aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authora-romanov <a-romanov@yandex-team.ru>2022-02-10 16:48:11 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:48:11 +0300
commit0f4c5d1e8c0672bf0a1f2f2d8acac5ba24772435 (patch)
treeb222e5ac2e2e98872661c51ccceee5da0d291e13
parentaa2986a34bde73b2cdcea5080c4443b7cf2ba686 (diff)
downloadydb-0f4c5d1e8c0672bf0a1f2f2d8acac5ba24772435.tar.gz
Restoring authorship annotation for <a-romanov@yandex-team.ru>. Commit 2 of 2.
-rw-r--r--contrib/libs/cxxsupp/builtins/ya.make4
-rw-r--r--library/cpp/actors/core/buffer.cpp98
-rw-r--r--library/cpp/actors/core/buffer.h84
-rw-r--r--library/cpp/actors/core/event.h8
-rw-r--r--library/cpp/actors/core/events.h14
-rw-r--r--library/cpp/actors/core/interconnect.h6
-rw-r--r--library/cpp/actors/testlib/test_runtime.cpp40
-rw-r--r--library/cpp/actors/testlib/test_runtime.h10
-rw-r--r--library/cpp/actors/util/funnel_queue.h228
-rw-r--r--library/cpp/binsaver/bin_saver.h20
-rw-r--r--library/cpp/containers/comptrie/comptrie_trie.h6
-rw-r--r--library/cpp/containers/comptrie/comptrie_ut.cpp2
-rw-r--r--library/cpp/dbg_output/dump.h6
-rw-r--r--library/cpp/dbg_output/engine.h4
-rw-r--r--library/cpp/digest/crc32c/crc32c.cpp24
-rw-r--r--library/cpp/digest/crc32c/crc32c.h8
-rw-r--r--library/cpp/digest/crc32c/ya.make2
-rw-r--r--library/cpp/lfalloc/yt/ya.make6
-rw-r--r--library/cpp/linear_regression/linear_regression.cpp6
-rw-r--r--library/cpp/linear_regression/linear_regression.h2
-rw-r--r--library/cpp/logger/element.cpp2
-rw-r--r--library/cpp/logger/element_ut.cpp2
-rw-r--r--library/cpp/messagebus/async_result.h8
-rw-r--r--library/cpp/messagebus/async_result_ut.cpp4
-rw-r--r--library/cpp/messagebus/session_impl.cpp4
-rw-r--r--library/cpp/messagebus/test/perftest/perftest.cpp4
-rw-r--r--library/cpp/monlib/counters/counters.h2
-rw-r--r--library/cpp/monlib/dynamic_counters/counters.cpp8
-rw-r--r--library/cpp/monlib/dynamic_counters/counters.h4
-rw-r--r--library/cpp/monlib/dynamic_counters/page.cpp40
-rw-r--r--library/cpp/monlib/dynamic_counters/page.h6
-rw-r--r--library/cpp/monlib/service/monservice.h2
-rw-r--r--library/cpp/monlib/service/pages/html_mon_page.cpp8
-rw-r--r--library/cpp/monlib/service/pages/html_mon_page.h2
-rw-r--r--library/cpp/monlib/service/pages/templates.cpp6
-rw-r--r--library/cpp/monlib/service/pages/templates.h8
-rw-r--r--library/cpp/monlib/service/service.cpp2
-rw-r--r--library/cpp/retry/retry.h2
-rw-r--r--library/cpp/scheme/scimpl_defs.h2
-rw-r--r--library/cpp/scheme/scimpl_private.cpp2
-rw-r--r--library/cpp/sighandler/async_signals_handler.cpp4
-rw-r--r--library/cpp/sighandler/async_signals_handler.h4
-rw-r--r--library/cpp/threading/future/legacy_future.h2
-rw-r--r--library/cpp/threading/local_executor/local_executor.h2
-rw-r--r--library/cpp/threading/poor_man_openmp/thread_helper.h4
-rw-r--r--library/cpp/threading/skip_list/perf/main.cpp2
-rw-r--r--library/cpp/xml/document/xml-textreader.h2
-rw-r--r--library/cpp/xml/document/xml-textreader_ut.cpp2
-rw-r--r--library/cpp/yson/node/node_builder.cpp2
-rw-r--r--library/cpp/yson_pull/detail/reader.h12
-rw-r--r--library/cpp/yson_pull/ut/reader_ut.cpp4
-rw-r--r--util/generic/bt_exception.h4
-rw-r--r--util/generic/buffer.cpp28
-rw-r--r--util/generic/buffer.h22
-rw-r--r--util/generic/buffer_ut.cpp4
-rw-r--r--util/generic/deque_ut.cpp6
-rw-r--r--util/generic/function_ut.cpp2
-rw-r--r--util/generic/hash.h52
-rw-r--r--util/generic/hash_set.h28
-rw-r--r--util/generic/hash_ut.cpp18
-rw-r--r--util/generic/lazy_value.h2
-rw-r--r--util/generic/maybe.h4
-rw-r--r--util/generic/ptr.h10
-rw-r--r--util/generic/queue_ut.cpp10
-rw-r--r--util/generic/set_ut.cpp10
-rw-r--r--util/generic/store_policy.h8
-rw-r--r--util/generic/vector_ut.cpp6
-rw-r--r--util/generic/yexception.h4
-rw-r--r--util/memory/pool.h4
-rw-r--r--util/memory/tempbuf.cpp4
-rw-r--r--util/memory/tempbuf_ut.cpp4
-rw-r--r--util/random/lcg_engine.h4
-rw-r--r--util/stream/buffered.h6
-rw-r--r--util/stream/file.h2
-rw-r--r--util/stream/holder.h2
-rw-r--r--util/string/builder.h4
-rw-r--r--util/string/strip.h2
-rw-r--r--util/thread/factory.cpp2
-rw-r--r--util/thread/factory.h2
-rw-r--r--util/thread/lfqueue_ut.cpp2
-rw-r--r--util/thread/lfstack_ut.cpp6
-rw-r--r--util/thread/pool.h2
-rw-r--r--util/ysaveload.h4
-rw-r--r--ydb/apps/ydbd/ya.make2
-rw-r--r--ydb/core/base/tablet.h2
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h2
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp2
-rw-r--r--ydb/core/client/metadata/functions_metadata.cpp14
-rw-r--r--ydb/core/client/metadata/functions_metadata.h4
-rw-r--r--ydb/core/client/metadata/ut/functions_metadata_ut.cpp28
-rw-r--r--ydb/core/client/metadata/ut/ya.make2
-rw-r--r--ydb/core/client/minikql_compile/ut/ya.make2
-rw-r--r--ydb/core/client/minikql_compile/yql_expr_minikql.cpp254
-rw-r--r--ydb/core/client/minikql_compile/yql_expr_minikql.h2
-rw-r--r--ydb/core/client/minikql_compile/yql_expr_minikql_compile_ut.cpp14
-rw-r--r--ydb/core/client/server/msgbus_server_db.cpp16
-rw-r--r--ydb/core/client/server/msgbus_server_types.cpp2
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp2
-rw-r--r--ydb/core/driver_lib/run/run.cpp6
-rw-r--r--ydb/core/engine/kikimr_program_builder.cpp20
-rw-r--r--ydb/core/engine/kikimr_program_builder.h4
-rw-r--r--ydb/core/engine/kikimr_program_builder_ut.cpp162
-rw-r--r--ydb/core/engine/minikql/flat_local_tx_minikql.h2
-rw-r--r--ydb/core/engine/minikql/minikql_engine_host.cpp254
-rw-r--r--ydb/core/engine/minikql/minikql_engine_host.h4
-rw-r--r--ydb/core/engine/mkql_engine_flat.cpp84
-rw-r--r--ydb/core/engine/mkql_engine_flat_extfunc.cpp372
-rw-r--r--ydb/core/engine/mkql_engine_flat_host.h4
-rw-r--r--ydb/core/engine/mkql_engine_flat_impl.h8
-rw-r--r--ydb/core/engine/mkql_engine_flat_ut.cpp412
-rw-r--r--ydb/core/engine/mkql_keys.cpp86
-rw-r--r--ydb/core/engine/mkql_proto.cpp8
-rw-r--r--ydb/core/engine/mkql_proto_ut.cpp18
-rw-r--r--ydb/core/kqp/compile/kqp_mkql_compiler.cpp4
-rw-r--r--ydb/core/kqp/host/kqp_host.cpp8
-rw-r--r--ydb/core/kqp/host/kqp_runner.cpp4
-rw-r--r--ydb/core/kqp/prepare/kqp_query_analyze.cpp16
-rw-r--r--ydb/core/kqp/prepare/kqp_query_exec.cpp6
-rw-r--r--ydb/core/kqp/prepare/kqp_query_finalize.cpp48
-rw-r--r--ydb/core/kqp/prepare/kqp_query_rewrite.cpp58
-rw-r--r--ydb/core/kqp/prepare/kqp_query_simplify.cpp18
-rw-r--r--ydb/core/kqp/prepare/kqp_query_substitute.cpp4
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_datasink.cpp62
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_datasource.cpp66
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_exec.cpp46
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_expr_nodes.cpp2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_expr_nodes.h26
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_kql.cpp2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_mkql.cpp16
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_opt.cpp18
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_opt_range.cpp2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_provider.cpp2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_provider_impl.h2
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_type_ann.cpp44
-rw-r--r--ydb/core/kqp/runtime/kqp_read_table.cpp8
-rw-r--r--ydb/core/kqp/ut/kqp_explain_ut.cpp10
-rw-r--r--ydb/core/kqp/ut/kqp_locks_ut.cpp10
-rw-r--r--ydb/core/mon/mon.cpp2
-rw-r--r--ydb/core/protos/config.proto16
-rw-r--r--ydb/core/scheme_types/scheme_types_defs.h2
-rw-r--r--ydb/core/tablet/pipe_tracker.h2
-rw-r--r--ydb/core/tablet/tablet_setup.h2
-rw-r--r--ydb/core/testlib/tablet_helpers.h2
-rw-r--r--ydb/core/testlib/test_client.cpp6
-rw-r--r--ydb/core/testlib/test_client.h2
-rw-r--r--ydb/core/tx/coordinator/coordinator__check.h2
-rw-r--r--ydb/core/tx/coordinator/coordinator__restore_transaction.cpp2
-rw-r--r--ydb/core/tx/datashard/datashard__engine_host.cpp30
-rw-r--r--ydb/core/tx/datashard/datashard_kqp_lookup_table.cpp4
-rw-r--r--ydb/core/tx/datashard/datashard_kqp_read_table.cpp2
-rw-r--r--ydb/core/util/cache.h10
-rw-r--r--ydb/core/util/queue_inplace_ut.cpp2
-rw-r--r--ydb/core/util/queue_oneone_inplace_ut.cpp2
-rw-r--r--ydb/core/ymq/actor/queue_schema.cpp4
-rw-r--r--ydb/core/yq/libs/actors/pending_fetcher.cpp16
-rw-r--r--ydb/core/yq/libs/actors/proxy.h2
-rw-r--r--ydb/core/yq/libs/actors/run_actor.cpp10
-rw-r--r--ydb/core/yq/libs/actors/run_actor_params.cpp4
-rw-r--r--ydb/core/yq/libs/actors/run_actor_params.h4
-rw-r--r--ydb/core/yq/libs/events/events.h4
-rw-r--r--ydb/core/yq/libs/private_client/utils.cpp4
-rw-r--r--ydb/core/yql_testlib/yql_testlib.cpp70
-rw-r--r--ydb/library/mkql_proto/mkql_proto_ut.cpp12
-rw-r--r--ydb/library/yql/ast/serialize/yql_expr_serialize.cpp64
-rw-r--r--ydb/library/yql/ast/yql_ast.cpp28
-rw-r--r--ydb/library/yql/ast/yql_ast.h2
-rw-r--r--ydb/library/yql/ast/yql_constraint.cpp646
-rw-r--r--ydb/library/yql/ast/yql_constraint.h124
-rw-r--r--ydb/library/yql/ast/yql_expr.cpp2556
-rw-r--r--ydb/library/yql/ast/yql_expr.h1642
-rw-r--r--ydb/library/yql/ast/yql_expr_builder.cpp350
-rw-r--r--ydb/library/yql/ast/yql_expr_builder.h80
-rw-r--r--ydb/library/yql/ast/yql_expr_builder_ut.cpp220
-rw-r--r--ydb/library/yql/ast/yql_expr_types.h8
-rw-r--r--ydb/library/yql/ast/yql_expr_ut.cpp1746
-rw-r--r--ydb/library/yql/ast/yql_gc_nodes.h4
-rw-r--r--ydb/library/yql/ast/yql_type_string.cpp96
-rw-r--r--ydb/library/yql/ast/yql_type_string_ut.cpp10
-rw-r--r--ydb/library/yql/core/common_opt/yql_co.h24
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_extr_members.cpp182
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_extr_members.h4
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_finalizers.cpp16
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_flow1.cpp2312
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_flow2.cpp196
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_simple1.cpp3048
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_simple2.cpp334
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_transformer.cpp12
-rw-r--r--ydb/library/yql/core/expr_nodes/yql_expr_nodes.h24
-rw-r--r--ydb/library/yql/core/expr_nodes/yql_expr_nodes.json358
-rw-r--r--ydb/library/yql/core/expr_nodes_gen/gen/ya.make2
-rw-r--r--ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h186
-rw-r--r--ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.jnj60
-rw-r--r--ydb/library/yql/core/facade/yql_facade.cpp42
-rw-r--r--ydb/library/yql/core/facade/yql_facade.h24
-rw-r--r--ydb/library/yql/core/issue/protos/issue_id.proto8
-rw-r--r--ydb/library/yql/core/issue/yql_issue.txt34
-rw-r--r--ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp10126
-rw-r--r--ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.h4
-rw-r--r--ydb/library/yql/core/services/yql_eval_expr.cpp8
-rw-r--r--ydb/library/yql/core/services/yql_plan.cpp48
-rw-r--r--ydb/library/yql/core/services/yql_transform_pipeline.cpp20
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.cpp4298
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.h4
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_expr.cpp118
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_expr.h6
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_impl.h8
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_join.cpp680
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_list.cpp3354
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_list.h126
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_types.cpp372
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_types.h8
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_wide.cpp1254
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_wide.h44
-rw-r--r--ydb/library/yql/core/type_ann/ya.make4
-rw-r--r--ydb/library/yql/core/ya.make4
-rw-r--r--ydb/library/yql/core/yql_callable_transform.h12
-rw-r--r--ydb/library/yql/core/yql_data_provider.h12
-rw-r--r--ydb/library/yql/core/yql_execution.cpp144
-rw-r--r--ydb/library/yql/core/yql_execution.h24
-rw-r--r--ydb/library/yql/core/yql_expr_constraint.cpp2146
-rw-r--r--ydb/library/yql/core/yql_expr_constraint.h2
-rw-r--r--ydb/library/yql/core/yql_expr_csee.cpp536
-rw-r--r--ydb/library/yql/core/yql_expr_optimize.cpp854
-rw-r--r--ydb/library/yql/core/yql_expr_optimize.h58
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.cpp2666
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.h146
-rw-r--r--ydb/library/yql/core/yql_gc_transformer.cpp68
-rw-r--r--ydb/library/yql/core/yql_gc_transformer.h2
-rw-r--r--ydb/library/yql/core/yql_graph_transformer.cpp10
-rw-r--r--ydb/library/yql/core/yql_graph_transformer.h22
-rw-r--r--ydb/library/yql/core/yql_join.cpp644
-rw-r--r--ydb/library/yql/core/yql_join.h14
-rw-r--r--ydb/library/yql/core/yql_library_compiler.cpp208
-rw-r--r--ydb/library/yql/core/yql_library_compiler.h20
-rw-r--r--ydb/library/yql/core/yql_opt_aggregate.cpp2630
-rw-r--r--ydb/library/yql/core/yql_opt_aggregate.h14
-rw-r--r--ydb/library/yql/core/yql_opt_proposed_by_data.cpp22
-rw-r--r--ydb/library/yql/core/yql_opt_rewrite_io.cpp22
-rw-r--r--ydb/library/yql/core/yql_opt_rewrite_io.h2
-rw-r--r--ydb/library/yql/core/yql_opt_utils.cpp478
-rw-r--r--ydb/library/yql/core/yql_opt_utils.h38
-rw-r--r--ydb/library/yql/core/yql_opt_window.cpp250
-rw-r--r--ydb/library/yql/core/yql_type_annotation.cpp8
-rw-r--r--ydb/library/yql/core/yql_type_annotation.h88
-rw-r--r--ydb/library/yql/core/yql_type_helpers.cpp6
-rw-r--r--ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h6
-rw-r--r--ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h2
-rw-r--r--ydb/library/yql/dq/opt/dq_opt.cpp18
-rw-r--r--ydb/library/yql/dq/opt/dq_opt.h4
-rw-r--r--ydb/library/yql/dq/opt/dq_opt_build.cpp86
-rw-r--r--ydb/library/yql/dq/opt/dq_opt_log.cpp2
-rw-r--r--ydb/library/yql/dq/opt/dq_opt_peephole.cpp176
-rw-r--r--ydb/library/yql/dq/opt/dq_opt_phy.cpp138
-rw-r--r--ydb/library/yql/dq/opt/dq_opt_phy.h4
-rw-r--r--ydb/library/yql/dq/runtime/dq_input_impl.h2
-rw-r--r--ydb/library/yql/dq/runtime/dq_source.h4
-rw-r--r--ydb/library/yql/dq/runtime/dq_tasks_runner.h2
-rw-r--r--ydb/library/yql/dq/tasks/dq_task_program.cpp2
-rw-r--r--ydb/library/yql/minikql/aligned_page_pool.cpp74
-rw-r--r--ydb/library/yql/minikql/aligned_page_pool.h56
-rw-r--r--ydb/library/yql/minikql/codegen/codegen.cpp200
-rw-r--r--ydb/library/yql/minikql/codegen/codegen.h22
-rw-r--r--ydb/library/yql/minikql/codegen/codegen_ut.cpp320
-rw-r--r--ydb/library/yql/minikql/codegen/ut/128_bit.ll8
-rw-r--r--ydb/library/yql/minikql/codegen/ut/str.cpp10
-rw-r--r--ydb/library/yql/minikql/codegen/ya.make18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_addmember.cpp258
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_aggrcount.cpp122
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_append.cpp180
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_apply.cpp128
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_callable.cpp250
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.cpp930
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.h2
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chain_map.cpp920
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chain_map.h2
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chopper.cpp1598
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_chopper.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_coalesce.cpp96
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_collect.cpp386
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_combine.cpp1962
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_condense.cpp838
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_condense.h2
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_condense1.cpp898
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_condense1.h2
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_contains.cpp64
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.cpp538
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.cpp564
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.cpp714
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_dictitems.cpp474
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_dictitems.h4
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_discard.cpp376
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_element.cpp472
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_element.h20
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_ensure.cpp82
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_enumerate.cpp184
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_exists.cpp40
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_extend.cpp282
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_factory.cpp142
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_filter.cpp2660
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_flatmap.cpp3264
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_flatmap.h6
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_flow.cpp618
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_flow.h22
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_fold.cpp248
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_fold1.cpp352
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_frombytes.cpp26
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_fromstring.cpp558
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_fromyson.cpp48
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_group.cpp32
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_guess.cpp220
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_hasitems.cpp120
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_heap.cpp802
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_heap.h32
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_hopping.cpp144
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_if.cpp564
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_ifpresent.cpp592
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_invoke.cpp396
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_iterator.cpp476
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_join.cpp3212
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_join_dict.cpp458
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.cpp206
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.h20
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_length.cpp120
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_listfromrange.cpp268
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_logical.cpp418
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_lookup.cpp56
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_map.cpp732
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_map_join.cpp3624
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_multimap.cpp1112
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_multimap.h22
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_now.cpp16
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_null.cpp2
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_pickle.cpp24
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_prepend.cpp180
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_queue.cpp112
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_random.cpp46
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_reduce.cpp256
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_removemember.cpp218
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_replicate.cpp56
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_reverse.cpp88
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_safe_circular_buffer.h10
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_saveload.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_size.cpp246
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_skip.cpp590
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_sort.cpp712
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_sort.h12
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_source.cpp158
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_source.h20
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.cpp192
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.h160
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.cpp374
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.h20
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_switch.cpp1670
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_take.cpp520
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_timezone.cpp194
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_tobytes.cpp144
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_todict.cpp2292
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_toindexdict.cpp88
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_tooptional.cpp430
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_tooptional.h4
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_tostring.cpp476
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_udf.cpp180
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_unwrap.cpp60
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_varitem.cpp112
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_visitall.cpp610
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_way.cpp212
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_weakmember.cpp32
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_while.cpp1184
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_while.h4
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.cpp570
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.cpp718
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.h18
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.cpp2018
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.h24
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.cpp548
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.h20
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.cpp864
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.h28
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_map.cpp596
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_wide_map.h26
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_zip.cpp270
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_chain_map_ut.cpp466
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_chopper_ut.cpp700
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_combine_ut.cpp2736
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_compare_ut.cpp1910
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.cpp8070
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.h132
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_condense_ut.cpp926
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_decimal_ut.cpp4238
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_dict_ut.cpp586
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_filters_ut.cpp2170
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp1540
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_fold_ut.cpp1900
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_group_ut.cpp50
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_heap_ut.cpp630
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_join_dict_ut.cpp744
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_join_ut.cpp492
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_listfromrange_ut.cpp200
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_map_join_ut.cpp2148
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_multihopping_ut.cpp46
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_multimap_ut.cpp340
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_safe_circular_buffer_ut.cpp30
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_sort_ut.cpp882
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_switch_ut.cpp548
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_todict_ut.cpp106
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_variant_ut.cpp1010
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chain_map_ut.cpp630
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp946
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp3394
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp344
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp770
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp504
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp202
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/ya.make58
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ya.make114
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h196
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node.cpp8
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node.h218
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_codegen.cpp3548
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h2818
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp274
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_graph_saveload_ut.cpp82
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_holders.cpp4726
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_holders.h394
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_impl.cpp580
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_impl.h1562
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_list.h52
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_list_ut.cpp246
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_pack.cpp624
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_pack.h24
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_pack_ut.cpp488
-rw-r--r--ydb/library/yql/minikql/computation/mkql_custom_list.cpp268
-rw-r--r--ydb/library/yql/minikql/computation/mkql_custom_list.h150
-rw-r--r--ydb/library/yql/minikql/computation/mkql_optional_usage_mask.h152
-rw-r--r--ydb/library/yql/minikql/computation/mkql_pack_bc.cpp384
-rw-r--r--ydb/library/yql/minikql/computation/mkql_validate.cpp236
-rw-r--r--ydb/library/yql/minikql/computation/mkql_validate.h4
-rw-r--r--ydb/library/yql/minikql/computation/mkql_validate_impl.h6
-rw-r--r--ydb/library/yql/minikql/computation/mkql_validate_ut.cpp710
-rw-r--r--ydb/library/yql/minikql/computation/mkql_value_builder.cpp228
-rw-r--r--ydb/library/yql/minikql/computation/mkql_value_builder.h82
-rw-r--r--ydb/library/yql/minikql/computation/mkql_value_builder_ut.cpp158
-rw-r--r--ydb/library/yql/minikql/computation/presort.cpp30
-rw-r--r--ydb/library/yql/minikql/computation/presort.h2
-rw-r--r--ydb/library/yql/minikql/computation/presort_ut.cpp54
-rw-r--r--ydb/library/yql/minikql/computation/ut/ya.make4
-rw-r--r--ydb/library/yql/minikql/computation/ya.make70
-rw-r--r--ydb/library/yql/minikql/defs.h16
-rw-r--r--ydb/library/yql/minikql/dom/convert.h762
-rw-r--r--ydb/library/yql/minikql/dom/hash.cpp300
-rw-r--r--ydb/library/yql/minikql/dom/hash.h22
-rw-r--r--ydb/library/yql/minikql/dom/json.cpp414
-rw-r--r--ydb/library/yql/minikql/dom/json.h10
-rw-r--r--ydb/library/yql/minikql/dom/make.cpp296
-rw-r--r--ydb/library/yql/minikql/dom/make.h16
-rw-r--r--ydb/library/yql/minikql/dom/node.cpp402
-rw-r--r--ydb/library/yql/minikql/dom/node.h176
-rw-r--r--ydb/library/yql/minikql/dom/peel.cpp734
-rw-r--r--ydb/library/yql/minikql/dom/peel.h18
-rw-r--r--ydb/library/yql/minikql/dom/ut/json_ut.cpp4046
-rw-r--r--ydb/library/yql/minikql/dom/ut/ya.make14
-rw-r--r--ydb/library/yql/minikql/dom/ut/yson_ut.cpp4114
-rw-r--r--ydb/library/yql/minikql/dom/ya.make12
-rw-r--r--ydb/library/yql/minikql/dom/yson.cpp334
-rw-r--r--ydb/library/yql/minikql/dom/yson.h4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp192
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h2
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp124
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp256
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitand.cpp30
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitnot.cpp30
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitor.cpp30
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitxor.cpp30
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_byteat.cpp170
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.cpp492
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.h68
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_compare.h890
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_concat.cpp52
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_convert.cpp1832
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_countbits.cpp40
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_datetime.h328
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_dec.cpp112
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.cpp144
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h596
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp224
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp538
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_find.cpp156
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp532
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp532
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h978
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_inc.cpp112
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_invprestr.cpp38
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp532
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp532
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_max.cpp368
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_min.cpp368
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp64
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp146
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp100
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_nanvl.cpp188
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp538
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_plus.cpp48
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotleft.cpp46
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotright.cpp46
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftleft.cpp42
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftright.cpp42
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp320
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_substring.cpp126
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_ut.cpp44
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_with.cpp132
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/ut/ya.make6
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/ya.make40
-rw-r--r--ydb/library/yql/minikql/mkql_alloc.cpp24
-rw-r--r--ydb/library/yql/minikql/mkql_alloc.h116
-rw-r--r--ydb/library/yql/minikql/mkql_function_metadata.h140
-rw-r--r--ydb/library/yql/minikql/mkql_function_registry.cpp86
-rw-r--r--ydb/library/yql/minikql/mkql_function_registry.h28
-rw-r--r--ydb/library/yql/minikql/mkql_mem_info.h46
-rw-r--r--ydb/library/yql/minikql/mkql_node.cpp276
-rw-r--r--ydb/library/yql/minikql/mkql_node.h172
-rw-r--r--ydb/library/yql/minikql/mkql_node_builder.cpp12
-rw-r--r--ydb/library/yql/minikql/mkql_node_cast.cpp4
-rw-r--r--ydb/library/yql/minikql/mkql_node_cast_ut.cpp2
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer.cpp62
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer_ut.cpp16
-rw-r--r--ydb/library/yql/minikql/mkql_node_serialization.cpp244
-rw-r--r--ydb/library/yql/minikql/mkql_node_ut.cpp58
-rw-r--r--ydb/library/yql/minikql/mkql_node_visitor.cpp38
-rw-r--r--ydb/library/yql/minikql/mkql_node_visitor.h22
-rw-r--r--ydb/library/yql/minikql/mkql_opt_literal.cpp62
-rw-r--r--ydb/library/yql/minikql/mkql_opt_literal_ut.cpp84
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.cpp5482
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.h724
-rw-r--r--ydb/library/yql/minikql/mkql_runtime_version.h8
-rw-r--r--ydb/library/yql/minikql/mkql_string_util.cpp298
-rw-r--r--ydb/library/yql/minikql/mkql_string_util.h30
-rw-r--r--ydb/library/yql/minikql/mkql_string_util_ut.cpp42
-rw-r--r--ydb/library/yql/minikql/mkql_terminator.cpp56
-rw-r--r--ydb/library/yql/minikql/mkql_terminator.h62
-rw-r--r--ydb/library/yql/minikql/mkql_type_builder.cpp244
-rw-r--r--ydb/library/yql/minikql/mkql_type_builder.h2
-rw-r--r--ydb/library/yql/minikql/mkql_type_ops.cpp2218
-rw-r--r--ydb/library/yql/minikql/mkql_type_ops.h24
-rw-r--r--ydb/library/yql/minikql/mkql_type_ops_ut.cpp26
-rw-r--r--ydb/library/yql/minikql/mkql_unboxed_value_stream.cpp38
-rw-r--r--ydb/library/yql/minikql/mkql_unboxed_value_stream.h16
-rw-r--r--ydb/library/yql/minikql/mkql_utils.h4
-rw-r--r--ydb/library/yql/minikql/perf/alloc/alloc.cpp10
-rw-r--r--ydb/library/yql/minikql/perf/presort/presort.cpp22
-rw-r--r--ydb/library/yql/minikql/ut/ya.make2
-rw-r--r--ydb/library/yql/minikql/ya.make14
-rw-r--r--ydb/library/yql/mount/lib/yql/aggregate.yql864
-rw-r--r--ydb/library/yql/mount/lib/yql/core.yql8
-rw-r--r--ydb/library/yql/mount/lib/yql/window.yql266
-rw-r--r--ydb/library/yql/protos/ya.make2
-rw-r--r--ydb/library/yql/protos/yql_mount.proto24
-rw-r--r--ydb/library/yql/providers/clickhouse/actors/ya.make36
-rw-r--r--ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.cpp322
-rw-r--r--ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.h34
-rw-r--r--ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.cpp22
-rw-r--r--ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.h22
-rw-r--r--ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.json20
-rw-r--r--ydb/library/yql/providers/clickhouse/proto/range.proto14
-rw-r--r--ydb/library/yql/providers/clickhouse/proto/source.proto22
-rw-r--r--ydb/library/yql/providers/clickhouse/proto/ya.make36
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/ya.make2
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasink.cpp26
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource.cpp30
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource_type_ann.cpp38
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.cpp176
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.h2
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_load_meta.cpp448
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_logical_opt.cpp62
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.cpp156
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.h2
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_physical_opt.cpp226
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.cpp6
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.h6
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider_impl.h4
-rw-r--r--ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_settings.h62
-rw-r--r--ydb/library/yql/providers/clickhouse/ya.make4
-rw-r--r--ydb/library/yql/providers/common/codec/yql_codec.cpp108
-rw-r--r--ydb/library/yql/providers/common/codec/yql_codec.h4
-rw-r--r--ydb/library/yql/providers/common/codec/yql_codec_results.cpp2
-rw-r--r--ydb/library/yql/providers/common/comp_nodes/ya.make12
-rw-r--r--ydb/library/yql/providers/common/comp_nodes/yql_makecode.cpp2
-rw-r--r--ydb/library/yql/providers/common/dq/yql_dq_integration_impl.cpp6
-rw-r--r--ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h4
-rw-r--r--ydb/library/yql/providers/common/http_gateway/ya.make34
-rw-r--r--ydb/library/yql/providers/common/http_gateway/yql_http_gateway.cpp734
-rw-r--r--ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h94
-rw-r--r--ydb/library/yql/providers/common/mkql/parser.cpp42
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp3126
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_provider_mkql.h98
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp62
-rw-r--r--ydb/library/yql/providers/common/proto/gateways_config.proto82
-rw-r--r--ydb/library/yql/providers/common/provider/yql_provider.cpp106
-rw-r--r--ydb/library/yql/providers/common/provider/yql_provider.h8
-rw-r--r--ydb/library/yql/providers/common/provider/yql_provider_names.h28
-rw-r--r--ydb/library/yql/providers/common/provider/yql_table_lookup.cpp142
-rw-r--r--ydb/library/yql/providers/common/provider/yql_table_lookup.h2
-rw-r--r--ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp10
-rw-r--r--ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp20
-rw-r--r--ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp2
-rw-r--r--ydb/library/yql/providers/common/ya.make2
-rw-r--r--ydb/library/yql/providers/config/yql_config_provider.cpp84
-rw-r--r--ydb/library/yql/providers/dq/actors/executer_actor.cpp10
-rw-r--r--ydb/library/yql/providers/dq/actors/executer_actor.h2
-rw-r--r--ydb/library/yql/providers/dq/api/protos/dqs.proto4
-rw-r--r--ydb/library/yql/providers/dq/api/protos/service.proto4
-rw-r--r--ydb/library/yql/providers/dq/common/yql_dq_settings.cpp2
-rw-r--r--ydb/library/yql/providers/dq/common/yql_dq_settings.h16
-rw-r--r--ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.json52
-rw-r--r--ydb/library/yql/providers/dq/interface/yql_dq_integration.h4
-rw-r--r--ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.cpp20
-rw-r--r--ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.h2
-rw-r--r--ydb/library/yql/providers/dq/mkql/dqs_mkql_compiler.cpp20
-rw-r--r--ydb/library/yql/providers/dq/opt/physical_optimize.cpp230
-rw-r--r--ydb/library/yql/providers/dq/planner/execution_planner.cpp28
-rw-r--r--ydb/library/yql/providers/dq/provider/exec/yql_dq_exectransformer.cpp176
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_datasink.cpp2
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_datasink_type_ann.cpp14
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp52
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_datasource_type_ann.cpp182
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_gateway.cpp4
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_gateway.h2
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_provider.cpp2
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_recapture.cpp10
-rw-r--r--ydb/library/yql/providers/dq/service/grpc_service.cpp4
-rw-r--r--ydb/library/yql/providers/dq/task_runner/tasks_runner_local.cpp6
-rw-r--r--ydb/library/yql/providers/dq/worker_manager/interface/events.cpp4
-rw-r--r--ydb/library/yql/providers/dq/worker_manager/interface/events.h2
-rw-r--r--ydb/library/yql/providers/pq/provider/yql_pq_dq_integration.cpp2
-rw-r--r--ydb/library/yql/providers/result/provider/yql_result_provider.cpp64
-rw-r--r--ydb/library/yql/providers/result/provider/yql_result_provider.h2
-rw-r--r--ydb/library/yql/providers/s3/actors/ya.make34
-rw-r--r--ydb/library/yql/providers/s3/actors/yql_s3_read_actor.cpp332
-rw-r--r--ydb/library/yql/providers/s3/actors/yql_s3_read_actor.h28
-rw-r--r--ydb/library/yql/providers/s3/actors/yql_s3_source_factory.cpp20
-rw-r--r--ydb/library/yql/providers/s3/actors/yql_s3_source_factory.h14
-rw-r--r--ydb/library/yql/providers/s3/expr_nodes/ya.make64
-rw-r--r--ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.cpp2
-rw-r--r--ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h112
-rw-r--r--ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.json162
-rw-r--r--ydb/library/yql/providers/s3/proto/range.proto16
-rw-r--r--ydb/library/yql/providers/s3/proto/source.proto30
-rw-r--r--ydb/library/yql/providers/s3/proto/ya.make30
-rw-r--r--ydb/library/yql/providers/s3/provider/ya.make56
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_datasink.cpp158
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_datasink_execution.cpp60
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_datasink_type_ann.cpp76
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_datasource.cpp252
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_datasource_type_ann.cpp264
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.cpp290
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.h24
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_exec.cpp78
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp596
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_logical_opt.cpp80
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.cpp42
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.h20
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_provider.cpp80
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_provider.h66
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.cpp12
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.h40
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_settings.cpp86
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_settings.h68
-rw-r--r--ydb/library/yql/providers/ydb/actors/ya.make28
-rw-r--r--ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.cpp492
-rw-r--r--ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.h28
-rw-r--r--ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.cpp20
-rw-r--r--ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.h14
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/ya.make30
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.cpp634
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.h18
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.cpp112
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.h18
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.cpp40
-rw-r--r--ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.h18
-rw-r--r--ydb/library/yql/providers/ydb/expr_nodes/ya.make64
-rw-r--r--ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.cpp2
-rw-r--r--ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h112
-rw-r--r--ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.json190
-rw-r--r--ydb/library/yql/providers/ydb/proto/range.proto16
-rw-r--r--ydb/library/yql/providers/ydb/proto/source.proto28
-rw-r--r--ydb/library/yql/providers/ydb/proto/ya.make30
-rw-r--r--ydb/library/yql/providers/ydb/provider/ya.make50
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_datasink.cpp254
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_execution.cpp60
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_type_ann.cpp118
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_datasource.cpp276
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_datasource_type_ann.cpp336
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.cpp284
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.h24
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_exec.cpp106
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_load_meta.cpp448
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_logical_opt.cpp176
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.cpp290
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.h20
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_physical_opt.cpp380
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_provider.cpp76
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_provider.h70
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.cpp254
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.h112
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_settings.cpp82
-rw-r--r--ydb/library/yql/providers/ydb/provider/yql_ydb_settings.h64
-rw-r--r--ydb/library/yql/providers/ydb/ya.make8
-rw-r--r--ydb/library/yql/public/decimal/ut/ya.make18
-rw-r--r--ydb/library/yql/public/decimal/ut/yql_decimal_ut.cpp478
-rw-r--r--ydb/library/yql/public/decimal/ut/yql_wide_int_ut.cpp926
-rw-r--r--ydb/library/yql/public/decimal/yql_decimal.cpp780
-rw-r--r--ydb/library/yql/public/decimal/yql_decimal.h172
-rw-r--r--ydb/library/yql/public/decimal/yql_wide_int.h680
-rw-r--r--ydb/library/yql/public/udf/service/exception_policy/udf_service.cpp36
-rw-r--r--ydb/library/yql/public/udf/service/exception_policy/ya.make10
-rw-r--r--ydb/library/yql/public/udf/service/stub/udf_service.cpp16
-rw-r--r--ydb/library/yql/public/udf/service/stub/ya.make10
-rw-r--r--ydb/library/yql/public/udf/service/terminate_policy/udf_service.cpp28
-rw-r--r--ydb/library/yql/public/udf/service/terminate_policy/ya.make10
-rw-r--r--ydb/library/yql/public/udf/support/udf_support.cpp34
-rw-r--r--ydb/library/yql/public/udf/tz/gen/ya.make2
-rw-r--r--ydb/library/yql/public/udf/tz/udf_tz.cpp20
-rw-r--r--ydb/library/yql/public/udf/tz/udf_tz.gen1194
-rw-r--r--ydb/library/yql/public/udf/tz/udf_tz.h6
-rw-r--r--ydb/library/yql/public/udf/tz/udf_tz_ut.cpp2
-rw-r--r--ydb/library/yql/public/udf/tz/update.py24
-rw-r--r--ydb/library/yql/public/udf/udf_allocator.h120
-rw-r--r--ydb/library/yql/public/udf/udf_counter.cpp4
-rw-r--r--ydb/library/yql/public/udf/udf_counter.h4
-rw-r--r--ydb/library/yql/public/udf/udf_counter_ut.cpp2
-rw-r--r--ydb/library/yql/public/udf/udf_data_type.h2
-rw-r--r--ydb/library/yql/public/udf/udf_helpers.cpp2
-rw-r--r--ydb/library/yql/public/udf/udf_helpers.h156
-rw-r--r--ydb/library/yql/public/udf/udf_ptr.h4
-rw-r--r--ydb/library/yql/public/udf/udf_registrator.h96
-rw-r--r--ydb/library/yql/public/udf/udf_static_registry.cpp2
-rw-r--r--ydb/library/yql/public/udf/udf_static_registry.h2
-rw-r--r--ydb/library/yql/public/udf/udf_string.h286
-rw-r--r--ydb/library/yql/public/udf/udf_string_ref.h170
-rw-r--r--ydb/library/yql/public/udf/udf_terminator.h10
-rw-r--r--ydb/library/yql/public/udf/udf_type_builder.h76
-rw-r--r--ydb/library/yql/public/udf/udf_type_inspection.h68
-rw-r--r--ydb/library/yql/public/udf/udf_type_ops.h108
-rw-r--r--ydb/library/yql/public/udf/udf_type_printer.cpp202
-rw-r--r--ydb/library/yql/public/udf/udf_type_printer.h64
-rw-r--r--ydb/library/yql/public/udf/udf_types.h4
-rw-r--r--ydb/library/yql/public/udf/udf_ut_helpers.h128
-rw-r--r--ydb/library/yql/public/udf/udf_validate.cpp4
-rw-r--r--ydb/library/yql/public/udf/udf_validate.h4
-rw-r--r--ydb/library/yql/public/udf/udf_value.h882
-rw-r--r--ydb/library/yql/public/udf/udf_value_builder.h164
-rw-r--r--ydb/library/yql/public/udf/udf_value_builder_ut.cpp44
-rw-r--r--ydb/library/yql/public/udf/udf_value_inl.h1304
-rw-r--r--ydb/library/yql/public/udf/udf_value_ut.cpp110
-rw-r--r--ydb/library/yql/public/udf/udf_version.cpp4
-rw-r--r--ydb/library/yql/public/udf/udf_version.h8
-rw-r--r--ydb/library/yql/public/udf/ut/ya.make2
-rw-r--r--ydb/library/yql/public/udf/ya.make6
-rw-r--r--ydb/library/yql/sql/settings/translation_settings.cpp2
-rw-r--r--ydb/library/yql/sql/settings/translation_settings.h14
-rw-r--r--ydb/library/yql/sql/v0/SQL.g20
-rw-r--r--ydb/library/yql/sql/v0/aggregation.cpp138
-rw-r--r--ydb/library/yql/sql/v0/builtin.cpp146
-rw-r--r--ydb/library/yql/sql/v0/context.h2
-rw-r--r--ydb/library/yql/sql/v0/node.cpp186
-rw-r--r--ydb/library/yql/sql/v0/node.h38
-rw-r--r--ydb/library/yql/sql/v0/query.cpp2
-rw-r--r--ydb/library/yql/sql/v0/select.cpp6
-rw-r--r--ydb/library/yql/sql/v0/sql.cpp124
-rw-r--r--ydb/library/yql/sql/v0/sql_ut.cpp66
-rw-r--r--ydb/library/yql/sql/v1/SQLv1.g.in12
-rw-r--r--ydb/library/yql/sql/v1/aggregation.cpp132
-rw-r--r--ydb/library/yql/sql/v1/builtin.cpp278
-rw-r--r--ydb/library/yql/sql/v1/context.cpp2
-rw-r--r--ydb/library/yql/sql/v1/context.h6
-rw-r--r--ydb/library/yql/sql/v1/list_builtin.cpp8
-rw-r--r--ydb/library/yql/sql/v1/list_builtin.h12
-rw-r--r--ydb/library/yql/sql/v1/node.cpp98
-rw-r--r--ydb/library/yql/sql/v1/node.h38
-rw-r--r--ydb/library/yql/sql/v1/query.cpp20
-rw-r--r--ydb/library/yql/sql/v1/select.cpp2
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp110
-rw-r--r--ydb/library/yql/sql/v1/sql_ut.cpp46
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/base/common/map.h18
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/clickhouse_client_udf.cpp728
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionFactory.cpp16
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Columns/ColumnArray.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/ClickHouseRevision.cpp4
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.h2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/RemoteHostFilter.cpp4
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/escapeForFileName.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Common/getMultipleKeysFromConfig.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Compression/CompressionFactory.cpp8
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Core/SettingsFields.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/DataStreams/NativeBlockOutputStream.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeFactory.cpp14
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeTuple.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Disks/DiskSelector.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Disks/IVolume.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Formats/FormatFactory.cpp30
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Formats/registerFormats.cpp16
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Functions/FunctionFactory.cpp4
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.h4
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Aggregator.h2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/ClientInfo.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Cluster.cpp12
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Context_fwd.h2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserExternalDDLQuery.cpp82
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserQuery.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/AvroRowInputFormat.cpp10
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ColumnsDescription.cpp4
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ProjectionsDescription.cpp2
-rw-r--r--ydb/library/yql/udfs/common/clickhouse/client/ya.make358
-rw-r--r--ydb/library/yql/udfs/common/datetime/datetime_udf.cpp10
-rw-r--r--ydb/library/yql/udfs/common/datetime2/datetime_udf.cpp498
-rw-r--r--ydb/library/yql/udfs/common/digest/digest_udf.cpp84
-rw-r--r--ydb/library/yql/udfs/common/digest/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/histogram/histogram_udf.cpp256
-rw-r--r--ydb/library/yql/udfs/common/hyperloglog/hyperloglog_udf.cpp58
-rw-r--r--ydb/library/yql/udfs/common/hyperscan/hyperscan_udf.cpp248
-rw-r--r--ydb/library/yql/udfs/common/hyperscan/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/json/json_udf.cpp8
-rw-r--r--ydb/library/yql/udfs/common/json2/sql_value.h4
-rw-r--r--ydb/library/yql/udfs/common/json2/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/math/math_ir.h4
-rw-r--r--ydb/library/yql/udfs/common/pire/pire_udf.cpp248
-rw-r--r--ydb/library/yql/udfs/common/pire/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/re2/re2_udf.cpp374
-rw-r--r--ydb/library/yql/udfs/common/set/set_udf.cpp2
-rw-r--r--ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp630
-rw-r--r--ydb/library/yql/udfs/common/stat/static/stat_udf.h2
-rw-r--r--ydb/library/yql/udfs/common/stat/static/static_udf.cpp2
-rw-r--r--ydb/library/yql/udfs/common/stat/ut/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/string/string_udf.cpp96
-rw-r--r--ydb/library/yql/udfs/common/top/top_udf.cpp8
-rw-r--r--ydb/library/yql/udfs/common/topfreq/static/static_udf.cpp2
-rw-r--r--ydb/library/yql/udfs/common/topfreq/static/topfreq.cpp44
-rw-r--r--ydb/library/yql/udfs/common/topfreq/static/topfreq.h18
-rw-r--r--ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h44
-rw-r--r--ydb/library/yql/udfs/common/topfreq/topfreq_udf_ut.cpp830
-rw-r--r--ydb/library/yql/udfs/common/url_base/lib/url_parse.cpp20
-rw-r--r--ydb/library/yql/udfs/common/yson2/ya.make2
-rw-r--r--ydb/library/yql/udfs/common/yson2/yson2_udf.cpp2056
-rw-r--r--ydb/library/yql/udfs/logs/dsv/dsv_udf.cpp348
-rw-r--r--ydb/library/yql/utils/backtrace/backtrace.cpp6
-rw-r--r--ydb/library/yql/utils/backtrace/ya.make2
-rw-r--r--ydb/library/yql/utils/log/log_component.h8
-rw-r--r--ydb/library/yql/utils/ut/ya.make2
-rw-r--r--ydb/library/yql/utils/utf8.cpp64
-rw-r--r--ydb/library/yql/utils/utf8.h22
-rw-r--r--ydb/library/yql/utils/utf8_ut.cpp52
-rw-r--r--ydb/library/yql/utils/ya.make2
-rw-r--r--ydb/public/api/protos/yq.proto10
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_client.h4
-rw-r--r--ydb/public/lib/deprecated/kicli/result.cpp2
-rw-r--r--ydb/public/lib/experimental/ydb_clickhouse_internal.cpp48
-rw-r--r--ydb/public/lib/experimental/ydb_clickhouse_internal.h10
-rw-r--r--ydb/public/sdk/cpp/client/ydb_persqueue_core/impl/read_session.h4
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value.cpp6
-rw-r--r--ydb/services/ydb/ydb_ut.cpp2
867 files changed, 114820 insertions, 114820 deletions
diff --git a/contrib/libs/cxxsupp/builtins/ya.make b/contrib/libs/cxxsupp/builtins/ya.make
index 54c5dad2f5..d2c319c927 100644
--- a/contrib/libs/cxxsupp/builtins/ya.make
+++ b/contrib/libs/cxxsupp/builtins/ya.make
@@ -75,7 +75,7 @@ SRCS(
extenddftf2.c
extendsftf2.c
fixdfti.c
- fixsfti.c
+ fixsfti.c
fixtfdi.c
fixtfsi.c
fixunsdfti.c
@@ -91,7 +91,7 @@ SRCS(
floatunditf.c
floatunsitf.c
floatuntidf.c
- floatuntisf.c
+ floatuntisf.c
gcc_personality_v0.c
int_util.c
lshrti3.c
diff --git a/library/cpp/actors/core/buffer.cpp b/library/cpp/actors/core/buffer.cpp
index a949e2ab0f..48128d76ef 100644
--- a/library/cpp/actors/core/buffer.cpp
+++ b/library/cpp/actors/core/buffer.cpp
@@ -1,93 +1,93 @@
-#include "buffer.h"
-
-#include <util/system/yassert.h>
-
+#include "buffer.h"
+
+#include <util/system/yassert.h>
+
#include <algorithm>
-
-TBufferBase::TBufferBase(size_t size) noexcept
- : Size(size)
+
+TBufferBase::TBufferBase(size_t size) noexcept
+ : Size(size)
{
}
-
-size_t
+
+size_t
TBufferBase::GetSize() const noexcept {
return Size;
-}
-
+}
+
void TBufferBase::SetSize(size_t size) noexcept {
Size = size;
-}
-
-/////////////////////////////////////////////////////////////////////
-
+}
+
+/////////////////////////////////////////////////////////////////////
+
template <typename PointerType>
-TBufferBaseT<PointerType>::TBufferBaseT(PointerType data, size_t size) noexcept
+TBufferBaseT<PointerType>::TBufferBaseT(PointerType data, size_t size) noexcept
: TBufferBase(size)
, Data(data)
{
}
-
+
template <typename PointerType>
-PointerType
+PointerType
TBufferBaseT<PointerType>::GetPointer() const noexcept {
return Data;
-}
-
+}
+
template <typename PointerType>
void TBufferBaseT<PointerType>::Assign(PointerType data, size_t size) noexcept {
Data = data;
Size = size;
-}
-
+}
+
template <>
void TBufferBaseT<void*>::Cut(size_t offset) noexcept {
Y_VERIFY_DEBUG(offset <= Size);
Data = static_cast<char*>(Data) + offset;
TBufferBase::Size -= offset;
-}
-
+}
+
template <>
void TBufferBaseT<const void*>::Cut(size_t offset) noexcept {
Y_VERIFY_DEBUG(offset <= Size);
Data = static_cast<const char*>(Data) + offset;
TBufferBase::Size -= offset;
-}
-
-template class TBufferBaseT<void*>;
-template class TBufferBaseT<const void*>;
-
-/////////////////////////////////////////////////////////////////////
-
-TConstBuffer::TConstBuffer(const void* data, size_t size) noexcept
- : TBufferBaseT<const void*>(data, size)
+}
+
+template class TBufferBaseT<void*>;
+template class TBufferBaseT<const void*>;
+
+/////////////////////////////////////////////////////////////////////
+
+TConstBuffer::TConstBuffer(const void* data, size_t size) noexcept
+ : TBufferBaseT<const void*>(data, size)
{
}
-
-TConstBuffer::TConstBuffer(const TMutableBuffer& buffer) noexcept
- : TBufferBaseT<const void*>(buffer.GetPointer(), buffer.GetSize())
+
+TConstBuffer::TConstBuffer(const TMutableBuffer& buffer) noexcept
+ : TBufferBaseT<const void*>(buffer.GetPointer(), buffer.GetSize())
{
}
-
-TConstBuffer
+
+TConstBuffer
TConstBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept {
return TConstBuffer(static_cast<const char*>(Data) + offset, std::min(Size - offset, size));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TMutableBuffer::TMutableBuffer(void* data, size_t size) noexcept
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TMutableBuffer::TMutableBuffer(void* data, size_t size) noexcept
: TBufferBaseT<void*>(data, size)
{
}
-
-TMutableBuffer
+
+TMutableBuffer
TMutableBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept {
return TMutableBuffer(static_cast<char*>(Data) + offset, std::min(Size - offset, size));
-}
-
-size_t
+}
+
+size_t
TMutableBuffer::CopyFrom(const TConstBuffer& buffer) const noexcept {
const auto size = std::min(Size, buffer.Size);
std::memcpy(Data, buffer.Data, size);
return size;
-}
+}
diff --git a/library/cpp/actors/core/buffer.h b/library/cpp/actors/core/buffer.h
index 459b788b27..95425046d6 100644
--- a/library/cpp/actors/core/buffer.h
+++ b/library/cpp/actors/core/buffer.h
@@ -1,62 +1,62 @@
-#pragma once
-
+#pragma once
+
#include <limits>
-
-class TConstBuffer;
-class TMutableBuffer;
-
+
+class TConstBuffer;
+class TMutableBuffer;
+
class TBufferBase {
-public:
- size_t GetSize() const noexcept;
-
- void SetSize(size_t newSize) noexcept;
-
-protected:
- TBufferBase(size_t size = 0) noexcept;
-
- size_t Size;
-};
-
+public:
+ size_t GetSize() const noexcept;
+
+ void SetSize(size_t newSize) noexcept;
+
+protected:
+ TBufferBase(size_t size = 0) noexcept;
+
+ size_t Size;
+};
+
template <typename PointerType>
class TBufferBaseT: public TBufferBase {
-public:
- PointerType GetPointer() const noexcept;
-
- void Cut(size_t offset) noexcept;
-
- void Assign(PointerType data = nullptr, size_t size = 0U) noexcept;
-
-protected:
- TBufferBaseT(PointerType data, size_t size) noexcept;
-
- PointerType Data;
-};
-
-/// Represents constant memory buffer, but do not owns it.
+public:
+ PointerType GetPointer() const noexcept;
+
+ void Cut(size_t offset) noexcept;
+
+ void Assign(PointerType data = nullptr, size_t size = 0U) noexcept;
+
+protected:
+ TBufferBaseT(PointerType data, size_t size) noexcept;
+
+ PointerType Data;
+};
+
+/// Represents constant memory buffer, but do not owns it.
class TConstBuffer: public TBufferBaseT<const void*> {
friend class TMutableBuffer;
-public:
+public:
TConstBuffer(const TMutableBuffer& buffer) noexcept;
-
+
TConstBuffer(const void* data = nullptr, size_t size = 0U) noexcept;
-
+
TConstBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept;
-};
-
-/// Represents mutable memory buffer, but do not owns it.
+};
+
+/// Represents mutable memory buffer, but do not owns it.
class TMutableBuffer: public TBufferBaseT<void*> {
friend class TConstBuffer;
-public:
+public:
TMutableBuffer(void* data = nullptr, size_t size = 0U) noexcept;
-
+
TMutableBuffer(const TMutableBuffer& value) noexcept
: TBufferBaseT<void*>(value)
{
}
-
+
TMutableBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept;
-
+
size_t CopyFrom(const TConstBuffer& buffer) const noexcept;
-};
+};
diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h
index 17edf0d436..6ff02aaf94 100644
--- a/library/cpp/actors/core/event.h
+++ b/library/cpp/actors/core/event.h
@@ -116,18 +116,18 @@ namespace NActors {
static const size_t ChannelBits = 12;
static const size_t ChannelShift = (sizeof(ui32) << 3) - ChannelBits;
-
+
#ifdef USE_ACTOR_CALLSTACK
TCallstack Callstack;
#endif
ui16 GetChannel() const noexcept {
return Flags >> ChannelShift;
}
-
+
ui64 GetSubChannel() const noexcept {
return Flags & FlagUseSubChannel ? Sender.LocalId() : 0ULL;
}
-
+
static ui32 MakeFlags(ui32 channel, ui32 flags) {
Y_VERIFY(channel < (1 << ChannelBits));
Y_VERIFY(flags < (1 << ChannelShift));
@@ -249,7 +249,7 @@ namespace NActors {
return 0;
}
}
-
+
bool HasBuffer() const {
return bool(Buffer);
}
diff --git a/library/cpp/actors/core/events.h b/library/cpp/actors/core/events.h
index 12d7b6899f..702cf50fad 100644
--- a/library/cpp/actors/core/events.h
+++ b/library/cpp/actors/core/events.h
@@ -58,15 +58,15 @@ namespace NActors {
: Blob(blob)
{
}
-
+
TString ToStringHeader() const noexcept override {
return "THelloWorld::Blob";
}
-
+
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
return serializer->WriteString(&Blob);
}
-
+
static IEventBase* Load(TEventSerializedData* bufs) noexcept {
return new TEvBlob(bufs->GetString());
}
@@ -75,7 +75,7 @@ namespace NActors {
return true;
}
};
-
+
struct TSystem {
enum {
Start = EventSpaceBegin(ES_SYSTEM),
@@ -103,7 +103,7 @@ namespace NActors {
PoisonPill = Poison,
ActorDied = Gone,
};
-
+
static_assert(End < EventSpaceEnd(ES_SYSTEM), "expect End < EventSpaceEnd(ES_SYSTEM)");
};
@@ -130,7 +130,7 @@ namespace NActors {
struct TEvUnsubscribe: public TEventBase<TEvUnsubscribe, TSystem::Unsubscribe> {
DEFINE_SIMPLE_LOCAL_EVENT(TEvUnsubscribe, "System: TEvUnsubscribe")
};
-
+
struct TEvUndelivered: public TEventBase<TEvUndelivered, TSystem::Undelivered> {
enum EReason {
ReasonUnknown,
@@ -141,7 +141,7 @@ namespace NActors {
const EReason Reason;
const bool Unsure;
const TString Data;
-
+
TEvUndelivered(ui32 sourceType, ui32 reason, bool unsure = false)
: SourceType(sourceType)
, Reason(static_cast<EReason>(reason))
diff --git a/library/cpp/actors/core/interconnect.h b/library/cpp/actors/core/interconnect.h
index 81dbde2c4d..679a4b8cc6 100644
--- a/library/cpp/actors/core/interconnect.h
+++ b/library/cpp/actors/core/interconnect.h
@@ -162,7 +162,7 @@ namespace NActors {
}
const ui32 NodeId;
};
-
+
struct TEvNodeDisconnected: public TEventLocal<TEvNodeDisconnected, EvNodeDisconnected> {
DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeDisconnected, "TEvInterconnect::TEvNodeDisconnected")
TEvNodeDisconnected(ui32 node) noexcept
@@ -171,10 +171,10 @@ namespace NActors {
}
const ui32 NodeId;
};
-
+
struct TEvRegisterNode;
struct TEvRegisterNodeResult;
-
+
struct TEvListNodes: public TEventLocal<TEvListNodes, EvListNodes> {
};
diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp
index 8df586041e..6fa25b9965 100644
--- a/library/cpp/actors/testlib/test_runtime.cpp
+++ b/library/cpp/actors/testlib/test_runtime.cpp
@@ -62,9 +62,9 @@ namespace NActors {
}
void TTestActorRuntimeBase::TNodeDataBase::Stop() {
- if (Poller)
- Poller->Stop();
-
+ if (Poller)
+ Poller->Stop();
+
if (MailboxTable) {
for (ui32 round = 0; !MailboxTable->Cleanup(); ++round)
Y_VERIFY(round < 10, "cyclic event/actor spawn while trying to shutdown actorsystem stub");
@@ -72,7 +72,7 @@ namespace NActors {
if (ActorSystem)
ActorSystem->Stop();
-
+
ActorSystem.Destroy();
Poller.Reset();
}
@@ -684,37 +684,37 @@ namespace NActors {
TTestActorRuntimeBase::TEventObserver TTestActorRuntimeBase::SetObserverFunc(TEventObserver observerFunc) {
TGuard<TMutex> guard(Mutex);
- auto result = ObserverFunc;
- ObserverFunc = observerFunc;
- return result;
+ auto result = ObserverFunc;
+ ObserverFunc = observerFunc;
+ return result;
}
TTestActorRuntimeBase::TScheduledEventsSelector TTestActorRuntimeBase::SetScheduledEventsSelectorFunc(TScheduledEventsSelector scheduledEventsSelectorFunc) {
TGuard<TMutex> guard(Mutex);
- auto result = ScheduledEventsSelectorFunc;
- ScheduledEventsSelectorFunc = scheduledEventsSelectorFunc;
- return result;
+ auto result = ScheduledEventsSelectorFunc;
+ ScheduledEventsSelectorFunc = scheduledEventsSelectorFunc;
+ return result;
}
TTestActorRuntimeBase::TEventFilter TTestActorRuntimeBase::SetEventFilter(TEventFilter filterFunc) {
TGuard<TMutex> guard(Mutex);
- auto result = EventFilterFunc;
- EventFilterFunc = filterFunc;
- return result;
+ auto result = EventFilterFunc;
+ EventFilterFunc = filterFunc;
+ return result;
}
TTestActorRuntimeBase::TScheduledEventFilter TTestActorRuntimeBase::SetScheduledEventFilter(TScheduledEventFilter filterFunc) {
TGuard<TMutex> guard(Mutex);
- auto result = ScheduledEventFilterFunc;
- ScheduledEventFilterFunc = filterFunc;
- return result;
+ auto result = ScheduledEventFilterFunc;
+ ScheduledEventFilterFunc = filterFunc;
+ return result;
}
TTestActorRuntimeBase::TRegistrationObserver TTestActorRuntimeBase::SetRegistrationObserverFunc(TRegistrationObserver observerFunc) {
TGuard<TMutex> guard(Mutex);
- auto result = RegistrationObserver;
- RegistrationObserver = observerFunc;
- return result;
+ auto result = RegistrationObserver;
+ RegistrationObserver = observerFunc;
+ return result;
}
bool TTestActorRuntimeBase::IsVerbose() {
@@ -1641,7 +1641,7 @@ namespace NActors {
}
const auto& interconnectCounters = GetCountersForComponent(node->DynamicCounters, "interconnect");
-
+
setup->LocalServices = node->LocalServices;
setup->Interconnect.ProxyActors.resize(FirstNodeId + NodeCount);
const TActorId nameserviceId = GetNameserviceActorId();
diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h
index 356c073868..26e3b45c98 100644
--- a/library/cpp/actors/testlib/test_runtime.h
+++ b/library/cpp/actors/testlib/test_runtime.h
@@ -30,8 +30,8 @@
#include <util/system/valgrind.h>
#include <utility>
-#include <functional>
-
+#include <functional>
+
const TDuration DEFAULT_DISPATCH_TIMEOUT = NSan::PlainOrUnderSanitizer(
NValgrind::PlainOrUnderValgrind(TDuration::Seconds(60), TDuration::Seconds(120)),
TDuration::Seconds(120)
@@ -355,7 +355,7 @@ namespace NActors {
template <typename TEvent>
TEvent* GrabEdgeEvent(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
+ std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
return GrabEdgeEventIf(handle, truth, simTimeout);
}
@@ -644,7 +644,7 @@ namespace NActors {
}
template <typename TEvent>
- TEvent* FindEvent(TEventsList& events, const std::function<bool(const TEvent&)>& predicate) {
+ TEvent* FindEvent(TEventsList& events, const std::function<bool(const TEvent&)>& predicate) {
for (auto& event : events) {
if (event && event->GetTypeRewrite() == TEvent::EventType && predicate(*static_cast<TEvent*>(event->GetBase()))) {
return static_cast<TEvent*>(event->GetBase());
@@ -669,7 +669,7 @@ namespace NActors {
template <typename TEvent>
TEvent* GrabEvent(TEventsList& events, TAutoPtr<IEventHandle>& ev,
- const std::function<bool(const typename TEvent::TPtr&)>& predicate) {
+ const std::function<bool(const typename TEvent::TPtr&)>& predicate) {
ev.Destroy();
for (auto& event : events) {
if (event && event->GetTypeRewrite() == TEvent::EventType) {
diff --git a/library/cpp/actors/util/funnel_queue.h b/library/cpp/actors/util/funnel_queue.h
index 35dec61f2a..0e21e2617c 100644
--- a/library/cpp/actors/util/funnel_queue.h
+++ b/library/cpp/actors/util/funnel_queue.h
@@ -1,96 +1,96 @@
-#pragma once
-
-#include <util/system/atomic.h>
-#include <util/generic/noncopyable.h>
-
+#pragma once
+
+#include <util/system/atomic.h>
+#include <util/generic/noncopyable.h>
+
template <typename ElementType>
class TFunnelQueue: private TNonCopyable {
-public:
- TFunnelQueue() noexcept
+public:
+ TFunnelQueue() noexcept
: Front(nullptr)
, Back(nullptr)
{
}
-
+
virtual ~TFunnelQueue() noexcept {
- for (auto entry = Front; entry; entry = DeleteEntry(entry))
- continue;
- }
-
- /// Push element. Can be used from many threads. Return true if is first element.
- bool
+ for (auto entry = Front; entry; entry = DeleteEntry(entry))
+ continue;
+ }
+
+ /// Push element. Can be used from many threads. Return true if is first element.
+ bool
Push(ElementType&& element) noexcept {
TEntry* const next = NewEntry(static_cast<ElementType&&>(element));
TEntry* const prev = AtomicSwap(&Back, next);
AtomicSet(prev ? prev->Next : Front, next);
- return !prev;
- }
-
- /// Extract top element. Must be used only from one thread. Return true if have more.
- bool
+ return !prev;
+ }
+
+ /// Extract top element. Must be used only from one thread. Return true if have more.
+ bool
Pop() noexcept {
if (TEntry* const top = AtomicGet(Front)) {
- const auto last = AtomicCas(&Back, nullptr, top);
- if (last) // This is last element in queue. Queue is empty now.
- AtomicCas(&Front, nullptr, top);
- else // This element is not last.
- for (;;) {
- if (const auto next = AtomicGet(top->Next)) {
- AtomicSet(Front, next);
- break;
- }
- // But Next is null. Wait next assignment in spin lock.
- }
-
- DeleteEntry(top);
- return !last;
- }
-
- return false;
- }
-
- /// Peek top element. Must be used only from one thread.
- ElementType&
+ const auto last = AtomicCas(&Back, nullptr, top);
+ if (last) // This is last element in queue. Queue is empty now.
+ AtomicCas(&Front, nullptr, top);
+ else // This element is not last.
+ for (;;) {
+ if (const auto next = AtomicGet(top->Next)) {
+ AtomicSet(Front, next);
+ break;
+ }
+ // But Next is null. Wait next assignment in spin lock.
+ }
+
+ DeleteEntry(top);
+ return !last;
+ }
+
+ return false;
+ }
+
+ /// Peek top element. Must be used only from one thread.
+ ElementType&
Top() const noexcept {
return AtomicGet(Front)->Data;
- }
-
- bool
+ }
+
+ bool
IsEmpty() const noexcept {
- return !AtomicGet(Front);
- }
-
-protected:
+ return !AtomicGet(Front);
+ }
+
+protected:
class TEntry: private TNonCopyable {
friend class TFunnelQueue;
- private:
- explicit TEntry(ElementType&& element) noexcept
+ private:
+ explicit TEntry(ElementType&& element) noexcept
: Data(static_cast<ElementType&&>(element))
, Next(nullptr)
{
}
-
+
~TEntry() noexcept {
}
-
- public:
- ElementType Data;
+
+ public:
+ ElementType Data;
TEntry* volatile Next;
- };
-
+ };
+
TEntry* volatile Front;
TEntry* volatile Back;
-
+
virtual TEntry* NewEntry(ElementType&& element) noexcept {
- return new TEntry(static_cast<ElementType&&>(element));
- }
-
+ return new TEntry(static_cast<ElementType&&>(element));
+ }
+
virtual TEntry* DeleteEntry(TEntry* entry) noexcept {
- const auto next = entry->Next;
- delete entry;
- return next;
- }
+ const auto next = entry->Next;
+ delete entry;
+ return next;
+ }
protected:
struct TEntryIter {
@@ -166,75 +166,75 @@ public:
const_iterator end() const {
return {nullptr};
}
-};
-
+};
+
template <typename ElementType>
class TPooledFunnelQueue: public TFunnelQueue<ElementType> {
-public:
- TPooledFunnelQueue() noexcept
- : Stack(nullptr)
+public:
+ TPooledFunnelQueue() noexcept
+ : Stack(nullptr)
{
}
-
+
virtual ~TPooledFunnelQueue() noexcept override {
- for (auto entry = TBase::Front; entry; entry = TBase::DeleteEntry(entry))
- continue;
- for (auto entry = Stack; entry; entry = TBase::DeleteEntry(entry))
- continue;
- TBase::Back = TBase::Front = Stack = nullptr;
- }
-
-private:
- typedef TFunnelQueue<ElementType> TBase;
-
+ for (auto entry = TBase::Front; entry; entry = TBase::DeleteEntry(entry))
+ continue;
+ for (auto entry = Stack; entry; entry = TBase::DeleteEntry(entry))
+ continue;
+ TBase::Back = TBase::Front = Stack = nullptr;
+ }
+
+private:
+ typedef TFunnelQueue<ElementType> TBase;
+
typename TBase::TEntry* volatile Stack;
-
-protected:
+
+protected:
virtual typename TBase::TEntry* NewEntry(ElementType&& element) noexcept override {
while (const auto top = AtomicGet(Stack))
if (AtomicCas(&Stack, top->Next, top)) {
- top->Data = static_cast<ElementType&&>(element);
- AtomicSet(top->Next, nullptr);
- return top;
- }
-
- return TBase::NewEntry(static_cast<ElementType&&>(element));
- }
-
+ top->Data = static_cast<ElementType&&>(element);
+ AtomicSet(top->Next, nullptr);
+ return top;
+ }
+
+ return TBase::NewEntry(static_cast<ElementType&&>(element));
+ }
+
virtual typename TBase::TEntry* DeleteEntry(typename TBase::TEntry* entry) noexcept override {
- entry->Data = ElementType();
- const auto next = entry->Next;
+ entry->Data = ElementType();
+ const auto next = entry->Next;
do
AtomicSet(entry->Next, AtomicGet(Stack));
while (!AtomicCas(&Stack, entry, entry->Next));
- return next;
- }
-};
-
+ return next;
+ }
+};
+
template <typename ElementType, template <typename T> class TQueueType = TFunnelQueue>
class TCountedFunnelQueue: public TQueueType<ElementType> {
-public:
- TCountedFunnelQueue() noexcept
- : Count(0)
+public:
+ TCountedFunnelQueue() noexcept
+ : Count(0)
{
}
-
+
TAtomicBase GetSize() const noexcept {
- return AtomicGet(Count);
- }
-
-private:
+ return AtomicGet(Count);
+ }
+
+private:
typedef TQueueType<ElementType> TBase;
-
+
virtual typename TBase::TEntry* NewEntry(ElementType&& element) noexcept override {
- AtomicAdd(Count, 1);
- return TBase::NewEntry(static_cast<ElementType&&>(element));
- }
-
+ AtomicAdd(Count, 1);
+ return TBase::NewEntry(static_cast<ElementType&&>(element));
+ }
+
virtual typename TBase::TEntry* DeleteEntry(typename TBase::TEntry* entry) noexcept override {
- AtomicSub(Count, 1);
- return TBase::DeleteEntry(entry);
- }
-
- TAtomic Count;
-};
+ AtomicSub(Count, 1);
+ return TBase::DeleteEntry(entry);
+ }
+
+ TAtomic Count;
+};
diff --git a/library/cpp/binsaver/bin_saver.h b/library/cpp/binsaver/bin_saver.h
index baf8abfe55..412424889f 100644
--- a/library/cpp/binsaver/bin_saver.h
+++ b/library/cpp/binsaver/bin_saver.h
@@ -147,7 +147,7 @@ private:
TVector<typename AM::key_type, typename std::allocator_traits<typename AM::allocator_type>::template rebind_alloc<typename AM::key_type>> indices;
indices.resize(nSize);
TStoredSize i = 1;
- for (auto pos = data.begin(); pos != data.end(); ++pos, ++i)
+ for (auto pos = data.begin(); pos != data.end(); ++pos, ++i)
indices[nSize - i] = pos->first;
for (TStoredSize j = 0; j < nSize; ++j)
Add(1, &indices[j]);
@@ -155,7 +155,7 @@ private:
Add(2, &data[indices[j]]);
}
}
-
+
// hash_multimap
template <class AMM>
void DoAnyMultiMap(AMM& data) {
@@ -168,7 +168,7 @@ private:
for (TStoredSize i = 0; i < nSize; ++i)
Add(1, &indices[i]);
for (TStoredSize i = 0; i < nSize; ++i) {
- std::pair<typename AMM::key_type, typename AMM::mapped_type> valToInsert;
+ std::pair<typename AMM::key_type, typename AMM::mapped_type> valToInsert;
valToInsert.first = indices[i];
Add(2, &valToInsert.second);
data.insert(valToInsert);
@@ -177,9 +177,9 @@ private:
TStoredSize nSize = data.size();
CheckOverflow(nSize, data.size());
Add(3, &nSize);
- for (auto pos = data.begin(); pos != data.end(); ++pos)
+ for (auto pos = data.begin(); pos != data.end(); ++pos)
Add(1, (typename AMM::key_type*)(&pos->first));
- for (auto pos = data.begin(); pos != data.end(); ++pos)
+ for (auto pos = data.begin(); pos != data.end(); ++pos)
Add(2, &pos->second);
}
}
@@ -345,27 +345,27 @@ public:
template <class T1, class T2, class T3, class T4>
int Add(const chunk_id, TMap<T1, T2, T3, T4>* pMap) {
- DoAnyMap(*pMap);
+ DoAnyMap(*pMap);
return 0;
}
template <class T1, class T2, class T3, class T4, class T5>
int Add(const chunk_id, THashMap<T1, T2, T3, T4, T5>* pHash) {
- DoAnyMap(*pHash);
+ DoAnyMap(*pHash);
return 0;
}
template <class T1, class T2, class T3, class T4, class T5>
int Add(const chunk_id, THashMultiMap<T1, T2, T3, T4, T5>* pHash) {
- DoAnyMultiMap(*pHash);
+ DoAnyMultiMap(*pHash);
return 0;
}
template <class K, class L, class A>
int Add(const chunk_id, TSet<K, L, A>* pSet) {
- DoAnySet(*pSet);
+ DoAnySet(*pSet);
return 0;
}
template <class T1, class T2, class T3, class T4>
int Add(const chunk_id, THashSet<T1, T2, T3, T4>* pHash) {
- DoAnySet(*pHash);
+ DoAnySet(*pHash);
return 0;
}
diff --git a/library/cpp/containers/comptrie/comptrie_trie.h b/library/cpp/containers/comptrie/comptrie_trie.h
index d47aa35587..40ec1e52b3 100644
--- a/library/cpp/containers/comptrie/comptrie_trie.h
+++ b/library/cpp/containers/comptrie/comptrie_trie.h
@@ -279,9 +279,9 @@ TCompactTrie<T, D, S>& TCompactTrie<T, D, S>::operator=(const TCompactTrie& othe
template <class T, class D, class S>
TCompactTrie<T, D, S>& TCompactTrie<T, D, S>::operator=(TCompactTrie&& other) noexcept {
if (this != &other) {
- DataHolder = std::move(other.DataHolder);
- EmptyValue = std::move(other.EmptyValue);
- Packer = std::move(other.Packer);
+ DataHolder = std::move(other.DataHolder);
+ EmptyValue = std::move(other.EmptyValue);
+ Packer = std::move(other.Packer);
}
return *this;
}
diff --git a/library/cpp/containers/comptrie/comptrie_ut.cpp b/library/cpp/containers/comptrie/comptrie_ut.cpp
index cf29b48960..74bee09b5d 100644
--- a/library/cpp/containers/comptrie/comptrie_ut.cpp
+++ b/library/cpp/containers/comptrie/comptrie_ut.cpp
@@ -1385,7 +1385,7 @@ void TCompactTrieTest::TestCopyAndAssignment() {
TTrie assign;
assign = trie;
UNIT_ASSERT(assign.HasCorrectSkipper());
- TTrie move(std::move(trie));
+ TTrie move(std::move(trie));
UNIT_ASSERT(move.HasCorrectSkipper());
TTrie moveAssign;
moveAssign = TTrie(bufout.Buffer().Data(), bufout.Buffer().Size());
diff --git a/library/cpp/dbg_output/dump.h b/library/cpp/dbg_output/dump.h
index 96fddc21e3..c7efa105ee 100644
--- a/library/cpp/dbg_output/dump.h
+++ b/library/cpp/dbg_output/dump.h
@@ -8,7 +8,7 @@
#include <util/stream/format.h>
#include <util/system/type_name.h>
#include <util/generic/hash_set.h>
-#include <utility>
+#include <utility>
/*
* Cout << DbgDump(any) << Endl;
@@ -24,7 +24,7 @@ namespace NPrivate {
struct TDump: public TDumpBase, public TColorSchemeContainer<TColorScheme> {
template <typename... Args>
inline TDump(Args&&... args)
- : TDumpBase(std::forward<Args>(args)...)
+ : TDumpBase(std::forward<Args>(args)...)
{
}
@@ -44,7 +44,7 @@ namespace NPrivate {
struct TDump: public TDumpBase, public TColorSchemeContainer<TColorScheme> {
template <typename... Args>
inline TDump(Args&&... args)
- : TDumpBase(std::forward<Args>(args)...)
+ : TDumpBase(std::forward<Args>(args)...)
{
}
diff --git a/library/cpp/dbg_output/engine.h b/library/cpp/dbg_output/engine.h
index 809361ef80..f13c728c39 100644
--- a/library/cpp/dbg_output/engine.h
+++ b/library/cpp/dbg_output/engine.h
@@ -2,7 +2,7 @@
#include <util/stream/output.h>
-#include <utility>
+#include <utility>
#include <util/generic/strbuf.h>
template <class T>
@@ -23,7 +23,7 @@ namespace NDumpPrivate {
inline T&& operator<<(T&& t, V&& v) {
Dump(t, v);
- return std::forward<T>(t);
+ return std::forward<T>(t);
}
struct TADLBase {
diff --git a/library/cpp/digest/crc32c/crc32c.cpp b/library/cpp/digest/crc32c/crc32c.cpp
index d9e56ec006..369b46a213 100644
--- a/library/cpp/digest/crc32c/crc32c.cpp
+++ b/library/cpp/digest/crc32c/crc32c.cpp
@@ -1,35 +1,35 @@
-#include "crc32c.h"
+#include "crc32c.h"
+
+#include <util/generic/singleton.h>
+
+#include <contrib/libs/crcutil/interface.h>
-#include <util/generic/singleton.h>
-
-#include <contrib/libs/crcutil/interface.h>
-
namespace {
typedef crcutil_interface::CRC TCrc;
struct TCrcUtilSse4 {
TCrc* const Pimpl;
-
- TCrcUtilSse4() noexcept
+
+ TCrcUtilSse4() noexcept
: Pimpl(TCrc::Create(0x82f63b78, 0, 32, true, 0, 0, 0, TCrc::IsSSE42Available(), nullptr))
{
}
-
+
~TCrcUtilSse4() noexcept {
Pimpl->Delete();
}
-
+
inline ui32 Extend(ui32 init, const void* data, size_t n) const noexcept {
crcutil_interface::UINT64 sum = init;
Pimpl->Compute(data, n, &sum);
return (ui32)sum;
}
- };
+ };
}
-
+
ui32 Crc32c(const void* p, size_t size) noexcept {
return Singleton<TCrcUtilSse4>()->Extend(0, p, size);
-}
+}
ui32 Crc32cExtend(ui32 init, const void* data, size_t n) noexcept {
return Singleton<TCrcUtilSse4>()->Extend(init, data, n);
diff --git a/library/cpp/digest/crc32c/crc32c.h b/library/cpp/digest/crc32c/crc32c.h
index 054f65dd83..17b554c8e1 100644
--- a/library/cpp/digest/crc32c/crc32c.h
+++ b/library/cpp/digest/crc32c/crc32c.h
@@ -1,8 +1,8 @@
-#pragma once
-
+#pragma once
+
#include <util/system/types.h>
-
-// Threadsafe
+
+// Threadsafe
ui32 Crc32c(const void* p, size_t size) noexcept;
ui32 Crc32cExtend(ui32 init, const void* data, size_t n) noexcept;
diff --git a/library/cpp/digest/crc32c/ya.make b/library/cpp/digest/crc32c/ya.make
index d07f0a8e75..d6faf16c9c 100644
--- a/library/cpp/digest/crc32c/ya.make
+++ b/library/cpp/digest/crc32c/ya.make
@@ -16,7 +16,7 @@ PEERDIR(
)
SRCS(
- crc32c.cpp
+ crc32c.cpp
)
END()
diff --git a/library/cpp/lfalloc/yt/ya.make b/library/cpp/lfalloc/yt/ya.make
index 4deeac71ef..8c1a4f8a72 100644
--- a/library/cpp/lfalloc/yt/ya.make
+++ b/library/cpp/lfalloc/yt/ya.make
@@ -1,6 +1,6 @@
LIBRARY()
-OWNER(a-romanov)
+OWNER(a-romanov)
NO_UTIL()
@@ -14,9 +14,9 @@ ELSE()
IF ("${YMAKE}" MATCHES "devtools")
CFLAGS(-DYMAKE=1)
ENDIF()
- CXXFLAGS(-DLFALLOC_YT)
+ CXXFLAGS(-DLFALLOC_YT)
SRCS(
- ../lf_allocX64.cpp
+ ../lf_allocX64.cpp
)
ENDIF()
diff --git a/library/cpp/linear_regression/linear_regression.cpp b/library/cpp/linear_regression/linear_regression.cpp
index 6cbbef6f56..150f9d214e 100644
--- a/library/cpp/linear_regression/linear_regression.cpp
+++ b/library/cpp/linear_regression/linear_regression.cpp
@@ -9,7 +9,7 @@
#endif
#include <algorithm>
-#include <functional>
+#include <functional>
namespace {
inline void AddFeaturesProduct(const double weight, const TVector<double>& features, TVector<double>& linearizedOLSTriangleMatrix);
@@ -122,7 +122,7 @@ TLinearModel TFastLinearRegressionSolver::Solve() const {
coefficients.pop_back();
}
- return TLinearModel(std::move(coefficients), intercept);
+ return TLinearModel(std::move(coefficients), intercept);
}
TLinearModel TLinearRegressionSolver::Solve() const {
@@ -134,7 +134,7 @@ TLinearModel TLinearRegressionSolver::Solve() const {
intercept -= FeatureMeans[featureNumber] * coefficients[featureNumber];
}
- return TLinearModel(std::move(coefficients), intercept);
+ return TLinearModel(std::move(coefficients), intercept);
}
double TFastLinearRegressionSolver::SumSquaredErrors() const {
diff --git a/library/cpp/linear_regression/linear_regression.h b/library/cpp/linear_regression/linear_regression.h
index 85da62e6dd..e57de5ff6c 100644
--- a/library/cpp/linear_regression/linear_regression.h
+++ b/library/cpp/linear_regression/linear_regression.h
@@ -206,7 +206,7 @@ public:
bestSolver->Solve(coefficients[bestSolver - SLRSolvers.begin()], intercept, regularizationParameter);
}
- TLinearModel model(std::move(coefficients), intercept);
+ TLinearModel model(std::move(coefficients), intercept);
return model;
}
diff --git a/library/cpp/logger/element.cpp b/library/cpp/logger/element.cpp
index f4114f53cc..b510fe16e1 100644
--- a/library/cpp/logger/element.cpp
+++ b/library/cpp/logger/element.cpp
@@ -1,7 +1,7 @@
#include "log.h"
#include "element.h"
-#include <utility>
+#include <utility>
TLogElement::TLogElement(const TLog* parent)
: Parent_(parent)
diff --git a/library/cpp/logger/element_ut.cpp b/library/cpp/logger/element_ut.cpp
index 730a0cef48..32edc52dfb 100644
--- a/library/cpp/logger/element_ut.cpp
+++ b/library/cpp/logger/element_ut.cpp
@@ -5,7 +5,7 @@
#include <util/generic/string.h>
#include <util/stream/str.h>
#include <util/generic/ptr.h>
-#include <utility>
+#include <utility>
#include <library/cpp/testing/unittest/registar.h>
diff --git a/library/cpp/messagebus/async_result.h b/library/cpp/messagebus/async_result.h
index 1aaa6b26ff..d24dde284a 100644
--- a/library/cpp/messagebus/async_result.h
+++ b/library/cpp/messagebus/async_result.h
@@ -5,8 +5,8 @@
#include <util/system/condvar.h>
#include <util/system/mutex.h>
#include <util/system/yassert.h>
-
-#include <functional>
+
+#include <functional>
// probably this thing should have been called TFuture
template <typename T>
@@ -19,7 +19,7 @@ private:
typedef void TOnResult(const T&);
- std::function<TOnResult> OnResult;
+ std::function<TOnResult> OnResult;
public:
void SetResult(const T& result) {
@@ -48,7 +48,7 @@ public:
onResult(*Result);
} else {
Y_ASSERT(!OnResult);
- OnResult = std::function<TOnResult>(onResult);
+ OnResult = std::function<TOnResult>(onResult);
}
}
};
diff --git a/library/cpp/messagebus/async_result_ut.cpp b/library/cpp/messagebus/async_result_ut.cpp
index 8ef034ef1d..2e96492afd 100644
--- a/library/cpp/messagebus/async_result_ut.cpp
+++ b/library/cpp/messagebus/async_result_ut.cpp
@@ -18,7 +18,7 @@ Y_UNIT_TEST_SUITE(TAsyncResult) {
r.SetResult(17);
- r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1));
+ r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1));
UNIT_ASSERT_VALUES_EQUAL(17, var);
}
@@ -28,7 +28,7 @@ Y_UNIT_TEST_SUITE(TAsyncResult) {
int var = 1;
- r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1));
+ r.AndThen(std::bind(&SetValue, &var, std::placeholders::_1));
r.SetResult(17);
diff --git a/library/cpp/messagebus/session_impl.cpp b/library/cpp/messagebus/session_impl.cpp
index 7b2e4f519e..ddf9f360c4 100644
--- a/library/cpp/messagebus/session_impl.cpp
+++ b/library/cpp/messagebus/session_impl.cpp
@@ -110,7 +110,7 @@ TBusSessionImpl::TBusSessionImpl(bool isSource, TBusMessageQueue* queue, TBusPro
{
Impl->DeadAcceptorStatusSummary.Summary = true;
- ReadEventLoopThread.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TEventLoop::Run, std::ref(ReadEventLoop))));
+ ReadEventLoopThread.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TEventLoop::Run, std::ref(ReadEventLoop))));
WriteEventLoopThread.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TEventLoop::Run, std::ref(WriteEventLoop))));
Queue->Schedule(IScheduleItemAutoPtr(new TScheduleSession(this, TInstant::Now() + Config.Secret.TimeoutPeriod)));
@@ -442,7 +442,7 @@ void TBusSessionImpl::Act(TStatusTag) {
EShutdownState shutdownState = StatusData.ShutdownState.State.Get();
- StatusData.ConnectionsAcceptorsSnapshotsQueue.DequeueAllLikelyEmpty(std::bind(&TBusSessionImpl::ProcessConnectionsAcceptorsShapshotQueueItem, this, std::placeholders::_1));
+ StatusData.ConnectionsAcceptorsSnapshotsQueue.DequeueAllLikelyEmpty(std::bind(&TBusSessionImpl::ProcessConnectionsAcceptorsShapshotQueueItem, this, std::placeholders::_1));
GetDeadConnectionWriterStatusQueue()->DequeueAllLikelyEmpty();
GetDeadConnectionReaderStatusQueue()->DequeueAllLikelyEmpty();
diff --git a/library/cpp/messagebus/test/perftest/perftest.cpp b/library/cpp/messagebus/test/perftest/perftest.cpp
index 2b3b9d2f05..8489319278 100644
--- a/library/cpp/messagebus/test/perftest/perftest.cpp
+++ b/library/cpp/messagebus/test/perftest/perftest.cpp
@@ -658,12 +658,12 @@ int main(int argc, char* argv[]) {
for (int i = 0; i < TheConfig->ClientCount; ++i) {
TGuard<TMutex> guard(ClientsLock);
Clients.push_back(new TPerftestClient);
- futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TPerftestClient::Work, Clients.back())));
+ futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TPerftestClient::Work, Clients.back())));
www->RegisterClientSession(Clients.back()->Session);
}
}
- futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TTestStats::PeriodicallyPrint, std::ref(Stats))));
+ futures.push_back(new NThreading::TLegacyFuture<void, false>(std::bind(&TTestStats::PeriodicallyPrint, std::ref(Stats))));
THolder<TBusWwwHttpServer> wwwServer;
if (TheConfig->WwwPort != 0) {
diff --git a/library/cpp/monlib/counters/counters.h b/library/cpp/monlib/counters/counters.h
index 70985948f9..038b55f0c8 100644
--- a/library/cpp/monlib/counters/counters.h
+++ b/library/cpp/monlib/counters/counters.h
@@ -55,7 +55,7 @@ namespace NMonitoring {
bool ForDerivative() const {
return Derivative;
}
-
+
operator TValueBase() const {
return AtomicGet(Value);
}
diff --git a/library/cpp/monlib/dynamic_counters/counters.cpp b/library/cpp/monlib/dynamic_counters/counters.cpp
index 08eb6faa13..3635d87d0d 100644
--- a/library/cpp/monlib/dynamic_counters/counters.cpp
+++ b/library/cpp/monlib/dynamic_counters/counters.cpp
@@ -157,8 +157,8 @@ void TDynamicCounters::MergeWithSubgroup(const TString& name, const TString& val
Counters.erase(it);
Counters.merge(subgroup->Resign());
AtomicAdd(ExpiringCount, AtomicSwap(&subgroup->ExpiringCount, 0));
-}
-
+}
+
void TDynamicCounters::ResetCounters(bool derivOnly) {
TReadGuard g(Lock);
for (auto& [key, value] : Counters) {
@@ -198,7 +198,7 @@ void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString
output(key.LabelName, key.LabelValue);
}
}
-}
+}
void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) const {
auto snap = ReadSnapshot();
@@ -206,7 +206,7 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent)
auto outputVisibilityMarker = [] (EVisibility vis) {
return vis == EVisibility::Private ? "\t[PRIVATE]" : "";
};
-
+
for (const auto& [key, value] : snap) {
if (const auto counter = AsCounter(value)) {
os << indent
diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h
index fd8f530854..dc178cfbe0 100644
--- a/library/cpp/monlib/dynamic_counters/counters.h
+++ b/library/cpp/monlib/dynamic_counters/counters.h
@@ -12,7 +12,7 @@
#include <util/string/cast.h>
#include <util/system/rwlock.h>
-#include <functional>
+#include <functional>
namespace NMonitoring {
struct TCounterForPtr;
@@ -333,7 +333,7 @@ namespace NMonitoring {
TIntrusivePtr<TDynamicCounters> FindSubgroup(const TString& name, const TString& value) const;
void RemoveSubgroup(const TString& name, const TString& value);
void ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup);
-
+
// Move all counters from specified subgroup and remove the subgroup.
void MergeWithSubgroup(const TString& name, const TString& value);
// Recursively reset all/deriv counters to 0.
diff --git a/library/cpp/monlib/dynamic_counters/page.cpp b/library/cpp/monlib/dynamic_counters/page.cpp
index 0dc63f149e..5124a47bb3 100644
--- a/library/cpp/monlib/dynamic_counters/page.cpp
+++ b/library/cpp/monlib/dynamic_counters/page.cpp
@@ -5,15 +5,15 @@
#include <library/cpp/string_utils/quote/quote.h>
#include <util/string/split.h>
-#include <util/system/tls.h>
+#include <util/system/tls.h>
using namespace NMonitoring;
namespace {
Y_POD_STATIC_THREAD(TDynamicCounters*)
currentCounters(nullptr);
-}
-
+}
+
TMaybe<EFormat> ParseFormat(TStringBuf str) {
if (str == TStringBuf("json")) {
return EFormat::JSON;
@@ -40,38 +40,38 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) {
.Split('/')
.SkipEmpty()
.Collect(&parts);
-
+
TMaybe<EFormat> format = !parts.empty() ? ParseFormat(parts.back()) : Nothing();
if (format) {
- parts.pop_back();
+ parts.pop_back();
}
-
+
if (!parts.empty() && parts.back() == TStringBuf("private")) {
visibility = TCountableBase::EVisibility::Private;
parts.pop_back();
}
- auto counters = Counters;
-
+ auto counters = Counters;
+
for (const auto& escaped : parts) {
const auto part = CGIUnescapeRet(escaped);
TVector<TString> labels;
StringSplitter(part).Split('=').SkipEmpty().Collect(&labels);
-
- if (labels.size() != 2U)
- return NotFound(request);
-
+
+ if (labels.size() != 2U)
+ return NotFound(request);
+
if (const auto child = counters->FindSubgroup(
labels.front(),
labels.back())) {
- counters = child;
+ counters = child;
} else {
return HandleAbsentSubgroup(request);
}
- }
-
+ }
+
if (!format) {
currentCounters = counters.Get();
THtmlMonPage::Output(request);
@@ -94,7 +94,7 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) {
counters->Accept(TString(), TString(), *encoder);
out.Flush();
}
-
+
void TDynamicCountersPage::HandleAbsentSubgroup(IMonHttpRequest& request) {
if (UnknownGroupPolicy == EUnknownGroupPolicy::Error) {
NotFound(request);
@@ -112,7 +112,7 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) {
out << "<a href='" << request.GetPath() << "/json'>Counters as JSON</a>";
out << " for <a href='https://wiki.yandex-team.ru/solomon/'>Solomon</a>";
}
-
+
H5() {
out << "Counters subgroups";
}
@@ -125,15 +125,15 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) {
}
});
}
-
+
H4() {
out << "Counters as text";
}
}
-}
+}
void TDynamicCountersPage::OutputText(IOutputStream& out, IMonHttpRequest&) {
- currentCounters->OutputPlainText(out);
+ currentCounters->OutputPlainText(out);
}
void TDynamicCountersPage::SetUnknownGroupPolicy(EUnknownGroupPolicy value) {
diff --git a/library/cpp/monlib/dynamic_counters/page.h b/library/cpp/monlib/dynamic_counters/page.h
index 61ae703907..1f0ef6a5ea 100644
--- a/library/cpp/monlib/dynamic_counters/page.h
+++ b/library/cpp/monlib/dynamic_counters/page.h
@@ -19,7 +19,7 @@ namespace NMonitoring {
using TOutputCallback = std::function<void()>;
private:
- const TIntrusivePtr<TDynamicCounters> Counters;
+ const TIntrusivePtr<TDynamicCounters> Counters;
TOutputCallback OutputCallback;
EUnknownGroupPolicy UnknownGroupPolicy {EUnknownGroupPolicy::Error};
@@ -40,11 +40,11 @@ namespace NMonitoring {
void Output(NMonitoring::IMonHttpRequest& request) override;
void BeforePre(NMonitoring::IMonHttpRequest& request) override;
-
+
void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override;
/// If set to Error, responds with 404 if the requested subgroup is not found. This is the default.
/// If set to Ignore, responds with 204 if the requested subgroup is not found
void SetUnknownGroupPolicy(EUnknownGroupPolicy value);
- };
+ };
}
diff --git a/library/cpp/monlib/service/monservice.h b/library/cpp/monlib/service/monservice.h
index 543a07d143..8f5e52fcdb 100644
--- a/library/cpp/monlib/service/monservice.h
+++ b/library/cpp/monlib/service/monservice.h
@@ -9,7 +9,7 @@
#include <util/system/progname.h>
-#include <functional>
+#include <functional>
namespace NMonitoring {
class TMonService2: public TMtHttpServer {
diff --git a/library/cpp/monlib/service/pages/html_mon_page.cpp b/library/cpp/monlib/service/pages/html_mon_page.cpp
index 5dc9eed1fd..eb4eb3b66c 100644
--- a/library/cpp/monlib/service/pages/html_mon_page.cpp
+++ b/library/cpp/monlib/service/pages/html_mon_page.cpp
@@ -46,12 +46,12 @@ void THtmlMonPage::Output(NMonitoring::IMonHttpRequest& request) {
}
}
}
-
+
void THtmlMonPage::NotFound(NMonitoring::IMonHttpRequest& request) const {
IOutputStream& out = request.Output();
- out << HTTPNOTFOUND;
- out.Flush();
-}
+ out << HTTPNOTFOUND;
+ out.Flush();
+}
void THtmlMonPage::NoContent(NMonitoring::IMonHttpRequest& request) const {
IOutputStream& out = request.Output();
diff --git a/library/cpp/monlib/service/pages/html_mon_page.h b/library/cpp/monlib/service/pages/html_mon_page.h
index 07fc883f44..e87c53b62b 100644
--- a/library/cpp/monlib/service/pages/html_mon_page.h
+++ b/library/cpp/monlib/service/pages/html_mon_page.h
@@ -16,7 +16,7 @@ namespace NMonitoring {
void NotFound(NMonitoring::IMonHttpRequest& request) const;
void NoContent(NMonitoring::IMonHttpRequest& request) const;
-
+
virtual void OutputContent(NMonitoring::IMonHttpRequest& request) = 0;
bool OutputTableSorterJsCss;
diff --git a/library/cpp/monlib/service/pages/templates.cpp b/library/cpp/monlib/service/pages/templates.cpp
index 132507f68b..ece12bea71 100644
--- a/library/cpp/monlib/service/pages/templates.cpp
+++ b/library/cpp/monlib/service/pages/templates.cpp
@@ -25,9 +25,9 @@ namespace NMonitoring {
extern const char H6Tag[] = "h6";
extern const char SmallTag[] = "small";
extern const char StrongTag[] = "strong";
- extern const char ListTag[] = "li";
- extern const char UListTag[] = "ul";
- extern const char OListTag[] = "ol";
+ extern const char ListTag[] = "li";
+ extern const char UListTag[] = "ul";
+ extern const char OListTag[] = "ol";
extern const char DListTag[] = "dl";
extern const char DTermTag[] = "dt";
extern const char DDescTag[] = "dd";
diff --git a/library/cpp/monlib/service/pages/templates.h b/library/cpp/monlib/service/pages/templates.h
index f9240d968b..b4656f059f 100644
--- a/library/cpp/monlib/service/pages/templates.h
+++ b/library/cpp/monlib/service/pages/templates.h
@@ -70,7 +70,7 @@
#define SMALL() TAG(TSMALL)
#define STRONG() TAG(TSTRONG)
-
+
#define LI() TAG(TLIST)
#define LI_CLASS(cls) TAG_CLASS(TLIST, cls)
#define UL() TAG(TULIST)
@@ -259,9 +259,9 @@ namespace NMonitoring {
typedef TTag<H6Tag> TH6;
typedef TTag<SmallTag> TSMALL;
typedef TTag<StrongTag> TSTRONG;
- typedef TTag<ListTag> TLIST;
- typedef TTag<UListTag> TULIST;
- typedef TTag<OListTag> TOLIST;
+ typedef TTag<ListTag> TLIST;
+ typedef TTag<UListTag> TULIST;
+ typedef TTag<OListTag> TOLIST;
typedef TTag<DListTag> DLIST;
typedef TTag<DTermTag> DTERM;
typedef TTag<DDescTag> DDESC;
diff --git a/library/cpp/monlib/service/service.cpp b/library/cpp/monlib/service/service.cpp
index 8142d16cff..929efbf816 100644
--- a/library/cpp/monlib/service/service.cpp
+++ b/library/cpp/monlib/service/service.cpp
@@ -242,7 +242,7 @@ namespace NMonitoring {
TMonService::TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort,
THandler coHandler, THandler mtHandler)
: CoServer(executor, "127.0.0.1", internalPort, std::move(coHandler))
- , MtServer(THttpServerOptions(externalPort), std::bind(&TMonService::DispatchRequest, this, std::placeholders::_1, std::placeholders::_2))
+ , MtServer(THttpServerOptions(externalPort), std::bind(&TMonService::DispatchRequest, this, std::placeholders::_1, std::placeholders::_2))
, MtHandler(std::move(mtHandler))
{
}
diff --git a/library/cpp/retry/retry.h b/library/cpp/retry/retry.h
index ad09008b69..c47ff5070f 100644
--- a/library/cpp/retry/retry.h
+++ b/library/cpp/retry/retry.h
@@ -8,7 +8,7 @@
#include <util/generic/maybe.h>
#include <util/generic/typetraits.h>
#include <util/generic/yexception.h>
-#include <functional>
+#include <functional>
struct TRetryOptions {
ui32 RetryCount;
diff --git a/library/cpp/scheme/scimpl_defs.h b/library/cpp/scheme/scimpl_defs.h
index 07589b88fb..f3dd66b437 100644
--- a/library/cpp/scheme/scimpl_defs.h
+++ b/library/cpp/scheme/scimpl_defs.h
@@ -12,7 +12,7 @@
#include <util/generic/strbuf.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
-#include <functional>
+#include <functional>
#include <util/string/vector.h>
#include <util/string/type.h>
diff --git a/library/cpp/scheme/scimpl_private.cpp b/library/cpp/scheme/scimpl_private.cpp
index ea404fa036..024bf8cc3b 100644
--- a/library/cpp/scheme/scimpl_private.cpp
+++ b/library/cpp/scheme/scimpl_private.cpp
@@ -1,7 +1,7 @@
#include "scimpl_private.h"
#include <util/generic/algorithm.h>
-#include <utility>
+#include <utility>
namespace NSc {
namespace NImpl {
diff --git a/library/cpp/sighandler/async_signals_handler.cpp b/library/cpp/sighandler/async_signals_handler.cpp
index a6b1b7f088..00ce1c18fb 100644
--- a/library/cpp/sighandler/async_signals_handler.cpp
+++ b/library/cpp/sighandler/async_signals_handler.cpp
@@ -239,7 +239,7 @@ void SetAsyncSignalHandler(int signum, void (*handler)(int)) {
SetAsyncSignalHandler(signum, new TFunctionEventHandler<void (*)(int)>(handler));
}
-void SetAsyncSignalFunction(int signum, std::function<void(int)> func) {
- typedef std::function<void(int)> TFunc;
+void SetAsyncSignalFunction(int signum, std::function<void(int)> func) {
+ typedef std::function<void(int)> TFunc;
SetAsyncSignalHandler(signum, new TFunctionEventHandler<TFunc>(func));
}
diff --git a/library/cpp/sighandler/async_signals_handler.h b/library/cpp/sighandler/async_signals_handler.h
index cee528d229..da36365ace 100644
--- a/library/cpp/sighandler/async_signals_handler.h
+++ b/library/cpp/sighandler/async_signals_handler.h
@@ -1,7 +1,7 @@
#pragma once
#include <util/generic/ptr.h>
-#include <functional>
+#include <functional>
struct TEventHandler {
virtual ~TEventHandler() {
@@ -11,4 +11,4 @@ struct TEventHandler {
void SetAsyncSignalHandler(int signum, TAutoPtr<TEventHandler> handler);
void SetAsyncSignalHandler(int signum, void (*handler)(int));
-void SetAsyncSignalFunction(int signum, std::function<void(int)> func);
+void SetAsyncSignalFunction(int signum, std::function<void(int)> func);
diff --git a/library/cpp/threading/future/legacy_future.h b/library/cpp/threading/future/legacy_future.h
index ce257caa48..6f1eabad73 100644
--- a/library/cpp/threading/future/legacy_future.h
+++ b/library/cpp/threading/future/legacy_future.h
@@ -5,7 +5,7 @@
#include <util/thread/factory.h>
-#include <functional>
+#include <functional>
namespace NThreading {
template <typename TR, bool IgnoreException>
diff --git a/library/cpp/threading/local_executor/local_executor.h b/library/cpp/threading/local_executor/local_executor.h
index 5b8a3b1af9..c1c824f67c 100644
--- a/library/cpp/threading/local_executor/local_executor.h
+++ b/library/cpp/threading/local_executor/local_executor.h
@@ -9,7 +9,7 @@
#include <util/generic/singleton.h>
#include <util/generic/ymath.h>
-#include <functional>
+#include <functional>
namespace NPar {
struct ILocallyExecutable : virtual public TThrRefBase {
diff --git a/library/cpp/threading/poor_man_openmp/thread_helper.h b/library/cpp/threading/poor_man_openmp/thread_helper.h
index a53727e088..0ecee0590b 100644
--- a/library/cpp/threading/poor_man_openmp/thread_helper.h
+++ b/library/cpp/threading/poor_man_openmp/thread_helper.h
@@ -45,7 +45,7 @@ namespace NYmp {
}
template <typename T>
- inline void ParallelForStaticChunk(T begin, T end, size_t chunkSize, std::function<void(T)> func) {
+ inline void ParallelForStaticChunk(T begin, T end, size_t chunkSize, std::function<void(T)> func) {
chunkSize = Max<size_t>(chunkSize, 1);
size_t threadCount = TMtpQueueHelper::Instance().GetThreadCount();
@@ -96,7 +96,7 @@ namespace NYmp {
}
template <typename T>
- inline void ParallelForStaticAutoChunk(T begin, T end, std::function<void(T)> func) {
+ inline void ParallelForStaticAutoChunk(T begin, T end, std::function<void(T)> func) {
const size_t taskSize = end - begin;
const size_t threadCount = TMtpQueueHelper::Instance().GetThreadCount();
diff --git a/library/cpp/threading/skip_list/perf/main.cpp b/library/cpp/threading/skip_list/perf/main.cpp
index 9b25574277..4ad52049e7 100644
--- a/library/cpp/threading/skip_list/perf/main.cpp
+++ b/library/cpp/threading/skip_list/perf/main.cpp
@@ -6,7 +6,7 @@
#include <util/datetime/base.h>
#include <util/generic/map.h>
#include <util/generic/vector.h>
-#include <functional>
+#include <functional>
#include <util/memory/pool.h>
#include <util/random/random.h>
#include <util/string/join.h>
diff --git a/library/cpp/xml/document/xml-textreader.h b/library/cpp/xml/document/xml-textreader.h
index bed5fbe0c2..ab4c329d26 100644
--- a/library/cpp/xml/document/xml-textreader.h
+++ b/library/cpp/xml/document/xml-textreader.h
@@ -11,7 +11,7 @@
#include <util/generic/ptr.h>
#include <util/generic/strbuf.h>
#include <util/generic/string.h>
-#include <functional>
+#include <functional>
#include <util/stream/input.h>
#include <util/stream/str.h>
diff --git a/library/cpp/xml/document/xml-textreader_ut.cpp b/library/cpp/xml/document/xml-textreader_ut.cpp
index 0f1b553911..6232dfe47e 100644
--- a/library/cpp/xml/document/xml-textreader_ut.cpp
+++ b/library/cpp/xml/document/xml-textreader_ut.cpp
@@ -11,7 +11,7 @@ namespace {
* Simple wrapper around the xmlTextReader wrapper
*/
void ParseXml(const TString& xmlData,
- std::function<void(NXml::TConstNode)> nodeHandlerFunc,
+ std::function<void(NXml::TConstNode)> nodeHandlerFunc,
const TString& localName,
const TString& namespaceUri = TString()) {
TStringInput in(xmlData);
diff --git a/library/cpp/yson/node/node_builder.cpp b/library/cpp/yson/node/node_builder.cpp
index 6bb2dcd832..b4431bc77a 100644
--- a/library/cpp/yson/node/node_builder.cpp
+++ b/library/cpp/yson/node/node_builder.cpp
@@ -86,7 +86,7 @@ void TNodeBuilder::OnNode(TNode node)
void TNodeBuilder::AddNode(TNode value, bool pop)
{
- Stack_.top()->MoveWithoutAttributes(std::move(value));
+ Stack_.top()->MoveWithoutAttributes(std::move(value));
if (pop)
Stack_.pop();
}
diff --git a/library/cpp/yson_pull/detail/reader.h b/library/cpp/yson_pull/detail/reader.h
index a26f18032a..0e02396358 100644
--- a/library/cpp/yson_pull/detail/reader.h
+++ b/library/cpp/yson_pull/detail/reader.h
@@ -657,12 +657,12 @@ namespace NYsonPull {
yield(lexer_.read_percent_scalar());
break;
- case char_class::none:
- COLD_BLOCK_BYVALUE
- lexer_.fail("Invalid yson value.");
- COLD_BLOCK_END
- break;
-
+ case char_class::none:
+ COLD_BLOCK_BYVALUE
+ lexer_.fail("Invalid yson value.");
+ COLD_BLOCK_END
+ break;
+
default:
Y_UNREACHABLE();
}
diff --git a/library/cpp/yson_pull/ut/reader_ut.cpp b/library/cpp/yson_pull/ut/reader_ut.cpp
index 3cc83ae9fa..1184265ddb 100644
--- a/library/cpp/yson_pull/ut/reader_ut.cpp
+++ b/library/cpp/yson_pull/ut/reader_ut.cpp
@@ -348,8 +348,8 @@ Y_UNIT_TEST_SUITE(Reader) {
REJECT("<a=b>");
REJECT("<>");
-
- REJECT("@");
+
+ REJECT("@");
}
Y_UNIT_TEST(ReadPastEnd) {
diff --git a/util/generic/bt_exception.h b/util/generic/bt_exception.h
index 72acee7d53..018d2bc89a 100644
--- a/util/generic/bt_exception.h
+++ b/util/generic/bt_exception.h
@@ -1,6 +1,6 @@
#pragma once
-#include <utility>
+#include <utility>
#include "yexception.h"
#include <util/system/backtrace.h>
@@ -10,7 +10,7 @@ class TWithBackTrace: public T {
public:
template <typename... Args>
inline TWithBackTrace(Args&&... args)
- : T(std::forward<Args>(args)...)
+ : T(std::forward<Args>(args)...)
{
BT_.Capture();
}
diff --git a/util/generic/buffer.cpp b/util/generic/buffer.cpp
index eac45a1248..b92697e1d0 100644
--- a/util/generic/buffer.cpp
+++ b/util/generic/buffer.cpp
@@ -58,20 +58,20 @@ void TBuffer::Append(const char* buf, size_t len) {
Y_ASSERT(Pos_ <= Len_);
}
-void TBuffer::Fill(char ch, size_t len) {
- if (len > Avail()) {
- Reserve(Pos_ + len);
- }
-
- Y_ASSERT(len <= Avail());
-
- memset(Data() + Pos_, ch, len);
- NSan::Unpoison(Data() + Pos_, len);
- Pos_ += len;
-
- Y_ASSERT(Pos_ <= Len_);
-}
-
+void TBuffer::Fill(char ch, size_t len) {
+ if (len > Avail()) {
+ Reserve(Pos_ + len);
+ }
+
+ Y_ASSERT(len <= Avail());
+
+ memset(Data() + Pos_, ch, len);
+ NSan::Unpoison(Data() + Pos_, len);
+ Pos_ += len;
+
+ Y_ASSERT(Pos_ <= Len_);
+}
+
void TBuffer::DoReserve(size_t realLen) {
// FastClp2<T>(x) returns 0 on x from [Max<T>/2 + 2, Max<T>]
const size_t len = Max<size_t>(FastClp2(realLen), realLen);
diff --git a/util/generic/buffer.h b/util/generic/buffer.h
index ccedad535e..9576467404 100644
--- a/util/generic/buffer.h
+++ b/util/generic/buffer.h
@@ -106,30 +106,30 @@ public:
*(Data() + Pos_++) = ch;
}
- void Fill(char ch, size_t len);
-
+ void Fill(char ch, size_t len);
+
// Method is useful when first messages from buffer are processed, and
// the last message in buffer is incomplete, so we need to move partial
// message to the begin of the buffer and continue filling the buffer
// from the network.
- inline void Chop(size_t pos, size_t count) {
- const auto end = pos + count;
- Y_ASSERT(end <= Pos_);
+ inline void Chop(size_t pos, size_t count) {
+ const auto end = pos + count;
+ Y_ASSERT(end <= Pos_);
if (count == 0) {
return;
} else if (count == Pos_) {
Pos_ = 0;
} else {
- memmove(Data_ + pos, Data_ + end, Pos_ - end);
- Pos_ -= count;
+ memmove(Data_ + pos, Data_ + end, Pos_ - end);
+ Pos_ -= count;
}
}
- inline void ChopHead(size_t count) {
- Chop(0U, count);
- }
-
+ inline void ChopHead(size_t count) {
+ Chop(0U, count);
+ }
+
inline void Proceed(size_t pos) {
//Y_ASSERT(pos <= Len_); // see discussion in REVIEW:29021
Resize(pos);
diff --git a/util/generic/buffer_ut.cpp b/util/generic/buffer_ut.cpp
index 46da4d8674..437d7122ec 100644
--- a/util/generic/buffer_ut.cpp
+++ b/util/generic/buffer_ut.cpp
@@ -178,14 +178,14 @@ Y_UNIT_TEST(TestSpeed) {
UNIT_ASSERT(t1 < t2);
}
#endif
-
+
Y_UNIT_TEST(TestFillAndChop) {
TBuffer buf;
buf.Append("Some ", 5);
buf.Fill('!', 5);
buf.Append(" text.", 6);
UNIT_ASSERT_VALUES_EQUAL(TString(buf.data(), buf.size()), "Some !!!!! text.");
-
+
buf.Chop(5, 6);
UNIT_ASSERT_VALUES_EQUAL(TString(buf.data(), buf.size()), "Some text.");
}
diff --git a/util/generic/deque_ut.cpp b/util/generic/deque_ut.cpp
index 62665ce409..93bf50fa92 100644
--- a/util/generic/deque_ut.cpp
+++ b/util/generic/deque_ut.cpp
@@ -2,7 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <utility>
+#include <utility>
#include "yexception.h"
class TDequeTest: public TTestBase {
@@ -40,7 +40,7 @@ void TDequeTest::TestConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(100, c1.at(0));
UNIT_ASSERT_VALUES_EQUAL(200, c2.at(1));
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -54,7 +54,7 @@ void TDequeTest::TestConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(300, c3.at(2));
c2.push_back(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
diff --git a/util/generic/function_ut.cpp b/util/generic/function_ut.cpp
index 903a581fea..3880295a9f 100644
--- a/util/generic/function_ut.cpp
+++ b/util/generic/function_ut.cpp
@@ -35,7 +35,7 @@ Y_UNIT_TEST_SUITE(TestFunctionSignature) {
}
Y_UNIT_TEST(TestFunction) {
- std::function<int(double)> f(FF);
+ std::function<int(double)> f(FF);
UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(f)>, decltype(FF));
}
diff --git a/util/generic/hash.h b/util/generic/hash.h
index f590fbb2cb..e46db21fa9 100644
--- a/util/generic/hash.h
+++ b/util/generic/hash.h
@@ -463,7 +463,7 @@ public:
using hasher = HashFcn;
using key_equal = EqualKey;
using key_extract = ExtractKey;
- using allocator_type = Alloc;
+ using allocator_type = Alloc;
using node_allocator_type = typename traits_type::node_allocator_type;
using size_type = size_t;
@@ -482,7 +482,7 @@ public:
key_equal key_eq() const {
return this->_get_key_eq();
}
- hasher hash_function() const {
+ hasher hash_function() const {
return this->_get_hash_fun();
}
@@ -659,7 +659,7 @@ public:
return buckets.size();
} /*y*/
- size_type bucket_size(size_type bucket) const {
+ size_type bucket_size(size_type bucket) const {
size_type result = 0;
if (const node* cur = buckets[bucket])
for (; !((uintptr_t)cur & 1); cur = cur->next)
@@ -669,19 +669,19 @@ public:
template <class OtherValue>
std::pair<iterator, bool> insert_unique(const OtherValue& obj) {
- reserve(num_elements + 1);
+ reserve(num_elements + 1);
return insert_unique_noresize(obj);
}
template <class OtherValue>
iterator insert_equal(const OtherValue& obj) {
- reserve(num_elements + 1);
+ reserve(num_elements + 1);
return emplace_equal_noresize(obj);
}
template <typename... Args>
iterator emplace_equal(Args&&... args) {
- reserve(num_elements + 1);
+ reserve(num_elements + 1);
return emplace_equal_noresize(std::forward<Args>(args)...);
}
@@ -692,7 +692,7 @@ public:
template <typename... Args>
iterator emplace_direct(insert_ctx ins, Args&&... args) {
- bool resized = reserve(num_elements + 1);
+ bool resized = reserve(num_elements + 1);
node* tmp = new_node(std::forward<Args>(args)...);
if (resized) {
find_i(get_key(tmp->val), ins);
@@ -705,7 +705,7 @@ public:
template <typename... Args>
std::pair<iterator, bool> emplace_unique(Args&&... args) {
- reserve(num_elements + 1);
+ reserve(num_elements + 1);
return emplace_unique_noresize(std::forward<Args>(args)...);
}
@@ -744,7 +744,7 @@ public:
void insert_unique(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag) {
difference_type n = std::distance(f, l);
- reserve(num_elements + n);
+ reserve(num_elements + n);
for (; n > 0; --n, ++f)
insert_unique_noresize(*f);
}
@@ -753,7 +753,7 @@ public:
void insert_equal(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag) {
difference_type n = std::distance(f, l);
- reserve(num_elements + n);
+ reserve(num_elements + n);
for (; n > 0; --n, ++f)
emplace_equal_noresize(*f);
}
@@ -819,7 +819,7 @@ public:
void erase(const const_iterator& it);
void erase(const_iterator first, const_iterator last);
- bool reserve(size_type num_elements_hint);
+ bool reserve(size_type num_elements_hint);
void basic_clear();
/**
@@ -1065,7 +1065,7 @@ __yhashtable_iterator<V> THashTable<V, K, HF, Ex, Eq, A>::emplace_equal_noresize
template <class V, class K, class HF, class Ex, class Eq, class A>
template <class OtherValue>
typename THashTable<V, K, HF, Ex, Eq, A>::reference THashTable<V, K, HF, Ex, Eq, A>::find_or_insert(const OtherValue& v) {
- reserve(num_elements + 1);
+ reserve(num_elements + 1);
size_type n = bkt_num_key(get_key(v));
node* first = buckets[n];
@@ -1432,7 +1432,7 @@ public:
using value_type = typename ht::value_type;
using hasher = typename ht::hasher;
using key_equal = typename ht::key_equal;
- using allocator_type = typename ht::allocator_type;
+ using allocator_type = typename ht::allocator_type;
using node_allocator_type = typename ht::node_allocator_type;
using mapped_type = T;
@@ -1447,8 +1447,8 @@ public:
using const_iterator = typename ht::const_iterator;
using insert_ctx = typename ht::insert_ctx;
- hasher hash_function() const {
- return rep.hash_function();
+ hasher hash_function() const {
+ return rep.hash_function();
}
key_equal key_eq() const {
return rep.key_eq();
@@ -1717,14 +1717,14 @@ public:
}
public:
- void reserve(size_type hint) {
- rep.reserve(hint);
+ void reserve(size_type hint) {
+ rep.reserve(hint);
}
size_type bucket_count() const {
return rep.bucket_count();
}
- size_type bucket_size(size_type n) const {
- return rep.bucket_size(n);
+ size_type bucket_size(size_type n) const {
+ return rep.bucket_size(n);
}
node_allocator_type& GetNodeAllocator() {
return rep.GetNodeAllocator();
@@ -1765,7 +1765,7 @@ public:
using hasher = typename ht::hasher;
using key_equal = typename ht::key_equal;
using mapped_type = T;
- using allocator_type = typename ht::allocator_type;
+ using allocator_type = typename ht::allocator_type;
using size_type = typename ht::size_type;
using difference_type = typename ht::difference_type;
@@ -1778,8 +1778,8 @@ public:
using const_iterator = typename ht::const_iterator;
using insert_ctx = typename ht::insert_ctx;
- hasher hash_function() const {
- return rep.hash_function();
+ hasher hash_function() const {
+ return rep.hash_function();
}
key_equal key_eq() const {
return rep.key_eq();
@@ -1983,14 +1983,14 @@ public:
}
public:
- void reserve(size_type hint) {
- rep.reserve(hint);
+ void reserve(size_type hint) {
+ rep.reserve(hint);
}
size_type bucket_count() const {
return rep.bucket_count();
}
- size_type bucket_size(size_type n) const {
- return rep.bucket_size(n);
+ size_type bucket_size(size_type n) const {
+ return rep.bucket_size(n);
}
};
diff --git a/util/generic/hash_set.h b/util/generic/hash_set.h
index dc9cfda3a9..e8088cf23b 100644
--- a/util/generic/hash_set.h
+++ b/util/generic/hash_set.h
@@ -21,7 +21,7 @@ public:
using value_type = typename ht::value_type;
using hasher = typename ht::hasher;
using key_equal = typename ht::key_equal;
- using allocator_type = typename ht::allocator_type;
+ using allocator_type = typename ht::allocator_type;
using node_allocator_type = typename ht::node_allocator_type;
using size_type = typename ht::size_type;
@@ -35,8 +35,8 @@ public:
using const_iterator = typename ht::const_iterator;
using insert_ctx = typename ht::insert_ctx;
- hasher hash_function() const {
- return rep.hash_function();
+ hasher hash_function() const {
+ return rep.hash_function();
}
key_equal key_eq() const {
return rep.key_eq();
@@ -246,14 +246,14 @@ public:
}
public:
- void reserve(size_type hint) {
- rep.reserve(hint);
+ void reserve(size_type hint) {
+ rep.reserve(hint);
}
size_type bucket_count() const {
return rep.bucket_count();
}
- size_type bucket_size(size_type n) const {
- return rep.bucket_size(n);
+ size_type bucket_size(size_type n) const {
+ return rep.bucket_size(n);
}
node_allocator_type& GetNodeAllocator() {
return rep.GetNodeAllocator();
@@ -289,7 +289,7 @@ public:
using value_type = typename ht::value_type;
using hasher = typename ht::hasher;
using key_equal = typename ht::key_equal;
- using allocator_type = typename ht::allocator_type;
+ using allocator_type = typename ht::allocator_type;
using node_allocator_type = typename ht::node_allocator_type;
using size_type = typename ht::size_type;
@@ -302,8 +302,8 @@ public:
using iterator = typename ht::const_iterator;
using const_iterator = typename ht::const_iterator;
- hasher hash_function() const {
- return rep.hash_function();
+ hasher hash_function() const {
+ return rep.hash_function();
}
key_equal key_eq() const {
return rep.key_eq();
@@ -449,14 +449,14 @@ public:
}
public:
- void reserve(size_type hint) {
- rep.reserve(hint);
+ void reserve(size_type hint) {
+ rep.reserve(hint);
}
size_type bucket_count() const {
return rep.bucket_count();
}
- size_type bucket_size(size_type n) const {
- return rep.bucket_size(n);
+ size_type bucket_size(size_type n) const {
+ return rep.bucket_size(n);
}
node_allocator_type& GetNodeAllocator() {
return rep.GetNodeAllocator();
diff --git a/util/generic/hash_ut.cpp b/util/generic/hash_ut.cpp
index 9d52acafb4..0551d58770 100644
--- a/util/generic/hash_ut.cpp
+++ b/util/generic/hash_ut.cpp
@@ -5,7 +5,7 @@
#include <library/cpp/testing/common/probe.h>
#include <library/cpp/testing/unittest/registar.h>
-#include <utility>
+#include <utility>
#include <util/str_stl.h>
#include <util/digest/multi.h>
@@ -128,7 +128,7 @@ void THashTest::TestHMapConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(1, c1.at("one")); /* Note: fails under MSVC since it does not support implicit generation of move constructors. */
UNIT_ASSERT_VALUES_EQUAL(2, c2.at("two"));
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -142,7 +142,7 @@ void THashTest::TestHMapConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(3, c3.at("three"));
c2["four"] = 4;
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
@@ -272,7 +272,7 @@ void THashTest::TestHMMapConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(2, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c2.size());
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -284,7 +284,7 @@ void THashTest::TestHMMapConstructorsAndAssignments() {
UNIT_ASSERT_VALUES_EQUAL(3, c3.size());
c2.insert(container::value_type("four", 4));
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
@@ -380,7 +380,7 @@ void THashTest::TestHSetConstructorsAndAssignments() {
UNIT_ASSERT(c1.contains(100));
UNIT_ASSERT(c2.contains(200));
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -394,7 +394,7 @@ void THashTest::TestHSetConstructorsAndAssignments() {
UNIT_ASSERT(c3.contains(300));
c2.insert(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
@@ -471,7 +471,7 @@ void THashTest::TestHMSetConstructorsAndAssignments() {
UNIT_ASSERT(c1.find(100) != c1.end());
UNIT_ASSERT(c2.find(200) != c2.end());
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -485,7 +485,7 @@ void THashTest::TestHMSetConstructorsAndAssignments() {
UNIT_ASSERT(c3.find(300) != c3.end());
c2.insert(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
diff --git a/util/generic/lazy_value.h b/util/generic/lazy_value.h
index 368689a147..3c720f76b5 100644
--- a/util/generic/lazy_value.h
+++ b/util/generic/lazy_value.h
@@ -6,7 +6,7 @@
template <class T>
class TLazyValueBase {
public:
- using TInitializer = std::function<T()>;
+ using TInitializer = std::function<T()>;
TLazyValueBase() = default;
diff --git a/util/generic/maybe.h b/util/generic/maybe.h
index b306726214..34d21aebcd 100644
--- a/util/generic/maybe.h
+++ b/util/generic/maybe.h
@@ -1,6 +1,6 @@
#pragma once
-#include <utility>
+#include <utility>
#include "maybe_traits.h"
#include "yexception.h"
@@ -443,7 +443,7 @@ private:
template <typename... Args>
void Init(Args&&... args) {
- new (Data()) T(std::forward<Args>(args)...);
+ new (Data()) T(std::forward<Args>(args)...);
this->Defined_ = true;
}
};
diff --git a/util/generic/ptr.h b/util/generic/ptr.h
index 9150e62d6f..19db0e3ec5 100644
--- a/util/generic/ptr.h
+++ b/util/generic/ptr.h
@@ -7,7 +7,7 @@
#include "typetraits.h"
#include "singleton.h"
-#include <utility>
+#include <utility>
#include <util/system/yassert.h>
#include <util/system/defaults.h>
@@ -780,7 +780,7 @@ typename TSimpleIntrusiveOps<T, Ops>::TFunc TSimpleIntrusiveOps<T, Ops>::UnRef_
template <typename T, class Ops = TDefaultIntrusivePtrOps<T>, typename... Args>
[[nodiscard]] TIntrusivePtr<T, Ops> MakeIntrusive(Args&&... args) {
- return new T{std::forward<Args>(args)...};
+ return new T{std::forward<Args>(args)...};
}
template <typename T, class Ops = TDefaultIntrusivePtrOps<T>, typename... Args>
@@ -949,17 +949,17 @@ using TSimpleSharedPtr = TSharedPtr<T, TSimpleCounter, D>;
template <typename T, typename C, typename... Args>
[[nodiscard]] TSharedPtr<T, C> MakeShared(Args&&... args) {
- return new T{std::forward<Args>(args)...};
+ return new T{std::forward<Args>(args)...};
}
template <typename T, typename... Args>
[[nodiscard]] inline TAtomicSharedPtr<T> MakeAtomicShared(Args&&... args) {
- return MakeShared<T, TAtomicCounter>(std::forward<Args>(args)...);
+ return MakeShared<T, TAtomicCounter>(std::forward<Args>(args)...);
}
template <typename T, typename... Args>
[[nodiscard]] inline TSimpleSharedPtr<T> MakeSimpleShared(Args&&... args) {
- return MakeShared<T, TSimpleCounter>(std::forward<Args>(args)...);
+ return MakeShared<T, TSimpleCounter>(std::forward<Args>(args)...);
}
class TCopyClone {
diff --git a/util/generic/queue_ut.cpp b/util/generic/queue_ut.cpp
index 96e40224ca..a33399e104 100644
--- a/util/generic/queue_ut.cpp
+++ b/util/generic/queue_ut.cpp
@@ -4,7 +4,7 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <utility>
+#include <utility>
Y_UNIT_TEST_SUITE(TYQueueTest) {
Y_UNIT_TEST(ConstructorsAndAssignments) {
@@ -22,7 +22,7 @@ Y_UNIT_TEST_SUITE(TYQueueTest) {
UNIT_ASSERT_VALUES_EQUAL(2, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c2.size());
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -34,7 +34,7 @@ Y_UNIT_TEST_SUITE(TYQueueTest) {
UNIT_ASSERT_VALUES_EQUAL(3, c3.size());
c2.push(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
@@ -54,7 +54,7 @@ Y_UNIT_TEST_SUITE(TYQueueTest) {
UNIT_ASSERT_VALUES_EQUAL(2, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c2.size());
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -66,7 +66,7 @@ Y_UNIT_TEST_SUITE(TYQueueTest) {
UNIT_ASSERT_VALUES_EQUAL(3, c3.size());
c2.push(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
diff --git a/util/generic/set_ut.cpp b/util/generic/set_ut.cpp
index 825840630a..d2769d327f 100644
--- a/util/generic/set_ut.cpp
+++ b/util/generic/set_ut.cpp
@@ -2,7 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <utility>
+#include <utility>
#include <algorithm>
@@ -206,7 +206,7 @@ Y_UNIT_TEST_SUITE(YSetTest) {
UNIT_ASSERT(c1.contains(100));
UNIT_ASSERT(c2.contains(200));
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -220,7 +220,7 @@ Y_UNIT_TEST_SUITE(YSetTest) {
UNIT_ASSERT(c3.contains(300));
c2.insert(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
@@ -241,7 +241,7 @@ Y_UNIT_TEST_SUITE(YSetTest) {
UNIT_ASSERT(c1.find(100) != c1.end());
UNIT_ASSERT(c2.find(200) != c2.end());
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -255,7 +255,7 @@ Y_UNIT_TEST_SUITE(YSetTest) {
UNIT_ASSERT(c3.find(300) != c3.end());
c2.insert(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
diff --git a/util/generic/store_policy.h b/util/generic/store_policy.h
index 10d8ecb0a7..148821c70c 100644
--- a/util/generic/store_policy.h
+++ b/util/generic/store_policy.h
@@ -1,13 +1,13 @@
#pragma once
-#include <utility>
+#include <utility>
#include "ptr.h"
template <class TBase, class TCounter>
struct TWithRefCount: public TBase, public TRefCounted<TWithRefCount<TBase, TCounter>, TCounter> {
template <typename... Args>
inline TWithRefCount(Args&&... args)
- : TBase(std::forward<Args>(args)...)
+ : TBase(std::forward<Args>(args)...)
{
}
};
@@ -34,7 +34,7 @@ template <class T>
struct TEmbedPolicy {
template <typename... Args>
inline TEmbedPolicy(Args&&... args)
- : T_(std::forward<Args>(args)...)
+ : T_(std::forward<Args>(args)...)
{
}
@@ -55,7 +55,7 @@ struct TRefPolicy {
template <typename... Args>
inline TRefPolicy(Args&&... args)
- : T_(new THelper(std::forward<Args>(args)...))
+ : T_(new THelper(std::forward<Args>(args)...))
{
}
diff --git a/util/generic/vector_ut.cpp b/util/generic/vector_ut.cpp
index dbb51ac5fc..0f6b4037a0 100644
--- a/util/generic/vector_ut.cpp
+++ b/util/generic/vector_ut.cpp
@@ -2,7 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <utility>
+#include <utility>
#include "yexception.h"
#include <stdexcept>
@@ -47,7 +47,7 @@ private:
UNIT_ASSERT_VALUES_EQUAL(100, c1.at(0));
UNIT_ASSERT_VALUES_EQUAL(200, c2.at(1));
- container c3(std::move(c1));
+ container c3(std::move(c1));
UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
@@ -61,7 +61,7 @@ private:
UNIT_ASSERT_VALUES_EQUAL(300, c3.at(2));
c2.push_back(400);
- c3 = std::move(c2);
+ c3 = std::move(c2);
UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
diff --git a/util/generic/yexception.h b/util/generic/yexception.h
index e4f1129524..b0c604e8c4 100644
--- a/util/generic/yexception.h
+++ b/util/generic/yexception.h
@@ -5,7 +5,7 @@
#include "string.h"
#include "utility.h"
#include "va_args.h"
-#include <utility>
+#include <utility>
#include <util/stream/tempbuf.h>
#include <util/system/compat.h>
@@ -70,7 +70,7 @@ namespace NPrivateException {
operator<<(E&& e, const T& t) {
e.Append(t);
- return std::forward<E>(e);
+ return std::forward<E>(e);
}
template <class T>
diff --git a/util/memory/pool.h b/util/memory/pool.h
index efc20f0fc5..13c8b6b9ed 100644
--- a/util/memory/pool.h
+++ b/util/memory/pool.h
@@ -12,7 +12,7 @@
#include <new>
#include <string>
-#include <utility>
+#include <utility>
/**
* Memory pool implements a memory allocation scheme that is very fast, but
@@ -191,7 +191,7 @@ public:
template <typename T, typename... Args>
inline T* New(Args&&... args) {
- return new (Allocate<T>()) T(std::forward<Args>(args)...);
+ return new (Allocate<T>()) T(std::forward<Args>(args)...);
}
template <typename T>
diff --git a/util/memory/tempbuf.cpp b/util/memory/tempbuf.cpp
index 6c60ebaf71..09a2d0f140 100644
--- a/util/memory/tempbuf.cpp
+++ b/util/memory/tempbuf.cpp
@@ -7,7 +7,7 @@
#include <util/generic/intrlist.h>
#include <util/generic/singleton.h>
#include <util/generic/yexception.h>
-#include <utility>
+#include <utility>
#include <util/thread/singleton.h>
#ifndef TMP_BUF_LEN
@@ -197,7 +197,7 @@ TTempBuf::TTempBuf(size_t len)
TTempBuf::TTempBuf(const TTempBuf&) noexcept = default;
TTempBuf::TTempBuf(TTempBuf&& b) noexcept
- : Impl_(std::move(b.Impl_))
+ : Impl_(std::move(b.Impl_))
{
}
diff --git a/util/memory/tempbuf_ut.cpp b/util/memory/tempbuf_ut.cpp
index b4774b7b05..d6bcf9d546 100644
--- a/util/memory/tempbuf_ut.cpp
+++ b/util/memory/tempbuf_ut.cpp
@@ -1,6 +1,6 @@
#include "tempbuf.h"
-#include <utility>
+#include <utility>
#include <library/cpp/testing/unittest/registar.h>
@@ -71,7 +71,7 @@ void TTempBufTest::TestMoveCtor() {
src.Proceed(10);
- TTempBuf dst(std::move(src));
+ TTempBuf dst(std::move(src));
UNIT_ASSERT(src.IsNull());
UNIT_ASSERT(!dst.IsNull());
diff --git a/util/random/lcg_engine.h b/util/random/lcg_engine.h
index 8cb8431c55..08cc93c845 100644
--- a/util/random/lcg_engine.h
+++ b/util/random/lcg_engine.h
@@ -1,6 +1,6 @@
#pragma once
-#include <utility>
+#include <utility>
#include <util/generic/typetraits.h>
// common engine for lcg-based RNG's
@@ -49,7 +49,7 @@ struct TLcgRngBase: public TIterator, public TMixer {
template <typename... Args>
inline TLcgRngBase(TStateType seed, Args&&... args)
- : TIterator(std::forward<Args>(args)...)
+ : TIterator(std::forward<Args>(args)...)
, X(seed)
{
}
diff --git a/util/stream/buffered.h b/util/stream/buffered.h
index 6ca2939508..0847186141 100644
--- a/util/stream/buffered.h
+++ b/util/stream/buffered.h
@@ -3,7 +3,7 @@
#include "zerocopy.h"
#include "zerocopy_output.h"
-#include <utility>
+#include <utility>
#include <util/generic/ptr.h>
#include <util/generic/typetraits.h>
#include <util/generic/store_policy.h>
@@ -188,7 +188,7 @@ class TBuffered: private TEmbedPolicy<TSlave>, public ::NPrivate::TBufferedStrea
public:
template <typename... Args>
inline TBuffered(size_t b, Args&&... args)
- : TSlaveBase(std::forward<Args>(args)...)
+ : TSlaveBase(std::forward<Args>(args)...)
, TBufferedBase(TSlaveBase::Ptr(), b)
{
}
@@ -221,7 +221,7 @@ class TAdaptivelyBuffered: private TEmbedPolicy<TSlave>, public TAdaptiveBuffere
public:
template <typename... Args>
inline TAdaptivelyBuffered(Args&&... args)
- : TSlaveBase(std::forward<Args>(args)...)
+ : TSlaveBase(std::forward<Args>(args)...)
, TAdaptiveBufferedOutput(TSlaveBase::Ptr())
{
}
diff --git a/util/stream/file.h b/util/stream/file.h
index 3e4865c1cd..c1cf4f591d 100644
--- a/util/stream/file.h
+++ b/util/stream/file.h
@@ -7,7 +7,7 @@
#include "mem.h"
#include <util/system/file.h>
-#include <utility>
+#include <utility>
/**
* @addtogroup Streams_Files
diff --git a/util/stream/holder.h b/util/stream/holder.h
index 0795320455..c60a4e510c 100644
--- a/util/stream/holder.h
+++ b/util/stream/holder.h
@@ -2,7 +2,7 @@
#include <util/generic/ptr.h>
-#include <utility>
+#include <utility>
#include <type_traits>
class IInputStream;
diff --git a/util/string/builder.h b/util/string/builder.h
index bff7909974..7b54821151 100644
--- a/util/string/builder.h
+++ b/util/string/builder.h
@@ -1,7 +1,7 @@
#pragma once
#include <util/stream/str.h>
-#include <utility>
+#include <utility>
#include <util/generic/string.h>
namespace NPrivateStringBuilder {
@@ -32,7 +32,7 @@ namespace NPrivateStringBuilder {
static inline TStringBuilder&& operator<<(TStringBuilder&& builder, const T& t) {
builder.Out << t;
- return std::move(builder);
+ return std::move(builder);
}
}
diff --git a/util/string/strip.h b/util/string/strip.h
index edba5bb40c..d5ef6da96d 100644
--- a/util/string/strip.h
+++ b/util/string/strip.h
@@ -4,7 +4,7 @@
#include <util/generic/string.h>
#include <util/generic/strbuf.h>
-#include <utility>
+#include <utility>
template <class It>
struct TIsAsciiSpaceAdapter {
diff --git a/util/thread/factory.cpp b/util/thread/factory.cpp
index e956b8b098..48e898f32d 100644
--- a/util/thread/factory.cpp
+++ b/util/thread/factory.cpp
@@ -62,7 +62,7 @@ namespace {
}
private:
- std::function<void()> Func;
+ std::function<void()> Func;
};
}
diff --git a/util/thread/factory.h b/util/thread/factory.h
index 8f13244e45..561fcbac88 100644
--- a/util/thread/factory.h
+++ b/util/thread/factory.h
@@ -1,7 +1,7 @@
#pragma once
#include <util/generic/ptr.h>
-#include <functional>
+#include <functional>
class IThreadFactory {
public:
diff --git a/util/thread/lfqueue_ut.cpp b/util/thread/lfqueue_ut.cpp
index 454a75cf82..83bca100cf 100644
--- a/util/thread/lfqueue_ut.cpp
+++ b/util/thread/lfqueue_ut.cpp
@@ -1,6 +1,6 @@
#include <library/cpp/threading/future/future.h>
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/generic/algorithm.h>
#include <util/generic/vector.h>
#include <util/generic/ptr.h>
diff --git a/util/thread/lfstack_ut.cpp b/util/thread/lfstack_ut.cpp
index 8fa1037789..e20a838f95 100644
--- a/util/thread/lfstack_ut.cpp
+++ b/util/thread/lfstack_ut.cpp
@@ -1,4 +1,4 @@
-
+
#include <util/system/atomic.h>
#include <util/system/event.h>
#include <util/generic/deque.h>
@@ -88,11 +88,11 @@ Y_UNIT_TEST_SUITE(TLockFreeStackTests) {
TVector<TSimpleSharedPtr<NThreading::TLegacyFuture<>>> futures;
for (size_t i = 0; i < EnqueueThreads; ++i) {
- futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::Enqueuer, this)));
+ futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::Enqueuer, this)));
}
for (size_t i = 0; i < DequeueThreads; ++i) {
- futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::DequeuerAll, this)));
+ futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::DequeuerAll, this)));
}
// effectively join
diff --git a/util/thread/pool.h b/util/thread/pool.h
index e0583c2a73..d1ea3a67cb 100644
--- a/util/thread/pool.h
+++ b/util/thread/pool.h
@@ -8,7 +8,7 @@
#include <util/generic/yexception.h>
#include <util/generic/ptr.h>
#include <util/generic/noncopyable.h>
-#include <functional>
+#include <functional>
class TDuration;
diff --git a/util/ysaveload.h b/util/ysaveload.h
index 6258df889f..02efb4049b 100644
--- a/util/ysaveload.h
+++ b/util/ysaveload.h
@@ -511,7 +511,7 @@ public:
inline TSetSerializerInserter(TMapType& m, size_t cnt)
: TBase(m)
{
- m.reserve(cnt);
+ m.reserve(cnt);
}
};
@@ -537,7 +537,7 @@ public:
inline TSetSerializerInserter(TSetType& s, size_t cnt)
: TBase(s)
{
- s.reserve(cnt);
+ s.reserve(cnt);
}
};
diff --git a/ydb/apps/ydbd/ya.make b/ydb/apps/ydbd/ya.make
index f28c7f4907..a7a8ceb029 100644
--- a/ydb/apps/ydbd/ya.make
+++ b/ydb/apps/ydbd/ya.make
@@ -93,7 +93,7 @@ IF (OPENSOURCE)
# https://st.yandex-team.ru/DTCC-553
EXCEPT
contrib/libs/linux-headers # DTCC-725
- EXCEPT contrib/libs/llvm12/include
+ EXCEPT contrib/libs/llvm12/include
)
ENDIF()
diff --git a/ydb/core/base/tablet.h b/ydb/core/base/tablet.h
index 04831f77ed..602e39c600 100644
--- a/ydb/core/base/tablet.h
+++ b/ydb/core/base/tablet.h
@@ -16,7 +16,7 @@
#include <util/generic/vector.h>
#include <util/datetime/base.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
index a6d55eac92..bc33af4b86 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
@@ -33,7 +33,7 @@ public:
Counters = new NMonitoring::TDynamicCounters;
TIntrusivePtr<NScheme::TTypeRegistry> typeRegistry(new NScheme::TKikimrTypeRegistry());
- auto functionRegistry = NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry());
+ auto functionRegistry = NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry());
AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(), functionRegistry.Get(), nullptr, &KikimrShouldContinue));
AppData->Counters = Counters;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
index f152444dd1..a514e261ab 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
@@ -6,7 +6,7 @@ namespace NKikimr {
TPDiskMon::TPDiskMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, ui32 pDiskId,
TPDiskConfig *cfg)
- : Counters(counters)
+ : Counters(counters)
, PDiskId(pDiskId)
, ChunksGroup(Counters->GetSubgroup("subsystem", "chunks"))
, StateGroup(Counters->GetSubgroup("subsystem", "state"))
diff --git a/ydb/core/client/metadata/functions_metadata.cpp b/ydb/core/client/metadata/functions_metadata.cpp
index b22372a1c1..6f8a042374 100644
--- a/ydb/core/client/metadata/functions_metadata.cpp
+++ b/ydb/core/client/metadata/functions_metadata.cpp
@@ -7,15 +7,15 @@
namespace NKikimr {
using namespace NMiniKQL;
-void SerializeMetadata(const IBuiltinFunctionRegistry& funcRegistry, TString* out)
+void SerializeMetadata(const IBuiltinFunctionRegistry& funcRegistry, TString* out)
{
NKikimrSchemeTypeOperation::TMetadata metadata;
- for (const auto& op : funcRegistry.GetFunctions()) {
+ for (const auto& op : funcRegistry.GetFunctions()) {
auto protoOp = metadata.AddOperation();
protoOp->SetName(op.first);
for (const auto& desc : op.second) {
auto protoDesc = protoOp->AddDescription();
- for (const auto* arg = desc.ResultAndArgs; arg->SchemeType; ++arg) {
+ for (const auto* arg = desc.ResultAndArgs; arg->SchemeType; ++arg) {
auto protoArg = protoDesc->AddArg();
protoArg->SetSchemeType(arg->SchemeType);
protoArg->SetFlags(arg->Flags);
@@ -26,7 +26,7 @@ void SerializeMetadata(const IBuiltinFunctionRegistry& funcRegistry, TString* ou
Y_PROTOBUF_SUPPRESS_NODISCARD metadata.SerializeToString(out);
}
-void DeserializeMetadata(TStringBuf buffer, IBuiltinFunctionRegistry& funcRegistry)
+void DeserializeMetadata(TStringBuf buffer, IBuiltinFunctionRegistry& funcRegistry)
{
NKikimrSchemeTypeOperation::TMetadata metadata;
Y_VERIFY(metadata.ParseFromArray(buffer.data(), buffer.size()));
@@ -37,7 +37,7 @@ void DeserializeMetadata(TStringBuf buffer, IBuiltinFunctionRegistry& funcRegist
}
}
- TFunctionParamMetadataList arguments;
+ TFunctionParamMetadataList arguments;
arguments.resize(totalArgsToAllocate);
TFunctionsMap functions;
@@ -58,13 +58,13 @@ void DeserializeMetadata(TStringBuf buffer, IBuiltinFunctionRegistry& funcRegist
++argPosition; // terminating arg
- desc.push_back(TFunctionDescriptor(&arguments[firstArg], nullptr));
+ desc.push_back(TFunctionDescriptor(&arguments[firstArg], nullptr));
}
}
Y_VERIFY(argPosition == arguments.size());
- funcRegistry.RegisterAll(std::move(functions), std::move(arguments));
+ funcRegistry.RegisterAll(std::move(functions), std::move(arguments));
}
} // namespace NKikimr
diff --git a/ydb/core/client/metadata/functions_metadata.h b/ydb/core/client/metadata/functions_metadata.h
index b422dea50a..a9a17dd2eb 100644
--- a/ydb/core/client/metadata/functions_metadata.h
+++ b/ydb/core/client/metadata/functions_metadata.h
@@ -8,7 +8,7 @@ namespace NMiniKQL {
class IBuiltinFunctionRegistry;
}
-void SerializeMetadata(const NMiniKQL::IBuiltinFunctionRegistry& funcRegistry, TString* out);
-void DeserializeMetadata(TStringBuf buffer, NMiniKQL::IBuiltinFunctionRegistry& funcRegistry);
+void SerializeMetadata(const NMiniKQL::IBuiltinFunctionRegistry& funcRegistry, TString* out);
+void DeserializeMetadata(TStringBuf buffer, NMiniKQL::IBuiltinFunctionRegistry& funcRegistry);
} // namespace NKikimr
diff --git a/ydb/core/client/metadata/ut/functions_metadata_ut.cpp b/ydb/core/client/metadata/ut/functions_metadata_ut.cpp
index f81393be32..0713c33e8d 100644
--- a/ydb/core/client/metadata/ut/functions_metadata_ut.cpp
+++ b/ydb/core/client/metadata/ut/functions_metadata_ut.cpp
@@ -22,27 +22,27 @@ Y_UNIT_TEST_SUITE(TFunctionsMetadataTest)
{ 0, 0 }
};
- const auto functionRegistry = CreateBuiltinRegistry();
- functionRegistry->Register("MyAdd", TFunctionDescriptor(AddUi32Metadata, nullptr));
+ const auto functionRegistry = CreateBuiltinRegistry();
+ functionRegistry->Register("MyAdd", TFunctionDescriptor(AddUi32Metadata, nullptr));
TString metadata;
- SerializeMetadata(*functionRegistry, &metadata);
- DeserializeMetadata(metadata, *functionRegistry);
+ SerializeMetadata(*functionRegistry, &metadata);
+ DeserializeMetadata(metadata, *functionRegistry);
std::pair<NScheme::TTypeId, bool> argTypes[] = {
{ Uint32Id, false},
- { Uint32Id, false},
+ { Uint32Id, false},
{ Uint32Id, false}
};
- const auto op = functionRegistry->GetBuiltin("MyAdd", argTypes, Y_ARRAY_SIZE(argTypes));
- UNIT_ASSERT_EQUAL(op.Function, nullptr);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].SchemeType, Uint32Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].SchemeType, Uint32Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].SchemeType, Uint32Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[3].SchemeType, 0);
+ const auto op = functionRegistry->GetBuiltin("MyAdd", argTypes, Y_ARRAY_SIZE(argTypes));
+ UNIT_ASSERT_EQUAL(op.Function, nullptr);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].SchemeType, Uint32Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].SchemeType, Uint32Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].SchemeType, Uint32Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[3].SchemeType, 0);
}
}
diff --git a/ydb/core/client/metadata/ut/ya.make b/ydb/core/client/metadata/ut/ya.make
index 362a61efd6..c4d21862f1 100644
--- a/ydb/core/client/metadata/ut/ya.make
+++ b/ydb/core/client/metadata/ut/ya.make
@@ -9,7 +9,7 @@ SRCS(
PEERDIR(
ydb/library/yql/public/udf/service/stub
)
-
+
YQL_LAST_ABI_VERSION()
END()
diff --git a/ydb/core/client/minikql_compile/ut/ya.make b/ydb/core/client/minikql_compile/ut/ya.make
index d81d652468..f9fb7ce498 100644
--- a/ydb/core/client/minikql_compile/ut/ya.make
+++ b/ydb/core/client/minikql_compile/ut/ya.make
@@ -20,5 +20,5 @@ PEERDIR(
)
YQL_LAST_ABI_VERSION()
-
+
END()
diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
index b6c0e1d9f2..76f38bf35c 100644
--- a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
+++ b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
@@ -137,7 +137,7 @@ void CollectEraseRowKey(const TExprNode* child, TContext::TPtr ctx) {
for (auto& tupleItem : rowTuple->Children()) {
Y_ENSURE_EX(tupleItem->IsList() && tupleItem->ChildrenSize() == 2,
- TNodeException(*tupleItem) << child->Content() << "Expected pair");
+ TNodeException(*tupleItem) << child->Content() << "Expected pair");
Y_ENSURE_EX(tupleItem->Child(0)->IsAtom() &&
!tupleItem->Child(0)->Content().empty(), TNodeException(tupleItem->Child(0))
@@ -161,7 +161,7 @@ void CollectUpdateRowKey(const TExprNode* child, TContext::TPtr ctx) {
for (auto& tupleItem : rowTuple->Children()) {
Y_ENSURE_EX(tupleItem->IsList() && tupleItem->ChildrenSize() == 2,
- TNodeException(*tupleItem) << child->Content() << "Expected pair");
+ TNodeException(*tupleItem) << child->Content() << "Expected pair");
Y_ENSURE_EX(tupleItem->Child(0)->IsAtom() &&
!tupleItem->Child(0)->Content().empty(), TNodeException(tupleItem->Child(0))
@@ -174,7 +174,7 @@ void CollectUpdateRowKey(const TExprNode* child, TContext::TPtr ctx) {
for (auto& tupleItem : updateTuple->Children()) {
Y_ENSURE_EX(tupleItem->IsList() && tupleItem->ChildrenSize() >= 1 && tupleItem->ChildrenSize() <= 3,
- TNodeException(*tupleItem) << child->Content() << "Expected tuple of size 1..3");
+ TNodeException(*tupleItem) << child->Content() << "Expected tuple of size 1..3");
Y_ENSURE_EX(tupleItem->Child(0)->IsAtom() &&
!tupleItem->Child(0)->Content().empty(), TNodeException(tupleItem->Child(0))
<< "Expected column name as non-empty atom.");
@@ -197,7 +197,7 @@ void CollectSelectRowKey(const TExprNode* child, TContext::TPtr ctx) {
for (auto& tupleItem : rowTuple->Children()) {
Y_ENSURE_EX(tupleItem->IsList() && tupleItem->ChildrenSize() == 2,
- TNodeException(*tupleItem) << child->Content() << "Expected pair");
+ TNodeException(*tupleItem) << child->Content() << "Expected pair");
Y_ENSURE_EX(tupleItem->Child(0)->IsAtom() &&
!tupleItem->Child(0)->Content().empty(), TNodeException(tupleItem->Child(0))
@@ -234,7 +234,7 @@ void CollectSelectRangeKey(const TExprNode* child, TContext::TPtr ctx) {
}
else {
Y_ENSURE_EX(rangeItem->IsList() && rangeItem->ChildrenSize() == 3,
- TNodeException(*rangeItem) << child->Content() << "Expected 3 items in range item - column/from/to");
+ TNodeException(*rangeItem) << child->Content() << "Expected 3 items in range item - column/from/to");
Y_ENSURE_EX(rangeItem->Child(0)->IsAtom() &&
!rangeItem->Child(0)->Content().empty(), TNodeException(rangeItem->Child(0)) << "Expected column name as non-empty atom.");
@@ -263,7 +263,7 @@ public:
, CallableTransformer(callableTransformer) {}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
{
auto name = input->Content();
TIssueScopeGuard issueScope(ctx.IssueManager, [&]() {
@@ -374,7 +374,7 @@ private:
return true;
}
- const TTypeAnnotationNode* GetSelectType(IDbSchemeResolver::TTableResult* lookup, TExprNode& selectTuple,
+ const TTypeAnnotationNode* GetSelectType(IDbSchemeResolver::TTableResult* lookup, TExprNode& selectTuple,
TExprContext& ctx)
{
TVector<const TItemExprType*> resultItems;
@@ -518,7 +518,7 @@ private:
Y_ENSURE_EX(optionsNode->IsList(), TNodeException(optionsNode) << "Expected tuple");
for (auto optionsItem : optionsNode->Children()) {
Y_ENSURE_EX(optionsItem->IsList() && optionsItem->ChildrenSize() == 2 && optionsItem->Child(0)->IsAtom(),
- TNodeException(*optionsItem) << "Expected pair of atom and value");
+ TNodeException(*optionsItem) << "Expected pair of atom and value");
auto optionName = optionsItem->Child(0)->Content();
if (optionName != "ItemsLimit" &&
@@ -657,9 +657,9 @@ private:
Y_ENSURE_EX(node.ChildrenSize() > 0, TNodeException(node) << "AsParameters expects > 0 args.");
// Use AsStruct type annotation
- auto tmpNode = ctx.RenameNode(node, "AsStruct");
- auto output = tmpNode;
- YQL_ENSURE(CallableTransformer->Transform(tmpNode, output, ctx) == TStatus::Ok);
+ auto tmpNode = ctx.RenameNode(node, "AsStruct");
+ auto output = tmpNode;
+ YQL_ENSURE(CallableTransformer->Transform(tmpNode, output, ctx) == TStatus::Ok);
node.SetTypeAnn(tmpNode->GetTypeAnn());
return TStatus::Ok;
@@ -669,9 +669,9 @@ private:
Y_ENSURE_EX(node.ChildrenSize() == 3, TNodeException(node) << "AddParameter expects 3 args.");
// Use AddMember type annotation
- auto tmpNode = ctx.RenameNode(node, "AddMember");
- auto output = tmpNode;
- YQL_ENSURE(CallableTransformer->Transform(tmpNode, output, ctx) == TStatus::Ok);
+ auto tmpNode = ctx.RenameNode(node, "AddMember");
+ auto output = tmpNode;
+ YQL_ENSURE(CallableTransformer->Transform(tmpNode, output, ctx) == TStatus::Ok);
node.SetTypeAnn(tmpNode->GetTypeAnn());
return TStatus::Ok;
@@ -692,7 +692,7 @@ private:
auto& lambda = node.ChildRef(1);
const TTypeAnnotationNode* itemType = node.Child(0)->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -723,7 +723,7 @@ private:
auto& lambda = node.ChildRef(1);
const TTypeAnnotationNode* itemType = node.Child(0)->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -776,18 +776,18 @@ private:
IGraphTransformer::TStatus DataTypeWrapper(TExprNode& node, TExprContext& ctx)
{
- switch (node.ChildrenSize()) {
- case 1:
+ switch (node.ChildrenSize()) {
+ case 1:
node.SetTypeAnn(ctx.MakeType<TTypeExprType>(ctx.MakeType<TDataExprType>(NKikimr::NUdf::GetDataSlot(
AdaptLegacyYqlType(node.Child(0)->Content())))));
- break;
- case 3:
+ break;
+ case 3:
node.SetTypeAnn(ctx.MakeType<TTypeExprType>(ctx.MakeType<TDataExprParamsType>(
NKikimr::NUdf::GetDataSlot(AdaptLegacyYqlType(node.Child(0)->Content())), node.Child(1)->Content(), node.Child(2)->Content())));
- break;
- default:
- return TStatus::Error;
- }
+ break;
+ default:
+ return TStatus::Error;
+ }
return TStatus::Ok;
}
@@ -796,7 +796,7 @@ private:
TAutoPtr<IGraphTransformer> CallableTransformer;
};
-bool PerformTypeAnnotation(TExprNode::TPtr& exprRoot, TExprContext& ctx, TContext::TPtr mkqlContext) {
+bool PerformTypeAnnotation(TExprNode::TPtr& exprRoot, TExprContext& ctx, TContext::TPtr mkqlContext) {
TTypeAnnotationContext types;
types.DeprecatedSQL = true;
@@ -812,17 +812,17 @@ bool PerformTypeAnnotation(TExprNode::TPtr& exprRoot, TExprContext& ctx, TContex
return InstantTransform(*typeTransformer, exprRoot, ctx) == IGraphTransformer::TStatus::Ok;
}
-TRuntimeNode GetReadTargetNode(const TExprNode& callable, ui32 index, TMkqlBuildContext& ctx,
+TRuntimeNode GetReadTargetNode(const TExprNode& callable, ui32 index, TMkqlBuildContext& ctx,
TContext::TPtr mkqlContext)
{
TReadTarget readTarget;
- if (callable.ChildrenSize() > index) {
- const auto child = callable.Child(index);
+ if (callable.ChildrenSize() > index) {
+ const auto child = callable.Child(index);
if (child->IsAtom()) {
- readTarget = GetReadTarget(child);
+ readTarget = GetReadTarget(child);
} else {
- return MkqlBuildExpr(*child, ctx);
+ return MkqlBuildExpr(*child, ctx);
}
}
@@ -893,16 +893,16 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
auto compiler = MakeIntrusive<NCommon::TMkqlCommonCallableCompiler>();
compiler->AddCallable("SetResult",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto label = node.Child(0)->Content();
- auto payload = MkqlBuildExpr(*node.Child(1), ctx);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto label = node.Child(0)->Content();
+ auto payload = MkqlBuildExpr(*node.Child(1), ctx);
TRuntimeNode result = mkqlContext->PgmBuilder->SetResult(label, payload);
- return result;
+ return result;
});
compiler->AddCallable("SelectRow",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
YQL_ENSURE(node.Child(0)->IsList() || HasUnversionedTable(node), "expected list or atom as table");
const auto lookup = GetTableLookup(mkqlContext, node);
YQL_ENSURE(lookup->TableId);
@@ -914,14 +914,14 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
lookup->TableId->SchemaVersion = 0;
}
- auto rowTuple = node.Child(1);
+ auto rowTuple = node.Child(1);
TVector<TRuntimeNode> row(rowTuple->ChildrenSize());
TVector<ui32> keyTypes(rowTuple->ChildrenSize());
for (ui32 i = 0; i < rowTuple->ChildrenSize(); ++i) {
auto columnName = rowTuple->Child(i)->Child(0)->Content();
auto column = lookup->Columns.FindPtr(columnName);
YQL_ENSURE(column);
- auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
+ auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
row[i] = keyValue;
keyTypes[i] = column->Type;
}
@@ -933,11 +933,11 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
auto result = mkqlContext->PgmBuilder->SelectRow(*lookup->TableId, keyTypes, columnsToRead, row,
readTargetNode);
- return result;
+ return result;
});
compiler->AddCallable("SelectRange",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
YQL_ENSURE(node.Child(0)->IsList() || HasUnversionedTable(node), "expected list or atom as table");
const auto lookup = GetTableLookup(mkqlContext, node);
YQL_ENSURE(lookup->TableId);
@@ -951,7 +951,7 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
bool includeFrom = true;
bool includeTo = true;
- auto rangeTuple = node.Child(1);
+ auto rangeTuple = node.Child(1);
ui32 keyCount = 0;
ui32 fromComponents = 0;
ui32 toComponents = 0;
@@ -1005,12 +1005,12 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
YQL_ENSURE(column);
if (keyIndex < fromComponents) {
- auto fromKeyValue = MkqlBuildExpr(*rangeItem->Child(1), ctx);
+ auto fromKeyValue = MkqlBuildExpr(*rangeItem->Child(1), ctx);
from[keyIndex] = fromKeyValue;
}
if (keyIndex < toComponents) {
- auto toKeyValue = MkqlBuildExpr(*rangeItem->Child(2), ctx);
+ auto toKeyValue = MkqlBuildExpr(*rangeItem->Child(2), ctx);
to[keyIndex] = toKeyValue;
}
@@ -1020,7 +1020,7 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
const ui32 flags = (includeFrom ? TReadRangeOptions::TFlags::IncludeInitValue : TReadRangeOptions::TFlags::ExcludeInitValue) |
(includeTo ? TReadRangeOptions::TFlags::IncludeTermValue : TReadRangeOptions::TFlags::ExcludeTermValue);
- options.Flags = ctx.ProgramBuilder.NewDataLiteral(flags);
+ options.Flags = ctx.ProgramBuilder.NewDataLiteral(flags);
options.FromColumns = from;
options.ToColumns = to;
@@ -1034,12 +1034,12 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
TVector<TSelectColumn> columnsToRead;
FillColumnsToRead(lookup, node.Child(2), columnsToRead);
- auto optionsNode = node.Child(3);
+ auto optionsNode = node.Child(3);
for (auto optionsItem : optionsNode->Children()) {
if (optionsItem->Child(0)->Content() == "ItemsLimit") {
- options.ItemsLimit = MkqlBuildExpr(*optionsItem->Child(1), ctx);
+ options.ItemsLimit = MkqlBuildExpr(*optionsItem->Child(1), ctx);
} else if (optionsItem->Child(0)->Content() == "BytesLimit") {
- options.BytesLimit = MkqlBuildExpr(*optionsItem->Child(1), ctx);
+ options.BytesLimit = MkqlBuildExpr(*optionsItem->Child(1), ctx);
} else if (optionsItem->Child(0)->Content() == "SkipNullKeys") {
FillKeyPosition(skipNullKeys, optionsItem->Child(1), lookup);
} else if (optionsItem->Child(0)->Content() == "ForbidNullArgsFrom") {
@@ -1057,11 +1057,11 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
TRuntimeNode result = mkqlContext->PgmBuilder->SelectRange(*lookup->TableId, keyTypes, columnsToRead,
options, readTargetNode);
- return result;
+ return result;
});
compiler->AddCallable("UpdateRow",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
YQL_ENSURE(node.Child(0)->IsList() || HasUnversionedTable(node), "expected list or atom as table");
const auto lookup = GetTableLookup(mkqlContext, node);
YQL_ENSURE(lookup->TableId);
@@ -1073,20 +1073,20 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
lookup->TableId->SchemaVersion = 0;
}
- auto rowTuple = node.Child(1);
+ auto rowTuple = node.Child(1);
TVector<TRuntimeNode> row(rowTuple->ChildrenSize());
TVector<ui32> keyTypes(rowTuple->ChildrenSize());
for (ui32 i = 0; i < rowTuple->ChildrenSize(); ++i) {
auto columnName = rowTuple->Child(i)->Child(0)->Content();
auto column = lookup->Columns.FindPtr(columnName);
YQL_ENSURE(column);
- auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
+ auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
row[i] = keyValue;
keyTypes[i] = column->Type;
}
auto update = mkqlContext->PgmBuilder->GetUpdateRowBuilder();
- auto updateTuple = node.Child(2);
+ auto updateTuple = node.Child(2);
for (ui32 i = 0; i < updateTuple->ChildrenSize(); ++i) {
auto child = updateTuple->Child(i);
auto columnName = child->Child(0)->Content();
@@ -1097,22 +1097,22 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
update.EraseColumn(column->Column);
}
else if (child->ChildrenSize() == 2) {
- auto setValue = MkqlBuildExpr(*updateTuple->Child(i)->Child(1), ctx);
+ auto setValue = MkqlBuildExpr(*updateTuple->Child(i)->Child(1), ctx);
update.SetColumn(column->Column, column->Type, setValue);
} else {
auto modeStr = child->Child(1)->Content();
EInplaceUpdateMode mode = ParseUpdateMode(modeStr);
- auto mergeValue = MkqlBuildExpr(*updateTuple->Child(i)->Child(2), ctx);
+ auto mergeValue = MkqlBuildExpr(*updateTuple->Child(i)->Child(2), ctx);
update.InplaceUpdateColumn(column->Column, column->Type, mergeValue, mode);
}
}
TRuntimeNode result = mkqlContext->PgmBuilder->UpdateRow(*lookup->TableId, keyTypes, row, update);
- return result;
+ return result;
});
compiler->AddCallable("EraseRow",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
YQL_ENSURE(node.Child(0)->IsList() || HasUnversionedTable(node), "expected list or atom as table");
const auto lookup = GetTableLookup(mkqlContext, node);
YQL_ENSURE(lookup->TableId);
@@ -1124,70 +1124,70 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
lookup->TableId->SchemaVersion = 0;
}
- auto rowTuple = node.Child(1);
+ auto rowTuple = node.Child(1);
TVector<TRuntimeNode> row(rowTuple->ChildrenSize());
TVector<ui32> keyTypes(rowTuple->ChildrenSize());
for (ui32 i = 0; i < rowTuple->ChildrenSize(); ++i) {
auto columnName = rowTuple->Child(i)->Child(0)->Content();
auto column = lookup->Columns.FindPtr(columnName);
YQL_ENSURE(column);
- auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
+ auto keyValue = MkqlBuildExpr(*rowTuple->Child(i)->Child(1), ctx);
row[i] = keyValue;
keyTypes[i] = column->Type;
}
TRuntimeNode result = mkqlContext->PgmBuilder->EraseRow(*lookup->TableId, keyTypes, row);
- return result;
+ return result;
});
- compiler->AddCallable("Increment", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto arg = MkqlBuildExpr(*node.Child(0), ctx);
+ compiler->AddCallable("Increment", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto arg = MkqlBuildExpr(*node.Child(0), ctx);
- return ctx.ProgramBuilder.Increment(arg);
+ return ctx.ProgramBuilder.Increment(arg);
});
- compiler->AddCallable("StepTxId", [mkqlContext](const TExprNode&, TMkqlBuildContext&) {
- return mkqlContext->PgmBuilder->StepTxId();
+ compiler->AddCallable("StepTxId", [mkqlContext](const TExprNode&, TMkqlBuildContext&) {
+ return mkqlContext->PgmBuilder->StepTxId();
});
- compiler->OverrideCallable("Parameter", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& name = node.Child(0)->Content();
- const auto type = BuildType(*node.Child(1), *node.Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ compiler->OverrideCallable("Parameter", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& name = node.Child(0)->Content();
+ const auto type = BuildType(*node.Child(1), *node.Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
return mkqlContext->NewParam(name, type);
});
- compiler->AddCallable("Parameters", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ compiler->AddCallable("Parameters", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
Y_UNUSED(ctx);
if (!mkqlContext->NewParamsBuilder()) {
- throw TNodeException(node) << "You can create only one Parameters object.";
+ throw TNodeException(node) << "You can create only one Parameters object.";
}
return TRuntimeNode();
});
- compiler->AddCallable("AsParameters", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ compiler->AddCallable("AsParameters", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
if (!mkqlContext->NewParamsBuilder()) {
- throw TNodeException(node) << "You can create only one Parameters object.";
+ throw TNodeException(node) << "You can create only one Parameters object.";
}
- for (auto child : node.Children()) {
+ for (auto child : node.Children()) {
const auto& name = child->Child(0)->Content();
- auto value = MkqlBuildExpr(*child->Child(1), ctx);
+ auto value = MkqlBuildExpr(*child->Child(1), ctx);
mkqlContext->ParamsBuilder->Add(name, value);
}
return mkqlContext->ParamsBuilder->Build();
});
- compiler->AddCallable("AddParameter", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ compiler->AddCallable("AddParameter", [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
if (!mkqlContext->NewParamsBuilder()) {
- throw TNodeException(node) << "You can create only one Parameters object.";
+ throw TNodeException(node) << "You can create only one Parameters object.";
}
- for (auto curNode = &node; curNode->Content() != "Parameters"; curNode = curNode->Child(0)) {
- Y_ENSURE_EX(curNode->Content() == "AddParameter", TNodeException(*curNode) << "Only AddParameter func can be in AddParameter func.");
+ for (auto curNode = &node; curNode->Content() != "Parameters"; curNode = curNode->Child(0)) {
+ Y_ENSURE_EX(curNode->Content() == "AddParameter", TNodeException(*curNode) << "Only AddParameter func can be in AddParameter func.");
const auto& name = curNode->Child(1)->Content();
- auto value = MkqlBuildExpr(*curNode->Child(2), ctx);
+ auto value = MkqlBuildExpr(*curNode->Child(2), ctx);
mkqlContext->ParamsBuilder->Add(name, value);
}
@@ -1195,88 +1195,88 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
});
compiler->AddCallable("MapParameter",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto list = MkqlBuildExpr(*node.Child(0), ctx);
- return mkqlContext->PgmBuilder->MapParameter(list, [&](TRuntimeNode item) {
- TMkqlBuildContext::TArgumentsMap innerArguments;
- auto arg = node.Child(1)->Child(0)->Child(0);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto list = MkqlBuildExpr(*node.Child(0), ctx);
+ return mkqlContext->PgmBuilder->MapParameter(list, [&](TRuntimeNode item) {
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ auto arg = node.Child(1)->Child(0)->Child(0);
innerArguments[arg] = item;
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(1)->UniqueId());
- auto res = MkqlBuildExpr(*node.Child(1)->Child(1), innerCtx);
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(1)->UniqueId());
+ auto res = MkqlBuildExpr(*node.Child(1)->Child(1), innerCtx);
return res;
- });
+ });
});
compiler->AddCallable("FlatMapParameter",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto list = MkqlBuildExpr(*node.Child(0), ctx);
- return mkqlContext->PgmBuilder->FlatMapParameter(list, [&](TRuntimeNode item) {
- TMkqlBuildContext::TArgumentsMap innerArguments;
- auto arg = node.Child(1)->Child(0)->Child(0);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto list = MkqlBuildExpr(*node.Child(0), ctx);
+ return mkqlContext->PgmBuilder->FlatMapParameter(list, [&](TRuntimeNode item) {
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ auto arg = node.Child(1)->Child(0)->Child(0);
innerArguments[arg] = item;
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(1)->UniqueId());
- auto res = MkqlBuildExpr(*node.Child(1)->Child(1), innerCtx);
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(1)->UniqueId());
+ auto res = MkqlBuildExpr(*node.Child(1)->Child(1), innerCtx);
return res;
- });
+ });
});
compiler->AddCallable("AcquireLocks",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto lockTxId = MkqlBuildExpr(*node.Child(0), ctx);
- return mkqlContext->PgmBuilder->AcquireLocks(lockTxId);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto lockTxId = MkqlBuildExpr(*node.Child(0), ctx);
+ return mkqlContext->PgmBuilder->AcquireLocks(lockTxId);
});
compiler->AddCallable("Diagnostics",
- [mkqlContext](const TExprNode&, TMkqlBuildContext&) {
- return mkqlContext->PgmBuilder->Diagnostics();
+ [mkqlContext](const TExprNode&, TMkqlBuildContext&) {
+ return mkqlContext->PgmBuilder->Diagnostics();
});
compiler->AddCallable("PartialSort",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto list = MkqlBuildExpr(*node.Child(0), ctx);
- auto ascending = MkqlBuildExpr(*node.Child(1), ctx);
- return mkqlContext->PgmBuilder->PartialSort(list, ascending, [&](TRuntimeNode item) {
- TMkqlBuildContext::TArgumentsMap innerArguments;
- auto argItem = node.Child(2)->Child(0)->Child(0);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto list = MkqlBuildExpr(*node.Child(0), ctx);
+ auto ascending = MkqlBuildExpr(*node.Child(1), ctx);
+ return mkqlContext->PgmBuilder->PartialSort(list, ascending, [&](TRuntimeNode item) {
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ auto argItem = node.Child(2)->Child(0)->Child(0);
innerArguments[argItem] = item;
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(2)->UniqueId());
- auto res = MkqlBuildExpr(*node.Child(2)->Child(1), innerCtx);
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), node.Child(2)->UniqueId());
+ auto res = MkqlBuildExpr(*node.Child(2)->Child(1), innerCtx);
return res;
- });
+ });
});
compiler->AddCallable("PartialTake",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto list = MkqlBuildExpr(*node.Child(0), ctx);
- auto len = MkqlBuildExpr(*node.Child(1), ctx);
- return mkqlContext->PgmBuilder->PartialTake(list, len);
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto list = MkqlBuildExpr(*node.Child(0), ctx);
+ auto len = MkqlBuildExpr(*node.Child(1), ctx);
+ return mkqlContext->PgmBuilder->PartialTake(list, len);
});
compiler->OverrideCallable("CombineByKey",
- [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
+ [mkqlContext](const TExprNode& node, TMkqlBuildContext& ctx) {
auto combineByKey = CombineByKeyImpl(node, ctx);
auto merge = mkqlContext->PgmBuilder->CombineByKeyMerge(combineByKey);
return merge;
});
// TODO: Remove override once we support custom types in YQL type annotaion.
- compiler->OverrideCallable("DataType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto typeName = node.Child(0)->Content();
+ compiler->OverrideCallable("DataType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto typeName = node.Child(0)->Content();
typeName = AdaptLegacyYqlType(typeName);
auto slot = NKikimr::NUdf::FindDataSlot(typeName);
if (!slot) {
- throw TNodeException(node) << "Unknown type '" << typeName << "'.";
+ throw TNodeException(node) << "Unknown type '" << typeName << "'.";
}
NUdf::TDataTypeId typeId = NKikimr::NUdf::GetDataTypeInfo(*slot).TypeId;
- if (typeId == NUdf::TDataType<NUdf::TDecimal>::Id) {
- auto precision = node.Child(1)->Content();
- auto scale = node.Child(2)->Content();
+ if (typeId == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ auto precision = node.Child(1)->Content();
+ auto scale = node.Child(2)->Content();
auto type = ctx.ProgramBuilder.NewDecimalType(FromString<ui8>(precision), FromString<ui8>(scale));
- return TRuntimeNode(type, true);
+ return TRuntimeNode(type, true);
} else {
auto type = ctx.ProgramBuilder.NewDataType(typeId);
- return TRuntimeNode(type, true);
+ return TRuntimeNode(type, true);
}
});
@@ -1284,9 +1284,9 @@ TIntrusivePtr<NCommon::IMkqlCallableCompiler> CreateMkqlCompiler(TContext::TPtr
}
TRuntimeNode CompileNode(const TExprNode& node, TExprContext& exprCtx, TContext::TPtr ctx, const IMkqlCallableCompiler* compiler) {
- const auto guard = ctx->TypeEnv->BindAllocator();
+ const auto guard = ctx->TypeEnv->BindAllocator();
TMkqlBuildContext mkqlCtx(*compiler, *ctx->PgmBuilder, exprCtx);
- return MkqlBuildExpr(node, mkqlCtx);
+ return MkqlBuildExpr(node, mkqlCtx);
}
} // anonymous namespace
@@ -1315,8 +1315,8 @@ void CollectKeys(const TExprNode* root, TContext::TPtr ctx) {
}
for (auto& child : current->Children()) {
- if (visited.insert(child.Get()).second) {
- activeNodes.push(child.Get());
+ if (visited.insert(child.Get()).second) {
+ activeNodes.push(child.Get());
}
}
}
@@ -1337,7 +1337,7 @@ ConvertToMiniKQL(TExprContainer::TPtr expr,
try {
TContext::TPtr ctx(new TContext(functionRegistry, typeEnv));
auto compiler = CreateMkqlCompiler(ctx);
- CollectKeys(expr->Root.Get(), ctx);
+ CollectKeys(expr->Root.Get(), ctx);
const auto& tablesToResolve = ctx->GetTablesToResolve();
if (!tablesToResolve.empty()) {
TVector<IDbSchemeResolver::TTable> requests;
@@ -1450,7 +1450,7 @@ public:
return SendResponseAndDie(result, {}, ctx);
}
- CollectKeys(Expr->Root.Get(), CompileCtx);
+ CollectKeys(Expr->Root.Get(), CompileCtx);
Compiler = CreateMkqlCompiler(CompileCtx);
const auto& tablesToResolve = CompileCtx->GetTablesToResolve();
@@ -1575,7 +1575,7 @@ private:
}
IGraphTransformer::TStatus status(IGraphTransformer::TStatus::Ok);
do {
- status = ExpandApply(Expr->Root, Expr->Root, Expr->Context);
+ status = ExpandApply(Expr->Root, Expr->Root, Expr->Context);
} while (status.Level == IGraphTransformer::TStatus::Repeat);
Y_VERIFY_DEBUG(status.Level == IGraphTransformer::TStatus::Ok ||
status.Level == IGraphTransformer::TStatus::Error);
diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql.h b/ydb/core/client/minikql_compile/yql_expr_minikql.h
index a680f04eb6..ab6011c105 100644
--- a/ydb/core/client/minikql_compile/yql_expr_minikql.h
+++ b/ydb/core/client/minikql_compile/yql_expr_minikql.h
@@ -28,7 +28,7 @@ struct TExprContainer : public TAtomicRefCount<TExprContainer> {
using TPtr = TIntrusivePtr<TExprContainer>;
TExprContext Context;
- TExprNode::TPtr Root;
+ TExprNode::TPtr Root;
};
NThreading::TFuture<TConvertResult>
diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql_compile_ut.cpp b/ydb/core/client/minikql_compile/yql_expr_minikql_compile_ut.cpp
index 3ccbdfa544..4fcdf735ba 100644
--- a/ydb/core/client/minikql_compile/yql_expr_minikql_compile_ut.cpp
+++ b/ydb/core/client/minikql_compile/yql_expr_minikql_compile_ut.cpp
@@ -22,17 +22,17 @@ namespace {
TVector<THolder<TKeyDesc>> DescList;
TServices()
- : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
+ : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
, TypeEnv(Alloc)
{
- Alloc.Release();
+ Alloc.Release();
+ }
+
+ ~TServices()
+ {
+ Alloc.Acquire();
}
- ~TServices()
- {
- Alloc.Acquire();
- }
-
void ExtractKeys(TRuntimeNode pgm) {
TExploringNodeVisitor explorer;
explorer.Walk(pgm.GetNode(), TypeEnv);
diff --git a/ydb/core/client/server/msgbus_server_db.cpp b/ydb/core/client/server/msgbus_server_db.cpp
index 904cb3f697..08f3d71786 100644
--- a/ydb/core/client/server/msgbus_server_db.cpp
+++ b/ydb/core/client/server/msgbus_server_db.cpp
@@ -346,22 +346,22 @@ public:
static NMiniKQL::TRuntimeNode NewDataLiteral(NMiniKQL::TKikimrProgramBuilder& pgmBuilder, const NJson::TJsonValue& jsonValue, NScheme::TTypeId typeId) {
// TODO
- auto& builder = static_cast<NMiniKQL::TProgramBuilder&>(pgmBuilder);
+ auto& builder = static_cast<NMiniKQL::TProgramBuilder&>(pgmBuilder);
switch (typeId) {
case NScheme::NTypeIds::Bool:
- return builder.NewDataLiteral<bool>(jsonValue.GetBoolean());
+ return builder.NewDataLiteral<bool>(jsonValue.GetBoolean());
case NScheme::NTypeIds::Float:
- return builder.NewDataLiteral<float>(jsonValue.GetDouble());
+ return builder.NewDataLiteral<float>(jsonValue.GetDouble());
case NScheme::NTypeIds::Double:
- return builder.NewDataLiteral(jsonValue.GetDouble());
+ return builder.NewDataLiteral(jsonValue.GetDouble());
case NScheme::NTypeIds::Int32:
- return builder.NewDataLiteral<i32>(jsonValue.GetInteger());
+ return builder.NewDataLiteral<i32>(jsonValue.GetInteger());
case NScheme::NTypeIds::Int64:
- return builder.NewDataLiteral<i64>(jsonValue.GetInteger());
+ return builder.NewDataLiteral<i64>(jsonValue.GetInteger());
case NScheme::NTypeIds::Uint32:
- return builder.NewDataLiteral<ui32>(jsonValue.GetUInteger());
+ return builder.NewDataLiteral<ui32>(jsonValue.GetUInteger());
case NScheme::NTypeIds::Uint64:
- return builder.NewDataLiteral<ui64>(jsonValue.GetUInteger());
+ return builder.NewDataLiteral<ui64>(jsonValue.GetUInteger());
case NScheme::NTypeIds::Utf8:
return builder.NewDataLiteral<NUdf::EDataSlot::Utf8>(jsonValue.GetString());
case NScheme::NTypeIds::String:
diff --git a/ydb/core/client/server/msgbus_server_types.cpp b/ydb/core/client/server/msgbus_server_types.cpp
index 6129858354..0495040e3c 100644
--- a/ydb/core/client/server/msgbus_server_types.cpp
+++ b/ydb/core/client/server/msgbus_server_types.cpp
@@ -26,7 +26,7 @@ public:
void Bootstrap(const TActorContext& ctx) {
const auto* typeRegistry = AppData(ctx)->TypeRegistry;
- const auto& functionRegistry = AppData(ctx)->FunctionRegistry->GetBuiltins();
+ const auto& functionRegistry = AppData(ctx)->FunctionRegistry->GetBuiltins();
ui64 typeEtag = typeRegistry->GetMetadataEtag();
ui64 functionEtag = functionRegistry->GetMetadataEtag();
diff --git a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
index fcb58e4758..b4429d5721 100644
--- a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
@@ -38,7 +38,7 @@ int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv) {
TCmdCompileAndExecMiniKQLConfig config;
config.Parse(argc, argv);
- auto functionRegistry = NMiniKQL::CreateFunctionRegistry(NMiniKQL::CreateBuiltinRegistry());
+ auto functionRegistry = NMiniKQL::CreateFunctionRegistry(NMiniKQL::CreateBuiltinRegistry());
TAlignedPagePoolCounters countersStub;
NMiniKQL::TScopedAlloc alloc(countersStub);
NMiniKQL::TTypeEnvironment TypeEnv(alloc);
diff --git a/ydb/core/driver_lib/run/run.cpp b/ydb/core/driver_lib/run/run.cpp
index 55e632a5e4..a4f74aa4e0 100644
--- a/ydb/core/driver_lib/run/run.cpp
+++ b/ydb/core/driver_lib/run/run.cpp
@@ -1450,9 +1450,9 @@ void TKikimrRunner::KikimrStop(bool graceful) {
}
if (PollerThreads) {
- PollerThreads->Stop();
- }
-
+ PollerThreads->Stop();
+ }
+
if (SqsHttp) {
SqsHttp.Destroy();
}
diff --git a/ydb/core/engine/kikimr_program_builder.cpp b/ydb/core/engine/kikimr_program_builder.cpp
index 0894bba984..fd32a772ee 100644
--- a/ydb/core/engine/kikimr_program_builder.cpp
+++ b/ydb/core/engine/kikimr_program_builder.cpp
@@ -16,10 +16,10 @@ namespace {
TType* ValidateColumns(
const TArrayRef<const TSelectColumn>& columns,
TRuntimeNode& tags,
- const TProgramBuilder* builder)
+ const TProgramBuilder* builder)
{
- TStructTypeBuilder rowTypeBuilder(builder->GetTypeEnvironment());
- TStructLiteralBuilder tagsBuilder(builder->GetTypeEnvironment());
+ TStructTypeBuilder rowTypeBuilder(builder->GetTypeEnvironment());
+ TStructLiteralBuilder tagsBuilder(builder->GetTypeEnvironment());
rowTypeBuilder.Reserve(columns.size());
tagsBuilder.Reserve(columns.size());
for (auto& col : columns) {
@@ -32,9 +32,9 @@ TType* ValidateColumns(
builder->GetTypeEnvironment());
else
dataType = TDataType::Create(col.SchemeType, builder->GetTypeEnvironment());
- auto optType = TOptionalType::Create(dataType, builder->GetTypeEnvironment());
+ auto optType = TOptionalType::Create(dataType, builder->GetTypeEnvironment());
rowTypeBuilder.Add(col.Label, optType);
- tagsBuilder.Add(col.Label, builder->NewDataLiteral<ui32>(col.ColumnId));
+ tagsBuilder.Add(col.Label, builder->NewDataLiteral<ui32>(col.ColumnId));
}
tags = TRuntimeNode(tagsBuilder.Build(), true);
@@ -175,7 +175,7 @@ EInplaceUpdateMode InplaceUpdateModeFromCString(const char* str) {
TKikimrProgramBuilder::TKikimrProgramBuilder(
const TTypeEnvironment& env,
const IFunctionRegistry& functionRegistry)
- : TProgramBuilder(env, functionRegistry, true)
+ : TProgramBuilder(env, functionRegistry, true)
{
UseNullType = false;
NullInternName = Env.InternName(TStringBuf("Null"));
@@ -238,7 +238,7 @@ TRuntimeNode TKikimrProgramBuilder::SelectRow(
auto rows = FixKeysType(keyTypes, row);
TRuntimeNode tags;
- auto rowType = ValidateColumns(columns, tags, this);
+ auto rowType = ValidateColumns(columns, tags, this);
TType* optType = NewOptionalType(rowType);
TCallableBuilder builder(Env, "SelectRow", optType);
@@ -331,7 +331,7 @@ TRuntimeNode TKikimrProgramBuilder::SelectRange(
}
TRuntimeNode tags;
- auto rowType = ValidateColumns(columns, tags, this);
+ auto rowType = ValidateColumns(columns, tags, this);
TType* listType = NewListType(rowType);
TDataType* boolType = TDataType::Create(NUdf::TDataType<bool>::Id, Env);
@@ -535,7 +535,7 @@ TRuntimeNode TKikimrProgramBuilder::Bind(TRuntimeNode program, TRuntimeNode para
MKQL_ENSURE(callable.GetType()->GetPayload(), "Expected payload");
auto structObj = AS_VALUE(NMiniKQL::TStructLiteral, NMiniKQL::TRuntimeNode(callable.GetType()->GetPayload(), true));
auto payloadIndex = 1; // fields: Args, Payload
- const TStringBuf parameterName(AS_VALUE(NMiniKQL::TDataLiteral, structObj->GetValue(payloadIndex))->AsValue().AsStringRef());
+ const TStringBuf parameterName(AS_VALUE(NMiniKQL::TDataLiteral, structObj->GetValue(payloadIndex))->AsValue().AsStringRef());
auto parameterIndex = parametersStruct.GetType()->FindMemberIndex(parameterName);
MKQL_ENSURE(parameterIndex, "Missing value for parameter: " << parameterName);
@@ -656,7 +656,7 @@ TRuntimeNode TKikimrProgramBuilder::SetResult(const TStringBuf& label, TRuntimeN
TRuntimeNode TKikimrProgramBuilder::NewDataLiteral(const std::pair<ui64, ui64>& data) const {
return TRuntimeNode(BuildDataLiteral(NUdf::TStringRef(reinterpret_cast<const char*>(&data), sizeof(data)), LegacyPairUi64Ui64, Env), true);
-}
+}
TRuntimeNode TKikimrProgramBuilder::BuildTableId(const TTableId& tableId) const {
if (tableId.SchemaVersion) {
diff --git a/ydb/core/engine/kikimr_program_builder.h b/ydb/core/engine/kikimr_program_builder.h
index 421f46ae62..717132c0b9 100644
--- a/ydb/core/engine/kikimr_program_builder.h
+++ b/ydb/core/engine/kikimr_program_builder.h
@@ -229,9 +229,9 @@ public:
TRuntimeNode Abort();
TRuntimeNode StepTxId();
TRuntimeNode SetResult(const TStringBuf& label, TRuntimeNode payload);
-
+
using TProgramBuilder::NewDataLiteral;
-private:
+private:
TRuntimeNode NewDataLiteral(const std::pair<ui64, ui64>& data) const;
TRuntimeNode BuildTableId(const TTableId& tableId) const;
TVector<TRuntimeNode> FixKeysType(
diff --git a/ydb/core/engine/kikimr_program_builder_ut.cpp b/ydb/core/engine/kikimr_program_builder_ut.cpp
index b7b313df00..efa073ae2f 100644
--- a/ydb/core/engine/kikimr_program_builder_ut.cpp
+++ b/ydb/core/engine/kikimr_program_builder_ut.cpp
@@ -16,55 +16,55 @@
namespace NKikimr {
namespace NMiniKQL {
- TIntrusivePtr<IRandomProvider> CreateRandomProvider() {
- return CreateDeterministicRandomProvider(1);
- }
-
- TIntrusivePtr<ITimeProvider> CreateTimeProvider() {
- return CreateDeterministicTimeProvider(1);
- }
-
- TComputationNodeFactory GetLazyListFactory() {
- return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
- if (callable.GetType()->GetName() == "LazyList") {
- return new TExternalComputationNode(ctx.Mutables);
- }
-
- return GetBuiltinFactory()(callable, ctx);
- };
- }
-
- struct TSetup {
- TSetup() {
- FunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
- RandomProvider = CreateRandomProvider();
- TimeProvider = CreateTimeProvider();
-
- Env.Reset(new TTypeEnvironment(Alloc));
+ TIntrusivePtr<IRandomProvider> CreateRandomProvider() {
+ return CreateDeterministicRandomProvider(1);
+ }
+
+ TIntrusivePtr<ITimeProvider> CreateTimeProvider() {
+ return CreateDeterministicTimeProvider(1);
+ }
+
+ TComputationNodeFactory GetLazyListFactory() {
+ return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
+ if (callable.GetType()->GetName() == "LazyList") {
+ return new TExternalComputationNode(ctx.Mutables);
+ }
+
+ return GetBuiltinFactory()(callable, ctx);
+ };
+ }
+
+ struct TSetup {
+ TSetup() {
+ FunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ RandomProvider = CreateRandomProvider();
+ TimeProvider = CreateTimeProvider();
+
+ Env.Reset(new TTypeEnvironment(Alloc));
PgmBuilder.Reset(new TKikimrProgramBuilder(*Env, *FunctionRegistry));
- }
-
- TAutoPtr<IComputationGraph> BuildGraph(TRuntimeNode pgm) {
- Explorer.Walk(pgm.GetNode(), *Env);
+ }
+
+ TAutoPtr<IComputationGraph> BuildGraph(TRuntimeNode pgm) {
+ Explorer.Walk(pgm.GetNode(), *Env);
TComputationPatternOpts opts(Alloc.Ref(), *Env, GetLazyListFactory(),
FunctionRegistry.Get(), NUdf::EValidateMode::None,
- NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
+ NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
Pattern = MakeComputationPattern(Explorer, pgm, {}, opts);
return Pattern->Clone(opts.ToComputationOptions(*RandomProvider, *TimeProvider));
- }
-
- TIntrusivePtr<IFunctionRegistry> FunctionRegistry;
- TIntrusivePtr<IRandomProvider> RandomProvider;
- TIntrusivePtr<ITimeProvider> TimeProvider;
-
- TScopedAlloc Alloc;
- THolder<TTypeEnvironment> Env;
- THolder<TKikimrProgramBuilder> PgmBuilder;
-
- TExploringNodeVisitor Explorer;
+ }
+
+ TIntrusivePtr<IFunctionRegistry> FunctionRegistry;
+ TIntrusivePtr<IRandomProvider> RandomProvider;
+ TIntrusivePtr<ITimeProvider> TimeProvider;
+
+ TScopedAlloc Alloc;
+ THolder<TTypeEnvironment> Env;
+ THolder<TKikimrProgramBuilder> PgmBuilder;
+
+ TExploringNodeVisitor Explorer;
IComputationPattern::TPtr Pattern;
- };
-
+ };
+
Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
void VerifySerialization(TNode* pgm, const TTypeEnvironment& env) {
@@ -83,11 +83,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestEraseRowStaticKey) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
- keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
keyColumns.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
keyColumns.push_back(pgmBuilder.NewOptional(
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe")));
@@ -126,14 +126,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestEraseRowPartialDynamicKey) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
keyColumns.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
keyColumns.push_back(pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
keyColumns.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe"));
TVector<ui32> keyTypes({ NUdf::TDataType<ui64>::Id, NUdf::TDataType<ui32>::Id, NUdf::TDataType<char*>::Id });
pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.EraseRow(TTableId(1, 2),
@@ -168,13 +168,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestEraseRowDynamicKey) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
keyColumns.push_back(pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
keyColumns.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe"));
TVector<ui32> keyTypes({ NUdf::TDataType<ui32>::Id, NUdf::TDataType<char*>::Id });
@@ -207,11 +207,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectRow) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
- keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
keyColumns.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
keyColumns.push_back(pgmBuilder.NewOptional(
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe")));
@@ -260,20 +260,20 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestUpdateRowStaticKey) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
- keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ keyColumns.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
keyColumns.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
keyColumns.push_back(pgmBuilder.NewOptional(
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe")));
auto update = pgmBuilder.GetUpdateRowBuilder();
update.SetColumn(34, NUdf::TDataType<ui32>::Id,
- pgmBuilder.NewOptional(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
+ pgmBuilder.NewOptional(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
update.EraseColumn(56);
update.InplaceUpdateColumn(78, NUdf::TDataType<ui64>::Id,
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1), EInplaceUpdateMode::Sum);
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1), EInplaceUpdateMode::Sum);
TVector<ui32> keyTypes({ NUdf::TDataType<ui32>::Id, NUdf::TDataType<ui64>::Id, NUdf::TDataType<char*>::Id });
pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.UpdateRow(TTableId(1, 2),
keyTypes,
@@ -318,22 +318,22 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestUpdateRowDynamicKey) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TVector<TRuntimeNode> keyColumns;
keyColumns.push_back(pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(34),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
keyColumns.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
keyColumns.push_back(pgmBuilder.NewOptional(
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("qwe")));
auto update = pgmBuilder.GetUpdateRowBuilder();
update.SetColumn(34, NUdf::TDataType<ui32>::Id,
- pgmBuilder.NewOptional(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
+ pgmBuilder.NewOptional(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(12)));
update.EraseColumn(56);
update.InplaceUpdateColumn(78, NUdf::TDataType<ui64>::Id,
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1), EInplaceUpdateMode::Sum);
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1), EInplaceUpdateMode::Sum);
TVector<ui32> keyTypes({ NUdf::TDataType<ui32>::Id, NUdf::TDataType<ui64>::Id, NUdf::TDataType<char*>::Id });
pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.UpdateRow(TTableId(1, 2),
keyTypes,
@@ -376,12 +376,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectFromInclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
TVector<TRuntimeNode> from;
- from.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ from.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
from.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
options.FromColumns = from;
@@ -425,15 +425,15 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectFromExclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
TVector<TRuntimeNode> from;
- from.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ from.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
from.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
options.FromColumns = from;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeInitValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeInitValue);
TVector<TSelectColumn> columnsToRead;
columnsToRead.emplace_back("column1", 34, (ui32)NUdf::TDataType<ui32>::Id);
@@ -475,14 +475,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectToInclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
TVector<TRuntimeNode> from;
from.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id));
TVector<TRuntimeNode> to;
- to.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ to.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
to.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
options.FromColumns = from;
options.ToColumns = to;
@@ -529,18 +529,18 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectToExclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
TVector<TRuntimeNode> from;
from.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id));
TVector<TRuntimeNode> to;
- to.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
+ to.push_back(pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42));
to.push_back(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id));
options.FromColumns = from;
options.ToColumns = to;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
TVector<TSelectColumn> columnsToRead;
columnsToRead.emplace_back("column1", 34, (ui32)NUdf::TDataType<ui32>::Id);
@@ -584,7 +584,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectBothFromInclusiveToInclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
@@ -634,7 +634,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestSelectBothFromExclusiveToExclusiveRange) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
TTableRangeOptions options(pgmBuilder.GetDefaultTableRangeOptions());
@@ -644,8 +644,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
to.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("bc"));
options.FromColumns = from;
options.ToColumns = to;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
- TReadRangeOptions::TFlags::ExcludeInitValue | TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ TReadRangeOptions::TFlags::ExcludeInitValue | TReadRangeOptions::TFlags::ExcludeTermValue);
TVector<TSelectColumn> columnsToRead;
columnsToRead.emplace_back("column1", 34, (ui32)NUdf::TDataType<ui32>::Id);
@@ -686,11 +686,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestAcquireLocks) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("locks",
- pgmBuilder.AcquireLocks(pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(0))));
+ pgmBuilder.AcquireLocks(pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(0))));
auto pgm = pgmBuilder.Build(pgmReturn, TKikimrProgramBuilder::TBindFlags::DisableOptimization).GetNode();
VerifyProgram(pgm, env);
@@ -699,7 +699,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestDiagnostics) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.NewEmptyListOfVoid();
pgmReturn = pgmBuilder.Append(pgmReturn, pgmBuilder.SetResult("diag", pgmBuilder.Diagnostics()));
@@ -711,7 +711,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestInvalidParameterName) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto paramsBuilder = pgmBuilder.GetParametersBuilder();
@@ -732,7 +732,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProgramBuilderTest) {
Y_UNIT_TEST(TestInvalidParameterType) {
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
- auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ auto functionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
TKikimrProgramBuilder pgmBuilder(env, *functionRegistry);
auto paramsBuilder = pgmBuilder.GetParametersBuilder();
diff --git a/ydb/core/engine/minikql/flat_local_tx_minikql.h b/ydb/core/engine/minikql/flat_local_tx_minikql.h
index 79008a28b0..0feabf20e6 100644
--- a/ydb/core/engine/minikql/flat_local_tx_minikql.h
+++ b/ydb/core/engine/minikql/flat_local_tx_minikql.h
@@ -156,7 +156,7 @@ class TFlatLocalMiniKQL : public NTabletFlatExecutor::ITransaction {
TScopedAlloc alloc(counters, appData->FunctionRegistry->SupportsSizedAllocators());
TTypeEnvironment typeEnv(alloc);
TLocalDbSchemeResolver dbResolver(txc.DB.GetScheme(), TabletId);
- const auto unguard = Unguard(alloc);
+ const auto unguard = Unguard(alloc);
auto future = ConvertToMiniKQL(expr, appData->FunctionRegistry, &typeEnv, &dbResolver);
future.Wait();
NYql::TConvertResult compileResult = future.GetValue();
diff --git a/ydb/core/engine/minikql/minikql_engine_host.cpp b/ydb/core/engine/minikql/minikql_engine_host.cpp
index 786accb35c..36c35f32cc 100644
--- a/ydb/core/engine/minikql/minikql_engine_host.cpp
+++ b/ydb/core/engine/minikql/minikql_engine_host.cpp
@@ -259,7 +259,7 @@ void TEngineHost::PinPages(const TVector<THolder<TKeyDesc>>& keys, ui64 pageFaul
throw TNotReadyTabletException();
}
-NUdf::TUnboxedValue TEngineHost::SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
+NUdf::TUnboxedValue TEngineHost::SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
TStructLiteral* columnIds, TOptionalType* returnType, const TReadTarget& readTarget,
const THolderFactory& holderFactory)
{
@@ -309,14 +309,14 @@ NUdf::TUnboxedValue TEngineHost::SelectRow(const TTableId& tableId, const TArray
}
if (NTable::EReady::Gone == ready) {
- return NUdf::TUnboxedValue();
+ return NUdf::TUnboxedValue();
}
- NUdf::TUnboxedValue* rowItems = nullptr;
- auto rowResult = holderFactory.CreateDirectArrayHolder(tags.size(), rowItems);
+ NUdf::TUnboxedValue* rowItems = nullptr;
+ auto rowResult = holderFactory.CreateDirectArrayHolder(tags.size(), rowItems);
ui64 rowBytes = 0;
- for (ui32 i = 0; i < tags.size(); ++i) {
+ for (ui32 i = 0; i < tags.size(); ++i) {
rowItems[i] = GetCellValue(dbRow.Get(i), cellTypes[i]);
rowBytes += dbRow.Get(i).IsNull() ? 1 : dbRow.Get(i).Size();
}
@@ -334,22 +334,22 @@ NUdf::TUnboxedValue TEngineHost::SelectRow(const TTableId& tableId, const TArray
Counters.SelectRowBytes += rowBytes;
Counters.SelectRowRows++;
- return std::move(rowResult);
+ return std::move(rowResult);
}
template<class TTableIt>
class TSelectRangeLazyRow : public TComputationValue<TSelectRangeLazyRow<TTableIt>>{
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- BuildValue(index);
- return GetPtr()[index];
- }
-
-public:
- ~TSelectRangeLazyRow() {
- for (ui32 i = 0; i < Size(); ++i) {
- (GetPtr() + i)->~TUnboxedValue();
- }
- }
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ BuildValue(index);
+ return GetPtr()[index];
+ }
+
+public:
+ ~TSelectRangeLazyRow() {
+ for (ui32 i = 0; i < Size(); ++i) {
+ (GetPtr() + i)->~TUnboxedValue();
+ }
+ }
void* operator new(size_t sz) = delete;
void* operator new[](size_t sz) = delete;
@@ -372,12 +372,12 @@ public:
return NUdf::TUnboxedValuePod(::new(buffer) TSelectRangeLazyRow(dbData, holderFactory, maskSize, systemColumnTags, shardId));
}
-
- void InvalidateDb() {
- for (ui32 i = 0; i < Size(); ++i) {
- BuildValue(i);
- }
- }
+
+ void InvalidateDb() {
+ for (ui32 i = 0; i < Size(); ++i) {
+ BuildValue(i);
+ }
+ }
void OwnDb(THolder<TTableIt>&& iter) {
Iter = std::move(iter);
@@ -401,17 +401,17 @@ private:
{
ClearMask();
for (ui32 i = 0; i < Size(); ++i) {
- ::new(GetPtr() + i) NUdf::TUnboxedValue();
+ ::new(GetPtr() + i) NUdf::TUnboxedValue();
}
}
private:
- inline NUdf::TUnboxedValue* GetPtr() const {
+ inline NUdf::TUnboxedValue* GetPtr() const {
return const_cast<NUdf::TUnboxedValue*>(reinterpret_cast<const NUdf::TUnboxedValue*>(this + 1));
}
inline ui64* GetMaskPtr() const {
- return reinterpret_cast<ui64*>(GetPtr() + Size());
+ return reinterpret_cast<ui64*>(GetPtr() + Size());
}
inline ui32 Size() const {
@@ -479,7 +479,7 @@ public:
TIterator(TMemoryUsageInfo* memInfo, const TSelectRangeLazyRowsList& list, TAutoPtr<TTableIt>&& iter,
const TSmallVec<NTable::TTag>& systemColumnTags, ui64 shardId)
: TBase(memInfo)
- , List(list)
+ , List(list)
, Iter(iter.Release())
, HasCurrent(false)
, Iterations(0)
@@ -488,14 +488,14 @@ public:
, SystemColumnTags(systemColumnTags)
, ShardId(shardId) {}
- bool Next(NUdf::TUnboxedValue& value) override {
- bool truncated = false;
-
+ bool Next(NUdf::TUnboxedValue& value) override {
+ bool truncated = false;
+
Clear();
-
+
while (Iter->Next(NTable::ENext::Data) == NTable::EReady::Data) {
TDbTupleRef tuple = Iter->GetKey();
-
+
++Iterations;
if (Iterations % PeriodicCallbackIterations == 0) {
List.EngineHost.ExecPeriodicCallback();
@@ -518,56 +518,56 @@ public:
}
if (skipRow) {
Clear();
- continue;
- }
-
- if ((List.ItemsLimit && Items >= List.ItemsLimit) || (List.BytesLimit && Bytes >= List.BytesLimit)) {
- truncated = true;
- break;
- }
-
- if (Items == 0) {
- TArrayRef<TCell> array(const_cast<TCell*>(tuple.Columns), tuple.ColumnCount);
- auto cells = TSerializedCellVec::Serialize(array);
+ continue;
+ }
+
+ if ((List.ItemsLimit && Items >= List.ItemsLimit) || (List.BytesLimit && Bytes >= List.BytesLimit)) {
+ truncated = true;
+ break;
+ }
+
+ if (Items == 0) {
+ TArrayRef<TCell> array(const_cast<TCell*>(tuple.Columns), tuple.ColumnCount);
+ auto cells = TSerializedCellVec::Serialize(array);
ui32 totalSize = sizeof(ui32) + tuple.ColumnCount * sizeof(NScheme::TTypeId) + cells.size();
- TString firstKey;
- firstKey.reserve(totalSize);
- firstKey.AppendNoAlias((const char*)&tuple.ColumnCount, sizeof(ui32));
- firstKey.AppendNoAlias((const char*)tuple.Types, tuple.ColumnCount * sizeof(NScheme::TTypeId));
- firstKey.AppendNoAlias(cells);
-
- if (List.FirstKey) {
- Y_VERIFY_DEBUG(*List.FirstKey == firstKey);
- } else {
- List.FirstKey = firstKey;
- }
- }
-
+ TString firstKey;
+ firstKey.reserve(totalSize);
+ firstKey.AppendNoAlias((const char*)&tuple.ColumnCount, sizeof(ui32));
+ firstKey.AppendNoAlias((const char*)tuple.Types, tuple.ColumnCount * sizeof(NScheme::TTypeId));
+ firstKey.AppendNoAlias(cells);
+
+ if (List.FirstKey) {
+ Y_VERIFY_DEBUG(*List.FirstKey == firstKey);
+ } else {
+ List.FirstKey = firstKey;
+ }
+ }
+
TDbTupleRef rowValues = Iter->GetValues();
- ui64 rowSize = 0;
- for (ui32 i = 0; i < rowValues.ColumnCount; ++i) {
+ ui64 rowSize = 0;
+ for (ui32 i = 0; i < rowValues.ColumnCount; ++i) {
rowSize += rowValues.Columns[i].IsNull() ? 1 : rowValues.Columns[i].Size();
- }
- // Some per-row overhead to deal with the case when no columns were requested
- rowSize = std::max(rowSize, (ui64)8);
-
- Items++;
- Bytes += rowSize;
+ }
+ // Some per-row overhead to deal with the case when no columns were requested
+ rowSize = std::max(rowSize, (ui64)8);
+
+ Items++;
+ Bytes += rowSize;
List.EngineHost.GetCounters().SelectRangeRows++;
List.EngineHost.GetCounters().SelectRangeBytes += rowSize;
List.KeyAccessSampler->AddSample(List.TableId, tuple.Cells());
-
- if (HasCurrent && CurrentRowValue.UniqueBoxed()) {
- CurrentRow()->Reuse(rowValues);
- } else {
+
+ if (HasCurrent && CurrentRowValue.UniqueBoxed()) {
+ CurrentRow()->Reuse(rowValues);
+ } else {
CurrentRowValue = TSelectRangeLazyRow<TTableIt>::Create(rowValues, List.HolderFactory, SystemColumnTags, ShardId);
- }
-
- value = CurrentRowValue;
- HasCurrent = true;
- return true;
- }
-
+ }
+
+ value = CurrentRowValue;
+ HasCurrent = true;
+ return true;
+ }
+
List.EngineHost.GetCounters().SelectRangeDeletedRowSkips += std::exchange(Iter->Stats.DeletedRowSkips, 0);
List.EngineHost.GetCounters().InvisibleRowSkips += std::exchange(Iter->Stats.InvisibleRowSkips, 0);
@@ -578,26 +578,26 @@ public:
throw TNotReadyTabletException();
}
- if (List.Truncated || List.SizeBytes) {
- Y_VERIFY_DEBUG(List.Truncated && *List.Truncated == truncated);
- Y_VERIFY_DEBUG(List.SizeBytes && *List.SizeBytes == Bytes);
- } else {
- List.Truncated = truncated;
- List.SizeBytes = Bytes;
- }
-
- CurrentRowValue = NUdf::TUnboxedValue();
- HasCurrent = false;
- return false;
- }
-
- ~TIterator() {
- if (HasCurrent) {
- if (!CurrentRowValue.UniqueBoxed()) {
+ if (List.Truncated || List.SizeBytes) {
+ Y_VERIFY_DEBUG(List.Truncated && *List.Truncated == truncated);
+ Y_VERIFY_DEBUG(List.SizeBytes && *List.SizeBytes == Bytes);
+ } else {
+ List.Truncated = truncated;
+ List.SizeBytes = Bytes;
+ }
+
+ CurrentRowValue = NUdf::TUnboxedValue();
+ HasCurrent = false;
+ return false;
+ }
+
+ ~TIterator() {
+ if (HasCurrent) {
+ if (!CurrentRowValue.UniqueBoxed()) {
CurrentRow()->OwnDb(std::move(Iter));
- }
- }
- }
+ }
+ }
+ }
private:
void Clear() {
if (HasCurrent) {
@@ -645,16 +645,16 @@ public:
, EngineHost(engineHost)
, KeyAccessSampler(keyAccessSampler)
{}
-
- NUdf::TUnboxedValue GetListIterator() const override {
- const TScheme::TTableInfo* tableInfo = Scheme.GetTableInfo(LocalTid);
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ const TScheme::TTableInfo* tableInfo = Scheme.GetTableInfo(LocalTid);
auto tableRange = RangeHolder.ToTableRange();
- TSmallVec<TRawTypeValue> keyFrom;
+ TSmallVec<TRawTypeValue> keyFrom;
TSmallVec<TRawTypeValue> keyTo;
ConvertTableKeys(Scheme, tableInfo, tableRange.From, keyFrom, nullptr);
ConvertTableKeys(Scheme, tableInfo, tableRange.To, keyTo, nullptr);
-
+
NTable::TKeyRange keyRange;
keyRange.MinKey = keyFrom;
keyRange.MaxKey = keyTo;
@@ -675,33 +675,33 @@ public:
}
}
- NUdf::TUnboxedValue GetTruncated() const {
+ NUdf::TUnboxedValue GetTruncated() const {
if (!Truncated) {
- for (const auto it = GetListIterator(); it.Skip();)
- continue;
+ for (const auto it = GetListIterator(); it.Skip();)
+ continue;
}
Y_VERIFY_DEBUG(Truncated);
- return NUdf::TUnboxedValuePod(*Truncated);
+ return NUdf::TUnboxedValuePod(*Truncated);
}
- NUdf::TUnboxedValue GetFirstKey() const {
+ NUdf::TUnboxedValue GetFirstKey() const {
if (!FirstKey) {
- GetListIterator().Skip();
+ GetListIterator().Skip();
}
TString key = FirstKey ? *FirstKey : TString();
- return MakeString(key);
+ return MakeString(key);
}
- NUdf::TUnboxedValue GetSizeBytes() const {
+ NUdf::TUnboxedValue GetSizeBytes() const {
if (!SizeBytes) {
- for (const auto it = GetListIterator(); it.Skip();)
- continue;
+ for (const auto it = GetListIterator(); it.Skip();)
+ continue;
}
Y_VERIFY_DEBUG(SizeBytes);
- return NUdf::TUnboxedValuePod(*SizeBytes);
+ return NUdf::TUnboxedValuePod(*SizeBytes);
}
private:
@@ -732,23 +732,23 @@ public:
const TSmallVec<NTable::TTag>& tags, const TSmallVec<bool>& skipNullKeys, const TTableRange& range,
ui64 itemsLimit, ui64 bytesLimit, bool reverse, TEngineHost& engineHost,
const TSmallVec<NTable::TTag>& systemColumnTags, ui64 shardId, IKeyAccessSampler::TPtr keyAccessSampler)
- : TComputationValue(&holderFactory.GetMemInfo())
+ : TComputationValue(&holderFactory.GetMemInfo())
, List(NUdf::TUnboxedValuePod(new TSelectRangeLazyRowsList(db, scheme, holderFactory, tableId, localTid, tags,
skipNullKeys, range, itemsLimit, bytesLimit, reverse, engineHost, systemColumnTags, shardId, keyAccessSampler))) {}
-
-private:
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- TSelectRangeLazyRowsList* list = static_cast<TSelectRangeLazyRowsList*>(List.AsBoxed().Get());
- switch (index) {
- case 0: return List;
- case 1: return list->GetTruncated();
- case 2: return list->GetFirstKey();
- case 3: return list->GetSizeBytes();
- }
-
- Y_FAIL("TSelectRangeResult: Index out of range.");
- }
-
+
+private:
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ TSelectRangeLazyRowsList* list = static_cast<TSelectRangeLazyRowsList*>(List.AsBoxed().Get());
+ switch (index) {
+ case 0: return List;
+ case 1: return list->GetTruncated();
+ case 2: return list->GetFirstKey();
+ case 3: return list->GetSizeBytes();
+ }
+
+ Y_FAIL("TSelectRangeResult: Index out of range.");
+ }
+
NUdf::TUnboxedValue List;
};
@@ -783,7 +783,7 @@ static TSmallVec<bool> CreateBoolVec(const TListLiteral* list) {
return res;
}
-NUdf::TUnboxedValue TEngineHost::SelectRange(const TTableId& tableId, const TTableRange& range,
+NUdf::TUnboxedValue TEngineHost::SelectRange(const TTableId& tableId, const TTableRange& range,
TStructLiteral* columnIds, TListLiteral* skipNullKeys, TStructType* returnType, const TReadTarget& readTarget,
ui64 itemsLimit, ui64 bytesLimit, bool reverse, std::pair<const TListLiteral*, const TListLiteral*> forbidNullArgs,
const THolderFactory& holderFactory)
@@ -961,7 +961,7 @@ void AnalyzeRowType(TStructLiteral* columnIds, TSmallVec<NTable::TTag>& tags, TS
NUdf::TUnboxedValue GetCellValue(const TCell& cell, NScheme::TTypeId type) {
if (cell.IsNull()) {
- return NUdf::TUnboxedValue();
+ return NUdf::TUnboxedValue();
}
switch (type) {
diff --git a/ydb/core/engine/minikql/minikql_engine_host.h b/ydb/core/engine/minikql/minikql_engine_host.h
index 8b832f7e65..012ee6891b 100644
--- a/ydb/core/engine/minikql/minikql_engine_host.h
+++ b/ydb/core/engine/minikql/minikql_engine_host.h
@@ -103,11 +103,11 @@ public:
ui64 CalculateResultSize(const TKeyDesc& key) const override;
void PinPages(const TVector<THolder<TKeyDesc>>& keys, ui64 pageFaultCount) override;
- NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
+ NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
TStructLiteral* columnIds, TOptionalType* returnType, const TReadTarget& readTarget,
const THolderFactory& holderFactory) override;
- NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
+ NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
TStructLiteral* columnIds, TListLiteral* skipNullKeys, TStructType* returnType,
const TReadTarget& readTarget, ui64 itemsLimit, ui64 bytesLimit, bool reverse,
std::pair<const TListLiteral*, const TListLiteral*> forbidNullArgs, const THolderFactory& holderFactory) override;
diff --git a/ydb/core/engine/mkql_engine_flat.cpp b/ydb/core/engine/mkql_engine_flat.cpp
index 3645787716..c7fe388eef 100644
--- a/ydb/core/engine/mkql_engine_flat.cpp
+++ b/ydb/core/engine/mkql_engine_flat.cpp
@@ -95,18 +95,18 @@ TStructLiteral& GetPgmReplyStruct(TStructLiteral& pgmStruct) {
class TCallableResults {
public:
- void AddResult(ui32 id, const TStringBuf& result, const TTypeEnvironment& env) {
- const auto insertResult = ResultsMap.emplace(id, env.NewStringValue(result));
+ void AddResult(ui32 id, const TStringBuf& result, const TTypeEnvironment& env) {
+ const auto insertResult = ResultsMap.emplace(id, env.NewStringValue(result));
MKQL_ENSURE(insertResult.second, "TCallableResults: duplicate result id: " << id);
}
- typedef std::unordered_map<ui32, NUdf::TUnboxedValue> TResultsMap;
+ typedef std::unordered_map<ui32, NUdf::TUnboxedValue> TResultsMap;
+
+ const TResultsMap& GetMap() const { return ResultsMap; }
- const TResultsMap& GetMap() const { return ResultsMap; }
-
public:
TString ToString(const THolderFactory& holderFactory, const TTypeEnvironment& env) const {
- const NUdf::TUnboxedValue value(GetResultsValue(holderFactory));
+ const NUdf::TUnboxedValue value(GetResultsValue(holderFactory));
return TString(TValuePacker(false, GetResultsType(env)).Pack(value));
}
@@ -117,11 +117,11 @@ public:
TValuePacker packer(false, GetResultsType(env));
NUdf::TUnboxedValue value = packer.Unpack(valueStr, holderFactory);
- const auto it = value.GetListIterator();
- for (NUdf::TUnboxedValue resultStruct; it.Next(resultStruct);) {
- ui32 id = resultStruct.GetElement(0).Get<ui32>();
- NUdf::TUnboxedValue result = resultStruct.GetElement(1);
- callableResults.AddResult(id, result.AsStringRef(), env);
+ const auto it = value.GetListIterator();
+ for (NUdf::TUnboxedValue resultStruct; it.Next(resultStruct);) {
+ ui32 id = resultStruct.GetElement(0).Get<ui32>();
+ NUdf::TUnboxedValue result = resultStruct.GetElement(1);
+ callableResults.AddResult(id, result.AsStringRef(), env);
}
return callableResults;
@@ -132,26 +132,26 @@ private:
const std::array<std::pair<TString, TType*>, 2> members = {{
{"Id", TDataType::Create(NUdf::TDataType<ui32>::Id, env)},
{"Result", TDataType::Create(NUdf::TDataType<char*>::Id, env)}
- }};
+ }};
- return TListType::Create(TStructType::Create(members.data(), members.size(), env), env);
+ return TListType::Create(TStructType::Create(members.data(), members.size(), env), env);
}
- NUdf::TUnboxedValue GetResultsValue(const THolderFactory& holderFactory) const {
- NUdf::TUnboxedValue* items = nullptr;
- auto results = holderFactory.CreateDirectArrayHolder(ResultsMap.size(), items);
- for (const auto& pair : ResultsMap) {
- NUdf::TUnboxedValue* resultItems = nullptr;
- *items++ = holderFactory.CreateDirectArrayHolder(2, resultItems);
- resultItems[0] = NUdf::TUnboxedValuePod(pair.first);
- resultItems[1] = pair.second;
+ NUdf::TUnboxedValue GetResultsValue(const THolderFactory& holderFactory) const {
+ NUdf::TUnboxedValue* items = nullptr;
+ auto results = holderFactory.CreateDirectArrayHolder(ResultsMap.size(), items);
+ for (const auto& pair : ResultsMap) {
+ NUdf::TUnboxedValue* resultItems = nullptr;
+ *items++ = holderFactory.CreateDirectArrayHolder(2, resultItems);
+ resultItems[0] = NUdf::TUnboxedValuePod(pair.first);
+ resultItems[1] = pair.second;
}
- return std::move(results);
+ return std::move(results);
}
private:
- TResultsMap ResultsMap;
+ TResultsMap ResultsMap;
};
TRuntimeNode ReplaceAsVoid(TCallable& callable, const TTypeEnvironment& env) {
@@ -177,7 +177,7 @@ void ExtractResultType(TCallable& callable, const TTypeEnvironment& env, TMap<TS
const auto& labelData = static_cast<const TDataLiteral&>(*labelInput.GetNode());
MKQL_ENSURE(labelData.GetType()->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected string");
- TStringBuf label = labelData.AsValue().AsStringRef();
+ TStringBuf label = labelData.AsValue().AsStringRef();
MKQL_ENSURE(!label.empty(), "Empty result label is not allowed");
MKQL_ENSURE(!label.StartsWith(TxInternalResultPrefix),
TStringBuilder() << "Label can't be used in SetResult as it's reserved for internal purposes: " << label);
@@ -233,7 +233,7 @@ ui64 ExtractAcquireLocksTxId(TCallable& callable) {
const auto& lockTxIdData = static_cast<const TDataLiteral&>(*lockTxIdInput.GetNode());
MKQL_ENSURE(lockTxIdData.GetType()->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected Uint64");
- return lockTxIdData.AsValue().Get<ui64>();
+ return lockTxIdData.AsValue().Get<ui64>();
}
class TEngineFlat : public IEngineFlat {
@@ -605,16 +605,16 @@ public:
{
TMemoryUsageInfo memInfo("Memory");
- THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
+ THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
for (auto& pair : ExecutionReplies) {
const TString& reply = pair.second;
TCallableResults results = TCallableResults::FromString(reply, holderFactory, Env);
- for (const auto& pair : results.GetMap()) {
+ for (const auto& pair : results.GetMap()) {
ui32 id = pair.first;
- const auto nodeIt = ProxyRepliesCallables.find(id);
+ const auto nodeIt = ProxyRepliesCallables.find(id);
if (nodeIt == ProxyRepliesCallables.end()) {
AddError("BuildResult", __LINE__, Sprintf(
"Bad shard reply, node %" PRIu32 " not found", id).data());
@@ -633,11 +633,11 @@ public:
GetFlatProxyExecutionFactory(execData),
Settings.FunctionRegistry,
NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception,
- Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
+ Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
Pattern = MakeComputationPattern(ProxyProgramExplorer, ProxyProgram, {}, opts);
ResultGraph = Pattern->Clone(opts.ToComputationOptions(Settings.RandomProvider, Settings.TimeProvider));
- const TBindTerminator bind(ResultGraph->GetTerminator());
+ const TBindTerminator bind(ResultGraph->GetTerminator());
value = ResultGraph->GetValue();
}
@@ -1023,11 +1023,11 @@ public:
GetFlatShardExecutionFactory(execData, true),
Settings.FunctionRegistry,
NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception,
- Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
+ Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
auto pattern = MakeComputationPattern(explorer, runPgm, {}, opts);
auto graph = pattern->Clone(opts.ToComputationOptions(Settings.RandomProvider, Settings.TimeProvider));
- const TBindTerminator bind(graph->GetTerminator());
+ const TBindTerminator bind(graph->GetTerminator());
graph->Prepare();
}
@@ -1102,7 +1102,7 @@ public:
THashMap<ui64, TCallableResults> resultsPerTarget;
TMemoryUsageInfo memInfo("Memory");
- THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
+ THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
for (auto pgm : ProgramPerOrigin) {
auto& pgmStruct = GetPgmStruct(pgm.second);
@@ -1304,13 +1304,13 @@ public:
ExecutionReplies.clear();
try {
TMemoryUsageInfo memInfo("Memory");
- THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
+ THolderFactory holderFactory(Alloc.Ref(), memInfo, Settings.FunctionRegistry);
for (auto pgm : ProgramPerOrigin) {
TShardExecData execData(Settings, Strings, StepTxId);
for (auto& rs: IncomingReadsets) {
TCallableResults results = TCallableResults::FromString(rs, holderFactory, Env);
- for (const auto& result : results.GetMap()) {
+ for (const auto& result : results.GetMap()) {
execData.Results[result.first].emplace_back(result.second.AsStringRef());
}
}
@@ -1352,16 +1352,16 @@ public:
GetFlatShardExecutionFactory(execData, false),
Settings.FunctionRegistry,
NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception,
- Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
+ Settings.LlvmRuntime ? "" : "OFF", EGraphPerProcess::Multi);
auto pattern = MakeComputationPattern(runExplorer, runPgm, {}, opts);
auto compOpts = opts.ToComputationOptions(Settings.RandomProvider, Settings.TimeProvider);
THolder<IComputationGraph> runGraph = pattern->Clone(compOpts);
- const TBindTerminator bind(runGraph->GetTerminator());
-
+ const TBindTerminator bind(runGraph->GetTerminator());
+
NUdf::TUnboxedValue runValue = runGraph->GetValue();
- NUdf::TUnboxedValue replyValue = runValue.GetElement(0);
- NUdf::TUnboxedValue writeValue = runValue.GetElement(1);
+ NUdf::TUnboxedValue replyValue = runValue.GetElement(0);
+ NUdf::TUnboxedValue writeValue = runValue.GetElement(1);
TEngineFlatApplyContext applyCtx;
applyCtx.Host = Settings.Host;
@@ -1376,10 +1376,10 @@ public:
auto memberName = replyStruct.GetType()->GetMemberName(i);
ui32 resultId = FromString<ui32>(memberName);
- NUdf::TUnboxedValue resultValue = replyValue.GetElement(i);
+ NUdf::TUnboxedValue resultValue = replyValue.GetElement(i);
auto returnType = GetActualReturnType(*callable, Env, Strings);
TValuePacker packer(false, returnType);
- replyResults.AddResult(resultId, packer.Pack(resultValue), Env);
+ replyResults.AddResult(resultId, packer.Pack(resultValue), Env);
}
auto replyStr = replyResults.ToString(holderFactory, Env);
diff --git a/ydb/core/engine/mkql_engine_flat_extfunc.cpp b/ydb/core/engine/mkql_engine_flat_extfunc.cpp
index 0399c2e7e4..414d3aeeb4 100644
--- a/ydb/core/engine/mkql_engine_flat_extfunc.cpp
+++ b/ydb/core/engine/mkql_engine_flat_extfunc.cpp
@@ -25,7 +25,7 @@ namespace {
data = opt->GetItem();
}
- const auto literal = AS_VALUE(TDataLiteral, data);
+ const auto literal = AS_VALUE(TDataLiteral, data);
return MakeCell(literal->GetType()->GetSchemeType(), literal->AsValue(), env, false);
}
@@ -37,21 +37,21 @@ namespace {
}
}
- TCell ExtractCell(const NUdf::TUnboxedValue& value, TType* type, const TTypeEnvironment& env) {
- if (type->IsOptional() && !value) {
- return TCell();
- }
+ TCell ExtractCell(const NUdf::TUnboxedValue& value, TType* type, const TTypeEnvironment& env) {
+ if (type->IsOptional() && !value) {
+ return TCell();
+ }
+
+ const auto dataType = type->IsOptional()
+ ? AS_TYPE(TDataType, AS_TYPE(TOptionalType, type)->GetItemType()) : AS_TYPE(TDataType, type);
- const auto dataType = type->IsOptional()
- ? AS_TYPE(TDataType, AS_TYPE(TOptionalType, type)->GetItemType()) : AS_TYPE(TDataType, type);
+ return MakeCell(dataType->GetSchemeType(), value, env);
+ }
- return MakeCell(dataType->GetSchemeType(), value, env);
- }
-
void ExtractRow(const NUdf::TUnboxedValue& row, TTupleType* rowType, TVector<TCell>& cells, const TTypeEnvironment& env) {
- cells.resize(rowType->GetElementsCount());
+ cells.resize(rowType->GetElementsCount());
for (ui32 i = 0; i < rowType->GetElementsCount(); ++i) {
- cells[i] = ExtractCell(row.GetElement(i), rowType->GetElementType(i), env);
+ cells[i] = ExtractCell(row.GetElement(i), rowType->GetElementType(i), env);
}
}
@@ -61,8 +61,8 @@ namespace {
: TComputationValue(memInfo)
{
}
- private:
- void Apply(NUdf::IApplyContext& applyContext) const override {
+ private:
+ void Apply(NUdf::IApplyContext& applyContext) const override {
auto& engineCtx = *CheckedCast<TEngineFlatApplyContext*>(&applyContext);
engineCtx.IsAborted = true;
}
@@ -70,24 +70,24 @@ namespace {
class TEmptyRangeHolder : public TComputationValue<TEmptyRangeHolder> {
public:
- TEmptyRangeHolder(const THolderFactory& holderFactory)
- : TComputationValue(&holderFactory.GetMemInfo())
- , EmptyContainer(holderFactory.GetEmptyContainer())
+ TEmptyRangeHolder(const THolderFactory& holderFactory)
+ : TComputationValue(&holderFactory.GetMemInfo())
+ , EmptyContainer(holderFactory.GetEmptyContainer())
{
}
- private:
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- switch (index) {
- case 0: return EmptyContainer;
- case 1: return NUdf::TUnboxedValuePod(false);
- case 2: return NUdf::TUnboxedValuePod::Zero();
- case 3: return NUdf::TUnboxedValuePod((ui64)0);
- }
-
- MKQL_ENSURE(false, "Wrong index: " << index);
- }
-
- const NUdf::TUnboxedValue EmptyContainer;
+ private:
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ switch (index) {
+ case 0: return EmptyContainer;
+ case 1: return NUdf::TUnboxedValuePod(false);
+ case 2: return NUdf::TUnboxedValuePod::Zero();
+ case 3: return NUdf::TUnboxedValuePod((ui64)0);
+ }
+
+ MKQL_ENSURE(false, "Wrong index: " << index);
+ }
+
+ const NUdf::TUnboxedValue EmptyContainer;
};
class TResultWrapper : public TMutableComputationNode<TResultWrapper> {
@@ -116,8 +116,8 @@ namespace {
Y_VERIFY(payloads.size() == labels.size());
}
- private:
- void Apply(NUdf::IApplyContext& applyContext) const override {
+ private:
+ void Apply(NUdf::IApplyContext& applyContext) const override {
auto& engineCtx = *CheckedCast<TEngineFlatApplyContext*>(&applyContext);
for (ui32 i = 0; i < Payloads.size(); ++i) {
(*engineCtx.ResultValues)[Labels[i]] = Payloads[i];
@@ -139,13 +139,13 @@ namespace {
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TResult>(Payload->GetValue(ctx), Label);
}
- private:
- void RegisterDependencies() const final {
- DependsOn(Payload);
+ private:
+ void RegisterDependencies() const final {
+ DependsOn(Payload);
}
TStringBuf Label;
@@ -164,12 +164,12 @@ namespace {
Locks.push_back(locks2);
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TResultWrapper::TResult>(Locks, Labels);
}
- private:
- void RegisterDependencies() const final {}
+ private:
+ void RegisterDependencies() const final {}
TVector<TStringBuf> Labels;
TVector<NUdf::TUnboxedValue> Locks;
@@ -183,18 +183,18 @@ namespace {
, Diagnostics(std::move(diags))
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TResultWrapper::TResult>(Diagnostics, TxInfoResultLabel);
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TResultWrapper::TResult>(Diagnostics, TxInfoResultLabel);
}
- private:
- void RegisterDependencies() const final {}
+ private:
+ void RegisterDependencies() const final {}
- const NUdf::TUnboxedValue Diagnostics;
+ const NUdf::TUnboxedValue Diagnostics;
};
IComputationNode* WrapAsVoid(const TComputationNodeFactoryContext& ctx) {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValue::Void());
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValue::Void());
}
class TDummyWrapper : public TMutableComputationNode<TDummyWrapper> {
@@ -204,11 +204,11 @@ namespace {
: TBaseComputation(mutables)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&) const {
Y_FAIL("Failed to build value for dummy node");
}
- private:
- void RegisterDependencies() const final {}
+ private:
+ void RegisterDependencies() const final {}
};
class TEraseRowWrapper : public TMutableComputationNode<TEraseRowWrapper> {
@@ -218,26 +218,26 @@ namespace {
class TResult : public TComputationValue<TResult> {
public:
- TResult(TMemoryUsageInfo* memInfo, const TEraseRowWrapper* owner, const NUdf::TUnboxedValue& row)
+ TResult(TMemoryUsageInfo* memInfo, const TEraseRowWrapper* owner, const NUdf::TUnboxedValue& row)
: TComputationValue(memInfo)
, Owner(owner)
, Row(row)
{
}
- private:
- void Apply(NUdf::IApplyContext& applyContext) const override {
+ private:
+ void Apply(NUdf::IApplyContext& applyContext) const override {
auto& engineCtx = *CheckedCast<TEngineFlatApplyContext*>(&applyContext);
TVector<TCell> row;
- ExtractRow(Row, Owner->RowType, row, *engineCtx.Env);
+ ExtractRow(Row, Owner->RowType, row, *engineCtx.Env);
if (!engineCtx.Host->IsPathErased(Owner->TableId) && engineCtx.Host->IsMyKey(Owner->TableId, row)) {
engineCtx.Host->EraseRow(Owner->TableId, row);
}
}
- const TEraseRowWrapper *const Owner;
- const NUdf::TUnboxedValue Row;
+ const TEraseRowWrapper *const Owner;
+ const NUdf::TUnboxedValue Row;
};
TEraseRowWrapper(TComputationMutables& mutables, const TTableId& tableId, TTupleType* rowType, IComputationNode* row)
@@ -248,13 +248,13 @@ namespace {
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TResult>(this, Row->GetValue(ctx));
}
- private:
- void RegisterDependencies() const final {
- DependsOn(Row);
+ private:
+ void RegisterDependencies() const final {
+ DependsOn(Row);
}
const TTableId TableId;
@@ -269,21 +269,21 @@ namespace {
class TResult : public TComputationValue<TResult> {
public:
- TResult(TMemoryUsageInfo* memInfo, const TUpdateRowWrapper* owner,
- NUdf::TUnboxedValue&& row,
- NUdf::TUnboxedValue&& update)
+ TResult(TMemoryUsageInfo* memInfo, const TUpdateRowWrapper* owner,
+ NUdf::TUnboxedValue&& row,
+ NUdf::TUnboxedValue&& update)
: TComputationValue(memInfo)
, Owner(owner)
- , Row(std::move(row))
- , Update(std::move(update))
+ , Row(std::move(row))
+ , Update(std::move(update))
{
}
- private:
- void Apply(NUdf::IApplyContext& applyContext) const override {
+ private:
+ void Apply(NUdf::IApplyContext& applyContext) const override {
auto& engineCtx = *CheckedCast<TEngineFlatApplyContext*>(&applyContext);
TVector<TCell> row;
- ExtractRow(Row, Owner->RowType, row, *engineCtx.Env);
+ ExtractRow(Row, Owner->RowType, row, *engineCtx.Env);
if (!engineCtx.Host->IsPathErased(Owner->TableId) && engineCtx.Host->IsMyKey(Owner->TableId, row)) {
auto updateStruct = Owner->UpdateStruct;
@@ -300,16 +300,16 @@ namespace {
else if (!type->IsTuple()) {
// write
cmd.Operation = TKeyDesc::EColumnOperation::Set;
- cmd.Value = ExtractCell(Update.GetElement(i), type, *engineCtx.Env);
+ cmd.Value = ExtractCell(Update.GetElement(i), type, *engineCtx.Env);
} else {
// inplace update
cmd.Operation = TKeyDesc::EColumnOperation::InplaceUpdate;
- auto item = Update.GetElement(i);
- auto mode = item.GetElement(0);
+ auto item = Update.GetElement(i);
+ auto mode = item.GetElement(0);
auto modeBuf = mode.AsStringRef();
cmd.InplaceUpdateMode = (EInplaceUpdateMode)*(const ui8*)modeBuf.Data();
- cmd.Value = ExtractCell(item.GetElement(1),
- AS_TYPE(TTupleType, type)->GetElementType(1), *engineCtx.Env);
+ cmd.Value = ExtractCell(item.GetElement(1),
+ AS_TYPE(TTupleType, type)->GetElementType(1), *engineCtx.Env);
}
}
@@ -317,9 +317,9 @@ namespace {
}
}
- const TUpdateRowWrapper *const Owner;
- const NUdf::TUnboxedValue Row;
- const NUdf::TUnboxedValue Update;
+ const TUpdateRowWrapper *const Owner;
+ const NUdf::TUnboxedValue Row;
+ const NUdf::TUnboxedValue Update;
};
TUpdateRowWrapper(TComputationMutables& mutables, const TTableId& tableId, TTupleType* rowType, IComputationNode* row,
@@ -333,14 +333,14 @@ namespace {
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TResult>(this, Row->GetValue(ctx), Update->GetValue(ctx));
}
- private:
- void RegisterDependencies() const final {
- DependsOn(Row);
- DependsOn(Update);
+ private:
+ void RegisterDependencies() const final {
+ DependsOn(Row);
+ DependsOn(Update);
}
const TTableId TableId;
@@ -363,7 +363,7 @@ namespace {
const auto& labelData = static_cast<const TDataLiteral&>(*labelInput.GetNode());
MKQL_ENSURE(labelData.GetType()->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected string");
- TStringBuf label = labelData.AsValue().AsStringRef();
+ TStringBuf label = labelData.AsValue().AsStringRef();
auto payloadNode = LocateNode(ctx.NodeLocator, callable, 1);
return new TResultWrapper(ctx.Mutables, label, payloadNode);
@@ -382,15 +382,15 @@ namespace {
auto structType = GetTxLockType(ctx.Env, false);
- NUdf::TUnboxedValue *listItems = nullptr;
- auto locksList = ctx.HolderFactory.CreateDirectArrayHolder(txLocks.size(), listItems);
+ NUdf::TUnboxedValue *listItems = nullptr;
+ auto locksList = ctx.HolderFactory.CreateDirectArrayHolder(txLocks.size(), listItems);
for (auto& txLock : txLocks) {
- NUdf::TUnboxedValue *items = nullptr;
- *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), items);
- items[structType->GetMemberIndex("Counter")] = NUdf::TUnboxedValuePod(txLock.Counter);
- items[structType->GetMemberIndex("DataShard")] = NUdf::TUnboxedValuePod(txLock.DataShard);
- items[structType->GetMemberIndex("Generation")] = NUdf::TUnboxedValuePod(txLock.Generation);
- items[structType->GetMemberIndex("LockId")] = NUdf::TUnboxedValuePod(txLock.LockId);
+ NUdf::TUnboxedValue *items = nullptr;
+ *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), items);
+ items[structType->GetMemberIndex("Counter")] = NUdf::TUnboxedValuePod(txLock.Counter);
+ items[structType->GetMemberIndex("DataShard")] = NUdf::TUnboxedValuePod(txLock.DataShard);
+ items[structType->GetMemberIndex("Generation")] = NUdf::TUnboxedValuePod(txLock.Generation);
+ items[structType->GetMemberIndex("LockId")] = NUdf::TUnboxedValuePod(txLock.LockId);
}
auto structType2 = GetTxLockType(ctx.Env, true);
@@ -418,28 +418,28 @@ namespace {
auto structType = GetDiagnosticsType(ctx.Env);
- NUdf::TUnboxedValue *listItems = nullptr;
- auto diagList = ctx.HolderFactory.CreateDirectArrayHolder(tabletInfos.size(), listItems);
+ NUdf::TUnboxedValue *listItems = nullptr;
+ auto diagList = ctx.HolderFactory.CreateDirectArrayHolder(tabletInfos.size(), listItems);
for (auto& info : tabletInfos) {
- NUdf::TUnboxedValue *items = nullptr;
- *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), items);
-
- items[structType->GetMemberIndex("ActorIdRawX1")] = NUdf::TUnboxedValuePod(info.ActorId.first);
- items[structType->GetMemberIndex("ActorIdRawX2")] = NUdf::TUnboxedValuePod(info.ActorId.second);
- items[structType->GetMemberIndex("TabletId")] = NUdf::TUnboxedValuePod(info.TabletId);
- items[structType->GetMemberIndex("Generation")] = NUdf::TUnboxedValuePod(info.TabletGenStep.first);
- items[structType->GetMemberIndex("GenStep")] = NUdf::TUnboxedValuePod(info.TabletGenStep.second);
+ NUdf::TUnboxedValue *items = nullptr;
+ *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), items);
+
+ items[structType->GetMemberIndex("ActorIdRawX1")] = NUdf::TUnboxedValuePod(info.ActorId.first);
+ items[structType->GetMemberIndex("ActorIdRawX2")] = NUdf::TUnboxedValuePod(info.ActorId.second);
+ items[structType->GetMemberIndex("TabletId")] = NUdf::TUnboxedValuePod(info.TabletId);
+ items[structType->GetMemberIndex("Generation")] = NUdf::TUnboxedValuePod(info.TabletGenStep.first);
+ items[structType->GetMemberIndex("GenStep")] = NUdf::TUnboxedValuePod(info.TabletGenStep.second);
items[structType->GetMemberIndex("IsFollower")] = NUdf::TUnboxedValuePod(info.IsFollower);
- items[structType->GetMemberIndex("TxStep")] = NUdf::TUnboxedValuePod(info.TxInfo.StepTxId.first);
- items[structType->GetMemberIndex("TxId")] = NUdf::TUnboxedValuePod(info.TxInfo.StepTxId.second);
- items[structType->GetMemberIndex("Status")] = NUdf::TUnboxedValuePod(info.TxInfo.Status);
+ items[structType->GetMemberIndex("TxStep")] = NUdf::TUnboxedValuePod(info.TxInfo.StepTxId.first);
+ items[structType->GetMemberIndex("TxId")] = NUdf::TUnboxedValuePod(info.TxInfo.StepTxId.second);
+ items[structType->GetMemberIndex("Status")] = NUdf::TUnboxedValuePod(info.TxInfo.Status);
items[structType->GetMemberIndex("PrepareArriveTime")] =
- NUdf::TUnboxedValuePod(info.TxInfo.PrepareArriveTime.MilliSeconds());
+ NUdf::TUnboxedValuePod(info.TxInfo.PrepareArriveTime.MilliSeconds());
items[structType->GetMemberIndex("ProposeLatency")] =
- NUdf::TUnboxedValuePod(info.TxInfo.ProposeLatency.MilliSeconds());
+ NUdf::TUnboxedValuePod(info.TxInfo.ProposeLatency.MilliSeconds());
items[structType->GetMemberIndex("ExecLatency")] =
- NUdf::TUnboxedValuePod(info.TxInfo.ExecLatency.MilliSeconds());
+ NUdf::TUnboxedValuePod(info.TxInfo.ExecLatency.MilliSeconds());
}
return new TDiagnosticsWrapper(ctx.Mutables, std::move(diagList));
@@ -447,7 +447,7 @@ namespace {
IComputationNode* WrapAbort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected zero args");
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TAbortHolder(&ctx.HolderFactory.GetMemInfo())));
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TAbortHolder(&ctx.HolderFactory.GetMemInfo())));
}
IComputationNode* WrapStepTxId(TCallable& callable, const TComputationNodeFactoryContext& ctx,
@@ -458,12 +458,12 @@ namespace {
TVector<TType*> tupleTypes(2, ui64Type);
auto tupleType = TTupleType::Create(tupleTypes.size(), tupleTypes.data(), ctx.Env);
- NUdf::TUnboxedValue* items = nullptr;
- auto tuple = ctx.HolderFactory.CreateDirectArrayHolder(tupleType->GetElementsCount(), items);
- items[0] = NUdf::TUnboxedValuePod(stepTxId.first);
- items[1] = NUdf::TUnboxedValuePod(stepTxId.second);
+ NUdf::TUnboxedValue* items = nullptr;
+ auto tuple = ctx.HolderFactory.CreateDirectArrayHolder(tupleType->GetElementsCount(), items);
+ items[0] = NUdf::TUnboxedValuePod(stepTxId.first);
+ items[1] = NUdf::TUnboxedValuePod(stepTxId.second);
- return ctx.NodeFactory.CreateImmutableNode(std::move(tuple));
+ return ctx.NodeFactory.CreateImmutableNode(std::move(tuple));
}
IComputationNode* WrapConcatenatedResults(TCallable& callable, TIncomingResults::const_iterator resultIt,
@@ -474,17 +474,17 @@ namespace {
TUnboxedValueVector lists;
TValuePacker listPacker(false, returnType);
- for (const auto& result : resultIt->second) {
- lists.emplace_back(listPacker.Unpack(result, ctx.HolderFactory));
+ for (const auto& result : resultIt->second) {
+ lists.emplace_back(listPacker.Unpack(result, ctx.HolderFactory));
}
- return ctx.NodeFactory.CreateImmutableNode(ctx.HolderFactory.Create<TExtendListValue>(std::move(lists)));
+ return ctx.NodeFactory.CreateImmutableNode(ctx.HolderFactory.Create<TExtendListValue>(std::move(lists)));
}
IComputationNode* WrapMergedSelectRow(TCallable& callable, TIncomingResults& results,
const THashSet<ui32>& localReadCallables, IEngineFlatHost* host, const TComputationNodeFactoryContext& ctx)
{
- TUnboxedValueVector values;
+ TUnboxedValueVector values;
if (localReadCallables.contains(callable.GetUniqueId())) {
values.push_back(PerformLocalSelectRow(callable, *host, ctx.HolderFactory, ctx.Env));
}
@@ -504,68 +504,68 @@ namespace {
return ctx.NodeFactory.CreateOptionalNode(nullptr);
}
- auto choosenValue = std::move(values.front());
+ auto choosenValue = std::move(values.front());
for (size_t i = 1; i < values.size(); ++i) {
- if (auto& value = values[i]) {
- MKQL_ENSURE(!choosenValue, "Multiple non-empty results for SelectRow");
- choosenValue = std::move(value);
+ if (auto& value = values[i]) {
+ MKQL_ENSURE(!choosenValue, "Multiple non-empty results for SelectRow");
+ choosenValue = std::move(value);
}
}
- return ctx.NodeFactory.CreateImmutableNode(std::move(choosenValue));
+ return ctx.NodeFactory.CreateImmutableNode(std::move(choosenValue));
}
class TPartialList : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& listIterator, ui64 itemsLimit)
- : TComputationValue(memInfo)
- , ListIterator(std::move(listIterator))
+ TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& listIterator, ui64 itemsLimit)
+ : TComputationValue(memInfo)
+ , ListIterator(std::move(listIterator))
, ItemsLimit(itemsLimit)
, ItemsCount(0) {}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (ItemsCount >= ItemsLimit) {
- return false;
- }
-
- MKQL_ENSURE(ListIterator.Next(value), "Unexpected end of list");
- ++ItemsCount;
- return true;
- }
-
- bool Skip() override {
- if (ItemsCount >= ItemsLimit) {
- return false;
- }
-
- MKQL_ENSURE(ListIterator.Skip(), "Unexpected end of list");
- ++ItemsCount;
- return true;
- }
-
- const NUdf::TUnboxedValue ListIterator;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (ItemsCount >= ItemsLimit) {
+ return false;
+ }
+
+ MKQL_ENSURE(ListIterator.Next(value), "Unexpected end of list");
+ ++ItemsCount;
+ return true;
+ }
+
+ bool Skip() override {
+ if (ItemsCount >= ItemsLimit) {
+ return false;
+ }
+
+ MKQL_ENSURE(ListIterator.Skip(), "Unexpected end of list");
+ ++ItemsCount;
+ return true;
+ }
+
+ const NUdf::TUnboxedValue ListIterator;
ui64 ItemsLimit;
ui64 ItemsCount;
};
public:
- TPartialList(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& list, ui64 itemsLimit)
+ TPartialList(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& list, ui64 itemsLimit)
: TCustomListValue(memInfo)
- , List(std::move(list))
+ , List(std::move(list))
, ItemsLimit(itemsLimit)
{
Length = itemsLimit;
HasItems = itemsLimit > 0;
}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), List.GetListIterator(), ItemsLimit));
- }
-
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), List.GetListIterator(), ItemsLimit));
+ }
+
NUdf::TUnboxedValue List;
ui64 ItemsLimit;
};
@@ -586,16 +586,16 @@ namespace {
auto resultIt = results.find(callable.GetUniqueId());
if (resultIt != results.end()) {
for (auto& result : resultIt->second) {
- values.push_back(valuePacker.Unpack(result, ctx.HolderFactory));
+ values.push_back(valuePacker.Unpack(result, ctx.HolderFactory));
}
}
if (values.empty()) {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TEmptyRangeHolder(ctx.HolderFactory)));
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TEmptyRangeHolder(ctx.HolderFactory)));
}
if (values.size() == 1) {
- return ctx.NodeFactory.CreateImmutableNode(std::move(values.front()));
+ return ctx.NodeFactory.CreateImmutableNode(std::move(values.front()));
}
bool truncatedAny = false;
@@ -604,20 +604,20 @@ namespace {
using TPartKey = std::tuple<const TCell*, NUdf::TUnboxedValue, ui64, ui64, NUdf::TUnboxedValue, bool>;
- std::vector<TPartKey> parts;
- std::vector<TSerializedCellVec> dataBuffers;
+ std::vector<TPartKey> parts;
+ std::vector<TSerializedCellVec> dataBuffers;
parts.reserve(values.size());
dataBuffers.reserve(values.size());
for (auto& value : values) {
MKQL_ENSURE(value.IsBoxed(), "Expected boxed value");
- auto list = value.GetElement(0);
+ auto list = value.GetElement(0);
MKQL_ENSURE(list.IsBoxed(), "Expected boxed value");
- bool truncated = value.GetElement(1).Get<bool>();
- auto firstKeyValue = value.GetElement(2);
- ui64 sizeInBytes = value.GetElement(3).Get<ui64>();
+ bool truncated = value.GetElement(1).Get<bool>();
+ auto firstKeyValue = value.GetElement(2);
+ ui64 sizeInBytes = value.GetElement(3).Get<ui64>();
TString firstKey(firstKeyValue.AsStringRef());
truncatedAny = truncatedAny || truncated;
@@ -667,8 +667,8 @@ namespace {
}
});
- ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
- ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
+ ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
+ ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
TUnboxedValueVector resultLists;
bool resultTruncated = false;
@@ -684,14 +684,14 @@ namespace {
resultTruncated = true;
ui64 itemsToFetch = itemsLimit - totalItems;
if (itemsToFetch > 0) {
- NUdf::TUnboxedValuePod listPart(new TPartialList(&ctx.HolderFactory.GetMemInfo(), std::move(list), itemsToFetch));
- resultLists.emplace_back(std::move(listPart));
+ NUdf::TUnboxedValuePod listPart(new TPartialList(&ctx.HolderFactory.GetMemInfo(), std::move(list), itemsToFetch));
+ resultLists.emplace_back(std::move(listPart));
}
break;
}
- resultLists.emplace_back(std::move(list));
+ resultLists.emplace_back(std::move(list));
totalSize += size;
totalItems += items;
@@ -719,19 +719,19 @@ namespace {
}
if (resultLists.empty()) {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TEmptyRangeHolder(ctx.HolderFactory)));
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(new TEmptyRangeHolder(ctx.HolderFactory)));
}
- auto resultList = ctx.HolderFactory.Create<TExtendListValue>(std::move(resultLists));
+ auto resultList = ctx.HolderFactory.Create<TExtendListValue>(std::move(resultLists));
- NUdf::TUnboxedValue* resultItems = nullptr;
- auto result = ctx.HolderFactory.CreateDirectArrayHolder(4, resultItems);
- resultItems[0] = std::move(resultList);
+ NUdf::TUnboxedValue* resultItems = nullptr;
+ auto result = ctx.HolderFactory.CreateDirectArrayHolder(4, resultItems);
+ resultItems[0] = std::move(resultList);
resultItems[1] = NUdf::TUnboxedValuePod(resultTruncated);
- resultItems[2] = std::move(std::get<4>(parts.front()));
- resultItems[3] = NUdf::TUnboxedValuePod(totalSize);
+ resultItems[2] = std::move(std::get<4>(parts.front()));
+ resultItems[3] = NUdf::TUnboxedValuePod(totalSize);
- return ctx.NodeFactory.CreateImmutableNode(std::move(result));
+ return ctx.NodeFactory.CreateImmutableNode(std::move(result));
}
IComputationNode* WrapEraseRow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
@@ -796,17 +796,17 @@ namespace {
TUnboxedValueVector lists;
TValuePacker listPacker(false, returnType);
- for (const auto& result : resultIt->second) {
- lists.emplace_back(listPacker.Unpack(result, ctx.HolderFactory));
+ for (const auto& result : resultIt->second) {
+ lists.emplace_back(listPacker.Unpack(result, ctx.HolderFactory));
}
auto countNode = callable.GetInput(1);
MKQL_ENSURE(countNode.IsImmediate() && countNode.GetStaticType()->IsData(), "Expected immediate data");
const auto& countData = static_cast<const TDataLiteral&>(*countNode.GetNode());
MKQL_ENSURE(countData.GetType()->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
- auto takeCount = countData.AsValue().Get<ui64>();
+ auto takeCount = countData.AsValue().Get<ui64>();
- return ctx.NodeFactory.CreateImmutableNode(ctx.Builder->TakeList(ctx.HolderFactory.Create<TExtendListValue>(std::move(lists)), takeCount));
+ return ctx.NodeFactory.CreateImmutableNode(ctx.Builder->TakeList(ctx.HolderFactory.Create<TExtendListValue>(std::move(lists)), takeCount));
}
IComputationNode* WrapMergedLength(TCallable& callable, TIncomingResults::const_iterator resultIt,
@@ -820,11 +820,11 @@ namespace {
ui64 totalLength = 0;
TValuePacker listPacker(false, returnType);
for (auto& result : resultIt->second) {
- const auto value = listPacker.Unpack(result, ctx.HolderFactory);
+ const auto value = listPacker.Unpack(result, ctx.HolderFactory);
totalLength += value.Get<ui64>();
}
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(totalLength));
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(totalLength));
}
}
@@ -951,7 +951,7 @@ TComputationNodeFactory GetFlatProxyExecutionFactory(TProxyExecData& execData)
};
}
-NUdf::TUnboxedValue PerformLocalSelectRow(TCallable& callable, IEngineFlatHost& engineHost,
+NUdf::TUnboxedValue PerformLocalSelectRow(TCallable& callable, IEngineFlatHost& engineHost,
const THolderFactory& holderFactory, const TTypeEnvironment& env)
{
MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
@@ -969,15 +969,15 @@ NUdf::TUnboxedValue PerformLocalSelectRow(TCallable& callable, IEngineFlatHost&
ExtractFlatReadTarget(callable.GetInput(4)), holderFactory);
}
-NUdf::TUnboxedValue PerformLocalSelectRange(TCallable& callable, IEngineFlatHost& engineHost,
+NUdf::TUnboxedValue PerformLocalSelectRange(TCallable& callable, IEngineFlatHost& engineHost,
const THolderFactory& holderFactory, const TTypeEnvironment& env)
{
MKQL_ENSURE(callable.GetInputsCount() >= 9 && callable.GetInputsCount() <= 13, "Expected 9 to 13 args");
auto tableNode = callable.GetInput(0);
const auto tableId = ExtractTableId(tableNode);
- ui32 flags = AS_VALUE(TDataLiteral, callable.GetInput(5))->AsValue().Get<ui32>();
- ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
- ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
+ ui32 flags = AS_VALUE(TDataLiteral, callable.GetInput(5))->AsValue().Get<ui32>();
+ ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
+ ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
TVector<TCell> fromValues;
TVector<TCell> toValues;
diff --git a/ydb/core/engine/mkql_engine_flat_host.h b/ydb/core/engine/mkql_engine_flat_host.h
index ac1b913baa..0593fb3a9b 100644
--- a/ydb/core/engine/mkql_engine_flat_host.h
+++ b/ydb/core/engine/mkql_engine_flat_host.h
@@ -42,12 +42,12 @@ public:
virtual void PinPages(const TVector<THolder<TKeyDesc>>& keys, ui64 pageFaultCount = 0) = 0;
// Returns empty optional with type 'returnType' or the filled one.
- virtual NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
+ virtual NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
TStructLiteral* columnIds, TOptionalType* returnType, const TReadTarget& readTarget,
const THolderFactory& holderFactory) = 0;
// Returns struct with type 'returnType' - that should have fields 'List' and 'Truncated'.
- virtual NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
+ virtual NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
TStructLiteral* columnIds, TListLiteral* skipNullKeys, TStructType* returnType,
const TReadTarget& readTarget, ui64 itemsLimit, ui64 bytesLimit, bool reverse,
std::pair<const TListLiteral*, const TListLiteral*> forbidNullArgs, const THolderFactory& holderFactory) = 0;
diff --git a/ydb/core/engine/mkql_engine_flat_impl.h b/ydb/core/engine/mkql_engine_flat_impl.h
index 0ed1fdaa8c..bb232a52aa 100644
--- a/ydb/core/engine/mkql_engine_flat_impl.h
+++ b/ydb/core/engine/mkql_engine_flat_impl.h
@@ -119,16 +119,16 @@ namespace NMiniKQL {
TComputationNodeFactory GetFlatShardExecutionFactory(TShardExecData& execData, bool validateOnly);
TComputationNodeFactory GetFlatProxyExecutionFactory(TProxyExecData& execData);
- NUdf::TUnboxedValue PerformLocalSelectRow(TCallable& callable, IEngineFlatHost& engineHost,
+ NUdf::TUnboxedValue PerformLocalSelectRow(TCallable& callable, IEngineFlatHost& engineHost,
const THolderFactory& holderFactory, const TTypeEnvironment& env);
- NUdf::TUnboxedValue PerformLocalSelectRange(TCallable& callable, IEngineFlatHost& engineHost,
+ NUdf::TUnboxedValue PerformLocalSelectRange(TCallable& callable, IEngineFlatHost& engineHost,
const THolderFactory& holderFactory, const TTypeEnvironment& env);
- struct TEngineFlatApplyContext : public NUdf::IApplyContext {
+ struct TEngineFlatApplyContext : public NUdf::IApplyContext {
bool IsAborted = false;
IEngineFlatHost* Host = nullptr;
THashMap<TString, NUdf::TUnboxedValue>* ResultValues = nullptr;
- const TTypeEnvironment* Env = nullptr;
+ const TTypeEnvironment* Env = nullptr;
};
TStructType* GetTxLockType(const TTypeEnvironment& env, bool v2);
diff --git a/ydb/core/engine/mkql_engine_flat_ut.cpp b/ydb/core/engine/mkql_engine_flat_ut.cpp
index fefadae97f..e2b12e2d7a 100644
--- a/ydb/core/engine/mkql_engine_flat_ut.cpp
+++ b/ydb/core/engine/mkql_engine_flat_ut.cpp
@@ -119,7 +119,7 @@ namespace {
std::function<void(ui64, const TString&)> ShardReplyInspector;
TDriver()
- : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
+ : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
, RandomProvider(CreateDeterministicRandomProvider(1))
, TimeProvider(CreateDeterministicTimeProvider(1))
, Env(Alloc)
@@ -145,7 +145,7 @@ namespace {
TEngineFlatSettings settings(IEngineFlat::EProtocol::V1, FunctionRegistry.Get(), *RandomProvider, *TimeProvider);
SettingsConfigurer(settings);
- const auto unguard = Unguard(Alloc);
+ const auto unguard = Unguard(Alloc);
auto proxyEngine = CreateEngineFlat(settings);
if (proxyEngine->SetProgram(pgmStr) != IEngineFlat::EResult::Ok) {
Cerr << proxyEngine->GetErrors() << Endl;
@@ -300,7 +300,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatTest) {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)TKey;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = key ? key : pgmBuilder.NewNull();
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -324,7 +324,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatTest) {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)TKey;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.NewNull();
TVector<TSelectColumn> columns;
@@ -356,7 +356,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLEngineFlatTest) {
Y_UNIT_TEST(TestPureProgram) {
TDriver driver;
auto& pgmBuilder = driver.PgmBuilder;
- auto value = pgmBuilder.TProgramBuilder::TProgramBuilder::NewDataLiteral<ui32>(42);
+ auto value = pgmBuilder.TProgramBuilder::TProgramBuilder::NewDataLiteral<ui32>(42);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
NKikimrMiniKQL::TResult res;
@@ -413,8 +413,8 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.TProgramBuilder::TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.TProgramBuilder::TProgramBuilder::NewDataLiteral<ui32>(42);
TVector<TSelectColumn> columns;
auto value = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -470,8 +470,8 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
TVector<TSelectColumn> columns;
auto value = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -529,8 +529,8 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
TVector<TSelectColumn> columns;
columns.emplace_back("2", (ui32)Schema1::Table1::Value::ColumnId, (ui32)Schema1::Table1::Value::ColumnType);
auto value = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row);
@@ -677,10 +677,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.EraseRow(TTableId(OwnerId, Table1Id), keyTypes, row)));
@@ -719,7 +719,7 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.NewNull();
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.EraseRow(TTableId(OwnerId, Table1Id), keyTypes, row)));
@@ -792,10 +792,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.UpdateRow(TTableId(OwnerId, Table1Id),
@@ -830,10 +830,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -902,10 +902,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -952,10 +952,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -1005,10 +1005,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -1046,10 +1046,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1117,7 +1117,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewNull();
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -1205,11 +1205,11 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1322,11 +1322,11 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
- options.ItemsLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.ItemsLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1432,7 +1432,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewNull();
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -1546,10 +1546,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
options.BytesLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(32);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1666,11 +1666,11 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
options.FromColumns = rowFrom;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1787,13 +1787,13 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
TReadRangeOptions::TFlags::ExcludeInitValue |
- TReadRangeOptions::TFlags::ExcludeTermValue);
+ TReadRangeOptions::TFlags::ExcludeTermValue);
options.FromColumns = rowFrom;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -1903,13 +1903,13 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::IncludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::IncludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2027,8 +2027,8 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
rowFrom[0] = pgmBuilder.NewNull();
rowTo[0] = pgmBuilder.NewNull();
@@ -2137,13 +2137,13 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2257,15 +2257,15 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
TReadRangeOptions::TFlags::IncludeInitValue |
- TReadRangeOptions::TFlags::IncludeTermValue);
+ TReadRangeOptions::TFlags::IncludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2386,15 +2386,15 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
TReadRangeOptions::TFlags::ExcludeInitValue |
- TReadRangeOptions::TFlags::IncludeTermValue);
+ TReadRangeOptions::TFlags::IncludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2508,15 +2508,15 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
TReadRangeOptions::TFlags::IncludeInitValue |
- TReadRangeOptions::TFlags::ExcludeTermValue);
+ TReadRangeOptions::TFlags::ExcludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2630,15 +2630,15 @@ Value {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
- TRuntimeNode::TList rowTo(1);
- rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
- rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
+ TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowTo(1);
+ rowFrom[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ rowTo[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(43);
auto options = pgmBuilder.GetDefaultTableRangeOptions();
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(
TReadRangeOptions::TFlags::ExcludeInitValue |
- TReadRangeOptions::TFlags::ExcludeTermValue);
+ TReadRangeOptions::TFlags::ExcludeTermValue);
options.FromColumns = rowFrom;
options.ToColumns = rowTo;
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
@@ -2745,22 +2745,22 @@ Value {
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row1(1);
+ TRuntimeNode::TList row1(1);
TVector<TSelectColumn> columns1;
columns1.emplace_back("2", (ui32)Schema1::Table1::Value::ColumnId, (ui32)Schema1::Table1::Value::ColumnType);
- row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
auto value1 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes1, columns1, row1);
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row2(1);
- row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
+ TRuntimeNode::TList row2(1);
+ row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
TVector<TSelectColumn> columns2;
columns2.emplace_back("4", (ui32)Schema2::Table2::Value::ColumnId, (ui32)Schema2::Table2::Value::ColumnType);
auto value2 = pgmBuilder.SelectRow(TTableId(OwnerId, Table2Id), keyTypes2, columns2, row2);
- TRuntimeNode::TList resList;
+ TRuntimeNode::TList resList;
resList.push_back(pgmBuilder.SetResult("myRes1", value1));
resList.push_back(pgmBuilder.SetResult("myRes2", value2));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(resList));
@@ -2894,17 +2894,17 @@ Value {
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row1(1);
- row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row1(1);
+ row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
auto value1 = pgmBuilder.EraseRow(TTableId(OwnerId, Table1Id), keyTypes1, row1);
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row2(1);
- row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
+ TRuntimeNode::TList row2(1);
+ row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
auto value2 = pgmBuilder.EraseRow(TTableId(OwnerId, Table2Id), keyTypes2, row2);
- TRuntimeNode::TList resList;
+ TRuntimeNode::TList resList;
resList.push_back(value1);
resList.push_back(value2);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(resList));
@@ -2950,8 +2950,8 @@ Value {
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row1(1);
- row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row1(1);
+ row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
auto update1 = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId1 = (ui32)Schema1::Table1::Value::ColumnId;
update1.SetColumn(columnId1,
@@ -2962,17 +2962,17 @@ Value {
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row2(1);
- row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
+ TRuntimeNode::TList row2(1);
+ row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
auto update2 = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId2 = (ui32)Schema2::Table2::Value::ColumnId;
update2.SetColumn(columnId2,
NUdf::TDataType<ui32>::Id,
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(21));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(21));
auto value2 = pgmBuilder.UpdateRow(TTableId(OwnerId, Table2Id), keyTypes2, row2, update2);
- TRuntimeNode::TList resList;
+ TRuntimeNode::TList resList;
resList.push_back(value1);
resList.push_back(value2);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(resList));
@@ -3042,8 +3042,8 @@ Value {
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row1(1);
- row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row1(1);
+ row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
auto update1 = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId1 = (ui32)Schema1::Table1::Value::ColumnId;
update1.SetColumn(columnId1,
@@ -3058,21 +3058,21 @@ Value {
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row2(1);
- row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
+ TRuntimeNode::TList row2(1);
+ row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(11);
auto update2 = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId2 = (ui32)Schema2::Table2::Value::ColumnId;
update2.SetColumn(columnId2,
NUdf::TDataType<ui32>::Id,
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(32));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(32));
TVector<TSelectColumn> columns2;
columns2.emplace_back("4", (ui32)Schema2::Table2::Value::ColumnId, (ui32)Schema2::Table2::Value::ColumnType);
auto oldRow2 = pgmBuilder.SelectRow(TTableId(OwnerId, Table2Id), keyTypes2, columns2, row2);
auto value2 = pgmBuilder.UpdateRow(TTableId(OwnerId, Table2Id), keyTypes2, row2, update2);
- TRuntimeNode::TList resList;
+ TRuntimeNode::TList resList;
resList.push_back(value1);
resList.push_back(value2);
auto prevValue1 = pgmBuilder.FlatMap(oldRow1, [&](TRuntimeNode item) {
@@ -3083,12 +3083,12 @@ Value {
return pgmBuilder.Member(item, "4");
});
- const TString str(simulateFail1 ? "XXX" : "qwe");
- auto predicate = pgmBuilder.And({
- pgmBuilder.Exists(prevValue1), pgmBuilder.AggrEquals(pgmBuilder.Unwrap(prevValue1, pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
- pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(str)),
- pgmBuilder.Exists(prevValue2), pgmBuilder.AggrEquals(pgmBuilder.Unwrap(prevValue2, pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(simulateFail2 ? 999 : 67))});
+ const TString str(simulateFail1 ? "XXX" : "qwe");
+ auto predicate = pgmBuilder.And({
+ pgmBuilder.Exists(prevValue1), pgmBuilder.AggrEquals(pgmBuilder.Unwrap(prevValue1, pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(str)),
+ pgmBuilder.Exists(prevValue2), pgmBuilder.AggrEquals(pgmBuilder.Unwrap(prevValue2, pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(simulateFail2 ? 999 : 67))});
auto pgm = pgmBuilder.Build(pgmBuilder.If(predicate, pgmBuilder.AsList(resList), pgmBuilder.AsList(pgmBuilder.Abort())));
@@ -3164,8 +3164,8 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(42);
TVector<TSelectColumn> columns;
columns.emplace_back("2", (ui32)Schema1::Table1::Value::ColumnId, (ui32)Schema1::Table1::Value::ColumnType);
auto value = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row);
@@ -3245,10 +3245,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -3331,10 +3331,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema1::Table1::Value::ColumnId;
@@ -3382,10 +3382,10 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(40),
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(2));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.EraseRow(TTableId(OwnerId, Table1Id), keyTypes, row)));
@@ -3442,10 +3442,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -3567,11 +3567,11 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
- options.ItemsLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.ItemsLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(1);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -3696,12 +3696,12 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
const ui64 RowOverheadBytes = 8;
- options.BytesLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(4 + RowOverheadBytes);
+ options.BytesLimit = pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(4 + RowOverheadBytes);
auto value = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -3829,7 +3829,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -3975,7 +3975,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -4101,7 +4101,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -4234,7 +4234,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -4339,8 +4339,8 @@ Value {
Y_UNIT_TEST(TestBug998) {
TDriver driver;
auto& pgmBuilder = driver.PgmBuilder;
- auto value1 = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(4294967172);
- auto value2 = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(123);
+ auto value1 = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(4294967172);
+ auto value2 = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(123);
auto value = pgmBuilder.Add(value1, value2);
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("myRes", value)));
@@ -4383,7 +4383,7 @@ Value {
auto& pgmBuilder = driver.PgmBuilder;
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.AcquireLocks(
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(0))));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(0))));
NKikimrMiniKQL::TResult res;
UNIT_ASSERT_EQUAL(driver.Run(pgm, res, &SingleShardResolver), IEngineFlat::EStatus::Complete);
@@ -4737,22 +4737,22 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
TVector<TStringBuf> filterNullColumns {"Value"};
auto filterNull = pgmBuilder.FilterNullMembers(list, filterNullColumns);
auto filtered = pgmBuilder.Filter(filterNull, [&pgmBuilder, &okValue](TRuntimeNode item) {
- return pgmBuilder.AggrEquals(
+ return pgmBuilder.AggrEquals(
pgmBuilder.Member(item, "Value"),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(okValue));
});
auto mapped = pgmBuilder.Map(filtered, [&pgmBuilder](TRuntimeNode item) {
return pgmBuilder.AddMember(item, "MappedID", pgmBuilder.Add(
- pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
+ pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
});
auto flatmapped = pgmBuilder.FlatMap(mapped, [&pgmBuilder](TRuntimeNode item) {
TString prefix = "mapped_";
@@ -4760,7 +4760,7 @@ Value {
return pgmBuilder.AsList(pgmBuilder.AddMember(item, "RemappedId", pgmBuilder.Concat(
prefixNode, pgmBuilder.ToString(pgmBuilder.Coalesce(pgmBuilder.Member(item, "MappedID"),
- pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(0))))));
+ pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(0))))));
});
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("Result", flatmapped)));
@@ -4813,18 +4813,18 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
auto mapped = pgmBuilder.Map(list, [&pgmBuilder](TRuntimeNode item) {
return pgmBuilder.AddMember(item, "MappedID", pgmBuilder.Add(
- pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
+ pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
});
- TRuntimeNode::TList results;
+ TRuntimeNode::TList results;
results.push_back(pgmBuilder.SetResult("Result1", mapped));
results.push_back(pgmBuilder.SetResult("Result2", list));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(results));
@@ -4881,15 +4881,15 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
auto mapped = pgmBuilder.Map(list, [&pgmBuilder, keyTypes, columns](TRuntimeNode item) {
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(3);
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(3);
return pgmBuilder.AddMember(item, "Fetch",
pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row));
@@ -4943,14 +4943,14 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
auto filtered = pgmBuilder.OrderedFilter(list, [&pgmBuilder, &okValue](TRuntimeNode item) {
- return pgmBuilder.AggrEquals(
+ return pgmBuilder.AggrEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(okValue));
});
@@ -5029,23 +5029,23 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
auto mapped = pgmBuilder.Map(list, [&pgmBuilder](TRuntimeNode item) {
return pgmBuilder.AddMember(item, "MappedID", pgmBuilder.Add(
- pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
+ pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
});
auto write = pgmBuilder.Map(mapped, [&pgmBuilder](TRuntimeNode item) {
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row(1);
- row[0] = pgmBuilder.Convert(pgmBuilder.Member(item, "ID"), pgmBuilder.NewOptionalType(pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)));
+ TRuntimeNode::TList row(1);
+ row[0] = pgmBuilder.Convert(pgmBuilder.Member(item, "ID"), pgmBuilder.NewOptionalType(pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)));
auto update = pgmBuilder.GetUpdateRowBuilder();
ui32 columnId = (ui32)Schema2::Table2::Value::ColumnId;
@@ -5072,10 +5072,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table2Id), keyTypes, columns, options);
auto checkpgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("Result", range)));
@@ -5133,7 +5133,7 @@ Value {
auto options1 = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom1(1);
+ TRuntimeNode::TList rowFrom1(1);
rowFrom1[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options1.FromColumns = rowFrom1;
options1.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5146,7 +5146,7 @@ Value {
auto options2 = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList rowFrom2(1);
+ TRuntimeNode::TList rowFrom2(1);
rowFrom2[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
options2.FromColumns = rowFrom2;
options2.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5223,7 +5223,7 @@ Value {
auto options1 = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes1(1);
keyTypes1[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom1(1);
+ TRuntimeNode::TList rowFrom1(1);
rowFrom1[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options1.FromColumns = rowFrom1;
options1.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5236,7 +5236,7 @@ Value {
auto options2 = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes2(1);
keyTypes2[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList rowFrom2(1);
+ TRuntimeNode::TList rowFrom2(1);
rowFrom2[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
options2.FromColumns = rowFrom2;
options2.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5327,10 +5327,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
@@ -5344,19 +5344,19 @@ Value {
return item;
});
- auto values = pgmBuilder.DictItems(dict);
+ auto values = pgmBuilder.DictItems(dict);
auto agg = pgmBuilder.FlatMap(values, [&](TRuntimeNode item) {
auto key = pgmBuilder.Nth(item, 0);
auto payloadList = pgmBuilder.Nth(item, 1);
auto fold1 = pgmBuilder.Fold1(payloadList, [&](TRuntimeNode item2) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
{"Key", key},
{"Sum", pgmBuilder.Member(item2, "ID")}
};
return pgmBuilder.NewOptional(pgmBuilder.NewStruct(fields));
}, [&](TRuntimeNode item2, TRuntimeNode state) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
{"Key", pgmBuilder.Member(state, "Key")},
{"Sum", pgmBuilder.AggrAdd(pgmBuilder.Member(state, "Sum"), pgmBuilder.Member(item2, "ID"))}
};
@@ -5441,10 +5441,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
@@ -5454,19 +5454,19 @@ Value {
return item;
});
- auto values = pgmBuilder.DictItems(dict);
+ auto values = pgmBuilder.DictItems(dict);
auto agg = pgmBuilder.FlatMap(values, [&](TRuntimeNode item) {
auto key = pgmBuilder.Nth(item, 0);
auto payloadList = pgmBuilder.Nth(item, 1);
auto fold1 = pgmBuilder.Fold1(payloadList, [&](TRuntimeNode item2) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
{"Key", key},
{"Sum", pgmBuilder.Member(item2, "ID")}
};
return pgmBuilder.NewOptional(pgmBuilder.NewStruct(fields));
}, [&](TRuntimeNode item2, TRuntimeNode state) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> fields {
{"Key", pgmBuilder.Member(state, "Key")},
{"Sum", pgmBuilder.AggrAdd(pgmBuilder.Member(state, "Sum"), pgmBuilder.Member(item2, "ID"))}
};
@@ -5550,21 +5550,21 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
const TString filterValue = "Value1";
auto filtered = pgmBuilder.Filter(list, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
});
- auto take = pgmBuilder.Take(filtered, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(2));
+ auto take = pgmBuilder.Take(filtered, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(2));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("Result", take)));
@@ -5632,14 +5632,14 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
- auto take = pgmBuilder.Take(list, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(4));
+ auto take = pgmBuilder.Take(list, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(4));
auto pgm = pgmBuilder.Build(pgmBuilder.AsList(pgmBuilder.SetResult("Result", take)));
@@ -5708,16 +5708,16 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
const TString filterValue = "Value2";
auto filtered = pgmBuilder.Filter(list, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
});
@@ -5787,23 +5787,23 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, columns, options);
auto list = pgmBuilder.Member(range, "List");
auto mapped = pgmBuilder.Map(list, [&pgmBuilder](TRuntimeNode item) {
return pgmBuilder.AddMember(item, "MappedID", pgmBuilder.Add(
- pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
+ pgmBuilder.Member(item, "ID"), pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10)));
});
- auto take = pgmBuilder.Take(mapped, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(2));
+ auto take = pgmBuilder.Take(mapped, pgmBuilder.TProgramBuilder::NewDataLiteral<ui64>(2));
const TString filterValue = "Value2";
auto filtered = pgmBuilder.Filter(take, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
});
@@ -5874,7 +5874,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5883,7 +5883,7 @@ Value {
const TString filterValue = "Value1";
auto filtered = pgmBuilder.Filter(list, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
});
@@ -5959,7 +5959,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -5968,7 +5968,7 @@ Value {
const TString filterValue = "Value6";
auto filtered = pgmBuilder.Filter(list, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"), pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
});
@@ -6048,7 +6048,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -6141,7 +6141,7 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -6210,10 +6210,10 @@ Value {
auto options = pgmBuilder.GetDefaultTableRangeOptions();
TVector<ui32> keyTypes(1);
keyTypes[0] = (ui32)NUdf::TDataType<ui32>::Id;
- TRuntimeNode::TList rowFrom(1);
+ TRuntimeNode::TList rowFrom(1);
rowFrom[0] = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
options.FromColumns = rowFrom;
- options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
+ options.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
auto range = pgmBuilder.SelectRange(TTableId(OwnerId, Table1Id), keyTypes, {}, options);
auto list = pgmBuilder.Member(range, "List");
auto length = pgmBuilder.Length(list);
@@ -6288,7 +6288,7 @@ Value {
{"Value", (ui32)Schema1::Table1::Value::ColumnId, (ui32)Schema1::Table1::Value::ColumnType}
};
- TRuntimeNode::TList fromColumns1{pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id)};
+ TRuntimeNode::TList fromColumns1{pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id)};
auto options1 = pgmBuilder.GetDefaultTableRangeOptions();
options1.FromColumns = fromColumns1;
options1.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -6298,7 +6298,7 @@ Value {
const TString filterValue = "Value6";
auto filtered1 = pgmBuilder.Filter(list1, [&pgmBuilder, &filterValue](TRuntimeNode item) {
- return pgmBuilder.AggrNotEquals(
+ return pgmBuilder.AggrNotEquals(
pgmBuilder.Unwrap(pgmBuilder.Member(item, "Value"),
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0),
pgmBuilder.TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(filterValue));
@@ -6311,7 +6311,7 @@ Value {
{"Value", (ui32)Schema2::Table2::Value::ColumnId, (ui32)Schema2::Table2::Value::ColumnType}
};
- TRuntimeNode::TList fromColumns2{pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id)};
+ TRuntimeNode::TList fromColumns2{pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id)};
auto options2 = pgmBuilder.GetDefaultTableRangeOptions();
options2.FromColumns = fromColumns2;
options2.Flags = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(TReadRangeOptions::TFlags::ExcludeTermValue);
@@ -6364,15 +6364,15 @@ Value {
TVector<TSelectColumn> columns;
columns.emplace_back("ID", (ui32)Schema1::Table1::ID::ColumnId, (ui32)Schema1::Table1::ID::ColumnType);
- TRuntimeNode::TList row1(1);
+ TRuntimeNode::TList row1(1);
row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(1);
auto value1 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row1);
- TRuntimeNode::TList row2(1);
+ TRuntimeNode::TList row2(1);
row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(3);
auto value2 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row2);
- TRuntimeNode::TList row3(1);
+ TRuntimeNode::TList row3(1);
row3[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(5);
auto value3 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row3);
@@ -6381,7 +6381,7 @@ Value {
auto mapped = pgmBuilder.Map(list, [&pgmBuilder, &keyTypes](TRuntimeNode item) {
auto update = pgmBuilder.GetUpdateRowBuilder();
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
pgmBuilder.Member(item, "ID"),
pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10));
@@ -6415,15 +6415,15 @@ Value {
TVector<ui32> key2Types(1);
key2Types[0] = (ui32)NUdf::TDataType<ui64>::Id;
- TRuntimeNode::TList row1(1);
+ TRuntimeNode::TList row1(1);
row1[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(1);
auto value1 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row1);
- TRuntimeNode::TList row2(1);
+ TRuntimeNode::TList row2(1);
row2[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(3);
auto value2 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row2);
- TRuntimeNode::TList row3(1);
+ TRuntimeNode::TList row3(1);
row3[0] = pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(5);
auto value3 = pgmBuilder.SelectRow(TTableId(OwnerId, Table1Id), keyTypes, columns, row3);
@@ -6432,9 +6432,9 @@ Value {
auto mapped = pgmBuilder.Map(list, [&pgmBuilder, &key2Types](TRuntimeNode item) {
auto update = pgmBuilder.GetUpdateRowBuilder();
- TRuntimeNode::TList row(1);
+ TRuntimeNode::TList row(1);
row[0] = pgmBuilder.Add(
- pgmBuilder.Convert(pgmBuilder.Member(item, "ID"), pgmBuilder.NewOptionalType(pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id))),
+ pgmBuilder.Convert(pgmBuilder.Member(item, "ID"), pgmBuilder.NewOptionalType(pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id))),
pgmBuilder.TProgramBuilder::NewDataLiteral<ui32>(10));
return pgmBuilder.UpdateRow(TTableId(OwnerId, Table2Id), key2Types, row, update);
diff --git a/ydb/core/engine/mkql_keys.cpp b/ydb/core/engine/mkql_keys.cpp
index 096207930f..05afb89adc 100644
--- a/ydb/core/engine/mkql_keys.cpp
+++ b/ydb/core/engine/mkql_keys.cpp
@@ -6,14 +6,14 @@
#include <util/generic/maybe.h>
#include <util/generic/algorithm.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
namespace NMiniKQL {
namespace {
-bool ExtractKeyData(TRuntimeNode valueNode, bool isOptional, NUdf::TUnboxedValue& data) {
+bool ExtractKeyData(TRuntimeNode valueNode, bool isOptional, NUdf::TUnboxedValue& data) {
if (valueNode.HasValue()) {
TNode* value = valueNode.GetValue();
TNode* dataValue = value;
@@ -21,7 +21,7 @@ bool ExtractKeyData(TRuntimeNode valueNode, bool isOptional, NUdf::TUnboxedValue
MKQL_ENSURE(value->GetType()->IsOptional(), "Expected optional");
auto opt = static_cast<TOptionalLiteral*>(value);
if (!opt->HasItem()) {
- data = NUdf::TUnboxedValue();
+ data = NUdf::TUnboxedValue();
return true;
}
else {
@@ -30,7 +30,7 @@ bool ExtractKeyData(TRuntimeNode valueNode, bool isOptional, NUdf::TUnboxedValue
}
if (dataValue->GetType()->IsData()) {
- data = NUdf::TUnboxedValuePod(static_cast<TDataLiteral*>(dataValue)->AsValue());
+ data = NUdf::TUnboxedValuePod(static_cast<TDataLiteral*>(dataValue)->AsValue());
return true;
}
}
@@ -38,13 +38,13 @@ bool ExtractKeyData(TRuntimeNode valueNode, bool isOptional, NUdf::TUnboxedValue
return false;
}
-template<typename T>
-TCell MakeCell(const NUdf::TUnboxedValuePod& value) {
- static_assert(TCell::CanInline(sizeof(T)), "Can't inline data in cell.");
- const auto v = value.Get<T>();
- return TCell(reinterpret_cast<const char*>(&v), sizeof(v));
-}
-
+template<typename T>
+TCell MakeCell(const NUdf::TUnboxedValuePod& value) {
+ static_assert(TCell::CanInline(sizeof(T)), "Can't inline data in cell.");
+ const auto v = value.Get<T>();
+ return TCell(reinterpret_cast<const char*>(&v), sizeof(v));
+}
+
THolder<TKeyDesc> ExtractKeyTuple(const TTableId& tableId, TTupleLiteral* tuple,
const TVector<TKeyDesc::TColumnOp>& columns,
TKeyDesc::ERowOperation rowOperation, bool requireStaticKey, const TTypeEnvironment& env) {
@@ -65,7 +65,7 @@ THolder<TKeyDesc> ExtractKeyTuple(const TTableId& tableId, TTupleLiteral* tuple,
}
auto valueNode = tuple->GetValue(i);
- NUdf::TUnboxedValue data;
+ NUdf::TUnboxedValue data;
bool hasImmediateData = ExtractKeyData(valueNode, isOptional, data);
if (!hasImmediateData) {
MKQL_ENSURE(!requireStaticKey, "Expected static key components");
@@ -75,7 +75,7 @@ THolder<TKeyDesc> ExtractKeyTuple(const TTableId& tableId, TTupleLiteral* tuple,
}
++staticComponents;
- fromValues[i] = toValues[i] = MakeCell(keyColumnTypes[i], data, env);
+ fromValues[i] = toValues[i] = MakeCell(keyColumnTypes[i], data, env);
}
TTableRange range(TConstArrayRef<TCell>(fromValues.data(), tuple->GetValuesCount()),
@@ -88,7 +88,7 @@ void ExtractReadColumns(TStructType* columnsType, TStructLiteral* tags, TVector<
for (ui32 i = 0; i < columnsType->GetMembersCount(); ++i) {
auto memberName = columnsType->GetMemberName(i);
MKQL_ENSURE(tags->GetType()->GetMemberName(i) == memberName, "Mismatch name of column");
- ui32 columnId = AS_VALUE(TDataLiteral, tags->GetValue(i))->AsValue().Get<ui32>();
+ ui32 columnId = AS_VALUE(TDataLiteral, tags->GetValue(i))->AsValue().Get<ui32>();
TKeyDesc::TColumnOp& op = columns[i];
op.Column = columnId;
op.Operation = TKeyDesc::EColumnOperation::Read;
@@ -126,10 +126,10 @@ THolder<TKeyDesc> ExtractSelectRange(TCallable& callable, const TTypeEnvironment
auto toTuple = AS_VALUE(TTupleLiteral, callable.GetInput(4));
auto flagsInput = callable.GetInput(5);
- const ui32 flags = AS_VALUE(TDataLiteral, flagsInput)->AsValue().Get<ui32>();
+ const ui32 flags = AS_VALUE(TDataLiteral, flagsInput)->AsValue().Get<ui32>();
- ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
- ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
+ ui64 itemsLimit = AS_VALUE(TDataLiteral, callable.GetInput(6))->AsValue().Get<ui64>();
+ ui64 bytesLimit = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().Get<ui64>();
TVector<ui32> keyColumnTypes(Max(fromTuple->GetValuesCount(), toTuple->GetValuesCount()));
TVector<TCell> fromValues(keyColumnTypes.size()); // padded with NULLs
@@ -143,10 +143,10 @@ THolder<TKeyDesc> ExtractSelectRange(TCallable& callable, const TTypeEnvironment
auto dataType = UnpackOptionalData(type, isOptional);
keyColumnTypes[i] = dataType->GetSchemeType();
auto valueNode = fromTuple->GetValue(i);
- NUdf::TUnboxedValue data;
+ NUdf::TUnboxedValue data;
bool hasImmediateData = ExtractKeyData(valueNode, isOptional, data);
MKQL_ENSURE(hasImmediateData, "Expected static key components");
- fromValues[i] = MakeCell(keyColumnTypes[i], data, env);
+ fromValues[i] = MakeCell(keyColumnTypes[i], data, env);
}
for (ui32 i = 0; i < toTuple->GetValuesCount(); ++i) {
@@ -155,10 +155,10 @@ THolder<TKeyDesc> ExtractSelectRange(TCallable& callable, const TTypeEnvironment
auto dataType = UnpackOptionalData(type, isOptional);
keyColumnTypes[i] = dataType->GetSchemeType();
auto valueNode = toTuple->GetValue(i);
- NUdf::TUnboxedValue data;
+ NUdf::TUnboxedValue data;
bool hasImmediateData = ExtractKeyData(valueNode, isOptional, data);
MKQL_ENSURE(hasImmediateData, "Expected static key components");
- toValues[i] = MakeCell(keyColumnTypes[i], data, env);
+ toValues[i] = MakeCell(keyColumnTypes[i], data, env);
}
bool reverse = false;
@@ -198,7 +198,7 @@ THolder<TKeyDesc> ExtractUpdateRow(TCallable& callable, const TTypeEnvironment&
TTupleLiteral* tuple = AS_VALUE(TTupleLiteral, cmd);
MKQL_ENSURE(tuple->GetValuesCount() == 2, "Expected pair");
auto inplaceModeNode = tuple->GetValue(0);
- ui32 mode = AS_VALUE(TDataLiteral, inplaceModeNode)->AsValue().Get<ui8>();
+ ui32 mode = AS_VALUE(TDataLiteral, inplaceModeNode)->AsValue().Get<ui8>();
MKQL_ENSURE(mode >= (ui32)EInplaceUpdateMode::FirstMode && mode <= (ui32)EInplaceUpdateMode::LastMode,
"Wrong inplace update mode");
auto valueNode = tuple->GetValue(1);
@@ -241,15 +241,15 @@ THolder<TKeyDesc> ExtractEraseRow(TCallable& callable, const TTypeEnvironment& e
}
-#define MAKE_PRIMITIVE_TYPE_CELL(type, layout) \
- case NUdf::TDataType<type>::Id: return MakeCell<layout>(value);
-
+#define MAKE_PRIMITIVE_TYPE_CELL(type, layout) \
+ case NUdf::TDataType<type>::Id: return MakeCell<layout>(value);
+
TCell MakeCell(NUdf::TDataTypeId typeId, const NUdf::TUnboxedValuePod& value, const TTypeEnvironment& env, bool copy) {
- if (!value)
- return TCell();
-
- switch(typeId) {
- KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_CELL)
+ if (!value)
+ return TCell();
+
+ switch(typeId) {
+ KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_CELL)
case NUdf::TDataType<NUdf::TDecimal>::Id:
{
auto intVal = value.GetInt128();
@@ -258,21 +258,21 @@ TCell MakeCell(NUdf::TDataTypeId typeId, const NUdf::TUnboxedValuePod& value, co
return TCell(val.Data(), val.Size());
}
break;
- }
-
- const auto& ref = value.AsStringRef();
+ }
+
+ const auto& ref = value.AsStringRef();
if (!copy || value.IsString() || TCell::CanInline(ref.Size()))
- return TCell(ref.Data(), ref.Size());
-
- const auto& val = env.NewString(ref.Size());
- std::memcpy(val.Data(), ref.Data(), ref.Size());
- return TCell(val.Data(), val.Size());
-}
-
-#undef MAKE_PRIMITIVE_TYPE_CELL
-
+ return TCell(ref.Data(), ref.Size());
+
+ const auto& val = env.NewString(ref.Size());
+ std::memcpy(val.Data(), ref.Data(), ref.Size());
+ return TCell(val.Data(), val.Size());
+}
+
+#undef MAKE_PRIMITIVE_TYPE_CELL
+
TReadTarget ExtractFlatReadTarget(TRuntimeNode modeInput) {
- const ui32 mode = static_cast<TDataLiteral&>(*modeInput.GetValue()).AsValue().Get<ui32>();
+ const ui32 mode = static_cast<TDataLiteral&>(*modeInput.GetValue()).AsValue().Get<ui32>();
switch ((TReadTarget::EMode)mode) {
case TReadTarget::EMode::Online:
return TReadTarget::Online();
diff --git a/ydb/core/engine/mkql_proto.cpp b/ydb/core/engine/mkql_proto.cpp
index 14afd6bfe2..3dd053e372 100644
--- a/ydb/core/engine/mkql_proto.cpp
+++ b/ydb/core/engine/mkql_proto.cpp
@@ -73,7 +73,7 @@ NUdf::TUnboxedValue ImportValueFromProto(TType* type, const Ydb::Value& value, c
return NUdf::TUnboxedValue();
case TType::EKind::Data:
- return HandleKindDataImport(type, value);
+ return HandleKindDataImport(type, value);
case TType::EKind::Optional: {
auto optionalType = static_cast<TOptionalType*>(type);
@@ -264,10 +264,10 @@ bool CellsFromTuple(const NKikimrMiniKQL::TType* tupleType,
type val = v.Get##protoField(); \
c = TCell((const char*)&val, sizeof(val)); \
} else if (allowCastFromString && v.HasText()) { \
- const auto slot = NUdf::GetDataSlot(types[i]); \
- const auto out = NMiniKQL::ValueFromString(slot, v.GetText()); \
+ const auto slot = NUdf::GetDataSlot(types[i]); \
+ const auto out = NMiniKQL::ValueFromString(slot, v.GetText()); \
CHECK_OR_RETURN_ERROR(out, Sprintf("Cannot parse value of type " #name " from text '%s' in tuple at position %" PRIu32, v.GetText().data(), i)); \
- const auto val = out.Get<type>(); \
+ const auto val = out.Get<type>(); \
c = TCell((const char*)&val, sizeof(val)); \
} else { \
CHECK_OR_RETURN_ERROR(false, Sprintf("Value of type " #name " expected in tuple at position %" PRIu32, i)); \
diff --git a/ydb/core/engine/mkql_proto_ut.cpp b/ydb/core/engine/mkql_proto_ut.cpp
index 347cde8794..c6e00e947c 100644
--- a/ydb/core/engine/mkql_proto_ut.cpp
+++ b/ydb/core/engine/mkql_proto_ut.cpp
@@ -34,7 +34,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTestYdb) {
Y_UNIT_TEST(TestExportDecimalTypeYdb) {
TestExportType<Ydb::Type>([](TProgramBuilder& pgmBuilder) {
- NYql::NDecimal::TInt128 x;
+ NYql::NDecimal::TInt128 x;
ui64* p = (ui64*)&x;
p[0] = 1;
p[1] = 0;
@@ -81,7 +81,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTestYdb) {
Y_UNIT_TEST(TestExportTupleTypeYdb) {
TestExportType<Ydb::Type>([](TProgramBuilder& pgmBuilder) {
- TRuntimeNode::TList items;
+ TRuntimeNode::TList items;
items.push_back(pgmBuilder.NewDataLiteral<i32>(42));
items.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
auto pgmReturn = pgmBuilder.NewTuple(items);
@@ -99,7 +99,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTestYdb) {
Y_UNIT_TEST(TestExportStructTypeYdb) {
TestExportType<Ydb::Type>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> items;
+ std::vector<std::pair<std::string_view, TRuntimeNode>> items;
items.push_back({ "x", pgmBuilder.NewDataLiteral<i32>(42) });
items.push_back({ "y", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc") });
auto pgmReturn = pgmBuilder.NewStruct(items);
@@ -186,7 +186,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
)___";
TestExportType<Ydb::Type>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TType*>> structElemenTypes;
+ std::vector<std::pair<std::string_view, TType*>> structElemenTypes;
structElemenTypes.push_back({"a", pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
structElemenTypes.push_back({"b", pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id)});
TType* structType = pgmBuilder.NewStructType(structElemenTypes);
@@ -244,7 +244,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
Y_UNIT_TEST(TestExportDecimalYdb) {
TestExportValue<Ydb::Value>([](TProgramBuilder& pgmBuilder) {
- NYql::NDecimal::TInt128 x;
+ NYql::NDecimal::TInt128 x;
ui64* p = (ui64*)&x;
p[0] = 1;
p[1] = 0;
@@ -255,7 +255,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
Y_UNIT_TEST(TestExportDecimalNegativeYdb) {
TestExportValue<Ydb::Value>([](TProgramBuilder& pgmBuilder) {
- NYql::NDecimal::TInt128 x;
+ NYql::NDecimal::TInt128 x;
ui64* p = (ui64*)&x;
p[0] = Max<ui64>();
p[1] = Max<ui64>();
@@ -267,7 +267,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
Y_UNIT_TEST(TestExportDecimalHugeYdb) {
TestExportValue<Ydb::Value>([](TProgramBuilder& pgmBuilder) {
- NYql::NDecimal::TInt128 x;
+ NYql::NDecimal::TInt128 x;
ui64* p = (ui64*)&x;
p[0] = 0;
p[1] = 1;
@@ -322,7 +322,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
Y_UNIT_TEST(TestExportTupleYdb) {
TestExportValue<Ydb::Value>([](TProgramBuilder& pgmBuilder) {
- TRuntimeNode::TList items;
+ TRuntimeNode::TList items;
items.push_back(pgmBuilder.NewDataLiteral<i32>(42));
items.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
auto pgmReturn = pgmBuilder.NewTuple(items);
@@ -338,7 +338,7 @@ Y_UNIT_TEST(TestExportVariantStructTypeYdb) {
Y_UNIT_TEST(TestExportStructYdb) {
TestExportValue<Ydb::Value>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> items;
+ std::vector<std::pair<std::string_view, TRuntimeNode>> items;
items.push_back({ "x", pgmBuilder.NewDataLiteral<i32>(42) });
items.push_back({ "y", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc") });
auto pgmReturn = pgmBuilder.NewStruct(items);
diff --git a/ydb/core/kqp/compile/kqp_mkql_compiler.cpp b/ydb/core/kqp/compile/kqp_mkql_compiler.cpp
index f5e63106cb..0413044698 100644
--- a/ydb/core/kqp/compile/kqp_mkql_compiler.cpp
+++ b/ydb/core/kqp/compile/kqp_mkql_compiler.cpp
@@ -287,7 +287,7 @@ TIntrusivePtr<IMkqlCallableCompiler> CreateKqlCompiler(const TKqlCompileContext&
});
compiler->AddCallable(TKqpUpsertRows::CallableName(),
- [&ctx](const TExprNode& node, TMkqlBuildContext& buildCtx) {
+ [&ctx](const TExprNode& node, TMkqlBuildContext& buildCtx) {
TKqpUpsertRows upsertRows(&node);
const auto& tableMeta = ctx.GetTableMeta(upsertRows.Table());
@@ -317,7 +317,7 @@ TIntrusivePtr<IMkqlCallableCompiler> CreateKqlCompiler(const TKqlCompileContext&
auto result = ctx.PgmBuilder().KqpUpsertRows(MakeTableId(upsertRows.Table()), rows,
GetKqpColumns(tableMeta, upsertColumns, false));
- return result;
+ return result;
});
compiler->AddCallable(TKqpDeleteRows::CallableName(),
diff --git a/ydb/core/kqp/host/kqp_host.cpp b/ydb/core/kqp/host/kqp_host.cpp
index 7c9050804c..44af6d1168 100644
--- a/ydb/core/kqp/host/kqp_host.cpp
+++ b/ydb/core/kqp/host/kqp_host.cpp
@@ -1022,7 +1022,7 @@ public:
if (funcRegistry) {
FuncRegistry = funcRegistry;
} else {
- FuncRegistryHolder = NMiniKQL::CreateFunctionRegistry(NMiniKQL::CreateBuiltinRegistry());
+ FuncRegistryHolder = NMiniKQL::CreateFunctionRegistry(NMiniKQL::CreateBuiltinRegistry());
FuncRegistry = FuncRegistryHolder.Get();
}
@@ -1058,7 +1058,7 @@ public:
auto writerFactory = [] () { return MakeIntrusive<TKqpResultWriter>(); };
ResultProviderConfig = MakeIntrusive<TResultProviderConfig>(*TypesCtx, *FuncRegistry, FillSettings.Format,
FillSettings.FormatDetails, writerFactory);
- auto resultProvider = CreateResultProvider(ResultProviderConfig);
+ auto resultProvider = CreateResultProvider(ResultProviderConfig);
TypesCtx->AddDataSink(ResultProviderName, resultProvider);
TypesCtx->AvailablePureResultDataSources = TVector<TString>(1, TString(KikimrProviderName));
@@ -1073,7 +1073,7 @@ public:
YQL_ENSURE(TypesCtx->Initialize(*ExprCtx));
YqlTransformer = TTransformationPipeline(TypesCtx)
- .AddServiceTransformers()
+ .AddServiceTransformers()
.Add(TLogExprTransformer::Sync("YqlTransformer", NYql::NLog::EComponent::ProviderKqp,
NYql::NLog::ELevel::TRACE), "LogYqlTransform")
.AddPreTypeAnnotation()
@@ -1455,7 +1455,7 @@ private:
return nullptr;
}
- TExprNode::TPtr result;
+ TExprNode::TPtr result;
if (!CompileExpr(*astRes.Root, result, ctx, ModuleResolver.get())) {
return nullptr;
}
diff --git a/ydb/core/kqp/host/kqp_runner.cpp b/ydb/core/kqp/host/kqp_runner.cpp
index abceadbda2..42b4eca7c6 100644
--- a/ydb/core/kqp/host/kqp_runner.cpp
+++ b/ydb/core/kqp/host/kqp_runner.cpp
@@ -114,7 +114,7 @@ public:
: Iterations(0) {}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
if (Iterations > MaxTransformIterations) {
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder()
@@ -440,7 +440,7 @@ private:
bool hasNonDeterministicFunctions;
TPeepholeSettings peepholeSettings;
peepholeSettings.WithNonDeterministicRules = false;
- status = PeepHoleOptimizeNode<false>(optimizedProgram, finalProgram, ctx, TypesCtx, KqlTypeAnnTransformer.Get(),
+ status = PeepHoleOptimizeNode<false>(optimizedProgram, finalProgram, ctx, TypesCtx, KqlTypeAnnTransformer.Get(),
hasNonDeterministicFunctions, peepholeSettings);
if (status != IGraphTransformer::TStatus::Ok) {
ctx.AddError(TIssue(ctx.GetPosition(dataQuery.Pos()), "Failed to peephole optimize KQL query."));
diff --git a/ydb/core/kqp/prepare/kqp_query_analyze.cpp b/ydb/core/kqp/prepare/kqp_query_analyze.cpp
index 15f35e18a5..b37e4eb058 100644
--- a/ydb/core/kqp/prepare/kqp_query_analyze.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_analyze.cpp
@@ -18,8 +18,8 @@ const THashSet<TStringBuf> SafeCallables {
TCoJust::CallableName(),
TCoCoalesce::CallableName(),
TCoToOptional::CallableName(),
- TCoHead::CallableName(),
- TCoLast::CallableName(),
+ TCoHead::CallableName(),
+ TCoLast::CallableName(),
TCoToList::CallableName(),
TCoMember::CallableName(),
@@ -47,14 +47,14 @@ bool IsSafePayloadCallable(const TCallable& callable) {
return true;
}
- if (callable.Maybe<TCoAnd>()) {
+ if (callable.Maybe<TCoAnd>()) {
+ return true;
+ }
+
+ if (callable.Maybe<TCoOr>()) {
return true;
}
- if (callable.Maybe<TCoOr>()) {
- return true;
- }
-
if (callable.Maybe<TCoBinaryArithmetic>()) {
return true;
}
@@ -527,7 +527,7 @@ public:
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
Y_UNUSED(ctx);
- output = input;
+ output = input;
auto commitSafety = TransformCtx->CommitSafety();
if (!TransformCtx->Config->HasAllowKqpUnsafeCommit()) {
diff --git a/ydb/core/kqp/prepare/kqp_query_exec.cpp b/ydb/core/kqp/prepare/kqp_query_exec.cpp
index 4fe14b3ad6..bc2d4e94ce 100644
--- a/ydb/core/kqp/prepare/kqp_query_exec.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_exec.cpp
@@ -209,7 +209,7 @@ NNodes::TExprBase PreserveParams(NNodes::TExprBase node,
return true;
});
- auto newNode = TExprBase(ctx.ReplaceNodes(node.Ptr(), replaceMap));
+ auto newNode = TExprBase(ctx.ReplaceNodes(node.Ptr(), replaceMap));
if (!resultsMap.empty()) {
VisitExpr(newNode.Ptr(), [&resultsMap] (const TExprNode::TPtr& node) {
@@ -240,7 +240,7 @@ public:
, TransformCtx(transformCtx) {}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
const auto& analyzeResults = TransformCtx->AnalyzeResults;
@@ -331,7 +331,7 @@ public:
}
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
NKikimr::NKqp::IKqpGateway::TMkqlResult result(MkqlExecuteResult.Future.ExtractValue());
diff --git a/ydb/core/kqp/prepare/kqp_query_finalize.cpp b/ydb/core/kqp/prepare/kqp_query_finalize.cpp
index 97f05ceb63..5e442780f7 100644
--- a/ydb/core/kqp/prepare/kqp_query_finalize.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_finalize.cpp
@@ -115,7 +115,7 @@ public:
, HasProgramResults(false) {}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
YQL_ENSURE(State == EFinalizeState::Initial);
@@ -496,32 +496,32 @@ private:
.Build()
.Done();
- TVector<TExprBase> args = {
- Build<TCoCmpEqual>(ctx, pos)
- .Left<TCoMember>()
- .Struct(selectLock)
- .Name().Build("Generation")
- .Build()
- .Right<TCoMember>()
- .Struct(lockArg)
- .Name().Build("Generation")
- .Build()
- .Done(),
- Build<TCoCmpEqual>(ctx, pos)
- .Left<TCoMember>()
- .Struct(selectLock)
- .Name().Build("Counter")
- .Build()
- .Right<TCoMember>()
- .Struct(lockArg)
- .Name().Build("Counter")
- .Build()
- .Done()
- };
+ TVector<TExprBase> args = {
+ Build<TCoCmpEqual>(ctx, pos)
+ .Left<TCoMember>()
+ .Struct(selectLock)
+ .Name().Build("Generation")
+ .Build()
+ .Right<TCoMember>()
+ .Struct(lockArg)
+ .Name().Build("Generation")
+ .Build()
+ .Done(),
+ Build<TCoCmpEqual>(ctx, pos)
+ .Left<TCoMember>()
+ .Struct(selectLock)
+ .Name().Build("Counter")
+ .Build()
+ .Right<TCoMember>()
+ .Struct(lockArg)
+ .Name().Build("Counter")
+ .Build()
+ .Done()
+ };
auto lockPredicate = Build<TCoNot>(ctx, pos)
.Value<TCoCoalesce>()
.Predicate<TCoAnd>()
- .Add(args)
+ .Add(args)
.Build()
.Value<TCoBool>()
.Literal().Build("false")
diff --git a/ydb/core/kqp/prepare/kqp_query_rewrite.cpp b/ydb/core/kqp/prepare/kqp_query_rewrite.cpp
index 4322cb7452..cb24a1b8a1 100644
--- a/ydb/core/kqp/prepare/kqp_query_rewrite.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_rewrite.cpp
@@ -58,7 +58,7 @@ TExprBase RebuildMapToList(TMapNode map, TExprContext& ctx) {
TExprNode::TPtr NormalizeCallables(TExprBase node, TExprContext& ctx, const TKqpAnalyzeResults& analyzeResults) {
if (!analyzeResults.CallableToExecRootsMap.contains(node.Raw())) {
- return node.Ptr();
+ return node.Ptr();
}
if (node.Maybe<TCoMap>() || node.Maybe<TCoFlatMap>()) {
@@ -73,23 +73,23 @@ TExprNode::TPtr NormalizeCallables(TExprBase node, TExprContext& ctx, const TKqp
.Input(filter.Cast().Input())
.Lambda()
.Args({"item"})
- .Body<TCoIf>()
+ .Body<TCoIf>()
.Predicate<TExprApplier>()
.Apply(filter.Cast().Lambda())
.With(0, "item")
.Build()
- .ThenValue<TCoJust>()
- .Input("item")
- .Build()
- .ElseValue<TCoNothing>()
- .OptionalType<TCoOptionalType>()
- .ItemType<TCoTypeOf>()
- .Value("item")
- .Build()
- .Build()
- .Build()
+ .ThenValue<TCoJust>()
+ .Input("item")
+ .Build()
+ .ElseValue<TCoNothing>()
+ .OptionalType<TCoOptionalType>()
+ .ItemType<TCoTypeOf>()
+ .Value("item")
+ .Build()
+ .Build()
+ .Build()
.Build()
- .Build()
+ .Build()
.Done()
.Ptr();
}
@@ -105,14 +105,14 @@ TExprNode::TPtr ToListOverToOptional(TExprBase node, TExprContext& ctx) {
YQL_CLOG(INFO, ProviderKqp) << "ToListOverToOptional";
return toOpt.Cast().List().Ptr();
}
- if (auto toOpt = toList.Cast().Optional().Maybe<TCoHead>()) {
- YQL_CLOG(INFO, ProviderKqp) << "ToListOverHead";
- return toOpt.Cast().Input().Ptr();
- }
- if (auto toOpt = toList.Cast().Optional().Maybe<TCoLast>()) {
- YQL_CLOG(INFO, ProviderKqp) << "ToListOverLast";
- return toOpt.Cast().Input().Ptr();
- }
+ if (auto toOpt = toList.Cast().Optional().Maybe<TCoHead>()) {
+ YQL_CLOG(INFO, ProviderKqp) << "ToListOverHead";
+ return toOpt.Cast().Input().Ptr();
+ }
+ if (auto toOpt = toList.Cast().Optional().Maybe<TCoLast>()) {
+ YQL_CLOG(INFO, ProviderKqp) << "ToListOverLast";
+ return toOpt.Cast().Input().Ptr();
+ }
}
return node.Ptr();
@@ -233,7 +233,7 @@ TExprBase SplitMap(TExprBase input, TCoLambda lambda, TExprContext& ctx, const T
replaceMap.emplace(jointNodes[i].Raw(), node.Ptr());
}
- auto outerLambdaBody = ctx.ReplaceNodes(lambda.Body().Ptr(), replaceMap);
+ auto outerLambdaBody = ctx.ReplaceNodes(lambda.Body().Ptr(), replaceMap);
auto outerLambda = Build<TCoLambda>(ctx, lambda.Pos())
.Args({outerLambdaArg})
.Body(TExprBase(outerLambdaBody))
@@ -349,7 +349,7 @@ public:
TExprBase node(input);
ret = NormalizeCallables(node, ctx, analyzeResults);
- if (ret != input) {
+ if (ret != input) {
return ret;
}
@@ -362,17 +362,17 @@ public:
}, ctx, optSettings);
YQL_ENSURE(status == TStatus::Ok);
- if (input != output) {
+ if (input != output) {
return TStatus(TStatus::Repeat, true);
}
status = OptimizeExpr(input, output,
- [&analyzeResults](const TExprNode::TPtr& input, TExprContext& ctx) {
- auto ret = input;
- TExprBase node(input);
+ [&analyzeResults](const TExprNode::TPtr& input, TExprContext& ctx) {
+ auto ret = input;
+ TExprBase node(input);
ret = UnnestExecutionRoots(node, ctx, analyzeResults);
- if (ret != input) {
+ if (ret != input) {
return ret;
}
@@ -380,7 +380,7 @@ public:
}, ctx, optSettings);
YQL_ENSURE(status == TStatus::Ok);
- YQL_ENSURE(input != output);
+ YQL_ENSURE(input != output);
return TStatus(TStatus::Repeat, true);
}
diff --git a/ydb/core/kqp/prepare/kqp_query_simplify.cpp b/ydb/core/kqp/prepare/kqp_query_simplify.cpp
index 340d0ce704..d8fefeb939 100644
--- a/ydb/core/kqp/prepare/kqp_query_simplify.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_simplify.cpp
@@ -141,12 +141,12 @@ TExprNode::TPtr ExtractCombineByKeyPreMap(TExprBase node, TExprContext& ctx) {
return node.Ptr();
}
-template <class TPartitionsType>
+template <class TPartitionsType>
TExprNode::TPtr ExtractPartitionByKeyListHandler(TExprBase node, TExprContext& ctx) {
- if (auto maybePartition = node.Maybe<TPartitionsType>()) {
+ if (auto maybePartition = node.Maybe<TPartitionsType>()) {
auto partition = maybePartition.Cast();
if (!IsKqlPureLambda(partition.ListHandlerLambda())) {
- auto newPartition = Build<TPartitionsType>(ctx, node.Pos())
+ auto newPartition = Build<TPartitionsType>(ctx, node.Pos())
.Input(partition.Input())
.KeySelectorLambda(partition.KeySelectorLambda())
.SortDirections(partition.SortDirections())
@@ -325,16 +325,16 @@ public:
return ret;
}
- ret = ExtractPartitionByKeyListHandler<TCoPartitionByKey>(node, ctx);
+ ret = ExtractPartitionByKeyListHandler<TCoPartitionByKey>(node, ctx);
+ if (ret != input) {
+ return ret;
+ }
+
+ ret = ExtractPartitionByKeyListHandler<TCoPartitionsByKeys>(node, ctx);
if (ret != input) {
return ret;
}
- ret = ExtractPartitionByKeyListHandler<TCoPartitionsByKeys>(node, ctx);
- if (ret != input) {
- return ret;
- }
-
ret = RewritePresentIfToFlatMap(node, ctx);
if (ret != input) {
return ret;
diff --git a/ydb/core/kqp/prepare/kqp_query_substitute.cpp b/ydb/core/kqp/prepare/kqp_query_substitute.cpp
index 26b90f675e..6d289bf78b 100644
--- a/ydb/core/kqp/prepare/kqp_query_substitute.cpp
+++ b/ydb/core/kqp/prepare/kqp_query_substitute.cpp
@@ -26,7 +26,7 @@ public:
return TStatus::Ok;
}
- TNodeOnNodeOwnedMap replaceMap;
+ TNodeOnNodeOwnedMap replaceMap;
for (size_t i = 0; i < analyzeResults.ExecutionRoots.size(); ++i) {
auto newParamName = TxState->Tx().NewParamName();
@@ -51,7 +51,7 @@ public:
replaceMap.emplace(node.Raw(), paramNode.Ptr());
}
- output = ctx.ReplaceNodes(std::move(input), replaceMap);
+ output = ctx.ReplaceNodes(std::move(input), replaceMap);
return TStatus(TStatus::Repeat, true);
}
diff --git a/ydb/core/kqp/provider/yql_kikimr_datasink.cpp b/ydb/core/kqp/provider/yql_kikimr_datasink.cpp
index 5fb4d239cc..035d6b7701 100644
--- a/ydb/core/kqp/provider/yql_kikimr_datasink.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_datasink.cpp
@@ -121,9 +121,9 @@ private:
}
TStatus HandleWrite(TExprBase node, TExprContext& ctx) override {
- auto cluster = node.Ref().Child(1)->Child(1)->Content();
+ auto cluster = node.Ref().Child(1)->Child(1)->Content();
TKikimrKey key(ctx);
- if (!key.Extract(*node.Ref().Child(2))) {
+ if (!key.Extract(*node.Ref().Child(2))) {
return TStatus::Error;
}
@@ -388,8 +388,8 @@ public:
bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
if (node.IsCallable(TCoDataSink::CallableName())) {
- if (node.Child(0)->Content() == KikimrProviderName) {
- if (node.Child(1)->Content().empty()) {
+ if (node.Child(0)->Content() == KikimrProviderName) {
+ if (node.Child(1)->Content().empty()) {
ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), "Empty cluster name"));
return false;
}
@@ -476,8 +476,8 @@ public:
return true;
}
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- YQL_ENSURE(node->IsCallable(WriteName), "Expected Write!, got: " << node->Content());
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ YQL_ENSURE(node->IsCallable(WriteName), "Expected Write!, got: " << node->Content());
TKikimrKey key(ctx);
YQL_ENSURE(key.Extract(*node->Child(2)), "Failed to extract ydb key.");
@@ -490,43 +490,43 @@ public:
if (mode == "drop") {
YQL_ENSURE(!settings.Columns);
- return Build<TKiDropTable>(ctx, node->Pos())
- .World(node->Child(0))
- .DataSink(node->Child(1))
+ return Build<TKiDropTable>(ctx, node->Pos())
+ .World(node->Child(0))
+ .DataSink(node->Child(1))
.Table().Build(key.GetTablePath())
.Settings(settings.Other)
.Done()
- .Ptr();
+ .Ptr();
} else if (mode == "update") {
YQL_ENSURE(settings.Filter);
YQL_ENSURE(settings.Update);
- return Build<TKiUpdateTable>(ctx, node->Pos())
- .World(node->Child(0))
- .DataSink(node->Child(1))
+ return Build<TKiUpdateTable>(ctx, node->Pos())
+ .World(node->Child(0))
+ .DataSink(node->Child(1))
.Table().Build(key.GetTablePath())
.Filter(settings.Filter.Cast())
.Update(settings.Update.Cast())
.Done()
- .Ptr();
+ .Ptr();
} else if (mode == "delete") {
YQL_ENSURE(settings.Filter);
- return Build<TKiDeleteTable>(ctx, node->Pos())
- .World(node->Child(0))
- .DataSink(node->Child(1))
+ return Build<TKiDeleteTable>(ctx, node->Pos())
+ .World(node->Child(0))
+ .DataSink(node->Child(1))
.Table().Build(key.GetTablePath())
.Filter(settings.Filter.Cast())
.Done()
- .Ptr();
+ .Ptr();
} else {
- return Build<TKiWriteTable>(ctx, node->Pos())
- .World(node->Child(0))
- .DataSink(node->Child(1))
+ return Build<TKiWriteTable>(ctx, node->Pos())
+ .World(node->Child(0))
+ .DataSink(node->Child(1))
.Table().Build(key.GetTablePath())
- .Input(node->Child(3))
+ .Input(node->Child(3))
.Mode(mode)
.Settings(settings.Other)
.Done()
- .Ptr();
+ .Ptr();
}
}
@@ -654,7 +654,7 @@ public:
bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
Y_UNUSED(compact);
if (CanExecute(node)) {
- children.push_back(node.ChildPtr(0));
+ children.push_back(node.ChildPtr(0));
return true;
}
@@ -693,10 +693,10 @@ private:
IGraphTransformer::TStatus TKiSinkVisitorTransformer::DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output,
TExprContext& ctx)
{
- YQL_ENSURE(input->Type() == TExprNode::Callable);
- output = input;
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
+ output = input;
- auto callable = TCallable(input);
+ auto callable = TCallable(input);
if (auto node = callable.Maybe<TKiClusterConfig>()) {
return HandleClusterConfig(node.Cast(), ctx);
@@ -714,7 +714,7 @@ IGraphTransformer::TStatus TKiSinkVisitorTransformer::DoTransform(TExprNode::TPt
return HandleDeleteTable(node.Cast(), ctx);
}
- if (auto node = TMaybeNode<TKiCreateTable>(input)) {
+ if (auto node = TMaybeNode<TKiCreateTable>(input)) {
return HandleCreateTable(node.Cast(), ctx);
}
@@ -722,7 +722,7 @@ IGraphTransformer::TStatus TKiSinkVisitorTransformer::DoTransform(TExprNode::TPt
return HandleAlterTable(node.Cast(), ctx);
}
- if (auto node = TMaybeNode<TKiDropTable>(input)) {
+ if (auto node = TMaybeNode<TKiDropTable>(input)) {
return HandleDropTable(node.Cast(), ctx);
}
@@ -750,8 +750,8 @@ IGraphTransformer::TStatus TKiSinkVisitorTransformer::DoTransform(TExprNode::TPt
return HandleDropGroup(node.Cast(), ctx);
}
- if (input->IsCallable(WriteName)) {
- return HandleWrite(TExprBase(input), ctx);
+ if (input->IsCallable(WriteName)) {
+ return HandleWrite(TExprBase(input), ctx);
}
if (auto node = callable.Maybe<TCoCommit>()) {
diff --git a/ydb/core/kqp/provider/yql_kikimr_datasource.cpp b/ydb/core/kqp/provider/yql_kikimr_datasource.cpp
index ce1bd634f8..65ef7eb932 100644
--- a/ydb/core/kqp/provider/yql_kikimr_datasource.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_datasource.cpp
@@ -21,7 +21,7 @@ private:
TStatus HandleKiRead(TKiReadBase node, TExprContext& ctx) override {
auto cluster = node.DataSource().Cluster();
TKikimrKey key(ctx);
- if (!key.Extract(node.TableKey().Ref())) {
+ if (!key.Extract(node.TableKey().Ref())) {
return TStatus::Error;
}
@@ -29,9 +29,9 @@ private:
}
TStatus HandleRead(TExprBase node, TExprContext& ctx) override {
- auto cluster = node.Ref().Child(1)->Child(1)->Content();
+ auto cluster = node.Ref().Child(1)->Child(1)->Content();
TKikimrKey key(ctx);
- if (!key.Extract(*node.Ref().Child(2))) {
+ if (!key.Extract(*node.Ref().Child(2))) {
return TStatus::Error;
}
@@ -87,7 +87,7 @@ public:
, SessionCtx(sessionCtx) {}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
if (ctx.Step.IsDone(TExprStep::LoadTablesMetadata)) {
return TStatus::Ok;
@@ -153,7 +153,7 @@ public:
}
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
YQL_ENSURE(AsyncFuture.HasValue());
for (auto& it : LoadResults) {
@@ -363,8 +363,8 @@ public:
bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
if (node.IsCallable(TCoDataSource::CallableName())) {
- if (node.Child(0)->Content() == KikimrProviderName) {
- if (node.Child(1)->Content().empty()) {
+ if (node.Child(0)->Content() == KikimrProviderName) {
+ if (node.Child(1)->Content().empty()) {
ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), "Empty cluster name"));
return false;
}
@@ -383,8 +383,8 @@ public:
return node.Child(1)->Child(0)->Content() == KikimrProviderName;
}
- if (node.IsCallable(TKiReadTable::CallableName()) || node.IsCallable(TKiReadTableScheme::CallableName()) || node.IsCallable(TKiReadTableList::CallableName())) {
- return TKiDataSource(node.ChildPtr(1)).Category() == KikimrProviderName;
+ if (node.IsCallable(TKiReadTable::CallableName()) || node.IsCallable(TKiReadTableScheme::CallableName()) || node.IsCallable(TKiReadTableList::CallableName())) {
+ return TKiDataSource(node.ChildPtr(1)).Category() == KikimrProviderName;
}
YQL_ENSURE(!KikimrDataSourceFunctions().contains(node.Content()));
@@ -403,19 +403,19 @@ public:
return false;
}
- bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
+ bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
Y_UNUSED(syncList);
canRef = false;
if (node.IsCallable(TCoRight::CallableName())) {
- const auto input = node.Child(0);
- if (input->IsCallable(TKiReadTableList::CallableName())) {
- return true;
- }
-
- if (input->IsCallable(TKiReadTableScheme::CallableName())) {
- return true;
- }
+ const auto input = node.Child(0);
+ if (input->IsCallable(TKiReadTableList::CallableName())) {
+ return true;
+ }
+
+ if (input->IsCallable(TKiReadTableScheme::CallableName())) {
+ return true;
+ }
}
if (auto maybeRight = TMaybeNode<TCoNth>(&node).Tuple().Maybe<TCoRight>()) {
@@ -441,8 +441,8 @@ public:
return false;
}
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- auto read = node->Child(0);
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ auto read = node->Child(0);
if (!read->IsCallable(ReadName)) {
ythrow yexception() << "Expected Read!";
}
@@ -467,7 +467,7 @@ public:
YQL_ENSURE(false, "Unsupported Kikimr KeyType.");
}
- auto newRead = ctx.RenameNode(*read, newName);
+ auto newRead = ctx.RenameNode(*read, newName);
if (auto maybeRead = TMaybeNode<TKiReadTable>(newRead)) {
auto read = maybeRead.Cast();
@@ -491,11 +491,11 @@ public:
auto retChildren = node->ChildrenList();
retChildren[0] = newRead;
- auto ret = ctx.ChangeChildren(*node, std::move(retChildren));
+ auto ret = ctx.ChangeChildren(*node, std::move(retChildren));
return ret;
}
- TExprNode::TPtr OptimizePull(const TExprNode::TPtr& source, const TFillSettings& fillSettings, TExprContext& ctx,
+ TExprNode::TPtr OptimizePull(const TExprNode::TPtr& source, const TFillSettings& fillSettings, TExprContext& ctx,
IOptimizationContext& optCtx) override
{
auto queryType = SessionCtx->Query().Type;
@@ -564,13 +564,13 @@ public:
optCtx.RemapNode(exec.Ref(), newExec.Ptr());
}
- return source;
+ return source;
}
bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
Y_UNUSED(compact);
if (CanExecute(node)) {
- children.push_back(node.ChildPtr(0));
+ children.push_back(node.ChildPtr(0));
return true;
}
@@ -599,21 +599,21 @@ private:
} // namespace
IGraphTransformer::TStatus TKiSourceVisitorTransformer::DoTransform(TExprNode::TPtr input,
- TExprNode::TPtr& output, TExprContext& ctx)
+ TExprNode::TPtr& output, TExprContext& ctx)
{
- YQL_ENSURE(input->Type() == TExprNode::Callable);
- output = input;
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
+ output = input;
- if (auto node = TMaybeNode<TKiReadBase>(input)) {
+ if (auto node = TMaybeNode<TKiReadBase>(input)) {
return HandleKiRead(node.Cast(), ctx);
}
- if (input->IsCallable(ReadName)) {
- return HandleRead(TExprBase(input), ctx);
+ if (input->IsCallable(ReadName)) {
+ return HandleRead(TExprBase(input), ctx);
}
- if (input->IsCallable(ConfigureName)) {
- return HandleConfigure(TExprBase(input), ctx);
+ if (input->IsCallable(ConfigureName)) {
+ return HandleConfigure(TExprBase(input), ctx);
}
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "(Kikimr DataSource) Unsupported function: " << input->Content()));
diff --git a/ydb/core/kqp/provider/yql_kikimr_exec.cpp b/ydb/core/kqp/provider/yql_kikimr_exec.cpp
index f09e9f2349..ad360fcaeb 100644
--- a/ydb/core/kqp/provider/yql_kikimr_exec.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_exec.cpp
@@ -174,11 +174,11 @@ public:
std::pair<TStatus, TAsyncTransformCallbackFuture> CallbackTransform(const TExprNode::TPtr& input,
TExprNode::TPtr& output, TExprContext& ctx)
{
- YQL_ENSURE(input->Type() == TExprNode::Callable);
- output = input;
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
+ output = input;
- if (input->Content() == "Pull") {
- auto pullInput = input->Child(0);
+ if (input->Content() == "Pull") {
+ auto pullInput = input->Child(0);
if (auto maybeNth = TMaybeNode<TCoNth>(pullInput)) {
ui32 index = FromString<ui32>(maybeNth.Cast().Index().Value());
@@ -188,7 +188,7 @@ public:
}
}
- IDataProvider::TFillSettings fillSettings = NCommon::GetFillSettings(*input);
+ IDataProvider::TFillSettings fillSettings = NCommon::GetFillSettings(*input);
if (auto maybeTableList = TMaybeNode<TCoRight>(pullInput).Input().Maybe<TKiReadTableList>()) {
if (!EnsureNotPrepare("tablelist", pullInput->Pos(), SessionCtx->Query(), ctx)) {
@@ -196,7 +196,7 @@ public:
}
TKikimrKey key(ctx);
- YQL_ENSURE(key.Extract(maybeTableList.Cast().TableKey().Ref()));
+ YQL_ENSURE(key.Extract(maybeTableList.Cast().TableKey().Ref()));
auto future = Gateway->ListPath(TString(maybeTableList.Cast().DataSource().Cluster()),
key.GetFolderPath());
@@ -217,7 +217,7 @@ public:
TKikimrKey key(ctx);
auto cluster = maybeTableScheme.Cast().DataSource().Cluster();
- YQL_ENSURE(key.Extract(maybeTableScheme.Cast().TableKey().Ref()));
+ YQL_ENSURE(key.Extract(maybeTableScheme.Cast().TableKey().Ref()));
auto& tableDesc = SessionCtx->Tables().ExistingTable(TString(cluster), key.GetTablePath());
TKikimrTableDescription rawTableDesc;
@@ -244,7 +244,7 @@ public:
}
}
- if (input->Content() == "Result") {
+ if (input->Content() == "Result") {
auto resultInput = TExprBase(input->ChildPtr(0));
auto exec = resultInput.Maybe<TCoNth>().Tuple().Maybe<TCoRight>().Input();
YQL_ENSURE(exec.Maybe<TKiExecDataQuery>());
@@ -278,7 +278,7 @@ public:
return SyncOk();
}
- if (input->Content() == "ClustersList") {
+ if (input->Content() == "ClustersList") {
if (!EnsureNotPrepare("ClustersList", input->Pos(), SessionCtx->Query(), ctx)) {
return SyncError();
}
@@ -304,13 +304,13 @@ public:
}
if (input->Content() == "KiReadTableList!" || input->Content() == "KiReadTableScheme!") {
- auto requireStatus = RequireChild(*input, 0);
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return SyncStatus(requireStatus);
}
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return SyncOk();
}
@@ -320,7 +320,7 @@ public:
}
private:
- static TExprNode::TPtr GetResOrPullResult(const TExprNode& node, const IDataProvider::TFillSettings& fillSettings,
+ static TExprNode::TPtr GetResOrPullResult(const TExprNode& node, const IDataProvider::TFillSettings& fillSettings,
const TTypeAnnotationNode* resultType, const NKikimrMiniKQL::TResult& resultValue, TExprContext& ctx)
{
TVector<TString> columnHints(NCommon::GetResOrPullColumnHints(node));
@@ -335,7 +335,7 @@ private:
// YQL_ENSURE(CheckKqpResultType(*protoValue, *resultType, ctx));
Y_UNUSED(resultType);
- TExprNode::TPtr resultNode;
+ TExprNode::TPtr resultNode;
if (fillSettings.Format == IDataProvider::EResultFormat::Yson) {
NYson::EYsonFormat ysonFormat = NCommon::GetYsonFormat(fillSettings);
@@ -414,11 +414,11 @@ public:
std::pair<TStatus, TAsyncTransformCallbackFuture> CallbackTransform(const TExprNode::TPtr& input,
TExprNode::TPtr& output, TExprContext& ctx)
{
- YQL_ENSURE(input->Type() == TExprNode::Callable);
- output = input;
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
+ output = input;
if (auto maybeCommit = TMaybeNode<TCoCommit>(input)) {
- auto requireStatus = RequireChild(*input, 0);
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return SyncStatus(requireStatus);
}
@@ -431,7 +431,7 @@ public:
}
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return SyncOk();
}
@@ -446,16 +446,16 @@ public:
if (TMaybeNode<TCoNth>(input)) {
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return SyncOk();
}
- if (auto maybeCreate = TMaybeNode<TKiCreateTable>(input)) {
+ if (auto maybeCreate = TMaybeNode<TKiCreateTable>(input)) {
if (!EnsureNotPrepare("CREATE TABLE", input->Pos(), SessionCtx->Query(), ctx)) {
return SyncError();
}
- auto requireStatus = RequireChild(*input, 0);
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return SyncStatus(requireStatus);
}
@@ -477,12 +477,12 @@ public:
}, "Executing CREATE TABLE");
}
- if (auto maybeDrop = TMaybeNode<TKiDropTable>(input)) {
+ if (auto maybeDrop = TMaybeNode<TKiDropTable>(input)) {
if (!EnsureNotPrepare("DROP TABLE", input->Pos(), SessionCtx->Query(), ctx)) {
return SyncError();
}
- auto requireStatus = RequireChild(*input, 0);
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return SyncStatus(requireStatus);
}
@@ -504,7 +504,7 @@ public:
});
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return SyncOk();
}
diff --git a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.cpp b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.cpp
index ef4248b3b8..cbe44c3a9d 100644
--- a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.cpp
@@ -7,7 +7,7 @@ namespace NNodes {
TString TKiReadTable::GetTable(TExprContext& ctx) const {
TKikimrKey key(ctx);
- YQL_ENSURE(key.Extract(TableKey().Ref()));
+ YQL_ENSURE(key.Extract(TableKey().Ref()));
YQL_ENSURE(key.GetKeyType() == TKikimrKey::Type::Table);
return key.GetTablePath();
diff --git a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.h b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.h
index fdf21596e6..e91fd7635a 100644
--- a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.h
+++ b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.h
@@ -13,10 +13,10 @@ namespace NNodes {
class TKiDataSource : public NGenerated::TKiDataSourceStub<TExprBase, TCallable, TCoAtom> {
public:
- explicit TKiDataSource(const TExprNode* node)
- : TKiDataSourceStub(node) {}
-
- explicit TKiDataSource(const TExprNode::TPtr& node)
+ explicit TKiDataSource(const TExprNode* node)
+ : TKiDataSourceStub(node) {}
+
+ explicit TKiDataSource(const TExprNode::TPtr& node)
: TKiDataSourceStub(node) {}
static bool Match(const TExprNode* node) {
@@ -34,10 +34,10 @@ public:
class TKiDataSink : public NGenerated::TKiDataSinkStub<TExprBase, TCallable, TCoAtom> {
public:
- explicit TKiDataSink(const TExprNode* node)
- : TKiDataSinkStub(node) {}
-
- explicit TKiDataSink(const TExprNode::TPtr& node)
+ explicit TKiDataSink(const TExprNode* node)
+ : TKiDataSinkStub(node) {}
+
+ explicit TKiDataSink(const TExprNode::TPtr& node)
: TKiDataSinkStub(node) {}
static bool Match(const TExprNode* node) {
@@ -55,10 +55,10 @@ public:
class TKiReadTable : public NGenerated::TKiReadTableStub<TExprBase, TKiReadBase, TCoNameValueTupleList> {
public:
- explicit TKiReadTable(const TExprNode* node)
- : TKiReadTableStub(node) {}
-
- explicit TKiReadTable(const TExprNode::TPtr& node)
+ explicit TKiReadTable(const TExprNode* node)
+ : TKiReadTableStub(node) {}
+
+ explicit TKiReadTable(const TExprNode::TPtr& node)
: TKiReadTableStub(node) {}
TString GetTable(TExprContext& ctx) const;
@@ -80,7 +80,7 @@ public:
: NGenerated::TKiColumnRangeTupleBuilder<TParent>(ctx, pos, buildFunc, getArgFunc) {}
TKiColumnRangeTuple DoBuild() {
- auto node = this->Ctx.NewList(this->Pos, { this->ColumnHolder.Cast().Ptr(), this->FromHolder.Cast().Ptr(), this->ToHolder.Cast().Ptr() });
+ auto node = this->Ctx.NewList(this->Pos, { this->ColumnHolder.Cast().Ptr(), this->FromHolder.Cast().Ptr(), this->ToHolder.Cast().Ptr() });
return TKiColumnRangeTuple(node);
}
};
diff --git a/ydb/core/kqp/provider/yql_kikimr_kql.cpp b/ydb/core/kqp/provider/yql_kikimr_kql.cpp
index 2ce729d0ff..95f5915a57 100644
--- a/ydb/core/kqp/provider/yql_kikimr_kql.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_kql.cpp
@@ -388,7 +388,7 @@ TExprNode::TPtr KiInsertTableToKql(const TKiWriteTable& node, TExprContext& ctx,
.Done();
auto predicate = Build<TCoOr>(ctx, node.Pos())
- .Add({duplicatesPredicate, fetchPredicate})
+ .Add({duplicatesPredicate, fetchPredicate})
.Done();
TExprNode::TPtr insertEffect;
diff --git a/ydb/core/kqp/provider/yql_kikimr_mkql.cpp b/ydb/core/kqp/provider/yql_kikimr_mkql.cpp
index e5782f5675..4cd98892e4 100644
--- a/ydb/core/kqp/provider/yql_kikimr_mkql.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_mkql.cpp
@@ -105,8 +105,8 @@ TExprNode::TPtr MkqlRewriteCallables(TCallable callable, TExprContext& ctx, cons
if (auto setResult = callable.Maybe<TKiSetResult>()) {
return ctx.Builder(setResult.Cast().Pos())
.Callable("SetResult")
- .Add(0, setResult.Cast().Name().Ptr())
- .Add(1, setResult.Cast().Data().Ptr())
+ .Add(0, setResult.Cast().Name().Ptr())
+ .Add(1, setResult.Cast().Data().Ptr())
.Seal()
.Build();
}
@@ -114,7 +114,7 @@ TExprNode::TPtr MkqlRewriteCallables(TCallable callable, TExprContext& ctx, cons
if (auto acquireLocks = callable.Maybe<TKiAcquireLocks>()) {
return ctx.Builder(acquireLocks.Cast().Pos())
.Callable("AcquireLocks")
- .Add(0, acquireLocks.Cast().LockTxId().Ptr())
+ .Add(0, acquireLocks.Cast().LockTxId().Ptr())
.Seal()
.Build();
}
@@ -130,8 +130,8 @@ TExprNode::TPtr MkqlRewriteCallables(TCallable callable, TExprContext& ctx, cons
if (auto map = callable.Maybe<TKiFlatMapParameter>()) {
return ctx.Builder(map.Cast().Pos())
.Callable("FlatMapParameter")
- .Add(0, map.Cast().Input().Ptr())
- .Add(1, map.Cast().Lambda().Ptr())
+ .Add(0, map.Cast().Input().Ptr())
+ .Add(1, map.Cast().Lambda().Ptr())
.Seal()
.Build();
}
@@ -153,7 +153,7 @@ TExprNode::TPtr MkqlRewriteCallables(TCallable callable, TExprContext& ctx, cons
.Build();
}
- return callable.Ptr();
+ return callable.Ptr();
}
} // namespace
@@ -177,7 +177,7 @@ TMaybeNode<TExprBase> TranslateToMkql(TExprBase node, TExprContext& ctx, const T
node = program.Effects();
}
- auto current = node.Ptr();
+ auto current = node.Ptr();
TExprNode::TPtr output;
TOptimizeExprSettings optSettings(nullptr);
optSettings.VisitChanges = true;
@@ -197,7 +197,7 @@ TMaybeNode<TExprBase> TranslateToMkql(TExprBase node, TExprContext& ctx, const T
}, ctx, optSettings);
if (status != IGraphTransformer::TStatus::Ok) {
- return TExprNode::TPtr();
+ return TExprNode::TPtr();
}
return TExprBase(output);
diff --git a/ydb/core/kqp/provider/yql_kikimr_opt.cpp b/ydb/core/kqp/provider/yql_kikimr_opt.cpp
index b8e44b51f5..cdbb6e600d 100644
--- a/ydb/core/kqp/provider/yql_kikimr_opt.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_opt.cpp
@@ -42,9 +42,9 @@ TExprNode::TPtr KiEmptyCommit(TExprBase node) {
return innerCommit.Ptr();
}
-TExprNode::TPtr KiEraseOverSelectRow(TExprBase node, TExprContext& ctx) {
+TExprNode::TPtr KiEraseOverSelectRow(TExprBase node, TExprContext& ctx) {
if (!node.Maybe<TCoFlatMap>().Input().Maybe<TKiSelectRow>()) {
- return node.Ptr();
+ return node.Ptr();
}
auto map = node.Cast<TCoFlatMap>();
@@ -97,7 +97,7 @@ TExprNode::TPtr KiEraseOverSelectRow(TExprBase node, TExprContext& ctx) {
}
}
- return node.Ptr();
+ return node.Ptr();
}
TExprNode::TPtr KiRewriteAggregate(TExprBase node, TExprContext& ctx) {
@@ -120,7 +120,7 @@ TExprNode::TPtr KiRewriteAggregate(TExprBase node, TExprContext& ctx) {
}
YQL_CLOG(INFO, ProviderKikimr) << "KiRewriteAggregate";
- return ExpandAggregate(node.Ptr(), ctx);
+ return ExpandAggregate(node.Ptr(), ctx);
}
TExprNode::TPtr KiRedundantSortByPk(TExprBase node, TExprContext& ctx,
@@ -667,8 +667,8 @@ TAutoPtr<IGraphTransformer> CreateKiLogicalOptProposalTransformer(TIntrusivePtr<
optCtx.ParentsMap = &parentsMap;
TStatus status = OptimizeExpr(input, output, [sessionCtx, &optCtx](const TExprNode::TPtr& inputNode, TExprContext& ctx) {
- auto ret = inputNode;
- TExprBase node(inputNode);
+ auto ret = inputNode;
+ TExprBase node(inputNode);
ret = KiSqlInToEquiJoin(node, sessionCtx->Tables(), sessionCtx->Config(), ctx);
if (ret != inputNode) {
@@ -691,17 +691,17 @@ TAutoPtr<IGraphTransformer> CreateKiLogicalOptProposalTransformer(TIntrusivePtr<
}
ret = KiApplyLimitToSelectRange(node, ctx);
- if (ret != inputNode) {
+ if (ret != inputNode) {
return ret;
}
ret = KiPushPredicateToSelectRange(node, ctx, sessionCtx->Tables(), sessionCtx->Config());
- if (ret != inputNode) {
+ if (ret != inputNode) {
return ret;
}
ret = KiEraseOverSelectRow(node, ctx);
- if (ret != inputNode) {
+ if (ret != inputNode) {
return ret;
}
diff --git a/ydb/core/kqp/provider/yql_kikimr_opt_range.cpp b/ydb/core/kqp/provider/yql_kikimr_opt_range.cpp
index 4f2f9d6f6d..cce81efc42 100644
--- a/ydb/core/kqp/provider/yql_kikimr_opt_range.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_opt_range.cpp
@@ -214,7 +214,7 @@ TMaybeNode<TExprBase> KiTableLookupGetValue(TExprBase node, const TTypeAnnotatio
if (dataTypeName == "Utf8") {
auto atom = maybeString.Cast().Literal();
auto value = atom.Value();
- if (!IsUtf8(value)) {
+ if (!IsUtf8(value)) {
return {};
}
diff --git a/ydb/core/kqp/provider/yql_kikimr_provider.cpp b/ydb/core/kqp/provider/yql_kikimr_provider.cpp
index 0a9f2f4b54..635d164827 100644
--- a/ydb/core/kqp/provider/yql_kikimr_provider.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_provider.cpp
@@ -314,7 +314,7 @@ void TKikimrTableDescription::ToYson(NYson::TYsonWriter& writer) const {
writer.OnEndMap();
}
-bool TKikimrKey::Extract(const TExprNode& key) {
+bool TKikimrKey::Extract(const TExprNode& key) {
if (key.IsCallable("MrTableConcat")) {
Ctx.AddError(TIssue(Ctx.GetPosition(key.Pos()), "CONCAT is not supported on Kikimr clusters."));
return false;
diff --git a/ydb/core/kqp/provider/yql_kikimr_provider_impl.h b/ydb/core/kqp/provider/yql_kikimr_provider_impl.h
index 2ec99fc2a6..e1aa3cda2b 100644
--- a/ydb/core/kqp/provider/yql_kikimr_provider_impl.h
+++ b/ydb/core/kqp/provider/yql_kikimr_provider_impl.h
@@ -88,7 +88,7 @@ public:
return View;
}
- bool Extract(const TExprNode& key);
+ bool Extract(const TExprNode& key);
private:
TExprContext& Ctx;
diff --git a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp
index 2d411893af..692165204a 100644
--- a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp
@@ -47,7 +47,7 @@ const TTypeAnnotationNode* GetExpectedRowType(const TKikimrTableDescription& tab
return GetExpectedRowType(tableDesc, columns, pos, ctx);
}
-IGraphTransformer::TStatus ConvertTableRowType(TExprNode::TPtr& input, const TKikimrTableDescription& tableDesc,
+IGraphTransformer::TStatus ConvertTableRowType(TExprNode::TPtr& input, const TKikimrTableDescription& tableDesc,
TExprContext& ctx)
{
YQL_ENSURE(input->GetTypeAnn());
@@ -108,7 +108,7 @@ private:
auto cluster = TString(node.DataSource().Cluster());
TKikimrKey key(ctx);
- if (!key.Extract(node.TableKey().Ref())) {
+ if (!key.Extract(node.TableKey().Ref())) {
return TStatus::Error;
}
@@ -212,7 +212,7 @@ private:
}
TStatus HandleConfigure(TExprBase node, TExprContext& ctx) override {
- if (!EnsureWorldType(*node.Ref().Child(0), ctx)) {
+ if (!EnsureWorldType(*node.Ref().Child(0), ctx)) {
return TStatus::Error;
}
@@ -283,11 +283,11 @@ private:
}
virtual TStatus HandleWriteTable(TKiWriteTable node, TExprContext& ctx) override {
- if (!EnsureWorldType(node.World().Ref(), ctx)) {
+ if (!EnsureWorldType(node.World().Ref(), ctx)) {
return TStatus::Error;
}
- if (!EnsureSpecificDataSink(node.DataSink().Ref(), KikimrProviderName, ctx)) {
+ if (!EnsureSpecificDataSink(node.DataSink().Ref(), KikimrProviderName, ctx)) {
return TStatus::Error;
}
@@ -425,7 +425,7 @@ private:
}
}
- auto status = ConvertTableRowType(node.Ptr()->ChildRef(TKiWriteTable::idx_Input), *table, ctx);
+ auto status = ConvertTableRowType(node.Ptr()->ChildRef(TKiWriteTable::idx_Input), *table, ctx);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -449,8 +449,8 @@ private:
}
auto rowType = table->SchemeNode;
- auto& filterLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Filter);
- if (!UpdateLambdaAllArgumentsTypes(filterLambda, {rowType}, ctx)) {
+ auto& filterLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Filter);
+ if (!UpdateLambdaAllArgumentsTypes(filterLambda, {rowType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -462,8 +462,8 @@ private:
return IGraphTransformer::TStatus::Error;
}
- auto& updateLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Update);
- if (!UpdateLambdaAllArgumentsTypes(updateLambda, {rowType}, ctx)) {
+ auto& updateLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Update);
+ if (!UpdateLambdaAllArgumentsTypes(updateLambda, {rowType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -496,7 +496,7 @@ private:
}
}
- auto updateBody = node.Update().Body().Ptr();
+ auto updateBody = node.Update().Body().Ptr();
auto status = ConvertTableRowType(updateBody, *table, ctx);
if (status != IGraphTransformer::TStatus::Ok) {
if (status == IGraphTransformer::TStatus::Repeat) {
@@ -504,7 +504,7 @@ private:
.Args(node.Update().Args())
.Body(updateBody)
.Done()
- .Ptr();
+ .Ptr();
}
return status;
@@ -529,8 +529,8 @@ private:
}
auto rowType = table->SchemeNode;
- auto& filterLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Filter);
- if (!UpdateLambdaAllArgumentsTypes(filterLambda, {rowType}, ctx)) {
+ auto& filterLambda = node.Ptr()->ChildRef(TKiUpdateTable::idx_Filter);
+ if (!UpdateLambdaAllArgumentsTypes(filterLambda, {rowType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1298,17 +1298,17 @@ private:
if (auto maybeMap = node.Maybe<TKiMapParameter>()) {
auto map = maybeMap.Cast();
- if (!EnsureArgsCount(map.Ref(), 2, ctx)) {
+ if (!EnsureArgsCount(map.Ref(), 2, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(map.Input().Ref(), ctx)) {
+ if (!EnsureListType(map.Input().Ref(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambda = map.Ptr()->ChildRef(TKiMapParameter::idx_Lambda);
+ auto& lambda = map.Ptr()->ChildRef(TKiMapParameter::idx_Lambda);
auto itemType = map.Input().Ref().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1324,17 +1324,17 @@ private:
if (auto maybeMap = node.Maybe<TKiFlatMapParameter>()) {
auto map = maybeMap.Cast();
- if (!EnsureArgsCount(map.Ref(), 2, ctx)) {
+ if (!EnsureArgsCount(map.Ref(), 2, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(map.Input().Ref(), ctx)) {
+ if (!EnsureListType(map.Input().Ref(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambda = map.Ptr()->ChildRef(TKiFlatMapParameter::idx_Lambda);
+ auto& lambda = map.Ptr()->ChildRef(TKiFlatMapParameter::idx_Lambda);
auto itemType = map.Input().Ref().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
diff --git a/ydb/core/kqp/runtime/kqp_read_table.cpp b/ydb/core/kqp/runtime/kqp_read_table.cpp
index 7b13ef6ea0..358ebd0a3e 100644
--- a/ydb/core/kqp/runtime/kqp_read_table.cpp
+++ b/ydb/core/kqp/runtime/kqp_read_table.cpp
@@ -235,8 +235,8 @@ class TKqpScanWideReadTableWrapperBase : public TStatelessWideFlowCodegeneratorN
using TBase = TStatelessWideFlowCodegeneratorNode<TKqpScanWideReadTableWrapperBase>;
public:
TKqpScanWideReadTableWrapperBase(TKqpScanComputeContext& computeCtx, std::vector<EValueRepresentation>&& representations)
- : TBase(this)
- , ComputeCtx(computeCtx)
+ : TBase(this)
+ , ComputeCtx(computeCtx)
, Representations(std::move(representations))
{}
@@ -340,8 +340,8 @@ private:
}
void RegisterDependencies() const {
- FlowDependsOn(FromNode);
- FlowDependsOn(ToNode);
+ FlowDependsOn(FromNode);
+ FlowDependsOn(ToNode);
}
private:
diff --git a/ydb/core/kqp/ut/kqp_explain_ut.cpp b/ydb/core/kqp/ut/kqp_explain_ut.cpp
index de4cae9d75..c3a0683636 100644
--- a/ydb/core/kqp/ut/kqp_explain_ut.cpp
+++ b/ydb/core/kqp/ut/kqp_explain_ut.cpp
@@ -65,7 +65,7 @@ Y_UNIT_TEST_SUITE(KqpExplain) {
NJson::TJsonValue plan;
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
- auto join = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan");
+ auto join = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan");
UNIT_ASSERT(join.IsDefined());
auto left = FindPlanNodeByKv(join, "Table", "EightShard");
UNIT_ASSERT(left.IsDefined());
@@ -91,7 +91,7 @@ Y_UNIT_TEST_SUITE(KqpExplain) {
NJson::TJsonValue plan;
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
- auto join = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan");
+ auto join = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan");
UNIT_ASSERT(join.IsDefined());
auto left = FindPlanNodeByKv(join, "Table", "EightShard");
UNIT_ASSERT(left.IsDefined());
@@ -179,7 +179,7 @@ Y_UNIT_TEST_SUITE(KqpExplain) {
auto join = FindPlanNodeByKv(
plan,
"Node Type",
- "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan"
+ "Aggregate-InnerJoin (MapJoin)-Filter-TableFullScan"
);
UNIT_ASSERT(join.IsDefined());
auto left = FindPlanNodeByKv(join, "Table", "EightShard");
@@ -319,9 +319,9 @@ Y_UNIT_TEST_SUITE(KqpExplain) {
NJson::TJsonValue plan;
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
- auto join1 = FindPlanNodeByKv(plan, "Node Type", "Sort-InnerJoin (MapJoin)-Filter-Aggregate-Sort");
+ auto join1 = FindPlanNodeByKv(plan, "Node Type", "Sort-InnerJoin (MapJoin)-Filter-Aggregate-Sort");
UNIT_ASSERT(join1.IsDefined());
- auto join2 = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter");
+ auto join2 = FindPlanNodeByKv(plan, "Node Type", "Aggregate-InnerJoin (MapJoin)-Filter");
UNIT_ASSERT(join2.IsDefined());
}
diff --git a/ydb/core/kqp/ut/kqp_locks_ut.cpp b/ydb/core/kqp/ut/kqp_locks_ut.cpp
index a08ff5e6a9..bd9d9ede5b 100644
--- a/ydb/core/kqp/ut/kqp_locks_ut.cpp
+++ b/ydb/core/kqp/ut/kqp_locks_ut.cpp
@@ -16,9 +16,9 @@ Y_UNIT_TEST_SUITE(KqpLocks) {
auto result = session1.ExecuteDataQuery(Q_(R"(
UPSERT INTO `/Root/Test`
- SELECT Group + 10U AS Group, Name, Amount, Comment ?? "" || "Updated" AS Comment
+ SELECT Group + 10U AS Group, Name, Amount, Comment ?? "" || "Updated" AS Comment
FROM `/Root/Test`
- WHERE Group == 1U AND Name == "Paul";
+ WHERE Group == 1U AND Name == "Paul";
)"), TTxControl::BeginTx(TTxSettings::SerializableRW())).ExtractValueSync();
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
@@ -27,13 +27,13 @@ Y_UNIT_TEST_SUITE(KqpLocks) {
result = session2.ExecuteDataQuery(Q_(R"(
UPSERT INTO `/Root/Test` (Group, Name, Comment)
- VALUES (1U, "Paul", "Changed");
+ VALUES (1U, "Paul", "Changed");
)"), TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync();
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
result = session1.ExecuteDataQuery(Q_(R"(
UPSERT INTO `/Root/Test` (Group, Name, Comment)
- VALUES (11U, "Sergey", "BadRow");
+ VALUES (11U, "Sergey", "BadRow");
)"), TTxControl::Tx(*tx1).CommitTx()).ExtractValueSync();
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::ABORTED, result.GetIssues().ToString());
result.GetIssues().PrintTo(Cerr);
@@ -105,7 +105,7 @@ Y_UNIT_TEST_SUITE(KqpLocks) {
result = session2.ExecuteDataQuery(Q_(R"(
UPSERT INTO `/Root/Test` (Group, Name, Comment)
- VALUES (2U, "Paul", "Changed");
+ VALUES (2U, "Paul", "Changed");
)"), TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync();
UNIT_ASSERT(result.IsSuccess());
diff --git a/ydb/core/mon/mon.cpp b/ydb/core/mon/mon.cpp
index d132720b34..d4722266f3 100644
--- a/ydb/core/mon/mon.cpp
+++ b/ydb/core/mon/mon.cpp
@@ -458,7 +458,7 @@ namespace NActors {
IMonPage *TMon::RegisterCountersPage(const TString &path, const TString &title, TIntrusivePtr<TDynamicCounters> counters) {
TDynamicCountersPage* page = new TDynamicCountersPage(path, title, counters);
page->SetUnknownGroupPolicy(EUnknownGroupPolicy::Ignore);
- Register(page);
+ Register(page);
return page;
}
diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto
index 7a553e6e8e..d64169d4fc 100644
--- a/ydb/core/protos/config.proto
+++ b/ydb/core/protos/config.proto
@@ -350,14 +350,14 @@ message TBootstrap {
optional TCompileServiceConfig CompileServiceConfig = 9; //may be need special file with resource limits?
optional bool EnableIntrospection = 10;
}
-
-message TInterconnectConfig {
- message TChannel {
- optional uint32 Index = 1;
+
+message TInterconnectConfig {
+ message TChannel {
+ optional uint32 Index = 1;
optional uint32 Quota = 2; // deprecated
optional uint32 Weight = 3; // use this instead of field "Quota"
- }
-
+ }
+
enum EMergeMode {
AUTO = 0;
PER_PEER = 1;
@@ -371,7 +371,7 @@ message TInterconnectConfig {
REQUIRED = 2;
};
- repeated TChannel Channel = 1;
+ repeated TChannel Channel = 1;
optional bool FirstTryBeforePoll = 2; // DEPRECATED
optional bool StartTcp = 3 [default = false];
optional uint32 SelfKickDelay = 4; // DEPRECATED
@@ -414,7 +414,7 @@ message TInterconnectConfig {
optional NKikimrConfigUnits.TDuration ForceConfirmPeriodDuration = 27;
optional NKikimrConfigUnits.TDuration LostConnectionDuration = 28;
optional NKikimrConfigUnits.TDuration BatchPeriodDuration = 29;
-}
+}
message TChannelProfileConfig {
message TProfile {
diff --git a/ydb/core/scheme_types/scheme_types_defs.h b/ydb/core/scheme_types/scheme_types_defs.h
index 3eda31c4b9..bb06b09702 100644
--- a/ydb/core/scheme_types/scheme_types_defs.h
+++ b/ydb/core/scheme_types/scheme_types_defs.h
@@ -95,7 +95,7 @@ namespace NNames {
extern const char Bool[5];
}
-class TBool : public TTypedType<bool, TBool, NTypeIds::Bool, NNames::Bool> {
+class TBool : public TTypedType<bool, TBool, NTypeIds::Bool, NNames::Bool> {
public:
};
diff --git a/ydb/core/tablet/pipe_tracker.h b/ydb/core/tablet/pipe_tracker.h
index 58dfa43477..33b90ba82b 100644
--- a/ydb/core/tablet/pipe_tracker.h
+++ b/ydb/core/tablet/pipe_tracker.h
@@ -2,7 +2,7 @@
#include "defs.h"
#include <ydb/core/tablet/tablet_pipe_client_cache.h>
#include <ydb/core/util/tuples.h>
-#include <functional>
+#include <functional>
#include <unordered_map>
#include <unordered_set>
diff --git a/ydb/core/tablet/tablet_setup.h b/ydb/core/tablet/tablet_setup.h
index e97619f944..57ea7d6edb 100644
--- a/ydb/core/tablet/tablet_setup.h
+++ b/ydb/core/tablet/tablet_setup.h
@@ -3,7 +3,7 @@
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/shared_quota.h>
#include <ydb/core/base/tablet_types.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
diff --git a/ydb/core/testlib/tablet_helpers.h b/ydb/core/testlib/tablet_helpers.h
index 2faa1f75ff..81a7c614aa 100644
--- a/ydb/core/testlib/tablet_helpers.h
+++ b/ydb/core/testlib/tablet_helpers.h
@@ -11,7 +11,7 @@
#include <ydb/core/protos/tablet_database.pb.h>
#include <ydb/core/tx/tx.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
struct TAppPrepare;
diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp
index 0a336695b8..d4907c26f1 100644
--- a/ydb/core/testlib/test_client.cpp
+++ b/ydb/core/testlib/test_client.cpp
@@ -899,8 +899,8 @@ namespace Tests {
, DomainName(settings.DomainName)
, SupportsRedirect(settings.SupportsRedirect)
, StoragePoolTypes(settings.StoragePoolTypes)
- , FunctionRegistry(NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry()))
- , LoadedFunctionRegistry(NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry()))
+ , FunctionRegistry(NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry()))
+ , LoadedFunctionRegistry(NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry()))
{
TServerSetup serverSetup;
if (SupportsRedirect && Tests::IsServerRedirected()) {
@@ -952,7 +952,7 @@ namespace Tests {
UNIT_ASSERT(response.HasTypeMetadata() && response.HasFunctionMetadata());
DeserializeMetadata(response.GetTypeMetadata(), &LoadedTypeMetadataRegistry);
- DeserializeMetadata(response.GetFunctionMetadata(), *LoadedFunctionRegistry->GetBuiltins());
+ DeserializeMetadata(response.GetFunctionMetadata(), *LoadedFunctionRegistry->GetBuiltins());
TypesEtag = response.GetETag();
return true;
}
diff --git a/ydb/core/testlib/test_client.h b/ydb/core/testlib/test_client.h
index 3c348439df..2064752ab4 100644
--- a/ydb/core/testlib/test_client.h
+++ b/ydb/core/testlib/test_client.h
@@ -27,7 +27,7 @@
#include <google/protobuf/text_format.h>
-#include <functional>
+#include <functional>
#include <algorithm>
namespace NKikimr {
diff --git a/ydb/core/tx/coordinator/coordinator__check.h b/ydb/core/tx/coordinator/coordinator__check.h
index 7872976f3a..8277b0200b 100644
--- a/ydb/core/tx/coordinator/coordinator__check.h
+++ b/ydb/core/tx/coordinator/coordinator__check.h
@@ -25,7 +25,7 @@ struct TTxCoordinator::TTxConsistencyCheck : public TTransactionBase<TTxCoordina
TTransaction& transaction = transactions[txId];
transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
TVector<TTabletId> affectedSet = rowset.GetValue<Schema::Transaction::AffectedSet>();
- transaction.AffectedSet.reserve(affectedSet.size());
+ transaction.AffectedSet.reserve(affectedSet.size());
for (TTabletId id : affectedSet)
transaction.AffectedSet.insert(id);
if (!rowset.Next())
diff --git a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
index 55431b98e1..26a916bdff 100644
--- a/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
+++ b/ydb/core/tx/coordinator/coordinator__restore_transaction.cpp
@@ -27,7 +27,7 @@ struct TTxCoordinator::TTxRestoreTransactions : public TTransactionBase<TTxCoord
TTransaction& transaction = transactions[txId];
transaction.PlanOnStep = rowset.GetValue<Schema::Transaction::Plan>();
TVector<TTabletId> affectedSet = rowset.GetValue<Schema::Transaction::AffectedSet>();
- transaction.AffectedSet.reserve(affectedSet.size());
+ transaction.AffectedSet.reserve(affectedSet.size());
for (TTabletId id : affectedSet)
transaction.AffectedSet.insert(id);
if (!rowset.Next())
diff --git a/ydb/core/tx/datashard/datashard__engine_host.cpp b/ydb/core/tx/datashard/datashard__engine_host.cpp
index f0b2851d0b..876c337093 100644
--- a/ydb/core/tx/datashard/datashard__engine_host.cpp
+++ b/ydb/core/tx/datashard/datashard__engine_host.cpp
@@ -28,8 +28,8 @@ namespace {
NUdf::TUnboxedValue CreateRow(const TVector<TCell>& inRow,
const TVector<NScheme::TTypeId>& inType,
const THolderFactory& holderFactory) {
- NUdf::TUnboxedValue* rowItems = nullptr;
- auto row = holderFactory.CreateDirectArrayHolder(inRow.size(), rowItems);
+ NUdf::TUnboxedValue* rowItems = nullptr;
+ auto row = holderFactory.CreateDirectArrayHolder(inRow.size(), rowItems);
for (ui32 i = 0; i < inRow.size(); ++i) {
rowItems[i] = GetCellValue(inRow[i], inType[i]);
@@ -71,7 +71,7 @@ struct TRowResultInfo {
for (ui32 i = 0; i < columnIds->GetValuesCount(); ++i) {
TOptionalType * optType = AS_TYPE(TOptionalType, RowType->GetMemberType(i));
TDataLiteral* literal = AS_VALUE(TDataLiteral, columnIds->GetValue(i));
- ui32 colId = literal->AsValue().Get<ui32>();
+ ui32 colId = literal->AsValue().Get<ui32>();
const TSysTables::TTableColumnInfo * colInfo = columns.FindPtr(colId);
Y_VERIFY(colInfo && (colInfo->Id == colId), "No column info for column");
@@ -81,7 +81,7 @@ struct TRowResultInfo {
NUdf::TUnboxedValue CreateResult(TVector<TCell>&& inRow, const THolderFactory& holderFactory) const {
if (inRow.empty()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
Y_VERIFY(inRow.size() >= ItemInfos.size());
@@ -129,7 +129,7 @@ struct TRangeResultInfo {
for (ui32 i = 0; i < columnIds->GetValuesCount(); ++i) {
TOptionalType * optType = AS_TYPE(TOptionalType, RowType->GetMemberType(i));
TDataLiteral* literal = AS_VALUE(TDataLiteral, columnIds->GetValue(i));
- ui32 colId = literal->AsValue().Get<ui32>();
+ ui32 colId = literal->AsValue().Get<ui32>();
const TSysTables::TTableColumnInfo * colInfo = columns.FindPtr(colId);
Y_VERIFY(colInfo && (colInfo->Id == colId), "No column info for column");
@@ -173,14 +173,14 @@ struct TRangeResultInfo {
}
}
- NUdf::TUnboxedValue CreateResult(const THolderFactory& holderFactory) {
- NUdf::TUnboxedValue* resultItems = nullptr;
- auto result = holderFactory.CreateDirectArrayHolder(4, resultItems);
+ NUdf::TUnboxedValue CreateResult(const THolderFactory& holderFactory) {
+ NUdf::TUnboxedValue* resultItems = nullptr;
+ auto result = holderFactory.CreateDirectArrayHolder(4, resultItems);
resultItems[0] = holderFactory.CreateDirectListHolder(std::move(Rows));
- resultItems[1] = NUdf::TUnboxedValuePod(false);
- resultItems[2] = MakeString(FirstKey);
- resultItems[3] = NUdf::TUnboxedValuePod(Bytes);
+ resultItems[1] = NUdf::TUnboxedValuePod(false);
+ resultItems[2] = MakeString(FirstKey);
+ resultItems[3] = NUdf::TUnboxedValuePod(Bytes);
return std::move(result);
}
@@ -207,7 +207,7 @@ public:
}
}
- NUdf::TUnboxedValue SelectRow(const TArrayRef<const TCell>& row, TStructLiteral* columnIds,
+ NUdf::TUnboxedValue SelectRow(const TArrayRef<const TCell>& row, TStructLiteral* columnIds,
TOptionalType* returnType, const TReadTarget& readTarget, const THolderFactory& holderFactory) const
{
Y_UNUSED(readTarget);
@@ -358,7 +358,7 @@ public:
return TEngineHost::IsValidKey(key, maxSnapshotTime);
}
- NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
+ NUdf::TUnboxedValue SelectRow(const TTableId& tableId, const TArrayRef<const TCell>& row,
TStructLiteral* columnIds, TOptionalType* returnType, const TReadTarget& readTarget,
const THolderFactory& holderFactory) override
{
@@ -372,7 +372,7 @@ public:
return TEngineHost::SelectRow(tableId, row, columnIds, returnType, readTarget, holderFactory);
}
- NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
+ NUdf::TUnboxedValue SelectRange(const TTableId& tableId, const TTableRange& range,
TStructLiteral* columnIds, TListLiteral* skipNullKeys, TStructType* returnType,
const TReadTarget& readTarget, ui64 itemsLimit, ui64 bytesLimit, bool reverse,
std::pair<const TListLiteral*, const TListLiteral*> forbidNullArgs, const THolderFactory& holderFactory) override
@@ -699,7 +699,7 @@ NKqp::TKqpTasksRunner& TEngineBay::GetKqpTasksRunner(const NKikimrTxDataShard::T
settings.CollectProfileStats = false;
}
- settings.OptLLVM = "OFF";
+ settings.OptLLVM = "OFF";
settings.TerminateOnError = false;
settings.AllowGeneratorsInUnboxedValues = false;
diff --git a/ydb/core/tx/datashard/datashard_kqp_lookup_table.cpp b/ydb/core/tx/datashard/datashard_kqp_lookup_table.cpp
index f9a41cb491..24582c2664 100644
--- a/ydb/core/tx/datashard/datashard_kqp_lookup_table.cpp
+++ b/ydb/core/tx/datashard/datashard_kqp_lookup_table.cpp
@@ -83,7 +83,7 @@ class TKqpLookupRowsWrapper : public TStatelessFlowComputationNode<TKqpLookupRow
public:
TKqpLookupRowsWrapper(TComputationMutables& mutables, TKqpDatashardComputeContext& computeCtx,
const TTypeEnvironment& typeEnv, const TParseLookupTableResult& parseResult, IComputationNode* lookupKeysNode)
- : TBase(mutables, this, EValueRepresentation::Boxed)
+ : TBase(mutables, this, EValueRepresentation::Boxed)
, ComputeCtx(computeCtx)
, TypeEnv(typeEnv)
, ParseResult(parseResult)
@@ -203,7 +203,7 @@ class TKqpLookupTableWrapper : public TStatelessFlowComputationNode<TKqpLookupTa
public:
TKqpLookupTableWrapper(TComputationMutables& mutables, TKqpDatashardComputeContext& computeCtx,
const TTypeEnvironment& typeEnv, const TParseLookupTableResult& parseResult, IComputationNode* lookupKeysNode)
- : TBase(mutables, this, EValueRepresentation::Boxed)
+ : TBase(mutables, this, EValueRepresentation::Boxed)
, ComputeCtx(computeCtx)
, TypeEnv(typeEnv)
, ParseResult(parseResult)
diff --git a/ydb/core/tx/datashard/datashard_kqp_read_table.cpp b/ydb/core/tx/datashard/datashard_kqp_read_table.cpp
index b1c5404a05..9fbd8ef0ad 100644
--- a/ydb/core/tx/datashard/datashard_kqp_read_table.cpp
+++ b/ydb/core/tx/datashard/datashard_kqp_read_table.cpp
@@ -198,7 +198,7 @@ public:
TKqpWideReadTableWrapperBase(TKqpDatashardComputeContext& computeCtx, const TTypeEnvironment& typeEnv,
const TSmallVec<TTag>& systemColumnTags, const TSmallVec<bool>& skipNullKeys)
: TStatelessWideFlowCodegeneratorNode<TKqpWideReadTableWrapperBase<IsReverse>>(this)
- , ComputeCtx(computeCtx)
+ , ComputeCtx(computeCtx)
, TypeEnv(typeEnv)
, SystemColumnTags(systemColumnTags)
, SkipNullKeys(skipNullKeys)
diff --git a/ydb/core/util/cache.h b/ydb/core/util/cache.h
index 766340bb8d..916701ebc7 100644
--- a/ydb/core/util/cache.h
+++ b/ydb/core/util/cache.h
@@ -3,7 +3,7 @@
#include <util/generic/intrlist.h>
#include <util/generic/map.h>
#include <util/generic/hash_set.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
namespace NCache {
@@ -95,10 +95,10 @@ class ICache {
public:
typedef ICache<TKey, TValue> TSelf;
- typedef std::function<void(const TKey& key, TValue& value, ui64 size)> TEvictionCallback;
- typedef std::function<void(const TKey& key)> TKeyEvictionCallback;
- typedef std::function<ui64(const TKey& key, const TValue& value)> TMeasureCallback;
- typedef std::function<bool(const TSelf& cache)> TOverflowCallback;
+ typedef std::function<void(const TKey& key, TValue& value, ui64 size)> TEvictionCallback;
+ typedef std::function<void(const TKey& key)> TKeyEvictionCallback;
+ typedef std::function<ui64(const TKey& key, const TValue& value)> TMeasureCallback;
+ typedef std::function<bool(const TSelf& cache)> TOverflowCallback;
virtual ~ICache() {}
virtual ui64 GetUsedSize() const = 0;
diff --git a/ydb/core/util/queue_inplace_ut.cpp b/ydb/core/util/queue_inplace_ut.cpp
index 070dce56b8..fb2d511d04 100644
--- a/ydb/core/util/queue_inplace_ut.cpp
+++ b/ydb/core/util/queue_inplace_ut.cpp
@@ -3,7 +3,7 @@
#include <util/generic/vector.h>
#include <library/cpp/threading/future/legacy_future.h>
-
+
#include "queue_inplace.h"
Y_UNIT_TEST_SUITE(TQueueInplaceTests) {
diff --git a/ydb/core/util/queue_oneone_inplace_ut.cpp b/ydb/core/util/queue_oneone_inplace_ut.cpp
index a4f3509eeb..ac60a69f3d 100644
--- a/ydb/core/util/queue_oneone_inplace_ut.cpp
+++ b/ydb/core/util/queue_oneone_inplace_ut.cpp
@@ -3,7 +3,7 @@
#include <util/generic/vector.h>
#include <library/cpp/threading/future/legacy_future.h>
-
+
#include "queue_oneone_inplace.h"
Y_UNIT_TEST_SUITE(TOneOneQueueTests) {
diff --git a/ydb/core/ymq/actor/queue_schema.cpp b/ydb/core/ymq/actor/queue_schema.cpp
index 0eab80a19c..91d3c5d3df 100644
--- a/ydb/core/ymq/actor/queue_schema.cpp
+++ b/ydb/core/ymq/actor/queue_schema.cpp
@@ -785,8 +785,8 @@ static const char* const CommitQueueParamsQuery = R"__(
(let queuesRead (SelectRow queuesTable queuesRow queuesSelect))
(let existingQueuesWithSameNameAndFolderId
- (If (Equal (Utf8String '"") customName)
- (List (TypeOf queues))
+ (If (Equal (Utf8String '"") customName)
+ (List (TypeOf queues))
(Filter queues (lambda '(item) (block '(
(return (Coalesce
(And
diff --git a/ydb/core/yq/libs/actors/pending_fetcher.cpp b/ydb/core/yq/libs/actors/pending_fetcher.cpp
index 3ad6377b03..0095963c8f 100644
--- a/ydb/core/yq/libs/actors/pending_fetcher.cpp
+++ b/ydb/core/yq/libs/actors/pending_fetcher.cpp
@@ -106,8 +106,8 @@ public:
TIntrusivePtr<IRandomProvider> randomProvider,
NKikimr::NMiniKQL::TComputationNodeFactory dqCompFactory,
const ::NYq::NCommon::TServiceCounters& serviceCounters,
- ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
- IHTTPGateway::TPtr s3Gateway,
+ ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
+ IHTTPGateway::TPtr s3Gateway,
::NPq::NConfigurationManager::IConnections::TPtr pqCmConnections,
const NMonitoring::TDynamicCounterPtr& clientCounters
)
@@ -123,7 +123,7 @@ public:
, DqCompFactory(dqCompFactory)
, ServiceCounters(serviceCounters, "pending_fetcher")
, CredentialsFactory(credentialsFactory)
- , S3Gateway(s3Gateway)
+ , S3Gateway(s3Gateway)
, PqCmConnections(std::move(pqCmConnections))
, Guid(CreateGuidAsString())
, ClientCounters(clientCounters)
@@ -235,7 +235,7 @@ private:
TRunActorParams params(
YqSharedResources->YdbDriver, S3Gateway,
- FunctionRegistry, RandomProvider,
+ FunctionRegistry, RandomProvider,
ModuleResolver, ModuleResolver->GetNextUniqueId(),
DqCompFactory, PqCmConnections,
CommonConfig, CheckpointCoordinatorConfig,
@@ -297,7 +297,7 @@ private:
TActorId DatabaseResolver;
ISecuredServiceAccountCredentialsFactory::TPtr CredentialsFactory;
- const IHTTPGateway::TPtr S3Gateway;
+ const IHTTPGateway::TPtr S3Gateway;
const ::NPq::NConfigurationManager::IConnections::TPtr PqCmConnections;
const TString Guid; //OwnerId
@@ -320,8 +320,8 @@ NActors::IActor* CreatePendingFetcher(
TIntrusivePtr<IRandomProvider> randomProvider,
NKikimr::NMiniKQL::TComputationNodeFactory dqCompFactory,
const ::NYq::NCommon::TServiceCounters& serviceCounters,
- ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
- IHTTPGateway::TPtr s3Gateway,
+ ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
+ IHTTPGateway::TPtr s3Gateway,
::NPq::NConfigurationManager::IConnections::TPtr pqCmConnections,
const NMonitoring::TDynamicCounterPtr& clientCounters)
{
@@ -337,7 +337,7 @@ NActors::IActor* CreatePendingFetcher(
randomProvider,
dqCompFactory,
serviceCounters,
- credentialsFactory,
+ credentialsFactory,
s3Gateway,
std::move(pqCmConnections),
clientCounters);
diff --git a/ydb/core/yq/libs/actors/proxy.h b/ydb/core/yq/libs/actors/proxy.h
index 73fcc9b1d2..442d29ac44 100644
--- a/ydb/core/yq/libs/actors/proxy.h
+++ b/ydb/core/yq/libs/actors/proxy.h
@@ -46,7 +46,7 @@ NActors::IActor* CreatePendingFetcher(
NKikimr::NMiniKQL::TComputationNodeFactory dqCompFactory,
const ::NYq::NCommon::TServiceCounters& serviceCounters,
NYql::ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
- NYql::IHTTPGateway::TPtr s3Gateway,
+ NYql::IHTTPGateway::TPtr s3Gateway,
::NPq::NConfigurationManager::IConnections::TPtr pqCmConnections,
const NMonitoring::TDynamicCounterPtr& clientCounters
);
diff --git a/ydb/core/yq/libs/actors/run_actor.cpp b/ydb/core/yq/libs/actors/run_actor.cpp
index 68574e92fe..5549f8f254 100644
--- a/ydb/core/yq/libs/actors/run_actor.cpp
+++ b/ydb/core/yq/libs/actors/run_actor.cpp
@@ -1144,13 +1144,13 @@ private:
}
{
- dataProvidersInit.push_back(GetClickHouseDataProviderInitializer(Params.S3Gateway, dbResolver));
+ dataProvidersInit.push_back(GetClickHouseDataProviderInitializer(Params.S3Gateway, dbResolver));
+ }
+
+ {
+ dataProvidersInit.push_back(GetS3DataProviderInitializer(Params.S3Gateway, Params.CredentialsFactory));
}
- {
- dataProvidersInit.push_back(GetS3DataProviderInitializer(Params.S3Gateway, Params.CredentialsFactory));
- }
-
{
NYql::TPqGatewayServices pqServices(
Params.Driver,
diff --git a/ydb/core/yq/libs/actors/run_actor_params.cpp b/ydb/core/yq/libs/actors/run_actor_params.cpp
index 93b80403fb..1446cae1bb 100644
--- a/ydb/core/yq/libs/actors/run_actor_params.cpp
+++ b/ydb/core/yq/libs/actors/run_actor_params.cpp
@@ -6,7 +6,7 @@ using namespace NActors;
TRunActorParams::TRunActorParams(
NYdb::TDriver driver,
- NYql::IHTTPGateway::TPtr s3Gateway,
+ NYql::IHTTPGateway::TPtr s3Gateway,
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
TIntrusivePtr<IRandomProvider> randomProvider,
NYql::IModuleResolver::TPtr& moduleResolver,
@@ -47,7 +47,7 @@ TRunActorParams::TRunActorParams(
const NMonitoring::TDynamicCounterPtr& clientCounters
)
: Driver(driver)
- , S3Gateway(s3Gateway)
+ , S3Gateway(s3Gateway)
, FunctionRegistry(functionRegistry)
, RandomProvider(randomProvider)
, ModuleResolver(moduleResolver)
diff --git a/ydb/core/yq/libs/actors/run_actor_params.h b/ydb/core/yq/libs/actors/run_actor_params.h
index 92cdabb9b1..bad5c3c32b 100644
--- a/ydb/core/yq/libs/actors/run_actor_params.h
+++ b/ydb/core/yq/libs/actors/run_actor_params.h
@@ -20,7 +20,7 @@ namespace NYq {
struct TRunActorParams { // TODO2 : Change name
TRunActorParams(
NYdb::TDriver driver,
- NYql::IHTTPGateway::TPtr s3Gateway,
+ NYql::IHTTPGateway::TPtr s3Gateway,
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
TIntrusivePtr<IRandomProvider> randomProvider,
NYql::IModuleResolver::TPtr& moduleResolver,
@@ -65,7 +65,7 @@ struct TRunActorParams { // TODO2 : Change name
TRunActorParams(TRunActorParams&& params) = default;
NYdb::TDriver Driver;
- NYql::IHTTPGateway::TPtr S3Gateway;
+ NYql::IHTTPGateway::TPtr S3Gateway;
const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry;
TIntrusivePtr<IRandomProvider> RandomProvider;
NYql::IModuleResolver::TPtr ModuleResolver;
diff --git a/ydb/core/yq/libs/events/events.h b/ydb/core/yq/libs/events/events.h
index db3c5c79f9..b3c70e5c5f 100644
--- a/ydb/core/yq/libs/events/events.h
+++ b/ydb/core/yq/libs/events/events.h
@@ -20,9 +20,9 @@ using NYdb::NYq::TScope;
enum class DatabaseType {
Ydb,
- ClickHouse,
+ ClickHouse,
DataStreams,
- ObjectStorage
+ ObjectStorage
};
struct TQueryResult {
diff --git a/ydb/core/yq/libs/private_client/utils.cpp b/ydb/core/yq/libs/private_client/utils.cpp
index f87fe4cb40..f1ba5c7e22 100644
--- a/ydb/core/yq/libs/private_client/utils.cpp
+++ b/ydb/core/yq/libs/private_client/utils.cpp
@@ -9,8 +9,8 @@ using namespace NYdb::NYq;
void UpdateConnections(
TClient& client,
- const TString& folderId,
- const TString& connectionsStr) {
+ const TString& folderId,
+ const TString& connectionsStr) {
NJson::TJsonValue value;
TStringStream in(connectionsStr);
NJson::ReadJsonTree(&in, &value);
diff --git a/ydb/core/yql_testlib/yql_testlib.cpp b/ydb/core/yql_testlib/yql_testlib.cpp
index 917e5eea17..35838c40f6 100644
--- a/ydb/core/yql_testlib/yql_testlib.cpp
+++ b/ydb/core/yql_testlib/yql_testlib.cpp
@@ -35,19 +35,19 @@ public:
return name;
}
-private:
- TUnboxedValue Run(
- const NKikimr::NUdf::IValueBuilder* valueBuilder,
- const NKikimr::NUdf::TUnboxedValuePod* args) const override
- {
+private:
+ TUnboxedValue Run(
+ const NKikimr::NUdf::IValueBuilder* valueBuilder,
+ const NKikimr::NUdf::TUnboxedValuePod* args) const override
+ {
TString orig(args[0].AsStringRef());
- ui64 times = args[1].Get<ui64>();
+ ui64 times = args[1].Get<ui64>();
TString res = "";
- for (ui64 i = 0; i < times; i++) {
- res += orig;
- }
- return valueBuilder->NewString(res);
- }
+ for (ui64 i = 0; i < times; i++) {
+ res += orig;
+ }
+ return valueBuilder->NewString(res);
+ }
};
@@ -68,24 +68,24 @@ public:
}
private:
- NKikimr::NUdf::TUnboxedValue Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override
- {
- Y_UNUSED(valueBuilder);
- YQL_ENSURE(Runtime->IsRealThreads());
-
- ui64 tabletID = args[0].Get<ui64>();
-
- auto sender = Runtime->AllocateEdgeActor();
-
- Runtime->SendToPipe(tabletID, sender, new NKikimr::TEvents::TEvPoisonPill);
-
- ResumeYqlExecution.Wait();
-
- ui64 result = 0;
- return TUnboxedValuePod(result);
- }
+ NKikimr::NUdf::TUnboxedValue Run(
+ const IValueBuilder* valueBuilder,
+ const TUnboxedValuePod* args) const override
+ {
+ Y_UNUSED(valueBuilder);
+ YQL_ENSURE(Runtime->IsRealThreads());
+
+ ui64 tabletID = args[0].Get<ui64>();
+
+ auto sender = Runtime->AllocateEdgeActor();
+
+ Runtime->SendToPipe(tabletID, sender, new NKikimr::TEvents::TEvPoisonPill);
+
+ ResumeYqlExecution.Wait();
+
+ ui64 result = 0;
+ return TUnboxedValuePod(result);
+ }
};
class TTestUDFs: public IUdfModule
@@ -103,11 +103,11 @@ public:
return TStringRef::Of("TestUDFs");
}
- void CleanupOnTerminate() const final {}
+ void CleanupOnTerminate() const final {}
- void GetAllFunctions(IFunctionsSink& sink) const final {
- sink.Add(TRepeat::Name());
- sink.Add(TSendPoisonPill::Name());
+ void GetAllFunctions(IFunctionsSink& sink) const final {
+ sink.Add(TRepeat::Name());
+ sink.Add(TSendPoisonPill::Name());
}
void BuildFunctionTypeInfo(
@@ -115,7 +115,7 @@ public:
TType* userType,
const TStringRef& typeConfig,
ui32 flags,
- IFunctionTypeInfoBuilder& builder) const final
+ IFunctionTypeInfoBuilder& builder) const final
{
try {
Y_UNUSED(userType);
@@ -168,7 +168,7 @@ void TYqlServer::Initialize() {
app.SetFnRegistry([this](const NKikimr::NScheme::TTypeRegistry& typeRegistry) -> NKikimr::NMiniKQL::IFunctionRegistry* {
Y_UNUSED(typeRegistry);
// register test UDFs
- auto freg = NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry())->Clone();
+ auto freg = NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry())->Clone();
freg->AddModule("", "TestUDFs", new TTestUDFs(GetRuntime(), ResumeYqlExecutionPromise.GetFuture()));
return freg.Release();
}
diff --git a/ydb/library/mkql_proto/mkql_proto_ut.cpp b/ydb/library/mkql_proto/mkql_proto_ut.cpp
index 96dbabbdcc..fdda085f18 100644
--- a/ydb/library/mkql_proto/mkql_proto_ut.cpp
+++ b/ydb/library/mkql_proto/mkql_proto_ut.cpp
@@ -172,7 +172,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTest) {
Y_UNIT_TEST(TestExportStructType) {
TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> items;
+ std::vector<std::pair<std::string_view, TRuntimeNode>> items;
items.push_back({ "x", pgmBuilder.NewDataLiteral<i32>(42) });
items.push_back({ "y", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc") });
auto pgmReturn = pgmBuilder.NewStruct(items);
@@ -288,9 +288,9 @@ Variant {
)___";
TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TType*>> structElemenTypes;
- structElemenTypes.push_back({"a", pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- structElemenTypes.push_back({"b", pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id)});
+ std::vector<std::pair<std::string_view, TType*>> structElemenTypes;
+ structElemenTypes.push_back({"a", pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ structElemenTypes.push_back({"b", pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id)});
TType* structType = pgmBuilder.NewStructType(structElemenTypes);
auto pgmReturn = pgmBuilder.NewVariant(
pgmBuilder.NewDataLiteral<ui32>(66),
@@ -476,7 +476,7 @@ Variant {
Y_UNIT_TEST(TestExportTuple) {
TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
- TRuntimeNode::TList items;
+ TRuntimeNode::TList items;
items.push_back(pgmBuilder.NewDataLiteral<i32>(42));
items.push_back(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
auto pgmReturn = pgmBuilder.NewTuple(items);
@@ -492,7 +492,7 @@ Variant {
Y_UNIT_TEST(TestExportStruct) {
TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> items;
+ std::vector<std::pair<std::string_view, TRuntimeNode>> items;
items.push_back({ "x", pgmBuilder.NewDataLiteral<i32>(42) });
items.push_back({ "y", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc") });
auto pgmReturn = pgmBuilder.NewStruct(items);
diff --git a/ydb/library/yql/ast/serialize/yql_expr_serialize.cpp b/ydb/library/yql/ast/serialize/yql_expr_serialize.cpp
index 560a3cb3e5..7f7bb063ac 100644
--- a/ydb/library/yql/ast/serialize/yql_expr_serialize.cpp
+++ b/ydb/library/yql/ast/serialize/yql_expr_serialize.cpp
@@ -13,7 +13,7 @@ enum ESerializeCommands {
INLINE_STR = 0x08, // string is unique, don't write it to the pool
SAME_POSITION = 0x40,
ATOM_FLAG = 0x20,
- WIDE = 0x80, // mark wide lambdas
+ WIDE = 0x80, // mark wide lambdas
ATOM = ATOM_FLAG | NODE_VALUE, // for atoms we will use TNodeFlags bits (1/2/4)
LIST = TExprNode::List | NODE_VALUE,
CALLABLE = TExprNode::Callable | NODE_VALUE,
@@ -111,10 +111,10 @@ public:
char command = (node.Type() == TExprNode::Atom) ? ATOM : ((node.Type() & TExprNode::TypeMask) | NODE_VALUE);
- if (node.Type() == TExprNode::Lambda && node.ChildrenSize() > 2U) {
- command |= WIDE;
- }
-
+ if (node.Type() == TExprNode::Lambda && node.ChildrenSize() > 2U) {
+ command |= WIDE;
+ }
+
if (Components_ & TSerializedExprGraphComponents::Positions) {
// will write position
if (Ctx.GetPosition(node.Pos()) == LastPosition_) {
@@ -163,7 +163,7 @@ public:
}
}
- if (node.Type() == TExprNode::Callable || node.Type() == TExprNode::Arguments || node.Type() == TExprNode::List || (node.Type() == TExprNode::Lambda && node.ChildrenSize() > 2U)) {
+ if (node.Type() == TExprNode::Callable || node.Type() == TExprNode::Arguments || node.Type() == TExprNode::List || (node.Type() == TExprNode::Lambda && node.ChildrenSize() > 2U)) {
WriteVar32(node.ChildrenSize());
}
@@ -299,7 +299,7 @@ private:
return Nodes_[nodeId - 1];
}
-
+
command &= ~NODE_VALUE;
TPosition pos = Pos_;
if (Components_ & TSerializedExprGraphComponents::Positions) {
@@ -335,9 +335,9 @@ private:
command |= TExprNode::Atom;
}
- const bool wide = command & WIDE;
- command &= ~WIDE;
-
+ const bool wide = command & WIDE;
+ command &= ~WIDE;
+
TStringBuf content;
if (command == TExprNode::Atom || command == TExprNode::Callable || command == TExprNode::Argument) {
if (hasInlineStr) {
@@ -354,7 +354,7 @@ private:
}
ui32 childrenSize = 0;
- if (command == TExprNode::Callable || command == TExprNode::Arguments || command == TExprNode::List || (command == TExprNode::Lambda && wide)) {
+ if (command == TExprNode::Callable || command == TExprNode::Arguments || command == TExprNode::List || (command == TExprNode::Lambda && wide)) {
childrenSize = ReadVar32();
}
@@ -366,8 +366,8 @@ private:
case TExprNode::List: {
TExprNode::TListType children;
children.reserve(childrenSize);
- for (ui32 i = 0U; i < childrenSize; ++i) {
- children.emplace_back(Fetch());
+ for (ui32 i = 0U; i < childrenSize; ++i) {
+ children.emplace_back(Fetch());
}
ret = Ctx_.NewList(pos, std::move(children));
@@ -377,45 +377,45 @@ private:
case TExprNode::Callable: {
TExprNode::TListType children;
children.reserve(childrenSize);
- for (ui32 i = 0U; i < childrenSize; ++i) {
- children.emplace_back(Fetch());
+ for (ui32 i = 0U; i < childrenSize; ++i) {
+ children.emplace_back(Fetch());
}
ret = Ctx_.NewCallable(pos, content, std::move(children));
break;
}
- case TExprNode::Argument:
+ case TExprNode::Argument:
ret = Ctx_.NewArgument(pos, content);
break;
case TExprNode::Arguments: {
TExprNode::TListType children;
children.reserve(childrenSize);
- for (ui32 i = 0U; i < childrenSize; ++i) {
- children.emplace_back(Fetch());
+ for (ui32 i = 0U; i < childrenSize; ++i) {
+ children.emplace_back(Fetch());
}
ret = Ctx_.NewArguments(pos, std::move(children));
break;
}
- case TExprNode::Lambda:
- if (wide) {
- TExprNode::TListType children;
- children.reserve(childrenSize);
- for (ui32 i = 0U; i < childrenSize; ++i) {
- children.emplace_back(Fetch());
- }
- ret = Ctx_.NewLambda(pos, std::move(children));
- } else {
- auto args = Fetch();
- auto body = Fetch();
- ret = Ctx_.NewLambda(pos, {std::move(args), std::move(body)});
- }
+ case TExprNode::Lambda:
+ if (wide) {
+ TExprNode::TListType children;
+ children.reserve(childrenSize);
+ for (ui32 i = 0U; i < childrenSize; ++i) {
+ children.emplace_back(Fetch());
+ }
+ ret = Ctx_.NewLambda(pos, std::move(children));
+ } else {
+ auto args = Fetch();
+ auto body = Fetch();
+ ret = Ctx_.NewLambda(pos, {std::move(args), std::move(body)});
+ }
break;
- case TExprNode::World:
+ case TExprNode::World:
ret = Ctx_.NewWorld(pos);
break;
diff --git a/ydb/library/yql/ast/yql_ast.cpp b/ydb/library/yql/ast/yql_ast.cpp
index dd8cb99022..16e521d901 100644
--- a/ydb/library/yql/ast/yql_ast.cpp
+++ b/ydb/library/yql/ast/yql_ast.cpp
@@ -50,8 +50,8 @@ namespace {
, Pool_(externalPool)
{
if (!Pool_) {
- InnerPool_ = std::make_unique<TMemoryPool>(4096);
- Pool_ = InnerPool_.get();
+ InnerPool_ = std::make_unique<TMemoryPool>(4096);
+ Pool_ = InnerPool_.get();
}
}
@@ -102,14 +102,14 @@ namespace {
inline ui32 Offset() const { return Offset_; }
inline const TPosition& Position() const { return Position_; }
inline TMemoryPool& Pool() { return *Pool_; }
- inline std::unique_ptr<TMemoryPool>&& InnerPool() { return std::move(InnerPool_); }
+ inline std::unique_ptr<TMemoryPool>&& InnerPool() { return std::move(InnerPool_); }
private:
TStringBuf Str_;
TPosition Position_;
ui32 Offset_;
TMemoryPool* Pool_;
- std::unique_ptr<TMemoryPool> InnerPool_;
+ std::unique_ptr<TMemoryPool> InnerPool_;
};
///////////////////////////////////////////////////////////////////////////
@@ -171,12 +171,12 @@ namespace {
}
}
- TAstNode* ParseList(size_t level) {
- if (level >= 1000U) {
- AddError("Too deep graph!");
- return nullptr;
- }
-
+ TAstNode* ParseList(size_t level) {
+ if (level >= 1000U) {
+ AddError("Too deep graph!");
+ return nullptr;
+ }
+
SkipSpace();
if (Ctx_.AtEnd()) {
@@ -206,7 +206,7 @@ namespace {
return TAstNode::NewList(listPos, children.data(), children.size(), Ctx_.Pool());
}
- TAstNode* elem = ParseElement(level);
+ TAstNode* elem = ParseElement(level);
if (!elem)
return nullptr;
@@ -214,7 +214,7 @@ namespace {
}
}
- TAstNode* ParseElement(size_t level) {
+ TAstNode* ParseElement(size_t level) {
if (Ctx_.AtEnd()) {
AddError("Expected element");
return nullptr;
@@ -234,7 +234,7 @@ namespace {
}
TAstNode* content = IsListStart(ch)
- ? ParseList(++level)
+ ? ParseList(++level)
: ParseAtom();
if (!content)
return nullptr;
@@ -243,7 +243,7 @@ namespace {
}
if (IsListStart(c))
- return ParseList(++level);
+ return ParseList(++level);
return ParseAtom();
}
diff --git a/ydb/library/yql/ast/yql_ast.h b/ydb/library/yql/ast/yql_ast.h
index 41ff3d1b7c..887b53dbc5 100644
--- a/ydb/library/yql/ast/yql_ast.h
+++ b/ydb/library/yql/ast/yql_ast.h
@@ -235,7 +235,7 @@ private:
};
struct TAstParseResult {
- std::unique_ptr<TMemoryPool> Pool;
+ std::unique_ptr<TMemoryPool> Pool;
TAstNode* Root = nullptr;
TIssues Issues;
diff --git a/ydb/library/yql/ast/yql_constraint.cpp b/ydb/library/yql/ast/yql_constraint.cpp
index f6acd84614..74adceb153 100644
--- a/ydb/library/yql/ast/yql_constraint.cpp
+++ b/ydb/library/yql/ast/yql_constraint.cpp
@@ -4,14 +4,14 @@
#include <util/digest/murmur.h>
#include <util/generic/utility.h>
#include <util/generic/algorithm.h>
-#include <util/string/join.h>
+#include <util/string/join.h>
#include <algorithm>
#include <iterator>
namespace NYql {
-TConstraintNode::TConstraintNode(TExprContext& ctx, std::string_view name)
+TConstraintNode::TConstraintNode(TExprContext& ctx, std::string_view name)
: Hash_(MurmurHash<ui64>(name.data(), name.size()))
, Name_(ctx.AppendString(name))
{
@@ -31,8 +31,8 @@ void TConstraintNode::Out(IOutputStream& out) const {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const TConstraintNode* TConstraintSet::GetConstraint(std::string_view name) const {
- const auto it = std::lower_bound(Constraints_.cbegin(), Constraints_.cend(), name, TConstraintNode::TCompare());
+const TConstraintNode* TConstraintSet::GetConstraint(std::string_view name) const {
+ const auto it = std::lower_bound(Constraints_.cbegin(), Constraints_.cend(), name, TConstraintNode::TCompare());
if (it != Constraints_.cend() && (*it)->GetName() == name) {
return *it;
}
@@ -43,7 +43,7 @@ void TConstraintSet::AddConstraint(const TConstraintNode* node) {
if (!node) {
return;
}
- const auto it = std::lower_bound(Constraints_.begin(), Constraints_.end(), node, TConstraintNode::TCompare());
+ const auto it = std::lower_bound(Constraints_.begin(), Constraints_.end(), node, TConstraintNode::TCompare());
if (it == Constraints_.end() || (*it)->GetName() != node->GetName()) {
Constraints_.insert(it, node);
} else {
@@ -51,9 +51,9 @@ void TConstraintSet::AddConstraint(const TConstraintNode* node) {
}
}
-const TConstraintNode* TConstraintSet::RemoveConstraint(std::string_view name) {
+const TConstraintNode* TConstraintSet::RemoveConstraint(std::string_view name) {
const TConstraintNode* res = nullptr;
- const auto it = std::lower_bound(Constraints_.begin(), Constraints_.end(), name, TConstraintNode::TCompare());
+ const auto it = std::lower_bound(Constraints_.begin(), Constraints_.end(), name, TConstraintNode::TCompare());
if (it != Constraints_.end() && (*it)->GetName() == name) {
res = *it;
Constraints_.erase(it);
@@ -61,13 +61,13 @@ const TConstraintNode* TConstraintSet::RemoveConstraint(std::string_view name) {
return res;
}
-void TConstraintSet::ToJson(NJson::TJsonWriter& writer) const {
- writer.OpenMap();
- for (const auto& node : Constraints_) {
- writer.WriteKey(node->GetName());
- node->ToJson(writer);
+void TConstraintSet::ToJson(NJson::TJsonWriter& writer) const {
+ writer.OpenMap();
+ for (const auto& node : Constraints_) {
+ writer.WriteKey(node->GetName());
+ node->ToJson(writer);
}
- writer.CloseMap();
+ writer.CloseMap();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -161,44 +161,44 @@ void TColumnSetConstraintNodeBase::Out(IOutputStream& out) const {
out.Write(')');
}
-void TColumnSetConstraintNodeBase::ToJson(NJson::TJsonWriter& out) const {
- out.OpenArray();
- for (const auto& column : Columns_) {
- out.Write(column);
+void TColumnSetConstraintNodeBase::ToJson(NJson::TJsonWriter& out) const {
+ out.OpenArray();
+ for (const auto& column : Columns_) {
+ out.Write(column);
}
- out.CloseArray();
+ out.CloseArray();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-TSortedConstraintNode::TSortedConstraintNode(TExprContext& ctx, TContainerType&& content)
- : TConstraintNode(ctx, Name()), Content_(std::move(content))
+TSortedConstraintNode::TSortedConstraintNode(TExprContext& ctx, TContainerType&& content)
+ : TConstraintNode(ctx, Name()), Content_(std::move(content))
{
- YQL_ENSURE(!Content_.empty());
- for (const auto& c : Content_) {
- Hash_ = std::accumulate(c.first.cbegin(), c.first.cend(), c.second ? Hash_ : ~Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
- }
+ YQL_ENSURE(!Content_.empty());
+ for (const auto& c : Content_) {
+ Hash_ = std::accumulate(c.first.cbegin(), c.first.cend(), c.second ? Hash_ : ~Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
+ }
}
TSortedConstraintNode::TSortedConstraintNode(TExprContext& ctx, const TSortedConstraintNode& constr, size_t prefixLength)
- : TConstraintNode(ctx, Name()), Content_(constr.Content_)
+ : TConstraintNode(ctx, Name()), Content_(constr.Content_)
{
- YQL_ENSURE(prefixLength > 0U);
- Content_.resize(prefixLength);
- for (const auto& c : Content_) {
- Hash_ = std::accumulate(c.first.cbegin(), c.first.cend(), c.second ? Hash_ : ~Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
- }
+ YQL_ENSURE(prefixLength > 0U);
+ Content_.resize(prefixLength);
+ for (const auto& c : Content_) {
+ Hash_ = std::accumulate(c.first.cbegin(), c.first.cend(), c.second ? Hash_ : ~Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
+ }
}
-TSortedConstraintNode::TSortedConstraintNode(TSortedConstraintNode&&) = default;
+TSortedConstraintNode::TSortedConstraintNode(TSortedConstraintNode&&) = default;
bool TSortedConstraintNode::Equals(const TConstraintNode& node) const {
if (this == &node) {
return true;
}
-
- if (const auto c = dynamic_cast<const TSortedConstraintNode*>(&node)) {
- return GetContent() == c->GetContent();
+
+ if (const auto c = dynamic_cast<const TSortedConstraintNode*>(&node)) {
+ return GetContent() == c->GetContent();
}
return false;
}
@@ -207,56 +207,56 @@ bool TSortedConstraintNode::Includes(const TConstraintNode& node) const {
if (this == &node) {
return true;
}
- if (GetName() != node.GetName()) {
- return false;
+ if (GetName() != node.GetName()) {
+ return false;
+ }
+
+ const auto& content = static_cast<const TSortedConstraintNode&>(node).GetContent();
+ if (content.size() > Content_.size())
+ return false;
+ for (TContainerType::size_type i = 0U; i < content.size(); ++i) {
+ if (Content_[i].second != content[i].second ||
+ !(std::includes(Content_[i].first.cbegin(), Content_[i].first.cend(), content[i].first.cbegin(), content[i].first.cend()) || std::includes(content[i].first.cbegin(), content[i].first.cend(), Content_[i].first.cbegin(), Content_[i].first.cend())))
+ return false;
}
-
- const auto& content = static_cast<const TSortedConstraintNode&>(node).GetContent();
- if (content.size() > Content_.size())
- return false;
- for (TContainerType::size_type i = 0U; i < content.size(); ++i) {
- if (Content_[i].second != content[i].second ||
- !(std::includes(Content_[i].first.cbegin(), Content_[i].first.cend(), content[i].first.cbegin(), content[i].first.cend()) || std::includes(content[i].first.cbegin(), content[i].first.cend(), Content_[i].first.cbegin(), Content_[i].first.cend())))
- return false;
- }
-
- return true;
+
+ return true;
}
void TSortedConstraintNode::Out(IOutputStream& out) const {
TConstraintNode::Out(out);
out.Write('(');
- for (size_t i = 0; i < Content_.size(); ++i) {
+ for (size_t i = 0; i < Content_.size(); ++i) {
if (i > 0) {
- out.Write(';');
+ out.Write(';');
}
- out.Write(JoinSeq(',', Content_[i].first));
+ out.Write(JoinSeq(',', Content_[i].first));
out.Write('[');
- out.Write(Content_[i].second ? "asc" : "desc");
+ out.Write(Content_[i].second ? "asc" : "desc");
out.Write(']');
}
out.Write(')');
}
-void TSortedConstraintNode::ToJson(NJson::TJsonWriter& out) const {
- out.OpenArray();
- for (size_t i = 0; i < Content_.size(); ++i) {
- out.OpenArray();
- out.Write(JoinSeq(';', Content_[i].first));
- out.Write(Content_[i].second);
- out.CloseArray();
+void TSortedConstraintNode::ToJson(NJson::TJsonWriter& out) const {
+ out.OpenArray();
+ for (size_t i = 0; i < Content_.size(); ++i) {
+ out.OpenArray();
+ out.Write(JoinSeq(';', Content_[i].first));
+ out.Write(Content_[i].second);
+ out.CloseArray();
}
- out.CloseArray();
+ out.CloseArray();
}
bool TSortedConstraintNode::IsPrefixOf(const TSortedConstraintNode& node) const {
- return node.Includes(*this);
+ return node.Includes(*this);
}
size_t TSortedConstraintNode::GetCommonPrefixLength(const TSortedConstraintNode& node) const {
- const size_t minSize = std::min(Content_.size(), node.Content_.size());
- for (size_t i = 0U; i < minSize; ++i) {
- if (Content_[i] != node.Content_[i]) {
+ const size_t minSize = std::min(Content_.size(), node.Content_.size());
+ for (size_t i = 0U; i < minSize; ++i) {
+ if (Content_[i] != node.Content_[i]) {
return i;
}
}
@@ -268,15 +268,15 @@ const TSortedConstraintNode* TSortedConstraintNode::MakeCommon(const TVector<con
return nullptr;
}
- const auto sort = constraints.front()->GetConstraint<TSortedConstraintNode>();
+ const auto sort = constraints.front()->GetConstraint<TSortedConstraintNode>();
if (constraints.size() == 1 || !sort) {
return sort;
}
- auto commonPrefixLength = sort->GetContent().size();
+ auto commonPrefixLength = sort->GetContent().size();
for (size_t i = 1; i < constraints.size() && commonPrefixLength > 0; ++i) {
- if (const auto nextSort = constraints[i]->GetConstraint<TSortedConstraintNode>()) {
- commonPrefixLength = std::min(commonPrefixLength, nextSort->GetCommonPrefixLength(*sort));
+ if (const auto nextSort = constraints[i]->GetConstraint<TSortedConstraintNode>()) {
+ commonPrefixLength = std::min(commonPrefixLength, nextSort->GetCommonPrefixLength(*sort));
} else if (!constraints[i]->GetConstraint<TEmptyConstraintNode>()) {
commonPrefixLength = 0;
}
@@ -288,44 +288,44 @@ const TSortedConstraintNode* TSortedConstraintNode::MakeCommon(const TVector<con
return nullptr;
}
-const TSortedConstraintNode* TSortedConstraintNode::FilterByType(const TSortedConstraintNode* sorted, const TStructExprType* outItemType, TExprContext& ctx) {
- if (sorted) {
- auto content = sorted->GetContent();
- for (size_t i = 0; i < content.size(); ++i) {
- for (auto it = content[i].first.cbegin(); content[i].first.cend() != it;) {
- if (outItemType->FindItem(*it))
- ++it;
- else
- it = content[i].first.erase(it);
- }
-
- if (content[i].first.empty()) {
- content.resize(i);
- break;
- }
- }
-
- if (!content.empty()) {
- return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
- }
- }
- return nullptr;
-}
-
-const TSortedConstraintNode* TSortedConstraintNode::CutPrefix(size_t newPrefixLength, TExprContext& ctx) const {
- if (!newPrefixLength)
- return nullptr;
-
- if (newPrefixLength >= Content_.size())
- return this;
-
- auto content = Content_;
- content.resize(newPrefixLength);
- return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+const TSortedConstraintNode* TSortedConstraintNode::FilterByType(const TSortedConstraintNode* sorted, const TStructExprType* outItemType, TExprContext& ctx) {
+ if (sorted) {
+ auto content = sorted->GetContent();
+ for (size_t i = 0; i < content.size(); ++i) {
+ for (auto it = content[i].first.cbegin(); content[i].first.cend() != it;) {
+ if (outItemType->FindItem(*it))
+ ++it;
+ else
+ it = content[i].first.erase(it);
+ }
+
+ if (content[i].first.empty()) {
+ content.resize(i);
+ break;
+ }
+ }
+
+ if (!content.empty()) {
+ return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
+ }
+ }
+ return nullptr;
+}
+
+const TSortedConstraintNode* TSortedConstraintNode::CutPrefix(size_t newPrefixLength, TExprContext& ctx) const {
+ if (!newPrefixLength)
+ return nullptr;
+
+ if (newPrefixLength >= Content_.size())
+ return this;
+
+ auto content = Content_;
+ content.resize(newPrefixLength);
+ return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
TGroupByConstraintNode::TGroupByConstraintNode(TExprContext& ctx, const TVector<TStringBuf>& columns)
: TColumnSetConstraintNodeBase(ctx, Name(), columns)
{
@@ -471,71 +471,71 @@ const TUniqueConstraintNode* TUniqueConstraintNode::MakeCommon(const TVector<con
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping)
- : TConstraintNode(ctx, Name()), Mapping_(std::move(mapping))
+TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping)
+ : TConstraintNode(ctx, Name()), Mapping_(std::move(mapping))
{
- YQL_ENSURE(!Mapping_.empty());
- if (const auto original = Mapping_.cbegin()->first;
- original && 1U == Mapping_.size() && 1U == original->Mapping_.size() && Mapping_.cbegin()->second == original->Mapping_.cbegin()->second) {
- // Comeback original constraint.
- Hash_ = original->Hash_;
- Mapping_ = original->Mapping_;
- } else {
- for (const auto& part : Mapping_) {
- YQL_ENSURE(!part.second.empty());
- if (part.first)
- Hash_ = MurmurHash<ui64>(&part.first->Hash_, sizeof(part.first->Hash_), Hash_);
- for (const auto& item: part.second) {
- Hash_ = std::accumulate(item.first.cbegin(), item.first.cend(), Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
- Hash_ = MurmurHash<ui64>(item.second.data(), item.second.size(), Hash_);
- }
- }
+ YQL_ENSURE(!Mapping_.empty());
+ if (const auto original = Mapping_.cbegin()->first;
+ original && 1U == Mapping_.size() && 1U == original->Mapping_.size() && Mapping_.cbegin()->second == original->Mapping_.cbegin()->second) {
+ // Comeback original constraint.
+ Hash_ = original->Hash_;
+ Mapping_ = original->Mapping_;
+ } else {
+ for (const auto& part : Mapping_) {
+ YQL_ENSURE(!part.second.empty());
+ if (part.first)
+ Hash_ = MurmurHash<ui64>(&part.first->Hash_, sizeof(part.first->Hash_), Hash_);
+ for (const auto& item: part.second) {
+ Hash_ = std::accumulate(item.first.cbegin(), item.first.cend(), Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); });
+ Hash_ = MurmurHash<ui64>(item.second.data(), item.second.size(), Hash_);
+ }
+ }
}
}
TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, const TStructExprType& itemType)
: TConstraintNode(ctx, Name())
{
- auto& mapping = Mapping_[nullptr];
+ auto& mapping = Mapping_[nullptr];
for (auto& item: itemType.GetItems()) {
- const auto name = ctx.AppendString(item->GetName());
+ const auto name = ctx.AppendString(item->GetName());
+ Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as name
+ Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as value
+ mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
+ }
+
+ YQL_ENSURE(!mapping.empty());
+}
+
+TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, const TTupleExprType& itemType)
+ : TConstraintNode(ctx, Name())
+{
+ auto& mapping = Mapping_[nullptr];
+ for (ui32 i = 0U; i < itemType.GetSize(); ++i) {
+ const auto name = ctx.AppendString(ToString(i));
+ Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as name
+ Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as value
+ mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
+ }
+
+ YQL_ENSURE(!mapping.empty());
+}
+
+TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, const TMultiExprType& itemType)
+ : TConstraintNode(ctx, Name())
+{
+ auto& mapping = Mapping_[nullptr];
+ for (ui32 i = 0U; i < itemType.GetSize(); ++i) {
+ const auto name = ctx.AppendString(ToString(i));
Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as name
Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as value
- mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
- }
-
- YQL_ENSURE(!mapping.empty());
-}
-
-TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, const TTupleExprType& itemType)
- : TConstraintNode(ctx, Name())
-{
- auto& mapping = Mapping_[nullptr];
- for (ui32 i = 0U; i < itemType.GetSize(); ++i) {
- const auto name = ctx.AppendString(ToString(i));
- Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as name
- Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as value
- mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
- }
-
- YQL_ENSURE(!mapping.empty());
-}
-
-TPassthroughConstraintNode::TPassthroughConstraintNode(TExprContext& ctx, const TMultiExprType& itemType)
- : TConstraintNode(ctx, Name())
-{
- auto& mapping = Mapping_[nullptr];
- for (ui32 i = 0U; i < itemType.GetSize(); ++i) {
- const auto name = ctx.AppendString(ToString(i));
- Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as name
- Hash_ = MurmurHash<ui64>(name.data(), name.size(), Hash_); // hash as value
- mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
- }
-
- YQL_ENSURE(!mapping.empty());
-}
-
-TPassthroughConstraintNode::TPassthroughConstraintNode(TPassthroughConstraintNode&& constr) = default;
+ mapping.push_back(std::make_pair(TKeyType(1U, name), name)); // Struct items are sorted
+ }
+
+ YQL_ENSURE(!mapping.empty());
+}
+
+TPassthroughConstraintNode::TPassthroughConstraintNode(TPassthroughConstraintNode&& constr) = default;
bool TPassthroughConstraintNode::Equals(const TConstraintNode& node) const {
if (this == &node) {
@@ -544,8 +544,8 @@ bool TPassthroughConstraintNode::Equals(const TConstraintNode& node) const {
if (GetHash() != node.GetHash()) {
return false;
}
- if (const auto c = dynamic_cast<const TPassthroughConstraintNode*>(&node)) {
- return Mapping_ == c->Mapping_;
+ if (const auto c = dynamic_cast<const TPassthroughConstraintNode*>(&node)) {
+ return Mapping_ == c->Mapping_;
}
return false;
}
@@ -554,15 +554,15 @@ bool TPassthroughConstraintNode::Includes(const TConstraintNode& node) const {
if (this == &node) {
return true;
}
- if (const auto c = dynamic_cast<const TPassthroughConstraintNode*>(&node)) {
- for (const auto& part : c->Mapping_) {
- if (const auto it = Mapping_.find(part.first == this ? nullptr : part.first); Mapping_.cend() != it) {
- for (const auto& pair : part.second) {
- if (const auto p = it->second.find(pair.first); it->second.cend() == p || p->second != pair.second) {
- return false;
- }
+ if (const auto c = dynamic_cast<const TPassthroughConstraintNode*>(&node)) {
+ for (const auto& part : c->Mapping_) {
+ if (const auto it = Mapping_.find(part.first == this ? nullptr : part.first); Mapping_.cend() != it) {
+ for (const auto& pair : part.second) {
+ if (const auto p = it->second.find(pair.first); it->second.cend() == p || p->second != pair.second) {
+ return false;
+ }
}
- } else
+ } else
return false;
}
return true;
@@ -575,127 +575,127 @@ void TPassthroughConstraintNode::Out(IOutputStream& out) const {
out.Write('(');
bool first = true;
- for (const auto& part : Mapping_) {
- for (const auto& item : part.second) {
- if (!first) {
- out.Write(',');
- }
- if (!item.first.empty()) {
- auto it = item.first.cbegin();
- out.Write(*it);
- while (item.first.cend() > ++it) {
- out.Write('#');
- out.Write(*it);
- }
- }
- out.Write(':');
- out.Write(item.second);
-
- first = false;
+ for (const auto& part : Mapping_) {
+ for (const auto& item : part.second) {
+ if (!first) {
+ out.Write(',');
+ }
+ if (!item.first.empty()) {
+ auto it = item.first.cbegin();
+ out.Write(*it);
+ while (item.first.cend() > ++it) {
+ out.Write('#');
+ out.Write(*it);
+ }
+ }
+ out.Write(':');
+ out.Write(item.second);
+
+ first = false;
}
}
out.Write(')');
}
-void TPassthroughConstraintNode::ToJson(NJson::TJsonWriter& out) const {
- out.OpenMap();
- for (const auto& part : Mapping_) {
- for (const auto& [resultColumn, originalColumn] : part.second) {
- out.Write(JoinSeq(';', resultColumn), originalColumn);
- }
- }
- out.CloseMap();
-}
-
-const TPassthroughConstraintNode* TPassthroughConstraintNode::ExtractField(TExprContext& ctx, const std::string_view& field) const {
- TMapType passtrought;
- for (const auto& part : Mapping_) {
- auto it = part.second.lower_bound(TKeyType(1U, field));
- if (part.second.cend() == it || it->first.front() != field)
- continue;
-
- if (1U == it->first.size()) {
- return ctx.MakeConstraint<TPassthroughConstraintNode>(TMapType{{part.first ? part.first : this , TPartType{{TKeyType(), it->second}}}});
- }
-
- TPartType mapping;
- mapping.reserve(part.second.size());
- while (it < part.second.cend() && it->first.size() > 1U && field == it->first.front()) {
- auto item = *it++;
- item.first.pop_front();
- mapping.emplace_back(std::move(item));
- }
-
- if (!mapping.empty()) {
- passtrought.emplace(part.first ? part.first : this, std::move(mapping));
- }
- }
- return passtrought.empty() ? nullptr : ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passtrought));
-}
-
+void TPassthroughConstraintNode::ToJson(NJson::TJsonWriter& out) const {
+ out.OpenMap();
+ for (const auto& part : Mapping_) {
+ for (const auto& [resultColumn, originalColumn] : part.second) {
+ out.Write(JoinSeq(';', resultColumn), originalColumn);
+ }
+ }
+ out.CloseMap();
+}
+
+const TPassthroughConstraintNode* TPassthroughConstraintNode::ExtractField(TExprContext& ctx, const std::string_view& field) const {
+ TMapType passtrought;
+ for (const auto& part : Mapping_) {
+ auto it = part.second.lower_bound(TKeyType(1U, field));
+ if (part.second.cend() == it || it->first.front() != field)
+ continue;
+
+ if (1U == it->first.size()) {
+ return ctx.MakeConstraint<TPassthroughConstraintNode>(TMapType{{part.first ? part.first : this , TPartType{{TKeyType(), it->second}}}});
+ }
+
+ TPartType mapping;
+ mapping.reserve(part.second.size());
+ while (it < part.second.cend() && it->first.size() > 1U && field == it->first.front()) {
+ auto item = *it++;
+ item.first.pop_front();
+ mapping.emplace_back(std::move(item));
+ }
+
+ if (!mapping.empty()) {
+ passtrought.emplace(part.first ? part.first : this, std::move(mapping));
+ }
+ }
+ return passtrought.empty() ? nullptr : ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passtrought));
+}
+
const TPassthroughConstraintNode* TPassthroughConstraintNode::MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx) {
if (constraints.empty()) {
return nullptr;
}
- auto part = constraints.front()->GetConstraint<TPassthroughConstraintNode>();
- if (constraints.size() == 1 || !part) {
- return part;
+ auto part = constraints.front()->GetConstraint<TPassthroughConstraintNode>();
+ if (constraints.size() == 1 || !part) {
+ return part;
}
- auto mapping = part->GetColumnMapping();
- if (const auto self = mapping.find(nullptr); mapping.cend() != self)
- mapping.emplace(part, std::move(mapping.extract(self).mapped()));
-
+ auto mapping = part->GetColumnMapping();
+ if (const auto self = mapping.find(nullptr); mapping.cend() != self)
+ mapping.emplace(part, std::move(mapping.extract(self).mapped()));
+
for (size_t i = 1; i < constraints.size() && !mapping.empty(); ++i) {
- part = constraints[i]->GetConstraint<TPassthroughConstraintNode>();
- if (!part) {
+ part = constraints[i]->GetConstraint<TPassthroughConstraintNode>();
+ if (!part) {
if (constraints[i]->GetConstraint<TEmptyConstraintNode>()) {
continue;
}
return nullptr;
}
-
- for (const auto& nextMapping : part->GetColumnMapping()) {
- if (const auto it = mapping.find(nextMapping.first ? nextMapping.first : part); mapping.cend() != it) {
- TPassthroughConstraintNode::TPartType result;
- std::set_intersection(
- it->second.cbegin(), it->second.cend(),
- nextMapping.second.cbegin(), nextMapping.second.cend(),
- std::back_inserter(result),
- [] (const TPassthroughConstraintNode::TPartType::value_type& c1, const TPassthroughConstraintNode::TPartType::value_type& c2) {
- return c1 < c2;
- }
- );
- if (result.empty())
- mapping.erase(it);
- else
- it->second = std::move(result);
+
+ for (const auto& nextMapping : part->GetColumnMapping()) {
+ if (const auto it = mapping.find(nextMapping.first ? nextMapping.first : part); mapping.cend() != it) {
+ TPassthroughConstraintNode::TPartType result;
+ std::set_intersection(
+ it->second.cbegin(), it->second.cend(),
+ nextMapping.second.cbegin(), nextMapping.second.cend(),
+ std::back_inserter(result),
+ [] (const TPassthroughConstraintNode::TPartType::value_type& c1, const TPassthroughConstraintNode::TPartType::value_type& c2) {
+ return c1 < c2;
+ }
+ );
+ if (result.empty())
+ mapping.erase(it);
+ else
+ it->second = std::move(result);
+ }
+ }
+ }
+
+ return mapping.empty() ? nullptr : ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping));
+}
+
+const TPassthroughConstraintNode::TMapType& TPassthroughConstraintNode::GetColumnMapping() const {
+ return Mapping_;
+}
+
+TPassthroughConstraintNode::TReverseMapType TPassthroughConstraintNode::GetReverseMapping() const {
+ if (1U == Mapping_.size() && 1U == Mapping_.cbegin()->second.size() && Mapping_.cbegin()->second.cbegin()->first.empty())
+ return {{Mapping_.cbegin()->second.cbegin()->second, Mapping_.cbegin()->second.cbegin()->second}};
+
+ TReverseMapType reverseMapping;
+ for (const auto& part : Mapping_) {
+ for (const auto& item : part.second) {
+ if (1U == item.first.size()) {
+ reverseMapping.emplace_back(item.second, item.first.front());
}
- }
- }
-
- return mapping.empty() ? nullptr : ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping));
-}
-
-const TPassthroughConstraintNode::TMapType& TPassthroughConstraintNode::GetColumnMapping() const {
- return Mapping_;
-}
-
-TPassthroughConstraintNode::TReverseMapType TPassthroughConstraintNode::GetReverseMapping() const {
- if (1U == Mapping_.size() && 1U == Mapping_.cbegin()->second.size() && Mapping_.cbegin()->second.cbegin()->first.empty())
- return {{Mapping_.cbegin()->second.cbegin()->second, Mapping_.cbegin()->second.cbegin()->second}};
-
- TReverseMapType reverseMapping;
- for (const auto& part : Mapping_) {
- for (const auto& item : part.second) {
- if (1U == item.first.size()) {
- reverseMapping.emplace_back(item.second, item.first.front());
- }
- }
- }
- ::Sort(reverseMapping);
- return reverseMapping;
+ }
+ }
+ ::Sort(reverseMapping);
+ return reverseMapping;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -720,8 +720,8 @@ bool TEmptyConstraintNode::Equals(const TConstraintNode& node) const {
return GetName() == node.GetName();
}
-void TEmptyConstraintNode::ToJson(NJson::TJsonWriter& out) const {
- out.Write(true);
+void TEmptyConstraintNode::ToJson(NJson::TJsonWriter& out) const {
+ out.Write(true);
}
const TEmptyConstraintNode* TEmptyConstraintNode::MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& /*ctx*/) {
@@ -831,15 +831,15 @@ void TVarIndexConstraintNode::Out(IOutputStream& out) const {
out.Write(')');
}
-void TVarIndexConstraintNode::ToJson(NJson::TJsonWriter& out) const {
- out.OpenArray();
- for (const auto& [resultIndex, originalIndex]: Mapping_) {
- out.OpenArray();
- out.Write(resultIndex);
- out.Write(originalIndex);
- out.CloseArray();
+void TVarIndexConstraintNode::ToJson(NJson::TJsonWriter& out) const {
+ out.OpenArray();
+ for (const auto& [resultIndex, originalIndex]: Mapping_) {
+ out.OpenArray();
+ out.Write(resultIndex);
+ out.Write(originalIndex);
+ out.CloseArray();
}
- out.CloseArray();
+ out.CloseArray();
}
const TVarIndexConstraintNode* TVarIndexConstraintNode::MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx) {
@@ -940,41 +940,41 @@ bool TMultiConstraintNode::Includes(const TConstraintNode& node) const {
return false;
}
-bool TMultiConstraintNode::FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const {
- if (this == &node) {
- return true;
- }
- if (GetName() != node.GetName()) {
- return false;
- }
-
- if (auto m = dynamic_cast<const TMultiConstraintNode*>(&node)) {
- for (auto& item: Items_) {
- const auto it = m->Items_.find(item.first);
- if (it == m->Items_.end()) {
- if (!item.second.GetConstraint<TEmptyConstraintNode>()) {
- return false;
- }
- continue;
- }
-
- for (auto c: it->second.GetAllConstraints()) {
- if (!blacklist.contains(c->GetName())) {
- const auto cit = item.second.GetConstraint(c->GetName());
- if (!cit) {
- return false;
- }
- if (!cit->Includes(*c)) {
- return false;
- }
- }
- }
- }
- return true;
- }
- return false;
-}
-
+bool TMultiConstraintNode::FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const {
+ if (this == &node) {
+ return true;
+ }
+ if (GetName() != node.GetName()) {
+ return false;
+ }
+
+ if (auto m = dynamic_cast<const TMultiConstraintNode*>(&node)) {
+ for (auto& item: Items_) {
+ const auto it = m->Items_.find(item.first);
+ if (it == m->Items_.end()) {
+ if (!item.second.GetConstraint<TEmptyConstraintNode>()) {
+ return false;
+ }
+ continue;
+ }
+
+ for (auto c: it->second.GetAllConstraints()) {
+ if (!blacklist.contains(c->GetName())) {
+ const auto cit = item.second.GetConstraint(c->GetName());
+ if (!cit) {
+ return false;
+ }
+ if (!cit->Includes(*c)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
void TMultiConstraintNode::Out(IOutputStream& out) const {
TConstraintNode::Out(out);
out.Write('(');
@@ -998,13 +998,13 @@ void TMultiConstraintNode::Out(IOutputStream& out) const {
out.Write(')');
}
-void TMultiConstraintNode::ToJson(NJson::TJsonWriter& out) const {
- out.OpenMap();
- for (const auto& [index, constraintSet] : Items_) {
- out.WriteKey(ToString(index));
- constraintSet.ToJson(out);
+void TMultiConstraintNode::ToJson(NJson::TJsonWriter& out) const {
+ out.OpenMap();
+ for (const auto& [index, constraintSet] : Items_) {
+ out.WriteKey(ToString(index));
+ constraintSet.ToJson(out);
}
- out.CloseMap();
+ out.CloseMap();
}
const TMultiConstraintNode* TMultiConstraintNode::MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx) {
diff --git a/ydb/library/yql/ast/yql_constraint.h b/ydb/library/yql/ast/yql_constraint.h
index ad34d3ea38..c093f3c9f4 100644
--- a/ydb/library/yql/ast/yql_constraint.h
+++ b/ydb/library/yql/ast/yql_constraint.h
@@ -2,28 +2,28 @@
#include <ydb/library/yql/utils/yql_panic.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
+#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <library/cpp/containers/sorted_vector/sorted_vector.h>
-#include <library/cpp/json/json_writer.h>
+#include <library/cpp/json/json_writer.h>
#include <util/generic/strbuf.h>
#include <util/generic/string.h>
#include <util/stream/output.h>
-#include <deque>
-#include <unordered_map>
+#include <deque>
+#include <unordered_map>
namespace NYql {
struct TExprContext;
class TStructExprType;
-class TTupleExprType;
-class TMultiExprType;
+class TTupleExprType;
+class TMultiExprType;
class TVariantExprType;
class TConstraintNode {
protected:
- TConstraintNode(TExprContext& ctx, std::string_view name);
+ TConstraintNode(TExprContext& ctx, std::string_view name);
TConstraintNode(TConstraintNode&& constr);
public:
@@ -46,11 +46,11 @@ public:
return l->GetName() < r->GetName();
}
- inline bool operator()(const std::string_view name, const TConstraintNode* r) const {
+ inline bool operator()(const std::string_view name, const TConstraintNode* r) const {
return name < r->GetName();
}
- inline bool operator()(const TConstraintNode* l, const std::string_view name) const {
+ inline bool operator()(const TConstraintNode* l, const std::string_view name) const {
return l->GetName() < name;
}
};
@@ -66,7 +66,7 @@ public:
return Equals(node);
}
virtual void Out(IOutputStream& out) const;
- virtual void ToJson(NJson::TJsonWriter& out) const = 0;
+ virtual void ToJson(NJson::TJsonWriter& out) const = 0;
template <typename T>
const T* Cast() const {
@@ -78,13 +78,13 @@ public:
return ret;
}
- std::string_view GetName() const {
+ std::string_view GetName() const {
return Name_;
}
protected:
ui64 Hash_;
- std::string_view Name_;
+ std::string_view Name_;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -126,11 +126,11 @@ public:
return Constraints_ != s.Constraints_;
}
- const TConstraintNode* GetConstraint(std::string_view name) const;
+ const TConstraintNode* GetConstraint(std::string_view name) const;
void AddConstraint(const TConstraintNode* node);
- const TConstraintNode* RemoveConstraint(std::string_view name);
+ const TConstraintNode* RemoveConstraint(std::string_view name);
- void ToJson(NJson::TJsonWriter& writer) const;
+ void ToJson(NJson::TJsonWriter& writer) const;
private:
TConstraintNode::TListType Constraints_;
};
@@ -155,55 +155,55 @@ public:
bool Equals(const TConstraintNode& node) const override;
bool Includes(const TConstraintNode& node) const override;
void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
protected:
TSetType Columns_;
};
-class TSortedConstraintNode final: public TConstraintNode {
-public:
- using TContainerType = TSmallVec<std::pair<NSorted::TSimpleSet<std::string_view>, bool>>;
-
-private:
+class TSortedConstraintNode final: public TConstraintNode {
+public:
+ using TContainerType = TSmallVec<std::pair<NSorted::TSimpleSet<std::string_view>, bool>>;
+
+private:
friend struct TExprContext;
- TSortedConstraintNode(TExprContext& ctx, TContainerType&& content);
+ TSortedConstraintNode(TExprContext& ctx, TContainerType&& content);
TSortedConstraintNode(TExprContext& ctx, const TSortedConstraintNode& constr, size_t prefixLength);
TSortedConstraintNode(TSortedConstraintNode&& constr);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "Sorted";
}
- const TContainerType& GetContent() const {
- return Content_;
+ const TContainerType& GetContent() const {
+ return Content_;
+ }
+
+ // TODO: deprecated, drop
+ const TVector<TStringBuf> GetColumns() const {
+ TVector<TStringBuf> result;
+ result.reserve(Content_.size());
+ for (const auto& c : Content_)
+ result.emplace_back(c.first.front());
+ return result;
}
- // TODO: deprecated, drop
- const TVector<TStringBuf> GetColumns() const {
- TVector<TStringBuf> result;
- result.reserve(Content_.size());
- for (const auto& c : Content_)
- result.emplace_back(c.first.front());
- return result;
- }
-
bool Equals(const TConstraintNode& node) const override;
bool Includes(const TConstraintNode& node) const override;
void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
bool IsPrefixOf(const TSortedConstraintNode& node) const;
size_t GetCommonPrefixLength(const TSortedConstraintNode& node) const;
- const TSortedConstraintNode* CutPrefix(size_t newPrefixLength, TExprContext& ctx) const;
-
+ const TSortedConstraintNode* CutPrefix(size_t newPrefixLength, TExprContext& ctx) const;
+
static const TSortedConstraintNode* MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx);
- static const TSortedConstraintNode* FilterByType(const TSortedConstraintNode* sorted, const TStructExprType* outItemType, TExprContext& ctx);
+ static const TSortedConstraintNode* FilterByType(const TSortedConstraintNode* sorted, const TStructExprType* outItemType, TExprContext& ctx);
protected:
- TContainerType Content_;
+ TContainerType Content_;
};
class TGroupByConstraintNode final: public TColumnSetConstraintNodeBase {
@@ -217,7 +217,7 @@ protected:
size_t GetCommonPrefixLength(const TGroupByConstraintNode& node) const;
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "GroupBy";
}
@@ -235,7 +235,7 @@ protected:
TUniqueConstraintNode(TUniqueConstraintNode&& constr);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "Unique";
}
@@ -247,33 +247,33 @@ public:
class TPassthroughConstraintNode final: public TConstraintNode {
public:
- using TKeyType = std::deque<std::string_view>;
- using TPartType = NSorted::TSimpleMap<TKeyType, std::string_view>;
- using TMapType = std::unordered_map<const TPassthroughConstraintNode*, TPartType>;
- using TReverseMapType = NSorted::TSimpleMap<std::string_view, std::string_view>;
-private:
+ using TKeyType = std::deque<std::string_view>;
+ using TPartType = NSorted::TSimpleMap<TKeyType, std::string_view>;
+ using TMapType = std::unordered_map<const TPassthroughConstraintNode*, TPartType>;
+ using TReverseMapType = NSorted::TSimpleMap<std::string_view, std::string_view>;
+private:
friend struct TExprContext;
TPassthroughConstraintNode(TExprContext& ctx, const TStructExprType& itemType);
- TPassthroughConstraintNode(TExprContext& ctx, const TTupleExprType& itemType);
- TPassthroughConstraintNode(TExprContext& ctx, const TMultiExprType& itemType);
+ TPassthroughConstraintNode(TExprContext& ctx, const TTupleExprType& itemType);
+ TPassthroughConstraintNode(TExprContext& ctx, const TMultiExprType& itemType);
TPassthroughConstraintNode(TPassthroughConstraintNode&& constr);
- TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping);
+ TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "Passthrough";
}
- const TMapType& GetColumnMapping() const;
- TReverseMapType GetReverseMapping() const;
+ const TMapType& GetColumnMapping() const;
+ TReverseMapType GetReverseMapping() const;
bool Equals(const TConstraintNode& node) const override;
bool Includes(const TConstraintNode& node) const override;
void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
+
+ const TPassthroughConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
- const TPassthroughConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
-
static const TPassthroughConstraintNode* MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx);
private:
TMapType Mapping_;
@@ -287,12 +287,12 @@ protected:
TEmptyConstraintNode(TEmptyConstraintNode&& constr);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "Empty";
}
bool Equals(const TConstraintNode& node) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
static const TEmptyConstraintNode* MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx);
};
@@ -310,7 +310,7 @@ protected:
TVarIndexConstraintNode(TVarIndexConstraintNode&& constr);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "VarIndex";
}
@@ -325,7 +325,7 @@ public:
bool Equals(const TConstraintNode& node) const override;
bool Includes(const TConstraintNode& node) const override;
void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
static const TVarIndexConstraintNode* MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx);
@@ -348,7 +348,7 @@ public:
TMultiConstraintNode(TMultiConstraintNode&& constr);
public:
- static constexpr std::string_view Name() {
+ static constexpr std::string_view Name() {
return "Multi";
}
@@ -363,11 +363,11 @@ public:
bool Equals(const TConstraintNode& node) const override;
bool Includes(const TConstraintNode& node) const override;
void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
+ void ToJson(NJson::TJsonWriter& out) const override;
static const TMultiConstraintNode* MakeCommon(const TVector<const TConstraintSet*>& constraints, TExprContext& ctx);
- bool FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const;
+ bool FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const;
protected:
TMapType Items_;
};
diff --git a/ydb/library/yql/ast/yql_expr.cpp b/ydb/library/yql/ast/yql_expr.cpp
index 5852b1710a..82f6c5812a 100644
--- a/ydb/library/yql/ast/yql_expr.cpp
+++ b/ydb/library/yql/ast/yql_expr.cpp
@@ -10,13 +10,13 @@
#include <util/string/cast.h>
#include <util/string/join.h>
-#include <util/digest/fnv.h>
-#include <util/digest/murmur.h>
-#include <util/digest/city.h>
-#include <util/digest/numeric.h>
-
-#include <map>
-
+#include <util/digest/fnv.h>
+#include <util/digest/murmur.h>
+#include <util/digest/city.h>
+#include <util/digest/numeric.h>
+
+#include <map>
+
namespace NYql {
const TStringBuf ZeroString = "";
@@ -26,20 +26,20 @@ void ReportError(TExprContext& ctx, const TIssue& issue) {
}
namespace {
- template <typename T>
- const T* FindType(const T& sample, TExprContext& ctx) {
- const auto it = ctx.TypeSet.find(&sample);
- return ctx.TypeSet.cend() != it ? static_cast<const T*>(*it) : nullptr;
- }
-
- template <typename T, typename... Args>
- const T* AddType(TExprContext& ctx, Args&&... args) {
+ template <typename T>
+ const T* FindType(const T& sample, TExprContext& ctx) {
+ const auto it = ctx.TypeSet.find(&sample);
+ return ctx.TypeSet.cend() != it ? static_cast<const T*>(*it) : nullptr;
+ }
+
+ template <typename T, typename... Args>
+ const T* AddType(TExprContext& ctx, Args&&... args) {
Y_VERIFY_DEBUG(!ctx.Frozen);
- ctx.TypeNodes.emplace(new T(std::forward<Args>(args)...));
- const auto ins = ctx.TypeSet.emplace(ctx.TypeNodes.top().get());
- return static_cast<const T*>(*ins.first);
- }
-
+ ctx.TypeNodes.emplace(new T(std::forward<Args>(args)...));
+ const auto ins = ctx.TypeSet.emplace(ctx.TypeNodes.top().get());
+ return static_cast<const T*>(*ins.first);
+ }
+
void DumpNode(const TExprNode& node, IOutputStream& out, ui32 level, TNodeSet& visited) {
for (ui32 i = 0; i < level; ++i) {
out.Write(' ');
@@ -54,24 +54,24 @@ namespace {
out << ", type: " << *node.GetTypeAnn();
}
- if (const auto scope = node.GetDependencyScope()) {
- out << ", outer lambda ";
- if (const auto outer = scope->first) {
- out << '#' << outer->UniqueId();
+ if (const auto scope = node.GetDependencyScope()) {
+ out << ", outer lambda ";
+ if (const auto outer = scope->first) {
+ out << '#' << outer->UniqueId();
+ } else {
+ out << "null";
+ }
+
+ out << ", inner lambda ";
+ if (const auto inner = scope->second) {
+ out << '#' << inner->UniqueId();
} else {
- out << "null";
+ out << "null";
}
-
- out << ", inner lambda ";
- if (const auto inner = scope->second) {
- out << '#' << inner->UniqueId();
- } else {
- out << "null";
- }
}
bool showChildren = true;
- if (!visited.emplace(&node).second) {
+ if (!visited.emplace(&node).second) {
if (node.Type() == TExprNode::Callable || node.Type() == TExprNode::List
|| node.Type() == TExprNode::Lambda || node.Type() == TExprNode::Arguments) {
out << " ...";
@@ -89,17 +89,17 @@ namespace {
struct TContext {
struct TFrame {
- THashMap<TString, TExprNode::TListType> Bindings;
+ THashMap<TString, TExprNode::TListType> Bindings;
THashMap<TString, TString> Imports;
- TExprNode::TListType Return;
+ TExprNode::TListType Return;
};
TExprContext& Expr;
TVector<TFrame> Frames;
- TLibraryCohesion Cohesion;
-
- TNodeOnNodeOwnedMap DeepClones;
-
+ TLibraryCohesion Cohesion;
+
+ TNodeOnNodeOwnedMap DeepClones;
+
const TAnnotationNodeMap* Annotations = nullptr;
IModuleResolver* ModuleResolver = nullptr;
ui32 TypeAnnotationIndex = Max<ui32>();
@@ -115,12 +115,12 @@ namespace {
Expr.AddError(TIssue(node.GetPosition(), message));
}
- TExprNode::TPtr&& ProcessNode(const TAstNode& node, TExprNode::TPtr&& exprNode) {
+ TExprNode::TPtr&& ProcessNode(const TAstNode& node, TExprNode::TPtr&& exprNode) {
if (TypeAnnotationIndex != Max<ui32>()) {
exprNode->SetTypeAnn(CompileTypeAnnotation(node));
}
- return std::move(exprNode);
+ return std::move(exprNode);
}
void PushFrame() {
@@ -131,26 +131,26 @@ namespace {
Frames.pop_back();
}
- TExprNode::TListType FindBinding(const TStringBuf& name) const {
- for (auto it = Frames.crbegin(); it != Frames.crend(); ++it) {
- const auto r = it->Bindings.find(name);
- if (it->Bindings.cend() != r)
- return r->second;
+ TExprNode::TListType FindBinding(const TStringBuf& name) const {
+ for (auto it = Frames.crbegin(); it != Frames.crend(); ++it) {
+ const auto r = it->Bindings.find(name);
+ if (it->Bindings.cend() != r)
+ return r->second;
}
- return {};
+ return {};
}
TString FindImport(const TStringBuf& name) const {
- for (auto it = Frames.crbegin(); it != Frames.crend(); ++it) {
- const auto r = it->Imports.find(name);
- if (it->Imports.cend() != r)
- return r->second;
- }
-
+ for (auto it = Frames.crbegin(); it != Frames.crend(); ++it) {
+ const auto r = it->Imports.find(name);
+ if (it->Imports.cend() != r)
+ return r->second;
+ }
+
return TString();
- }
-
+ }
+
const TTypeAnnotationNode* CompileTypeAnnotation(const TAstNode& node) {
auto ptr = Annotations->FindPtr(&node);
if (!ptr || TypeAnnotationIndex >= ptr->size()) {
@@ -167,19 +167,19 @@ namespace {
return nullptr;
}
else if (node.GetContent() == TStringBuf("Unit")) {
- return Expr.MakeType<TUnitExprType>();
+ return Expr.MakeType<TUnitExprType>();
}
else if (node.GetContent() == TStringBuf("World")) {
- return Expr.MakeType<TWorldExprType>();
+ return Expr.MakeType<TWorldExprType>();
}
else if (node.GetContent() == TStringBuf("Void")) {
- return Expr.MakeType<TVoidExprType>();
+ return Expr.MakeType<TVoidExprType>();
}
else if (node.GetContent() == TStringBuf("Null")) {
return Expr.MakeType<TNullExprType>();
}
else if (node.GetContent() == TStringBuf("Generic")) {
- return Expr.MakeType<TGenericExprType>();
+ return Expr.MakeType<TGenericExprType>();
}
else if (node.GetContent() == TStringBuf("EmptyList")) {
return Expr.MakeType<TEmptyListExprType>();
@@ -204,8 +204,8 @@ namespace {
auto content = node.GetChild(0)->GetContent();
if (content == TStringBuf("Data")) {
- const auto count = node.GetChildrenCount();
- if (!(count == 2 || count == 4) || !node.GetChild(1)->IsAtom()) {
+ const auto count = node.GetChildrenCount();
+ if (!(count == 2 || count == 4) || !node.GetChild(1)->IsAtom()) {
AddError(node, "Bad data type annotation");
return nullptr;
}
@@ -216,20 +216,20 @@ namespace {
return nullptr;
}
- if (count == 2) {
+ if (count == 2) {
return Expr.MakeType<TDataExprType>(*slot);
- } else {
- if (!(node.GetChild(2)->IsAtom() && node.GetChild(3)->IsAtom())) {
- AddError(node, "Bad data type annotation");
- return nullptr;
- }
+ } else {
+ if (!(node.GetChild(2)->IsAtom() && node.GetChild(3)->IsAtom())) {
+ AddError(node, "Bad data type annotation");
+ return nullptr;
+ }
auto ann = Expr.MakeType<TDataExprParamsType>(*slot, node.GetChild(2)->GetContent(), node.GetChild(3)->GetContent());
if (!ann->Validate(node.GetPosition(), Expr)) {
return nullptr;
}
return ann;
- }
+ }
} else if (content == TStringBuf("List")) {
if (node.GetChildrenCount() != 2) {
AddError(node, "Bad list type annotation");
@@ -274,21 +274,21 @@ namespace {
return ann;
} else if (content == TStringBuf("Multi")) {
- TTypeAnnotationNode::TListType children;
- for (size_t index = 1; index < node.GetChildrenCount(); ++index) {
- auto r = CompileTypeAnnotationNode(*node.GetChild(index));
- if (!r)
- return nullptr;
-
- children.push_back(r);
- }
-
- auto ann = Expr.MakeType<TMultiExprType>(children);
- if (!ann->Validate(node.GetPosition(), Expr)) {
- return nullptr;
- }
-
- return ann;
+ TTypeAnnotationNode::TListType children;
+ for (size_t index = 1; index < node.GetChildrenCount(); ++index) {
+ auto r = CompileTypeAnnotationNode(*node.GetChild(index));
+ if (!r)
+ return nullptr;
+
+ children.push_back(r);
+ }
+
+ auto ann = Expr.MakeType<TMultiExprType>(children);
+ if (!ann->Validate(node.GetPosition(), Expr)) {
+ return nullptr;
+ }
+
+ return ann;
} else if (content == TStringBuf("Tuple")) {
TTypeAnnotationNode::TListType children;
for (size_t index = 1; index < node.GetChildrenCount(); ++index) {
@@ -521,15 +521,15 @@ namespace {
return ann;
} else if (content == TStringBuf("Stream")) {
- if (node.GetChildrenCount() != 2) {
+ if (node.GetChildrenCount() != 2) {
AddError(node, "Bad stream type annotation");
- return nullptr;
- }
-
- auto r = CompileTypeAnnotationNode(*node.GetChild(1));
- if (!r)
- return nullptr;
-
+ return nullptr;
+ }
+
+ auto r = CompileTypeAnnotationNode(*node.GetChild(1));
+ if (!r)
+ return nullptr;
+
return Expr.MakeType<TStreamExprType>(r);
} else if (content == TStringBuf("Flow")) {
if (node.GetChildrenCount() != 2) {
@@ -762,18 +762,18 @@ namespace {
return TAstNode::NewList(TPosition(), pool, self, itemType);
}
- case ETypeAnnotationKind::Multi:
- {
+ case ETypeAnnotationKind::Multi:
+ {
auto self = TAstNode::NewLiteralAtom(TPosition(), TStringBuf("Multi"), pool);
- TSmallVec<TAstNode*> children;
- children.push_back(self);
- for (auto& child : annotation.Cast<TMultiExprType>()->GetItems()) {
- children.push_back(ConvertTypeAnnotationToAst(*child, pool, refAtoms));
- }
-
- return TAstNode::NewList(TPosition(), children.data(), children.size(), pool);
- }
-
+ TSmallVec<TAstNode*> children;
+ children.push_back(self);
+ for (auto& child : annotation.Cast<TMultiExprType>()->GetItems()) {
+ children.push_back(ConvertTypeAnnotationToAst(*child, pool, refAtoms));
+ }
+
+ return TAstNode::NewList(TPosition(), children.data(), children.size(), pool);
+ }
+
case ETypeAnnotationKind::EmptyList:
{
return TAstNode::NewLiteralAtom(TPosition(), TStringBuf("EmptyList"), pool);
@@ -813,44 +813,44 @@ namespace {
return TAstNode::NewList(node->GetPosition(), children.data(), children.size(), pool);
}
- TExprNode::TListType Compile(const TAstNode& node, TContext& ctx);
+ TExprNode::TListType Compile(const TAstNode& node, TContext& ctx);
- TExprNode::TPtr CompileQuote(const TAstNode& node, TContext& ctx) {
+ TExprNode::TPtr CompileQuote(const TAstNode& node, TContext& ctx) {
if (node.IsAtom()) {
return ctx.ProcessNode(node, ctx.Expr.NewAtom(node.GetPosition(), TString(node.GetContent()), node.GetFlags()));
} else {
TExprNode::TListType children;
- children.reserve(node.GetChildrenCount());
+ children.reserve(node.GetChildrenCount());
for (ui32 index = 0; index < node.GetChildrenCount(); ++index) {
auto r = Compile(*node.GetChild(index), ctx);
- if (r.empty())
- return {};
+ if (r.empty())
+ return {};
- std::move(r.begin(), r.end(), std::back_inserter(children));
+ std::move(r.begin(), r.end(), std::back_inserter(children));
}
- return ctx.ProcessNode(node, ctx.Expr.NewList(node.GetPosition(), std::move(children)));
+ return ctx.ProcessNode(node, ctx.Expr.NewList(node.GetPosition(), std::move(children)));
}
}
- TExprNode::TListType CompileLambda(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() < 2) {
- ctx.AddError(node, "Expected size of list at least 3.");
- return {};
+ TExprNode::TListType CompileLambda(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() < 2) {
+ ctx.AddError(node, "Expected size of list at least 3.");
+ return {};
}
- const auto args = node.GetChild(1);
+ const auto args = node.GetChild(1);
if (!args->IsList() || args->GetChildrenCount() != 2 || !args->GetChild(0)->IsAtom() ||
args->GetChild(0)->GetContent() != TStringBuf("quote") || !args->GetChild(1)->IsList()) {
ctx.AddError(node, "Lambda arguments must be a quoted list of atoms");
- return {};
+ return {};
}
- const auto params = args->GetChild(1);
+ const auto params = args->GetChild(1);
for (ui32 index = 0; index < params->GetChildrenCount(); ++index) {
if (!params->GetChild(index)->IsAtom()) {
ctx.AddError(node, "Lambda arguments must be a quoted list of atoms");
- return {};
+ return {};
}
}
@@ -861,28 +861,28 @@ namespace {
auto lambdaArg = ctx.ProcessNode(*arg, ctx.Expr.NewArgument(arg->GetPosition(), TString(arg->GetContent())));
argNodes.push_back(lambdaArg);
auto& binding = ctx.Frames.back().Bindings[arg->GetContent()];
- if (!binding.empty()) {
+ if (!binding.empty()) {
ctx.PopFrame();
ctx.AddError(*arg, TStringBuilder() << "Duplicated name of lambda parameter: " << arg->GetContent());
- return {};
+ return {};
}
- binding = {lambdaArg};
+ binding = {lambdaArg};
}
- TExprNode::TListType body;
- body.reserve(node.GetChildrenCount() - 2U);
- for (auto i = 2U; i < node.GetChildrenCount(); ++i) {
- auto r = Compile(*node.GetChild(i), ctx);
- if (r.empty())
- return {};
- std::move(r.begin(), r.end(), std::back_inserter(body));
- }
- ctx.PopFrame();
+ TExprNode::TListType body;
+ body.reserve(node.GetChildrenCount() - 2U);
+ for (auto i = 2U; i < node.GetChildrenCount(); ++i) {
+ auto r = Compile(*node.GetChild(i), ctx);
+ if (r.empty())
+ return {};
+ std::move(r.begin(), r.end(), std::back_inserter(body));
+ }
+ ctx.PopFrame();
- auto arguments = ctx.ProcessNode(*args, ctx.Expr.NewArguments(args->GetPosition(), std::move(argNodes)));
- auto lambda = ctx.ProcessNode(node, ctx.Expr.NewLambda(node.GetPosition(), std::move(arguments), std::move(body)));
- return {lambda};
+ auto arguments = ctx.ProcessNode(*args, ctx.Expr.NewArguments(args->GetPosition(), std::move(argNodes)));
+ auto lambda = ctx.ProcessNode(node, ctx.Expr.NewLambda(node.GetPosition(), std::move(arguments), std::move(body)));
+ return {lambda};
}
bool CompileSetPackageVersion(const TAstNode& node, TContext& ctx) {
@@ -918,128 +918,128 @@ namespace {
return true;
}
- TExprNode::TPtr CompileBind(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() != 3) {
- ctx.AddError(node, "Expected list of size 3");
- return nullptr;
- }
-
- const auto name = node.GetChild(1);
- if (!name->IsAtom()) {
- ctx.AddError(*name, "Expected atom");
- return nullptr;
- }
-
- const auto alias = node.GetChild(2);
+ TExprNode::TPtr CompileBind(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() != 3) {
+ ctx.AddError(node, "Expected list of size 3");
+ return nullptr;
+ }
+
+ const auto name = node.GetChild(1);
+ if (!name->IsAtom()) {
+ ctx.AddError(*name, "Expected atom");
+ return nullptr;
+ }
+
+ const auto alias = node.GetChild(2);
if (alias->IsAtom() || alias->GetChildrenCount() != 2 || !alias->GetChild(0)->IsAtom() || !alias->GetChild(1)->IsAtom() ||
alias->GetChild(0)->GetContent() != TStringBuf("quote")) {
- ctx.AddError(*alias, "Expected quoted pair");
- return nullptr;
- }
-
- const auto& aliasValue = alias->GetChild(1)->GetContent();
+ ctx.AddError(*alias, "Expected quoted pair");
+ return nullptr;
+ }
+
+ const auto& aliasValue = alias->GetChild(1)->GetContent();
const auto& moduleName = name->GetContent();
TStringBuilder baseMsg;
baseMsg << "Module '" << name->GetContent() << "'";
-
+
const auto& import = ctx.FindImport(moduleName);
- if (import.empty()) {
+ if (import.empty()) {
ctx.AddError(*name, baseMsg << " does not exist");
- return nullptr;
- }
-
- if (ctx.ModuleResolver) {
+ return nullptr;
+ }
+
+ if (ctx.ModuleResolver) {
auto exportsPtr = ctx.ModuleResolver->GetModule(import);
if (!exportsPtr) {
ctx.AddError(*name, baseMsg << "'" << import << "' does not exist");
- return nullptr;
- }
-
+ return nullptr;
+ }
+
const auto& exports = exportsPtr->Symbols();
- const auto ex = exports.find(aliasValue);
- if (exports.cend() == ex) {
+ const auto ex = exports.find(aliasValue);
+ if (exports.cend() == ex) {
ctx.AddError(*alias, baseMsg << " export '" << aliasValue << "' does not exist");
- return nullptr;
- }
-
+ return nullptr;
+ }
+
return ctx.Expr.DeepCopy(*ex->second, exportsPtr->ExprCtx(), ctx.DeepClones, true, false);
- } else {
- const auto stub = ctx.Expr.NewAtom(node.GetPosition(), "stub");
- ctx.Frames.back().Bindings[name->GetContent()] = {stub};
+ } else {
+ const auto stub = ctx.Expr.NewAtom(node.GetPosition(), "stub");
+ ctx.Frames.back().Bindings[name->GetContent()] = {stub};
ctx.Cohesion.Imports[stub.Get()] = std::make_pair(import, TString(aliasValue));
- return stub;
- }
- }
-
- bool CompileLet(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() < 3) {
- ctx.AddError(node, "Expected size of list at least 3.");
- return false;
- }
-
- const auto name = node.GetChild(1);
- if (!name->IsAtom()) {
- ctx.AddError(*name, "Expected atom");
- return false;
- }
-
- TExprNode::TListType bind;
- bind.reserve(node.GetChildrenCount() - 2U);
- for (auto i = 2U; i < node.GetChildrenCount(); ++i) {
- auto r = Compile(*node.GetChild(i), ctx);
- if (r.empty())
- return false;
- std::move(r.begin(), r.end(), std::back_inserter(bind));
- }
-
- ctx.Frames.back().Bindings[name->GetContent()] = std::move(bind);
- return true;
- }
-
- bool CompileImport(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() != 3) {
- ctx.AddError(node, "Expected list of size 3");
- return false;
- }
-
- const auto name = node.GetChild(1);
- if (!name->IsAtom()) {
- ctx.AddError(*name, "Expected atom");
- return false;
- }
-
- const auto alias = node.GetChild(2);
+ return stub;
+ }
+ }
+
+ bool CompileLet(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() < 3) {
+ ctx.AddError(node, "Expected size of list at least 3.");
+ return false;
+ }
+
+ const auto name = node.GetChild(1);
+ if (!name->IsAtom()) {
+ ctx.AddError(*name, "Expected atom");
+ return false;
+ }
+
+ TExprNode::TListType bind;
+ bind.reserve(node.GetChildrenCount() - 2U);
+ for (auto i = 2U; i < node.GetChildrenCount(); ++i) {
+ auto r = Compile(*node.GetChild(i), ctx);
+ if (r.empty())
+ return false;
+ std::move(r.begin(), r.end(), std::back_inserter(bind));
+ }
+
+ ctx.Frames.back().Bindings[name->GetContent()] = std::move(bind);
+ return true;
+ }
+
+ bool CompileImport(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() != 3) {
+ ctx.AddError(node, "Expected list of size 3");
+ return false;
+ }
+
+ const auto name = node.GetChild(1);
+ if (!name->IsAtom()) {
+ ctx.AddError(*name, "Expected atom");
+ return false;
+ }
+
+ const auto alias = node.GetChild(2);
if (!alias->IsListOfSize(2) || !alias->GetChild(0)->IsAtom() || !alias->GetChild(1)->IsAtom() ||
alias->GetChild(0)->GetContent() != TStringBuf("quote")) {
- ctx.AddError(node, "Expected quoted pair");
- return false;
- }
-
- ctx.Frames.back().Imports[name->GetContent()] = alias->GetChild(1)->GetContent();
- return true;
- }
-
- bool CompileExport(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() != 2) {
- ctx.AddError(node, "Expected list of size 2");
- return false;
- }
-
- const auto name = node.GetChild(1);
- if (!name->IsAtom()) {
- ctx.AddError(*name, "Expected atom");
- return false;
- }
-
- auto r = Compile(*node.GetChild(1), ctx);
- if (r.size() != 1U)
- return false;
-
- ctx.Cohesion.Exports.Symbols(ctx.Expr)[name->GetContent()] = std::move(r.front());
- return true;
- }
-
+ ctx.AddError(node, "Expected quoted pair");
+ return false;
+ }
+
+ ctx.Frames.back().Imports[name->GetContent()] = alias->GetChild(1)->GetContent();
+ return true;
+ }
+
+ bool CompileExport(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() != 2) {
+ ctx.AddError(node, "Expected list of size 2");
+ return false;
+ }
+
+ const auto name = node.GetChild(1);
+ if (!name->IsAtom()) {
+ ctx.AddError(*name, "Expected atom");
+ return false;
+ }
+
+ auto r = Compile(*node.GetChild(1), ctx);
+ if (r.size() != 1U)
+ return false;
+
+ ctx.Cohesion.Exports.Symbols(ctx.Expr)[name->GetContent()] = std::move(r.front());
+ return true;
+ }
+
bool CompileDeclare(const TAstNode& node, TContext& ctx) {
if (node.GetChildrenCount() != 3) {
ctx.AddError(node, "Expected list of size 3");
@@ -1063,17 +1063,17 @@ namespace {
return false;
}
- auto typeExpr = Compile(*node.GetChild(2), ctx);
- if (typeExpr.size() != 1U)
+ auto typeExpr = Compile(*node.GetChild(2), ctx);
+ if (typeExpr.size() != 1U)
return false;
auto parameterExpr = ctx.ProcessNode(node,
ctx.Expr.NewCallable(node.GetPosition(), "Parameter", {
ctx.Expr.NewAtom(node.GetPosition(), nameStr),
- std::move(typeExpr.front())
+ std::move(typeExpr.front())
}));
- if (!ctx.Frames.back().Bindings.emplace(nameStr, TExprNode::TListType{std::move(parameterExpr)}).second) {
+ if (!ctx.Frames.back().Bindings.emplace(nameStr, TExprNode::TListType{std::move(parameterExpr)}).second) {
ctx.AddError(node, TStringBuilder() << "Declare statement hides previously defined name: "
<< nameStr);
return false;
@@ -1123,68 +1123,68 @@ namespace {
return true;
}
- bool CompileReturn(const TAstNode& node, TContext& ctx) {
- if (node.GetChildrenCount() < 2U) {
- ctx.AddError(node, "Expected non empty list.");
- return false;
- }
-
- TExprNode::TListType returns;
- returns.reserve(node.GetChildrenCount() - 1U);
- for (auto i = 1U; i < node.GetChildrenCount(); ++i) {
- auto r = Compile(*node.GetChild(i), ctx);
- if (r.empty())
- return false;
- std::move(r.begin(), r.end(), std::back_inserter(returns));
- }
-
- ctx.Frames.back().Return = std::move(returns);
- return true;
- }
-
- TExprNode::TListType CompileFunction(const TAstNode& root, TContext& ctx, bool topLevel = false) {
+ bool CompileReturn(const TAstNode& node, TContext& ctx) {
+ if (node.GetChildrenCount() < 2U) {
+ ctx.AddError(node, "Expected non empty list.");
+ return false;
+ }
+
+ TExprNode::TListType returns;
+ returns.reserve(node.GetChildrenCount() - 1U);
+ for (auto i = 1U; i < node.GetChildrenCount(); ++i) {
+ auto r = Compile(*node.GetChild(i), ctx);
+ if (r.empty())
+ return false;
+ std::move(r.begin(), r.end(), std::back_inserter(returns));
+ }
+
+ ctx.Frames.back().Return = std::move(returns);
+ return true;
+ }
+
+ TExprNode::TListType CompileFunction(const TAstNode& root, TContext& ctx, bool topLevel = false) {
if (!root.IsList()) {
ctx.AddError(root, "Expected list");
- return {};
+ return {};
+ }
+
+ if (ctx.Frames.size() > 1000U) {
+ ctx.AddError(root, "Too deep graph!");
+ return {};
}
- if (ctx.Frames.size() > 1000U) {
- ctx.AddError(root, "Too deep graph!");
- return {};
- }
-
ctx.PushFrame();
if (topLevel) {
for (ui32 index = 0; index < root.GetChildrenCount(); ++index) {
const auto node = root.GetChild(index);
if (!node->IsList()) {
ctx.AddError(*node, "Expected list");
- return {};
+ return {};
}
if (node->GetChildrenCount() == 0) {
ctx.AddError(*node, "Expected not empty list");
- return {};
+ return {};
}
- const auto firstChild = node->GetChild(0);
+ const auto firstChild = node->GetChild(0);
if (!firstChild->IsAtom()) {
ctx.AddError(*firstChild, "Expected atom");
- return {};
+ return {};
}
if (firstChild->GetContent() == TStringBuf("library")) {
if (!CompileLibraryDef(*node, ctx))
- return {};
+ return {};
} else if (firstChild->GetContent() == TStringBuf("set_package_version")) {
if (!CompileSetPackageVersion(*node, ctx))
- return {};
+ return {};
}
}
if (ctx.ModuleResolver) {
if (!ctx.ModuleResolver->Link(ctx.Expr)) {
- return {};
+ return {};
}
ctx.ModuleResolver->UpdateNextUniqueId(ctx.Expr);
@@ -1192,126 +1192,126 @@ namespace {
}
for (ui32 index = 0; index < root.GetChildrenCount(); ++index) {
- const auto node = root.GetChild(index);
- if (!ctx.Frames.back().Return.empty()) {
- ctx.Frames.back().Return.clear();
+ const auto node = root.GetChild(index);
+ if (!ctx.Frames.back().Return.empty()) {
+ ctx.Frames.back().Return.clear();
ctx.AddError(*node, "Return is already exist");
- return {};
+ return {};
}
if (!node->IsList()) {
ctx.AddError(*node, "Expected list");
- return {};
+ return {};
}
if (node->GetChildrenCount() == 0) {
ctx.AddError(*node, "Expected not empty list");
- return {};
+ return {};
}
auto firstChild = node->GetChild(0);
if (!firstChild->IsAtom()) {
ctx.AddError(*firstChild, "Expected atom");
- return {};
+ return {};
}
if (firstChild->GetContent() == TStringBuf("let")) {
- if (!CompileLet(*node, ctx))
- return {};
+ if (!CompileLet(*node, ctx))
+ return {};
} else if (firstChild->GetContent() == TStringBuf("return")) {
- if (!CompileReturn(*node, ctx))
- return {};
+ if (!CompileReturn(*node, ctx))
+ return {};
} else if (firstChild->GetContent() == TStringBuf("import")) {
- if (!CompileImport(*node, ctx))
- return {};
+ if (!CompileImport(*node, ctx))
+ return {};
} else if (firstChild->GetContent() == TStringBuf("declare")) {
if (!topLevel) {
ctx.AddError(*firstChild, "Declare statements are only allowed on top level block");
- return {};
+ return {};
}
if (!CompileDeclare(*node, ctx))
- return {};
+ return {};
} else if (firstChild->GetContent() == TStringBuf("library")) {
if (!topLevel) {
ctx.AddError(*firstChild, "Library statements are only allowed on top level block");
- return {};
+ return {};
}
continue;
} else if (firstChild->GetContent() == TStringBuf("set_package_version")) {
if (!topLevel) {
ctx.AddError(*firstChild, "set_package_version statements are only allowed on top level block");
- return {};
+ return {};
}
continue;
} else {
ctx.AddError(*firstChild, ToString("expected either let, return or import, but have ") + firstChild->GetContent());
- return {};
+ return {};
}
}
- auto ret = std::move(ctx.Frames.back().Return);
+ auto ret = std::move(ctx.Frames.back().Return);
ctx.PopFrame();
- if (ret.empty()) {
+ if (ret.empty()) {
ctx.AddError(root, "No return found");
}
return ret;
}
- bool CompileLibrary(const TAstNode& root, TContext& ctx) {
- if (!root.IsList()) {
- ctx.AddError(root, "Expected list");
- return false;
- }
-
- ctx.PushFrame();
- for (ui32 index = 0; index < root.GetChildrenCount(); ++index) {
- const auto node = root.GetChild(index);
-
- if (!node->IsList()) {
- ctx.AddError(*node, "Expected list");
- return false;
- }
-
- if (node->GetChildrenCount() == 0) {
- ctx.AddError(*node, "Expected not empty list");
+ bool CompileLibrary(const TAstNode& root, TContext& ctx) {
+ if (!root.IsList()) {
+ ctx.AddError(root, "Expected list");
+ return false;
+ }
+
+ ctx.PushFrame();
+ for (ui32 index = 0; index < root.GetChildrenCount(); ++index) {
+ const auto node = root.GetChild(index);
+
+ if (!node->IsList()) {
+ ctx.AddError(*node, "Expected list");
+ return false;
+ }
+
+ if (node->GetChildrenCount() == 0) {
+ ctx.AddError(*node, "Expected not empty list");
return false;
- }
-
- auto firstChild = node->GetChild(0);
- if (!firstChild->IsAtom()) {
- ctx.AddError(*firstChild, "Expected atom");
- return false;
- }
-
+ }
+
+ auto firstChild = node->GetChild(0);
+ if (!firstChild->IsAtom()) {
+ ctx.AddError(*firstChild, "Expected atom");
+ return false;
+ }
+
if (firstChild->GetContent() == TStringBuf("let")) {
- if (!CompileLet(*node, ctx))
- return false;
+ if (!CompileLet(*node, ctx))
+ return false;
} else if (firstChild->GetContent() == TStringBuf("import")) {
- if (!CompileImport(*node, ctx))
- return false;
+ if (!CompileImport(*node, ctx))
+ return false;
} else if (firstChild->GetContent() == TStringBuf("export")) {
- if (!CompileExport(*node, ctx))
- return false;
- } else {
- ctx.AddError(*firstChild, "expected either let, export or import");
- return false;
- }
- }
-
- ctx.PopFrame();
- return true;
- }
-
- TExprNode::TListType Compile(const TAstNode& node, TContext& ctx) {
+ if (!CompileExport(*node, ctx))
+ return false;
+ } else {
+ ctx.AddError(*firstChild, "expected either let, export or import");
+ return false;
+ }
+ }
+
+ ctx.PopFrame();
+ return true;
+ }
+
+ TExprNode::TListType Compile(const TAstNode& node, TContext& ctx) {
if (node.IsAtom()) {
- const auto foundNode = ctx.FindBinding(node.GetContent());
- if (foundNode.empty()) {
+ const auto foundNode = ctx.FindBinding(node.GetContent());
+ if (foundNode.empty()) {
ctx.AddError(node, TStringBuilder() << "Name not found: " << node.GetContent());
- return {};
+ return {};
}
return foundNode;
@@ -1319,30 +1319,30 @@ namespace {
if (node.GetChildrenCount() == 0) {
ctx.AddError(node, "Empty list, did you forget quote?");
- return {};
+ return {};
}
if (!node.GetChild(0)->IsAtom()) {
ctx.AddError(node, "First item in list is not an atom, did you forget quote?");
- return {};
+ return {};
}
auto function = node.GetChild(0)->GetContent();
if (function == TStringBuf("quote")) {
if (node.GetChildrenCount() != 2) {
ctx.AddError(node, "Quote should have one argument");
- return {};
+ return {};
}
- if (auto quote = CompileQuote(*node.GetChild(1), ctx))
- return {std::move(quote)};
-
- return {};
+ if (auto quote = CompileQuote(*node.GetChild(1), ctx))
+ return {std::move(quote)};
+
+ return {};
}
if (function == TStringBuf("let") || function == TStringBuf("return")) {
ctx.AddError(node, "Let and return should be used only at first level or inside def");
- return {};
+ return {};
}
if (function == TStringBuf("lambda")) {
@@ -1350,45 +1350,45 @@ namespace {
}
if (function == TStringBuf("bind")) {
- if (auto bind = CompileBind(node, ctx))
- return {std::move(bind)};
- return {};
- }
-
+ if (auto bind = CompileBind(node, ctx))
+ return {std::move(bind)};
+ return {};
+ }
+
if (function == TStringBuf("block")) {
if (node.GetChildrenCount() != 2) {
ctx.AddError(node, "Block should have one argument");
- return {};
+ return {};
}
- const auto quotedList = node.GetChild(1);
+ const auto quotedList = node.GetChild(1);
if (quotedList->GetChildrenCount() != 2 || !quotedList->GetChild(0)->IsAtom() ||
quotedList->GetChild(0)->GetContent() != TStringBuf("quote")) {
ctx.AddError(node, "Expected quoted list");
- return {};
+ return {};
}
return CompileFunction(*quotedList->GetChild(1), ctx);
}
TExprNode::TListType children;
- children.reserve(node.GetChildrenCount() - 1U);
- for (auto index = 1U; index < node.GetChildrenCount(); ++index) {
+ children.reserve(node.GetChildrenCount() - 1U);
+ for (auto index = 1U; index < node.GetChildrenCount(); ++index) {
auto r = Compile(*node.GetChild(index), ctx);
- if (r.empty())
- return {};
+ if (r.empty())
+ return {};
- std::move(r.begin(), r.end(), std::back_inserter(children));
+ std::move(r.begin(), r.end(), std::back_inserter(children));
}
- return {ctx.ProcessNode(node, ctx.Expr.NewCallable(node.GetPosition(), TString(function), std::move(children)))};
+ return {ctx.ProcessNode(node, ctx.Expr.NewCallable(node.GetPosition(), TString(function), std::move(children)))};
}
struct TFrameContext {
size_t Index = 0;
size_t Parent = 0;
- std::map<size_t, const TExprNode*> Nodes;
- std::vector<const TExprNode*> TopoSortedNodes;
+ std::map<size_t, const TExprNode*> Nodes;
+ std::vector<const TExprNode*> TopoSortedNodes;
TNodeMap<TString> Bindings;
};
@@ -1398,158 +1398,158 @@ namespace {
{}
TExprContext& Expr;
- size_t Order = 0ULL;
+ size_t Order = 0ULL;
bool RefAtoms = false;
- std::unique_ptr<TMemoryPool> Pool;
- std::vector<TFrameContext> Frames;
+ std::unique_ptr<TMemoryPool> Pool;
+ std::vector<TFrameContext> Frames;
TFrameContext* CurrentFrame = nullptr;
- TNodeMap<size_t> LambdaFrames;
+ TNodeMap<size_t> LambdaFrames;
std::map<TStringBuf, std::pair<const TExprNode*, TAstNode*>> Parameters;
-
- struct TCounters {
- size_t References = 0ULL, Neighbors = 0ULL, Order = 0ULL, Frame = 0ULL;
- };
-
- TNodeMap<TCounters> References;
-
+
+ struct TCounters {
+ size_t References = 0ULL, Neighbors = 0ULL, Order = 0ULL, Frame = 0ULL;
+ };
+
+ TNodeMap<TCounters> References;
+
const TString& FindBinding(const TExprNode* node) const {
- for (const auto* frame = CurrentFrame; frame; frame = frame->Index > 0 ? &Frames[frame->Parent] : nullptr) {
- const auto it = frame->Bindings.find(node);
- if (frame->Bindings.cend() != it)
- return it->second;
- }
-
+ for (const auto* frame = CurrentFrame; frame; frame = frame->Index > 0 ? &Frames[frame->Parent] : nullptr) {
+ const auto it = frame->Bindings.find(node);
+ if (frame->Bindings.cend() != it)
+ return it->second;
+ }
+
static const TString stub;
- return stub;
- }
-
- size_t FindCommonAncestor(size_t one, size_t two) const {
- while (one && two) {
- if (one == two)
- return one;
- if (one > two)
- one = Frames[one].Parent;
- else
- two = Frames[two].Parent;
- }
-
- return 0ULL;
- }
+ return stub;
+ }
+
+ size_t FindCommonAncestor(size_t one, size_t two) const {
+ while (one && two) {
+ if (one == two)
+ return one;
+ if (one > two)
+ one = Frames[one].Parent;
+ else
+ two = Frames[two].Parent;
+ }
+
+ return 0ULL;
+ }
};
- void VisitArguments(const TExprNode& node, TVisitNodeContext& ctx) {
- YQL_ENSURE(node.Type() == TExprNode::Arguments);
- for (const auto& arg : node.Children()) {
- auto& counts = ctx.References[arg.Get()];
- ++counts.References;
- YQL_ENSURE(ctx.CurrentFrame->Nodes.emplace(counts.Order = ++ctx.Order, arg.Get()).second);
- }
- }
-
- void RevisitNode(const TExprNode& node, TVisitNodeContext& ctx);
-
- void RevisitNode(TVisitNodeContext::TCounters& counts, const TExprNode& node, TVisitNodeContext& ctx) {
- const auto nf = ctx.FindCommonAncestor(ctx.CurrentFrame->Index, counts.Frame);
- if (counts.Frame != nf) {
- auto& frame = ctx.Frames[counts.Frame = nf];
- frame.Nodes.emplace(counts.Order, &node);
- if (TExprNode::Lambda == node.Type()) {
- ctx.Frames[ctx.LambdaFrames[&node]].Parent = counts.Frame;
- } else {
- node.ForEachChild([&ctx](const TExprNode& child) {
- RevisitNode(child, ctx);
- });
- }
- }
- }
-
- void RevisitNode(const TExprNode& node, TVisitNodeContext& ctx) {
- if (TExprNode::Argument != node.Type()) {
- RevisitNode(ctx.References[&node], node, ctx);
- }
- }
-
- void VisitNode(const TExprNode& node, size_t neighbors, TVisitNodeContext& ctx) {
- if (TExprNode::Argument == node.Type())
- return;
-
- auto& counts = ctx.References[&node];
- counts.Neighbors += neighbors;
- if (counts.References++) {
- RevisitNode(counts, node, ctx);
- } else {
- counts.Frame = ctx.CurrentFrame->Index;
-
- if (node.Type() == TExprNode::Lambda) {
- YQL_ENSURE(node.ChildrenSize() > 0U);
- const auto index = ctx.Frames.size();
- if (ctx.LambdaFrames.emplace(&node, index).second) {
- const auto prevFrameIndex = ctx.CurrentFrame - &ctx.Frames.front();
- const auto parentIndex = ctx.CurrentFrame->Index;
- ctx.Frames.emplace_back();
- ctx.CurrentFrame = &ctx.Frames.back();
- ctx.CurrentFrame->Index = index;
- ctx.CurrentFrame->Parent = parentIndex;
- VisitArguments(node.Head(), ctx);
- for(ui32 i = 1U; i < node.ChildrenSize(); ++i) {
- VisitNode(*node.Child(i), node.ChildrenSize() - 1U, ctx);
- }
- ctx.CurrentFrame = &ctx.Frames.front() + prevFrameIndex;
- }
- } else {
- node.ForEachChild([&](const TExprNode& child) {
- VisitNode(child, node.ChildrenSize(), ctx);
- });
- }
-
- if (!counts.Order)
- counts.Order = ++ctx.Order;
-
- ctx.CurrentFrame->Nodes.emplace(counts.Order, &node);
- }
- }
-
- using TRoots = TSmallVec<const TExprNode*>;
-
- TAstNode* ConvertFunction(TPositionHandle position, const TRoots& roots, TVisitNodeContext& ctx, ui32 annotationFlags, TMemoryPool& pool);
-
+ void VisitArguments(const TExprNode& node, TVisitNodeContext& ctx) {
+ YQL_ENSURE(node.Type() == TExprNode::Arguments);
+ for (const auto& arg : node.Children()) {
+ auto& counts = ctx.References[arg.Get()];
+ ++counts.References;
+ YQL_ENSURE(ctx.CurrentFrame->Nodes.emplace(counts.Order = ++ctx.Order, arg.Get()).second);
+ }
+ }
+
+ void RevisitNode(const TExprNode& node, TVisitNodeContext& ctx);
+
+ void RevisitNode(TVisitNodeContext::TCounters& counts, const TExprNode& node, TVisitNodeContext& ctx) {
+ const auto nf = ctx.FindCommonAncestor(ctx.CurrentFrame->Index, counts.Frame);
+ if (counts.Frame != nf) {
+ auto& frame = ctx.Frames[counts.Frame = nf];
+ frame.Nodes.emplace(counts.Order, &node);
+ if (TExprNode::Lambda == node.Type()) {
+ ctx.Frames[ctx.LambdaFrames[&node]].Parent = counts.Frame;
+ } else {
+ node.ForEachChild([&ctx](const TExprNode& child) {
+ RevisitNode(child, ctx);
+ });
+ }
+ }
+ }
+
+ void RevisitNode(const TExprNode& node, TVisitNodeContext& ctx) {
+ if (TExprNode::Argument != node.Type()) {
+ RevisitNode(ctx.References[&node], node, ctx);
+ }
+ }
+
+ void VisitNode(const TExprNode& node, size_t neighbors, TVisitNodeContext& ctx) {
+ if (TExprNode::Argument == node.Type())
+ return;
+
+ auto& counts = ctx.References[&node];
+ counts.Neighbors += neighbors;
+ if (counts.References++) {
+ RevisitNode(counts, node, ctx);
+ } else {
+ counts.Frame = ctx.CurrentFrame->Index;
+
+ if (node.Type() == TExprNode::Lambda) {
+ YQL_ENSURE(node.ChildrenSize() > 0U);
+ const auto index = ctx.Frames.size();
+ if (ctx.LambdaFrames.emplace(&node, index).second) {
+ const auto prevFrameIndex = ctx.CurrentFrame - &ctx.Frames.front();
+ const auto parentIndex = ctx.CurrentFrame->Index;
+ ctx.Frames.emplace_back();
+ ctx.CurrentFrame = &ctx.Frames.back();
+ ctx.CurrentFrame->Index = index;
+ ctx.CurrentFrame->Parent = parentIndex;
+ VisitArguments(node.Head(), ctx);
+ for(ui32 i = 1U; i < node.ChildrenSize(); ++i) {
+ VisitNode(*node.Child(i), node.ChildrenSize() - 1U, ctx);
+ }
+ ctx.CurrentFrame = &ctx.Frames.front() + prevFrameIndex;
+ }
+ } else {
+ node.ForEachChild([&](const TExprNode& child) {
+ VisitNode(child, node.ChildrenSize(), ctx);
+ });
+ }
+
+ if (!counts.Order)
+ counts.Order = ++ctx.Order;
+
+ ctx.CurrentFrame->Nodes.emplace(counts.Order, &node);
+ }
+ }
+
+ using TRoots = TSmallVec<const TExprNode*>;
+
+ TAstNode* ConvertFunction(TPositionHandle position, const TRoots& roots, TVisitNodeContext& ctx, ui32 annotationFlags, TMemoryPool& pool);
+
TAstNode* BuildValueNode(const TExprNode& node, TVisitNodeContext& ctx, const TString& topLevelName, ui32 annotationFlags, TMemoryPool& pool, bool useBindings) {
TAstNode* res = nullptr;
- const auto& name = ctx.FindBinding(&node);
+ const auto& name = ctx.FindBinding(&node);
if (!name.empty() && name != topLevelName && useBindings) {
res = TAstNode::NewAtom(ctx.Expr.GetPosition(node.Pos()), name, pool);
- } else {
- switch (node.Type()) {
- case TExprNode::Atom:
- {
- auto quote = AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms);
- auto content = AnnotateAstNode(
- ctx.RefAtoms ?
+ } else {
+ switch (node.Type()) {
+ case TExprNode::Atom:
+ {
+ auto quote = AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms);
+ auto content = AnnotateAstNode(
+ ctx.RefAtoms ?
TAstNode::NewLiteralAtom(ctx.Expr.GetPosition(node.Pos()), node.Content(), pool, node.Flags()) :
TAstNode::NewAtom(ctx.Expr.GetPosition(node.Pos()), node.Content(), pool, node.Flags()),
- &node, annotationFlags, pool, ctx.RefAtoms);
+ &node, annotationFlags, pool, ctx.RefAtoms);
res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool, quote, content);
- break;
+ break;
}
- case TExprNode::List:
- {
- TSmallVec<TAstNode*> values;
- for (const auto& child : node.Children()) {
+ case TExprNode::List:
+ {
+ TSmallVec<TAstNode*> values;
+ for (const auto& child : node.Children()) {
values.push_back(BuildValueNode(*child, ctx, topLevelName, annotationFlags, pool, useBindings));
- }
+ }
- auto quote = AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms);
- auto list = AnnotateAstNode(TAstNode::NewList(
+ auto quote = AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms);
+ auto list = AnnotateAstNode(TAstNode::NewList(
ctx.Expr.GetPosition(node.Pos()), values.data(), values.size(), pool), &node, annotationFlags, pool, ctx.RefAtoms);
res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool, quote, list);
- break;
+ break;
}
- case TExprNode::Callable:
- {
+ case TExprNode::Callable:
+ {
if (node.Content() == "Parameter") {
const auto& nameNode = *node.Child(0);
const auto& typeNode = *node.Child(1);
@@ -1579,94 +1579,94 @@ namespace {
break;
}
- TSmallVec<TAstNode*> children;
- children.push_back(AnnotateAstNode(
- ctx.RefAtoms ?
+ TSmallVec<TAstNode*> children;
+ children.push_back(AnnotateAstNode(
+ ctx.RefAtoms ?
TAstNode::NewLiteralAtom(ctx.Expr.GetPosition(node.Pos()), node.Content(), pool) :
TAstNode::NewAtom(ctx.Expr.GetPosition(node.Pos()), node.Content(), pool),
- nullptr, annotationFlags, pool, ctx.RefAtoms));
- for (const auto& child : node.Children()) {
+ nullptr, annotationFlags, pool, ctx.RefAtoms));
+ for (const auto& child : node.Children()) {
children.push_back(BuildValueNode(*child, ctx, topLevelName, annotationFlags, pool, useBindings));
- }
+ }
res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), children.data(), children.size(), pool);
- break;
+ break;
}
- case TExprNode::Lambda:
- {
- const auto prevFrame = ctx.CurrentFrame;
- ctx.CurrentFrame = &ctx.Frames[ctx.LambdaFrames.find(&node)->second];
- YQL_ENSURE(node.ChildrenSize() > 0U);
- const auto& args = node.Head();
- TSmallVec<TAstNode*> argsChildren;
- for (const auto& arg : args.Children()) {
- const auto& name = ctx.FindBinding(arg.Get());
+ case TExprNode::Lambda:
+ {
+ const auto prevFrame = ctx.CurrentFrame;
+ ctx.CurrentFrame = &ctx.Frames[ctx.LambdaFrames.find(&node)->second];
+ YQL_ENSURE(node.ChildrenSize() > 0U);
+ const auto& args = node.Head();
+ TSmallVec<TAstNode*> argsChildren;
+ for (const auto& arg : args.Children()) {
+ const auto& name = ctx.FindBinding(arg.Get());
const auto atom = TAstNode::NewAtom(ctx.Expr.GetPosition(node.Pos()), name, pool);
- argsChildren.emplace_back(AnnotateAstNode(atom, arg.Get(), annotationFlags, pool, ctx.RefAtoms));
- }
-
- auto argsNode = TAstNode::NewList(ctx.Expr.GetPosition(args.Pos()), argsChildren.data(), argsChildren.size(), pool);
- auto argsContainer = TAstNode::NewList(ctx.Expr.GetPosition(args.Pos()), pool,
- AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms),
- AnnotateAstNode(argsNode, nullptr, annotationFlags, pool, ctx.RefAtoms));
-
- const bool block = ctx.CurrentFrame->Bindings.cend() != std::find_if(ctx.CurrentFrame->Bindings.cbegin(), ctx.CurrentFrame->Bindings.cend(),
- [](const auto& bind) { return bind.first->Type() != TExprNode::Argument; }
- );
-
- if (block) {
- TSmallVec<const TExprNode*> body(node.ChildrenSize() - 1U);
- for (ui32 i = 0U; i < body.size(); ++i)
- body[i] = node.Child(i + 1U);
+ argsChildren.emplace_back(AnnotateAstNode(atom, arg.Get(), annotationFlags, pool, ctx.RefAtoms));
+ }
+
+ auto argsNode = TAstNode::NewList(ctx.Expr.GetPosition(args.Pos()), argsChildren.data(), argsChildren.size(), pool);
+ auto argsContainer = TAstNode::NewList(ctx.Expr.GetPosition(args.Pos()), pool,
+ AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms),
+ AnnotateAstNode(argsNode, nullptr, annotationFlags, pool, ctx.RefAtoms));
+
+ const bool block = ctx.CurrentFrame->Bindings.cend() != std::find_if(ctx.CurrentFrame->Bindings.cbegin(), ctx.CurrentFrame->Bindings.cend(),
+ [](const auto& bind) { return bind.first->Type() != TExprNode::Argument; }
+ );
+
+ if (block) {
+ TSmallVec<const TExprNode*> body(node.ChildrenSize() - 1U);
+ for (ui32 i = 0U; i < body.size(); ++i)
+ body[i] = node.Child(i + 1U);
const auto blockNode = TAstNode::NewLiteralAtom(ctx.Expr.GetPosition(node.Pos()), TStringBuf("block"), pool);
- const auto quotedListNode = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
- AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms),
- ConvertFunction(node.Pos(), body, ctx, annotationFlags, pool));
-
- const auto blockBody = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
- AnnotateAstNode(blockNode, nullptr, annotationFlags, pool, ctx.RefAtoms),
- AnnotateAstNode(quotedListNode, nullptr, annotationFlags, pool, ctx.RefAtoms));
- res = AnnotateAstNode(blockBody, nullptr, annotationFlags, pool, ctx.RefAtoms);
-
- ctx.CurrentFrame = prevFrame;
- res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
- AnnotateAstNode(TAstNode::NewLiteralAtom(
+ const auto quotedListNode = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
+ AnnotateAstNode(&TAstNode::QuoteAtom, nullptr, annotationFlags, pool, ctx.RefAtoms),
+ ConvertFunction(node.Pos(), body, ctx, annotationFlags, pool));
+
+ const auto blockBody = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
+ AnnotateAstNode(blockNode, nullptr, annotationFlags, pool, ctx.RefAtoms),
+ AnnotateAstNode(quotedListNode, nullptr, annotationFlags, pool, ctx.RefAtoms));
+ res = AnnotateAstNode(blockBody, nullptr, annotationFlags, pool, ctx.RefAtoms);
+
+ ctx.CurrentFrame = prevFrame;
+ res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), pool,
+ AnnotateAstNode(TAstNode::NewLiteralAtom(
ctx.Expr.GetPosition(node.Pos()), TStringBuf("lambda"), pool), nullptr, annotationFlags, pool, ctx.RefAtoms),
- AnnotateAstNode(argsContainer, &args, annotationFlags, pool, ctx.RefAtoms),
- res);
- } else {
- TSmallVec<TAstNode*> children(node.ChildrenSize() + 1U);
- for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
- children[i + 1U] = BuildValueNode(*node.Child(i), ctx, topLevelName, annotationFlags, pool, useBindings);
- }
-
- ctx.CurrentFrame = prevFrame;
- children[0] = AnnotateAstNode(TAstNode::NewLiteralAtom(
+ AnnotateAstNode(argsContainer, &args, annotationFlags, pool, ctx.RefAtoms),
+ res);
+ } else {
+ TSmallVec<TAstNode*> children(node.ChildrenSize() + 1U);
+ for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
+ children[i + 1U] = BuildValueNode(*node.Child(i), ctx, topLevelName, annotationFlags, pool, useBindings);
+ }
+
+ ctx.CurrentFrame = prevFrame;
+ children[0] = AnnotateAstNode(TAstNode::NewLiteralAtom(
ctx.Expr.GetPosition(node.Pos()), TStringBuf("lambda"), pool), nullptr, annotationFlags, pool, ctx.RefAtoms);
- children[1] = AnnotateAstNode(argsContainer, &args, annotationFlags, pool, ctx.RefAtoms);
- res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), children.data(), children.size(), pool);
- }
- break;
- }
-
- case TExprNode::World:
+ children[1] = AnnotateAstNode(argsContainer, &args, annotationFlags, pool, ctx.RefAtoms);
+ res = TAstNode::NewList(ctx.Expr.GetPosition(node.Pos()), children.data(), children.size(), pool);
+ }
+ break;
+ }
+
+ case TExprNode::World:
res = TAstNode::NewLiteralAtom(ctx.Expr.GetPosition(node.Pos()), TStringBuf("world"), pool);
- break;
- default:
+ break;
+ default:
YQL_ENSURE(false, "Unknown type: " << static_cast<ui32>(node.Type()));
}
}
- return AnnotateAstNode(res, &node, annotationFlags, pool, ctx.RefAtoms);
+ return AnnotateAstNode(res, &node, annotationFlags, pool, ctx.RefAtoms);
}
- TAstNode* ConvertFunction(TPositionHandle position, const TRoots& roots, TVisitNodeContext& ctx, ui32 annotationFlags, TMemoryPool& pool) {
- YQL_ENSURE(!roots.empty(), "Missed roots.");
+ TAstNode* ConvertFunction(TPositionHandle position, const TRoots& roots, TVisitNodeContext& ctx, ui32 annotationFlags, TMemoryPool& pool) {
+ YQL_ENSURE(!roots.empty(), "Missed roots.");
TSmallVec<TAstNode*> children;
- for (const auto& node : ctx.CurrentFrame->TopoSortedNodes) {
- const auto& name = ctx.FindBinding(node);
- if (name.empty() || node->Type() == TExprNode::Arguments || node->Type() == TExprNode::Argument) {
+ for (const auto& node : ctx.CurrentFrame->TopoSortedNodes) {
+ const auto& name = ctx.FindBinding(node);
+ if (name.empty() || node->Type() == TExprNode::Arguments || node->Type() == TExprNode::Argument) {
continue;
}
@@ -1682,14 +1682,14 @@ namespace {
}
const auto returnAtom = TAstNode::NewLiteralAtom(ctx.Expr.GetPosition(position), TStringBuf("return"), pool);
- TSmallVec<TAstNode*> returnChildren;
- returnChildren.reserve(roots.size() + 1U);
- returnChildren.emplace_back(AnnotateAstNode(returnAtom, nullptr, annotationFlags, pool, ctx.RefAtoms));
- for (const auto root : roots) {
- returnChildren.emplace_back(BuildValueNode(*root, ctx, TString(), annotationFlags, pool, true));
- }
- const auto returnList = TAstNode::NewList(ctx.Expr.GetPosition(position), returnChildren.data(), returnChildren.size(), pool);
- children.emplace_back(AnnotateAstNode(returnList, 1U == roots.size() ? roots.front() : nullptr, annotationFlags, pool, ctx.RefAtoms));
+ TSmallVec<TAstNode*> returnChildren;
+ returnChildren.reserve(roots.size() + 1U);
+ returnChildren.emplace_back(AnnotateAstNode(returnAtom, nullptr, annotationFlags, pool, ctx.RefAtoms));
+ for (const auto root : roots) {
+ returnChildren.emplace_back(BuildValueNode(*root, ctx, TString(), annotationFlags, pool, true));
+ }
+ const auto returnList = TAstNode::NewList(ctx.Expr.GetPosition(position), returnChildren.data(), returnChildren.size(), pool);
+ children.emplace_back(AnnotateAstNode(returnList, 1U == roots.size() ? roots.front() : nullptr, annotationFlags, pool, ctx.RefAtoms));
if (!ctx.CurrentFrame->Index && !ctx.Parameters.empty()) {
TSmallVec<TAstNode*> parameterNodes;
@@ -1705,7 +1705,7 @@ namespace {
const auto res = TAstNode::NewList(ctx.Expr.GetPosition(position), children.data(), children.size(), pool);
return AnnotateAstNode(res, nullptr, annotationFlags, pool, ctx.RefAtoms);
}
-
+
bool InlineNode(const TExprNode& node, size_t references, size_t neighbors, const TConvertToAstSettings& settings) {
if (settings.NoInlineFunc) {
if (settings.NoInlineFunc(node)) {
@@ -1713,95 +1713,95 @@ namespace {
}
}
- switch (node.Type()) {
- case TExprNode::Argument:
- return false;
- case TExprNode::Atom:
- if (const auto flags = node.Flags()) {
- if ((TNodeFlags::BinaryContent | TNodeFlags::MultilineContent) & flags)
- return false;
- else {
- if (TNodeFlags::ArbitraryContent & flags)
- return node.Content().length() <= (references == 1U ? 0x40U : 0x10U);
- else
- return true;
- }
- } else
- return true;
- default:
- if (neighbors < 2U)
- return true;
- if (const auto children = node.ChildrenSize())
- return references == 1U && children < 3U;
- else
- return true;
- }
- }
-
- typedef std::pair<const TExprNode*, const TExprNode*> TPairOfNodePotinters;
- typedef std::unordered_set<TPairOfNodePotinters, THash<TPairOfNodePotinters>> TNodesPairSet;
- typedef TNodeMap<std::pair<ui32, ui32>> TArgumentsMap;
-
+ switch (node.Type()) {
+ case TExprNode::Argument:
+ return false;
+ case TExprNode::Atom:
+ if (const auto flags = node.Flags()) {
+ if ((TNodeFlags::BinaryContent | TNodeFlags::MultilineContent) & flags)
+ return false;
+ else {
+ if (TNodeFlags::ArbitraryContent & flags)
+ return node.Content().length() <= (references == 1U ? 0x40U : 0x10U);
+ else
+ return true;
+ }
+ } else
+ return true;
+ default:
+ if (neighbors < 2U)
+ return true;
+ if (const auto children = node.ChildrenSize())
+ return references == 1U && children < 3U;
+ else
+ return true;
+ }
+ }
+
+ typedef std::pair<const TExprNode*, const TExprNode*> TPairOfNodePotinters;
+ typedef std::unordered_set<TPairOfNodePotinters, THash<TPairOfNodePotinters>> TNodesPairSet;
+ typedef TNodeMap<std::pair<ui32, ui32>> TArgumentsMap;
+
bool CompareExpressions(const TExprNode*& one, const TExprNode*& two, TArgumentsMap& argumentsMap, ui32 level, TNodesPairSet& visited) {
- const auto ins = visited.emplace(one, two);
- if (!ins.second) {
- return true;
- }
-
- if (one->Type() != two->Type())
- return false;
-
- if (one->ChildrenSize() != two->ChildrenSize())
- return false;
-
- switch (two->Type()) {
- case TExprNode::Arguments: {
- ui32 i1 = 0U, i2 = 0U;
- one->ForEachChild([&](const TExprNode& arg){ argumentsMap.emplace(&arg, std::make_pair(level, ++i1)); });
- two->ForEachChild([&](const TExprNode& arg){ argumentsMap.emplace(&arg, std::make_pair(level, ++i2)); });
- return true;
- }
- case TExprNode::Argument:
- if (const auto oneArg = argumentsMap.find(one), twoArg = argumentsMap.find(two); oneArg == twoArg)
- return argumentsMap.cend() != oneArg || one == two;
- else if (argumentsMap.cend() != oneArg && argumentsMap.cend() != twoArg) {
- return oneArg->second == twoArg->second;
- }
- return false;
- case TExprNode::Atom:
- if (one->GetFlagsToCompare() != two->GetFlagsToCompare())
- return false;
+ const auto ins = visited.emplace(one, two);
+ if (!ins.second) {
+ return true;
+ }
+
+ if (one->Type() != two->Type())
+ return false;
+
+ if (one->ChildrenSize() != two->ChildrenSize())
+ return false;
+
+ switch (two->Type()) {
+ case TExprNode::Arguments: {
+ ui32 i1 = 0U, i2 = 0U;
+ one->ForEachChild([&](const TExprNode& arg){ argumentsMap.emplace(&arg, std::make_pair(level, ++i1)); });
+ two->ForEachChild([&](const TExprNode& arg){ argumentsMap.emplace(&arg, std::make_pair(level, ++i2)); });
+ return true;
+ }
+ case TExprNode::Argument:
+ if (const auto oneArg = argumentsMap.find(one), twoArg = argumentsMap.find(two); oneArg == twoArg)
+ return argumentsMap.cend() != oneArg || one == two;
+ else if (argumentsMap.cend() != oneArg && argumentsMap.cend() != twoArg) {
+ return oneArg->second == twoArg->second;
+ }
+ return false;
+ case TExprNode::Atom:
+ if (one->GetFlagsToCompare() != two->GetFlagsToCompare())
+ return false;
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- case TExprNode::Callable:
- if (one->Content() != two->Content())
- return false;
+ case TExprNode::Callable:
+ if (one->Content() != two->Content())
+ return false;
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- default:
- break;
- case TExprNode::Lambda:
- ++level;
- }
-
- if (const auto childs = one->ChildrenSize()) {
- const auto& l = one->Children();
- const auto& r = two->Children();
- for (ui32 i = 0U; i < childs; ++i) {
+ default:
+ break;
+ case TExprNode::Lambda:
+ ++level;
+ }
+
+ if (const auto childs = one->ChildrenSize()) {
+ const auto& l = one->Children();
+ const auto& r = two->Children();
+ for (ui32 i = 0U; i < childs; ++i) {
if (!CompareExpressions(one = l[i].Get(), two = r[i].Get(), argumentsMap, level, visited)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
using TNodeSetPtr = std::shared_ptr<TNodeSet>;
TNodeSetPtr ExcludeFromUnresolved(const TExprNode& args, const TNodeSetPtr& unresolved) {
if (!unresolved || unresolved->empty() || args.ChildrenSize() == 0) {
return unresolved;
- }
-
+ }
+
size_t excluded = 0;
auto newUnresolved = std::make_shared<TNodeSet>(*unresolved);
for (auto& toExclude : args.Children()) {
@@ -1829,9 +1829,9 @@ namespace {
for (auto& item : *smaller) {
if (result->insert(item).second) {
inserted = true;
- }
- }
-
+ }
+ }
+
return inserted ? result : bigger;
}
@@ -1848,11 +1848,11 @@ namespace {
break;
case TExprNode::Lambda:
{
- if (!root.ChildrenSize()) {
+ if (!root.ChildrenSize()) {
ythrow yexception() << "lambda #" << root.UniqueId() << " has " << root.ChildrenSize() << " children";
- }
+ }
- const auto& arguments = root.Head();
+ const auto& arguments = root.Head();
if (arguments.Type() != TExprNode::Arguments) {
ythrow yexception() << "unexpected type of arguments node in lambda #" << root.UniqueId();
}
@@ -1866,10 +1866,10 @@ namespace {
}
});
- for (ui32 i = 1U; i < root.ChildrenSize(); ++i) {
- const auto bodyUnresolvedArgs = CollectUnresolvedArgs(*root.Child(i), unresolvedArgs, allArgs);
- result = ExcludeFromUnresolved(arguments, bodyUnresolvedArgs);
- }
+ for (ui32 i = 1U; i < root.ChildrenSize(); ++i) {
+ const auto bodyUnresolvedArgs = CollectUnresolvedArgs(*root.Child(i), unresolvedArgs, allArgs);
+ result = ExcludeFromUnresolved(arguments, bodyUnresolvedArgs);
+ }
break;
}
case TExprNode::Callable:
@@ -1886,75 +1886,75 @@ namespace {
case TExprNode::Arguments:
ythrow yexception() << "unexpected free arguments node #[" << root.UniqueId() << "]";
break;
- }
-
+ }
+
unresolvedArgs[&root] = result;
return result;
- }
-
- typedef TNodeMap<long> TRefCountsMap;
-
-
- void CalculateReferences(const TExprNode& node, TRefCountsMap& refCounts) {
- if (!refCounts[&node]++)
- for (const auto& child : node.Children())
- CalculateReferences(*child, refCounts);
- }
-
- void CheckReferences(const TExprNode& node, TRefCountsMap& refCounts, TNodeSet& visited) {
- if (visited.emplace(&node).second) {
- for (const auto& child : node.Children()) {
- YQL_ENSURE(child->UseCount() == refCounts[child.Get()]);
- CheckReferences(*child, refCounts, visited);
- }
- }
- }
-
+ }
+
+ typedef TNodeMap<long> TRefCountsMap;
+
+
+ void CalculateReferences(const TExprNode& node, TRefCountsMap& refCounts) {
+ if (!refCounts[&node]++)
+ for (const auto& child : node.Children())
+ CalculateReferences(*child, refCounts);
+ }
+
+ void CheckReferences(const TExprNode& node, TRefCountsMap& refCounts, TNodeSet& visited) {
+ if (visited.emplace(&node).second) {
+ for (const auto& child : node.Children()) {
+ YQL_ENSURE(child->UseCount() == refCounts[child.Get()]);
+ CheckReferences(*child, refCounts, visited);
+ }
+ }
+ }
+
template <class TPMap>
bool GatherParentsImpl(const TExprNode& node, TPMap& parentsMap, TNodeSet& visited, bool withLeaves) {
- if (node.Type() == TExprNode::Arguments) {
- return false;
- }
-
- if (!withLeaves) {
- if (node.Type() == TExprNode::Atom || node.Type() == TExprNode::World) {
- return false;
- }
- }
-
- if (!visited.emplace(&node).second) {
- return true;
- }
-
- node.ForEachChild([&](const TExprNode& child) {
+ if (node.Type() == TExprNode::Arguments) {
+ return false;
+ }
+
+ if (!withLeaves) {
+ if (node.Type() == TExprNode::Atom || node.Type() == TExprNode::World) {
+ return false;
+ }
+ }
+
+ if (!visited.emplace(&node).second) {
+ return true;
+ }
+
+ node.ForEachChild([&](const TExprNode& child) {
if (GatherParentsImpl<TPMap>(child, parentsMap, visited, withLeaves)) {
- parentsMap[&child].emplace(&node);
- }
- });
-
- return true;
- }
-
+ parentsMap[&child].emplace(&node);
+ }
+ });
+
+ return true;
+ }
+
} // namespace
bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
IModuleResolver* resolver, bool hasAnnotations, ui32 typeAnnotationIndex, ui16 syntaxVersion) {
- exprRoot.Reset();
+ exprRoot.Reset();
TAstNode* cleanRoot = nullptr;
TAnnotationNodeMap annotations;
- const TAnnotationNodeMap* currentAnnotations = nullptr;
+ const TAnnotationNodeMap* currentAnnotations = nullptr;
TAstParseResult cleanupRes;
if (!hasAnnotations) {
typeAnnotationIndex = Max<ui32>();
cleanRoot = &astRoot;
currentAnnotations = nullptr;
} else if (typeAnnotationIndex != Max<ui32>()) {
- cleanupRes.Pool = std::make_unique<TMemoryPool>(4096);
+ cleanupRes.Pool = std::make_unique<TMemoryPool>(4096);
cleanRoot = ExtractAnnotations(astRoot, annotations, *cleanupRes.Pool);
cleanupRes.Root = cleanRoot;
currentAnnotations = &annotations;
} else {
- cleanupRes.Pool = std::make_unique<TMemoryPool>(4096);
+ cleanupRes.Pool = std::make_unique<TMemoryPool>(4096);
cleanRoot = RemoveAnnotations(astRoot, *cleanupRes.Pool);
cleanupRes.Root = cleanRoot;
currentAnnotations = nullptr;
@@ -1968,7 +1968,7 @@ bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx
compileCtx.SyntaxVersion = syntaxVersion;
compileCtx.Annotations = currentAnnotations;
compileCtx.TypeAnnotationIndex = typeAnnotationIndex;
- compileCtx.ModuleResolver = resolver;
+ compileCtx.ModuleResolver = resolver;
compileCtx.PushFrame();
auto world = compileCtx.Expr.NewWorld(astRoot.GetPosition());
if (typeAnnotationIndex != Max<ui32>()) {
@@ -1977,11 +1977,11 @@ bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx
compileCtx.Frames.back().Bindings[TStringBuf("world")] = {std::move(world)};
auto ret = CompileFunction(*cleanRoot, compileCtx, true);
- if (1U != ret.size())
- return false;
- exprRoot = std::move(ret.front());
+ if (1U != ret.size())
+ return false;
+ exprRoot = std::move(ret.front());
compileCtx.PopFrame();
- return bool(exprRoot);
+ return bool(exprRoot);
}
bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
@@ -1998,58 +1998,58 @@ bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx
}
bool CompileExpr(TAstNode& astRoot, TLibraryCohesion& library, TExprContext& ctx, ui16 syntaxVersion) {
- const TAstNode* cleanRoot = &astRoot;
- TContext compileCtx(ctx);
- compileCtx.Annotations = nullptr;
- compileCtx.TypeAnnotationIndex = Max<ui32>();
+ const TAstNode* cleanRoot = &astRoot;
+ TContext compileCtx(ctx);
+ compileCtx.Annotations = nullptr;
+ compileCtx.TypeAnnotationIndex = Max<ui32>();
compileCtx.SyntaxVersion = syntaxVersion;
- const bool ok = CompileLibrary(*cleanRoot, compileCtx);
- library = compileCtx.Cohesion;
- return ok;
-}
-
+ const bool ok = CompileLibrary(*cleanRoot, compileCtx);
+ library = compileCtx.Cohesion;
+ return ok;
+}
+
const TTypeAnnotationNode* CompileTypeAnnotation(const TAstNode& node, TExprContext& ctx) {
TContext compileCtx(ctx);
return compileCtx.CompileTypeAnnotationNode(node);
}
-template<class Set>
+template<class Set>
bool IsDependedImpl(const TExprNode& node, const Set& dependences, TNodeSet& visited) {
- if (!visited.emplace(&node).second)
- return false;
-
- if (dependences.cend() != dependences.find(&node))
- return true;
-
- for (const auto& child : node.Children()) {
+ if (!visited.emplace(&node).second)
+ return false;
+
+ if (dependences.cend() != dependences.find(&node))
+ return true;
+
+ for (const auto& child : node.Children()) {
if (IsDependedImpl(*child, dependences, visited))
- return true;
+ return true;
}
- return false;
-}
-
-namespace {
-
+ return false;
+}
+
+namespace {
+
enum EChangeState : ui8 {
Unknown = 0,
Changed = 1,
- Unchanged = 2
+ Unchanged = 2
};
-ui64 CalcBloom(const ui64 id) {
- return 1ULL |
- (2ULL << (std::hash<ui64>()(id) % 63ULL)) |
- (2ULL << (IntHash<ui64>(id) % 63ULL)) |
- (2ULL << (FnvHash<ui64>(&id, sizeof(id)) % 63ULL)) |
- (2ULL << (MurmurHash<ui64>(&id, sizeof(id)) % 63ULL)) |
- (2ULL << (CityHash64(reinterpret_cast<const char*>(&id), sizeof(id)) % 63ULL));
-}
-
-inline bool InBloom(const ui64 set, const ui64 bloom) {
+ui64 CalcBloom(const ui64 id) {
+ return 1ULL |
+ (2ULL << (std::hash<ui64>()(id) % 63ULL)) |
+ (2ULL << (IntHash<ui64>(id) % 63ULL)) |
+ (2ULL << (FnvHash<ui64>(&id, sizeof(id)) % 63ULL)) |
+ (2ULL << (MurmurHash<ui64>(&id, sizeof(id)) % 63ULL)) |
+ (2ULL << (CityHash64(reinterpret_cast<const char*>(&id), sizeof(id)) % 63ULL));
+}
+
+inline bool InBloom(const ui64 set, const ui64 bloom) {
return (bloom >> 1) == ((bloom & set) >> 1);
-}
-
+}
+
EChangeState GetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces, const TNodeMap<TNodeOnNodeOwnedMap>& localReplaces,
TNodeMap<EChangeState>& changes, TNodeMap<bool>& updatedLambdas);
@@ -2088,8 +2088,8 @@ EChangeState DoGetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces,
start->SetBloom(start->GetBloom() | child.GetBloom());
incompleteBloom = incompleteBloom || (child.Type() != TExprNode::Arguments && !child.GetBloom());
});
- if (incompleteBloom) {
- start->SetBloom(0ULL);
+ if (incompleteBloom) {
+ start->SetBloom(0ULL);
}
return (EChangeState)combinedState;
@@ -2103,15 +2103,15 @@ EChangeState GetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces, c
if (!start->GetBloom() && TExprNode::Argument == start->Type()) {
start->SetBloom(CalcBloom(start->UniqueId()));
- }
-
- auto& state = changes[start];
+ }
+
+ auto& state = changes[start];
if (state != EChangeState::Unknown) {
return state;
}
- if (const auto it = replaces.find(start); it != replaces.cend()) {
- return state = it->second ? EChangeState::Changed : EChangeState::Unchanged;
+ if (const auto it = replaces.find(start); it != replaces.cend()) {
+ return state = it->second ? EChangeState::Changed : EChangeState::Unchanged;
}
if (start->ChildrenSize() == 0) {
@@ -2120,21 +2120,21 @@ EChangeState GetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces, c
if (start->Type() == TExprNode::Lambda) {
TNodeOnNodeOwnedMap newReplaces = replaces;
-
- start->Head().ForEachChild([&](const TExprNode& arg){ newReplaces[&arg] = {}; });
-
- const auto locIt = localReplaces.find(start);
+
+ start->Head().ForEachChild([&](const TExprNode& arg){ newReplaces[&arg] = {}; });
+
+ const auto locIt = localReplaces.find(start);
if (locIt != localReplaces.end()) {
for (auto& r: locIt->second) {
newReplaces[r.first] = r.second;
- }
- }
-
+ }
+ }
+
state = DoGetChanges(start, newReplaces, localReplaces, changes, updatedLambdas);
if ((state & EChangeState::Changed) != 0) {
updatedLambdas.emplace(start, false);
- }
+ }
return state;
}
@@ -2142,20 +2142,20 @@ EChangeState GetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces, c
return state = DoGetChanges(start, replaces, localReplaces, changes, updatedLambdas);
}
-template<bool KeepTypeAnns>
+template<bool KeepTypeAnns>
TExprNode::TPtr DoReplace(const TExprNode::TPtr& start, const TNodeOnNodeOwnedMap& replaces, const TNodeMap<TNodeOnNodeOwnedMap>& localReplaces,
- TNodeMap<EChangeState>& changes, TNodeOnNodeOwnedMap& processed, TExprContext& ctx) {
-
- auto& target = processed[start.Get()];
+ TNodeMap<EChangeState>& changes, TNodeOnNodeOwnedMap& processed, TExprContext& ctx) {
+
+ auto& target = processed[start.Get()];
if (target) {
return target;
}
- const auto it = replaces.find(start.Get());
+ const auto it = replaces.find(start.Get());
if (it != replaces.end()) {
return target = it->second ? it->second : start;
- }
-
+ }
+
if (start->ChildrenSize() != 0) {
auto changeIt = changes.find(start.Get());
YQL_ENSURE(changeIt != changes.end(), "Missing change");
@@ -2163,51 +2163,51 @@ TExprNode::TPtr DoReplace(const TExprNode::TPtr& start, const TNodeOnNodeOwnedMa
if (isChanged) {
if (start->Type() == TExprNode::Lambda) {
TNodeOnNodeOwnedMap newReplaces = replaces;
- const auto locIt = localReplaces.find(start.Get());
+ const auto locIt = localReplaces.find(start.Get());
YQL_ENSURE(locIt != localReplaces.end(), "Missing local changes");
for (auto& r: locIt->second) {
newReplaces[r.first] = r.second;
}
- const auto& args = start->Head();
+ const auto& args = start->Head();
TExprNode::TListType newArgsList;
- newArgsList.reserve(args.ChildrenSize());
- args.ForEachChild([&](const TExprNode& arg) {
- const auto argIt = newReplaces.find(&arg);
+ newArgsList.reserve(args.ChildrenSize());
+ args.ForEachChild([&](const TExprNode& arg) {
+ const auto argIt = newReplaces.find(&arg);
YQL_ENSURE(argIt != newReplaces.end(), "Missing argument");
- processed.emplace(&arg, argIt->second);
+ processed.emplace(&arg, argIt->second);
newArgsList.emplace_back(argIt->second);
- });
+ });
- auto newBody = GetLambdaBody(*start);
- std::for_each(newBody.begin(), newBody.end(), [&](TExprNode::TPtr& node) {
- node = DoReplace<KeepTypeAnns>(node, newReplaces, localReplaces, changes, processed, ctx);
- });
+ auto newBody = GetLambdaBody(*start);
+ std::for_each(newBody.begin(), newBody.end(), [&](TExprNode::TPtr& node) {
+ node = DoReplace<KeepTypeAnns>(node, newReplaces, localReplaces, changes, processed, ctx);
+ });
auto newArgs = ctx.NewArguments(start->Pos(), std::move(newArgsList));
- if constexpr (KeepTypeAnns)
- newArgs->SetTypeAnn(ctx.MakeType<TUnitExprType>());
- target = ctx.NewLambda(start->Pos(), std::move(newArgs), std::move(newBody));
- if constexpr (KeepTypeAnns)
- target->SetTypeAnn(start->GetTypeAnn());
- return target;
+ if constexpr (KeepTypeAnns)
+ newArgs->SetTypeAnn(ctx.MakeType<TUnitExprType>());
+ target = ctx.NewLambda(start->Pos(), std::move(newArgs), std::move(newBody));
+ if constexpr (KeepTypeAnns)
+ target->SetTypeAnn(start->GetTypeAnn());
+ return target;
} else {
bool replaced = false;
TExprNode::TListType newChildren;
newChildren.reserve(start->ChildrenSize());
for (const auto& child : start->Children()) {
- auto newChild = DoReplace<KeepTypeAnns>(child, replaces, localReplaces, changes, processed, ctx);
+ auto newChild = DoReplace<KeepTypeAnns>(child, replaces, localReplaces, changes, processed, ctx);
if (newChild != child)
replaced = true;
newChildren.emplace_back(std::move(newChild));
}
- if (replaced) {
- target = ctx.ChangeChildren(*start, std::move(newChildren));
- if constexpr (KeepTypeAnns)
- target->SetTypeAnn(start->GetTypeAnn());
- return target;
- }
+ if (replaced) {
+ target = ctx.ChangeChildren(*start, std::move(newChildren));
+ if constexpr (KeepTypeAnns)
+ target->SetTypeAnn(start->GetTypeAnn());
+ return target;
+ }
}
}
}
@@ -2215,29 +2215,29 @@ TExprNode::TPtr DoReplace(const TExprNode::TPtr& start, const TNodeOnNodeOwnedMa
return target = start;
}
-void EnsureNoBadReplaces(const TExprNode& start, const TNodeOnNodeOwnedMap& replaces, TNodeSet&& visited = TNodeSet()) {
- if (!visited.insert(&start).second) {
+void EnsureNoBadReplaces(const TExprNode& start, const TNodeOnNodeOwnedMap& replaces, TNodeSet&& visited = TNodeSet()) {
+ if (!visited.insert(&start).second) {
return;
}
- const auto it = replaces.find(&start);
+ const auto it = replaces.find(&start);
if (it != replaces.end() && it->second) {
- ythrow yexception() << "Bad replace for node: " << start.UniqueId() << "\n";
+ ythrow yexception() << "Bad replace for node: " << start.UniqueId() << "\n";
}
- if (start.Type() == TExprNode::Lambda) {
+ if (start.Type() == TExprNode::Lambda) {
TNodeOnNodeOwnedMap newReplaces = replaces;
- start.Head().ForEachChild([&](const TExprNode& arg){ newReplaces[&arg] = {}; });
- start.ForEachChild([&](const TExprNode& child){ EnsureNoBadReplaces(child, newReplaces, std::move(visited)); });
+ start.Head().ForEachChild([&](const TExprNode& arg){ newReplaces[&arg] = {}; });
+ start.ForEachChild([&](const TExprNode& child){ EnsureNoBadReplaces(child, newReplaces, std::move(visited)); });
} else {
- start.ForEachChild([&](const TExprNode& child){ EnsureNoBadReplaces(child, replaces, std::move(visited)); });
+ start.ForEachChild([&](const TExprNode& child){ EnsureNoBadReplaces(child, replaces, std::move(visited)); });
}
}
const bool InternalDebug = false;
-template<bool KeepTypeAnns>
-TExprNode::TPtr ReplaceNodesImpl(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces, TNodeOnNodeOwnedMap& processed, TExprContext& ctx) {
+template<bool KeepTypeAnns>
+TExprNode::TPtr ReplaceNodesImpl(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces, TNodeOnNodeOwnedMap& processed, TExprContext& ctx) {
if (InternalDebug) {
Cerr << "Before\n" << start->Dump() << "\n";
Cerr << "Replaces\n";
@@ -2253,21 +2253,21 @@ TExprNode::TPtr ReplaceNodesImpl(TExprNode::TPtr&& start, const TNodeOnNodeOwned
TNodeMap<bool> updatedLambdas;
TNodeMap<TNodeOnNodeOwnedMap> localReplaces;
if ((GetChanges(start.Get(), replaces, localReplaces, changes, updatedLambdas) & EChangeState::Changed) == 0) {
- return std::move(start);
- }
-
+ return std::move(start);
+ }
+
if (!updatedLambdas.empty()) {
for (;;) {
changes.clear();
for (auto& x : updatedLambdas) {
if (!x.second) {
TNodeOnNodeOwnedMap& lambdaReplaces = localReplaces[x.first];
- const auto& args = x.first->Head();
- args.ForEachChild([&](const TExprNode& arg) {
- const auto newArg = lambdaReplaces.emplace(&arg, ctx.ShallowCopy(arg)).first->second;
- if constexpr (KeepTypeAnns)
- newArg->SetTypeAnn(arg.GetTypeAnn());
- });
+ const auto& args = x.first->Head();
+ args.ForEachChild([&](const TExprNode& arg) {
+ const auto newArg = lambdaReplaces.emplace(&arg, ctx.ShallowCopy(arg)).first->second;
+ if constexpr (KeepTypeAnns)
+ newArg->SetTypeAnn(arg.GetTypeAnn());
+ });
x.second = true;
}
}
@@ -2280,78 +2280,78 @@ TExprNode::TPtr ReplaceNodesImpl(TExprNode::TPtr&& start, const TNodeOnNodeOwned
}
}
- auto ret = DoReplace<KeepTypeAnns>(start, replaces, localReplaces, changes, processed, ctx);
+ auto ret = DoReplace<KeepTypeAnns>(start, replaces, localReplaces, changes, processed, ctx);
if (InternalDebug) {
Cerr << "After\n" << ret->Dump() << "\n";
- EnsureNoBadReplaces(*ret, replaces);
+ EnsureNoBadReplaces(*ret, replaces);
}
return ret;
-}
-
-}
-
-TExprNode::TPtr TExprContext::ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst) {
- if (start->Type() == TExprNode::Lambda) {
- const auto& args = start->Head();
- auto body = GetLambdaBody(*start);
- std::optional<ui32> argIndex;
- for (ui32 index = 0U; index < args.ChildrenSize(); ++index) {
- const auto arg = args.Child(index);
- if (arg == &src) {
- if (argIndex) {
+}
+
+}
+
+TExprNode::TPtr TExprContext::ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst) {
+ if (start->Type() == TExprNode::Lambda) {
+ const auto& args = start->Head();
+ auto body = GetLambdaBody(*start);
+ std::optional<ui32> argIndex;
+ for (ui32 index = 0U; index < args.ChildrenSize(); ++index) {
+ const auto arg = args.Child(index);
+ if (arg == &src) {
+ if (argIndex) {
ythrow yexception() << "argument is duplicated, #[" << arg->UniqueId() << "]";
- }
-
- argIndex = index;
- }
+ }
+
+ argIndex = index;
+ }
}
- if (argIndex) {
+ if (argIndex) {
TExprNode::TListType newArgNodes;
- newArgNodes.reserve(args.ChildrenSize());
- TNodeOnNodeOwnedMap replaces(args.ChildrenSize());
-
- for (ui32 i = 0U; i < args.ChildrenSize(); ++i) {
- const auto arg = args.Child(i);
+ newArgNodes.reserve(args.ChildrenSize());
+ TNodeOnNodeOwnedMap replaces(args.ChildrenSize());
+
+ for (ui32 i = 0U; i < args.ChildrenSize(); ++i) {
+ const auto arg = args.Child(i);
auto newArg = (i == *argIndex) ? dst : ShallowCopy(*arg);
- YQL_ENSURE(replaces.emplace(arg, newArg).second);
- newArgNodes.emplace_back(std::move(newArg));
- }
-
- return NewLambda(start->Pos(), NewArguments(args.Pos(), std::move(newArgNodes)), ReplaceNodes<false>(std::move(body), replaces));
- }
- } else if (&src == start) {
- return dst;
- }
-
- return ReplaceNodes(std::move(start), {{&src, std::move(dst)}});
-}
-
-TExprNode::TPtr TExprContext::ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces) {
- TNodeOnNodeOwnedMap processed;
- return replaces.empty() ? std::move(start) : ReplaceNodesImpl<false>(std::move(start), replaces, processed, *this);
-}
-
-template<bool KeepTypeAnns>
-TExprNode::TListType TExprContext::ReplaceNodes(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces) {
- if (!replaces.empty()) {
- TNodeOnNodeOwnedMap processed;
- for (auto& node : starts) {
- node = ReplaceNodesImpl<KeepTypeAnns>(std::move(node), replaces, processed, *this);
- }
- }
- return std::move(starts);
-}
-
-template TExprNode::TListType TExprContext::ReplaceNodes<true>(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces);
-template TExprNode::TListType TExprContext::ReplaceNodes<false>(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces);
-
-bool IsDepended(const TExprNode& node, const TNodeSet& dependences) {
+ YQL_ENSURE(replaces.emplace(arg, newArg).second);
+ newArgNodes.emplace_back(std::move(newArg));
+ }
+
+ return NewLambda(start->Pos(), NewArguments(args.Pos(), std::move(newArgNodes)), ReplaceNodes<false>(std::move(body), replaces));
+ }
+ } else if (&src == start) {
+ return dst;
+ }
+
+ return ReplaceNodes(std::move(start), {{&src, std::move(dst)}});
+}
+
+TExprNode::TPtr TExprContext::ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces) {
+ TNodeOnNodeOwnedMap processed;
+ return replaces.empty() ? std::move(start) : ReplaceNodesImpl<false>(std::move(start), replaces, processed, *this);
+}
+
+template<bool KeepTypeAnns>
+TExprNode::TListType TExprContext::ReplaceNodes(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces) {
+ if (!replaces.empty()) {
+ TNodeOnNodeOwnedMap processed;
+ for (auto& node : starts) {
+ node = ReplaceNodesImpl<KeepTypeAnns>(std::move(node), replaces, processed, *this);
+ }
+ }
+ return std::move(starts);
+}
+
+template TExprNode::TListType TExprContext::ReplaceNodes<true>(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces);
+template TExprNode::TListType TExprContext::ReplaceNodes<false>(TExprNode::TListType&& starts, const TNodeOnNodeOwnedMap& replaces);
+
+bool IsDepended(const TExprNode& node, const TNodeSet& dependences) {
TNodeSet visited;
return !dependences.empty() && IsDependedImpl(node, dependences, visited);
-}
-
+}
+
void CheckArguments(const TExprNode& root) {
try {
TNodeMap<TNodeSetPtr> unresolvedArgsMap;
@@ -2376,19 +2376,19 @@ TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& exprContext, c
#endif
TVisitNodeContext ctx(exprContext);
ctx.RefAtoms = settings.RefAtoms;
- ctx.Pool = std::make_unique<TMemoryPool>(4096);
+ ctx.Pool = std::make_unique<TMemoryPool>(4096);
ctx.Frames.push_back(TFrameContext());
ctx.CurrentFrame = &ctx.Frames.front();
- VisitNode(root, 0ULL, ctx);
+ VisitNode(root, 0ULL, ctx);
ui32 uniqueNum = 0;
-
+
for (auto& frame : ctx.Frames) {
- ctx.CurrentFrame = &frame;
- frame.TopoSortedNodes.reserve(frame.Nodes.size());
- for (const auto& node : frame.Nodes) {
- const auto name = ctx.FindBinding(node.second);
- if (name.empty()) {
- const auto& ref = ctx.References[node.second];
+ ctx.CurrentFrame = &frame;
+ frame.TopoSortedNodes.reserve(frame.Nodes.size());
+ for (const auto& node : frame.Nodes) {
+ const auto name = ctx.FindBinding(node.second);
+ if (name.empty()) {
+ const auto& ref = ctx.References[node.second];
if (!InlineNode(*node.second, ref.References, ref.Neighbors, settings)) {
if (settings.PrintArguments && node.second->IsArgument()) {
auto buffer = TStringBuilder() << "$" << ++uniqueNum
@@ -2400,7 +2400,7 @@ TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& exprContext, c
sprintf(buffer, "$%" PRIu32, ++uniqueNum);
YQL_ENSURE(frame.Bindings.emplace(node.second, buffer).second);
}
- frame.TopoSortedNodes.emplace_back(node.second);
+ frame.TopoSortedNodes.emplace_back(node.second);
}
}
}
@@ -2408,8 +2408,8 @@ TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& exprContext, c
ctx.CurrentFrame = &ctx.Frames.front();
TAstParseResult result;
- result.Root = ConvertFunction(exprContext.AppendPosition(TPosition(1, 1)), {&root}, ctx, settings.AnnotationFlags, *ctx.Pool);
- result.Pool = std::move(ctx.Pool);
+ result.Root = ConvertFunction(exprContext.AppendPosition(TPosition(1, 1)), {&root}, ctx, settings.AnnotationFlags, *ctx.Pool);
+ result.Pool = std::move(ctx.Pool);
return result;
}
@@ -2421,7 +2421,7 @@ TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& exprContext, u
}
TString TExprNode::Dump() const {
- TNodeSet visited;
+ TNodeSet visited;
TStringStream out;
DumpNode(*this, out, 0, visited);
return out.Str();
@@ -2431,140 +2431,140 @@ TPosition TExprNode::Pos(const TExprContext& ctx) const {
return ctx.GetPosition(Pos());
}
-TExprNode::TPtr TExprContext::RenameNode(const TExprNode& node, const TStringBuf& name) {
- const auto newNode = node.ChangeContent(AllocateNextUniqueId(), AppendString(name));
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
-}
-
-TExprNode::TPtr TExprContext::ShallowCopy(const TExprNode& node) {
- YQL_ENSURE(node.Type() != TExprNode::Lambda);
- const auto newNode = node.Clone(AllocateNextUniqueId());
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
+TExprNode::TPtr TExprContext::RenameNode(const TExprNode& node, const TStringBuf& name) {
+ const auto newNode = node.ChangeContent(AllocateNextUniqueId(), AppendString(name));
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
+}
+
+TExprNode::TPtr TExprContext::ShallowCopy(const TExprNode& node) {
+ YQL_ENSURE(node.Type() != TExprNode::Lambda);
+ const auto newNode = node.Clone(AllocateNextUniqueId());
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
}
TExprNode::TPtr TExprContext::ChangeChildren(const TExprNode& node, TExprNode::TListType&& children) {
- const auto newNode = node.ChangeChildren(AllocateNextUniqueId(), std::move(children));
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
+ const auto newNode = node.ChangeChildren(AllocateNextUniqueId(), std::move(children));
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
}
-TExprNode::TPtr TExprContext::ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child) {
- const auto newNode = node.ChangeChild(AllocateNextUniqueId(), index, std::move(child));
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
+TExprNode::TPtr TExprContext::ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child) {
+ const auto newNode = node.ChangeChild(AllocateNextUniqueId(), index, std::move(child));
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
}
TExprNode::TPtr TExprContext::ExactChangeChildren(const TExprNode& node, TExprNode::TListType&& children) {
- const auto newNode = node.ChangeChildren(AllocateNextUniqueId(), std::move(children));
+ const auto newNode = node.ChangeChildren(AllocateNextUniqueId(), std::move(children));
newNode->SetTypeAnn(node.GetTypeAnn());
newNode->CopyConstraints(node);
newNode->SetState(node.GetState());
newNode->Result = node.Result;
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
}
-TExprNode::TPtr TExprContext::ExactShallowCopy(const TExprNode& node) {
+TExprNode::TPtr TExprContext::ExactShallowCopy(const TExprNode& node) {
YQL_ENSURE(node.Type() != TExprNode::Lambda);
- const auto newNode = node.Clone(AllocateNextUniqueId());
+ const auto newNode = node.Clone(AllocateNextUniqueId());
newNode->SetTypeAnn(node.GetTypeAnn());
newNode->CopyConstraints(node);
newNode->SetState(node.GetState());
newNode->Result = node.Result;
- ExprNodes.emplace_back(newNode.Get());
- return newNode;
-}
-
-TExprNode::TListType GetLambdaBody(const TExprNode& node) {
- switch (node.ChildrenSize()) {
- case 1U: return {};
- case 2U: return {node.TailPtr()};
- default: break;
- }
-
- auto body = node.ChildrenList();
- body.erase(body.cbegin());
- return body;
-}
-
-TExprNode::TPtr TExprContext::DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body) {
- YQL_ENSURE(node.IsLambda());
- const auto& prevArgs = node.Head();
-
- TNodeOnNodeOwnedMap replaces(prevArgs.ChildrenSize());
-
- TExprNode::TListType newArgNodes;
- newArgNodes.reserve(prevArgs.ChildrenSize());
- prevArgs.ForEachChild([&](const TExprNode& arg) {
- auto newArg = ShallowCopy(arg);
- YQL_ENSURE(replaces.emplace(&arg, newArg).second);
- newArgNodes.emplace_back(std::move(newArg));
- });
-
- auto newBody = ReplaceNodes(std::move(body), replaces);
- return NewLambda(node.Pos(), NewArguments(prevArgs.Pos(), std::move(newArgNodes)), std::move(newBody));
-}
-
-TExprNode::TPtr TExprContext::DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body) {
- YQL_ENSURE(node.IsLambda());
- const auto& prevArgs = node.Head();
-
- TNodeOnNodeOwnedMap replaces(prevArgs.ChildrenSize());
-
+ ExprNodes.emplace_back(newNode.Get());
+ return newNode;
+}
+
+TExprNode::TListType GetLambdaBody(const TExprNode& node) {
+ switch (node.ChildrenSize()) {
+ case 1U: return {};
+ case 2U: return {node.TailPtr()};
+ default: break;
+ }
+
+ auto body = node.ChildrenList();
+ body.erase(body.cbegin());
+ return body;
+}
+
+TExprNode::TPtr TExprContext::DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body) {
+ YQL_ENSURE(node.IsLambda());
+ const auto& prevArgs = node.Head();
+
+ TNodeOnNodeOwnedMap replaces(prevArgs.ChildrenSize());
+
+ TExprNode::TListType newArgNodes;
+ newArgNodes.reserve(prevArgs.ChildrenSize());
+ prevArgs.ForEachChild([&](const TExprNode& arg) {
+ auto newArg = ShallowCopy(arg);
+ YQL_ENSURE(replaces.emplace(&arg, newArg).second);
+ newArgNodes.emplace_back(std::move(newArg));
+ });
+
+ auto newBody = ReplaceNodes(std::move(body), replaces);
+ return NewLambda(node.Pos(), NewArguments(prevArgs.Pos(), std::move(newArgNodes)), std::move(newBody));
+}
+
+TExprNode::TPtr TExprContext::DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body) {
+ YQL_ENSURE(node.IsLambda());
+ const auto& prevArgs = node.Head();
+
+ TNodeOnNodeOwnedMap replaces(prevArgs.ChildrenSize());
+
+ TExprNode::TListType newArgNodes;
+ newArgNodes.reserve(prevArgs.ChildrenSize());
+ prevArgs.ForEachChild([&](const TExprNode& arg) {
+ auto newArg = ShallowCopy(arg);
+ YQL_ENSURE(replaces.emplace(&arg, newArg).second);
+ newArgNodes.emplace_back(std::move(newArg));
+ });
+
+ auto newBody = ReplaceNodes(body ? TExprNode::TListType{std::move(body)} : GetLambdaBody(node), replaces);
+ return NewLambda(node.Pos(), NewArguments(prevArgs.Pos(), std::move(newArgNodes)), std::move(newBody));
+}
+
+TExprNode::TPtr TExprContext::FuseLambdas(const TExprNode& outer, const TExprNode& inner) {
+ YQL_ENSURE(outer.IsLambda() && inner.IsLambda());
+ const auto& outerArgs = outer.Head();
+ const auto& innerArgs = inner.Head();
+
+ TNodeOnNodeOwnedMap innerReplaces(innerArgs.ChildrenSize());
+
TExprNode::TListType newArgNodes;
- newArgNodes.reserve(prevArgs.ChildrenSize());
- prevArgs.ForEachChild([&](const TExprNode& arg) {
- auto newArg = ShallowCopy(arg);
- YQL_ENSURE(replaces.emplace(&arg, newArg).second);
- newArgNodes.emplace_back(std::move(newArg));
- });
-
- auto newBody = ReplaceNodes(body ? TExprNode::TListType{std::move(body)} : GetLambdaBody(node), replaces);
- return NewLambda(node.Pos(), NewArguments(prevArgs.Pos(), std::move(newArgNodes)), std::move(newBody));
-}
-
-TExprNode::TPtr TExprContext::FuseLambdas(const TExprNode& outer, const TExprNode& inner) {
- YQL_ENSURE(outer.IsLambda() && inner.IsLambda());
- const auto& outerArgs = outer.Head();
- const auto& innerArgs = inner.Head();
-
- TNodeOnNodeOwnedMap innerReplaces(innerArgs.ChildrenSize());
-
- TExprNode::TListType newArgNodes;
- newArgNodes.reserve(innerArgs.ChildrenSize());
-
- innerArgs.ForEachChild([&](const TExprNode& arg) {
- auto newArg = ShallowCopy(arg);
- YQL_ENSURE(innerReplaces.emplace(&arg, newArg).second);
- newArgNodes.emplace_back(std::move(newArg));
- });
-
- auto body = ReplaceNodes(GetLambdaBody(inner), innerReplaces);
-
- TExprNode::TListType newBody;
- if (outerArgs.ChildrenSize() + 1U == inner.ChildrenSize()) {
- auto i = 0U;
- TNodeOnNodeOwnedMap outerReplaces(outerArgs.ChildrenSize());
- outerArgs.ForEachChild([&](const TExprNode& arg) {
- YQL_ENSURE(outerReplaces.emplace(&arg, std::move(body[i++])).second);
- });
- newBody = ReplaceNodes(GetLambdaBody(outer), outerReplaces);
- } else if (1U == outerArgs.ChildrenSize()) {
- const auto& outerBody = GetLambdaBody(outer);
- newBody.reserve(newBody.size() * body.size());
- for (auto item : body) {
- for (auto root : outerBody) {
- newBody.emplace_back(ReplaceNode(TExprNode::TPtr(root), outerArgs.Head(), TExprNode::TPtr(item)));
- }
- }
- }
-
- YQL_ENSURE(!newBody.empty(), "Incompatible lambdas for fuse.");
- return NewLambda(outer.Pos(), NewArguments(inner.Head().Pos(), std::move(newArgNodes)), std::move(newBody));
-}
-
+ newArgNodes.reserve(innerArgs.ChildrenSize());
+
+ innerArgs.ForEachChild([&](const TExprNode& arg) {
+ auto newArg = ShallowCopy(arg);
+ YQL_ENSURE(innerReplaces.emplace(&arg, newArg).second);
+ newArgNodes.emplace_back(std::move(newArg));
+ });
+
+ auto body = ReplaceNodes(GetLambdaBody(inner), innerReplaces);
+
+ TExprNode::TListType newBody;
+ if (outerArgs.ChildrenSize() + 1U == inner.ChildrenSize()) {
+ auto i = 0U;
+ TNodeOnNodeOwnedMap outerReplaces(outerArgs.ChildrenSize());
+ outerArgs.ForEachChild([&](const TExprNode& arg) {
+ YQL_ENSURE(outerReplaces.emplace(&arg, std::move(body[i++])).second);
+ });
+ newBody = ReplaceNodes(GetLambdaBody(outer), outerReplaces);
+ } else if (1U == outerArgs.ChildrenSize()) {
+ const auto& outerBody = GetLambdaBody(outer);
+ newBody.reserve(newBody.size() * body.size());
+ for (auto item : body) {
+ for (auto root : outerBody) {
+ newBody.emplace_back(ReplaceNode(TExprNode::TPtr(root), outerArgs.Head(), TExprNode::TPtr(item)));
+ }
+ }
+ }
+
+ YQL_ENSURE(!newBody.empty(), "Incompatible lambdas for fuse.");
+ return NewLambda(outer.Pos(), NewArguments(inner.Head().Pos(), std::move(newArgNodes)), std::move(newBody));
+}
+
TExprNode::TPtr TExprContext::DeepCopy(const TExprNode& node, TExprContext& nodeCtx, TNodeOnNodeOwnedMap& deepClones,
bool internStrings, bool copyTypes, bool copyResult, TCustomDeepCopier customCopier)
{
@@ -2599,18 +2599,18 @@ TExprNode::TPtr TExprContext::DeepCopy(const TExprNode& node, TExprContext& node
return ins.first->second;
}
-TExprNode::TPtr TExprContext::WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node) {
- if (!condition) {
- return node;
- }
- const auto pos = node->Pos();
- return NewCallable(pos, callable, {std::move(node)});
-}
-
-TExprNode::TPtr TExprContext::SwapWithHead(const TExprNode& node) {
- return ChangeChild(node.Head(), 0U, ChangeChild(node, 0U, node.Head().HeadPtr()));
-}
-
+TExprNode::TPtr TExprContext::WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node) {
+ if (!condition) {
+ return node;
+ }
+ const auto pos = node->Pos();
+ return NewCallable(pos, callable, {std::move(node)});
+}
+
+TExprNode::TPtr TExprContext::SwapWithHead(const TExprNode& node) {
+ return ChangeChild(node.Head(), 0U, ChangeChild(node, 0U, node.Head().HeadPtr()));
+}
+
TNodeException::TNodeException()
: Pos_()
{
@@ -2638,7 +2638,7 @@ bool ValidateName(TPosition position, TStringBuf name, TStringBuf descr, TExprCo
return false;
}
- if (!IsUtf8(name)) {
+ if (!IsUtf8(name)) {
ctx.AddError(TIssue(position, TStringBuilder() <<
TString(descr).to_title() << " name must be a valid utf-8 byte sequence: " << TString{name}.Quote()));
return false;
@@ -2657,29 +2657,29 @@ bool ValidateName(TPositionHandle position, TStringBuf name, TStringBuf descr, T
return ValidateName(ctx.GetPosition(position), name, descr, ctx);
}
-bool TDataExprParamsType::Validate(TPosition position, TExprContext& ctx) const {
+bool TDataExprParamsType::Validate(TPosition position, TExprContext& ctx) const {
if (GetSlot() != EDataSlot::Decimal) {
ctx.AddError(TIssue(position, TStringBuilder() << "Only Decimal may contain parameters, but got: " << GetName()));
- return false;
- }
-
- const auto precision = FromString<ui8>(GetParamOne());
-
- if (!precision || precision > 35) {
- ctx.AddError(TIssue(position, TStringBuilder() << "Invalid decimal precision: " << GetParamOne()));
- return false;
- }
-
- const auto scale = FromString<ui8>(GetParamTwo());
-
- if (scale > precision) {
- ctx.AddError(TIssue(position, TStringBuilder() << "Invalid decimal parameters: (" << GetParamOne() << "," << GetParamTwo() << ")."));
- return false;
- }
-
- return true;
-}
-
+ return false;
+ }
+
+ const auto precision = FromString<ui8>(GetParamOne());
+
+ if (!precision || precision > 35) {
+ ctx.AddError(TIssue(position, TStringBuilder() << "Invalid decimal precision: " << GetParamOne()));
+ return false;
+ }
+
+ const auto scale = FromString<ui8>(GetParamTwo());
+
+ if (scale > precision) {
+ ctx.AddError(TIssue(position, TStringBuilder() << "Invalid decimal parameters: (" << GetParamOne() << "," << GetParamTwo() << ")."));
+ return false;
+ }
+
+ return true;
+}
+
bool TDataExprParamsType::Validate(TPositionHandle position, TExprContext& ctx) const {
return Validate(ctx.GetPosition(position), ctx);
}
@@ -2692,19 +2692,19 @@ bool TItemExprType::Validate(TPositionHandle position, TExprContext& ctx) const
return Validate(ctx.GetPosition(position), ctx);
}
-bool TMultiExprType::Validate(TPosition position, TExprContext& ctx) const {
- if (Items.size() > Max<ui16>()) {
- ctx.AddError(TIssue(position, TStringBuilder() << "Too many elements: " << Items.size()));
- return false;
- }
+bool TMultiExprType::Validate(TPosition position, TExprContext& ctx) const {
+ if (Items.size() > Max<ui16>()) {
+ ctx.AddError(TIssue(position, TStringBuilder() << "Too many elements: " << Items.size()));
+ return false;
+ }
+
+ return true;
+}
+
+bool TMultiExprType::Validate(TPositionHandle position, TExprContext& ctx) const {
+ return Validate(ctx.GetPosition(position), ctx);
+}
- return true;
-}
-
-bool TMultiExprType::Validate(TPositionHandle position, TExprContext& ctx) const {
- return Validate(ctx.GetPosition(position), ctx);
-}
-
bool TTupleExprType::Validate(TPosition position, TExprContext& ctx) const {
if (Items.size() > Max<ui16>()) {
ctx.AddError(TIssue(position, TStringBuilder() << "Too many tuple elements: " << Items.size()));
@@ -2771,27 +2771,27 @@ bool TVariantExprType::Validate(TPositionHandle position, TExprContext& ctx) con
}
ui32 TVariantExprType::MakeFlags(const TTypeAnnotationNode* underlyingType) {
- switch (underlyingType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto tupleType = underlyingType->Cast<TTupleExprType>();
- auto ret = CombineFlags(tupleType->GetItems());
- if (tupleType->GetSize() > 1) {
- ret |= TypeHasManyValues;
- }
- return ret;
+ switch (underlyingType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto tupleType = underlyingType->Cast<TTupleExprType>();
+ auto ret = CombineFlags(tupleType->GetItems());
+ if (tupleType->GetSize() > 1) {
+ ret |= TypeHasManyValues;
+ }
+ return ret;
}
- case ETypeAnnotationKind::Struct: {
- const auto structType = underlyingType->Cast<TStructExprType>();
- auto ret = CombineFlags(structType->GetItems());
- if (structType->GetSize() > 1) {
- ret |= TypeHasManyValues;
- }
- return ret;
+ case ETypeAnnotationKind::Struct: {
+ const auto structType = underlyingType->Cast<TStructExprType>();
+ auto ret = CombineFlags(structType->GetItems());
+ if (structType->GetSize() > 1) {
+ ret |= TypeHasManyValues;
+ }
+ return ret;
}
- default: break;
+ default: break;
}
- ythrow yexception() << "unexpected underlying type" << *underlyingType;
+ ythrow yexception() << "unexpected underlying type" << *underlyingType;
}
@@ -2825,7 +2825,7 @@ bool TCallableExprType::Validate(TPosition position, TExprContext& ctx) const {
}
bool startedNames = false;
- std::unordered_set<std::string_view> usedNames(Arguments.size());
+ std::unordered_set<std::string_view> usedNames(Arguments.size());
for (ui32 index = 0; index < Arguments.size(); ++index) {
bool hasName = !Arguments[index].Name.empty();
if (startedNames) {
@@ -2861,9 +2861,9 @@ bool TTaggedExprType::Validate(TPositionHandle position, TExprContext& ctx) cons
return Validate(ctx.GetPosition(position), ctx);
}
-TExprContext::TExprContext(ui64 nextUniqueId)
+TExprContext::TExprContext(ui64 nextUniqueId)
: StringPool(4096)
- , NextUniqueId(nextUniqueId)
+ , NextUniqueId(nextUniqueId)
, Frozen(false)
, PositionSet(
16,
@@ -2945,18 +2945,18 @@ size_t TExprContext::GetHash(TPositionHandle p) const {
return CombineHashes(h, NumericHash(pos.Column));
}
-template<class T, typename... Args>
-const T* MakeSinglethonType(TExprContext& ctx, Args&&... args) {
- auto& singleton = std::get<const T*>(ctx.SingletonTypeCache);
- if (!singleton)
- singleton = AddType<T>(ctx, T::MakeHash(args...), std::forward<Args>(args)...);
- return singleton;
-}
-
-const TVoidExprType* TMakeTypeImpl<TVoidExprType>::Make(TExprContext& ctx) {
- return MakeSinglethonType<TVoidExprType>(ctx);
-}
-
+template<class T, typename... Args>
+const T* MakeSinglethonType(TExprContext& ctx, Args&&... args) {
+ auto& singleton = std::get<const T*>(ctx.SingletonTypeCache);
+ if (!singleton)
+ singleton = AddType<T>(ctx, T::MakeHash(args...), std::forward<Args>(args)...);
+ return singleton;
+}
+
+const TVoidExprType* TMakeTypeImpl<TVoidExprType>::Make(TExprContext& ctx) {
+ return MakeSinglethonType<TVoidExprType>(ctx);
+}
+
const TNullExprType* TMakeTypeImpl<TNullExprType>::Make(TExprContext& ctx) {
return MakeSinglethonType<TNullExprType>(ctx);
}
@@ -2969,233 +2969,233 @@ const TEmptyDictExprType* TMakeTypeImpl<TEmptyDictExprType>::Make(TExprContext&
return MakeSinglethonType<TEmptyDictExprType>(ctx);
}
-const TUnitExprType* TMakeTypeImpl<TUnitExprType>::Make(TExprContext& ctx) {
- return MakeSinglethonType<TUnitExprType>(ctx);
-}
-
-const TWorldExprType* TMakeTypeImpl<TWorldExprType>::Make(TExprContext& ctx) {
- return MakeSinglethonType<TWorldExprType>(ctx);
-}
-
-const TGenericExprType* TMakeTypeImpl<TGenericExprType>::Make(TExprContext& ctx) {
- return MakeSinglethonType<TGenericExprType>(ctx);
-}
-
-const TItemExprType* TMakeTypeImpl<TItemExprType>::Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType) {
- const auto hash = TItemExprType::MakeHash(name, itemType);
- TItemExprType sample(hash, name, itemType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- auto nameStr = ctx.AppendString(name);
- return AddType<TItemExprType>(ctx, hash, nameStr, itemType);
-}
-
-const TListExprType* TMakeTypeImpl<TListExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
- const auto hash = TListExprType::MakeHash(itemType);
- TListExprType sample(hash, itemType);
- if (const auto found = FindType(sample, ctx))
- return found;
- return AddType<TListExprType>(ctx, hash, itemType);
-}
-
-const TOptionalExprType* TMakeTypeImpl<TOptionalExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
- const auto hash = TOptionalExprType::MakeHash(itemType);
- TOptionalExprType sample(hash, itemType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TOptionalExprType>(ctx, hash, itemType);
-}
-
-const TVariantExprType* TMakeTypeImpl<TVariantExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType) {
- const auto hash = TVariantExprType::MakeHash(underlyingType);
- TVariantExprType sample(hash, underlyingType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TVariantExprType>(ctx, hash, underlyingType);
-}
-
+const TUnitExprType* TMakeTypeImpl<TUnitExprType>::Make(TExprContext& ctx) {
+ return MakeSinglethonType<TUnitExprType>(ctx);
+}
+
+const TWorldExprType* TMakeTypeImpl<TWorldExprType>::Make(TExprContext& ctx) {
+ return MakeSinglethonType<TWorldExprType>(ctx);
+}
+
+const TGenericExprType* TMakeTypeImpl<TGenericExprType>::Make(TExprContext& ctx) {
+ return MakeSinglethonType<TGenericExprType>(ctx);
+}
+
+const TItemExprType* TMakeTypeImpl<TItemExprType>::Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType) {
+ const auto hash = TItemExprType::MakeHash(name, itemType);
+ TItemExprType sample(hash, name, itemType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ auto nameStr = ctx.AppendString(name);
+ return AddType<TItemExprType>(ctx, hash, nameStr, itemType);
+}
+
+const TListExprType* TMakeTypeImpl<TListExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
+ const auto hash = TListExprType::MakeHash(itemType);
+ TListExprType sample(hash, itemType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+ return AddType<TListExprType>(ctx, hash, itemType);
+}
+
+const TOptionalExprType* TMakeTypeImpl<TOptionalExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
+ const auto hash = TOptionalExprType::MakeHash(itemType);
+ TOptionalExprType sample(hash, itemType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TOptionalExprType>(ctx, hash, itemType);
+}
+
+const TVariantExprType* TMakeTypeImpl<TVariantExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType) {
+ const auto hash = TVariantExprType::MakeHash(underlyingType);
+ TVariantExprType sample(hash, underlyingType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TVariantExprType>(ctx, hash, underlyingType);
+}
+
const TErrorExprType* TMakeTypeImpl<TErrorExprType>::Make(TExprContext& ctx, const TIssue& error) {
- const auto hash = TErrorExprType::MakeHash(error);
- TErrorExprType sample(hash, error);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TErrorExprType>(ctx, hash, error);
-}
-
-const TDictExprType* TMakeTypeImpl<TDictExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
- const TTypeAnnotationNode* payloadType) {
- const auto hash = TDictExprType::MakeHash(keyType, payloadType);
- TDictExprType sample(hash, keyType, payloadType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TDictExprType>(ctx, hash, keyType, payloadType);
-}
-
-const TTypeExprType* TMakeTypeImpl<TTypeExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* baseType) {
- const auto hash = TTypeExprType::MakeHash(baseType);
- TTypeExprType sample(hash, baseType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TTypeExprType>(ctx, hash, baseType);
-}
-
+ const auto hash = TErrorExprType::MakeHash(error);
+ TErrorExprType sample(hash, error);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TErrorExprType>(ctx, hash, error);
+}
+
+const TDictExprType* TMakeTypeImpl<TDictExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
+ const TTypeAnnotationNode* payloadType) {
+ const auto hash = TDictExprType::MakeHash(keyType, payloadType);
+ TDictExprType sample(hash, keyType, payloadType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TDictExprType>(ctx, hash, keyType, payloadType);
+}
+
+const TTypeExprType* TMakeTypeImpl<TTypeExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* baseType) {
+ const auto hash = TTypeExprType::MakeHash(baseType);
+ TTypeExprType sample(hash, baseType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TTypeExprType>(ctx, hash, baseType);
+}
+
const TDataExprType* TMakeTypeImpl<TDataExprType>::Make(TExprContext& ctx, EDataSlot slot) {
const auto hash = TDataExprType::MakeHash(slot);
TDataExprType sample(hash, slot);
- if (const auto found = FindType(sample, ctx))
- return found;
-
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
return AddType<TDataExprType>(ctx, hash, slot);
-}
-
+}
+
const TDataExprParamsType* TMakeTypeImpl<TDataExprParamsType>::Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two) {
const auto hash = TDataExprParamsType::MakeHash(slot, one, two);
TDataExprParamsType sample(hash, slot, one, two);
- if (const auto found = FindType(sample, ctx))
- return found;
-
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
return AddType<TDataExprParamsType>(ctx, hash, slot, ctx.AppendString(one), ctx.AppendString(two));
-}
-
-const TCallableExprType* TMakeTypeImpl<TCallableExprType>::Make(
+}
+
+const TCallableExprType* TMakeTypeImpl<TCallableExprType>::Make(
TExprContext& ctx, const TTypeAnnotationNode* returnType, const TVector<TCallableExprType::TArgumentInfo>& arguments,
- size_t optionalArgumentsCount, const TStringBuf& payload) {
- const auto hash = TCallableExprType::MakeHash(returnType, arguments, optionalArgumentsCount, payload);
- TCallableExprType sample(hash, returnType, arguments, optionalArgumentsCount, payload);
- if (const auto found = FindType(sample, ctx))
- return found;
-
+ size_t optionalArgumentsCount, const TStringBuf& payload) {
+ const auto hash = TCallableExprType::MakeHash(returnType, arguments, optionalArgumentsCount, payload);
+ TCallableExprType sample(hash, returnType, arguments, optionalArgumentsCount, payload);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
TVector<TCallableExprType::TArgumentInfo> newArgs;
- newArgs.reserve(arguments.size());
- for (const auto& x : arguments) {
- TCallableExprType::TArgumentInfo arg;
- arg.Type = x.Type;
- arg.Name = ctx.AppendString(x.Name);
- arg.Flags = x.Flags;
- newArgs.emplace_back(arg);
- }
-
- return AddType<TCallableExprType>(ctx, hash, returnType, newArgs, optionalArgumentsCount, ctx.AppendString(payload));
-}
-
-const TResourceExprType* TMakeTypeImpl<TResourceExprType>::Make(TExprContext& ctx, const TStringBuf& tag) {
- const auto hash = TResourceExprType::MakeHash(tag);
- TResourceExprType sample(hash, tag);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TResourceExprType>(ctx, hash, ctx.AppendString(tag));
-}
-
-const TTaggedExprType* TMakeTypeImpl<TTaggedExprType>::Make(
- TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
- const auto hash = TTaggedExprType::MakeHash(baseType, tag);
- TTaggedExprType sample(hash, baseType, tag);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TTaggedExprType>(ctx, hash, baseType, ctx.AppendString(tag));
-}
-
-const TStructExprType* TMakeTypeImpl<TStructExprType>::Make(
+ newArgs.reserve(arguments.size());
+ for (const auto& x : arguments) {
+ TCallableExprType::TArgumentInfo arg;
+ arg.Type = x.Type;
+ arg.Name = ctx.AppendString(x.Name);
+ arg.Flags = x.Flags;
+ newArgs.emplace_back(arg);
+ }
+
+ return AddType<TCallableExprType>(ctx, hash, returnType, newArgs, optionalArgumentsCount, ctx.AppendString(payload));
+}
+
+const TResourceExprType* TMakeTypeImpl<TResourceExprType>::Make(TExprContext& ctx, const TStringBuf& tag) {
+ const auto hash = TResourceExprType::MakeHash(tag);
+ TResourceExprType sample(hash, tag);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TResourceExprType>(ctx, hash, ctx.AppendString(tag));
+}
+
+const TTaggedExprType* TMakeTypeImpl<TTaggedExprType>::Make(
+ TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
+ const auto hash = TTaggedExprType::MakeHash(baseType, tag);
+ TTaggedExprType sample(hash, baseType, tag);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TTaggedExprType>(ctx, hash, baseType, ctx.AppendString(tag));
+}
+
+const TStructExprType* TMakeTypeImpl<TStructExprType>::Make(
TExprContext& ctx, const TVector<const TItemExprType*>& items) {
- if (items.empty())
- return MakeSinglethonType<TStructExprType>(ctx, items);
-
- auto sortedItems = items;
- Sort(sortedItems, TStructExprType::TItemLess());
- const auto hash = TStructExprType::MakeHash(sortedItems);
- TStructExprType sample(hash, sortedItems);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TStructExprType>(ctx, hash, sortedItems);
-}
-
-const TMultiExprType* TMakeTypeImpl<TMultiExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items) {
- if (items.empty())
- return MakeSinglethonType<TMultiExprType>(ctx, items);
-
- const auto hash = TMultiExprType::MakeHash(items);
- TMultiExprType sample(hash, items);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TMultiExprType>(ctx, hash, items);
-}
-
+ if (items.empty())
+ return MakeSinglethonType<TStructExprType>(ctx, items);
+
+ auto sortedItems = items;
+ Sort(sortedItems, TStructExprType::TItemLess());
+ const auto hash = TStructExprType::MakeHash(sortedItems);
+ TStructExprType sample(hash, sortedItems);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TStructExprType>(ctx, hash, sortedItems);
+}
+
+const TMultiExprType* TMakeTypeImpl<TMultiExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items) {
+ if (items.empty())
+ return MakeSinglethonType<TMultiExprType>(ctx, items);
+
+ const auto hash = TMultiExprType::MakeHash(items);
+ TMultiExprType sample(hash, items);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TMultiExprType>(ctx, hash, items);
+}
+
const TTupleExprType* TMakeTypeImpl<TTupleExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items) {
- if (items.empty())
- return MakeSinglethonType<TTupleExprType>(ctx, items);
-
- const auto hash = TTupleExprType::MakeHash(items);
- TTupleExprType sample(hash, items);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TTupleExprType>(ctx, hash, items);
-}
-
-const TStreamExprType* TMakeTypeImpl<TStreamExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
- const auto hash = TStreamExprType::MakeHash(itemType);
- TStreamExprType sample(hash, itemType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TStreamExprType>(ctx, hash, itemType);
-}
-
-const TFlowExprType* TMakeTypeImpl<TFlowExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
- const auto hash = TFlowExprType::MakeHash(itemType);
- TFlowExprType sample(hash, itemType);
- if (const auto found = FindType(sample, ctx))
- return found;
-
- return AddType<TFlowExprType>(ctx, hash, itemType);
-}
-
-bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two) {
+ if (items.empty())
+ return MakeSinglethonType<TTupleExprType>(ctx, items);
+
+ const auto hash = TTupleExprType::MakeHash(items);
+ TTupleExprType sample(hash, items);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TTupleExprType>(ctx, hash, items);
+}
+
+const TStreamExprType* TMakeTypeImpl<TStreamExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
+ const auto hash = TStreamExprType::MakeHash(itemType);
+ TStreamExprType sample(hash, itemType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TStreamExprType>(ctx, hash, itemType);
+}
+
+const TFlowExprType* TMakeTypeImpl<TFlowExprType>::Make(TExprContext& ctx, const TTypeAnnotationNode* itemType) {
+ const auto hash = TFlowExprType::MakeHash(itemType);
+ TFlowExprType sample(hash, itemType);
+ if (const auto found = FindType(sample, ctx))
+ return found;
+
+ return AddType<TFlowExprType>(ctx, hash, itemType);
+}
+
+bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two) {
TArgumentsMap map;
ui32 level = 0;
TNodesPairSet visited;
return CompareExpressions(one, two, map, level, visited);
-}
-
-bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap) {
- TArgumentsMap map;
+}
+
+bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap) {
+ TArgumentsMap map;
ui32 level = 0;
TNodesPairSet visited;
- map.reserve(argsMap.size());
- std::for_each(argsMap.cbegin(), argsMap.cend(), [&](const TNodeMap<ui32>::value_type& v){ map.emplace(v.first, std::make_pair(0U, v.second)); });
- auto l = &one, r = &two;
+ map.reserve(argsMap.size());
+ std::for_each(argsMap.cbegin(), argsMap.cend(), [&](const TNodeMap<ui32>::value_type& v){ map.emplace(v.first, std::make_pair(0U, v.second)); });
+ auto l = &one, r = &two;
return CompareExpressions(l, r, map, level, visited);
-}
-
-void GatherParents(const TExprNode& node, TParentsMap& parentsMap, bool withLeaves) {
- parentsMap.clear();
- TNodeSet visisted;
+}
+
+void GatherParents(const TExprNode& node, TParentsMap& parentsMap, bool withLeaves) {
+ parentsMap.clear();
+ TNodeSet visisted;
GatherParentsImpl<TParentsMap>(node, parentsMap, visisted, withLeaves);
-}
-
+}
+
void GatherParentsMulti(const TExprNode& node, TParentsMultiMap& parentsMap, bool withLeaves) {
parentsMap.clear();
TNodeSet visisted;
GatherParentsImpl<TParentsMultiMap>(node, parentsMap, visisted, withLeaves);
}
-void CheckCounts(const TExprNode& root) {
- TRefCountsMap refCounts;
- CalculateReferences(root, refCounts);
- TNodeSet visited;
- CheckReferences(root, refCounts, visited);
-}
-
+void CheckCounts(const TExprNode& root) {
+ TRefCountsMap refCounts;
+ CalculateReferences(root, refCounts);
+ TNodeSet visited;
+ CheckReferences(root, refCounts, visited);
+}
+
} // namespace NYql
template<>
diff --git a/ydb/library/yql/ast/yql_expr.h b/ydb/library/yql/ast/yql_expr.h
index e22f1c0ae7..d6eb544f9a 100644
--- a/ydb/library/yql/ast/yql_expr.h
+++ b/ydb/library/yql/ast/yql_expr.h
@@ -4,7 +4,7 @@
#include "yql_expr_types.h"
#include "yql_type_string.h"
#include "yql_expr_builder.h"
-#include "yql_gc_nodes.h"
+#include "yql_gc_nodes.h"
#include "yql_constraint.h"
#include "yql_pos_handle.h"
@@ -25,14 +25,14 @@
#include <util/generic/maybe.h>
#include <util/generic/bt_exception.h>
#include <util/generic/algorithm.h>
-#include <util/digest/murmur.h>
+#include <util/digest/murmur.h>
#include <algorithm>
-#include <unordered_set>
-#include <unordered_map>
-#include <span>
-#include <stack>
-
+#include <unordered_set>
+#include <unordered_map>
+#include <span>
+#include <stack>
+
//#define YQL_CHECK_NODES_CONSISTENCY
#ifdef YQL_CHECK_NODES_CONSISTENCY
#define ENSURE_NOT_DELETED \
@@ -41,18 +41,18 @@
YQL_ENSURE(!Frozen(), "Change in frozen node # " << UniqueId_ << ": " << Type_ << " '" << ContentUnchecked() << "'");
#define ENSURE_NOT_FROZEN_CTX \
YQL_ENSURE(!Frozen, "Change in frozen expr context.");
-#else
+#else
#define ENSURE_NOT_DELETED Y_VERIFY_DEBUG(!Dead(), "Access to dead node # %lu: %d '%s'", UniqueId_, (int)Type_, TString(ContentUnchecked()).data());
#define ENSURE_NOT_FROZEN Y_VERIFY_DEBUG(!Frozen());
#define ENSURE_NOT_FROZEN_CTX Y_VERIFY_DEBUG(!Frozen);
-#endif
+#endif
namespace NYql {
using NUdf::EDataSlot;
class TUnitExprType;
-class TMultiExprType;
+class TMultiExprType;
class TTupleExprType;
class TStructExprType;
class TItemExprType;
@@ -71,8 +71,8 @@ class TGenericExprType;
class TTaggedExprType;
class TErrorExprType;
class TVariantExprType;
-class TStreamExprType;
-class TFlowExprType;
+class TStreamExprType;
+class TFlowExprType;
class TEmptyListExprType;
class TEmptyDictExprType;
@@ -84,13 +84,13 @@ struct TTypeAnnotationVisitor {
virtual ~TTypeAnnotationVisitor() = default;
virtual void Visit(const TUnitExprType& type) = 0;
- virtual void Visit(const TMultiExprType& type) = 0;
+ virtual void Visit(const TMultiExprType& type) = 0;
virtual void Visit(const TTupleExprType& type) = 0;
virtual void Visit(const TStructExprType& type) = 0;
virtual void Visit(const TItemExprType& type) = 0;
virtual void Visit(const TListExprType& type) = 0;
virtual void Visit(const TStreamExprType& type) = 0;
- virtual void Visit(const TFlowExprType& type) = 0;
+ virtual void Visit(const TFlowExprType& type) = 0;
virtual void Visit(const TDataExprType& type) = 0;
virtual void Visit(const TWorldExprType& type) = 0;
virtual void Visit(const TOptionalExprType& type) = 0;
@@ -122,36 +122,36 @@ enum ETypeAnnotationFlags {
TypeHasBareYson = 0x400,
};
-const ui64 TypeHashMagic = 0x10000;
-
-inline ui64 StreamHash(const void* buffer, size_t size, ui64 seed) {
- return MurmurHash(buffer, size, seed);
-}
-
-inline ui64 StreamHash(ui64 value, ui64 seed) {
- return MurmurHash(&value, sizeof(value), seed);
-}
-
+const ui64 TypeHashMagic = 0x10000;
+
+inline ui64 StreamHash(const void* buffer, size_t size, ui64 seed) {
+ return MurmurHash(buffer, size, seed);
+}
+
+inline ui64 StreamHash(ui64 value, ui64 seed) {
+ return MurmurHash(&value, sizeof(value), seed);
+}
+
void ReportError(TExprContext& ctx, const TIssue& issue);
-class TTypeAnnotationNode {
+class TTypeAnnotationNode {
protected:
- TTypeAnnotationNode(ETypeAnnotationKind kind, ui32 flags, ui64 hash)
+ TTypeAnnotationNode(ETypeAnnotationKind kind, ui32 flags, ui64 hash)
: Kind(kind)
- , Flags(flags)
- , Hash(hash)
+ , Flags(flags)
+ , Hash(hash)
{
}
public:
- virtual ~TTypeAnnotationNode() = default;
-
+ virtual ~TTypeAnnotationNode() = default;
+
template <typename T>
const T* Cast() const {
static_assert(std::is_base_of<TTypeAnnotationNode, T>::value,
"Should be derived from TTypeAnnotationNode");
- const auto ret = dynamic_cast<const T*>(this);
+ const auto ret = dynamic_cast<const T*>(this);
YQL_ENSURE(ret, "Cannot cast type " << *this << " to " << ETypeAnnotationKind(T::KindValue));
return ret;
}
@@ -226,14 +226,14 @@ public:
return (GetFlags() & TypeHasBareYson) != 0;
}
- ui32 GetFlags() const {
- return Flags;
- }
+ ui32 GetFlags() const {
+ return Flags;
+ }
+
+ ui64 GetHash() const {
+ return Hash;
+ }
- ui64 GetHash() const {
- return Hash;
- }
-
bool Equals(const TTypeAnnotationNode& node) const;
void Accept(TTypeAnnotationVisitor& visitor) const;
@@ -241,49 +241,49 @@ public:
out << FormatType(this);
}
- struct THash {
- size_t operator()(const TTypeAnnotationNode* node) const {
- return node->GetHash();
- }
- };
+ struct THash {
+ size_t operator()(const TTypeAnnotationNode* node) const {
+ return node->GetHash();
+ }
+ };
+
+ struct TEqual {
+ bool operator()(const TTypeAnnotationNode* one, const TTypeAnnotationNode* two) const {
+ return one->Equals(*two);
+ }
+ };
- struct TEqual {
- bool operator()(const TTypeAnnotationNode* one, const TTypeAnnotationNode* two) const {
- return one->Equals(*two);
- }
- };
-
typedef std::vector<const TTypeAnnotationNode*> TListType;
- typedef std::span<const TTypeAnnotationNode*> TSpanType;
-protected:
- template <typename T>
- static ui32 CombineFlags(const T& items) {
- ui32 flags = 0;
- for (auto& item : items) {
- flags |= item->GetFlags();
- }
-
- return flags;
- }
-
+ typedef std::span<const TTypeAnnotationNode*> TSpanType;
+protected:
+ template <typename T>
+ static ui32 CombineFlags(const T& items) {
+ ui32 flags = 0;
+ for (auto& item : items) {
+ flags |= item->GetFlags();
+ }
+
+ return flags;
+ }
+
private:
const ETypeAnnotationKind Kind;
- const ui32 Flags;
- const ui64 Hash;
+ const ui32 Flags;
+ const ui64 Hash;
};
class TUnitExprType : public TTypeAnnotationNode {
-public:
+public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Unit;
- TUnitExprType(ui64 hash)
+ TUnitExprType(ui64 hash)
: TTypeAnnotationNode(KindValue,
- TypeNonComputable | TypeNonPersistable, hash)
+ TypeNonComputable | TypeNonPersistable, hash)
{
}
- static ui64 MakeHash() {
- return TypeHashMagic | (ui64)ETypeAnnotationKind::Unit;
+ static ui64 MakeHash() {
+ return TypeHashMagic | (ui64)ETypeAnnotationKind::Unit;
}
bool operator==(const TUnitExprType& other) const {
@@ -300,16 +300,16 @@ public:
: TTypeAnnotationNode(KindValue, CombineFlags(items), hash)
, Items(items)
{
- }
-
+ }
+
static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tuple;
- hash = StreamHash(items.size(), hash);
- for (const auto& item : items) {
- hash = StreamHash(item->GetHash(), hash);
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tuple;
+ hash = StreamHash(items.size(), hash);
+ for (const auto& item : items) {
+ hash = StreamHash(item->GetHash(), hash);
}
-
- return hash;
+
+ return hash;
}
size_t GetSize() const {
@@ -341,55 +341,55 @@ private:
TTypeAnnotationNode::TListType Items;
};
-class TMultiExprType : public TTypeAnnotationNode {
-public:
- static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Multi;
-
- TMultiExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
- : TTypeAnnotationNode(KindValue, CombineFlags(items), hash)
- , Items(items)
- {
- }
-
- static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Multi;
- hash = StreamHash(items.size(), hash);
- for (const auto& item : items) {
- hash = StreamHash(item->GetHash(), hash);
- }
-
- return hash;
- }
-
- size_t GetSize() const {
- return Items.size();
- }
-
- const TTypeAnnotationNode::TListType& GetItems() const {
- return Items;
- }
-
- bool operator==(const TMultiExprType& other) const {
- if (GetSize() != other.GetSize()) {
- return false;
- }
-
- for (ui32 i = 0, e = GetSize(); i < e; ++i) {
- if (GetItems()[i] != other.GetItems()[i]) {
- return false;
- }
- }
-
- return true;
- }
-
- bool Validate(TPosition position, TExprContext& ctx) const;
- bool Validate(TPositionHandle position, TExprContext& ctx) const;
-
-private:
- TTypeAnnotationNode::TListType Items;
-};
-
+class TMultiExprType : public TTypeAnnotationNode {
+public:
+ static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Multi;
+
+ TMultiExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
+ : TTypeAnnotationNode(KindValue, CombineFlags(items), hash)
+ , Items(items)
+ {
+ }
+
+ static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Multi;
+ hash = StreamHash(items.size(), hash);
+ for (const auto& item : items) {
+ hash = StreamHash(item->GetHash(), hash);
+ }
+
+ return hash;
+ }
+
+ size_t GetSize() const {
+ return Items.size();
+ }
+
+ const TTypeAnnotationNode::TListType& GetItems() const {
+ return Items;
+ }
+
+ bool operator==(const TMultiExprType& other) const {
+ if (GetSize() != other.GetSize()) {
+ return false;
+ }
+
+ for (ui32 i = 0, e = GetSize(); i < e; ++i) {
+ if (GetItems()[i] != other.GetItems()[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool Validate(TPosition position, TExprContext& ctx) const;
+ bool Validate(TPositionHandle position, TExprContext& ctx) const;
+
+private:
+ TTypeAnnotationNode::TListType Items;
+};
+
struct TExprContext;
@@ -400,20 +400,20 @@ class TItemExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Item;
- TItemExprType(ui64 hash, const TStringBuf& name, const TTypeAnnotationNode* itemType)
+ TItemExprType(ui64 hash, const TStringBuf& name, const TTypeAnnotationNode* itemType)
: TTypeAnnotationNode(KindValue, itemType->GetFlags(), hash)
, Name(name)
, ItemType(itemType)
{
}
- static ui64 MakeHash(const TStringBuf& name, const TTypeAnnotationNode* itemType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Item;
+ static ui64 MakeHash(const TStringBuf& name, const TTypeAnnotationNode* itemType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Item;
hash = StreamHash(name.size(), hash);
hash = StreamHash(name.data(), name.size(), hash);
- return StreamHash(itemType->GetHash(), hash);
- }
-
+ return StreamHash(itemType->GetHash(), hash);
+ }
+
bool Validate(TPosition position, TExprContext& ctx) const;
bool Validate(TPositionHandle position, TExprContext& ctx) const;
@@ -431,7 +431,7 @@ public:
private:
const TStringBuf Name;
- const TTypeAnnotationNode* ItemType;
+ const TTypeAnnotationNode* ItemType;
};
class TStructExprType : public TTypeAnnotationNode {
@@ -456,17 +456,17 @@ public:
: TTypeAnnotationNode(KindValue, TypeNonComparable | CombineFlags(items), hash)
, Items(items)
{
- }
-
+ }
+
static ui64 MakeHash(const TVector<const TItemExprType*>& items) {
- Y_VERIFY_DEBUG(IsSorted(items.begin(), items.end(), TItemLess()));
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Struct;
- hash = StreamHash(items.size(), hash);
- for (const auto& item : items) {
- hash = StreamHash(item->GetHash(), hash);
+ Y_VERIFY_DEBUG(IsSorted(items.begin(), items.end(), TItemLess()));
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Struct;
+ hash = StreamHash(items.size(), hash);
+ for (const auto& item : items) {
+ hash = StreamHash(item->GetHash(), hash);
}
- return hash;
+ return hash;
}
bool Validate(TPosition position, TExprContext& ctx) const;
@@ -489,15 +489,15 @@ public:
return it - Items.begin();
}
- const TTypeAnnotationNode* FindItemType(const TStringBuf& name) const {
- const auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
- if (it == Items.end() || (*it)->GetName() != name) {
- return nullptr;
- }
-
- return (*it)->GetItemType();
- }
-
+ const TTypeAnnotationNode* FindItemType(const TStringBuf& name) const {
+ const auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
+ if (it == Items.end() || (*it)->GetName() != name) {
+ return nullptr;
+ }
+
+ return (*it)->GetItemType();
+ }
+
TMaybe<TStringBuf> FindMistype(const TStringBuf& name) const {
for (const auto& item: Items) {
if (NLevenshtein::Distance(name, item->GetName()) < DefaultMistypeDistance) {
@@ -529,17 +529,17 @@ class TListExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::List;
- TListExprType(ui64 hash, const TTypeAnnotationNode* itemType)
+ TListExprType(ui64 hash, const TTypeAnnotationNode* itemType)
: TTypeAnnotationNode(KindValue, itemType->GetFlags(), hash)
, ItemType(itemType)
{
}
- static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::List;
- return StreamHash(itemType->GetHash(), hash);
- }
-
+ static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::List;
+ return StreamHash(itemType->GetHash(), hash);
+ }
+
const TTypeAnnotationNode* GetItemType() const {
return ItemType;
}
@@ -549,24 +549,24 @@ public:
}
private:
- const TTypeAnnotationNode* ItemType;
+ const TTypeAnnotationNode* ItemType;
};
class TStreamExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Stream;
- TStreamExprType(ui64 hash, const TTypeAnnotationNode* itemType)
+ TStreamExprType(ui64 hash, const TTypeAnnotationNode* itemType)
: TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash)
, ItemType(itemType)
{
}
- static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Stream;
- return StreamHash(itemType->GetHash(), hash);
- }
-
+ static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Stream;
+ return StreamHash(itemType->GetHash(), hash);
+ }
+
const TTypeAnnotationNode* GetItemType() const {
return ItemType;
}
@@ -576,36 +576,36 @@ public:
}
private:
- const TTypeAnnotationNode* ItemType;
+ const TTypeAnnotationNode* ItemType;
+};
+
+class TFlowExprType : public TTypeAnnotationNode {
+public:
+ static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Flow;
+
+ TFlowExprType(ui64 hash, const TTypeAnnotationNode* itemType)
+ : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash)
+ , ItemType(itemType)
+ {
+ }
+
+ static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Flow;
+ return StreamHash(itemType->GetHash(), hash);
+ }
+
+ const TTypeAnnotationNode* GetItemType() const {
+ return ItemType;
+ }
+
+ bool operator==(const TFlowExprType& other) const {
+ return GetItemType() == other.GetItemType();
+ }
+
+private:
+ const TTypeAnnotationNode* ItemType;
};
-class TFlowExprType : public TTypeAnnotationNode {
-public:
- static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Flow;
-
- TFlowExprType(ui64 hash, const TTypeAnnotationNode* itemType)
- : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash)
- , ItemType(itemType)
- {
- }
-
- static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Flow;
- return StreamHash(itemType->GetHash(), hash);
- }
-
- const TTypeAnnotationNode* GetItemType() const {
- return ItemType;
- }
-
- bool operator==(const TFlowExprType& other) const {
- return GetItemType() == other.GetItemType();
- }
-
-private:
- const TTypeAnnotationNode* ItemType;
-};
-
class TDataExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Data;
@@ -613,8 +613,8 @@ public:
TDataExprType(ui64 hash, EDataSlot slot)
: TTypeAnnotationNode(KindValue, GetFlags(slot), hash)
, Slot(slot)
- {
- }
+ {
+ }
static ui32 GetFlags(EDataSlot slot) {
ui32 ret = TypeHasManyValues;
@@ -639,12 +639,12 @@ public:
}
static ui64 MakeHash(EDataSlot slot) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Data;
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Data;
auto dataType = NUdf::GetDataTypeInfo(slot).Name;
hash = StreamHash(dataType.size(), hash);
return StreamHash(dataType.data(), dataType.size(), hash);
- }
-
+ }
+
EDataSlot GetSlot() const {
return Slot;
}
@@ -661,52 +661,52 @@ private:
EDataSlot Slot;
};
-class TDataExprParamsType : public TDataExprType {
-public:
+class TDataExprParamsType : public TDataExprType {
+public:
TDataExprParamsType(ui64 hash, EDataSlot slot, const TStringBuf& one, const TStringBuf& two)
: TDataExprType(hash, slot), One(one), Two(two)
- {}
-
+ {}
+
static ui64 MakeHash(EDataSlot slot, const TStringBuf& one, const TStringBuf& two) {
auto hash = TDataExprType::MakeHash(slot);
hash = StreamHash(one.size(), hash);
hash = StreamHash(one.data(), one.size(), hash);
hash = StreamHash(two.size(), hash);
hash = StreamHash(two.data(), two.size(), hash);
- return hash;
- }
-
- const TStringBuf& GetParamOne() const {
- return One;
- }
-
- const TStringBuf& GetParamTwo() const {
- return Two;
- }
-
- bool operator==(const TDataExprParamsType& other) const {
+ return hash;
+ }
+
+ const TStringBuf& GetParamOne() const {
+ return One;
+ }
+
+ const TStringBuf& GetParamTwo() const {
+ return Two;
+ }
+
+ bool operator==(const TDataExprParamsType& other) const {
return GetSlot() == other.GetSlot() && GetParamOne() == other.GetParamOne() && GetParamTwo() == other.GetParamTwo();
- }
-
- bool Validate(TPosition position, TExprContext& ctx) const;
+ }
+
+ bool Validate(TPosition position, TExprContext& ctx) const;
bool Validate(TPositionHandle position, TExprContext& ctx) const;
-private:
- const TStringBuf One, Two;
-};
-
+private:
+ const TStringBuf One, Two;
+};
+
class TWorldExprType : public TTypeAnnotationNode {
-public:
+public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::World;
- TWorldExprType(ui64 hash)
+ TWorldExprType(ui64 hash)
: TTypeAnnotationNode(KindValue,
- TypeNonComposable | TypeNonComputable | TypeNonPersistable | TypeNonInspectable, hash)
+ TypeNonComposable | TypeNonComputable | TypeNonPersistable | TypeNonInspectable, hash)
{
}
- static ui64 MakeHash() {
- return TypeHashMagic | (ui64)ETypeAnnotationKind::World;
+ static ui64 MakeHash() {
+ return TypeHashMagic | (ui64)ETypeAnnotationKind::World;
}
bool operator==(const TWorldExprType& other) const {
@@ -719,7 +719,7 @@ class TOptionalExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Optional;
- TOptionalExprType(ui64 hash, const TTypeAnnotationNode* itemType)
+ TOptionalExprType(ui64 hash, const TTypeAnnotationNode* itemType)
: TTypeAnnotationNode(KindValue, GetFlags(itemType), hash)
, ItemType(itemType)
{
@@ -735,11 +735,11 @@ public:
return ret;
}
- static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Optional;
- return StreamHash(itemType->GetHash(), hash);
- }
-
+ static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Optional;
+ return StreamHash(itemType->GetHash(), hash);
+ }
+
const TTypeAnnotationNode* GetItemType() const {
return ItemType;
}
@@ -749,24 +749,24 @@ public:
}
private:
- const TTypeAnnotationNode* ItemType;
+ const TTypeAnnotationNode* ItemType;
};
class TVariantExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Variant;
- TVariantExprType(ui64 hash, const TTypeAnnotationNode* underlyingType)
+ TVariantExprType(ui64 hash, const TTypeAnnotationNode* underlyingType)
: TTypeAnnotationNode(KindValue, MakeFlags(underlyingType), hash)
, UnderlyingType(underlyingType)
{
}
- static ui64 MakeHash(const TTypeAnnotationNode* underlyingType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Variant;
- return StreamHash(underlyingType->GetHash(), hash);
- }
-
+ static ui64 MakeHash(const TTypeAnnotationNode* underlyingType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Variant;
+ return StreamHash(underlyingType->GetHash(), hash);
+ }
+
const TTypeAnnotationNode* GetUnderlyingType() const {
return UnderlyingType;
}
@@ -781,22 +781,22 @@ public:
static ui32 MakeFlags(const TTypeAnnotationNode* underlyingType);
private:
- const TTypeAnnotationNode* UnderlyingType;
+ const TTypeAnnotationNode* UnderlyingType;
};
class TTypeExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Type;
- TTypeExprType(ui64 hash, const TTypeAnnotationNode* type)
- : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable, hash)
+ TTypeExprType(ui64 hash, const TTypeAnnotationNode* type)
+ : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable, hash)
, Type(type)
- {
- }
+ {
+ }
- static ui64 MakeHash(const TTypeAnnotationNode* type) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Type;
- return StreamHash(type->GetHash(), hash);
+ static ui64 MakeHash(const TTypeAnnotationNode* type) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Type;
+ return StreamHash(type->GetHash(), hash);
}
const TTypeAnnotationNode* GetType() const {
@@ -808,25 +808,25 @@ public:
}
private:
- const TTypeAnnotationNode* Type;
+ const TTypeAnnotationNode* Type;
};
class TDictExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Dict;
- TDictExprType(ui64 hash, const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType)
+ TDictExprType(ui64 hash, const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType)
: TTypeAnnotationNode(KindValue, TypeNonComparable | keyType->GetFlags() | payloadType->GetFlags(), hash)
, KeyType(keyType)
, PayloadType(payloadType)
{
}
- static ui64 MakeHash(const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Dict;
- return StreamHash(StreamHash(keyType->GetHash(), hash), payloadType->GetHash());
- }
-
+ static ui64 MakeHash(const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Dict;
+ return StreamHash(StreamHash(keyType->GetHash(), hash), payloadType->GetHash());
+ }
+
bool Validate(TPosition position, TExprContext& ctx) const;
bool Validate(TPositionHandle position, TExprContext& ctx) const;
@@ -844,21 +844,21 @@ public:
}
private:
- const TTypeAnnotationNode* KeyType;
- const TTypeAnnotationNode* PayloadType;
+ const TTypeAnnotationNode* KeyType;
+ const TTypeAnnotationNode* PayloadType;
};
class TVoidExprType : public TTypeAnnotationNode {
-public:
+public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Void;
- TVoidExprType(ui64 hash)
+ TVoidExprType(ui64 hash)
: TTypeAnnotationNode(KindValue, 0, hash)
{
}
- static ui64 MakeHash() {
- return TypeHashMagic | (ui64)ETypeAnnotationKind::Void;
+ static ui64 MakeHash() {
+ return TypeHashMagic | (ui64)ETypeAnnotationKind::Void;
}
bool operator==(const TVoidExprType& other) const {
@@ -924,24 +924,24 @@ public:
IndexByName.insert({ arg.Name, i });
}
}
- }
+ }
static ui64 MakeHash(const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
- , size_t optionalArgumentsCount, const TStringBuf& payload) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Callable;
- hash = StreamHash(returnType->GetHash(), hash);
- hash = StreamHash(arguments.size(), hash);
- for (const auto& arg : arguments) {
+ , size_t optionalArgumentsCount, const TStringBuf& payload) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Callable;
+ hash = StreamHash(returnType->GetHash(), hash);
+ hash = StreamHash(arguments.size(), hash);
+ for (const auto& arg : arguments) {
hash = StreamHash(arg.Name.size(), hash);
hash = StreamHash(arg.Name.data(), arg.Name.size(), hash);
- hash = StreamHash(arg.Flags, hash);
- hash = StreamHash(arg.Type->GetHash(), hash);
- }
-
- hash = StreamHash(optionalArgumentsCount, hash);
+ hash = StreamHash(arg.Flags, hash);
+ hash = StreamHash(arg.Type->GetHash(), hash);
+ }
+
+ hash = StreamHash(optionalArgumentsCount, hash);
hash = StreamHash(payload.size(), hash);
hash = StreamHash(payload.data(), payload.size(), hash);
- return hash;
+ return hash;
}
const TTypeAnnotationNode* GetReturnType() const {
@@ -1000,13 +1000,13 @@ public:
private:
static ui32 MakeFlags(const TTypeAnnotationNode* returnType) {
- ui32 flags = TypeNonPersistable;
- flags |= returnType->GetFlags();
- return flags;
- }
-
-private:
- const TTypeAnnotationNode* ReturnType;
+ ui32 flags = TypeNonPersistable;
+ flags |= returnType->GetFlags();
+ return flags;
+ }
+
+private:
+ const TTypeAnnotationNode* ReturnType;
TVector<TArgumentInfo> Arguments;
const size_t OptionalArgumentsCount;
const TStringBuf Payload;
@@ -1014,15 +1014,15 @@ private:
};
class TGenericExprType : public TTypeAnnotationNode {
-public:
+public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Generic;
- TGenericExprType(ui64 hash)
+ TGenericExprType(ui64 hash)
: TTypeAnnotationNode(KindValue, TypeNonComputable, hash)
{
}
- static ui64 MakeHash() {
+ static ui64 MakeHash() {
return TypeHashMagic | (ui64)ETypeAnnotationKind::Generic;
}
@@ -1036,17 +1036,17 @@ class TResourceExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Resource;
- TResourceExprType(ui64 hash, const TStringBuf& tag)
+ TResourceExprType(ui64 hash, const TStringBuf& tag)
: TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeHasManyValues, hash)
, Tag(tag)
{}
- static ui64 MakeHash(const TStringBuf& tag) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Resource;
+ static ui64 MakeHash(const TStringBuf& tag) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Resource;
hash = StreamHash(tag.size(), hash);
return StreamHash(tag.data(), tag.size(), hash);
- }
-
+ }
+
const TStringBuf& GetTag() const {
return Tag;
}
@@ -1063,19 +1063,19 @@ class TTaggedExprType : public TTypeAnnotationNode {
public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Tagged;
- TTaggedExprType(ui64 hash, const TTypeAnnotationNode* baseType, const TStringBuf& tag)
+ TTaggedExprType(ui64 hash, const TTypeAnnotationNode* baseType, const TStringBuf& tag)
: TTypeAnnotationNode(KindValue, baseType->GetFlags(), hash)
, BaseType(baseType)
, Tag(tag)
{}
- static ui64 MakeHash(const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
- ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tagged;
- hash = StreamHash(baseType->GetHash(), hash);
+ static ui64 MakeHash(const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
+ ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tagged;
+ hash = StreamHash(baseType->GetHash(), hash);
hash = StreamHash(tag.size(), hash);
return StreamHash(tag.data(), tag.size(), hash);
- }
-
+ }
+
const TStringBuf& GetTag() const {
return Tag;
}
@@ -1092,7 +1092,7 @@ public:
bool Validate(TPositionHandle position, TExprContext& ctx) const;
private:
- const TTypeAnnotationNode* BaseType;
+ const TTypeAnnotationNode* BaseType;
const TStringBuf Tag;
};
@@ -1106,9 +1106,9 @@ public:
{}
static ui64 MakeHash(const TIssue& error) {
- return error.Hash();
- }
-
+ return error.Hash();
+ }
+
const TIssue& GetError() const {
return Error;
}
@@ -1230,73 +1230,73 @@ inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const {
case ETypeAnnotationKind::Stream:
return static_cast<const TStreamExprType&>(*this) == static_cast<const TStreamExprType&>(node);
- case ETypeAnnotationKind::Flow:
- return static_cast<const TFlowExprType&>(*this) == static_cast<const TFlowExprType&>(node);
-
+ case ETypeAnnotationKind::Flow:
+ return static_cast<const TFlowExprType&>(*this) == static_cast<const TFlowExprType&>(node);
+
case ETypeAnnotationKind::EmptyList:
return static_cast<const TEmptyListExprType&>(*this) == static_cast<const TEmptyListExprType&>(node);
case ETypeAnnotationKind::EmptyDict:
return static_cast<const TEmptyDictExprType&>(*this) == static_cast<const TEmptyDictExprType&>(node);
- case ETypeAnnotationKind::Multi:
- return static_cast<const TMultiExprType&>(*this) == static_cast<const TMultiExprType&>(node);
-
+ case ETypeAnnotationKind::Multi:
+ return static_cast<const TMultiExprType&>(*this) == static_cast<const TMultiExprType&>(node);
+
case ETypeAnnotationKind::LastType:
YQL_ENSURE(false, "Incorrect type");
}
- return false;
+ return false;
}
inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const {
switch (Kind) {
case ETypeAnnotationKind::Unit:
- return visitor.Visit(static_cast<const TUnitExprType&>(*this));
+ return visitor.Visit(static_cast<const TUnitExprType&>(*this));
case ETypeAnnotationKind::Tuple:
- return visitor.Visit(static_cast<const TTupleExprType&>(*this));
+ return visitor.Visit(static_cast<const TTupleExprType&>(*this));
case ETypeAnnotationKind::Struct:
- return visitor.Visit(static_cast<const TStructExprType&>(*this));
+ return visitor.Visit(static_cast<const TStructExprType&>(*this));
case ETypeAnnotationKind::Item:
- return visitor.Visit(static_cast<const TItemExprType&>(*this));
+ return visitor.Visit(static_cast<const TItemExprType&>(*this));
case ETypeAnnotationKind::List:
- return visitor.Visit(static_cast<const TListExprType&>(*this));
+ return visitor.Visit(static_cast<const TListExprType&>(*this));
case ETypeAnnotationKind::Data:
- return visitor.Visit(static_cast<const TDataExprType&>(*this));
+ return visitor.Visit(static_cast<const TDataExprType&>(*this));
case ETypeAnnotationKind::World:
- return visitor.Visit(static_cast<const TWorldExprType&>(*this));
+ return visitor.Visit(static_cast<const TWorldExprType&>(*this));
case ETypeAnnotationKind::Optional:
- return visitor.Visit(static_cast<const TOptionalExprType&>(*this));
+ return visitor.Visit(static_cast<const TOptionalExprType&>(*this));
case ETypeAnnotationKind::Type:
- return visitor.Visit(static_cast<const TTypeExprType&>(*this));
+ return visitor.Visit(static_cast<const TTypeExprType&>(*this));
case ETypeAnnotationKind::Dict:
- return visitor.Visit(static_cast<const TDictExprType&>(*this));
+ return visitor.Visit(static_cast<const TDictExprType&>(*this));
case ETypeAnnotationKind::Void:
- return visitor.Visit(static_cast<const TVoidExprType&>(*this));
+ return visitor.Visit(static_cast<const TVoidExprType&>(*this));
case ETypeAnnotationKind::Null:
return visitor.Visit(static_cast<const TNullExprType&>(*this));
case ETypeAnnotationKind::Callable:
- return visitor.Visit(static_cast<const TCallableExprType&>(*this));
+ return visitor.Visit(static_cast<const TCallableExprType&>(*this));
case ETypeAnnotationKind::Generic:
- return visitor.Visit(static_cast<const TGenericExprType&>(*this));
+ return visitor.Visit(static_cast<const TGenericExprType&>(*this));
case ETypeAnnotationKind::Resource:
- return visitor.Visit(static_cast<const TResourceExprType&>(*this));
+ return visitor.Visit(static_cast<const TResourceExprType&>(*this));
case ETypeAnnotationKind::Tagged:
- return visitor.Visit(static_cast<const TTaggedExprType&>(*this));
+ return visitor.Visit(static_cast<const TTaggedExprType&>(*this));
case ETypeAnnotationKind::Error:
- return visitor.Visit(static_cast<const TErrorExprType&>(*this));
+ return visitor.Visit(static_cast<const TErrorExprType&>(*this));
case ETypeAnnotationKind::Variant:
- return visitor.Visit(static_cast<const TVariantExprType&>(*this));
+ return visitor.Visit(static_cast<const TVariantExprType&>(*this));
case ETypeAnnotationKind::Stream:
- return visitor.Visit(static_cast<const TStreamExprType&>(*this));
- case ETypeAnnotationKind::Flow:
- return visitor.Visit(static_cast<const TFlowExprType&>(*this));
+ return visitor.Visit(static_cast<const TStreamExprType&>(*this));
+ case ETypeAnnotationKind::Flow:
+ return visitor.Visit(static_cast<const TFlowExprType&>(*this));
case ETypeAnnotationKind::EmptyList:
return visitor.Visit(static_cast<const TEmptyListExprType&>(*this));
case ETypeAnnotationKind::EmptyDict:
return visitor.Visit(static_cast<const TEmptyDictExprType&>(*this));
- case ETypeAnnotationKind::Multi:
- return visitor.Visit(static_cast<const TMultiExprType&>(*this));
+ case ETypeAnnotationKind::Multi:
+ return visitor.Visit(static_cast<const TMultiExprType&>(*this));
case ETypeAnnotationKind::LastType:
YQL_ENSURE(false, "Incorrect type");
}
@@ -1318,16 +1318,16 @@ private:
};
public:
- typedef TIntrusivePtr<TExprNode> TPtr;
+ typedef TIntrusivePtr<TExprNode> TPtr;
typedef std::vector<TPtr> TListType;
typedef TArrayRef<const TPtr> TChildrenType;
-
- struct TPtrHash : private std::hash<const TExprNode*> {
- size_t operator()(const TPtr& p) const {
- return std::hash<const TExprNode*>::operator()(p.Get());
- }
- };
-
+
+ struct TPtrHash : private std::hash<const TExprNode*> {
+ size_t operator()(const TPtr& p) const {
+ return std::hash<const TExprNode*>::operator()(p.Get());
+ }
+ };
+
#define YQL_EXPR_NODE_TYPE_MAP(xx) \
xx(List, 0) \
xx(Atom, 1) \
@@ -1362,49 +1362,49 @@ public:
YQL_EXPR_NODE_STATE_MAP(ENUM_VALUE_GEN)
};
- static TPtr GetResult(const TPtr& node) {
- return node->Type() == Callable ? node->Result : node;
- }
-
- const TExprNode& GetResult() const {
- ENSURE_NOT_DELETED
- return Type() == Callable ? *Result : *this;
+ static TPtr GetResult(const TPtr& node) {
+ return node->Type() == Callable ? node->Result : node;
+ }
+
+ const TExprNode& GetResult() const {
+ ENSURE_NOT_DELETED
+ return Type() == Callable ? *Result : *this;
}
bool HasResult() const {
- ENSURE_NOT_DELETED
- return Type() != Callable || bool(Result);
+ ENSURE_NOT_DELETED
+ return Type() != Callable || bool(Result);
}
- void SetResult(TPtr&& result) {
- ENSURE_NOT_DELETED
+ void SetResult(TPtr&& result) {
+ ENSURE_NOT_DELETED
ENSURE_NOT_FROZEN
- Result = std::move(result);
+ Result = std::move(result);
}
bool IsCallable(const TStringBuf& name) const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::Callable && Content() == name;
}
- bool IsCallable(const std::initializer_list<std::string_view>& names) const {
- ENSURE_NOT_DELETED
- return Type() == TExprNode::Callable && names.end() != std::find(names.begin(), names.end(), Content());
- }
-
+ bool IsCallable(const std::initializer_list<std::string_view>& names) const {
+ ENSURE_NOT_DELETED
+ return Type() == TExprNode::Callable && names.end() != std::find(names.begin(), names.end(), Content());
+ }
+
template <class TKey>
bool IsCallable(const THashSet<TKey>& names) const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::Callable && names.contains(Content());
}
bool IsCallable() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::Callable;
}
bool IsAtom() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::Atom;
}
@@ -1414,12 +1414,12 @@ public:
}
bool IsAtom(const TStringBuf& content) const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::Atom && Content() == content;
}
bool IsList() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Type() == TExprNode::List;
}
@@ -1434,38 +1434,38 @@ public:
}
bool IsComposable() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return !IsLambda() && TypeAnnotation_->IsComposable();
}
bool IsPersistable() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return !IsLambda() && TypeAnnotation_->IsPersistable();
}
bool IsComputable() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return !IsLambda() && TypeAnnotation_->IsComputable();
}
bool IsInspectable() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return !IsLambda() && TypeAnnotation_->IsInspectable();
}
- bool ForDisclosing() const {
- ENSURE_NOT_DELETED
- return Type() == TExprNode::List && ShallBeDisclosed;
- }
-
- void SetDisclosing() {
- ENSURE_NOT_DELETED
- Y_ENSURE(Type() == TExprNode::List, "Must be list.");
- ShallBeDisclosed = true;
- }
-
+ bool ForDisclosing() const {
+ ENSURE_NOT_DELETED
+ return Type() == TExprNode::List && ShallBeDisclosed;
+ }
+
+ void SetDisclosing() {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(Type() == TExprNode::List, "Must be list.");
+ ShallBeDisclosed = true;
+ }
+
ui32 GetFlagsToCompare() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
ui32 ret = Flags();
if ((ret & TNodeFlags::BinaryContent) == 0) {
ret |= TNodeFlags::ArbitraryContent | TNodeFlags::MultilineContent;
@@ -1477,7 +1477,7 @@ public:
TString Dump() const;
bool StartsExecution() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return State == EState::ExecutionComplete
|| State == EState::ExecutionInProgress
|| State == EState::ExecutionRequired
@@ -1485,165 +1485,165 @@ public:
}
bool IsComplete() const {
- YQL_ENSURE(HasLambdaScope);
- return !OuterLambda;
+ YQL_ENSURE(HasLambdaScope);
+ return !OuterLambda;
}
- void Ref() {
+ void Ref() {
ENSURE_NOT_DELETED
ENSURE_NOT_FROZEN
Y_ENSURE(RefCount_ < Max<ui32>());
- ++RefCount_;
- }
-
- void UnRef() {
+ ++RefCount_;
+ }
+
+ void UnRef() {
ENSURE_NOT_DELETED
ENSURE_NOT_FROZEN
- if (!--RefCount_) {
- Result.Reset();
- Children_.clear();
+ if (!--RefCount_) {
+ Result.Reset();
+ Children_.clear();
Constraints_.Clear();
MarkDead();
- }
- }
-
- ui32 UseCount() const { return RefCount_; }
- bool Unique() const { return 1U == UseCount(); }
-
+ }
+ }
+
+ ui32 UseCount() const { return RefCount_; }
+ bool Unique() const { return 1U == UseCount(); }
+
bool Dead() const {
return ExprFlags_ & TExprFlags::Dead;
}
TPositionHandle Pos() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Position_;
}
TPosition Pos(const TExprContext& ctx) const;
EType Type() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return (EType)Type_;
}
TListType::size_type ChildrenSize() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Children_.size();
}
TExprNode* Child(ui32 index) const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
+ Y_ENSURE(index < Children_.size(), "index out of range");
+ return Children_[index].Get();
+ }
+
+ TPtr ChildPtr(ui32 index) const {
+ ENSURE_NOT_DELETED
Y_ENSURE(index < Children_.size(), "index out of range");
- return Children_[index].Get();
- }
-
- TPtr ChildPtr(ui32 index) const {
- ENSURE_NOT_DELETED
- Y_ENSURE(index < Children_.size(), "index out of range");
return Children_[index];
}
- TPtr& ChildRef(ui32 index) {
- ENSURE_NOT_DELETED
+ TPtr& ChildRef(ui32 index) {
+ ENSURE_NOT_DELETED
ENSURE_NOT_FROZEN
Y_ENSURE(index < Children_.size(), "index out of range");
return Children_[index];
}
- const TExprNode& Head() const {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return *Children_.front();
- }
-
- TExprNode& Head() {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return *Children_.front();
- }
-
- TPtr HeadPtr() const {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return Children_.front();
- }
-
- TPtr& HeadRef() {
- ENSURE_NOT_DELETED
- ENSURE_NOT_FROZEN
- Y_ENSURE(!Children_.empty(), "no children");
- return Children_.front();
- }
-
- const TExprNode& Tail() const {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return *Children_.back();
- }
-
- TExprNode& Tail() {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return *Children_.back();
- }
-
- TPtr TailPtr() const {
- ENSURE_NOT_DELETED
- Y_ENSURE(!Children_.empty(), "no children");
- return Children_.back();
- }
-
- TPtr& TailRef() {
- ENSURE_NOT_DELETED
- ENSURE_NOT_FROZEN
- Y_ENSURE(!Children_.empty(), "no children");
- return Children_.back();
- }
-
+ const TExprNode& Head() const {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return *Children_.front();
+ }
+
+ TExprNode& Head() {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return *Children_.front();
+ }
+
+ TPtr HeadPtr() const {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return Children_.front();
+ }
+
+ TPtr& HeadRef() {
+ ENSURE_NOT_DELETED
+ ENSURE_NOT_FROZEN
+ Y_ENSURE(!Children_.empty(), "no children");
+ return Children_.front();
+ }
+
+ const TExprNode& Tail() const {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return *Children_.back();
+ }
+
+ TExprNode& Tail() {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return *Children_.back();
+ }
+
+ TPtr TailPtr() const {
+ ENSURE_NOT_DELETED
+ Y_ENSURE(!Children_.empty(), "no children");
+ return Children_.back();
+ }
+
+ TPtr& TailRef() {
+ ENSURE_NOT_DELETED
+ ENSURE_NOT_FROZEN
+ Y_ENSURE(!Children_.empty(), "no children");
+ return Children_.back();
+ }
+
TChildrenType Children() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return TChildrenType(Children_.data(), Children_.size());
}
TListType ChildrenList() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Children_;
- }
-
+ }
+
void ChangeChildrenInplace(TListType&& newChildren) {
ENSURE_NOT_DELETED
Children_ = std::move(newChildren);
}
- template<class F>
- void ForEachChild(const F& visitor) const {
- for (const auto& child : Children_)
- visitor(*child);
- }
-
+ template<class F>
+ void ForEachChild(const F& visitor) const {
+ for (const auto& child : Children_)
+ visitor(*child);
+ }
+
TStringBuf Content() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return ContentUnchecked();
}
ui32 Flags() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Flags_;
}
- void NormalizeAtomFlags(const TExprNode& otherAtom) {
+ void NormalizeAtomFlags(const TExprNode& otherAtom) {
ENSURE_NOT_DELETED
ENSURE_NOT_FROZEN
- Y_ENSURE(Type_ == Atom && otherAtom.Type_ == Atom, "Expected atoms");
- Y_ENSURE((Flags_ & TNodeFlags::BinaryContent) ==
- (otherAtom.Flags_ & TNodeFlags::BinaryContent), "Mismatch binary atom flags");
- if (!(Flags_ & TNodeFlags::BinaryContent)) {
- Flags_ = Min(Flags_, otherAtom.Flags_);
+ Y_ENSURE(Type_ == Atom && otherAtom.Type_ == Atom, "Expected atoms");
+ Y_ENSURE((Flags_ & TNodeFlags::BinaryContent) ==
+ (otherAtom.Flags_ & TNodeFlags::BinaryContent), "Mismatch binary atom flags");
+ if (!(Flags_ & TNodeFlags::BinaryContent)) {
+ Flags_ = Min(Flags_, otherAtom.Flags_);
}
}
ui64 UniqueId() const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return UniqueId_;
}
@@ -1698,40 +1698,40 @@ public:
}
static TPtr NewAtom(ui64 uniqueId, TPositionHandle pos, const TStringBuf& content, ui32 flags) {
- return Make(pos, Atom, {}, content, flags, uniqueId);
+ return Make(pos, Atom, {}, content, flags, uniqueId);
}
static TPtr NewArgument(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name) {
- return Make(pos, Argument, {}, name, 0, uniqueId);
+ return Make(pos, Argument, {}, name, 0, uniqueId);
}
static TPtr NewArguments(ui64 uniqueId, TPositionHandle pos, TListType&& argNodes) {
return Make(pos, Arguments, std::move(argNodes), ZeroString, 0, uniqueId);
}
- static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TListType&& lambda) {
- return Make(pos, Lambda, std::move(lambda), ZeroString, 0, uniqueId);
- }
-
- static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TListType&& body) {
- TListType lambda(body.size() + 1U);
- lambda.front() = std::move(args);
- std::move(body.rbegin(), body.rend(), lambda.rbegin());
- return NewLambda(uniqueId, pos, std::move(lambda));
- }
-
+ static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TListType&& lambda) {
+ return Make(pos, Lambda, std::move(lambda), ZeroString, 0, uniqueId);
+ }
+
+ static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TListType&& body) {
+ TListType lambda(body.size() + 1U);
+ lambda.front() = std::move(args);
+ std::move(body.rbegin(), body.rend(), lambda.rbegin());
+ return NewLambda(uniqueId, pos, std::move(lambda));
+ }
+
static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TPtr&& body) {
TListType children(body ? 2 : 1);
- children.front() = std::move(args);
+ children.front() = std::move(args);
if (body) {
- children.back() = std::move(body);
+ children.back() = std::move(body);
}
- return NewLambda(uniqueId, pos, std::move(children));
+ return NewLambda(uniqueId, pos, std::move(children));
}
static TPtr NewWorld(ui64 uniqueId, TPositionHandle pos) {
- return Make(pos, World, {}, {}, 0, uniqueId);
+ return Make(pos, World, {}, {}, 0, uniqueId);
}
static TPtr NewList(ui64 uniqueId, TPositionHandle pos, TListType&& children) {
@@ -1739,33 +1739,33 @@ public:
}
static TPtr NewCallable(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name, TListType&& children) {
- return Make(pos, Callable, std::move(children), name, 0, uniqueId);
+ return Make(pos, Callable, std::move(children), name, 0, uniqueId);
}
- TPtr Clone(ui64 newUniqueId) const {
- ENSURE_NOT_DELETED
+ TPtr Clone(ui64 newUniqueId) const {
+ ENSURE_NOT_DELETED
return Make(Position_, (EType)Type_, TListType(Children_), Content(), Flags_, newUniqueId);
}
static TPtr NewNode(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
- return Make(position, type, std::move(children), content, flags, uniqueId);
- }
-
- TPtr ChangeContent(ui64 newUniqueId, const TStringBuf& content) const {
- ENSURE_NOT_DELETED
+ return Make(position, type, std::move(children), content, flags, uniqueId);
+ }
+
+ TPtr ChangeContent(ui64 newUniqueId, const TStringBuf& content) const {
+ ENSURE_NOT_DELETED
return Make(Position_, (EType)Type_, TListType(Children_), content, Flags_, newUniqueId);
- }
-
+ }
+
TPtr ChangeChildren(ui64 newUniqueId, TListType&& children) const {
- ENSURE_NOT_DELETED
+ ENSURE_NOT_DELETED
return Make(Position_, (EType)Type_, std::move(children), Content(), Flags_, newUniqueId);
}
- TPtr ChangeChild(ui64 newUniqueId, ui32 index, TPtr&& child) const {
- ENSURE_NOT_DELETED
+ TPtr ChangeChild(ui64 newUniqueId, ui32 index, TPtr&& child) const {
+ ENSURE_NOT_DELETED
Y_ENSURE(index < Children_.size(), "index out of range");
TListType newChildren(Children_);
- newChildren[index] = std::move(child);
+ newChildren[index] = std::move(child);
return Make(Position_, (EType)Type_, std::move(newChildren), Content(), Flags_, newUniqueId);
}
@@ -1798,30 +1798,30 @@ public:
}
ui64 GetHash() const {
- Y_VERIFY_DEBUG(HashAbove == HashBelow);
- return HashAbove;
+ Y_VERIFY_DEBUG(HashAbove == HashBelow);
+ return HashAbove;
}
void SetHash(ui64 hash) {
- HashAbove = HashBelow = hash;
- }
-
- ui64 GetHashAbove() const {
- return HashAbove;
- }
-
- void SetHashAbove(ui64 hash) {
- HashAbove = hash;
- }
-
- ui64 GetHashBelow() const {
- return HashBelow;
- }
-
- void SetHashBelow(ui64 hash) {
- HashBelow = hash;
- }
-
+ HashAbove = HashBelow = hash;
+ }
+
+ ui64 GetHashAbove() const {
+ return HashAbove;
+ }
+
+ void SetHashAbove(ui64 hash) {
+ HashAbove = hash;
+ }
+
+ ui64 GetHashBelow() const {
+ return HashBelow;
+ }
+
+ void SetHashBelow(ui64 hash) {
+ HashBelow = hash;
+ }
+
ui64 GetBloom() const {
return Bloom;
}
@@ -1830,23 +1830,23 @@ public:
Bloom = bloom;
}
- // return pair of outer and inner lambda.
- std::optional<std::pair<const TExprNode*, const TExprNode*>> GetDependencyScope() const {
- if (HasLambdaScope) {
- return std::make_pair(OuterLambda, InnerLambda);
+ // return pair of outer and inner lambda.
+ std::optional<std::pair<const TExprNode*, const TExprNode*>> GetDependencyScope() const {
+ if (HasLambdaScope) {
+ return std::make_pair(OuterLambda, InnerLambda);
}
- return std::nullopt;
+ return std::nullopt;
}
- void SetDependencyScope(const TExprNode* outerLambda, const TExprNode* innerLambda) {
- Y_VERIFY_DEBUG(outerLambda == innerLambda || outerLambda->GetLambdaLevel() < innerLambda->GetLambdaLevel(), "Wrong scope of closures.");
- HasLambdaScope = 1;
+ void SetDependencyScope(const TExprNode* outerLambda, const TExprNode* innerLambda) {
+ Y_VERIFY_DEBUG(outerLambda == innerLambda || outerLambda->GetLambdaLevel() < innerLambda->GetLambdaLevel(), "Wrong scope of closures.");
+ HasLambdaScope = 1;
OuterLambda = outerLambda;
- InnerLambda = innerLambda;
+ InnerLambda = innerLambda;
}
- ui16 GetLambdaLevel() const { return LambdaLevel; }
- void SetLambdaLevel(ui16 lambdaLevel) { LambdaLevel = lambdaLevel; }
+ ui16 GetLambdaLevel() const { return LambdaLevel; }
+ void SetLambdaLevel(ui16 lambdaLevel) { LambdaLevel = lambdaLevel; }
bool IsUsedInDependsOn() const {
YQL_ENSURE(Type() == EType::Argument);
@@ -1858,22 +1858,22 @@ public:
UsedInDependsOn = 1;
}
- void SetUnorderedChildren() {
- YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
- UnordChildren = 1;
- }
-
- bool UnorderedChildren() const {
- YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
- return bool(UnordChildren);
- }
-
- ~TExprNode() {
+ void SetUnorderedChildren() {
+ YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
+ UnordChildren = 1;
+ }
+
+ bool UnorderedChildren() const {
+ YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
+ return bool(UnordChildren);
+ }
+
+ ~TExprNode() {
Y_VERIFY(Dead(), "Node (id: %lu, type: %s, content: '%s') not dead on destruction.",
UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
Y_VERIFY(!UseCount(), "Node (id: %lu, type: %s, content: '%s') has non-zero use count on destruction.",
UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
- }
+ }
private:
static TPtr Make(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
@@ -1884,8 +1884,8 @@ private:
Y_ENSURE(children[i], "Unable to create node " << content << ": " << i << "th child is null");
}
return TPtr(new TExprNode(position, type, std::move(children), content.data(), ui32(content.size()), flags, uniqueId));
- }
-
+ }
+
TExprNode(TPositionHandle position, EType type, TListType&& children,
const char* content, ui32 contentSize, ui32 flags, ui64 uniqueId)
: Children_(std::move(children))
@@ -1897,10 +1897,10 @@ private:
, Flags_(flags)
, ExprFlags_(TExprFlags::Default)
, State(EState::Initial)
- , HasLambdaScope(0)
+ , HasLambdaScope(0)
, UsedInDependsOn(0)
- , UnordChildren(0)
- , ShallBeDisclosed(0)
+ , UnordChildren(0)
+ , ShallBeDisclosed(0)
{}
TExprNode(const TExprNode&) = delete;
@@ -1934,12 +1934,12 @@ private:
const char* Content_ = nullptr;
const TExprNode* OuterLambda = nullptr;
- const TExprNode* InnerLambda = nullptr;
+ const TExprNode* InnerLambda = nullptr;
TPtr Result;
- ui64 HashAbove = 0ULL;
- ui64 HashBelow = 0ULL;
+ ui64 HashAbove = 0ULL;
+ ui64 HashBelow = 0ULL;
ui64 Bloom = 0ULL;
const ui64 UniqueId_;
@@ -1963,68 +1963,68 @@ private:
ui8 ExprFlags_ : 2;
EState State : 4;
- ui8 HasLambdaScope : 1;
+ ui8 HasLambdaScope : 1;
ui8 UsedInDependsOn : 1;
- ui8 UnordChildren : 1;
- ui8 ShallBeDisclosed: 1;
+ ui8 UnordChildren : 1;
+ ui8 ShallBeDisclosed: 1;
};
};
-class TExportTable {
-public:
- using TSymbols = THashMap<TString, TExprNode::TPtr>;
-
- TExportTable() = default;
- TExportTable(TExprContext& ctx, TSymbols&& symbols)
- : Symbols_(std::move(symbols))
- , Ctx_(&ctx)
- {}
-
- const TSymbols& Symbols() const {
- return Symbols_;
- }
-
- TSymbols& Symbols(TExprContext& ctx) {
- if (Ctx_) {
- YQL_ENSURE(Ctx_ == &ctx);
- } else {
- Ctx_ = &ctx;
- }
- return Symbols_;
- }
-
- TExprContext& ExprCtx() const {
- YQL_ENSURE(Ctx_);
- return *Ctx_;
- }
-private:
- TSymbols Symbols_;
- TExprContext* Ctx_ = nullptr;
-};
-
-using TModulesTable = THashMap<TString, TExportTable>;
-
-class IModuleResolver {
-public:
- typedef std::shared_ptr<IModuleResolver> TPtr;
- virtual bool AddFromFile(const TStringBuf& file, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion) = 0;
+class TExportTable {
+public:
+ using TSymbols = THashMap<TString, TExprNode::TPtr>;
+
+ TExportTable() = default;
+ TExportTable(TExprContext& ctx, TSymbols&& symbols)
+ : Symbols_(std::move(symbols))
+ , Ctx_(&ctx)
+ {}
+
+ const TSymbols& Symbols() const {
+ return Symbols_;
+ }
+
+ TSymbols& Symbols(TExprContext& ctx) {
+ if (Ctx_) {
+ YQL_ENSURE(Ctx_ == &ctx);
+ } else {
+ Ctx_ = &ctx;
+ }
+ return Symbols_;
+ }
+
+ TExprContext& ExprCtx() const {
+ YQL_ENSURE(Ctx_);
+ return *Ctx_;
+ }
+private:
+ TSymbols Symbols_;
+ TExprContext* Ctx_ = nullptr;
+};
+
+using TModulesTable = THashMap<TString, TExportTable>;
+
+class IModuleResolver {
+public:
+ typedef std::shared_ptr<IModuleResolver> TPtr;
+ virtual bool AddFromFile(const TStringBuf& file, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion) = 0;
virtual bool AddFromUrl(const TStringBuf& file, const TStringBuf& url, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion) = 0;
- virtual bool AddFromMemory(const TStringBuf& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion) = 0;
- virtual bool AddFromMemory(const TStringBuf& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TString& moduleName, std::vector<TString>* exports = nullptr, std::vector<TString>* imports = nullptr) = 0;
- virtual bool Link(TExprContext& ctx) = 0;
- virtual void UpdateNextUniqueId(TExprContext& ctx) const = 0;
+ virtual bool AddFromMemory(const TStringBuf& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion) = 0;
+ virtual bool AddFromMemory(const TStringBuf& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TString& moduleName, std::vector<TString>* exports = nullptr, std::vector<TString>* imports = nullptr) = 0;
+ virtual bool Link(TExprContext& ctx) = 0;
+ virtual void UpdateNextUniqueId(TExprContext& ctx) const = 0;
virtual ui64 GetNextUniqueId() const = 0;
- virtual void RegisterPackage(const TString& package) = 0;
- virtual bool SetPackageDefaultVersion(const TString& package, ui32 version) = 0;
- virtual const TExportTable* GetModule(const TString& module) const = 0;
- /*
- Create new resolver which will use already collected modules in readonly manner.
- Parent resolver should be alive while using child due to raw data sharing.
- */
- virtual IModuleResolver::TPtr CreateMutableChild() const = 0;
- virtual ~IModuleResolver() = default;
-};
-
+ virtual void RegisterPackage(const TString& package) = 0;
+ virtual bool SetPackageDefaultVersion(const TString& package, ui32 version) = 0;
+ virtual const TExportTable* GetModule(const TString& module) const = 0;
+ /*
+ Create new resolver which will use already collected modules in readonly manner.
+ Parent resolver should be alive while using child due to raw data sharing.
+ */
+ virtual IModuleResolver::TPtr CreateMutableChild() const = 0;
+ virtual ~IModuleResolver() = default;
+};
+
struct TExprStep {
enum ELevel {
ExpandApplyForLambdas,
@@ -2068,21 +2068,21 @@ private:
template <typename T>
struct TMakeTypeImpl;
-template <class T>
-using TNodeMap = std::unordered_map<const TExprNode*, T>;
-using TNodeSet = std::unordered_set<const TExprNode*>;
-using TNodeOnNodeOwnedMap = TNodeMap<TExprNode::TPtr>;
-using TParentsMap = TNodeMap<TNodeSet>;
-
+template <class T>
+using TNodeMap = std::unordered_map<const TExprNode*, T>;
+using TNodeSet = std::unordered_set<const TExprNode*>;
+using TNodeOnNodeOwnedMap = TNodeMap<TExprNode::TPtr>;
+using TParentsMap = TNodeMap<TNodeSet>;
+
using TNodeMultiSet = std::unordered_multiset<const TExprNode*>;
using TParentsMultiMap = TNodeMap<TNodeMultiSet>;
-template <>
-struct TMakeTypeImpl<TVoidExprType> {
- static const TVoidExprType* Make(TExprContext& ctx);
-};
-
-template <>
+template <>
+struct TMakeTypeImpl<TVoidExprType> {
+ static const TVoidExprType* Make(TExprContext& ctx);
+};
+
+template <>
struct TMakeTypeImpl<TNullExprType> {
static const TNullExprType* Make(TExprContext& ctx);
};
@@ -2098,121 +2098,121 @@ struct TMakeTypeImpl<TEmptyDictExprType> {
};
template <>
-struct TMakeTypeImpl<TUnitExprType> {
- static const TUnitExprType* Make(TExprContext& ctx);
-};
-
-template <>
-struct TMakeTypeImpl<TWorldExprType> {
- static const TWorldExprType* Make(TExprContext& ctx);
-};
-
-template <>
-struct TMakeTypeImpl<TGenericExprType> {
- static const TGenericExprType* Make(TExprContext& ctx);
-};
-
-template <>
-struct TMakeTypeImpl<TItemExprType> {
- static const TItemExprType* Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType);
-};
-
-template <>
-struct TMakeTypeImpl<TListExprType> {
- static const TListExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
-};
-
-template <>
-struct TMakeTypeImpl<TOptionalExprType> {
- static const TOptionalExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
-};
-
-template <>
-struct TMakeTypeImpl<TVariantExprType> {
- static const TVariantExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType);
-};
-
-template <>
-struct TMakeTypeImpl<TErrorExprType> {
+struct TMakeTypeImpl<TUnitExprType> {
+ static const TUnitExprType* Make(TExprContext& ctx);
+};
+
+template <>
+struct TMakeTypeImpl<TWorldExprType> {
+ static const TWorldExprType* Make(TExprContext& ctx);
+};
+
+template <>
+struct TMakeTypeImpl<TGenericExprType> {
+ static const TGenericExprType* Make(TExprContext& ctx);
+};
+
+template <>
+struct TMakeTypeImpl<TItemExprType> {
+ static const TItemExprType* Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType);
+};
+
+template <>
+struct TMakeTypeImpl<TListExprType> {
+ static const TListExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
+};
+
+template <>
+struct TMakeTypeImpl<TOptionalExprType> {
+ static const TOptionalExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
+};
+
+template <>
+struct TMakeTypeImpl<TVariantExprType> {
+ static const TVariantExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType);
+};
+
+template <>
+struct TMakeTypeImpl<TErrorExprType> {
static const TErrorExprType* Make(TExprContext& ctx, const TIssue& error);
-};
-
-template <>
-struct TMakeTypeImpl<TDictExprType> {
- static const TDictExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
- const TTypeAnnotationNode* payloadType);
-};
-
-template <>
-struct TMakeTypeImpl<TTypeExprType> {
- static const TTypeExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType);
-};
-
-template <>
-struct TMakeTypeImpl<TDataExprType> {
+};
+
+template <>
+struct TMakeTypeImpl<TDictExprType> {
+ static const TDictExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
+ const TTypeAnnotationNode* payloadType);
+};
+
+template <>
+struct TMakeTypeImpl<TTypeExprType> {
+ static const TTypeExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType);
+};
+
+template <>
+struct TMakeTypeImpl<TDataExprType> {
static const TDataExprType* Make(TExprContext& ctx, EDataSlot slot);
-};
-
-template <>
-struct TMakeTypeImpl<TDataExprParamsType> {
+};
+
+template <>
+struct TMakeTypeImpl<TDataExprParamsType> {
static const TDataExprParamsType* Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two);
-};
-
-template <>
-struct TMakeTypeImpl<TCallableExprType> {
- static const TCallableExprType* Make(
+};
+
+template <>
+struct TMakeTypeImpl<TCallableExprType> {
+ static const TCallableExprType* Make(
TExprContext& ctx, const TTypeAnnotationNode* returnType, const TVector<TCallableExprType::TArgumentInfo>& arguments,
- size_t optionalArgumentsCount, const TStringBuf& payload);
-};
-
-template <>
-struct TMakeTypeImpl<TResourceExprType> {
- static const TResourceExprType* Make(TExprContext& ctx, const TStringBuf& tag);
-};
-
-template <>
-struct TMakeTypeImpl<TTaggedExprType> {
- static const TTaggedExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag);
-};
-
-template <>
-struct TMakeTypeImpl<TStructExprType> {
+ size_t optionalArgumentsCount, const TStringBuf& payload);
+};
+
+template <>
+struct TMakeTypeImpl<TResourceExprType> {
+ static const TResourceExprType* Make(TExprContext& ctx, const TStringBuf& tag);
+};
+
+template <>
+struct TMakeTypeImpl<TTaggedExprType> {
+ static const TTaggedExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag);
+};
+
+template <>
+struct TMakeTypeImpl<TStructExprType> {
static const TStructExprType* Make(TExprContext& ctx, const TVector<const TItemExprType*>& items);
-};
-
-template <>
-struct TMakeTypeImpl<TTupleExprType> {
+};
+
+template <>
+struct TMakeTypeImpl<TTupleExprType> {
static const TTupleExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
-};
-
-template <>
-struct TMakeTypeImpl<TMultiExprType> {
- static const TMultiExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
-};
-
-template <>
-struct TMakeTypeImpl<TStreamExprType> {
- static const TStreamExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
-};
-
-template <>
-struct TMakeTypeImpl<TFlowExprType> {
- static const TFlowExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
-};
-
-using TSingletonTypeCache = std::tuple<
- const TVoidExprType*,
+};
+
+template <>
+struct TMakeTypeImpl<TMultiExprType> {
+ static const TMultiExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
+};
+
+template <>
+struct TMakeTypeImpl<TStreamExprType> {
+ static const TStreamExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
+};
+
+template <>
+struct TMakeTypeImpl<TFlowExprType> {
+ static const TFlowExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
+};
+
+using TSingletonTypeCache = std::tuple<
+ const TVoidExprType*,
const TNullExprType*,
- const TUnitExprType*,
+ const TUnitExprType*,
const TEmptyListExprType*,
const TEmptyDictExprType*,
- const TWorldExprType*,
- const TGenericExprType*,
- const TTupleExprType*,
- const TStructExprType*,
- const TMultiExprType*
->;
-
+ const TWorldExprType*,
+ const TGenericExprType*,
+ const TTupleExprType*,
+ const TStructExprType*,
+ const TMultiExprType*
+>;
+
struct TExprContext : private TNonCopyable {
class TFreezeGuard {
public:
@@ -2234,32 +2234,32 @@ struct TExprContext : private TNonCopyable {
};
TIssueManager IssueManager;
- TNodeMap<TIssues> AssociativeIssues;
-
+ TNodeMap<TIssues> AssociativeIssues;
+
TMemoryPool StringPool;
- std::unordered_set<std::string_view> Strings;
-
- std::stack<std::unique_ptr<const TTypeAnnotationNode>> TypeNodes;
+ std::unordered_set<std::string_view> Strings;
+
+ std::stack<std::unique_ptr<const TTypeAnnotationNode>> TypeNodes;
std::stack<std::unique_ptr<const TConstraintNode>> ConstraintNodes;
- std::deque<std::unique_ptr<TExprNode>> ExprNodes;
-
- TSingletonTypeCache SingletonTypeCache;
- std::unordered_set<const TTypeAnnotationNode*, TTypeAnnotationNode::THash, TTypeAnnotationNode::TEqual> TypeSet;
+ std::deque<std::unique_ptr<TExprNode>> ExprNodes;
+
+ TSingletonTypeCache SingletonTypeCache;
+ std::unordered_set<const TTypeAnnotationNode*, TTypeAnnotationNode::THash, TTypeAnnotationNode::TEqual> TypeSet;
std::unordered_set<const TConstraintNode*, TConstraintNode::THash, TConstraintNode::TEqual> ConstraintSet;
std::unordered_map<const TTypeAnnotationNode*, TExprNode::TPtr> TypeAsNodeCache;
std::unordered_set<TStringBuf, THash<TStringBuf>> DisabledConstraints;
-
+
ui64 NextUniqueId = 0;
ui64 NodeAllocationCounter = 0;
ui64 NodesAllocationLimit = 3000000;
ui64 StringsAllocationLimit = 100000000;
ui64 RepeatTransformLimit = 1000000;
ui64 RepeatTransformCounter = 0;
-
- TGcNodeConfig GcConfig;
-
- std::unordered_multimap<ui64, TExprNode*> UniqueNodes;
-
+
+ TGcNodeConfig GcConfig;
+
+ std::unordered_multimap<ui64, TExprNode*> UniqueNodes;
+
TExprStep Step;
bool Frozen;
@@ -2269,7 +2269,7 @@ struct TExprContext : private TNonCopyable {
ui64 AllocateNextUniqueId() {
ENSURE_NOT_FROZEN_CTX
- const auto ret = ++NextUniqueId;
+ const auto ret = ++NextUniqueId;
return ret;
}
@@ -2297,98 +2297,98 @@ struct TExprContext : private TNonCopyable {
}
[[nodiscard]]
- TExprNode::TPtr RenameNode(const TExprNode& node, const TStringBuf& name);
+ TExprNode::TPtr RenameNode(const TExprNode& node, const TStringBuf& name);
[[nodiscard]]
- TExprNode::TPtr ShallowCopy(const TExprNode& node);
+ TExprNode::TPtr ShallowCopy(const TExprNode& node);
[[nodiscard]]
TExprNode::TPtr ChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
[[nodiscard]]
- TExprNode::TPtr ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child);
+ TExprNode::TPtr ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child);
[[nodiscard]]
TExprNode::TPtr ExactChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
[[nodiscard]]
- TExprNode::TPtr ExactShallowCopy(const TExprNode& node);
+ TExprNode::TPtr ExactShallowCopy(const TExprNode& node);
[[nodiscard]]
- TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body);
+ TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body);
[[nodiscard]]
- TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body = TExprNode::TPtr());
+ TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body = TExprNode::TPtr());
[[nodiscard]]
- TExprNode::TPtr FuseLambdas(const TExprNode& outer, const TExprNode& inner);
+ TExprNode::TPtr FuseLambdas(const TExprNode& outer, const TExprNode& inner);
using TCustomDeepCopier = std::function<bool(const TExprNode& node, TExprNode::TListType& newChildren)>;
-
+
[[nodiscard]]
TExprNode::TPtr DeepCopy(const TExprNode& node, TExprContext& nodeContext, TNodeOnNodeOwnedMap& deepClones,
bool internStrings, bool copyTypes, bool copyResult = false, TCustomDeepCopier customCopier = {});
[[nodiscard]]
- TExprNode::TPtr SwapWithHead(const TExprNode& node);
- TExprNode::TPtr ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst);
- TExprNode::TPtr ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces);
- template<bool KeepTypeAnns = false>
- TExprNode::TListType ReplaceNodes(TExprNode::TListType&& start, const TNodeOnNodeOwnedMap& replaces);
-
+ TExprNode::TPtr SwapWithHead(const TExprNode& node);
+ TExprNode::TPtr ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst);
+ TExprNode::TPtr ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces);
+ template<bool KeepTypeAnns = false>
+ TExprNode::TListType ReplaceNodes(TExprNode::TListType&& start, const TNodeOnNodeOwnedMap& replaces);
+
TExprNode::TPtr NewAtom(TPositionHandle pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, AppendString(content), flags);
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, AppendString(content), flags);
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewArgument(TPositionHandle pos, const TStringBuf& name) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewArgument(AllocateNextUniqueId(), pos, AppendString(name));
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewArgument(AllocateNextUniqueId(), pos, AppendString(name));
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewArguments(TPositionHandle pos, TExprNode::TListType&& argNodes) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewArguments(AllocateNextUniqueId(), pos, std::move(argNodes));
- ExprNodes.emplace_back(node.Get());
- return node;
- }
-
- TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TListType&& lambda) {
- ++NodeAllocationCounter;
- const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(lambda));
- ExprNodes.emplace_back(node.Get());
- return node;
- }
-
- TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
- ++NodeAllocationCounter;
- const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
- ExprNodes.emplace_back(node.Get());
- return node;
- }
-
+ const auto node = TExprNode::NewArguments(AllocateNextUniqueId(), pos, std::move(argNodes));
+ ExprNodes.emplace_back(node.Get());
+ return node;
+ }
+
+ TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TListType&& lambda) {
+ ++NodeAllocationCounter;
+ const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(lambda));
+ ExprNodes.emplace_back(node.Get());
+ return node;
+ }
+
+ TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
+ ++NodeAllocationCounter;
+ const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
+ ExprNodes.emplace_back(node.Get());
+ return node;
+ }
+
TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewWorld(TPositionHandle pos) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewWorld(AllocateNextUniqueId(), pos);
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewWorld(AllocateNextUniqueId(), pos);
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewList(TPositionHandle pos, TExprNode::TListType&& children) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewList(AllocateNextUniqueId(), pos, std::move(children));
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewList(AllocateNextUniqueId(), pos, std::move(children));
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewCallable(TPositionHandle pos, const TStringBuf& name, TExprNode::TListType&& children) {
++NodeAllocationCounter;
- const auto node = TExprNode::NewCallable(AllocateNextUniqueId(), pos, AppendString(name), std::move(children));
- ExprNodes.emplace_back(node.Get());
- return node;
+ const auto node = TExprNode::NewCallable(AllocateNextUniqueId(), pos, AppendString(name), std::move(children));
+ ExprNodes.emplace_back(node.Get());
+ return node;
}
TExprNode::TPtr NewAtom(TPosition pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
@@ -2403,14 +2403,14 @@ struct TExprContext : private TNonCopyable {
return NewArguments(AppendPosition(pos), std::move(argNodes));
}
- TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TListType&& lambda) {
- return NewLambda(AppendPosition(pos), std::move(lambda));
- }
-
- TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
- return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
- }
-
+ TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TListType&& lambda) {
+ return NewLambda(AppendPosition(pos), std::move(lambda));
+ }
+
+ TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
+ return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
+ }
+
TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
}
@@ -2427,10 +2427,10 @@ struct TExprContext : private TNonCopyable {
return NewCallable(AppendPosition(pos), name, std::move(children));
}
- TExprNode::TPtr WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node);
-
+ TExprNode::TPtr WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node);
+
template <typename T, typename... Args>
- const T* MakeType(Args&&... args);
+ const T* MakeType(Args&&... args);
template <typename T, typename... Args>
const T* MakeConstraint(Args&&... args);
@@ -2493,8 +2493,8 @@ inline bool IsSameAnnotation(const TTypeAnnotationNode& left, const TTypeAnnotat
}
template <typename T, typename... Args>
-const T* TExprContext::MakeType(Args&&... args) {
- return TMakeTypeImpl<T>::Make(*this, std::forward<Args>(args)...);
+const T* TExprContext::MakeType(Args&&... args) {
+ return TMakeTypeImpl<T>::Make(*this, std::forward<Args>(args)...);
}
struct TExprAnnotationFlags {
@@ -2523,34 +2523,34 @@ private:
const TPositionHandle Pos_;
};
-bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
+bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
IModuleResolver* resolver, bool hasAnnotations = false, ui32 typeAnnotationIndex = Max<ui32>(), ui16 syntaxVersion = 0);
bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
IModuleResolver* resolver, ui32 annotationFlags, ui16 syntaxVersion = 0);
-struct TLibraryCohesion {
+struct TLibraryCohesion {
TExportTable Exports;
TNodeMap<std::pair<TString, TString>> Imports;
-};
-
+};
+
bool CompileExpr(TAstNode& astRoot, TLibraryCohesion& cohesion, TExprContext& ctx, ui16 syntaxVersion = 0);
-
+
const TTypeAnnotationNode* CompileTypeAnnotation(const TAstNode& node, TExprContext& ctx);
// validate consistency of arguments and lambdas
void CheckArguments(const TExprNode& root);
-void CheckCounts(const TExprNode& root);
-
-// Compare expression trees and return first diffrent nodes.
-bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two);
-
-bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap);
-
-void GatherParents(const TExprNode& node, TParentsMap& parentsMap, bool withLeaves = false);
+void CheckCounts(const TExprNode& root);
+
+// Compare expression trees and return first diffrent nodes.
+bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two);
+
+bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap);
+
+void GatherParents(const TExprNode& node, TParentsMap& parentsMap, bool withLeaves = false);
void GatherParentsMulti(const TExprNode& node, TParentsMultiMap& parentsMap, bool withLeaves = false);
-
+
struct TConvertToAstSettings {
ui32 AnnotationFlags = 0;
bool RefAtoms = false;
@@ -2563,8 +2563,8 @@ TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, const TCo
// refAtoms allows omit copying of atom bodies - they will be referenced from expr graph
TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, ui32 annotationFlags, bool refAtoms);
-TExprNode::TListType GetLambdaBody(const TExprNode& lambda);
-
+TExprNode::TListType GetLambdaBody(const TExprNode& lambda);
+
} // namespace NYql
template<>
diff --git a/ydb/library/yql/ast/yql_expr_builder.cpp b/ydb/library/yql/ast/yql_expr_builder.cpp
index d378e98c9d..4b22308b99 100644
--- a/ydb/library/yql/ast/yql_expr_builder.cpp
+++ b/ydb/library/yql/ast/yql_expr_builder.cpp
@@ -26,7 +26,7 @@ TExprNodeBuilder::TExprNodeBuilder(TPositionHandle pos, TExprNodeBuilder* parent
: Ctx(parent->Ctx)
, Parent(parent)
, ParentReplacer(nullptr)
- , Container(std::move(container))
+ , Container(std::move(container))
, Pos(pos)
, CurrentNode(nullptr)
{
@@ -45,11 +45,11 @@ TExprNodeBuilder::TExprNodeBuilder(TPositionHandle pos, TExprNodeReplaceBuilder*
{
}
-TExprNode::TPtr TExprNodeBuilder::Build() {
+TExprNode::TPtr TExprNodeBuilder::Build() {
Y_ENSURE(CurrentNode, "No current node");
Y_ENSURE(!Parent, "Build is allowed only on top level");
if (CurrentNode->Type() == TExprNode::Lambda) {
- Y_ENSURE(CurrentNode->ChildrenSize() > 0U, "Lambda is not complete");
+ Y_ENSURE(CurrentNode->ChildrenSize() > 0U, "Lambda is not complete");
}
return CurrentNode;
@@ -58,12 +58,12 @@ TExprNode::TPtr TExprNodeBuilder::Build() {
TExprNodeBuilder& TExprNodeBuilder::Seal() {
Y_ENSURE(Parent, "Seal is allowed only on non-top level");
if (Container->Type() == TExprNode::Lambda) {
- if (CurrentNode) {
- Y_ENSURE(Container->ChildrenSize() == 1, "Lambda is already complete.");
- Container->Children_.emplace_back(std::move(CurrentNode));
- } else {
- Y_ENSURE(Container->ChildrenSize() > 0U, "Lambda isn't complete.");
- }
+ if (CurrentNode) {
+ Y_ENSURE(Container->ChildrenSize() == 1, "Lambda is already complete.");
+ Container->Children_.emplace_back(std::move(CurrentNode));
+ } else {
+ Y_ENSURE(Container->ChildrenSize() > 0U, "Lambda isn't complete.");
+ }
}
return *Parent;
@@ -72,13 +72,13 @@ TExprNodeBuilder& TExprNodeBuilder::Seal() {
TExprNodeReplaceBuilder& TExprNodeBuilder::Done() {
Y_ENSURE(ParentReplacer, "Done is allowed only if parent is a replacer");
Y_ENSURE(CurrentNode, "No current node");
- for (auto& body : ParentReplacer->Body)
- body = Ctx.ReplaceNode(std::move(body), ParentReplacer->CurrentNode ? *ParentReplacer->CurrentNode : *ParentReplacer->Args->Child(ParentReplacer->CurrentIndex), CurrentNode);
+ for (auto& body : ParentReplacer->Body)
+ body = Ctx.ReplaceNode(std::move(body), ParentReplacer->CurrentNode ? *ParentReplacer->CurrentNode : *ParentReplacer->Args->Child(ParentReplacer->CurrentIndex), CurrentNode);
return *ParentReplacer;
}
TExprNodeBuilder& TExprNodeBuilder::Atom(ui32 index, TPositionHandle pos, const TStringBuf& content, ui32 flags) {
- Y_ENSURE(Container && !Container->IsLambda(), "Container expected");
+ Y_ENSURE(Container && !Container->IsLambda(), "Container expected");
Y_ENSURE(Container->ChildrenSize() == index,
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
@@ -88,7 +88,7 @@ TExprNodeBuilder& TExprNodeBuilder::Atom(ui32 index, TPositionHandle pos, const
}
TExprNodeBuilder& TExprNodeBuilder::Atom(TPositionHandle pos, const TStringBuf& content, ui32 flags) {
- Y_ENSURE(!Container || Container->IsLambda(), "No container expected");
+ Y_ENSURE(!Container || Container->IsLambda(), "No container expected");
Y_ENSURE(!CurrentNode, "Node is already build");
CurrentNode = Ctx.NewAtom(pos, content, flags);
return *this;
@@ -104,10 +104,10 @@ TExprNodeBuilder& TExprNodeBuilder::Atom(const TStringBuf& content, ui32 flags)
TExprNodeBuilder TExprNodeBuilder::List(ui32 index, TPositionHandle pos) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
- const auto child = Ctx.NewList(pos, {});
+ const auto child = Ctx.NewList(pos, {});
Container->Children_.push_back(child);
return TExprNodeBuilder(pos, this, child);
}
@@ -127,9 +127,9 @@ TExprNodeBuilder TExprNodeBuilder::List() {
return List(Pos);
}
-TExprNodeBuilder& TExprNodeBuilder::Add(ui32 index, const TExprNode::TPtr& child) {
- Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+TExprNodeBuilder& TExprNodeBuilder::Add(ui32 index, const TExprNode::TPtr& child) {
+ Y_ENSURE(Container, "Container expected");
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
Y_ENSURE(child, "child should not be nullptr");
@@ -137,40 +137,40 @@ TExprNodeBuilder& TExprNodeBuilder::Add(ui32 index, const TExprNode::TPtr& child
return *this;
}
-TExprNodeBuilder& TExprNodeBuilder::Add(ui32 index, TExprNode::TPtr&& child) {
- Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
- "Container position mismatch, expected: " << Container->ChildrenSize() <<
- ", actual: " << index);
+TExprNodeBuilder& TExprNodeBuilder::Add(ui32 index, TExprNode::TPtr&& child) {
+ Y_ENSURE(Container, "Container expected");
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ "Container position mismatch, expected: " << Container->ChildrenSize() <<
+ ", actual: " << index);
Y_ENSURE(child, "child should not be nullptr");
- Container->Children_.push_back(std::move(child));
- return *this;
-}
-
-TExprNodeBuilder& TExprNodeBuilder::Add(TExprNode::TListType&& children) {
- Y_ENSURE(Container && Container->Type() != TExprNode::Lambda, "Container expected");
- Y_ENSURE(Container->Children_.empty(), "container should be empty");
- Container->Children_ = std::move(children);
- return *this;
-}
-
-TExprNodeBuilder& TExprNodeBuilder::Set(TExprNode::TPtr&& body) {
+ Container->Children_.push_back(std::move(child));
+ return *this;
+}
+
+TExprNodeBuilder& TExprNodeBuilder::Add(TExprNode::TListType&& children) {
+ Y_ENSURE(Container && Container->Type() != TExprNode::Lambda, "Container expected");
+ Y_ENSURE(Container->Children_.empty(), "container should be empty");
+ Container->Children_ = std::move(children);
+ return *this;
+}
+
+TExprNodeBuilder& TExprNodeBuilder::Set(TExprNode::TPtr&& body) {
+ Y_ENSURE(Container && Container->Type() == TExprNode::Lambda, "Lambda expected");
+ Y_ENSURE(!CurrentNode, "Lambda already has a body");
+ CurrentNode = std::move(body);
+ return *this;
+}
+
+TExprNodeBuilder& TExprNodeBuilder::Set(const TExprNode::TPtr& body) {
Y_ENSURE(Container && Container->Type() == TExprNode::Lambda, "Lambda expected");
Y_ENSURE(!CurrentNode, "Lambda already has a body");
- CurrentNode = std::move(body);
- return *this;
-}
-
-TExprNodeBuilder& TExprNodeBuilder::Set(const TExprNode::TPtr& body) {
- Y_ENSURE(Container && Container->Type() == TExprNode::Lambda, "Lambda expected");
- Y_ENSURE(!CurrentNode, "Lambda already has a body");
CurrentNode = body;
return *this;
}
TExprNodeBuilder TExprNodeBuilder::Callable(ui32 index, TPositionHandle pos, const TStringBuf& content) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
auto child = Ctx.NewCallable(pos, content, {});
@@ -195,7 +195,7 @@ TExprNodeBuilder TExprNodeBuilder::Callable(const TStringBuf& content) {
TExprNodeBuilder& TExprNodeBuilder::World(ui32 index, TPositionHandle pos) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
auto child = Ctx.NewWorld(pos);
@@ -220,7 +220,7 @@ TExprNodeBuilder& TExprNodeBuilder::World() {
TExprNodeBuilder TExprNodeBuilder::Lambda(ui32 index, TPositionHandle pos) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
auto child = Ctx.NewLambda(pos, Ctx.NewArguments(pos, {}), nullptr);
@@ -248,11 +248,11 @@ TExprNodeBuilder& TExprNodeBuilder::Param(TPositionHandle pos, const TStringBuf&
Y_ENSURE(Container, "Container expected");
Y_ENSURE(Container->Type() == TExprNode::Lambda, "Container must be a lambda");
Y_ENSURE(!CurrentNode, "Lambda already has a body");
- for (auto arg : Container->Head().Children()) {
+ for (auto arg : Container->Head().Children()) {
Y_ENSURE(arg->Content() != name, "Duplicate of lambda param name: " << name);
}
- Container->Head().Children_.push_back(Ctx.NewArgument(pos, name));
+ Container->Head().Children_.push_back(Ctx.NewArgument(pos, name));
return *this;
}
@@ -260,17 +260,17 @@ TExprNodeBuilder& TExprNodeBuilder::Param(const TStringBuf& name) {
return Param(Pos, name);
}
-TExprNodeBuilder& TExprNodeBuilder::Params(const TStringBuf& name, ui32 width) {
- Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
- for (ui32 i = 0U; i < width; ++i)
- Param(Pos, TString(name) += ToString(i));
- return *this;
-}
-
+TExprNodeBuilder& TExprNodeBuilder::Params(const TStringBuf& name, ui32 width) {
+ Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
+ for (ui32 i = 0U; i < width; ++i)
+ Param(Pos, TString(name) += ToString(i));
+ return *this;
+}
+
TExprNodeBuilder& TExprNodeBuilder::Arg(ui32 index, const TStringBuf& name) {
Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
auto arg = FindArgument(name);
@@ -285,16 +285,16 @@ TExprNodeBuilder& TExprNodeBuilder::Arg(const TStringBuf& name) {
return *this;
}
-TExprNodeBuilder& TExprNodeBuilder::Arg(ui32 index, const TStringBuf& name, ui32 toIndex) {
- Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
- return Arg(index, TString(name) += ToString(toIndex));
-}
-
-TExprNodeBuilder& TExprNodeBuilder::Arg(const TStringBuf& name, ui32 toIndex) {
- Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
- return Arg(TString(name) += ToString(toIndex));
-}
-
+TExprNodeBuilder& TExprNodeBuilder::Arg(ui32 index, const TStringBuf& name, ui32 toIndex) {
+ Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
+ return Arg(index, TString(name) += ToString(toIndex));
+}
+
+TExprNodeBuilder& TExprNodeBuilder::Arg(const TStringBuf& name, ui32 toIndex) {
+ Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
+ return Arg(TString(name) += ToString(toIndex));
+}
+
TExprNodeBuilder& TExprNodeBuilder::Arg(const TExprNodePtr& arg) {
Y_ENSURE(arg->Type() == TExprNode::Argument, "Argument expected");
Y_ENSURE(!Container || Container->Type() == TExprNode::Lambda, "No container expected");
@@ -303,37 +303,37 @@ TExprNodeBuilder& TExprNodeBuilder::Arg(const TExprNodePtr& arg) {
return *this;
}
-TExprNodeBuilder& TExprNodeBuilder::Args(ui32 index, const TStringBuf& name, ui32 toIndex) {
- Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
- for (auto i = 0U; index < toIndex; ++i)
- Arg(index++, TString(name) += ToString(i));
- return *this;
-}
-
-TExprNodeBuilder& TExprNodeBuilder::Args(const TStringBuf& name, ui32 toIndex) {
- Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
- for (auto i = 0U; i < toIndex; ++i)
- Arg(i, TString(name) += ToString(i));
- return *this;
-}
-
-TExprNode::TPtr TExprNodeBuilder::FindArgument(const TStringBuf& name) {
- for (auto builder = this; builder; builder = builder->Parent) {
+TExprNodeBuilder& TExprNodeBuilder::Args(ui32 index, const TStringBuf& name, ui32 toIndex) {
+ Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
+ for (auto i = 0U; index < toIndex; ++i)
+ Arg(index++, TString(name) += ToString(i));
+ return *this;
+}
+
+TExprNodeBuilder& TExprNodeBuilder::Args(const TStringBuf& name, ui32 toIndex) {
+ Y_ENSURE(!name.empty(), "Empty parameter name is not allowed");
+ for (auto i = 0U; i < toIndex; ++i)
+ Arg(i, TString(name) += ToString(i));
+ return *this;
+}
+
+TExprNode::TPtr TExprNodeBuilder::FindArgument(const TStringBuf& name) {
+ for (auto builder = this; builder; builder = builder->Parent) {
while (builder->ParentReplacer) {
builder = builder->ParentReplacer->Owner;
}
- if (builder->Container && builder->Container->IsLambda()) {
- for (const auto& arg : builder->Container->Head().Children()) {
- if (arg->Content() == name) {
- return arg;
+ if (builder->Container && builder->Container->IsLambda()) {
+ for (const auto& arg : builder->Container->Head().Children()) {
+ if (arg->Content() == name) {
+ return arg;
}
}
}
}
if (ExtArgsFunc) {
- if (const auto arg = ExtArgsFunc(name)) {
+ if (const auto arg = ExtArgsFunc(name)) {
return arg;
}
}
@@ -341,128 +341,128 @@ TExprNode::TPtr TExprNodeBuilder::FindArgument(const TStringBuf& name) {
ythrow yexception() << "Parameter not found: " << name;
}
-TExprNodeReplaceBuilder TExprNodeBuilder::Apply(ui32 index, const TExprNode& lambda) {
+TExprNodeReplaceBuilder TExprNodeBuilder::Apply(ui32 index, const TExprNode& lambda) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
- return TExprNodeReplaceBuilder(this, Container, lambda.HeadPtr(), GetLambdaBody(lambda));
+ return TExprNodeReplaceBuilder(this, Container, lambda.HeadPtr(), GetLambdaBody(lambda));
}
-TExprNodeReplaceBuilder TExprNodeBuilder::Apply(const TExprNode& lambda) {
+TExprNodeReplaceBuilder TExprNodeBuilder::Apply(const TExprNode& lambda) {
Y_ENSURE(!Container || Container->Type() == TExprNode::Lambda, "No container expected");
Y_ENSURE(!CurrentNode, "Node is already build");
- return TExprNodeReplaceBuilder(this, Container, lambda.HeadPtr(), GetLambdaBody(lambda));
-}
-
-TExprNodeReplaceBuilder TExprNodeBuilder::Apply(ui32 index, const TExprNode::TPtr& lambda) {
- return Apply(index, *lambda);
-}
-
-TExprNodeReplaceBuilder TExprNodeBuilder::Apply(const TExprNode::TPtr& lambda) {
- return Apply(*lambda);
-}
-
-TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(ui32 index, TExprNode::TPtr args, TExprNode::TPtr body) {
+ return TExprNodeReplaceBuilder(this, Container, lambda.HeadPtr(), GetLambdaBody(lambda));
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::Apply(ui32 index, const TExprNode::TPtr& lambda) {
+ return Apply(index, *lambda);
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::Apply(const TExprNode::TPtr& lambda) {
+ return Apply(*lambda);
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(ui32 index, TExprNode::TPtr args, TExprNode::TPtr body) {
+ Y_ENSURE(Container, "Container expected");
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ "Container position mismatch, expected: " << Container->ChildrenSize() <<
+ ", actual: " << index);
+ return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(ui32 index, TExprNode::TPtr args, TExprNode::TListType body) {
Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
+ Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
"Container position mismatch, expected: " << Container->ChildrenSize() <<
", actual: " << index);
- return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
-}
-
-TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(ui32 index, TExprNode::TPtr args, TExprNode::TListType body) {
- Y_ENSURE(Container, "Container expected");
- Y_ENSURE(Container->ChildrenSize() == index + (Container->IsLambda() ? 1U : 0U),
- "Container position mismatch, expected: " << Container->ChildrenSize() <<
- ", actual: " << index);
- return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
-}
-
-TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(TExprNode::TPtr args, TExprNode::TPtr body) {
+ return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(TExprNode::TPtr args, TExprNode::TPtr body) {
+ Y_ENSURE(!Container || Container->Type() == TExprNode::Lambda, "No container expected");
+ Y_ENSURE(!CurrentNode, "Node is already build");
+ return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
+}
+
+TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(TExprNode::TPtr args, TExprNode::TListType body) {
Y_ENSURE(!Container || Container->Type() == TExprNode::Lambda, "No container expected");
Y_ENSURE(!CurrentNode, "Node is already build");
- return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
+ return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
+}
+
+TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
+ TExprNode::TPtr&& args, TExprNode::TPtr&& body)
+ : Owner(owner)
+ , Container(std::move(container))
+ , Args(std::move(args))
+ , Body({std::move(body)})
+ , CurrentIndex(0)
+ , CurrentNode(nullptr)
+{
}
-TExprNodeReplaceBuilder TExprNodeBuilder::ApplyPartial(TExprNode::TPtr args, TExprNode::TListType body) {
- Y_ENSURE(!Container || Container->Type() == TExprNode::Lambda, "No container expected");
- Y_ENSURE(!CurrentNode, "Node is already build");
- return TExprNodeReplaceBuilder(this, Container, std::move(args), std::move(body));
-}
-
-TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
- TExprNode::TPtr&& args, TExprNode::TPtr&& body)
+TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
+ TExprNode::TPtr&& args, TExprNode::TListType&& body)
: Owner(owner)
- , Container(std::move(container))
- , Args(std::move(args))
- , Body({std::move(body)})
- , CurrentIndex(0)
- , CurrentNode(nullptr)
-{
-}
-
-TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
- TExprNode::TPtr&& args, TExprNode::TListType&& body)
- : Owner(owner)
- , Container(std::move(container))
- , Args(std::move(args))
- , Body(std::move(body))
+ , Container(std::move(container))
+ , Args(std::move(args))
+ , Body(std::move(body))
, CurrentIndex(0)
, CurrentNode(nullptr)
{
}
-TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
- const TExprNode& lambda)
- : TExprNodeReplaceBuilder(owner, std::move(container), lambda.HeadPtr(), lambda.TailPtr())
+TExprNodeReplaceBuilder::TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNode::TPtr container,
+ const TExprNode& lambda)
+ : TExprNodeReplaceBuilder(owner, std::move(container), lambda.HeadPtr(), lambda.TailPtr())
{
- Y_ENSURE(lambda.Type() == TExprNode::Lambda, "Expected lambda");
+ Y_ENSURE(lambda.Type() == TExprNode::Lambda, "Expected lambda");
}
TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(
ui32 argIndex, const TStringBuf& toName) {
Y_ENSURE(Args, "No arguments");
Y_ENSURE(argIndex < Args->ChildrenSize(), "Wrong argument index");
- Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{Args->Child(argIndex), Owner->FindArgument(toName)}});
+ Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{Args->Child(argIndex), Owner->FindArgument(toName)}});
return *this;
}
TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(
- ui32 argIndex, TExprNode::TPtr toNode) {
+ ui32 argIndex, TExprNode::TPtr toNode) {
Y_ENSURE(Args, "No arguments");
Y_ENSURE(argIndex < Args->ChildrenSize(), "Wrong argument index");
- Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{Args->Child(argIndex), std::move(toNode)}});
+ Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{Args->Child(argIndex), std::move(toNode)}});
return *this;
}
-TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(const TStringBuf& toName) {
- Y_ENSURE(Args, "No arguments");
- Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
- TNodeOnNodeOwnedMap replaces(Args->ChildrenSize());
- for (ui32 i = 0U; i < Args->ChildrenSize(); ++i)
- Y_ENSURE(replaces.emplace(Args->Child(i), Owner->FindArgument(TString(toName) += ToString(i))).second, "Must be uinique.");
- Body = Owner->Ctx.ReplaceNodes(std::move(Body), replaces);
- return *this;
-}
-
-TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(const TStringBuf& toName, ui32 toIndex) {
- Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
- return With(TString(toName) += ToString(toIndex));
-}
-
-TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(ui32 argIndex, const TStringBuf& toName, ui32 toIndex) {
- Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
- return With(argIndex, TString(toName) += ToString(toIndex));
-}
-
-TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::WithNode(const TExprNode& fromNode, TExprNode::TPtr&& toNode) {
- Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{&fromNode, std::move(toNode)}});
+TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(const TStringBuf& toName) {
+ Y_ENSURE(Args, "No arguments");
+ Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
+ TNodeOnNodeOwnedMap replaces(Args->ChildrenSize());
+ for (ui32 i = 0U; i < Args->ChildrenSize(); ++i)
+ Y_ENSURE(replaces.emplace(Args->Child(i), Owner->FindArgument(TString(toName) += ToString(i))).second, "Must be uinique.");
+ Body = Owner->Ctx.ReplaceNodes(std::move(Body), replaces);
+ return *this;
+}
+
+TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(const TStringBuf& toName, ui32 toIndex) {
+ Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
+ return With(TString(toName) += ToString(toIndex));
+}
+
+TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::With(ui32 argIndex, const TStringBuf& toName, ui32 toIndex) {
+ Y_ENSURE(!toName.empty(), "Empty parameter name is not allowed");
+ return With(argIndex, TString(toName) += ToString(toIndex));
+}
+
+TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::WithNode(const TExprNode& fromNode, TExprNode::TPtr&& toNode) {
+ Body = Owner->Ctx.ReplaceNodes(std::move(Body), {{&fromNode, std::move(toNode)}});
return *this;
}
-TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::WithNode(const TExprNode& fromNode, const TStringBuf& toName) {
- return WithNode(fromNode, Owner->FindArgument(toName));
+TExprNodeReplaceBuilder& TExprNodeReplaceBuilder::WithNode(const TExprNode& fromNode, const TStringBuf& toName) {
+ return WithNode(fromNode, Owner->FindArgument(toName));
}
TExprNodeBuilder TExprNodeReplaceBuilder::With(ui32 argIndex) {
@@ -470,19 +470,19 @@ TExprNodeBuilder TExprNodeReplaceBuilder::With(ui32 argIndex) {
return TExprNodeBuilder(Owner->Pos, this);
}
-TExprNodeBuilder TExprNodeReplaceBuilder::WithNode(TExprNode::TPtr&& fromNode) {
- CurrentNode = std::move(fromNode);
+TExprNodeBuilder TExprNodeReplaceBuilder::WithNode(TExprNode::TPtr&& fromNode) {
+ CurrentNode = std::move(fromNode);
return TExprNodeBuilder(Owner->Pos, this);
}
TExprNodeBuilder& TExprNodeReplaceBuilder::Seal() {
if (Container) {
- std::move(Body.begin(), Body.end(), std::back_inserter(Container->Children_));
+ std::move(Body.begin(), Body.end(), std::back_inserter(Container->Children_));
} else {
- Y_ENSURE(1U == Body.size() && Body.front(), "Expected single node.");
- Owner->CurrentNode = std::move(Body.front());
+ Y_ENSURE(1U == Body.size() && Body.front(), "Expected single node.");
+ Owner->CurrentNode = std::move(Body.front());
}
- Body.clear();
+ Body.clear();
return *Owner;
}
diff --git a/ydb/library/yql/ast/yql_expr_builder.h b/ydb/library/yql/ast/yql_expr_builder.h
index bb01a6af23..18c63f2eea 100644
--- a/ydb/library/yql/ast/yql_expr_builder.h
+++ b/ydb/library/yql/ast/yql_expr_builder.h
@@ -10,19 +10,19 @@ namespace NYql {
struct TExprContext;
class TExprNode;
-typedef TIntrusivePtr<TExprNode> TExprNodePtr;
-typedef std::vector<TExprNodePtr> TExprNodeList;
+typedef TIntrusivePtr<TExprNode> TExprNodePtr;
+typedef std::vector<TExprNodePtr> TExprNodeList;
class TExprNodeReplaceBuilder;
class TExprNodeBuilder {
friend class TExprNodeReplaceBuilder;
public:
- typedef std::function<TExprNodePtr(const TStringBuf&)> ExtArgsFuncType;
+ typedef std::function<TExprNodePtr(const TStringBuf&)> ExtArgsFuncType;
public:
TExprNodeBuilder(TPositionHandle pos, TExprContext& ctx);
TExprNodeBuilder(TPositionHandle pos, TExprContext& ctx, ExtArgsFuncType extArgsFunc);
- TExprNodePtr Build();
+ TExprNodePtr Build();
TExprNodeBuilder& Seal();
TExprNodeReplaceBuilder& Done();
@@ -38,12 +38,12 @@ public:
TExprNodeBuilder List(ui32 index);
TExprNodeBuilder List();
- TExprNodeBuilder& Add(ui32 index, TExprNodePtr&& child);
- TExprNodeBuilder& Add(ui32 index, const TExprNodePtr& child);
- TExprNodeBuilder& Add(TExprNodeList&& children);
+ TExprNodeBuilder& Add(ui32 index, TExprNodePtr&& child);
+ TExprNodeBuilder& Add(ui32 index, const TExprNodePtr& child);
+ TExprNodeBuilder& Add(TExprNodeList&& children);
// only for lambda bodies
- TExprNodeBuilder& Set(TExprNodePtr&& body);
- TExprNodeBuilder& Set(const TExprNodePtr& body);
+ TExprNodeBuilder& Set(TExprNodePtr&& body);
+ TExprNodeBuilder& Set(const TExprNodePtr& body);
TExprNodeBuilder Callable(ui32 index, TPositionHandle pos, const TStringBuf& content);
TExprNodeBuilder Callable(TPositionHandle pos, const TStringBuf& content);
@@ -62,25 +62,25 @@ public:
TExprNodeBuilder& Param(TPositionHandle pos, const TStringBuf& name);
TExprNodeBuilder& Param(const TStringBuf& name);
- TExprNodeBuilder& Params(const TStringBuf& name, ui32 width);
+ TExprNodeBuilder& Params(const TStringBuf& name, ui32 width);
TExprNodeBuilder& Arg(ui32 index, const TStringBuf& name);
TExprNodeBuilder& Arg(const TStringBuf& name);
- TExprNodeBuilder& Arg(ui32 index, const TStringBuf& name, ui32 toIndex);
- TExprNodeBuilder& Arg(const TStringBuf& name, ui32 toIndex);
+ TExprNodeBuilder& Arg(ui32 index, const TStringBuf& name, ui32 toIndex);
+ TExprNodeBuilder& Arg(const TStringBuf& name, ui32 toIndex);
TExprNodeBuilder& Arg(const TExprNodePtr& arg);
- TExprNodeBuilder& Args(ui32 index, const TStringBuf& name, ui32 toIndex);
- TExprNodeBuilder& Args(const TStringBuf& name, ui32 toIndex);
-
- TExprNodeReplaceBuilder Apply(ui32 index, const TExprNode& lambda);
- TExprNodeReplaceBuilder Apply(ui32 index, const TExprNodePtr& lambda);
- TExprNodeReplaceBuilder Apply(const TExprNode& lambda);
- TExprNodeReplaceBuilder Apply(const TExprNodePtr& lambda);
- TExprNodeReplaceBuilder ApplyPartial(ui32 index, TExprNodePtr args, TExprNodePtr body);
- TExprNodeReplaceBuilder ApplyPartial(ui32 index, TExprNodePtr args, TExprNodeList body);
- TExprNodeReplaceBuilder ApplyPartial(TExprNodePtr args, TExprNodePtr body);
- TExprNodeReplaceBuilder ApplyPartial(TExprNodePtr args, TExprNodeList body);
+ TExprNodeBuilder& Args(ui32 index, const TStringBuf& name, ui32 toIndex);
+ TExprNodeBuilder& Args(const TStringBuf& name, ui32 toIndex);
+
+ TExprNodeReplaceBuilder Apply(ui32 index, const TExprNode& lambda);
+ TExprNodeReplaceBuilder Apply(ui32 index, const TExprNodePtr& lambda);
+ TExprNodeReplaceBuilder Apply(const TExprNode& lambda);
+ TExprNodeReplaceBuilder Apply(const TExprNodePtr& lambda);
+ TExprNodeReplaceBuilder ApplyPartial(ui32 index, TExprNodePtr args, TExprNodePtr body);
+ TExprNodeReplaceBuilder ApplyPartial(ui32 index, TExprNodePtr args, TExprNodeList body);
+ TExprNodeReplaceBuilder ApplyPartial(TExprNodePtr args, TExprNodePtr body);
+ TExprNodeReplaceBuilder ApplyPartial(TExprNodePtr args, TExprNodeList body);
template <typename TFunc>
TExprNodeBuilder& Do(const TFunc& func) {
@@ -90,15 +90,15 @@ public:
private:
TExprNodeBuilder(TPositionHandle pos, TExprNodeBuilder* parent, const TExprNodePtr& container);
TExprNodeBuilder(TPositionHandle pos, TExprNodeReplaceBuilder* parentReplacer);
- TExprNodePtr FindArgument(const TStringBuf& name);
+ TExprNodePtr FindArgument(const TStringBuf& name);
private:
TExprContext& Ctx;
TExprNodeBuilder* Parent;
TExprNodeReplaceBuilder* ParentReplacer;
- TExprNodePtr Container;
+ TExprNodePtr Container;
TPositionHandle Pos;
- TExprNodePtr CurrentNode;
+ TExprNodePtr CurrentNode;
ExtArgsFuncType ExtArgsFunc;
};
@@ -124,18 +124,18 @@ private:
};
public:
- TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, const TExprNode& lambda);
- TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, TExprNodePtr&& args, TExprNodePtr&& body);
- TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, TExprNodePtr&& args, TExprNodeList&& body);
+ TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, const TExprNode& lambda);
+ TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, TExprNodePtr&& args, TExprNodePtr&& body);
+ TExprNodeReplaceBuilder(TExprNodeBuilder* owner, TExprNodePtr container, TExprNodePtr&& args, TExprNodeList&& body);
TExprNodeReplaceBuilder& With(ui32 argIndex, const TStringBuf& toName);
- TExprNodeReplaceBuilder& With(ui32 argIndex, const TStringBuf& toName, ui32 toIndex);
- TExprNodeReplaceBuilder& With(ui32 argIndex, TExprNodePtr toNode);
- TExprNodeReplaceBuilder& With(const TStringBuf& toName);
- TExprNodeReplaceBuilder& With(const TStringBuf& toName, ui32 toIndex);
- TExprNodeReplaceBuilder& WithNode(const TExprNode& fromNode, TExprNodePtr&& toNode);
- TExprNodeReplaceBuilder& WithNode(const TExprNode& fromNode, const TStringBuf& toName);
+ TExprNodeReplaceBuilder& With(ui32 argIndex, const TStringBuf& toName, ui32 toIndex);
+ TExprNodeReplaceBuilder& With(ui32 argIndex, TExprNodePtr toNode);
+ TExprNodeReplaceBuilder& With(const TStringBuf& toName);
+ TExprNodeReplaceBuilder& With(const TStringBuf& toName, ui32 toIndex);
+ TExprNodeReplaceBuilder& WithNode(const TExprNode& fromNode, TExprNodePtr&& toNode);
+ TExprNodeReplaceBuilder& WithNode(const TExprNode& fromNode, const TStringBuf& toName);
TExprNodeBuilder With(ui32 argIndex);
- TExprNodeBuilder WithNode(TExprNodePtr&& fromNode);
+ TExprNodeBuilder WithNode(TExprNodePtr&& fromNode);
template<typename TNode>
NNodes::TNodeBuilder<TBuildAdapter, TNode> With(ui32 argIndex) {
@@ -162,11 +162,11 @@ public:
private:
TExprNodeBuilder* Owner;
- TExprNodePtr Container;
- TExprNodePtr Args;
- TExprNodeList Body;
+ TExprNodePtr Container;
+ TExprNodePtr Args;
+ TExprNodeList Body;
ui32 CurrentIndex;
- TExprNodePtr CurrentNode;
+ TExprNodePtr CurrentNode;
};
} // namespace NYql
diff --git a/ydb/library/yql/ast/yql_expr_builder_ut.cpp b/ydb/library/yql/ast/yql_expr_builder_ut.cpp
index 6e24d68e4f..eb0f2a0bf1 100644
--- a/ydb/library/yql/ast/yql_expr_builder_ut.cpp
+++ b/ydb/library/yql/ast/yql_expr_builder_ut.cpp
@@ -51,8 +51,8 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
}
@@ -76,8 +76,8 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
}
@@ -96,12 +96,12 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::List);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::List);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
}
@@ -131,8 +131,8 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func");
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "ABC");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
}
@@ -152,13 +152,13 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func1");
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Callable);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "Func2");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Callable);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Content(), "Func2");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "DEF");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "XYZ");
}
@@ -180,7 +180,7 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(res->Content(), "Func");
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::World);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::World);
}
Y_UNIT_TEST(TestIncompleteRootLambda) {
@@ -204,8 +204,8 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
auto res = ctx.Builder(TPositionHandle()).Lambda().Atom("ABC").Seal().Build();
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC");
}
@@ -220,8 +220,8 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 0);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "ABC");
}
@@ -239,14 +239,14 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Lambda);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Content(), "x");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "ABC");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Lambda);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Head().Content(), "x");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Atom);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "ABC");
}
Y_UNIT_TEST(TestDuplicateLambdaParamNames) {
@@ -335,49 +335,49 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
.Build(), yexception);
}
- Y_UNIT_TEST(TestWrongIndexAtomAtLambda) {
+ Y_UNIT_TEST(TestWrongIndexAtomAtLambda) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .Atom(1, "ABC")
+ .Atom(1, "ABC")
.Seal()
.Build(), yexception);
}
- Y_UNIT_TEST(TestWrongIndexListAtLambda) {
+ Y_UNIT_TEST(TestWrongIndexListAtLambda) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .List(1)
+ .List(1)
.Seal()
.Seal()
.Build(), yexception);
}
- Y_UNIT_TEST(TestWrongIndexWorldAtLambda) {
+ Y_UNIT_TEST(TestWrongIndexWorldAtLambda) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .World(1)
+ .World(1)
.Seal()
.Build(), yexception);
}
- Y_UNIT_TEST(TestWrongIndexCallableAtLambda) {
+ Y_UNIT_TEST(TestWrongIndexCallableAtLambda) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .Callable(1, "Func")
+ .Callable(1, "Func")
.Seal()
.Seal()
.Build(), yexception);
}
- Y_UNIT_TEST(TestWrongIndexLambdaAtLambda) {
+ Y_UNIT_TEST(TestWrongIndexLambdaAtLambda) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .Lambda(1)
+ .Lambda(1)
.Atom("ABC")
.Seal()
.Seal()
@@ -388,7 +388,7 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle())
.Lambda()
- .Add(1, ctx.Builder(TPositionHandle()).Atom("ABC").Build())
+ .Add(1, ctx.Builder(TPositionHandle()).Atom("ABC").Build())
.Seal()
.Build(), yexception);
}
@@ -405,20 +405,20 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
- UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
+ UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
}
Y_UNIT_TEST(TestIndexedArgAsLambdaBody) {
TExprContext ctx;
UNIT_ASSERT_EXCEPTION(ctx.Builder(TPositionHandle()).Lambda()
.Param("x")
- .Arg(1, "x")
+ .Arg(1, "x")
.Seal()
.Build(), yexception);
}
@@ -447,17 +447,17 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "+");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 2);
- UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(1));
- UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
+ UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(1));
+ UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
}
Y_UNIT_TEST(TestNestedScopeInLambda) {
@@ -480,28 +480,28 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "x");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Child(1)->Content(), "y");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Content(), "Apply");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Type(), TExprNode::Lambda);
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Content(), "x");
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Type(), TExprNode::Callable);
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Content(), "+");
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->ChildrenSize(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Type(), TExprNode::Lambda);
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Head().Head().Content(), "x");
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Type(), TExprNode::Callable);
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Content(), "+");
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->ChildrenSize(), 2);
// nested x
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(0),
- res->Child(1)->Head().Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(0),
+ res->Child(1)->Head().Head().Child(0));
// outer y
- UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(1),
- res->Head().Child(1));
+ UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Head().Child(1)->Child(1),
+ res->Head().Child(1));
}
Y_UNIT_TEST(TestNonIndexedArg) {
@@ -533,11 +533,11 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
- UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
+ UNIT_ASSERT_EQUAL(res->Child(1), res->Head().Child(0));
}
Y_UNIT_TEST(TestApplyLambdaArgInContainer) {
@@ -560,13 +560,13 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(res->Child(1)->ChildrenSize(), 1);
- UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(0));
+ UNIT_ASSERT_EQUAL(res->Child(1)->Child(0), res->Head().Child(0));
}
Y_UNIT_TEST(TestApplyPartialLambdaArgAsRoot) {
@@ -586,17 +586,17 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
auto res = ctx.Builder(TPositionHandle())
.Lambda()
.Param("y")
- .ApplyPartial(lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
+ .ApplyPartial(lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
.Seal()
.Build();
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
- UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
+ UNIT_ASSERT_EQUAL(res->Child(1)->Child(1), res->Head().Child(0));
}
Y_UNIT_TEST(TestApplyPartialLambdaArgInContainer) {
@@ -617,18 +617,18 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
.Lambda()
.Param("y")
.Callable("Func3")
- .ApplyPartial(0, lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
+ .ApplyPartial(0, lambda->HeadPtr(), lambda->Child(1)->HeadPtr()).With(0, "y").Seal()
.Seal()
.Seal()
.Build();
UNIT_ASSERT_VALUES_EQUAL(res->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
- UNIT_ASSERT_EQUAL(res->Child(1)->Head().Child(1), res->Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res->Head().Head().Content(), "y");
+ UNIT_ASSERT_EQUAL(res->Child(1)->Head().Child(1), res->Head().Child(0));
}
Y_UNIT_TEST(TestApplyOuterArg) {
@@ -652,19 +652,19 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
.Lambda()
.Param("y")
.Callable("Func3")
- .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
- .WithNode(*ast->Head().Child(0), "y").Seal()
+ .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
+ .WithNode(*ast->Head().Child(0), "y").Seal()
.Seal()
.Seal()
.Build();
UNIT_ASSERT_VALUES_EQUAL(res1->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res1->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res1->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res1->Head().ChildrenSize(), 1);
- UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Type(), TExprNode::Argument);
- UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Content(), "y");
- UNIT_ASSERT_EQUAL(res1->Child(1)->Head().Child(1), res1->Head().Child(0));
+ UNIT_ASSERT_VALUES_EQUAL(res1->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res1->Head().ChildrenSize(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Type(), TExprNode::Argument);
+ UNIT_ASSERT_VALUES_EQUAL(res1->Head().Head().Content(), "y");
+ UNIT_ASSERT_EQUAL(res1->Child(1)->Head().Child(1), res1->Head().Child(0));
auto atom = ctx.Builder(TPositionHandle())
.Atom("const")
@@ -673,17 +673,17 @@ Y_UNIT_TEST_SUITE(TExprBuilder) {
auto res2 = ctx.Builder(TPositionHandle())
.Lambda()
.Callable("Func3")
- .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
- .WithNode(ast->Head().Head(), TExprNode::TPtr(atom)).Seal()
+ .ApplyPartial(0, nullptr, ast->Child(1)->Child(1)->ChildPtr(1))
+ .WithNode(ast->Head().Head(), TExprNode::TPtr(atom)).Seal()
.Seal()
.Seal()
.Build();
UNIT_ASSERT_VALUES_EQUAL(res2->Type(), TExprNode::Lambda);
UNIT_ASSERT_VALUES_EQUAL(res2->ChildrenSize(), 2);
- UNIT_ASSERT_VALUES_EQUAL(res2->Head().Type(), TExprNode::Arguments);
- UNIT_ASSERT_VALUES_EQUAL(res2->Head().ChildrenSize(), 0);
- UNIT_ASSERT_EQUAL(res2->Child(1)->Head().ChildPtr(1), atom);
+ UNIT_ASSERT_VALUES_EQUAL(res2->Head().Type(), TExprNode::Arguments);
+ UNIT_ASSERT_VALUES_EQUAL(res2->Head().ChildrenSize(), 0);
+ UNIT_ASSERT_EQUAL(res2->Child(1)->Head().ChildPtr(1), atom);
}
}
diff --git a/ydb/library/yql/ast/yql_expr_types.h b/ydb/library/yql/ast/yql_expr_types.h
index fe5abd4868..391fa1ca97 100644
--- a/ydb/library/yql/ast/yql_expr_types.h
+++ b/ydb/library/yql/ast/yql_expr_types.h
@@ -23,13 +23,13 @@ namespace NYql {
xx(Error, 16) \
xx(Variant, 17) \
xx(Stream, 18) \
- xx(Null, 19) \
+ xx(Null, 19) \
xx(Flow, 20) \
xx(EmptyList, 21) \
- xx(EmptyDict, 22) \
- xx(Multi, 23)
+ xx(EmptyDict, 22) \
+ xx(Multi, 23)
-enum class ETypeAnnotationKind : ui64 {
+enum class ETypeAnnotationKind : ui64 {
YQL_TYPE_ANN_KIND_MAP(ENUM_VALUE_GEN)
LastType
};
diff --git a/ydb/library/yql/ast/yql_expr_ut.cpp b/ydb/library/yql/ast/yql_expr_ut.cpp
index 4a4afb68f5..06550f2507 100644
--- a/ydb/library/yql/ast/yql_expr_ut.cpp
+++ b/ydb/library/yql/ast/yql_expr_ut.cpp
@@ -14,7 +14,7 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
return res;
}
- static void CompileExprWithCheck(TAstNode& root, TExprNode::TPtr& exprRoot, TExprContext& exprCtx, ui32 typeAnnotationIndex = Max<ui32>()) {
+ static void CompileExprWithCheck(TAstNode& root, TExprNode::TPtr& exprRoot, TExprContext& exprCtx, ui32 typeAnnotationIndex = Max<ui32>()) {
const bool success = CompileExpr(root, exprRoot, exprCtx, nullptr, typeAnnotationIndex != Max<ui32>(), typeAnnotationIndex);
exprCtx.IssueManager.GetIssues().PrintTo(Cout);
@@ -22,17 +22,17 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
UNIT_ASSERT_VALUES_EQUAL(exprRoot->GetState(), typeAnnotationIndex != Max<ui32>() ? TExprNode::EState::TypeComplete : TExprNode::EState::Initial);
}
- static void CompileExprWithCheck(TAstNode& root, TLibraryCohesion& cohesion, TExprContext& exprCtx) {
- const bool success = CompileExpr(root, cohesion, exprCtx);
+ static void CompileExprWithCheck(TAstNode& root, TLibraryCohesion& cohesion, TExprContext& exprCtx) {
+ const bool success = CompileExpr(root, cohesion, exprCtx);
exprCtx.IssueManager.GetIssues().PrintTo(Cout);
-
- UNIT_ASSERT(success);
- }
-
+
+ UNIT_ASSERT(success);
+ }
+
static bool ParseAndCompile(const TString& program) {
TAstParseResult astRes = ParseAstWithCheck(program);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
bool result = CompileExpr(*astRes.Root, exprRoot, exprCtx, nullptr);
exprCtx.IssueManager.GetIssues().PrintTo(Cout);
return result;
@@ -52,16 +52,16 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
}
Y_UNIT_TEST(TestExportInsteadOfReturn) {
- const auto s =
- "# library\n"
- "(\n"
- " (let sqr (lambda '(x) (* x x)))\n"
- " (export sqr)\n"
- ")\n"
- ;
- UNIT_ASSERT(false == ParseAndCompile(s));
- }
-
+ const auto s =
+ "# library\n"
+ "(\n"
+ " (let sqr (lambda '(x) (* x x)))\n"
+ " (export sqr)\n"
+ ")\n"
+ ;
+ UNIT_ASSERT(false == ParseAndCompile(s));
+ }
+
Y_UNIT_TEST(TestLeftAfterReturn) {
auto s = "(\n"
"(return 'x)\n"
@@ -77,43 +77,43 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::World);
}
Y_UNIT_TEST(TestExport) {
- auto s = "(\n"
- "(let X 'Y)\n"
- "(let ex '42)\n"
- "(export ex)\n"
- "(export X)\n"
- ")\n";
-
- TAstParseResult astRes = ParseAstWithCheck(s);
- TExprContext exprCtx;
- TLibraryCohesion cohesion;
- CompileExprWithCheck(*astRes.Root, cohesion, exprCtx);
+ auto s = "(\n"
+ "(let X 'Y)\n"
+ "(let ex '42)\n"
+ "(export ex)\n"
+ "(export X)\n"
+ ")\n";
+
+ TAstParseResult astRes = ParseAstWithCheck(s);
+ TExprContext exprCtx;
+ TLibraryCohesion cohesion;
+ CompileExprWithCheck(*astRes.Root, cohesion, exprCtx);
auto& exports = cohesion.Exports.Symbols(exprCtx);
UNIT_ASSERT_VALUES_EQUAL(2U, exports.size());
UNIT_ASSERT_VALUES_EQUAL("42", exports["ex"]->Content());
UNIT_ASSERT_VALUES_EQUAL("Y", exports["X"]->Content());
- }
-
+ }
+
Y_UNIT_TEST(TestEmptyLib) {
- auto s = "(\n"
- "(let X 'Y)\n"
- "(let ex '42)\n"
- ")\n";
-
- TAstParseResult astRes = ParseAstWithCheck(s);
- TExprContext exprCtx;
- TLibraryCohesion cohesion;
- CompileExprWithCheck(*astRes.Root, cohesion, exprCtx);
+ auto s = "(\n"
+ "(let X 'Y)\n"
+ "(let ex '42)\n"
+ ")\n";
+
+ TAstParseResult astRes = ParseAstWithCheck(s);
+ TExprContext exprCtx;
+ TLibraryCohesion cohesion;
+ CompileExprWithCheck(*astRes.Root, cohesion, exprCtx);
UNIT_ASSERT(cohesion.Exports.Symbols().empty());
- UNIT_ASSERT(cohesion.Imports.empty());
- }
-
+ UNIT_ASSERT(cohesion.Imports.empty());
+ }
+
Y_UNIT_TEST(TestArbitraryAtom) {
auto s = "(\n"
"(let x '\"\\x01\\x23\\x45\\x67\\x89\\xAB\\xCD\\xEF\")"
@@ -122,7 +122,7 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::Atom);
UNIT_ASSERT_STRINGS_EQUAL(HexEncode(exprRoot->Content()), "0123456789ABCDEF");
@@ -142,14 +142,14 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::Atom);
UNIT_ASSERT_STRINGS_EQUAL(HexEncode(exprRoot->Content()), "FEDCBA9876543210");
UNIT_ASSERT(exprRoot->Flags() & TNodeFlags::BinaryContent);
auto ast = ConvertToAst(*exprRoot, exprCtx, TExprAnnotationFlags::None, true);
- TAstNode* xValue = ast.Root->GetChild(0)->GetChild(2)->GetChild(1);
+ TAstNode* xValue = ast.Root->GetChild(0)->GetChild(2)->GetChild(1);
UNIT_ASSERT_STRINGS_EQUAL(HexEncode(TString(xValue->GetContent())), "FEDCBA9876543210");
UNIT_ASSERT(xValue->GetFlags() & TNodeFlags::BinaryContent);
}
@@ -162,7 +162,7 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::Atom);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Content(), "y");
@@ -178,7 +178,7 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::List);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->ChildrenSize(), 2);
@@ -211,7 +211,7 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
TAstParseResult astRes = ParseAstWithCheck(s);
TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
CompileExprWithCheck(*astRes.Root, exprRoot, exprCtx);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Type(), TExprNode::Callable);
UNIT_ASSERT_VALUES_EQUAL(exprRoot->Content(), "+");
@@ -307,856 +307,856 @@ Y_UNIT_TEST_SUITE(TCompileYqlExpr) {
Y_UNIT_TEST_SUITE(TCompareExprTrees) {
void CompileAndCompare(const TString& one, const TString& two, const std::pair<TPosition, TPosition> *const diffPositions = nullptr) {
- const auto progOne(ParseAst(one)), progTwo(ParseAst(two));
- UNIT_ASSERT(progOne.IsOk() && progTwo.IsOk());
-
- TExprContext ctxOne, ctxTwo;
- TExprNode::TPtr rootOne, rootTwo;
-
+ const auto progOne(ParseAst(one)), progTwo(ParseAst(two));
+ UNIT_ASSERT(progOne.IsOk() && progTwo.IsOk());
+
+ TExprContext ctxOne, ctxTwo;
+ TExprNode::TPtr rootOne, rootTwo;
+
UNIT_ASSERT(CompileExpr(*progOne.Root, rootOne, ctxOne, nullptr));
UNIT_ASSERT(CompileExpr(*progTwo.Root, rootTwo, ctxTwo, nullptr));
-
- const TExprNode* diffOne = rootOne.Get();
- const TExprNode* diffTwo = rootTwo.Get();
-
- if (diffPositions) {
+
+ const TExprNode* diffOne = rootOne.Get();
+ const TExprNode* diffTwo = rootTwo.Get();
+
+ if (diffPositions) {
UNIT_ASSERT(!CompareExprTrees(diffOne, diffTwo));
UNIT_ASSERT_EQUAL(ctxOne.GetPosition(diffOne->Pos()), diffPositions->first);
UNIT_ASSERT_EQUAL(ctxTwo.GetPosition(diffTwo->Pos()), diffPositions->second);
- } else
- UNIT_ASSERT(CompareExprTrees(diffOne, diffTwo));
- }
-
+ } else
+ UNIT_ASSERT(CompareExprTrees(diffOne, diffTwo));
+ }
+
Y_UNIT_TEST(BigGoodCompare) {
- const auto one = R"(
- (
- (let $1 world)
- (let $2 (DataSource '"yt" '"plato"))
- (let $3 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
- (let $4 '('table $3))
- (let $5 (Key $4))
- (let $6 '('"method" '"uri" '"login" '"user_agent" '"millis"))
- (let $7 '())
- (let $8 (Read! $1 $2 $5 $6 $7))
- (let $9 (Left! $8))
- (let $10 (DataSink 'result))
- (let $11 (Key))
- (let $12 (Right! $8))
- (let $13 (lambda '($111) (block '(
- (let $113 (Member $111 '"method"))
- (let $114 (String '"POST"))
- (let $115 (== $113 $114))
- (let $116 (Member $111 '"uri"))
- (let $117 (String '"/api/v2/operations"))
- (let $118 (== $116 $117))
- (let $119 (Udf '"String.HasPrefix"))
- (let $120 (Member $111 '"uri"))
- (let $121 (String '"/api/v2/tutorials/"))
- (let $122 (Apply $119 $120 $121))
- (let $123 (Or $118 $122))
- (let $124 (Udf '"String.HasPrefix"))
- (let $125 (Member $111 '"uri"))
- (let $126 (String '"/api/v2/queries/"))
- (let $127 (Apply $124 $125 $126))
- (let $128 (Or $123 $127))
- (let $129 (And $115 $128))
- (let $130 (Udf '"String.HasPrefix"))
- (let $131 (Member $111 '"uri"))
- (let $132 (String '"/api/v2/table_data_async"))
- (let $133 (Apply $130 $131 $132))
- (let $134 (Or $129 $133))
- (let $135 (Udf '"String.HasPrefix"))
- (let $136 (Member $111 '"login"))
- (let $137 (String '"robot-"))
- (let $138 (Apply $135 $136 $137))
- (let $139 (Not $138))
- (let $140 (And $134 $139))
- (let $141 (Bool 'false))
- (let $142 (Coalesce $140 $141))
- (return $142)
- ))))
- (let $14 (Filter $12 $13))
- (let $15 (lambda '($143) (block '(
- (let $145 (Struct))
- (let $146 (Member $143 '"login"))
- (let $147 (AddMember $145 '"login" $146))
- (let $148 (Udf '"String.HasPrefix"))
- (let $149 (Member $143 '"user_agent"))
- (let $150 (String '"YQL "))
- (let $151 (Apply $148 $149 $150))
- (let $152 (Bool 'false))
- (let $153 (Coalesce $151 $152))
- (let $154 (Udf '"String.SplitToList"))
- (let $155 (Member $143 '"user_agent"))
- (let $156 (String '" "))
- (let $157 (Apply $154 $155 $156))
- (let $158 (Int64 '"1"))
- (let $159 (SqlAccess 'dict $157 $158))
- (let $160 (String '"CLI"))
- (let $161 (== $159 $160))
- (let $162 (Bool 'false))
- (let $163 (Coalesce $161 $162))
- (let $164 (String '"CLI"))
- (let $165 (String '"API"))
- (let $166 (If $163 $164 $165))
- (let $167 (String '"Web UI"))
- (let $168 (If $153 $166 $167))
- (let $169 (AddMember $147 '"client_type" $168))
- (let $170 (Udf '"DateTime.ToDate"))
- (let $171 (Udf '"DateTime.StartOfWeek"))
- (let $172 (Udf '"DateTime.FromMilliSeconds"))
- (let $173 (Member $143 '"millis"))
- (let $174 (Cast $173 'Uint64))
- (let $175 (Apply $172 $174))
- (let $176 (Apply $171 $175))
- (let $177 (Apply $170 $176))
- (let $178 (String '""))
- (let $179 (Coalesce $177 $178))
- (let $180 (String '" - "))
- (let $181 (Concat $179 $180))
- (let $182 (Udf '"DateTime.ToDate"))
- (let $183 (Udf '"DateTime.StartOfWeek"))
- (let $184 (Udf '"DateTime.FromMilliSeconds"))
- (let $185 (Member $143 '"millis"))
- (let $186 (Cast $185 'Uint64))
- (let $187 (Apply $184 $186))
- (let $188 (Apply $183 $187))
- (let $189 (Udf '"DateTime.FromDays"))
- (let $190 (Int64 '"6"))
- (let $191 (Apply $189 $190))
- (let $192 (+ $188 $191))
- (let $193 (Apply $182 $192))
- (let $194 (String '""))
- (let $195 (Coalesce $193 $194))
- (let $196 (Concat $181 $195))
- (let $197 (AddMember $169 '"week" $196))
- (let $198 (AsList $197))
- (return $198)
- ))))
+ const auto one = R"(
+ (
+ (let $1 world)
+ (let $2 (DataSource '"yt" '"plato"))
+ (let $3 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
+ (let $4 '('table $3))
+ (let $5 (Key $4))
+ (let $6 '('"method" '"uri" '"login" '"user_agent" '"millis"))
+ (let $7 '())
+ (let $8 (Read! $1 $2 $5 $6 $7))
+ (let $9 (Left! $8))
+ (let $10 (DataSink 'result))
+ (let $11 (Key))
+ (let $12 (Right! $8))
+ (let $13 (lambda '($111) (block '(
+ (let $113 (Member $111 '"method"))
+ (let $114 (String '"POST"))
+ (let $115 (== $113 $114))
+ (let $116 (Member $111 '"uri"))
+ (let $117 (String '"/api/v2/operations"))
+ (let $118 (== $116 $117))
+ (let $119 (Udf '"String.HasPrefix"))
+ (let $120 (Member $111 '"uri"))
+ (let $121 (String '"/api/v2/tutorials/"))
+ (let $122 (Apply $119 $120 $121))
+ (let $123 (Or $118 $122))
+ (let $124 (Udf '"String.HasPrefix"))
+ (let $125 (Member $111 '"uri"))
+ (let $126 (String '"/api/v2/queries/"))
+ (let $127 (Apply $124 $125 $126))
+ (let $128 (Or $123 $127))
+ (let $129 (And $115 $128))
+ (let $130 (Udf '"String.HasPrefix"))
+ (let $131 (Member $111 '"uri"))
+ (let $132 (String '"/api/v2/table_data_async"))
+ (let $133 (Apply $130 $131 $132))
+ (let $134 (Or $129 $133))
+ (let $135 (Udf '"String.HasPrefix"))
+ (let $136 (Member $111 '"login"))
+ (let $137 (String '"robot-"))
+ (let $138 (Apply $135 $136 $137))
+ (let $139 (Not $138))
+ (let $140 (And $134 $139))
+ (let $141 (Bool 'false))
+ (let $142 (Coalesce $140 $141))
+ (return $142)
+ ))))
+ (let $14 (Filter $12 $13))
+ (let $15 (lambda '($143) (block '(
+ (let $145 (Struct))
+ (let $146 (Member $143 '"login"))
+ (let $147 (AddMember $145 '"login" $146))
+ (let $148 (Udf '"String.HasPrefix"))
+ (let $149 (Member $143 '"user_agent"))
+ (let $150 (String '"YQL "))
+ (let $151 (Apply $148 $149 $150))
+ (let $152 (Bool 'false))
+ (let $153 (Coalesce $151 $152))
+ (let $154 (Udf '"String.SplitToList"))
+ (let $155 (Member $143 '"user_agent"))
+ (let $156 (String '" "))
+ (let $157 (Apply $154 $155 $156))
+ (let $158 (Int64 '"1"))
+ (let $159 (SqlAccess 'dict $157 $158))
+ (let $160 (String '"CLI"))
+ (let $161 (== $159 $160))
+ (let $162 (Bool 'false))
+ (let $163 (Coalesce $161 $162))
+ (let $164 (String '"CLI"))
+ (let $165 (String '"API"))
+ (let $166 (If $163 $164 $165))
+ (let $167 (String '"Web UI"))
+ (let $168 (If $153 $166 $167))
+ (let $169 (AddMember $147 '"client_type" $168))
+ (let $170 (Udf '"DateTime.ToDate"))
+ (let $171 (Udf '"DateTime.StartOfWeek"))
+ (let $172 (Udf '"DateTime.FromMilliSeconds"))
+ (let $173 (Member $143 '"millis"))
+ (let $174 (Cast $173 'Uint64))
+ (let $175 (Apply $172 $174))
+ (let $176 (Apply $171 $175))
+ (let $177 (Apply $170 $176))
+ (let $178 (String '""))
+ (let $179 (Coalesce $177 $178))
+ (let $180 (String '" - "))
+ (let $181 (Concat $179 $180))
+ (let $182 (Udf '"DateTime.ToDate"))
+ (let $183 (Udf '"DateTime.StartOfWeek"))
+ (let $184 (Udf '"DateTime.FromMilliSeconds"))
+ (let $185 (Member $143 '"millis"))
+ (let $186 (Cast $185 'Uint64))
+ (let $187 (Apply $184 $186))
+ (let $188 (Apply $183 $187))
+ (let $189 (Udf '"DateTime.FromDays"))
+ (let $190 (Int64 '"6"))
+ (let $191 (Apply $189 $190))
+ (let $192 (+ $188 $191))
+ (let $193 (Apply $182 $192))
+ (let $194 (String '""))
+ (let $195 (Coalesce $193 $194))
+ (let $196 (Concat $181 $195))
+ (let $197 (AddMember $169 '"week" $196))
+ (let $198 (AsList $197))
+ (return $198)
+ ))))
)"
R"(
- (let $16 (FlatMap $14 $15))
- (let $17 '('"client_type" '"week"))
- (let $18 (lambda '($199 $200) (block '(
- (let $202 (lambda '($205 $206 $207) (block '(
- (let $209 (ListItemType $205))
- (let $210 (lambda '($223) (block '(
- (let $212 (ListItemType $205))
- (let $213 (InstanceOf $212))
- (let $214 (Apply $206 $213))
- (let $215 (TypeOf $214))
- (let $216 (ListType $215))
- (let $217 (Apply $207 $216))
- (let $225 (NthArg '1 $217))
- (let $226 (Apply $206 $223))
- (let $227 (Apply $225 $226))
- (return $227)
- ))))
- (let $211 (lambda '($228 $229) (block '(
- (let $212 (ListItemType $205))
- (let $213 (InstanceOf $212))
- (let $214 (Apply $206 $213))
- (let $215 (TypeOf $214))
- (let $216 (ListType $215))
- (let $217 (Apply $207 $216))
- (let $231 (NthArg '2 $217))
- (let $232 (Apply $206 $228))
- (let $233 (Apply $231 $232 $229))
- (return $233)
- ))))
- (let $212 (ListItemType $205))
- (let $213 (InstanceOf $212))
- (let $214 (Apply $206 $213))
- (let $215 (TypeOf $214))
- (let $216 (ListType $215))
- (let $217 (Apply $207 $216))
- (let $218 (NthArg '3 $217))
- (let $219 (NthArg '4 $217))
- (let $220 (NthArg '5 $217))
- (let $221 (NthArg '6 $217))
- (let $222 (AggregationTraits $209 $210 $211 $218 $219 $220 $221))
- (return $222)
- ))))
- (let $203 (lambda '($234) (block '(
- (let $236 (ListItemType $234))
- (let $237 (lambda '($244) (block '(
- (let $246 (AggrCountInit $244))
- (return $246)
- ))))
- (let $238 (lambda '($247 $248) (block '(
- (let $250 (AggrCountUpdate $247 $248))
- (return $250)
- ))))
- (let $239 (lambda '($251) (block '(
- (return $251)
- ))))
- (let $240 (lambda '($253) (block '(
- (return $253)
- ))))
- (let $241 (lambda '($255 $256) (block '(
- (let $258 (+ $255 $256))
- (return $258)
- ))))
- (let $242 (lambda '($259) (block '(
- (return $259)
- ))))
- (let $243 (AggregationTraits $236 $237 $238 $239 $240 $241 $242))
- (return $243)
- ))))
- (let $204 (Apply $202 $199 $200 $203))
- (return $204)
- ))))
- (let $19 (TypeOf $16))
- (let $20 (ListItemType $19))
- (let $21 (StructMemberType $20 '"login"))
- (let $22 (ListType $21))
- (let $23 (lambda '($261) (block '(
- (return $261)
- ))))
- (let $24 (Apply $18 $22 $23))
- (let $25 '('Count1 $24 '"login"))
- (let $26 (TypeOf $16))
- (let $27 (lambda '($263) (block '(
- (let $265 (Void))
- (return $265)
- ))))
- (let $28 (Apply $18 $26 $27))
- (let $29 '('Count2 $28))
- (let $30 (TypeOf $16))
- (let $31 (lambda '($266) (block '(
- (let $268 (Void))
- (return $268)
- ))))
- (let $32 (Apply $18 $30 $31))
- (let $33 '('Count3 $32))
- (let $34 (TypeOf $16))
- (let $35 (ListItemType $34))
- (let $36 (StructMemberType $35 '"login"))
- (let $37 (ListType $36))
- (let $38 (lambda '($269) (block '(
- (return $269)
- ))))
- (let $39 (Apply $18 $37 $38))
- (let $40 '('Count4 $39 '"login"))
- (let $41 '($25 $29 $33 $40))
- (let $42 (Aggregate $16 $17 $41))
- (let $43 (lambda '($271) (block '(
- (let $273 (Struct))
- (let $274 (Member $271 '"week"))
- (let $275 (AddMember $273 '"week" $274))
- (let $276 (Member $271 '"client_type"))
- (let $277 (AddMember $275 '"client_type" $276))
- (let $278 (Member $271 'Count1))
- (let $279 (AddMember $277 '"users_count" $278))
- (let $280 (Member $271 'Count2))
- (let $281 (AddMember $279 '"operations_count" $280))
- (let $282 (Member $271 'Count3))
- (let $283 (Member $271 'Count4))
- (let $284 (/ $282 $283))
- (let $285 (AddMember $281 '"operations_per_user" $284))
- (let $286 (AsList $285))
- (return $286)
- ))))
- (let $44 (FlatMap $42 $43))
- (let $45 (Bool 'false))
- (let $46 (Bool 'false))
- (let $47 '($45 $46))
- (let $48 (lambda '($287) (block '(
- (let $289 (Member $287 '"week"))
- (let $290 (Member $287 '"users_count"))
- (let $291 '($289 $290))
- (return $291)
- ))))
- (let $49 (Sort $44 $47 $48))
- (let $50 '('type))
- (let $51 '('autoref))
- (let $52 '('"week" '"client_type" '"users_count" '"operations_count" '"operations_per_user"))
- (let $53 '('columns $52))
- (let $54 '($50 $51 $53))
- (let $55 (Write! $9 $10 $11 $49 $54))
- (let $56 (Commit! $55 $10))
- (let $57 (DataSource '"yt" '"plato"))
- (let $58 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
- (let $59 '('table $58))
- (let $60 (Key $59))
- (let $61 '('"method" '"uri" '"login" '"user_agent" '"millis"))
- (let $62 '())
- (let $63 (Read! $56 $57 $60 $61 $62))
- (let $64 (Left! $63))
- (let $65 (DataSink 'result))
- (let $66 (Key))
- (let $67 (Right! $63))
- (let $68 (lambda '($292) (block '(
- (let $294 (Member $292 '"method"))
- (let $295 (String '"POST"))
- (let $296 (== $294 $295))
- (let $297 (Member $292 '"uri"))
- (let $298 (String '"/api/v2/operations"))
- (let $299 (== $297 $298))
- (let $300 (Udf '"String.HasPrefix"))
- (let $301 (Member $292 '"uri"))
- (let $302 (String '"/api/v2/tutorials/"))
- (let $303 (Apply $300 $301 $302))
- (let $304 (Or $299 $303))
- (let $305 (Udf '"String.HasPrefix"))
- (let $306 (Member $292 '"uri"))
- (let $307 (String '"/api/v2/queries/"))
- (let $308 (Apply $305 $306 $307))
- (let $309 (Or $304 $308))
- (let $310 (And $296 $309))
- (let $311 (Udf '"String.HasPrefix"))
- (let $312 (Member $292 '"uri"))
- (let $313 (String '"/api/v2/table_data_async"))
- (let $314 (Apply $311 $312 $313))
- (let $315 (Or $310 $314))
- (let $316 (Udf '"String.HasPrefix"))
- (let $317 (Member $292 '"login"))
- (let $318 (String '"robot-"))
- (let $319 (Apply $316 $317 $318))
- (let $320 (Not $319))
- (let $321 (And $315 $320))
- (let $322 (Bool 'false))
- (let $323 (Coalesce $321 $322))
- (return $323)
- ))))
- (let $69 (Filter $67 $68))
- (let $70 (lambda '($324) (block '(
- (let $326 (Struct))
- (let $327 (Member $324 '"login"))
- (let $328 (AddMember $326 '"login" $327))
- (let $329 (Udf '"String.HasPrefix"))
- (let $330 (Member $324 '"user_agent"))
- (let $331 (String '"YQL "))
- (let $332 (Apply $329 $330 $331))
- (let $333 (Bool 'false))
- (let $334 (Coalesce $332 $333))
- (let $335 (Udf '"String.SplitToList"))
- (let $336 (Member $324 '"user_agent"))
- (let $337 (String '" "))
- (let $338 (Apply $335 $336 $337))
- (let $339 (Int64 '"1"))
- (let $340 (SqlAccess 'dict $338 $339))
- (let $341 (String '"CLI"))
- (let $342 (== $340 $341))
- (let $343 (Bool 'false))
- (let $344 (Coalesce $342 $343))
- (let $345 (String '"CLI"))
- (let $346 (String '"API"))
- (let $347 (If $344 $345 $346))
- (let $348 (String '"Web UI"))
- (let $349 (If $334 $347 $348))
- (let $350 (AddMember $328 '"client_type" $349))
- (let $351 (Udf '"DateTime.ToDate"))
- (let $352 (Udf '"DateTime.StartOfWeek"))
- (let $353 (Udf '"DateTime.FromMilliSeconds"))
- (let $354 (Member $324 '"millis"))
- (let $355 (Cast $354 'Uint64))
- (let $356 (Apply $353 $355))
- (let $357 (Apply $352 $356))
- (let $358 (Apply $351 $357))
- (let $359 (String '""))
- (let $360 (Coalesce $358 $359))
- (let $361 (String '" - "))
- (let $362 (Concat $360 $361))
- (let $363 (Udf '"DateTime.ToDate"))
- (let $364 (Udf '"DateTime.StartOfWeek"))
- (let $365 (Udf '"DateTime.FromMilliSeconds"))
- (let $366 (Member $324 '"millis"))
- (let $367 (Cast $366 'Uint64))
- (let $368 (Apply $365 $367))
- (let $369 (Apply $364 $368))
- (let $370 (Udf '"DateTime.FromDays"))
- (let $371 (Int64 '"6"))
- (let $372 (Apply $370 $371))
- (let $373 (+ $369 $372))
- (let $374 (Apply $363 $373))
- (let $375 (String '""))
- (let $376 (Coalesce $374 $375))
- (let $377 (Concat $362 $376))
- (let $378 (AddMember $350 '"week" $377))
- (let $379 (AsList $378))
- (return $379)
- ))))
- (let $71 (FlatMap $69 $70))
- (let $72 '('"week"))
- (let $73 (TypeOf $71))
- (let $74 (ListItemType $73))
- (let $75 (StructMemberType $74 '"login"))
- (let $76 (ListType $75))
- (let $77 (lambda '($380) (block '(
- (return $380)
- ))))
- (let $78 (Apply $18 $76 $77))
- (let $79 '('Count6 $78 '"login"))
- (let $80 (TypeOf $71))
- (let $81 (lambda '($382) (block '(
- (let $384 (Void))
- (return $384)
- ))))
- (let $82 (Apply $18 $80 $81))
- (let $83 '('Count7 $82))
- (let $84 (TypeOf $71))
- (let $85 (lambda '($385) (block '(
- (let $387 (Void))
- (return $387)
- ))))
- (let $86 (Apply $18 $84 $85))
- (let $87 '('Count8 $86))
- (let $88 (TypeOf $71))
- (let $89 (ListItemType $88))
- (let $90 (StructMemberType $89 '"login"))
- (let $91 (ListType $90))
- (let $92 (lambda '($388) (block '(
- (return $388)
- ))))
- (let $93 (Apply $18 $91 $92))
- (let $94 '('Count9 $93 '"login"))
- (let $95 '($79 $83 $87 $94))
- (let $96 (Aggregate $71 $72 $95))
- (let $97 (lambda '($390) (block '(
- (let $392 (Struct))
- (let $393 (Member $390 '"week"))
- (let $394 (AddMember $392 '"week" $393))
- (let $395 (Member $390 'Count6))
- (let $396 (AddMember $394 '"users_count" $395))
- (let $397 (Member $390 'Count7))
- (let $398 (AddMember $396 '"operations_count" $397))
- (let $399 (Member $390 'Count8))
- (let $400 (Member $390 'Count9))
- (let $401 (/ $399 $400))
- (let $402 (AddMember $398 '"operations_per_user" $401))
- (let $403 (AsList $402))
- (return $403)
- ))))
- (let $98 (FlatMap $96 $97))
- (let $99 (Bool 'false))
- (let $100 (lambda '($404) (block '(
- (let $406 (Member $404 '"week"))
- (return $406)
- ))))
- (let $101 (Sort $98 $99 $100))
- (let $102 '('type))
- (let $103 '('autoref))
- (let $104 '('"week" '"users_count" '"operations_count" '"operations_per_user"))
- (let $105 '('columns $104))
- (let $106 '($102 $103 $105))
- (let $107 (Write! $64 $65 $66 $101 $106))
- (let $108 (Commit! $107 $65))
- (let $109 (DataSink '"yt" '"plato"))
- (let $110 (Commit! $108 $109))
- (return $110)
- )
- )";
-
- const auto two = R"(
- (
- (let $1 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
- (let $2 '('"method" '"uri" '"login" '"user_agent" '"millis"))
- (let $3 (Read! world (DataSource '"yt" '"plato") (Key '('table $1)) $2 '()))
- (let $4 (DataSink 'result))
- (let $5 (FlatMap (Filter (Right! $3) (lambda '($36) (block '(
- (let $37 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/tutorials/")))
- (let $38 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/queries/")))
- (let $39 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/table_data_async")))
- (let $40 (Apply (Udf '"String.HasPrefix") (Member $36 '"login") (String '"robot-")))
- (return (Coalesce (And (Or (And (== (Member $36 '"method") (String '"POST")) (Or (Or (== (Member $36 '"uri") (String '"/api/v2/operations")) $37) $38)) $39) (Not $40)) (Bool 'false)))
- )))) (lambda '($41) (block '(
- (let $42 (AddMember (Struct) '"login" (Member $41 '"login")))
- (let $43 (Apply (Udf '"String.HasPrefix") (Member $41 '"user_agent") (String '"YQL ")))
- (let $44 (Apply (Udf '"String.SplitToList") (Member $41 '"user_agent") (String '" ")))
- (let $45 (SqlAccess 'dict $44 (Int64 '"1")))
- (let $46 (If (Coalesce (== $45 (String '"CLI")) (Bool 'false)) (String '"CLI") (String '"API")))
- (let $47 (If (Coalesce $43 (Bool 'false)) $46 (String '"Web UI")))
- (let $48 (AddMember $42 '"client_type" $47))
- (let $49 (AddMember $48 '"week" (Concat (Concat (Coalesce (Apply (Udf '"DateTime.ToDate") (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $41 '"millis") 'Uint64)))) (String '"")) (String '" - ")) (Coalesce (Apply (Udf '"DateTime.ToDate") (+ (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $41 '"millis") 'Uint64))) (Apply (Udf '"DateTime.FromDays") (Int64 '"6")))) (String '"")))))
- (return (AsList $49))
- )))))
- (let $6 (lambda '($50 $51) (block '(
- (let $52 (Apply (lambda '($53 $54 $55) (block '(
- (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
- (let $58 (AggregationTraits (ListItemType $53) (lambda '($59) (block '(
- (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
- (return (Apply (NthArg '1 $57) (Apply $54 $59)))
- ))) (lambda '($60 $61) (block '(
- (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
- (let $62 (Apply (NthArg '2 $57) (Apply $54 $60) $61))
- (return $62)
- ))) (NthArg '3 $57) (NthArg '4 $57) (NthArg '5 $57) (NthArg '6 $57)))
- (return $58)
- ))) $50 $51 (lambda '($63) (block '(
- (let $64 (AggregationTraits (ListItemType $63) (lambda '($65) (AggrCountInit $65)) (lambda '($66 $67) (AggrCountUpdate $66 $67)) (lambda '($68) $68) (lambda '($69) $69) (lambda '($70 $71) (+ $70 $71)) (lambda '($72) $72)))
- (return $64)
- )))))
- (return $52)
- ))))
- (let $7 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $5)) '"login")) (lambda '($73) $73)))
- (let $8 '('Count1 $7 '"login"))
- (let $9 (Apply $6 (TypeOf $5) (lambda '($74) (Void))))
- (let $10 (Apply $6 (TypeOf $5) (lambda '($75) (Void))))
- (let $11 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $5)) '"login")) (lambda '($76) $76)))
- (let $12 '('Count4 $11 '"login"))
- (let $13 '($8 '('Count2 $9) '('Count3 $10) $12))
- (let $14 (Aggregate $5 '('"client_type" '"week") $13))
- (let $15 (Sort (FlatMap $14 (lambda '($77) (block '(
- (let $78 (AddMember (Struct) '"week" (Member $77 '"week")))
- (let $79 (AddMember $78 '"client_type" (Member $77 '"client_type")))
- (let $80 (AddMember $79 '"users_count" (Member $77 'Count1)))
- (let $81 (AddMember $80 '"operations_count" (Member $77 'Count2)))
- (let $82 (AddMember $81 '"operations_per_user" (/ (Member $77 'Count3) (Member $77 'Count4))))
- (return (AsList $82))
- )))) '((Bool 'false) (Bool 'false)) (lambda '($83) '((Member $83 '"week") (Member $83 '"users_count")))))
- (let $16 '('"week" '"client_type" '"users_count" '"operations_count" '"operations_per_user"))
- (let $17 '('('type) '('autoref) '('columns $16)))
- (let $18 (Write! (Left! $3) $4 (Key) $15 $17))
- (let $19 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
- (let $20 '('"method" '"uri" '"login" '"user_agent" '"millis"))
- (let $21 (Read! (Commit! $18 $4) (DataSource '"yt" '"plato") (Key '('table $19)) $20 '()))
- (let $22 (DataSink 'result))
- (let $23 (FlatMap (Filter (Right! $21) (lambda '($84) (block '(
- (let $85 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/tutorials/")))
- (let $86 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/queries/")))
- (let $87 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/table_data_async")))
- (let $88 (Apply (Udf '"String.HasPrefix") (Member $84 '"login") (String '"robot-")))
- (return (Coalesce (And (Or (And (== (Member $84 '"method") (String '"POST")) (Or (Or (== (Member $84 '"uri") (String '"/api/v2/operations")) $85) $86)) $87) (Not $88)) (Bool 'false)))
- )))) (lambda '($89) (block '(
- (let $90 (AddMember (Struct) '"login" (Member $89 '"login")))
- (let $91 (Apply (Udf '"String.HasPrefix") (Member $89 '"user_agent") (String '"YQL ")))
- (let $92 (Apply (Udf '"String.SplitToList") (Member $89 '"user_agent") (String '" ")))
- (let $93 (SqlAccess 'dict $92 (Int64 '"1")))
- (let $94 (If (Coalesce (== $93 (String '"CLI")) (Bool 'false)) (String '"CLI") (String '"API")))
- (let $95 (If (Coalesce $91 (Bool 'false)) $94 (String '"Web UI")))
- (let $96 (AddMember $90 '"client_type" $95))
- (let $97 (AddMember $96 '"week" (Concat (Concat (Coalesce (Apply (Udf '"DateTime.ToDate") (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $89 '"millis") 'Uint64)))) (String '"")) (String '" - ")) (Coalesce (Apply (Udf '"DateTime.ToDate") (+ (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $89 '"millis") 'Uint64))) (Apply (Udf '"DateTime.FromDays") (Int64 '"6")))) (String '"")))))
- (return (AsList $97))
- )))))
- (let $24 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $23)) '"login")) (lambda '($98) $98)))
- (let $25 '('Count6 $24 '"login"))
- (let $26 (Apply $6 (TypeOf $23) (lambda '($99) (Void))))
- (let $27 (Apply $6 (TypeOf $23) (lambda '($100) (Void))))
- (let $28 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $23)) '"login")) (lambda '($101) $101)))
- (let $29 '('Count9 $28 '"login"))
- (let $30 '($25 '('Count7 $26) '('Count8 $27) $29))
- (let $31 (Aggregate $23 '('"week") $30))
- (let $32 (Sort (FlatMap $31 (lambda '($102) (block '(
- (let $103 (AddMember (Struct) '"week" (Member $102 '"week")))
- (let $104 (AddMember $103 '"users_count" (Member $102 'Count6)))
- (let $105 (AddMember $104 '"operations_count" (Member $102 'Count7)))
- (let $106 (AddMember $105 '"operations_per_user" (/ (Member $102 'Count8) (Member $102 'Count9))))
- (return (AsList $106))
- )))) (Bool 'false) (lambda '($107) (Member $107 '"week"))))
- (let $33 '('"week" '"users_count" '"operations_count" '"operations_per_user"))
- (let $34 '('('type) '('autoref) '('columns $33)))
- (let $35 (Write! (Left! $21) $22 (Key) $32 $34))
- (return (Commit! (Commit! $35 $22) (DataSink '"yt" '"plato")))
- )
- )";
-
- CompileAndCompare(one, two);
- }
-
+ (let $16 (FlatMap $14 $15))
+ (let $17 '('"client_type" '"week"))
+ (let $18 (lambda '($199 $200) (block '(
+ (let $202 (lambda '($205 $206 $207) (block '(
+ (let $209 (ListItemType $205))
+ (let $210 (lambda '($223) (block '(
+ (let $212 (ListItemType $205))
+ (let $213 (InstanceOf $212))
+ (let $214 (Apply $206 $213))
+ (let $215 (TypeOf $214))
+ (let $216 (ListType $215))
+ (let $217 (Apply $207 $216))
+ (let $225 (NthArg '1 $217))
+ (let $226 (Apply $206 $223))
+ (let $227 (Apply $225 $226))
+ (return $227)
+ ))))
+ (let $211 (lambda '($228 $229) (block '(
+ (let $212 (ListItemType $205))
+ (let $213 (InstanceOf $212))
+ (let $214 (Apply $206 $213))
+ (let $215 (TypeOf $214))
+ (let $216 (ListType $215))
+ (let $217 (Apply $207 $216))
+ (let $231 (NthArg '2 $217))
+ (let $232 (Apply $206 $228))
+ (let $233 (Apply $231 $232 $229))
+ (return $233)
+ ))))
+ (let $212 (ListItemType $205))
+ (let $213 (InstanceOf $212))
+ (let $214 (Apply $206 $213))
+ (let $215 (TypeOf $214))
+ (let $216 (ListType $215))
+ (let $217 (Apply $207 $216))
+ (let $218 (NthArg '3 $217))
+ (let $219 (NthArg '4 $217))
+ (let $220 (NthArg '5 $217))
+ (let $221 (NthArg '6 $217))
+ (let $222 (AggregationTraits $209 $210 $211 $218 $219 $220 $221))
+ (return $222)
+ ))))
+ (let $203 (lambda '($234) (block '(
+ (let $236 (ListItemType $234))
+ (let $237 (lambda '($244) (block '(
+ (let $246 (AggrCountInit $244))
+ (return $246)
+ ))))
+ (let $238 (lambda '($247 $248) (block '(
+ (let $250 (AggrCountUpdate $247 $248))
+ (return $250)
+ ))))
+ (let $239 (lambda '($251) (block '(
+ (return $251)
+ ))))
+ (let $240 (lambda '($253) (block '(
+ (return $253)
+ ))))
+ (let $241 (lambda '($255 $256) (block '(
+ (let $258 (+ $255 $256))
+ (return $258)
+ ))))
+ (let $242 (lambda '($259) (block '(
+ (return $259)
+ ))))
+ (let $243 (AggregationTraits $236 $237 $238 $239 $240 $241 $242))
+ (return $243)
+ ))))
+ (let $204 (Apply $202 $199 $200 $203))
+ (return $204)
+ ))))
+ (let $19 (TypeOf $16))
+ (let $20 (ListItemType $19))
+ (let $21 (StructMemberType $20 '"login"))
+ (let $22 (ListType $21))
+ (let $23 (lambda '($261) (block '(
+ (return $261)
+ ))))
+ (let $24 (Apply $18 $22 $23))
+ (let $25 '('Count1 $24 '"login"))
+ (let $26 (TypeOf $16))
+ (let $27 (lambda '($263) (block '(
+ (let $265 (Void))
+ (return $265)
+ ))))
+ (let $28 (Apply $18 $26 $27))
+ (let $29 '('Count2 $28))
+ (let $30 (TypeOf $16))
+ (let $31 (lambda '($266) (block '(
+ (let $268 (Void))
+ (return $268)
+ ))))
+ (let $32 (Apply $18 $30 $31))
+ (let $33 '('Count3 $32))
+ (let $34 (TypeOf $16))
+ (let $35 (ListItemType $34))
+ (let $36 (StructMemberType $35 '"login"))
+ (let $37 (ListType $36))
+ (let $38 (lambda '($269) (block '(
+ (return $269)
+ ))))
+ (let $39 (Apply $18 $37 $38))
+ (let $40 '('Count4 $39 '"login"))
+ (let $41 '($25 $29 $33 $40))
+ (let $42 (Aggregate $16 $17 $41))
+ (let $43 (lambda '($271) (block '(
+ (let $273 (Struct))
+ (let $274 (Member $271 '"week"))
+ (let $275 (AddMember $273 '"week" $274))
+ (let $276 (Member $271 '"client_type"))
+ (let $277 (AddMember $275 '"client_type" $276))
+ (let $278 (Member $271 'Count1))
+ (let $279 (AddMember $277 '"users_count" $278))
+ (let $280 (Member $271 'Count2))
+ (let $281 (AddMember $279 '"operations_count" $280))
+ (let $282 (Member $271 'Count3))
+ (let $283 (Member $271 'Count4))
+ (let $284 (/ $282 $283))
+ (let $285 (AddMember $281 '"operations_per_user" $284))
+ (let $286 (AsList $285))
+ (return $286)
+ ))))
+ (let $44 (FlatMap $42 $43))
+ (let $45 (Bool 'false))
+ (let $46 (Bool 'false))
+ (let $47 '($45 $46))
+ (let $48 (lambda '($287) (block '(
+ (let $289 (Member $287 '"week"))
+ (let $290 (Member $287 '"users_count"))
+ (let $291 '($289 $290))
+ (return $291)
+ ))))
+ (let $49 (Sort $44 $47 $48))
+ (let $50 '('type))
+ (let $51 '('autoref))
+ (let $52 '('"week" '"client_type" '"users_count" '"operations_count" '"operations_per_user"))
+ (let $53 '('columns $52))
+ (let $54 '($50 $51 $53))
+ (let $55 (Write! $9 $10 $11 $49 $54))
+ (let $56 (Commit! $55 $10))
+ (let $57 (DataSource '"yt" '"plato"))
+ (let $58 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
+ (let $59 '('table $58))
+ (let $60 (Key $59))
+ (let $61 '('"method" '"uri" '"login" '"user_agent" '"millis"))
+ (let $62 '())
+ (let $63 (Read! $56 $57 $60 $61 $62))
+ (let $64 (Left! $63))
+ (let $65 (DataSink 'result))
+ (let $66 (Key))
+ (let $67 (Right! $63))
+ (let $68 (lambda '($292) (block '(
+ (let $294 (Member $292 '"method"))
+ (let $295 (String '"POST"))
+ (let $296 (== $294 $295))
+ (let $297 (Member $292 '"uri"))
+ (let $298 (String '"/api/v2/operations"))
+ (let $299 (== $297 $298))
+ (let $300 (Udf '"String.HasPrefix"))
+ (let $301 (Member $292 '"uri"))
+ (let $302 (String '"/api/v2/tutorials/"))
+ (let $303 (Apply $300 $301 $302))
+ (let $304 (Or $299 $303))
+ (let $305 (Udf '"String.HasPrefix"))
+ (let $306 (Member $292 '"uri"))
+ (let $307 (String '"/api/v2/queries/"))
+ (let $308 (Apply $305 $306 $307))
+ (let $309 (Or $304 $308))
+ (let $310 (And $296 $309))
+ (let $311 (Udf '"String.HasPrefix"))
+ (let $312 (Member $292 '"uri"))
+ (let $313 (String '"/api/v2/table_data_async"))
+ (let $314 (Apply $311 $312 $313))
+ (let $315 (Or $310 $314))
+ (let $316 (Udf '"String.HasPrefix"))
+ (let $317 (Member $292 '"login"))
+ (let $318 (String '"robot-"))
+ (let $319 (Apply $316 $317 $318))
+ (let $320 (Not $319))
+ (let $321 (And $315 $320))
+ (let $322 (Bool 'false))
+ (let $323 (Coalesce $321 $322))
+ (return $323)
+ ))))
+ (let $69 (Filter $67 $68))
+ (let $70 (lambda '($324) (block '(
+ (let $326 (Struct))
+ (let $327 (Member $324 '"login"))
+ (let $328 (AddMember $326 '"login" $327))
+ (let $329 (Udf '"String.HasPrefix"))
+ (let $330 (Member $324 '"user_agent"))
+ (let $331 (String '"YQL "))
+ (let $332 (Apply $329 $330 $331))
+ (let $333 (Bool 'false))
+ (let $334 (Coalesce $332 $333))
+ (let $335 (Udf '"String.SplitToList"))
+ (let $336 (Member $324 '"user_agent"))
+ (let $337 (String '" "))
+ (let $338 (Apply $335 $336 $337))
+ (let $339 (Int64 '"1"))
+ (let $340 (SqlAccess 'dict $338 $339))
+ (let $341 (String '"CLI"))
+ (let $342 (== $340 $341))
+ (let $343 (Bool 'false))
+ (let $344 (Coalesce $342 $343))
+ (let $345 (String '"CLI"))
+ (let $346 (String '"API"))
+ (let $347 (If $344 $345 $346))
+ (let $348 (String '"Web UI"))
+ (let $349 (If $334 $347 $348))
+ (let $350 (AddMember $328 '"client_type" $349))
+ (let $351 (Udf '"DateTime.ToDate"))
+ (let $352 (Udf '"DateTime.StartOfWeek"))
+ (let $353 (Udf '"DateTime.FromMilliSeconds"))
+ (let $354 (Member $324 '"millis"))
+ (let $355 (Cast $354 'Uint64))
+ (let $356 (Apply $353 $355))
+ (let $357 (Apply $352 $356))
+ (let $358 (Apply $351 $357))
+ (let $359 (String '""))
+ (let $360 (Coalesce $358 $359))
+ (let $361 (String '" - "))
+ (let $362 (Concat $360 $361))
+ (let $363 (Udf '"DateTime.ToDate"))
+ (let $364 (Udf '"DateTime.StartOfWeek"))
+ (let $365 (Udf '"DateTime.FromMilliSeconds"))
+ (let $366 (Member $324 '"millis"))
+ (let $367 (Cast $366 'Uint64))
+ (let $368 (Apply $365 $367))
+ (let $369 (Apply $364 $368))
+ (let $370 (Udf '"DateTime.FromDays"))
+ (let $371 (Int64 '"6"))
+ (let $372 (Apply $370 $371))
+ (let $373 (+ $369 $372))
+ (let $374 (Apply $363 $373))
+ (let $375 (String '""))
+ (let $376 (Coalesce $374 $375))
+ (let $377 (Concat $362 $376))
+ (let $378 (AddMember $350 '"week" $377))
+ (let $379 (AsList $378))
+ (return $379)
+ ))))
+ (let $71 (FlatMap $69 $70))
+ (let $72 '('"week"))
+ (let $73 (TypeOf $71))
+ (let $74 (ListItemType $73))
+ (let $75 (StructMemberType $74 '"login"))
+ (let $76 (ListType $75))
+ (let $77 (lambda '($380) (block '(
+ (return $380)
+ ))))
+ (let $78 (Apply $18 $76 $77))
+ (let $79 '('Count6 $78 '"login"))
+ (let $80 (TypeOf $71))
+ (let $81 (lambda '($382) (block '(
+ (let $384 (Void))
+ (return $384)
+ ))))
+ (let $82 (Apply $18 $80 $81))
+ (let $83 '('Count7 $82))
+ (let $84 (TypeOf $71))
+ (let $85 (lambda '($385) (block '(
+ (let $387 (Void))
+ (return $387)
+ ))))
+ (let $86 (Apply $18 $84 $85))
+ (let $87 '('Count8 $86))
+ (let $88 (TypeOf $71))
+ (let $89 (ListItemType $88))
+ (let $90 (StructMemberType $89 '"login"))
+ (let $91 (ListType $90))
+ (let $92 (lambda '($388) (block '(
+ (return $388)
+ ))))
+ (let $93 (Apply $18 $91 $92))
+ (let $94 '('Count9 $93 '"login"))
+ (let $95 '($79 $83 $87 $94))
+ (let $96 (Aggregate $71 $72 $95))
+ (let $97 (lambda '($390) (block '(
+ (let $392 (Struct))
+ (let $393 (Member $390 '"week"))
+ (let $394 (AddMember $392 '"week" $393))
+ (let $395 (Member $390 'Count6))
+ (let $396 (AddMember $394 '"users_count" $395))
+ (let $397 (Member $390 'Count7))
+ (let $398 (AddMember $396 '"operations_count" $397))
+ (let $399 (Member $390 'Count8))
+ (let $400 (Member $390 'Count9))
+ (let $401 (/ $399 $400))
+ (let $402 (AddMember $398 '"operations_per_user" $401))
+ (let $403 (AsList $402))
+ (return $403)
+ ))))
+ (let $98 (FlatMap $96 $97))
+ (let $99 (Bool 'false))
+ (let $100 (lambda '($404) (block '(
+ (let $406 (Member $404 '"week"))
+ (return $406)
+ ))))
+ (let $101 (Sort $98 $99 $100))
+ (let $102 '('type))
+ (let $103 '('autoref))
+ (let $104 '('"week" '"users_count" '"operations_count" '"operations_per_user"))
+ (let $105 '('columns $104))
+ (let $106 '($102 $103 $105))
+ (let $107 (Write! $64 $65 $66 $101 $106))
+ (let $108 (Commit! $107 $65))
+ (let $109 (DataSink '"yt" '"plato"))
+ (let $110 (Commit! $108 $109))
+ (return $110)
+ )
+ )";
+
+ const auto two = R"(
+ (
+ (let $1 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
+ (let $2 '('"method" '"uri" '"login" '"user_agent" '"millis"))
+ (let $3 (Read! world (DataSource '"yt" '"plato") (Key '('table $1)) $2 '()))
+ (let $4 (DataSink 'result))
+ (let $5 (FlatMap (Filter (Right! $3) (lambda '($36) (block '(
+ (let $37 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/tutorials/")))
+ (let $38 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/queries/")))
+ (let $39 (Apply (Udf '"String.HasPrefix") (Member $36 '"uri") (String '"/api/v2/table_data_async")))
+ (let $40 (Apply (Udf '"String.HasPrefix") (Member $36 '"login") (String '"robot-")))
+ (return (Coalesce (And (Or (And (== (Member $36 '"method") (String '"POST")) (Or (Or (== (Member $36 '"uri") (String '"/api/v2/operations")) $37) $38)) $39) (Not $40)) (Bool 'false)))
+ )))) (lambda '($41) (block '(
+ (let $42 (AddMember (Struct) '"login" (Member $41 '"login")))
+ (let $43 (Apply (Udf '"String.HasPrefix") (Member $41 '"user_agent") (String '"YQL ")))
+ (let $44 (Apply (Udf '"String.SplitToList") (Member $41 '"user_agent") (String '" ")))
+ (let $45 (SqlAccess 'dict $44 (Int64 '"1")))
+ (let $46 (If (Coalesce (== $45 (String '"CLI")) (Bool 'false)) (String '"CLI") (String '"API")))
+ (let $47 (If (Coalesce $43 (Bool 'false)) $46 (String '"Web UI")))
+ (let $48 (AddMember $42 '"client_type" $47))
+ (let $49 (AddMember $48 '"week" (Concat (Concat (Coalesce (Apply (Udf '"DateTime.ToDate") (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $41 '"millis") 'Uint64)))) (String '"")) (String '" - ")) (Coalesce (Apply (Udf '"DateTime.ToDate") (+ (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $41 '"millis") 'Uint64))) (Apply (Udf '"DateTime.FromDays") (Int64 '"6")))) (String '"")))))
+ (return (AsList $49))
+ )))))
+ (let $6 (lambda '($50 $51) (block '(
+ (let $52 (Apply (lambda '($53 $54 $55) (block '(
+ (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
+ (let $58 (AggregationTraits (ListItemType $53) (lambda '($59) (block '(
+ (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
+ (return (Apply (NthArg '1 $57) (Apply $54 $59)))
+ ))) (lambda '($60 $61) (block '(
+ (let $57 (Apply $55 (ListType (TypeOf (Apply $54 (InstanceOf (ListItemType $53)))))))
+ (let $62 (Apply (NthArg '2 $57) (Apply $54 $60) $61))
+ (return $62)
+ ))) (NthArg '3 $57) (NthArg '4 $57) (NthArg '5 $57) (NthArg '6 $57)))
+ (return $58)
+ ))) $50 $51 (lambda '($63) (block '(
+ (let $64 (AggregationTraits (ListItemType $63) (lambda '($65) (AggrCountInit $65)) (lambda '($66 $67) (AggrCountUpdate $66 $67)) (lambda '($68) $68) (lambda '($69) $69) (lambda '($70 $71) (+ $70 $71)) (lambda '($72) $72)))
+ (return $64)
+ )))))
+ (return $52)
+ ))))
+ (let $7 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $5)) '"login")) (lambda '($73) $73)))
+ (let $8 '('Count1 $7 '"login"))
+ (let $9 (Apply $6 (TypeOf $5) (lambda '($74) (Void))))
+ (let $10 (Apply $6 (TypeOf $5) (lambda '($75) (Void))))
+ (let $11 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $5)) '"login")) (lambda '($76) $76)))
+ (let $12 '('Count4 $11 '"login"))
+ (let $13 '($8 '('Count2 $9) '('Count3 $10) $12))
+ (let $14 (Aggregate $5 '('"client_type" '"week") $13))
+ (let $15 (Sort (FlatMap $14 (lambda '($77) (block '(
+ (let $78 (AddMember (Struct) '"week" (Member $77 '"week")))
+ (let $79 (AddMember $78 '"client_type" (Member $77 '"client_type")))
+ (let $80 (AddMember $79 '"users_count" (Member $77 'Count1)))
+ (let $81 (AddMember $80 '"operations_count" (Member $77 'Count2)))
+ (let $82 (AddMember $81 '"operations_per_user" (/ (Member $77 'Count3) (Member $77 'Count4))))
+ (return (AsList $82))
+ )))) '((Bool 'false) (Bool 'false)) (lambda '($83) '((Member $83 '"week") (Member $83 '"users_count")))))
+ (let $16 '('"week" '"client_type" '"users_count" '"operations_count" '"operations_per_user"))
+ (let $17 '('('type) '('autoref) '('columns $16)))
+ (let $18 (Write! (Left! $3) $4 (Key) $15 $17))
+ (let $19 (MrTableRange '"statbox/yql-log" '"2016-05-25" '"2016-06-01"))
+ (let $20 '('"method" '"uri" '"login" '"user_agent" '"millis"))
+ (let $21 (Read! (Commit! $18 $4) (DataSource '"yt" '"plato") (Key '('table $19)) $20 '()))
+ (let $22 (DataSink 'result))
+ (let $23 (FlatMap (Filter (Right! $21) (lambda '($84) (block '(
+ (let $85 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/tutorials/")))
+ (let $86 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/queries/")))
+ (let $87 (Apply (Udf '"String.HasPrefix") (Member $84 '"uri") (String '"/api/v2/table_data_async")))
+ (let $88 (Apply (Udf '"String.HasPrefix") (Member $84 '"login") (String '"robot-")))
+ (return (Coalesce (And (Or (And (== (Member $84 '"method") (String '"POST")) (Or (Or (== (Member $84 '"uri") (String '"/api/v2/operations")) $85) $86)) $87) (Not $88)) (Bool 'false)))
+ )))) (lambda '($89) (block '(
+ (let $90 (AddMember (Struct) '"login" (Member $89 '"login")))
+ (let $91 (Apply (Udf '"String.HasPrefix") (Member $89 '"user_agent") (String '"YQL ")))
+ (let $92 (Apply (Udf '"String.SplitToList") (Member $89 '"user_agent") (String '" ")))
+ (let $93 (SqlAccess 'dict $92 (Int64 '"1")))
+ (let $94 (If (Coalesce (== $93 (String '"CLI")) (Bool 'false)) (String '"CLI") (String '"API")))
+ (let $95 (If (Coalesce $91 (Bool 'false)) $94 (String '"Web UI")))
+ (let $96 (AddMember $90 '"client_type" $95))
+ (let $97 (AddMember $96 '"week" (Concat (Concat (Coalesce (Apply (Udf '"DateTime.ToDate") (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $89 '"millis") 'Uint64)))) (String '"")) (String '" - ")) (Coalesce (Apply (Udf '"DateTime.ToDate") (+ (Apply (Udf '"DateTime.StartOfWeek") (Apply (Udf '"DateTime.FromMilliSeconds") (Cast (Member $89 '"millis") 'Uint64))) (Apply (Udf '"DateTime.FromDays") (Int64 '"6")))) (String '"")))))
+ (return (AsList $97))
+ )))))
+ (let $24 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $23)) '"login")) (lambda '($98) $98)))
+ (let $25 '('Count6 $24 '"login"))
+ (let $26 (Apply $6 (TypeOf $23) (lambda '($99) (Void))))
+ (let $27 (Apply $6 (TypeOf $23) (lambda '($100) (Void))))
+ (let $28 (Apply $6 (ListType (StructMemberType (ListItemType (TypeOf $23)) '"login")) (lambda '($101) $101)))
+ (let $29 '('Count9 $28 '"login"))
+ (let $30 '($25 '('Count7 $26) '('Count8 $27) $29))
+ (let $31 (Aggregate $23 '('"week") $30))
+ (let $32 (Sort (FlatMap $31 (lambda '($102) (block '(
+ (let $103 (AddMember (Struct) '"week" (Member $102 '"week")))
+ (let $104 (AddMember $103 '"users_count" (Member $102 'Count6)))
+ (let $105 (AddMember $104 '"operations_count" (Member $102 'Count7)))
+ (let $106 (AddMember $105 '"operations_per_user" (/ (Member $102 'Count8) (Member $102 'Count9))))
+ (return (AsList $106))
+ )))) (Bool 'false) (lambda '($107) (Member $107 '"week"))))
+ (let $33 '('"week" '"users_count" '"operations_count" '"operations_per_user"))
+ (let $34 '('('type) '('autoref) '('columns $33)))
+ (let $35 (Write! (Left! $21) $22 (Key) $32 $34))
+ (return (Commit! (Commit! $35 $22) (DataSink '"yt" '"plato")))
+ )
+ )";
+
+ CompileAndCompare(one, two);
+ }
+
Y_UNIT_TEST(DiffrentAtoms) {
- const auto one = "((return (+ '4 (- '3 '2))))";
- const auto two = "((let x '3)\n(let y '1)\n(let z (- x y))\n(let r (+ '4 z))\n(return r))";
-
- const auto diff = std::make_pair(TPosition(23,1), TPosition(9,2));
- CompileAndCompare(one, two, &diff);
- }
-
+ const auto one = "((return (+ '4 (- '3 '2))))";
+ const auto two = "((let x '3)\n(let y '1)\n(let z (- x y))\n(let r (+ '4 z))\n(return r))";
+
+ const auto diff = std::make_pair(TPosition(23,1), TPosition(9,2));
+ CompileAndCompare(one, two, &diff);
+ }
+
Y_UNIT_TEST(DiffrentLists) {
- const auto one = "((return '('7 '4 '('1 '3 '2))))";
- const auto two = "((let x '('1 '3))\n(let y '('7 '4 x))\n(return y))";
-
- const auto diff = std::make_pair(TPosition(20,1), TPosition(11,1));
- CompileAndCompare(one, two, &diff);
- }
-
+ const auto one = "((return '('7 '4 '('1 '3 '2))))";
+ const auto two = "((let x '('1 '3))\n(let y '('7 '4 x))\n(return y))";
+
+ const auto diff = std::make_pair(TPosition(20,1), TPosition(11,1));
+ CompileAndCompare(one, two, &diff);
+ }
+
Y_UNIT_TEST(DiffrentCallables) {
- const auto one = "((return (- '4 (- '3 '2))))";
- const auto two = "((let x '3)\n(let y '2)\n(let z (- x y))\n(let r (+ '4 z))\n(return r))";
-
- const auto diff = std::make_pair(TPosition(11,1), TPosition(9,4));
- CompileAndCompare(one, two, &diff);
- }
-
+ const auto one = "((return (- '4 (- '3 '2))))";
+ const auto two = "((let x '3)\n(let y '2)\n(let z (- x y))\n(let r (+ '4 z))\n(return r))";
+
+ const auto diff = std::make_pair(TPosition(11,1), TPosition(9,4));
+ CompileAndCompare(one, two, &diff);
+ }
+
Y_UNIT_TEST(SwapArguments) {
- const auto one = "((let l (lambda '(x y) (+ x y)))\n(return (Apply l '7 '9)))";
- const auto two = "((return (Apply (lambda '(x y) (+ y x)) '7 '9)))";
-
- const auto diff = std::make_pair(TPosition(19,1), TPosition(29,1));
- CompileAndCompare(one, two, &diff);
- }
-}
-
+ const auto one = "((let l (lambda '(x y) (+ x y)))\n(return (Apply l '7 '9)))";
+ const auto two = "((return (Apply (lambda '(x y) (+ y x)) '7 '9)))";
+
+ const auto diff = std::make_pair(TPosition(19,1), TPosition(29,1));
+ CompileAndCompare(one, two, &diff);
+ }
+}
+
Y_UNIT_TEST_SUITE(TConvertToAst) {
static TString CompileAndDisassemble(const TString& program, bool expectEqualExprs = true) {
- const auto astRes = ParseAst(program);
- UNIT_ASSERT(astRes.IsOk());
- TExprContext exprCtx;
- TExprNode::TPtr exprRoot;
+ const auto astRes = ParseAst(program);
+ UNIT_ASSERT(astRes.IsOk());
+ TExprContext exprCtx;
+ TExprNode::TPtr exprRoot;
UNIT_ASSERT(CompileExpr(*astRes.Root, exprRoot, exprCtx, nullptr));
- UNIT_ASSERT(exprRoot);
-
+ UNIT_ASSERT(exprRoot);
+
const auto convRes = ConvertToAst(*exprRoot, exprCtx, 0, true);
- UNIT_ASSERT(convRes.IsOk());
-
- TExprContext exprCtx2;
- TExprNode::TPtr exprRoot2;
+ UNIT_ASSERT(convRes.IsOk());
+
+ TExprContext exprCtx2;
+ TExprNode::TPtr exprRoot2;
auto compileOk = CompileExpr(*convRes.Root, exprRoot2, exprCtx2, nullptr);
exprCtx2.IssueManager.GetIssues().PrintTo(Cout);
UNIT_ASSERT(compileOk);
- UNIT_ASSERT(exprRoot2);
- const TExprNode* node = exprRoot.Get();
- const TExprNode* node2 = exprRoot2.Get();
+ UNIT_ASSERT(exprRoot2);
+ const TExprNode* node = exprRoot.Get();
+ const TExprNode* node2 = exprRoot2.Get();
bool equal = CompareExprTrees(node, node2);
UNIT_ASSERT(equal == expectEqualExprs);
-
- return convRes.Root->ToString(TAstPrintFlags::PerLine | TAstPrintFlags::ShortQuote);
- }
-
+
+ return convRes.Root->ToString(TAstPrintFlags::PerLine | TAstPrintFlags::ShortQuote);
+ }
+
Y_UNIT_TEST(ManyLambdaWithCaptures) {
- const auto program = R"(
- (
- #comment
- (let mr_source (DataSource 'yt 'plato))
- (let x (Read! world mr_source (Key '('table (String 'Input))) '('key 'subkey 'value) '()))
- (let world (Left! x))
- (let table1 (Right! x))
- (let table1int (FlatMap table1
- (lambda '(item) (block '(
- (let intKey (FromString (Member item 'key) 'Int32))
- (let keyDiv100 (FlatMap intKey (lambda '(x) (/ x (Int32 '100)))))
- (let ret (Map keyDiv100 (lambda '(y) (block '(
- (let r '(y (Member item 'value)))
- (return r)
- )))))
- (return ret)
- )))
- ))
- (let table1intDebug (Map table1int (lambda '(it) (block '(
- (let s (Struct))
- (let s (AddMember s 'key (ToString (Nth it '0))))
- (let s (AddMember s 'subkey (String '.)))
- (let s (AddMember s 'value (Nth it '1)))
- (return s)
- )))))
- (let mr_sink (DataSink 'yt (quote plato)))
- (let world (Write! world mr_sink (Key '('table (String 'Output))) table1intDebug '('('mode 'append))))
- (let world (Commit! world mr_sink))
- (return world)
- )
- )";
- CompileAndDisassemble(program);
- }
-
+ const auto program = R"(
+ (
+ #comment
+ (let mr_source (DataSource 'yt 'plato))
+ (let x (Read! world mr_source (Key '('table (String 'Input))) '('key 'subkey 'value) '()))
+ (let world (Left! x))
+ (let table1 (Right! x))
+ (let table1int (FlatMap table1
+ (lambda '(item) (block '(
+ (let intKey (FromString (Member item 'key) 'Int32))
+ (let keyDiv100 (FlatMap intKey (lambda '(x) (/ x (Int32 '100)))))
+ (let ret (Map keyDiv100 (lambda '(y) (block '(
+ (let r '(y (Member item 'value)))
+ (return r)
+ )))))
+ (return ret)
+ )))
+ ))
+ (let table1intDebug (Map table1int (lambda '(it) (block '(
+ (let s (Struct))
+ (let s (AddMember s 'key (ToString (Nth it '0))))
+ (let s (AddMember s 'subkey (String '.)))
+ (let s (AddMember s 'value (Nth it '1)))
+ (return s)
+ )))))
+ (let mr_sink (DataSink 'yt (quote plato)))
+ (let world (Write! world mr_sink (Key '('table (String 'Output))) table1intDebug '('('mode 'append))))
+ (let world (Commit! world mr_sink))
+ (return world)
+ )
+ )";
+ CompileAndDisassemble(program);
+ }
+
Y_UNIT_TEST(LambdaWithCaptureArgumentOfTopLambda) {
- const auto program = R"(
- (
- (let mr_source (DataSource 'yt 'plato))
- (let x (Read! world mr_source (Key '('table (String 'Input))) '('key 'subkey 'value) '()))
- (let world (Left! x))
- (let table1 (Right! x))
- (let table1low (FlatMap table1 (lambda '(item) (block '(
- (let intValueOpt (FromString (Member item 'key) 'Int32))
- (let ret (FlatMap intValueOpt (lambda '(item2) (block '(
- (return (ListIf (< item2 (Int32 '100)) item))
- )))))
- (return ret)
- )))))
- (let res_sink (DataSink 'result))
- (let data (AsList (String 'x)))
- (let world (Write! world res_sink (Key) table1low '()))
- (let world (Commit! world res_sink))
- (return world)
- )
- )";
- CompileAndDisassemble(program);
- }
-
+ const auto program = R"(
+ (
+ (let mr_source (DataSource 'yt 'plato))
+ (let x (Read! world mr_source (Key '('table (String 'Input))) '('key 'subkey 'value) '()))
+ (let world (Left! x))
+ (let table1 (Right! x))
+ (let table1low (FlatMap table1 (lambda '(item) (block '(
+ (let intValueOpt (FromString (Member item 'key) 'Int32))
+ (let ret (FlatMap intValueOpt (lambda '(item2) (block '(
+ (return (ListIf (< item2 (Int32 '100)) item))
+ )))))
+ (return ret)
+ )))))
+ (let res_sink (DataSink 'result))
+ (let data (AsList (String 'x)))
+ (let world (Write! world res_sink (Key) table1low '()))
+ (let world (Commit! world res_sink))
+ (return world)
+ )
+ )";
+ CompileAndDisassemble(program);
+ }
+
Y_UNIT_TEST(LambdaWithCapture) {
- const auto program = R"(
- (
- (let conf (Configure! world (DataSource 'yt '"$all") '"Attr" '"mapjoinlimit" '"1"))
- (let dsr (DataSink 'result))
- (let dsy (DataSink 'yt 'plato))
- (let co '('key 'subkey 'value))
- (let data (DataSource 'yt 'plato))
- (let string (DataType 'String))
- (let ostr (OptionalType string))
- (let struct (StructType '('key ostr) '('subkey ostr) '('value ostr)))
- (let scheme '('('"scheme" struct)))
- (let temp (MrTempTable dsy '"tmp/bb686f68-2245bd5f-2318fa4e-1" scheme))
- (let str (lambda '(arg) (Just (AsStruct '('key (Just (Member arg 'key))) '('subkey (Just (Member arg 'subkey))) '('value (Just (Member arg 'value)))))))
- (let map (MrMap! world dsy (Key '('table (String 'Input1))) co '() data temp '() str))
- (let tt (MrTempTable dsy '"tmp/7ae6459a-7382d1e7-7935c08e-2" scheme))
- (let map2 (MrMap! world dsy (Key '('table (String 'Input2))) co '() data tt '() str))
- (let s2 (StructType '('"a.key" string) '('"a.subkey" ostr) '('"a.value" ostr) '('"b.key" string) '('"b.subkey" ostr) '('"b.value" ostr)))
- (let mtt3 (MrTempTable dsy '"tmp/ecfc6738-59d47572-b9936849-3" '('('"scheme" s2))))
- (let tuple '('('"take" (Uint64 '"101"))))
- (let lmap (MrLMap! (Sync! map map2) dsy temp co '() data mtt3 '('('"limit" '(tuple))) (lambda '(arg) (block '(
- (let read (MrReadTable! world data tt co '()))
- (let key '('"key"))
- (let wtf '('"Hashed" '"One" '"Compact" '('"ItemsCount" '"4")))
- (let dict (ToDict (FilterNullMembers (MrTableContent read '()) key) (lambda '(arg) (Member arg '"key")) (lambda '(x) x) wtf))
- (let acols '('"key" '"a.key" '"subkey" '"a.subkey" '"value" '"a.value"))
- (let bcols '('"key" '"b.key" '"subkey" '"b.subkey" '"value" '"b.value"))
- (return (MapJoinCore arg dict 'Inner key acols bcols))
- )))))
- (let cols '('"a.key" '"a.subkey" '"a.value" '"b.key" '"b.subkey" '"b.value"))
- (let res (ResPull! conf dsr (Key) (Right! (MrReadTable! lmap data mtt3 cols tuple)) '('('type)) 'yt))
- (return (Commit! res dsr))
- )
- )";
-
- const auto disassembled = CompileAndDisassemble(program);
+ const auto program = R"(
+ (
+ (let conf (Configure! world (DataSource 'yt '"$all") '"Attr" '"mapjoinlimit" '"1"))
+ (let dsr (DataSink 'result))
+ (let dsy (DataSink 'yt 'plato))
+ (let co '('key 'subkey 'value))
+ (let data (DataSource 'yt 'plato))
+ (let string (DataType 'String))
+ (let ostr (OptionalType string))
+ (let struct (StructType '('key ostr) '('subkey ostr) '('value ostr)))
+ (let scheme '('('"scheme" struct)))
+ (let temp (MrTempTable dsy '"tmp/bb686f68-2245bd5f-2318fa4e-1" scheme))
+ (let str (lambda '(arg) (Just (AsStruct '('key (Just (Member arg 'key))) '('subkey (Just (Member arg 'subkey))) '('value (Just (Member arg 'value)))))))
+ (let map (MrMap! world dsy (Key '('table (String 'Input1))) co '() data temp '() str))
+ (let tt (MrTempTable dsy '"tmp/7ae6459a-7382d1e7-7935c08e-2" scheme))
+ (let map2 (MrMap! world dsy (Key '('table (String 'Input2))) co '() data tt '() str))
+ (let s2 (StructType '('"a.key" string) '('"a.subkey" ostr) '('"a.value" ostr) '('"b.key" string) '('"b.subkey" ostr) '('"b.value" ostr)))
+ (let mtt3 (MrTempTable dsy '"tmp/ecfc6738-59d47572-b9936849-3" '('('"scheme" s2))))
+ (let tuple '('('"take" (Uint64 '"101"))))
+ (let lmap (MrLMap! (Sync! map map2) dsy temp co '() data mtt3 '('('"limit" '(tuple))) (lambda '(arg) (block '(
+ (let read (MrReadTable! world data tt co '()))
+ (let key '('"key"))
+ (let wtf '('"Hashed" '"One" '"Compact" '('"ItemsCount" '"4")))
+ (let dict (ToDict (FilterNullMembers (MrTableContent read '()) key) (lambda '(arg) (Member arg '"key")) (lambda '(x) x) wtf))
+ (let acols '('"key" '"a.key" '"subkey" '"a.subkey" '"value" '"a.value"))
+ (let bcols '('"key" '"b.key" '"subkey" '"b.subkey" '"value" '"b.value"))
+ (return (MapJoinCore arg dict 'Inner key acols bcols))
+ )))))
+ (let cols '('"a.key" '"a.subkey" '"a.value" '"b.key" '"b.subkey" '"b.value"))
+ (let res (ResPull! conf dsr (Key) (Right! (MrReadTable! lmap data mtt3 cols tuple)) '('('type)) 'yt))
+ (return (Commit! res dsr))
+ )
+ )";
+
+ const auto disassembled = CompileAndDisassemble(program);
UNIT_ASSERT(TString::npos != disassembled.find("'('key 'subkey 'value)"));
- UNIT_ASSERT_EQUAL(disassembled.find("'('key 'subkey 'value)"), disassembled.rfind("'('key 'subkey 'value)"));
- }
-
+ UNIT_ASSERT_EQUAL(disassembled.find("'('key 'subkey 'value)"), disassembled.rfind("'('key 'subkey 'value)"));
+ }
+
Y_UNIT_TEST(ManyLambdasWithCommonCapture) {
- const auto program = R"(
- (
- (let c42 (+ (Int64 '40) (Int64 '2)))
- (let c100 (Int64 '100))
- (let l0 (lambda '(x) (- (* x c42) c42)))
- (let l1 (lambda '(y) (Apply l0 y)))
- (let l2 (lambda '(z) (+ (* c42) (Apply l0 c42))))
- (return (* (Apply l1 c100)(Apply l2 c100)))
- )
- )";
-
- const auto disassembled = CompileAndDisassemble(program);
+ const auto program = R"(
+ (
+ (let c42 (+ (Int64 '40) (Int64 '2)))
+ (let c100 (Int64 '100))
+ (let l0 (lambda '(x) (- (* x c42) c42)))
+ (let l1 (lambda '(y) (Apply l0 y)))
+ (let l2 (lambda '(z) (+ (* c42) (Apply l0 c42))))
+ (return (* (Apply l1 c100)(Apply l2 c100)))
+ )
+ )";
+
+ const auto disassembled = CompileAndDisassemble(program);
UNIT_ASSERT(TString::npos != disassembled.find("(+ (Int64 '40) (Int64 '2))"));
- UNIT_ASSERT_EQUAL(disassembled.find("(+ (Int64 '40) (Int64 '2))"), disassembled.rfind("(+ (Int64 '40) (Int64 '2))"));
- }
-
+ UNIT_ASSERT_EQUAL(disassembled.find("(+ (Int64 '40) (Int64 '2))"), disassembled.rfind("(+ (Int64 '40) (Int64 '2))"));
+ }
+
Y_UNIT_TEST(CapturedUseInTopLevelAfrerLambda) {
- const auto program = R"(
- (
- (let $1 (DataSink 'result))
- (let $2 (DataSink '"yt" '"plato"))
- (let $3 (DataSource '"yt" '"plato"))
- (let $4 (TupleType (DataType 'Int64) (DataType 'Uint64)))
- (let $5 (MrTempTable $2 '"tmp/ecfc6738-59d47572-b9936849-3" '('('"scheme" (StructType '('"key" (DataType 'String)) '('"value" (StructType '('Avg1 (OptionalType $4)) '('Avg2 $4))))))))
- (let $6 (MrMapCombine! world $2 (Key '('table (String '"Input"))) '('"key" '"subkey") '() $3 $5 '() (lambda '($13) (Just (AsStruct '('"key" (Cast (Member $13 '"key") 'Int64)) '('"sub" (Unwrap (Cast (Member $13 '"subkey") 'Int64)))))) (lambda '($14) (Uint32 '"0")) (lambda '($15 $16) (block '(
- (let $18 (Uint64 '1))
- (let $17 (IfPresent (Member $16 '"key") (lambda '($19) (Just '($19 $18))) (Nothing (OptionalType (TupleType (DataType 'Int64) (DataType 'Uint64))))))
- (return (AsStruct '('Avg1 $17) '('Avg2 '((Member $16 '"sub") $18))))
- ))) (lambda '($20 $21 $22) (block '(
- (let $23 (IfPresent (Member $21 '"key") (lambda '($28) (block '(
- (let $29 (Uint64 '1))
- (return (Just '($28 $29)))
- ))) (Nothing (OptionalType (TupleType (DataType 'Int64) (DataType 'Uint64))))))
- (let $24 (IfPresent (Member $22 'Avg1) (lambda '($26) (IfPresent (Member $21 '"key") (lambda '($27) (Just '((+ (Nth $26 '0) $27) (Inc (Nth $26 '1))))) (Just $26))) $23))
- (let $25 (Member $22 'Avg2))
- (return (AsStruct '('Avg1 $24) '('Avg2 '((+ (Nth $25 '0) (Member $21 '"sub")) (Inc (Nth $25 '1))))))
- ))) (lambda '($30 $31) (Just (AsStruct '('"value" $31) '('"key" (String '"")))))))
- (return $6)
- )
- )";
-
- CompileAndDisassemble(program);
- }
-
+ const auto program = R"(
+ (
+ (let $1 (DataSink 'result))
+ (let $2 (DataSink '"yt" '"plato"))
+ (let $3 (DataSource '"yt" '"plato"))
+ (let $4 (TupleType (DataType 'Int64) (DataType 'Uint64)))
+ (let $5 (MrTempTable $2 '"tmp/ecfc6738-59d47572-b9936849-3" '('('"scheme" (StructType '('"key" (DataType 'String)) '('"value" (StructType '('Avg1 (OptionalType $4)) '('Avg2 $4))))))))
+ (let $6 (MrMapCombine! world $2 (Key '('table (String '"Input"))) '('"key" '"subkey") '() $3 $5 '() (lambda '($13) (Just (AsStruct '('"key" (Cast (Member $13 '"key") 'Int64)) '('"sub" (Unwrap (Cast (Member $13 '"subkey") 'Int64)))))) (lambda '($14) (Uint32 '"0")) (lambda '($15 $16) (block '(
+ (let $18 (Uint64 '1))
+ (let $17 (IfPresent (Member $16 '"key") (lambda '($19) (Just '($19 $18))) (Nothing (OptionalType (TupleType (DataType 'Int64) (DataType 'Uint64))))))
+ (return (AsStruct '('Avg1 $17) '('Avg2 '((Member $16 '"sub") $18))))
+ ))) (lambda '($20 $21 $22) (block '(
+ (let $23 (IfPresent (Member $21 '"key") (lambda '($28) (block '(
+ (let $29 (Uint64 '1))
+ (return (Just '($28 $29)))
+ ))) (Nothing (OptionalType (TupleType (DataType 'Int64) (DataType 'Uint64))))))
+ (let $24 (IfPresent (Member $22 'Avg1) (lambda '($26) (IfPresent (Member $21 '"key") (lambda '($27) (Just '((+ (Nth $26 '0) $27) (Inc (Nth $26 '1))))) (Just $26))) $23))
+ (let $25 (Member $22 'Avg2))
+ (return (AsStruct '('Avg1 $24) '('Avg2 '((+ (Nth $25 '0) (Member $21 '"sub")) (Inc (Nth $25 '1))))))
+ ))) (lambda '($30 $31) (Just (AsStruct '('"value" $31) '('"key" (String '"")))))))
+ (return $6)
+ )
+ )";
+
+ CompileAndDisassemble(program);
+ }
+
Y_UNIT_TEST(SelectCommonAncestor) {
- const auto program = R"(
- (
- (let $1 (DataSink 'result))
- (let $2 (DataSink '"yt" '"plato"))
- (let $3 '('"key" '"value"))
- (let $4 (DataSource '"yt" '"plato"))
- (let $5 (DataType 'String))
- (let $6 (OptionalType $5))
- (let $7 (MrTempTable $2 '"tmp/41c7eb81-87a9f8b6-70daa714-11" '('('"scheme" (StructType '('"key" $5) '('"value" (StructType '('Histogram0 $6) '('Histogram1 $6))))))))
- (let $8 (Udf 'Histogram.AdaptiveWardHistogram_Create (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'Double)) '((DataType 'Double)) '((DataType 'Uint32)))))
- (let $9 (Double '1.0))
- (let $10 (Cast (Int32 '"1") 'Uint32))
- (let $11 (Double '1.0))
- (let $12 (Cast (Int32 '"1000000") 'Uint32))
- (let $13 (MrMapCombine! world $2 (Key '('table (String '"Input"))) $3 '() $4 $7 '() (lambda '($21) (Just $21)) (lambda '($22) (Uint32 '"0")) (lambda '($23 $24) (AsStruct '('Histogram0 (FlatMap (Cast (Member $24 '"key") 'Double) (lambda '($25) (block '(
- (let $26 '((DataType 'Double)))
- (let $27 (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) $26 $26 '((DataType 'Uint32))))
- (let $28 '((Unwrap (Cast (Member $24 '"key") 'Double)) $9 $10))
- (return (Just (NamedApply $8 $28 (AsStruct) (Uint32 '"0"))))
- ))))) '('Histogram1 (FlatMap (Cast (Member $24 '"value") 'Double) (lambda '($29) (block '(
- (let $30 '((Unwrap (Cast (Member $24 '"value") 'Double)) $11 $12))
- (return (Just (NamedApply $8 $30 (AsStruct) (Uint32 '"1"))))
- ))))))) (lambda '($31 $32 $33) (block '(
- (let $34 (Udf 'Histogram.AdaptiveWardHistogram_AddValue (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'Double)) '((DataType 'Double)))))
- (let $35 (Uint32 '"0"))
- (let $36 (IfPresent (Member $33 'Histogram0) (lambda '($39) (block '(
- (let $40 (Cast (Member $32 '"key") 'Double))
- (let $41 '((ResourceType '"Histogram.AdaptiveWard")))
- (let $42 '((DataType 'Double)))
- (let $43 (CallableType '() $41 $41 $42 $42))
- (let $44 '($39 (Unwrap $40) $9))
- (let $45 (NamedApply $34 $44 (AsStruct) $35))
- (return (Just (If (Exists $40) $45 $39)))
- ))) (FlatMap (Cast (Member $32 '"key") 'Double) (lambda '($46) (block '(
- (let $47 '((Unwrap (Cast (Member $32 '"key") 'Double)) $9 $10))
- (return (Just (NamedApply $8 $47 (AsStruct) $35)))
- ))))))
- (let $37 (Uint32 '"1"))
- (let $38 (IfPresent (Member $33 'Histogram1) (lambda '($48) (block '(
- (let $49 (Cast (Member $32 '"value") 'Double))
- (let $50 '($48 (Unwrap $49) $11))
- (let $51 (NamedApply $34 $50 (AsStruct) $37))
- (return (Just (If (Exists $49) $51 $48)))
- ))) (FlatMap (Cast (Member $32 '"value") 'Double) (lambda '($52) (block '(
- (let $53 '((Unwrap (Cast (Member $32 '"value") 'Double)) $11 $12))
- (return (Just (NamedApply $8 $53 (AsStruct) $37)))
- ))))))
- (return (AsStruct '('Histogram0 $36) '('Histogram1 $38)))
- ))) (lambda '($54 $55) (block '(
- (let $56 (lambda '($57) (block '(
- (let $58 (CallableType '() '((DataType 'String)) '((ResourceType '"Histogram.AdaptiveWard"))))
- (let $59 (Udf 'Histogram.AdaptiveWardHistogram_Serialize (Void) (VoidType) '"" $58))
- (return (Just (Apply $59 $57)))
- ))))
- (return (Just (AsStruct '('"value" (AsStruct '('Histogram0 (FlatMap (Member $55 'Histogram0) $56)) '('Histogram1 (FlatMap (Member $55 'Histogram1) $56)))) '('"key" (String '"")))))
- )))))
- (let $14 (DataType 'Double))
- (let $15 (OptionalType (StructType '('"Bins" (ListType (StructType '('"Frequency" $14) '('"Position" $14)))) '('"Max" $14) '('"Min" $14) '('"WeightsSum" $14))))
- (let $16 (MrTempTable $2 '"tmp/b6d6c3ee-30bb3e55-ea0c48bc-12" '('('"scheme" (StructType '('"key_histogram" $15) '('"value_histogram" $15))))))
- (let $17 (MrReduce! $13 $2 $7 $3 '() $4 $16 '('('"reduceBy" '('"key"))) (lambda '($60 $61) (block '(
- (let $67 (Udf 'Histogram.AdaptiveWardHistogram_Deserialize (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'String)) '((DataType 'Uint32)))))
- (let $62 (lambda '($68) (block '(
- (let $69 (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'String)) '((DataType 'Uint32))))
- (return (Just (Apply $67 $68 $10)))
- ))))
- (let $63 (lambda '($70) (Just (Apply $67 $70 $12))))
- (let $64 (Fold1 (FlatMap $61 (lambda '($65) (Just (Member $65 '"value")))) (lambda '($66) (block '(
- (return (AsStruct '('Histogram0 (FlatMap (Member $66 'Histogram0) $62)) '('Histogram1 (FlatMap (Member $66 'Histogram1) $63))))
- ))) (lambda '($71 $72) (block '(
- (let $73 (lambda '($76 $77) (block '(
- (let $78 '((ResourceType '"Histogram.AdaptiveWard")))
- (let $79 (CallableType '() $78 $78 $78))
- (let $80 (Udf 'Histogram.AdaptiveWardHistogram_Merge (Void) (VoidType) '"" $79))
- (return (Apply $80 $76 $77))
- ))))
- (let $74 (OptionalReduce (FlatMap (Member $71 'Histogram0) $62) (Member $72 'Histogram0) $73))
- (let $75 (OptionalReduce (FlatMap (Member $71 'Histogram1) $63) (Member $72 'Histogram1) $73))
- (return (AsStruct '('Histogram0 $74) '('Histogram1 $75)))
- )))))
- (return (FlatMap $64 (lambda '($81) (block '(
- (let $82 (lambda '($83) (block '(
- (let $84 (DataType 'Double))
- (let $85 (CallableType '() '((StructType '('"Bins" (ListType (StructType '('"Frequency" $84) '('"Position" $84)))) '('"Max" $84) '('"Min" $84) '('"WeightsSum" $84))) '((ResourceType '"Histogram.AdaptiveWard"))))
- (let $86 (Udf 'Histogram.AdaptiveWardHistogram_GetResult (Void) (VoidType) '"" $85))
- (return (Just (Apply $86 $83)))
- ))))
- (return (AsList (AsStruct '('"key_histogram" (FlatMap (Member $81 'Histogram0) $82)) '('"value_histogram" (FlatMap (Member $81 'Histogram1) $82)))))
- )))))
- )))))
- (let $18 '('"key_histogram" '"value_histogram"))
- (let $19 '('('type) '('autoref) '('columns $18)))
- (let $20 (ResPull! world $1 (Key) (Right! (MrReadTable! $17 $4 $16 $18 '())) $19 '"yt"))
- (return (Commit! (Commit! $20 $1) $2 '('('"epoch" '"1"))))
- )
- )";
-
- CompileAndDisassemble(program);
- }
-
+ const auto program = R"(
+ (
+ (let $1 (DataSink 'result))
+ (let $2 (DataSink '"yt" '"plato"))
+ (let $3 '('"key" '"value"))
+ (let $4 (DataSource '"yt" '"plato"))
+ (let $5 (DataType 'String))
+ (let $6 (OptionalType $5))
+ (let $7 (MrTempTable $2 '"tmp/41c7eb81-87a9f8b6-70daa714-11" '('('"scheme" (StructType '('"key" $5) '('"value" (StructType '('Histogram0 $6) '('Histogram1 $6))))))))
+ (let $8 (Udf 'Histogram.AdaptiveWardHistogram_Create (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'Double)) '((DataType 'Double)) '((DataType 'Uint32)))))
+ (let $9 (Double '1.0))
+ (let $10 (Cast (Int32 '"1") 'Uint32))
+ (let $11 (Double '1.0))
+ (let $12 (Cast (Int32 '"1000000") 'Uint32))
+ (let $13 (MrMapCombine! world $2 (Key '('table (String '"Input"))) $3 '() $4 $7 '() (lambda '($21) (Just $21)) (lambda '($22) (Uint32 '"0")) (lambda '($23 $24) (AsStruct '('Histogram0 (FlatMap (Cast (Member $24 '"key") 'Double) (lambda '($25) (block '(
+ (let $26 '((DataType 'Double)))
+ (let $27 (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) $26 $26 '((DataType 'Uint32))))
+ (let $28 '((Unwrap (Cast (Member $24 '"key") 'Double)) $9 $10))
+ (return (Just (NamedApply $8 $28 (AsStruct) (Uint32 '"0"))))
+ ))))) '('Histogram1 (FlatMap (Cast (Member $24 '"value") 'Double) (lambda '($29) (block '(
+ (let $30 '((Unwrap (Cast (Member $24 '"value") 'Double)) $11 $12))
+ (return (Just (NamedApply $8 $30 (AsStruct) (Uint32 '"1"))))
+ ))))))) (lambda '($31 $32 $33) (block '(
+ (let $34 (Udf 'Histogram.AdaptiveWardHistogram_AddValue (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'Double)) '((DataType 'Double)))))
+ (let $35 (Uint32 '"0"))
+ (let $36 (IfPresent (Member $33 'Histogram0) (lambda '($39) (block '(
+ (let $40 (Cast (Member $32 '"key") 'Double))
+ (let $41 '((ResourceType '"Histogram.AdaptiveWard")))
+ (let $42 '((DataType 'Double)))
+ (let $43 (CallableType '() $41 $41 $42 $42))
+ (let $44 '($39 (Unwrap $40) $9))
+ (let $45 (NamedApply $34 $44 (AsStruct) $35))
+ (return (Just (If (Exists $40) $45 $39)))
+ ))) (FlatMap (Cast (Member $32 '"key") 'Double) (lambda '($46) (block '(
+ (let $47 '((Unwrap (Cast (Member $32 '"key") 'Double)) $9 $10))
+ (return (Just (NamedApply $8 $47 (AsStruct) $35)))
+ ))))))
+ (let $37 (Uint32 '"1"))
+ (let $38 (IfPresent (Member $33 'Histogram1) (lambda '($48) (block '(
+ (let $49 (Cast (Member $32 '"value") 'Double))
+ (let $50 '($48 (Unwrap $49) $11))
+ (let $51 (NamedApply $34 $50 (AsStruct) $37))
+ (return (Just (If (Exists $49) $51 $48)))
+ ))) (FlatMap (Cast (Member $32 '"value") 'Double) (lambda '($52) (block '(
+ (let $53 '((Unwrap (Cast (Member $32 '"value") 'Double)) $11 $12))
+ (return (Just (NamedApply $8 $53 (AsStruct) $37)))
+ ))))))
+ (return (AsStruct '('Histogram0 $36) '('Histogram1 $38)))
+ ))) (lambda '($54 $55) (block '(
+ (let $56 (lambda '($57) (block '(
+ (let $58 (CallableType '() '((DataType 'String)) '((ResourceType '"Histogram.AdaptiveWard"))))
+ (let $59 (Udf 'Histogram.AdaptiveWardHistogram_Serialize (Void) (VoidType) '"" $58))
+ (return (Just (Apply $59 $57)))
+ ))))
+ (return (Just (AsStruct '('"value" (AsStruct '('Histogram0 (FlatMap (Member $55 'Histogram0) $56)) '('Histogram1 (FlatMap (Member $55 'Histogram1) $56)))) '('"key" (String '"")))))
+ )))))
+ (let $14 (DataType 'Double))
+ (let $15 (OptionalType (StructType '('"Bins" (ListType (StructType '('"Frequency" $14) '('"Position" $14)))) '('"Max" $14) '('"Min" $14) '('"WeightsSum" $14))))
+ (let $16 (MrTempTable $2 '"tmp/b6d6c3ee-30bb3e55-ea0c48bc-12" '('('"scheme" (StructType '('"key_histogram" $15) '('"value_histogram" $15))))))
+ (let $17 (MrReduce! $13 $2 $7 $3 '() $4 $16 '('('"reduceBy" '('"key"))) (lambda '($60 $61) (block '(
+ (let $67 (Udf 'Histogram.AdaptiveWardHistogram_Deserialize (Void) (VoidType) '"" (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'String)) '((DataType 'Uint32)))))
+ (let $62 (lambda '($68) (block '(
+ (let $69 (CallableType '() '((ResourceType '"Histogram.AdaptiveWard")) '((DataType 'String)) '((DataType 'Uint32))))
+ (return (Just (Apply $67 $68 $10)))
+ ))))
+ (let $63 (lambda '($70) (Just (Apply $67 $70 $12))))
+ (let $64 (Fold1 (FlatMap $61 (lambda '($65) (Just (Member $65 '"value")))) (lambda '($66) (block '(
+ (return (AsStruct '('Histogram0 (FlatMap (Member $66 'Histogram0) $62)) '('Histogram1 (FlatMap (Member $66 'Histogram1) $63))))
+ ))) (lambda '($71 $72) (block '(
+ (let $73 (lambda '($76 $77) (block '(
+ (let $78 '((ResourceType '"Histogram.AdaptiveWard")))
+ (let $79 (CallableType '() $78 $78 $78))
+ (let $80 (Udf 'Histogram.AdaptiveWardHistogram_Merge (Void) (VoidType) '"" $79))
+ (return (Apply $80 $76 $77))
+ ))))
+ (let $74 (OptionalReduce (FlatMap (Member $71 'Histogram0) $62) (Member $72 'Histogram0) $73))
+ (let $75 (OptionalReduce (FlatMap (Member $71 'Histogram1) $63) (Member $72 'Histogram1) $73))
+ (return (AsStruct '('Histogram0 $74) '('Histogram1 $75)))
+ )))))
+ (return (FlatMap $64 (lambda '($81) (block '(
+ (let $82 (lambda '($83) (block '(
+ (let $84 (DataType 'Double))
+ (let $85 (CallableType '() '((StructType '('"Bins" (ListType (StructType '('"Frequency" $84) '('"Position" $84)))) '('"Max" $84) '('"Min" $84) '('"WeightsSum" $84))) '((ResourceType '"Histogram.AdaptiveWard"))))
+ (let $86 (Udf 'Histogram.AdaptiveWardHistogram_GetResult (Void) (VoidType) '"" $85))
+ (return (Just (Apply $86 $83)))
+ ))))
+ (return (AsList (AsStruct '('"key_histogram" (FlatMap (Member $81 'Histogram0) $82)) '('"value_histogram" (FlatMap (Member $81 'Histogram1) $82)))))
+ )))))
+ )))))
+ (let $18 '('"key_histogram" '"value_histogram"))
+ (let $19 '('('type) '('autoref) '('columns $18)))
+ (let $20 (ResPull! world $1 (Key) (Right! (MrReadTable! $17 $4 $16 $18 '())) $19 '"yt"))
+ (return (Commit! (Commit! $20 $1) $2 '('('"epoch" '"1"))))
+ )
+ )";
+
+ CompileAndDisassemble(program);
+ }
+
Y_UNIT_TEST(Parameters) {
const auto program = R"(
(
@@ -1213,6 +1213,6 @@ Y_UNIT_TEST_SUITE(TConvertToAst) {
UNIT_ASSERT(TString::npos != disassembled.find("(declare $Group (DataType 'Uint32))"));
UNIT_ASSERT(TString::npos != disassembled.find("(declare $Name (OptionalType (DataType 'String)))"));
}
-}
-
+}
+
} // namespace NYql
diff --git a/ydb/library/yql/ast/yql_gc_nodes.h b/ydb/library/yql/ast/yql_gc_nodes.h
index f1fbb9c028..59c35d5a51 100644
--- a/ydb/library/yql/ast/yql_gc_nodes.h
+++ b/ydb/library/yql/ast/yql_gc_nodes.h
@@ -1,6 +1,6 @@
#pragma once
-#include <util/system/types.h>
+#include <util/system/types.h>
namespace NYql {
@@ -14,7 +14,7 @@ struct TGcNodeStatistics {
ui64 TotalCollectedNodes = 0;
};
-struct TGcNodeConfig {
+struct TGcNodeConfig {
TGcNodeSettings Settings;
TGcNodeStatistics Statistics;
};
diff --git a/ydb/library/yql/ast/yql_type_string.cpp b/ydb/library/yql/ast/yql_type_string.cpp
index bc28006455..af9af93259 100644
--- a/ydb/library/yql/ast/yql_type_string.cpp
+++ b/ydb/library/yql/ast/yql_type_string.cpp
@@ -62,7 +62,7 @@ enum EToken
TOKEN_DATETIME = -30,
TOKEN_TIMESTAMP = -31,
TOKEN_INTERVAL = -32,
- TOKEN_DECIMAL = -33,
+ TOKEN_DECIMAL = -33,
TOKEN_INT8 = -34,
TOKEN_UINT8 = -35,
TOKEN_INT16 = -36,
@@ -215,10 +215,10 @@ private:
GetNextToken();
break;
- case TOKEN_DECIMAL:
- type = ParseDecimalType();
- break;
-
+ case TOKEN_DECIMAL:
+ type = ParseDecimalType();
+ break;
+
case TOKEN_LIST:
type = ParseListType();
break;
@@ -344,7 +344,7 @@ private:
Identifier = {};
char lastChar = Get();
- if (lastChar == '_' || isalnum(lastChar)) { // identifier
+ if (lastChar == '_' || isalnum(lastChar)) { // identifier
size_t start = Index;
while (!AtEnd()) {
lastChar = Get();
@@ -621,23 +621,23 @@ private:
return MakeFlowType(itemType);
}
- TAstNode* ParseDecimalType() {
- GetNextToken(); // eat keyword
- EXPECT_AND_SKIP_TOKEN('(', nullptr);
-
- const auto precision = Identifier;
- GetNextToken(); // eat keyword
-
- EXPECT_AND_SKIP_TOKEN(',', nullptr);
-
- const auto scale = Identifier;
- GetNextToken(); // eat keyword
-
- EXPECT_AND_SKIP_TOKEN(')', nullptr);
-
- return MakeDecimalType(precision, scale);
- }
-
+ TAstNode* ParseDecimalType() {
+ GetNextToken(); // eat keyword
+ EXPECT_AND_SKIP_TOKEN('(', nullptr);
+
+ const auto precision = Identifier;
+ GetNextToken(); // eat keyword
+
+ EXPECT_AND_SKIP_TOKEN(',', nullptr);
+
+ const auto scale = Identifier;
+ GetNextToken(); // eat keyword
+
+ EXPECT_AND_SKIP_TOKEN(')', nullptr);
+
+ return MakeDecimalType(precision, scale);
+ }
+
TAstNode* ParseOptionalType() {
GetNextToken(); // eat keyword
EXPECT_AND_SKIP_TOKEN('<', nullptr);
@@ -1012,16 +1012,16 @@ private:
return MakeList(items, Y_ARRAY_SIZE(items));
}
- TAstNode* MakeDecimalType(TStringBuf precision, TStringBuf scale) {
- TAstNode* items[] = {
+ TAstNode* MakeDecimalType(TStringBuf precision, TStringBuf scale) {
+ TAstNode* items[] = {
MakeLiteralAtom(TStringBuf("DataType")),
MakeQuotedAtom(TStringBuf("Decimal")),
- MakeQuotedAtom(precision),
- MakeQuotedAtom(scale),
- };
- return MakeList(items, Y_ARRAY_SIZE(items));
- }
-
+ MakeQuotedAtom(precision),
+ MakeQuotedAtom(scale),
+ };
+ return MakeList(items, Y_ARRAY_SIZE(items));
+ }
+
TAstNode* MakeOptionalType(TAstNode* type) {
TAstNode* items[] = {
MakeLiteralAtom(TStringBuf("OptionalType")),
@@ -1113,16 +1113,16 @@ private:
void Visit(const TMultiExprType& type) final {
Out_ << TStringBuf("Multi<");
- const auto& items = type.GetItems();
- for (ui32 i = 0; i < items.size(); ++i) {
- if (i) {
- Out_ << ',';
- }
- items[i]->Accept(*this);
- }
- Out_ << '>';
- }
-
+ const auto& items = type.GetItems();
+ for (ui32 i = 0; i < items.size(); ++i) {
+ if (i) {
+ Out_ << ',';
+ }
+ items[i]->Accept(*this);
+ }
+ Out_ << '>';
+ }
+
void Visit(const TTupleExprType& type) final {
Out_ << TStringBuf("Tuple<");
const auto& items = type.GetItems();
@@ -1167,15 +1167,15 @@ private:
void Visit(const TFlowExprType& type) final {
Out_ << TStringBuf("Flow<");
- type.GetItemType()->Accept(*this);
- Out_ << '>';
- }
-
+ type.GetItemType()->Accept(*this);
+ Out_ << '>';
+ }
+
void Visit(const TDataExprType& type) final {
Out_ << type.GetName();
- if (const auto dataExprParamsType = dynamic_cast<const TDataExprParamsType*>(&type)) {
- Out_ << '(' << dataExprParamsType->GetParamOne() << ',' << dataExprParamsType->GetParamTwo() << ')';
- }
+ if (const auto dataExprParamsType = dynamic_cast<const TDataExprParamsType*>(&type)) {
+ Out_ << '(' << dataExprParamsType->GetParamOne() << ',' << dataExprParamsType->GetParamTwo() << ')';
+ }
}
void Visit(const TWorldExprType& type) final {
diff --git a/ydb/library/yql/ast/yql_type_string_ut.cpp b/ydb/library/yql/ast/yql_type_string_ut.cpp
index bd673fb2fa..2f22c42258 100644
--- a/ydb/library/yql/ast/yql_type_string_ut.cpp
+++ b/ydb/library/yql/ast/yql_type_string_ut.cpp
@@ -58,7 +58,7 @@ Y_UNIT_TEST_SUITE(TTypeString)
TestOk("TzDatetime", "(DataType 'TzDatetime)");
TestOk("TzTimestamp", "(DataType 'TzTimestamp)");
TestOk("Uuid", "(DataType 'Uuid)");
- TestOk("Decimal(10,2)", "(DataType 'Decimal '10 '2)");
+ TestOk("Decimal(10,2)", "(DataType 'Decimal '10 '2)");
}
Y_UNIT_TEST(Multiline) {
@@ -551,10 +551,10 @@ Y_UNIT_TEST_SUITE(TTypeString)
"Struct<'Age':Uint32,'Male':Bool,'Name':String>");
}
- Y_UNIT_TEST(FormatDecimal) {
- TestFormat("((Data Decimal 10 3))", "Decimal(10,3)");
- }
-
+ Y_UNIT_TEST(FormatDecimal) {
+ TestFormat("((Data Decimal 10 3))", "Decimal(10,3)");
+ }
+
Y_UNIT_TEST(FormatList) {
TestFormat("((List (Data String)))", "List<String>");
}
diff --git a/ydb/library/yql/core/common_opt/yql_co.h b/ydb/library/yql/core/common_opt/yql_co.h
index 75ff8d01c9..b8f2719037 100644
--- a/ydb/library/yql/core/common_opt/yql_co.h
+++ b/ydb/library/yql/core/common_opt/yql_co.h
@@ -11,33 +11,33 @@ struct TOptimizeContext {
TTypeAnnotationContext* Types = nullptr;
TParentsMap* ParentsMap = nullptr;
- const TExprNode* GetParentIfSingle(const TExprNode& node) const {
+ const TExprNode* GetParentIfSingle(const TExprNode& node) const {
YQL_ENSURE(ParentsMap);
- const auto it = ParentsMap->find(&node);
+ const auto it = ParentsMap->find(&node);
YQL_ENSURE(it != ParentsMap->cend());
auto& parents = it->second;
YQL_ENSURE(!parents.empty());
if (parents.size() > 1) {
- return nullptr;
+ return nullptr;
}
size_t usageCount = 0;
- for (const auto& child : (*parents.cbegin())->ChildrenList()) {
+ for (const auto& child : (*parents.cbegin())->ChildrenList()) {
if (child.Get() == &node && ++usageCount > 1) {
- return nullptr;
+ return nullptr;
}
}
YQL_ENSURE(usageCount == 1);
- return *parents.cbegin();
+ return *parents.cbegin();
+ }
+
+ bool IsSingleUsage(const TExprNode& node) const {
+ return bool(GetParentIfSingle(node));
}
- bool IsSingleUsage(const TExprNode& node) const {
- return bool(GetParentIfSingle(node));
- }
-
bool IsSingleUsage(const NNodes::TExprBase& node) const {
return IsSingleUsage(node.Ref());
}
@@ -71,9 +71,9 @@ struct TOptimizeContext {
};
using TCallableOptimizerExt = std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&, TOptimizeContext&)>;
-using TCallableOptimizerMap = std::unordered_map<std::string_view, TCallableOptimizerExt>;
+using TCallableOptimizerMap = std::unordered_map<std::string_view, TCallableOptimizerExt>;
using TFinalizingOptimizerExt = std::function<void (const TExprNode::TPtr&, TNodeOnNodeOwnedMap&, TExprContext&, TOptimizeContext&)>;
-using TFinalizingOptimizerMap = std::unordered_map<std::string_view, TFinalizingOptimizerExt>;
+using TFinalizingOptimizerMap = std::unordered_map<std::string_view, TFinalizingOptimizerExt>;
struct TCoCallableRules {
enum {
diff --git a/ydb/library/yql/core/common_opt/yql_co_extr_members.cpp b/ydb/library/yql/core/common_opt/yql_co_extr_members.cpp
index e2b66d0b7b..215a1e9f69 100644
--- a/ydb/library/yql/core/common_opt/yql_co_extr_members.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_extr_members.cpp
@@ -13,7 +13,7 @@ using namespace NNodes;
TExprNode::TPtr ApplyExtractMembersToTake(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
TCoTake take(node);
- YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
return Build<TCoTake>(ctx, node->Pos())
.Input<TCoExtractMembers>()
.Input(take.Input())
@@ -25,7 +25,7 @@ TExprNode::TPtr ApplyExtractMembersToTake(const TExprNode::TPtr& node, const TEx
TExprNode::TPtr ApplyExtractMembersToSkip(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
TCoSkip skip(node);
- YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
return Build<TCoSkip>(ctx, node->Pos())
.Input<TCoExtractMembers>()
.Input(skip.Input())
@@ -52,12 +52,12 @@ TExprNode::TPtr ApplyExtractMembersToExtend(const TExprNode::TPtr& node, const T
TExprNode::TPtr ApplyExtractMembersToSkipNullMembers(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
TCoSkipNullMembers skipNullMembers(node);
- const auto& filtered = skipNullMembers.Members();
- if (!filtered) {
- return {};
- }
+ const auto& filtered = skipNullMembers.Members();
+ if (!filtered) {
+ return {};
+ }
TExprNode::TListType filteredMembers;
- for (const auto& x : filtered.Cast()) {
+ for (const auto& x : filtered.Cast()) {
auto member = x.Value();
bool hasMember = false;
for (const auto& y : members->ChildrenList()) {
@@ -72,7 +72,7 @@ TExprNode::TPtr ApplyExtractMembersToSkipNullMembers(const TExprNode::TPtr& node
}
}
- YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
return Build<TCoSkipNullMembers>(ctx, skipNullMembers.Pos())
.Input<TCoExtractMembers>()
.Input(skipNullMembers.Input())
@@ -208,7 +208,7 @@ TExprNode::TPtr ApplyExtractMembersToSort(const TExprNode::TPtr& node, const TEx
.Build();
}
else if (fieldSubset) {
- const auto structType = GetSeqItemType(sort.Ref().GetTypeAnn())->Cast<TStructExprType>();
+ const auto structType = GetSeqItemType(sort.Ref().GetTypeAnn())->Cast<TStructExprType>();
if (structType->GetSize() <= extractFields.size()) {
return {};
}
@@ -291,7 +291,7 @@ TExprNode::TPtr ApplyExtractMembersToTop(const TExprNode::TPtr& node, const TExp
return ctx.ChangeChildren(*node, std::move(children));
}
else if (fieldSubset) {
- const auto structType = GetSeqItemType(top.Ref().GetTypeAnn())->Cast<TStructExprType>();
+ const auto structType = GetSeqItemType(top.Ref().GetTypeAnn())->Cast<TStructExprType>();
if (structType->GetSize() <= extractFields.size()) {
return {};
}
@@ -319,12 +319,12 @@ TExprNode::TPtr ApplyExtractMembersToTop(const TExprNode::TPtr& node, const TExp
TExprNode::TPtr ApplyExtractMembersToEquiJoin(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
TCoEquiJoin join(node);
- const auto structType = GetSeqItemType(join.Ref().GetTypeAnn())->Cast<TStructExprType>();
+ const auto structType = GetSeqItemType(join.Ref().GetTypeAnn())->Cast<TStructExprType>();
if (structType->GetSize() == 0) {
return {};
}
- YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Move ExtractMembers over " << node->Content() << logSuffix;
auto joinSettings = join.Arg(join.ArgCount() - 1).Ptr();
auto renameMap = LoadJoinRenameMap(*joinSettings);
joinSettings = RemoveSetting(*joinSettings, "rename", ctx);
@@ -414,7 +414,7 @@ TExprNode::TPtr ApplyExtractMembersToFlatMap(const TExprNode::TPtr& node, const
TExprNode::TPtr ApplyExtractMembersToPartitionByKey(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
TCoPartitionByKey part(node);
- YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
auto newBody = Build<TCoExtractMembers>(ctx, part.Pos())
.Input(part.ListHandlerLambda().Body())
.Members(members)
@@ -436,82 +436,82 @@ TExprNode::TPtr ApplyExtractMembersToPartitionByKey(const TExprNode::TPtr& node,
.Ptr();
}
-TExprNode::TPtr ApplyExtractMembersToChopper(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
- const TCoChopper chopper(node);
- YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
- auto newBody = Build<TCoExtractMembers>(ctx, chopper.Handler().Pos())
- .Input(chopper.Handler().Body())
- .Members(members)
- .Done();
-
- return Build<TCoChopper>(ctx, chopper.Pos())
- .Input(chopper.Input())
- .KeyExtractor(chopper.KeyExtractor())
- .GroupSwitch(chopper.GroupSwitch())
- .Handler()
- .Args({"key", "group"})
- .Body<TExprApplier>()
- .Apply(newBody)
- .With(chopper.Handler().Args().Arg(0), "key")
- .With(chopper.Handler().Args().Arg(1), "group")
- .Build()
- .Build()
- .Done()
- .Ptr();
-}
-
-TExprNode::TPtr ApplyExtractMembersToMapJoinCore(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
- const TCoMapJoinCore mapJoin(node);
- YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
- TNodeSet used(members->ChildrenSize());
- members->ForEachChild([&used](const TExprNode& member) { used.emplace(&member); });
-
- auto right = mapJoin.RightRenames().Ref().ChildrenList();
- for (auto it = right.cbegin(); it < right.cend();) {
- if (used.contains((++it)->Get()))
- ++it;
- else {
- auto to = it;
- it = right.erase(--it, ++to);
- }
- }
-
- auto left = mapJoin.LeftRenames().Ref().ChildrenList();
- auto input = mapJoin.LeftKeysColumns().Ref().ChildrenList();
- const auto leftColumsEstimate = input.size() + (left.size() >> 1U);
- input.reserve(leftColumsEstimate);
- TNodeSet set(leftColumsEstimate);
- for (auto it = input.cbegin(); input.cend() != it;) {
- if (set.emplace(it->Get()).second)
- ++it;
- else
- it = input.erase(it);
- }
-
- for (auto it = left.cbegin(); it < left.cend();) {
- if (set.emplace(it->Get()).second)
- input.emplace_back(*it);
- if (used.contains((++it)->Get()))
- ++it;
- else {
- auto to = it;
- it = left.erase(--it, ++to);
- }
- }
-
- return Build<TCoMapJoinCore>(ctx, mapJoin.Pos())
- .LeftInput<TCoExtractMembers>()
- .Input(mapJoin.LeftInput())
- .Members(ctx.NewList(mapJoin.Pos(), std::move(input)))
- .Build()
- .RightDict(mapJoin.RightDict())
- .JoinKind(mapJoin.JoinKind())
- .LeftKeysColumns(mapJoin.LeftKeysColumns())
- .LeftRenames(ctx.NewList(mapJoin.LeftInput().Pos(), std::move(left)))
- .RightRenames(ctx.NewList(mapJoin.RightRenames().Pos(), std::move(right)))
- .Done().Ptr();
-}
-
+TExprNode::TPtr ApplyExtractMembersToChopper(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
+ const TCoChopper chopper(node);
+ YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
+ auto newBody = Build<TCoExtractMembers>(ctx, chopper.Handler().Pos())
+ .Input(chopper.Handler().Body())
+ .Members(members)
+ .Done();
+
+ return Build<TCoChopper>(ctx, chopper.Pos())
+ .Input(chopper.Input())
+ .KeyExtractor(chopper.KeyExtractor())
+ .GroupSwitch(chopper.GroupSwitch())
+ .Handler()
+ .Args({"key", "group"})
+ .Body<TExprApplier>()
+ .Apply(newBody)
+ .With(chopper.Handler().Args().Arg(0), "key")
+ .With(chopper.Handler().Args().Arg(1), "group")
+ .Build()
+ .Build()
+ .Done()
+ .Ptr();
+}
+
+TExprNode::TPtr ApplyExtractMembersToMapJoinCore(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
+ const TCoMapJoinCore mapJoin(node);
+ YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
+ TNodeSet used(members->ChildrenSize());
+ members->ForEachChild([&used](const TExprNode& member) { used.emplace(&member); });
+
+ auto right = mapJoin.RightRenames().Ref().ChildrenList();
+ for (auto it = right.cbegin(); it < right.cend();) {
+ if (used.contains((++it)->Get()))
+ ++it;
+ else {
+ auto to = it;
+ it = right.erase(--it, ++to);
+ }
+ }
+
+ auto left = mapJoin.LeftRenames().Ref().ChildrenList();
+ auto input = mapJoin.LeftKeysColumns().Ref().ChildrenList();
+ const auto leftColumsEstimate = input.size() + (left.size() >> 1U);
+ input.reserve(leftColumsEstimate);
+ TNodeSet set(leftColumsEstimate);
+ for (auto it = input.cbegin(); input.cend() != it;) {
+ if (set.emplace(it->Get()).second)
+ ++it;
+ else
+ it = input.erase(it);
+ }
+
+ for (auto it = left.cbegin(); it < left.cend();) {
+ if (set.emplace(it->Get()).second)
+ input.emplace_back(*it);
+ if (used.contains((++it)->Get()))
+ ++it;
+ else {
+ auto to = it;
+ it = left.erase(--it, ++to);
+ }
+ }
+
+ return Build<TCoMapJoinCore>(ctx, mapJoin.Pos())
+ .LeftInput<TCoExtractMembers>()
+ .Input(mapJoin.LeftInput())
+ .Members(ctx.NewList(mapJoin.Pos(), std::move(input)))
+ .Build()
+ .RightDict(mapJoin.RightDict())
+ .JoinKind(mapJoin.JoinKind())
+ .LeftKeysColumns(mapJoin.LeftKeysColumns())
+ .LeftRenames(ctx.NewList(mapJoin.LeftInput().Pos(), std::move(left)))
+ .RightRenames(ctx.NewList(mapJoin.RightRenames().Pos(), std::move(right)))
+ .Done().Ptr();
+}
+
TExprNode::TPtr ApplyExtractMembersToCalcOverWindow(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix) {
YQL_ENSURE(node->IsCallable({"CalcOverWindow", "CalcOverSessionWindow", "CalcOverWindowGroup"}));
@@ -661,7 +661,7 @@ TExprNode::TPtr ApplyExtractMembersToCalcOverWindow(const TExprNode::TPtr& node,
.Calcs(ctx.NewList(node->Pos(), std::move(newCalcs)))
.Done().Ptr();
- YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
return Build<TCoExtractMembers>(ctx, node->Pos())
.Input(calcOverWindow)
.Members(members)
@@ -770,7 +770,7 @@ TExprNode::TPtr ApplyExtractMembersToAggregate(const TExprNode::TPtr& node, cons
.Done()
.Ptr();
- YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
+ YQL_CLOG(DEBUG, Core) << "Apply ExtractMembers to " << node->Content() << logSuffix;
return Build<TCoExtractMembers>(ctx, aggr.Pos())
.Input<TCoAggregate>()
.Input(newInput)
diff --git a/ydb/library/yql/core/common_opt/yql_co_extr_members.h b/ydb/library/yql/core/common_opt/yql_co_extr_members.h
index 364c066efa..8244636784 100644
--- a/ydb/library/yql/core/common_opt/yql_co_extr_members.h
+++ b/ydb/library/yql/core/common_opt/yql_co_extr_members.h
@@ -22,8 +22,8 @@ TExprNode::TPtr ApplyExtractMembersToFlatMap(const TExprNode::TPtr& node, const
TExprNode::TPtr ApplyExtractMembersToPartitionByKey(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
TExprNode::TPtr ApplyExtractMembersToCalcOverWindow(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
TExprNode::TPtr ApplyExtractMembersToAggregate(const TExprNode::TPtr& node, const TExprNode::TPtr& members, const TParentsMap& parentsMap, TExprContext& ctx, TStringBuf logSuffix);
-TExprNode::TPtr ApplyExtractMembersToChopper(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
+TExprNode::TPtr ApplyExtractMembersToChopper(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
TExprNode::TPtr ApplyExtractMembersToCollect(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
-TExprNode::TPtr ApplyExtractMembersToMapJoinCore(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
+TExprNode::TPtr ApplyExtractMembersToMapJoinCore(const TExprNode::TPtr& node, const TExprNode::TPtr& members, TExprContext& ctx, TStringBuf logSuffix);
} // NYql
diff --git a/ydb/library/yql/core/common_opt/yql_co_finalizers.cpp b/ydb/library/yql/core/common_opt/yql_co_finalizers.cpp
index 9a7662217b..b77766bc6f 100644
--- a/ydb/library/yql/core/common_opt/yql_co_finalizers.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_finalizers.cpp
@@ -187,14 +187,14 @@ void RegisterCoFinalizers(TFinalizingOptimizerMap& map) {
}
);
};
-
- map[TCoChopper::CallableName()] = [](const TExprNode::TPtr& node, TNodeOnNodeOwnedMap& toOptimize, TExprContext& ctx, TOptimizeContext& optCtx) {
- SubsetFieldsForNodeWithMultiUsage(node, *optCtx.ParentsMap, toOptimize, ctx,
- [] (const TExprNode::TPtr& input, const TExprNode::TPtr& members, const TParentsMap&, TExprContext& ctx) {
- return ApplyExtractMembersToChopper(input, members, ctx, " with multi-usage");
- }
- );
- };
+
+ map[TCoChopper::CallableName()] = [](const TExprNode::TPtr& node, TNodeOnNodeOwnedMap& toOptimize, TExprContext& ctx, TOptimizeContext& optCtx) {
+ SubsetFieldsForNodeWithMultiUsage(node, *optCtx.ParentsMap, toOptimize, ctx,
+ [] (const TExprNode::TPtr& input, const TExprNode::TPtr& members, const TParentsMap&, TExprContext& ctx) {
+ return ApplyExtractMembersToChopper(input, members, ctx, " with multi-usage");
+ }
+ );
+ };
map[TCoCollect::CallableName()] = [](const TExprNode::TPtr& node, TNodeOnNodeOwnedMap& toOptimize, TExprContext& ctx, TOptimizeContext& optCtx) {
SubsetFieldsForNodeWithMultiUsage(node, *optCtx.ParentsMap, toOptimize, ctx,
diff --git a/ydb/library/yql/core/common_opt/yql_co_flow1.cpp b/ydb/library/yql/core/common_opt/yql_co_flow1.cpp
index bd90a495c2..728838dc8e 100644
--- a/ydb/library/yql/core/common_opt/yql_co_flow1.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_flow1.cpp
@@ -21,8 +21,8 @@ namespace {
using namespace NNodes;
bool IsConstMapLambda(TCoLambda lambda) {
- const auto body = lambda.Body();
- return body.Ref().IsCallable("Just") && body.Ref().GetDependencyScope()->second != lambda.Raw();
+ const auto body = lambda.Body();
+ return body.Ref().IsCallable("Just") && body.Ref().GetDependencyScope()->second != lambda.Raw();
}
template <typename TResult>
@@ -36,37 +36,37 @@ TExprNode::TPtr FuseFlatmaps(TCoFlatMapBase outerMap, TExprContext& ctx, TTypeAn
return outerMap.Ptr();
}
- if (outerBody.Ref().IsCallable({"Just", "AsList"}) && innerBody.Ref().IsCallable({"Just", "AsList"})) {
- const auto width = outerBody.Ref().ChildrenSize() * innerBody.Ref().ChildrenSize();
- YQL_CLOG(DEBUG, Core) << "Fuse " << outerMap.Ref().Content() << " with " << innerMap.Ref().Content() << " width " << width;
- auto flatMap = ctx.Builder(outerMap.Pos())
- .Callable(TResult::CallableName())
- .Add(0, innerMap.Input().Ptr())
- .Lambda(1)
- .Param("item")
- .Callable(width > 1U ? "AsList" : "Just")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- auto j = 0U;
- for (auto i = 0U; i < innerBody.Ref().ChildrenSize(); ++i) {
- for (auto o = 0U; o < outerBody.Ref().ChildrenSize(); ++o) {
- parent.ApplyPartial(j++, outerMap.Lambda().Args().Ptr(), outerBody.Ref().ChildPtr(o))
- .With(0)
- .ApplyPartial(innerMap.Lambda().Args().Ptr(), innerBody.Ref().ChildPtr(i))
- .With(0, "item")
- .Seal()
- .Done()
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- return ctx.WrapByCallableIf(1U == width && outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List && innerMap.Input().Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "ToList", std::move(flatMap));
- }
-
-
+ if (outerBody.Ref().IsCallable({"Just", "AsList"}) && innerBody.Ref().IsCallable({"Just", "AsList"})) {
+ const auto width = outerBody.Ref().ChildrenSize() * innerBody.Ref().ChildrenSize();
+ YQL_CLOG(DEBUG, Core) << "Fuse " << outerMap.Ref().Content() << " with " << innerMap.Ref().Content() << " width " << width;
+ auto flatMap = ctx.Builder(outerMap.Pos())
+ .Callable(TResult::CallableName())
+ .Add(0, innerMap.Input().Ptr())
+ .Lambda(1)
+ .Param("item")
+ .Callable(width > 1U ? "AsList" : "Just")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ auto j = 0U;
+ for (auto i = 0U; i < innerBody.Ref().ChildrenSize(); ++i) {
+ for (auto o = 0U; o < outerBody.Ref().ChildrenSize(); ++o) {
+ parent.ApplyPartial(j++, outerMap.Lambda().Args().Ptr(), outerBody.Ref().ChildPtr(o))
+ .With(0)
+ .ApplyPartial(innerMap.Lambda().Args().Ptr(), innerBody.Ref().ChildPtr(i))
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ return ctx.WrapByCallableIf(1U == width && outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List && innerMap.Input().Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "ToList", std::move(flatMap));
+ }
+
+
if (IsJustOrSingleAsList(innerBody.Ref())) {
auto placeHolder = ctx.NewArgument(outerMap.Pos(), "placeholder");
@@ -90,27 +90,27 @@ TExprNode::TPtr FuseFlatmaps(TCoFlatMapBase outerMap, TExprContext& ctx, TTypeAn
if (outerMap.Input().Ref().GetTypeAnn()->GetKind() != innerMap.Input().Ref().GetTypeAnn()->GetKind()
&& innerMap.Input().Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
- outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow) {
-
- return Build<TResult>(ctx, outerMap.Pos())
- .Input(innerMap.Input())
- .Lambda()
- .Args({"item"})
- .template Body<TCoToFlow>()
- .template Input<TExprApplier>()
- .Apply(TCoLambda(outerLambda))
- .With(0, outerArgValue)
- .With(innerMap.Lambda().Args().Arg(0), "item")
- .template With<TCoDependsOn>(TExprBase(placeHolder))
- .Input("item")
- .Build()
- .Build()
- .Build()
- .Build()
- .Done().Ptr();
-
- } else if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream &&
+ if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
+ outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow) {
+
+ return Build<TResult>(ctx, outerMap.Pos())
+ .Input(innerMap.Input())
+ .Lambda()
+ .Args({"item"})
+ .template Body<TCoToFlow>()
+ .template Input<TExprApplier>()
+ .Apply(TCoLambda(outerLambda))
+ .With(0, outerArgValue)
+ .With(innerMap.Lambda().Args().Arg(0), "item")
+ .template With<TCoDependsOn>(TExprBase(placeHolder))
+ .Input("item")
+ .Build()
+ .Build()
+ .Build()
+ .Build()
+ .Done().Ptr();
+
+ } else if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream &&
outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Stream) {
return Build<TResult>(ctx, outerMap.Pos())
@@ -197,7 +197,7 @@ TExprNode::TPtr FuseFlatmaps(TCoFlatMapBase outerMap, TExprContext& ctx, TTypeAn
.Seal()
.Build();
- if (outerBody.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream || outerBody.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
+ if (outerBody.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream || outerBody.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
value = ctx.Builder(outerMap.Pos())
.Callable(TCoForwardList::CallableName())
.Add(0, value)
@@ -220,26 +220,26 @@ TExprNode::TPtr FuseFlatmaps(TCoFlatMapBase outerMap, TExprContext& ctx, TTypeAn
if (outerMap.Input().Ref().GetTypeAnn()->GetKind() != innerMap.Input().Ref().GetTypeAnn()->GetKind()
&& innerMap.Input().Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
- outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow) {
-
- return Build<TResult>(ctx, outerMap.Pos())
- .Input(innerMap.Input())
- .Lambda()
- .Args({"item"})
- .template Body<TCoToFlow>()
- .template Input<TExprApplier>()
- .Apply(newBody)
- .With(innerMap.Lambda().Args().Arg(0), "item")
- .template With<TCoDependsOn>(TExprBase(placeHolder))
- .Input("item")
- .Build()
- .Build()
- .Build()
- .Build()
- .Done().Ptr();
-
- } else if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream &&
+ if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
+ outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow) {
+
+ return Build<TResult>(ctx, outerMap.Pos())
+ .Input(innerMap.Input())
+ .Lambda()
+ .Args({"item"})
+ .template Body<TCoToFlow>()
+ .template Input<TExprApplier>()
+ .Apply(newBody)
+ .With(innerMap.Lambda().Args().Arg(0), "item")
+ .template With<TCoDependsOn>(TExprBase(placeHolder))
+ .Input("item")
+ .Build()
+ .Build()
+ .Build()
+ .Build()
+ .Done().Ptr();
+
+ } else if (outerMap.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream &&
outerBody.Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Stream) {
return Build<TResult>(ctx, outerMap.Pos())
@@ -453,241 +453,241 @@ TExprNode::TPtr FuseCombineByKeyOverFlatmap(TCoCombineByKey combine, TExprContex
return ret.Ptr();
}
-template <bool TakeOrSkip>
-TExprNode::TPtr FusePart(const TExprNode& node, TExprContext& ctx) {
- auto children = node.Head().ChildrenList();
- children.back() = ctx.NewCallable(node.Pos(), TakeOrSkip ? "Min" : "Add", {node.TailPtr(), std::move(children.back())});
- return ctx.ChangeChildren(node.Head(), std::move(children));
+template <bool TakeOrSkip>
+TExprNode::TPtr FusePart(const TExprNode& node, TExprContext& ctx) {
+ auto children = node.Head().ChildrenList();
+ children.back() = ctx.NewCallable(node.Pos(), TakeOrSkip ? "Min" : "Add", {node.TailPtr(), std::move(children.back())});
+ return ctx.ChangeChildren(node.Head(), std::move(children));
}
TExprNode::TPtr SumLengthOverExtend(const TExprNode& node, TExprContext& ctx) {
- auto children = node.Head().ChildrenList();
- for (auto& child : children) {
- child = ctx.ChangeChild(node, 0U, std::move(child));
+ auto children = node.Head().ChildrenList();
+ for (auto& child : children) {
+ child = ctx.ChangeChild(node, 0U, std::move(child));
}
return ctx.Builder(node.Pos())
.Callable("Fold")
- .Callable(0, "AsList")
- .Add(std::move(children))
- .Seal()
+ .Callable(0, "AsList")
+ .Add(std::move(children))
+ .Seal()
.Callable(1, "Uint64")
- .Atom(0, "0", TNodeFlags::Default)
+ .Atom(0, "0", TNodeFlags::Default)
.Seal()
.Lambda(2)
.Param("item")
.Param("state")
- .Callable("AggrAdd")
+ .Callable("AggrAdd")
.Arg(0, "item")
.Arg(1, "state")
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
}
TExprNode::TPtr OrHasItemsOverExtend(const TExprNode& node, TExprContext& ctx) {
- auto children = node.Head().ChildrenList();
- for (auto& child : children) {
- child = ctx.ChangeChild(node, 0U, std::move(child));
+ auto children = node.Head().ChildrenList();
+ for (auto& child : children) {
+ child = ctx.ChangeChild(node, 0U, std::move(child));
}
- return ctx.NewCallable(node.Pos(), "Or", std::move(children));
+ return ctx.NewCallable(node.Pos(), "Or", std::move(children));
}
TExprNode::TPtr FuseSkipAfterEnumerate(const TExprNode& node, TExprContext& ctx) {
- auto enumerateChildren = node.Head().ChildrenList(); // Enumerate
- enumerateChildren.front() = ctx.ChangeChild(node, 0U, std::move(enumerateChildren.front()));
+ auto enumerateChildren = node.Head().ChildrenList(); // Enumerate
+ enumerateChildren.front() = ctx.ChangeChild(node, 0U, std::move(enumerateChildren.front()));
- auto offset = enumerateChildren.size() > 2U ?
- ctx.NewCallable(node.Pos(), "*", {enumerateChildren[2], node.TailPtr()}):
- node.TailPtr();
+ auto offset = enumerateChildren.size() > 2U ?
+ ctx.NewCallable(node.Pos(), "*", {enumerateChildren[2], node.TailPtr()}):
+ node.TailPtr();
- if (enumerateChildren.size() > 1U) {
- enumerateChildren[1] = ctx.NewCallable(node.Pos(), "+", {std::move(enumerateChildren[1]), std::move(offset)});
+ if (enumerateChildren.size() > 1U) {
+ enumerateChildren[1] = ctx.NewCallable(node.Pos(), "+", {std::move(enumerateChildren[1]), std::move(offset)});
} else {
- enumerateChildren.emplace_back(std::move(offset));
+ enumerateChildren.emplace_back(std::move(offset));
}
- return ctx.ChangeChildren(node.Head(), std::move(enumerateChildren));
+ return ctx.ChangeChildren(node.Head(), std::move(enumerateChildren));
}
-template <bool SingleArg>
-TExprNode::TPtr FuseFlatMapOverByKey(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node.Content() << " over " << node.Head().Content();
- auto lambda = SingleArg ?
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("list")
+template <bool SingleArg>
+TExprNode::TPtr FuseFlatMapOverByKey(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node.Content() << " over " << node.Head().Content();
+ auto lambda = SingleArg ?
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("list")
.Callable(node.Content())
- .Apply(0, node.Head().Tail())
- .With(0, "list")
- .Seal()
- .Add(1, node.TailPtr())
- .Seal()
- .Seal().Build():
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("key")
- .Param("state")
+ .Apply(0, node.Head().Tail())
+ .With(0, "list")
+ .Seal()
+ .Add(1, node.TailPtr())
+ .Seal()
+ .Seal().Build():
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("key")
+ .Param("state")
.Callable(node.Content())
- .Apply(0, node.Head().Tail())
- .With(0, "key")
- .With(1, "state")
- .Seal()
- .Add(1, node.TailPtr())
- .Seal()
- .Seal().Build();
-
- return ctx.ChangeChild(node.Head(), node.Head().ChildrenSize() - 1U, std::move(lambda));
+ .Apply(0, node.Head().Tail())
+ .With(0, "key")
+ .With(1, "state")
+ .Seal()
+ .Add(1, node.TailPtr())
+ .Seal()
+ .Seal().Build();
+
+ return ctx.ChangeChild(node.Head(), node.Head().ChildrenSize() - 1U, std::move(lambda));
}
TExprNode::TPtr ExtractOneItemStructFromFold(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
- const auto structType = node.Child(1)->GetTypeAnn()->Cast<TStructExprType>();
- const auto memberName = structType->GetItems().front()->GetName();
- const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
-
- return ctx.Builder(node.Pos())
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Callable(1, node.Content())
- .Add(0, node.HeadPtr())
- .Callable(1, "Member")
- .Add(0, node.ChildPtr(1))
+ YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
+ const auto structType = node.Child(1)->GetTypeAnn()->Cast<TStructExprType>();
+ const auto memberName = structType->GetItems().front()->GetName();
+ const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
+
+ return ctx.Builder(node.Pos())
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Callable(1, node.Content())
+ .Add(0, node.HeadPtr())
+ .Callable(1, "Member")
+ .Add(0, node.ChildPtr(1))
.Add(1, memberNameAtom)
.Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable("Member")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Add(1, memberNameAtom)
- .Seal()
- .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable("Member")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Seal()
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
}
TExprNode::TPtr ExtractOneItemTupleFromFold(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
- return ctx.Builder(node.Pos())
+ YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
+ return ctx.Builder(node.Pos())
.List()
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
.Callable(1, "Nth")
- .Add(0, node.ChildPtr(1))
- .Atom(1, "0", TNodeFlags::Default)
+ .Add(0, node.ChildPtr(1))
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable("Nth")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
.Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable("Nth")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
}
TExprNode::TPtr ExtractOneItemStructFromFold1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
- const auto structType = node.Child(1)->Child(1)->GetTypeAnn()->Cast<TStructExprType>();
- const auto memberName = structType->GetItems().front()->GetName();
- const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
-
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Member")
- .Apply(0, *node.Child(1))
- .With(0, "item")
- .Seal()
+ YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
+ const auto structType = node.Child(1)->Child(1)->GetTypeAnn()->Cast<TStructExprType>();
+ const auto memberName = structType->GetItems().front()->GetName();
+ const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
+
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Member")
+ .Apply(0, *node.Child(1))
+ .With(0, "item")
+ .Seal()
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable("Member")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
.Add(1, memberNameAtom)
.Seal()
.Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable("Member")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Add(1, memberNameAtom)
- .Seal()
- .Seal()
.Seal()
.Lambda(1)
.Param("m")
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "m")
- .Seal()
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "m")
+ .Seal()
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
}
TExprNode::TPtr ExtractOneItemTupleFromFold1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Nth")
- .Apply(0, *node.Child(1))
- .With(0, "item")
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
+ YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Nth")
+ .Apply(0, *node.Child(1))
+ .With(0, "item")
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable("Nth")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
.Seal()
.Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable("Nth")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
.Seal()
.Lambda(1)
.Param("m")
@@ -695,244 +695,244 @@ TExprNode::TPtr ExtractOneItemTupleFromFold1(const TExprNode& node, TExprContext
.Arg(0, "m")
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExtractOneItemStructFromCondense(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
+ const auto structType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
+ const auto memberName = structType->GetItems().front()->GetName();
+ const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
+
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Callable(1, "Member")
+ .Add(0, node.ChildPtr(1))
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Callable("Member")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("out")
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "out")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExtractOneItemTupleFromCondense(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Callable(1, "Nth")
+ .Add(0, node.ChildPtr(1))
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Callable("Nth")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("out")
+ .List()
+ .Arg(0, "out")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExtractOneItemStructFromCondense1(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
+ const auto structType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
+ const auto memberName = structType->GetItems().front()->GetName();
+ const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
+
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Member")
+ .Apply(0, *node.Child(1))
+ .With(0, "item")
+ .Seal()
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Callable("Member")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "state")
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Add(1, memberNameAtom)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("out")
+ .Callable("AsStruct")
+ .List(0)
+ .Add(0, memberNameAtom)
+ .Arg(1, "out")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExtractOneItemTupleFromCondense1(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Nth")
+ .Apply(0, *node.Child(1))
+ .With(0, "item")
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Callable("Nth")
+ .Apply(0, node.Tail())
+ .With(0, "item")
+ .With(1)
+ .List()
+ .Arg(0, "state")
+ .Seal()
+ .Done()
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("out")
+ .List()
+ .Arg(0, "out")
+ .Seal()
+ .Seal()
+ .Seal().Build();
}
-TExprNode::TPtr ExtractOneItemStructFromCondense(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
- const auto structType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
- const auto memberName = structType->GetItems().front()->GetName();
- const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
-
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Callable(1, "Member")
- .Add(0, node.ChildPtr(1))
- .Add(1, memberNameAtom)
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Callable("Member")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Add(1, memberNameAtom)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("out")
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "out")
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr ExtractOneItemTupleFromCondense(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Callable(1, "Nth")
- .Add(0, node.ChildPtr(1))
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Callable("Nth")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("out")
- .List()
- .Arg(0, "out")
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr ExtractOneItemStructFromCondense1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item struct from " << node.Content();
- const auto structType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
- const auto memberName = structType->GetItems().front()->GetName();
- const auto memberNameAtom = ctx.NewAtom(node.Pos(), memberName);
-
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Member")
- .Apply(0, *node.Child(1))
- .With(0, "item")
- .Seal()
- .Add(1, memberNameAtom)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Callable("Member")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "state")
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Add(1, memberNameAtom)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("out")
- .Callable("AsStruct")
- .List(0)
- .Add(0, memberNameAtom)
- .Arg(1, "out")
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr ExtractOneItemTupleFromCondense1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Extract single item tuple from " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Nth")
- .Apply(0, *node.Child(1))
- .With(0, "item")
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Callable("Nth")
- .Apply(0, node.Tail())
- .With(0, "item")
- .With(1)
- .List()
- .Arg(0, "state")
- .Seal()
- .Done()
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("out")
- .List()
- .Arg(0, "out")
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
TExprNode::TPtr ConvertFoldBySumToLength(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& lambda = node->Tail();
- auto arg1 = lambda.Tail().Child(0);
- const bool isInc = lambda.Tail().IsCallable("Inc");
- auto arg2 = isInc ? nullptr : lambda.Tail().Child(1);
+ const auto& lambda = node->Tail();
+ auto arg1 = lambda.Tail().Child(0);
+ const bool isInc = lambda.Tail().IsCallable("Inc");
+ auto arg2 = isInc ? nullptr : lambda.Tail().Child(1);
if (arg1->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data ||
(arg2 && arg2->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data)) {
return node;
}
- const auto stateArg = lambda.Head().Child(1);
+ const auto stateArg = lambda.Head().Child(1);
if (arg2 && (arg2 == stateArg)) {
DoSwap(arg1, arg2);
}
@@ -941,43 +941,43 @@ TExprNode::TPtr ConvertFoldBySumToLength(const TExprNode::TPtr& node, TExprConte
return node;
}
- if (arg2 && arg2->GetDependencyScope()->second == &lambda) {
+ if (arg2 && arg2->GetDependencyScope()->second == &lambda) {
return node;
}
- YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by sum to length";
-
- auto convertedIncrementValue = arg2 ? arg2 : ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
- const bool integral = IsDataTypeIntegral(arg1->GetTypeAnn()->Cast<TDataExprType>()->GetSlot())
- && (!arg2 || IsDataTypeIntegral(arg2->GetTypeAnn()->Cast<TDataExprType>()->GetSlot()));
-
- auto type = ExpandType(arg1->Pos(), *arg1->GetTypeAnn(), ctx);
- return ctx.Builder(node->Pos())
- .Callable(integral ? "BitCast" : "SafeCast")
- .Callable(0, "+")
- .Add(0, node->ChildPtr(1))
- .Callable(1, "*")
- .Add(0, std::move(convertedIncrementValue))
- .Callable(1, "Length")
- .Add(0, node->HeadPtr())
- .Seal()
- .Seal()
- .Seal()
- .Add(1, std::move(type))
- .Seal().Build();
+ YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by sum to length";
+
+ auto convertedIncrementValue = arg2 ? arg2 : ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
+ const bool integral = IsDataTypeIntegral(arg1->GetTypeAnn()->Cast<TDataExprType>()->GetSlot())
+ && (!arg2 || IsDataTypeIntegral(arg2->GetTypeAnn()->Cast<TDataExprType>()->GetSlot()));
+
+ auto type = ExpandType(arg1->Pos(), *arg1->GetTypeAnn(), ctx);
+ return ctx.Builder(node->Pos())
+ .Callable(integral ? "BitCast" : "SafeCast")
+ .Callable(0, "+")
+ .Add(0, node->ChildPtr(1))
+ .Callable(1, "*")
+ .Add(0, std::move(convertedIncrementValue))
+ .Callable(1, "Length")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal().Build();
}
TExprNode::TPtr ConvertFold1BySumToLength(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& updateLambda = node->Tail();
- auto arg1 = updateLambda.Tail().Child(0);
- const bool isInc = updateLambda.Tail().IsCallable("Inc");
- auto arg2 = isInc ? nullptr : updateLambda.Tail().Child(1);
+ const auto& updateLambda = node->Tail();
+ auto arg1 = updateLambda.Tail().Child(0);
+ const bool isInc = updateLambda.Tail().IsCallable("Inc");
+ auto arg2 = isInc ? nullptr : updateLambda.Tail().Child(1);
if (arg1->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data ||
(arg2 && arg2->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data)) {
return node;
}
- const auto stateArg = updateLambda.Head().Child(1);
+ const auto stateArg = updateLambda.Head().Child(1);
if (arg2 && (arg2 == stateArg)) {
DoSwap(arg1, arg2);
}
@@ -986,91 +986,91 @@ TExprNode::TPtr ConvertFold1BySumToLength(const TExprNode::TPtr& node, TExprCont
return node;
}
- if (arg2 && arg2->GetDependencyScope()->second == &updateLambda) {
+ if (arg2 && arg2->GetDependencyScope()->second == &updateLambda) {
+ return node;
+ }
+
+ const auto& initLambda = *node->Child(1);
+ if (initLambda.Tail().GetDependencyScope()->second == &initLambda) {
+ return node;
+ }
+
+ YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by sum to length";
+
+ auto convertedIncrementValue = arg2 ? arg2 : ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
+ const bool integral = IsDataTypeIntegral(arg1->GetTypeAnn()->Cast<TDataExprType>()->GetSlot())
+ && (!arg2 || IsDataTypeIntegral(arg2->GetTypeAnn()->Cast<TDataExprType>()->GetSlot()));
+
+ auto type = ExpandType(arg1->Pos(), *arg1->GetTypeAnn(), ctx);
+ return ctx.Builder(node->Pos())
+ .Callable("OptionalIf")
+ .Callable(0, "HasItems")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Callable(1, integral ? "BitCast" : "SafeCast")
+ .Callable(0, "+")
+ .Add(0, initLambda.TailPtr())
+ .Callable(1, "*")
+ .Add(0, std::move(convertedIncrementValue))
+ .Callable(1, "Dec")
+ .Callable(0, "Length")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr ConvertFoldByConstMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto& lambda = node->Tail();
+ auto arg1 = lambda.Tail().Child(0);
+ auto arg2 = lambda.Tail().Child(1);
+ if (arg1->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data ||
+ arg2->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data) {
+ return node;
+ }
+
+ const auto stateArg = lambda.Head().Child(1);
+ if (arg2 == stateArg) {
+ DoSwap(arg1, arg2);
+ }
+
+ if (arg1 != stateArg) {
return node;
}
- const auto& initLambda = *node->Child(1);
- if (initLambda.Tail().GetDependencyScope()->second == &initLambda) {
+ if (arg2->GetDependencyScope()->second == &lambda) {
return node;
}
- YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by sum to length";
-
- auto convertedIncrementValue = arg2 ? arg2 : ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
- const bool integral = IsDataTypeIntegral(arg1->GetTypeAnn()->Cast<TDataExprType>()->GetSlot())
- && (!arg2 || IsDataTypeIntegral(arg2->GetTypeAnn()->Cast<TDataExprType>()->GetSlot()));
-
- auto type = ExpandType(arg1->Pos(), *arg1->GetTypeAnn(), ctx);
- return ctx.Builder(node->Pos())
- .Callable("OptionalIf")
- .Callable(0, "HasItems")
- .Add(0, node->HeadPtr())
- .Seal()
- .Callable(1, integral ? "BitCast" : "SafeCast")
- .Callable(0, "+")
- .Add(0, initLambda.TailPtr())
- .Callable(1, "*")
- .Add(0, std::move(convertedIncrementValue))
- .Callable(1, "Dec")
- .Callable(0, "Length")
- .Add(0, node->HeadPtr())
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Add(1, std::move(type))
- .Seal()
- .Seal().Build();
+ YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by const " << lambda.Tail().Content();
+
+ return ctx.Builder(node->Pos())
+ .Callable("If")
+ .Callable(0, "HasItems")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Callable(1, lambda.Tail().Content())
+ .Add(0, node->ChildPtr(1))
+ .Add(1, arg2)
+ .Seal()
+ .Add(2, node->ChildPtr(1))
+ .Seal().Build();
}
-TExprNode::TPtr ConvertFoldByConstMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& lambda = node->Tail();
- auto arg1 = lambda.Tail().Child(0);
- auto arg2 = lambda.Tail().Child(1);
- if (arg1->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data ||
- arg2->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data) {
- return node;
- }
-
- const auto stateArg = lambda.Head().Child(1);
- if (arg2 == stateArg) {
- DoSwap(arg1, arg2);
- }
-
- if (arg1 != stateArg) {
- return node;
- }
-
- if (arg2->GetDependencyScope()->second == &lambda) {
- return node;
- }
-
- YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by const " << lambda.Tail().Content();
-
- return ctx.Builder(node->Pos())
- .Callable("If")
- .Callable(0, "HasItems")
- .Add(0, node->HeadPtr())
- .Seal()
- .Callable(1, lambda.Tail().Content())
- .Add(0, node->ChildPtr(1))
- .Add(1, arg2)
- .Seal()
- .Add(2, node->ChildPtr(1))
- .Seal().Build();
-}
-
-TExprNode::TPtr ConvertFold1ByConstMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& updateLambda = node->Tail();
- auto arg1 = updateLambda.Tail().Child(0);
- auto arg2 = updateLambda.Tail().Child(1);
+TExprNode::TPtr ConvertFold1ByConstMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto& updateLambda = node->Tail();
+ auto arg1 = updateLambda.Tail().Child(0);
+ auto arg2 = updateLambda.Tail().Child(1);
if (arg1->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data ||
arg2->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data) {
return node;
}
- const auto stateArg = updateLambda.Head().Child(1);
+ const auto stateArg = updateLambda.Head().Child(1);
if (arg2 == stateArg) {
DoSwap(arg1, arg2);
}
@@ -1079,205 +1079,205 @@ TExprNode::TPtr ConvertFold1ByConstMinMax(const TExprNode::TPtr& node, TExprCont
return node;
}
- if (arg2->GetDependencyScope()->second == &updateLambda) {
+ if (arg2->GetDependencyScope()->second == &updateLambda) {
return node;
}
- const auto& initLambda = *node->Child(1);
- if (initLambda.Tail().GetDependencyScope()->second == &initLambda) {
+ const auto& initLambda = *node->Child(1);
+ if (initLambda.Tail().GetDependencyScope()->second == &initLambda) {
return node;
}
- YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by const " << updateLambda.Tail().Content();
-
- return ctx.Builder(node->Pos())
- .Callable("OptionalIf")
- .Callable(0, "HasItems")
- .Add(0, node->HeadPtr())
- .Seal()
- .Callable(1, "If")
- .Callable(0, "==")
- .Callable(0, "Length")
- .Add(0, node->HeadPtr())
- .Seal()
- .Callable(1, "Uint64")
- .Atom(0, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, initLambda.TailPtr())
- .Callable(2, updateLambda.Tail().Content())
- .Add(0, arg2)
- .Add(1, initLambda.TailPtr())
- .Seal()
- .Seal()
- .Seal().Build();
+ YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " by const " << updateLambda.Tail().Content();
+
+ return ctx.Builder(node->Pos())
+ .Callable("OptionalIf")
+ .Callable(0, "HasItems")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Callable(1, "If")
+ .Callable(0, "==")
+ .Callable(0, "Length")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Callable(1, "Uint64")
+ .Atom(0, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, initLambda.TailPtr())
+ .Callable(2, updateLambda.Tail().Content())
+ .Add(0, arg2)
+ .Add(1, initLambda.TailPtr())
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr PropagateMapToFold(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Add(0, node.Head().HeadPtr())
+ .Add(1, node.ChildPtr(1))
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(node.Tail())
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr PropagateMapToFold1(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Add(0, node.Head().HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(*node.Child(1))
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(node.Tail())
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr PropagateMapToCondense(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Add(0, node.Head().HeadPtr())
+ .Add(1, node.ChildPtr(1))
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Apply(node.Tail())
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Seal().Build();
}
-TExprNode::TPtr PropagateMapToFold(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Add(0, node.Head().HeadPtr())
- .Add(1, node.ChildPtr(1))
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(node.Tail())
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr PropagateMapToFold1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Add(0, node.Head().HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(*node.Child(1))
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(node.Tail())
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Seal().Build();
+TExprNode::TPtr PropagateMapToCondense1(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Add(0, node.Head().HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(*node.Child(1))
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Apply(*node.Child(2))
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Apply(node.Tail())
+ .With(0)
+ .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .With(1, "state")
+ .Seal()
+ .Seal()
+ .Seal().Build();
}
-TExprNode::TPtr PropagateMapToCondense(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Add(0, node.Head().HeadPtr())
- .Add(1, node.ChildPtr(1))
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Apply(node.Tail())
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr PropagateMapToCondense1(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Propagate " << node.Head().Content() << " to " << node.Content();
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Add(0, node.Head().HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(*node.Child(1))
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Apply(*node.Child(2))
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Apply(node.Tail())
- .With(0)
- .ApplyPartial(node.Head().Tail().HeadPtr(), node.Head().Tail().Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .With(1, "state")
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr PropagateConstPremapIntoCombineByKey(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Propagate const premap into " << node.Content();
-
- const auto constItem = node.Child(1)->Tail().HeadPtr();
-
- auto children = node.ChildrenList();
+TExprNode::TPtr PropagateConstPremapIntoCombineByKey(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Propagate const premap into " << node.Content();
+
+ const auto constItem = node.Child(1)->Tail().HeadPtr();
+
+ auto children = node.ChildrenList();
// keyExtractorLambda
- children[2] = ctx.Builder(children[2]->Pos())
+ children[2] = ctx.Builder(children[2]->Pos())
.Lambda()
- .Param("item")
- .Apply(*children[2])
- .With(0, constItem)
- .Seal()
+ .Param("item")
+ .Apply(*children[2])
+ .With(0, constItem)
+ .Seal()
.Seal()
.Build();
// init lambda
- children[3] = ctx.Builder(children[3]->Pos())
+ children[3] = ctx.Builder(children[3]->Pos())
.Lambda()
- .Param("item")
- .Apply(*children[3])
- .With(0, constItem)
- .Seal()
+ .Param("item")
+ .Apply(*children[3])
+ .With(0, constItem)
+ .Seal()
.Seal()
.Build();
// update lambda
- children[4] = ctx.Builder(children[4]->Pos())
+ children[4] = ctx.Builder(children[4]->Pos())
.Lambda()
- .Param("item")
- .Param("state")
- .Apply(*children[4])
- .With(0, constItem)
- .With(1, "state")
- .Seal()
+ .Param("item")
+ .Param("state")
+ .Apply(*children[4])
+ .With(0, constItem)
+ .With(1, "state")
+ .Seal()
.Seal()
.Build();
- return ctx.ChangeChildren(node, std::move(children));
+ return ctx.ChangeChildren(node, std::move(children));
}
TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ctx) {
@@ -1302,9 +1302,9 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
const bool isDistinct = (aggregatedColumn.Ref().ChildrenSize() == 3);
auto traits = aggregatedColumn.Ref().Child(1);
- auto outputColumn = aggregatedColumn.Ref().HeadPtr();
+ auto outputColumn = aggregatedColumn.Ref().HeadPtr();
// validation of traits
- auto inputItemType = traits->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto inputItemType = traits->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
const bool isOptionalColumn = inputItemType->GetKind() == ETypeAnnotationKind::Optional;
auto init = TCoLambda(traits->Child(1));
@@ -1313,13 +1313,13 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
TExprNode::TPtr initVal;
TExprNode::TPtr updateVal;
if (init.Body().Ref().IsCallable("Uint64") &&
- init.Body().Ref().Head().Content() == "1") {
+ init.Body().Ref().Head().Content() == "1") {
onlyZero = false;
} else if (init.Body().Ref().IsCallable("Uint64") &&
- init.Body().Ref().Head().Content() == "0") {
+ init.Body().Ref().Head().Content() == "0") {
onlyColumn = false;
} else if (init.Body().Ref().IsCallable("AggrCountInit")) {
- initVal = init.Body().Ref().HeadPtr();
+ initVal = init.Body().Ref().HeadPtr();
onlyColumn = onlyColumn && init.Body().Ref().Child(0) == init.Args().Arg(0).Raw();
onlyZero = false;
} else {
@@ -1331,7 +1331,7 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
if (inc->IsCallable("Inc") && inc->Child(0) == update.Args().Arg(1).Raw()) {
onlyZero = false;
} else if (inc->IsCallable("AggrCountUpdate") && inc->Child(1) == update.Args().Arg(1).Raw()) {
- updateVal = inc->HeadPtr();
+ updateVal = inc->HeadPtr();
onlyColumn = onlyColumn && inc->Child(0) == update.Args().Arg(0).Raw();
onlyZero = false;
} else if (inc == update.Args().Arg(1).Raw()) {
@@ -1369,7 +1369,7 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
}
auto defVal = traits->Child(7);
- if (!defVal->IsCallable("Uint64") || defVal->Head().Content() != "0") {
+ if (!defVal->IsCallable("Uint64") || defVal->Head().Content() != "0") {
return node.Ptr();
}
@@ -1383,7 +1383,7 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
if (onlyZero) {
length = ctx.Builder(node.Pos())
.Callable("Uint64")
- .Atom(0, "0", TNodeFlags::Default)
+ .Atom(0, "0", TNodeFlags::Default)
.Seal()
.Build();
} else if (!onlyColumn) {
@@ -1396,9 +1396,9 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
.Callable(0, "Exists")
.Add(0, initVal)
.Seal()
- .Add(1, std::move(length))
+ .Add(1, std::move(length))
.Callable(2, "Uint64")
- .Atom(0, "0", TNodeFlags::Default)
+ .Atom(0, "0", TNodeFlags::Default)
.Seal()
.Seal()
.Build();
@@ -1408,8 +1408,8 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
.Callable("AsList")
.Callable(0, "AsStruct")
.List(0)
- .Add(0, std::move(outputColumn))
- .Add(1, std::move(length))
+ .Add(0, std::move(outputColumn))
+ .Add(1, std::move(length))
.Seal()
.Seal()
.Seal()
@@ -1538,7 +1538,7 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
.List(0)
.Add(0, outputColumn)
.Callable(1, "Length")
- .Add(0, std::move(groupByKey))
+ .Add(0, std::move(groupByKey))
.Seal()
.Seal()
.Seal()
@@ -1548,252 +1548,252 @@ TExprNode::TPtr CountAggregateRewrite(const TCoAggregate& node, TExprContext& ct
return ret;
}
-TExprNode::TPtr OptimizeReverse(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+TExprNode::TPtr OptimizeReverse(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (optCtx.IsSingleUsage(node->Head()) && node->Head().IsCallable({"Sort", "AssumeSorted"})) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- auto asc = node->Head().ChildPtr(1);
- if (asc->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- TExprNode::TListType newAscChildren;
- if (asc->IsList()) {
- newAscChildren = asc->ChildrenList();
- } else {
- const auto size = asc->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- newAscChildren.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- newAscChildren.emplace_back(ctx.Builder(asc->Pos())
- .Callable("Nth")
- .Add(0, asc)
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal().Build());
- }
- }
- for (auto& child : newAscChildren) {
- child = ctx.NewCallable(asc->Pos(), "Not", {std::move(child)});
- }
-
- asc = ctx.NewList(node->Pos(), std::move(newAscChildren));
- } else {
- asc = ctx.NewCallable(node->Pos(), "Not", {std::move(asc)});
- }
-
- auto children = node->Head().ChildrenList();
- if (node->Head().IsCallable("AssumeSorted")) {
- children.front() = ctx.ChangeChild(*node, 0U, std::move(children.front()));
- }
- children[1] = std::move(asc);
- return ctx.ChangeChildren(node->Head(), std::move(children));
- }
-
- return node;
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ auto asc = node->Head().ChildPtr(1);
+ if (asc->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ TExprNode::TListType newAscChildren;
+ if (asc->IsList()) {
+ newAscChildren = asc->ChildrenList();
+ } else {
+ const auto size = asc->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ newAscChildren.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ newAscChildren.emplace_back(ctx.Builder(asc->Pos())
+ .Callable("Nth")
+ .Add(0, asc)
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal().Build());
+ }
+ }
+ for (auto& child : newAscChildren) {
+ child = ctx.NewCallable(asc->Pos(), "Not", {std::move(child)});
+ }
+
+ asc = ctx.NewList(node->Pos(), std::move(newAscChildren));
+ } else {
+ asc = ctx.NewCallable(node->Pos(), "Not", {std::move(asc)});
+ }
+
+ auto children = node->Head().ChildrenList();
+ if (node->Head().IsCallable("AssumeSorted")) {
+ children.front() = ctx.ChangeChild(*node, 0U, std::move(children.front()));
+ }
+ children[1] = std::move(asc);
+ return ctx.ChangeChildren(node->Head(), std::move(children));
+ }
+
+ return node;
}
-TExprNode::TPtr OptimizeLookup(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+TExprNode::TPtr OptimizeLookup(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (optCtx.IsSingleUsage(node->Head()) && node->Head().IsCallable("ToIndexDict") && TMaybeNode<TCoIntegralCtor>(node->TailPtr())) {
- const auto& atom = node->Tail().Head();
- if (atom.Content() == "0" && !(TNodeFlags::BinaryContent & atom.Flags())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " zero item over " << node->Head().Content();
- return ctx.RenameNode(node->Head(), "ListHead");
- }
- }
- return node;
-}
-
-constexpr std::initializer_list<std::string_view> FlowPriority = {
+ const auto& atom = node->Tail().Head();
+ if (atom.Content() == "0" && !(TNodeFlags::BinaryContent & atom.Flags())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " zero item over " << node->Head().Content();
+ return ctx.RenameNode(node->Head(), "ListHead");
+ }
+ }
+ return node;
+}
+
+constexpr std::initializer_list<std::string_view> FlowPriority = {
"AssumeSorted", "AssumeUnique",
- "Map", "OrderedMap",
- "Filter", "OrderedFilter",
- "FlatMap", "OrderedFlatMap",
- "MultiMap", "OrderedMultiMap",
- "FoldMap", "Fold1Map", "Chain1Map",
- "Take", "Skip",
- "TakeWhile", "SkipWhile",
- "TakeWhileInclusive", "SkipWhileInclusive",
- "SkipNullMembers", "FilterNullMembers",
- "SkipNullElements", "FilterNullElements",
- "Condense", "Condense1",
- "MapJoinCore", "CommonJoinCore",
- "CombineCore", "ExtractMembers",
- "PartitionByKey", "SqueezeToDict"
-};
-
-TExprNode::TPtr OptimizeToFlow(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ "Map", "OrderedMap",
+ "Filter", "OrderedFilter",
+ "FlatMap", "OrderedFlatMap",
+ "MultiMap", "OrderedMultiMap",
+ "FoldMap", "Fold1Map", "Chain1Map",
+ "Take", "Skip",
+ "TakeWhile", "SkipWhile",
+ "TakeWhileInclusive", "SkipWhileInclusive",
+ "SkipNullMembers", "FilterNullMembers",
+ "SkipNullElements", "FilterNullElements",
+ "Condense", "Condense1",
+ "MapJoinCore", "CommonJoinCore",
+ "CombineCore", "ExtractMembers",
+ "PartitionByKey", "SqueezeToDict"
+};
+
+TExprNode::TPtr OptimizeToFlow(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- if (node->Head().IsCallable(FlowPriority)) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
- return ctx.SwapWithHead(*node);
- }
-
- if (node->Head().IsCallable("FromFlow")) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with " << node->Head().Content();
- return node->Head().HeadPtr();
- }
-
- if (node->Head().IsCallable("Chopper")) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Head().Content() << " with " << node->Content();
- auto children = node->Head().ChildrenList();
- children.front() = ctx.ChangeChildren(*node, {std::move(children.front())});
- children.back() = ctx.Builder(children.back()->Pos())
- .Lambda()
- .Param("key")
- .Param("flow")
- .Callable("ToFlow")
- .Apply(0, *children.back())
- .With(0, "key")
- .With(1)
- .Callable("FromFlow")
- .Arg(0, "flow")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- return ctx.ChangeChildren(node->Head(), std::move(children));
- }
-
- if (node->Head().IsCallable("Switch")) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Head().Content() << " with " << node->Content();
- auto children = node->Head().ChildrenList();
- children.front() = ctx.ChangeChildren(*node, {std::move(children.front())});
- for (auto i = 3U; i < children.size(); ++++i) {
- children[i] = ctx.Builder(children[i]->Pos())
- .Lambda()
- .Param("flow")
- .Callable("ToFlow")
- .Apply(0, *children[i])
- .With(0)
- .Callable("FromFlow")
- .Arg(0, "flow")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- return ctx.ChangeChildren(node->Head(), std::move(children));
- }
-
- return node;
-}
-
-template <bool Ordered>
-TExprNode::TPtr OptimizeFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- const std::conditional_t<Ordered, TCoOrderedFlatMap, TCoFlatMap> self(node);
- if (!optCtx.IsSingleUsage(self.Input().Ref())) {
- return node;
- }
-
- if constexpr (Ordered) {
- if (self.Input().template Maybe<TCoOrderedFlatMap>()) {
- if (const auto ret = FuseFlatmaps<TCoOrderedFlatMap>(self, ctx, optCtx.Types); ret != node) {
+ return node;
+ }
+
+ if (node->Head().IsCallable(FlowPriority)) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
+ }
+
+ if (node->Head().IsCallable("FromFlow")) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
+
+ if (node->Head().IsCallable("Chopper")) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Head().Content() << " with " << node->Content();
+ auto children = node->Head().ChildrenList();
+ children.front() = ctx.ChangeChildren(*node, {std::move(children.front())});
+ children.back() = ctx.Builder(children.back()->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("flow")
+ .Callable("ToFlow")
+ .Apply(0, *children.back())
+ .With(0, "key")
+ .With(1)
+ .Callable("FromFlow")
+ .Arg(0, "flow")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ return ctx.ChangeChildren(node->Head(), std::move(children));
+ }
+
+ if (node->Head().IsCallable("Switch")) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Head().Content() << " with " << node->Content();
+ auto children = node->Head().ChildrenList();
+ children.front() = ctx.ChangeChildren(*node, {std::move(children.front())});
+ for (auto i = 3U; i < children.size(); ++++i) {
+ children[i] = ctx.Builder(children[i]->Pos())
+ .Lambda()
+ .Param("flow")
+ .Callable("ToFlow")
+ .Apply(0, *children[i])
+ .With(0)
+ .Callable("FromFlow")
+ .Arg(0, "flow")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ return ctx.ChangeChildren(node->Head(), std::move(children));
+ }
+
+ return node;
+}
+
+template <bool Ordered>
+TExprNode::TPtr OptimizeFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ const std::conditional_t<Ordered, TCoOrderedFlatMap, TCoFlatMap> self(node);
+ if (!optCtx.IsSingleUsage(self.Input().Ref())) {
+ return node;
+ }
+
+ if constexpr (Ordered) {
+ if (self.Input().template Maybe<TCoOrderedFlatMap>()) {
+ if (const auto ret = FuseFlatmaps<TCoOrderedFlatMap>(self, ctx, optCtx.Types); ret != node) {
return ret;
}
}
- }
-
- if (self.Input().template Maybe<TCoFlatMapBase>()) {
- if (const auto ret = FuseFlatmaps<TCoFlatMap>(self, ctx, optCtx.Types); ret != node) {
- return ret;
- }
- }
-
- if (node->Head().IsCallable({"GroupByKey", "CombineByKey"})) {
- return FuseFlatMapOverByKey<false>(*node, ctx);
- }
-
- if (node->Head().IsCallable({"PartitionByKey", "PartitionsByKeys"})) {
- return FuseFlatMapOverByKey<true>(*node, ctx);
- }
-
- if (node->Head().IsCallable("ForwardList")) {
- if (ETypeAnnotationKind::List == node->GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
- return ctx.SwapWithHead(*node);
- } else {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- }
- }
-
- if (const auto& input = self.Input().Ref(); input.IsCallable("Switch") && IsJustOrSingleAsList(self.Lambda().Body().Ref())) {
- if (const auto item = optCtx.GetParentIfSingle(self.Lambda().Args().Arg(0).Ref()); item && item->IsCallable("VariantItem")) {
- const auto inputItemType = GetSeqItemType(input.Head().GetTypeAnn());
- const auto variants = ETypeAnnotationKind::Variant == inputItemType->GetKind() ? inputItemType->template Cast<TVariantExprType>()->GetUnderlyingType()->template Cast<TTupleExprType>()->GetSize() : 0U;
- TNodeSet atoms(variants);
- for (auto i = 2U; i < self.Input().Ref().ChildrenSize(); ++i) {
- const auto& ids = *input.Child(i);
- for (auto j = 0U; j < ids.ChildrenSize(); ++j)
- if (!atoms.emplace(ids.Child(j)).second)
- return node;
-
- if (input.Child(++i) != &input.Tail())
- return node;
- }
-
- if (variants != atoms.size()) {
- return node;
- }
-
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << input.Content() << " with all " << variants << " identical lambdas.";
- auto lambda = ctx.DeepCopyLambda(node->Tail(), ctx.ReplaceNode(self.Lambda().Body().Ref().HeadPtr(), *item, item->HeadPtr()));
- constexpr auto mapType = Ordered ? "OrderedMap" : "Map";
- return ctx.Builder(node->Pos())
- .Callable(mapType)
- .Apply(0, input.Tail())
- .With(0)
- .Callable(mapType)
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("var")
- .Callable(item->Content())
- .Arg(0, "var")
- .Seal()
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Add(1, std::move(lambda))
- .Seal().Build();
- }
- }
-
- return node;
-}
-
-}
-
-void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
- using namespace std::placeholders;
-
- map["ToFlow"] = std::bind(&OptimizeToFlow, _1, _2, _3);
-
- map["FlatMap"] = std::bind(&OptimizeFlatMap<false>, _1, _2, _3);
- map["OrderedFlatMap"] = std::bind(&OptimizeFlatMap<true>, _1, _2, _3);
-
- map["Lookup"] = std::bind(&OptimizeLookup, _1, _2, _3);
+ }
+
+ if (self.Input().template Maybe<TCoFlatMapBase>()) {
+ if (const auto ret = FuseFlatmaps<TCoFlatMap>(self, ctx, optCtx.Types); ret != node) {
+ return ret;
+ }
+ }
+
+ if (node->Head().IsCallable({"GroupByKey", "CombineByKey"})) {
+ return FuseFlatMapOverByKey<false>(*node, ctx);
+ }
+
+ if (node->Head().IsCallable({"PartitionByKey", "PartitionsByKeys"})) {
+ return FuseFlatMapOverByKey<true>(*node, ctx);
+ }
+
+ if (node->Head().IsCallable("ForwardList")) {
+ if (ETypeAnnotationKind::List == node->GetTypeAnn()->GetKind()) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
+ } else {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ }
+ }
+
+ if (const auto& input = self.Input().Ref(); input.IsCallable("Switch") && IsJustOrSingleAsList(self.Lambda().Body().Ref())) {
+ if (const auto item = optCtx.GetParentIfSingle(self.Lambda().Args().Arg(0).Ref()); item && item->IsCallable("VariantItem")) {
+ const auto inputItemType = GetSeqItemType(input.Head().GetTypeAnn());
+ const auto variants = ETypeAnnotationKind::Variant == inputItemType->GetKind() ? inputItemType->template Cast<TVariantExprType>()->GetUnderlyingType()->template Cast<TTupleExprType>()->GetSize() : 0U;
+ TNodeSet atoms(variants);
+ for (auto i = 2U; i < self.Input().Ref().ChildrenSize(); ++i) {
+ const auto& ids = *input.Child(i);
+ for (auto j = 0U; j < ids.ChildrenSize(); ++j)
+ if (!atoms.emplace(ids.Child(j)).second)
+ return node;
+
+ if (input.Child(++i) != &input.Tail())
+ return node;
+ }
+
+ if (variants != atoms.size()) {
+ return node;
+ }
+
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << input.Content() << " with all " << variants << " identical lambdas.";
+ auto lambda = ctx.DeepCopyLambda(node->Tail(), ctx.ReplaceNode(self.Lambda().Body().Ref().HeadPtr(), *item, item->HeadPtr()));
+ constexpr auto mapType = Ordered ? "OrderedMap" : "Map";
+ return ctx.Builder(node->Pos())
+ .Callable(mapType)
+ .Apply(0, input.Tail())
+ .With(0)
+ .Callable(mapType)
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("var")
+ .Callable(item->Content())
+ .Arg(0, "var")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Add(1, std::move(lambda))
+ .Seal().Build();
+ }
+ }
+
+ return node;
+}
+
+}
+
+void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
+ using namespace std::placeholders;
+
+ map["ToFlow"] = std::bind(&OptimizeToFlow, _1, _2, _3);
+
+ map["FlatMap"] = std::bind(&OptimizeFlatMap<false>, _1, _2, _3);
+ map["OrderedFlatMap"] = std::bind(&OptimizeFlatMap<true>, _1, _2, _3);
+
+ map["Lookup"] = std::bind(&OptimizeLookup, _1, _2, _3);
map["Skip"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head()) && !optCtx.IsPersistentNode(node->Head())) {
return node;
}
- if (TCoSkip::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
- return FusePart<false>(*node, ctx);
+ if (TCoSkip::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ return FusePart<false>(*node, ctx);
}
- if (TCoEnumerate::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ if (TCoEnumerate::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
return FuseSkipAfterEnumerate(*node, ctx);
}
- if (TCoFlatMapBase::Match(&node->Head()) &&
- node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List &&
- IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.SwapWithHead(*node);
+ if (TCoFlatMapBase::Match(&node->Head()) &&
+ node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List &&
+ IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
}
return node;
@@ -1803,35 +1803,35 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
if (!optCtx.IsSingleUsage(node->Head()) && !optCtx.IsPersistentNode(node->Head())) {
return node;
}
-/*TODO: Enable later. Providers is not ready right now.
- if (node->Head().IsCallable("Sort")) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
- auto children = node->Head().ChildrenList();
- auto it = children.cbegin();
- children.emplace(++it, node->TailPtr());
- return ctx.NewCallable(node->Pos(), "TopSort", std::move(children));
- }
-*/
- if (node->Head().IsCallable({"Top", "TopSort"})) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 1U, ctx.NewCallable(node->Pos(), "Min", {node->TailPtr(), node->Head().ChildPtr(1)}));
- }
+/*TODO: Enable later. Providers is not ready right now.
+ if (node->Head().IsCallable("Sort")) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ auto children = node->Head().ChildrenList();
+ auto it = children.cbegin();
+ children.emplace(++it, node->TailPtr());
+ return ctx.NewCallable(node->Pos(), "TopSort", std::move(children));
+ }
+*/
+ if (node->Head().IsCallable({"Top", "TopSort"})) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 1U, ctx.NewCallable(node->Pos(), "Min", {node->TailPtr(), node->Head().ChildPtr(1)}));
+ }
- if (TCoTake::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
- return FusePart<true>(*node, ctx);
+ if (TCoTake::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ return FusePart<true>(*node, ctx);
}
- if (TCoEnumerate::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
- return ctx.SwapWithHead(*node);
+ if (TCoEnumerate::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
}
- if (TCoFlatMapBase::Match(&node->Head()) &&
- node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List &&
- IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.SwapWithHead(*node);
+ if (TCoFlatMapBase::Match(&node->Head()) &&
+ node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List &&
+ IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
}
return node;
@@ -1842,39 +1842,39 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
}
- if (node->Head().IsCallable("Enumerate")) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ if (node->Head().IsCallable("Enumerate")) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
}
- if (TCoExtendBase::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Sum " << node->Content() << " over " << node->Head().Content();
+ if (TCoExtendBase::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Sum " << node->Content() << " over " << node->Head().Content();
return SumLengthOverExtend(*node, ctx);
}
- if (node->Head().IsCallable({"Append", "Insert"})) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Head().Tail().Pos(), "Inc", {ctx.ChangeChild(*node, 0U, node->Head().HeadPtr())});
+ if (node->Head().IsCallable({"Append", "Insert"})) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Head().Tail().Pos(), "Inc", {ctx.ChangeChild(*node, 0U, node->Head().HeadPtr())});
}
- if (node->Head().IsCallable("Prepend")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Head().Head().Pos(), "Inc", {ctx.ChangeChild(*node, 0U, node->Head().TailPtr())});
+ if (node->Head().IsCallable("Prepend")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Head().Head().Pos(), "Inc", {ctx.ChangeChild(*node, 0U, node->Head().TailPtr())});
}
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
- const auto itemType = node->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
+ const auto itemType = node->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
if (itemType->GetKind() == ETypeAnnotationKind::Struct) {
- const auto structType = itemType->Cast<TStructExprType>();
+ const auto structType = itemType->Cast<TStructExprType>();
if (structType->GetSize() > 0) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over non empty structs";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over non empty structs";
return ctx.Builder(node->Pos())
.Callable("Length")
.Callable(0, "ExtractMembers")
- .Add(0, node->HeadPtr())
- .List(1).Seal()
+ .Add(0, node->HeadPtr())
+ .List(1).Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
}
}
}
@@ -1887,13 +1887,13 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
}
- if (node->Head().IsCallable("Enumerate")) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ if (node->Head().IsCallable("Enumerate")) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
}
- if (TCoExtendBase::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (TCoExtendBase::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return OrHasItemsOverExtend(*node, ctx);
}
@@ -1905,26 +1905,26 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
}
- if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct &&
- 1U == node->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize()) {
- return ExtractOneItemStructFromFold(*node, ctx);
- } else if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
- 1U == node->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
- return ExtractOneItemTupleFromFold(*node, ctx);
+ if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct &&
+ 1U == node->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize()) {
+ return ExtractOneItemStructFromFold(*node, ctx);
+ } else if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
+ 1U == node->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
+ return ExtractOneItemTupleFromFold(*node, ctx);
+ }
+
+ if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ return PropagateMapToFold(*node, ctx);
}
- if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- return PropagateMapToFold(*node, ctx);
+ if (node->Tail().Tail().IsCallable({"+", "Add", "Inc", "AggrAdd"})) {
+ return ConvertFoldBySumToLength(node, ctx);
}
- if (node->Tail().Tail().IsCallable({"+", "Add", "Inc", "AggrAdd"})) {
- return ConvertFoldBySumToLength(node, ctx);
+ if (2U == node->Tail().Tail().ChildrenSize() && node->Tail().Tail().IsCallable({"Min", "Max", "AggrMin", "AggrMax"})) {
+ return ConvertFoldByConstMinMax(node, ctx);
}
- if (2U == node->Tail().Tail().ChildrenSize() && node->Tail().Tail().IsCallable({"Min", "Max", "AggrMin", "AggrMax"})) {
- return ConvertFoldByConstMinMax(node, ctx);
- }
-
return node;
};
@@ -1933,81 +1933,81 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
}
- if (node->Child(1)->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct &&
- 1U == node->Child(1)->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize()) {
- return ExtractOneItemStructFromFold1(*node, ctx);
- } else if (node->Child(1)->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
- 1U == node->Child(1)->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
- return ExtractOneItemTupleFromFold1(*node, ctx);
+ if (node->Child(1)->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct &&
+ 1U == node->Child(1)->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize()) {
+ return ExtractOneItemStructFromFold1(*node, ctx);
+ } else if (node->Child(1)->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
+ 1U == node->Child(1)->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
+ return ExtractOneItemTupleFromFold1(*node, ctx);
}
- if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- return PropagateMapToFold1(*node, ctx);
+ if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ return PropagateMapToFold1(*node, ctx);
}
- if (node->Tail().Tail().IsCallable({"+", "Add", "Inc", "AggrAdd"})) {
- return ConvertFold1BySumToLength(node, ctx);
+ if (node->Tail().Tail().IsCallable({"+", "Add", "Inc", "AggrAdd"})) {
+ return ConvertFold1BySumToLength(node, ctx);
}
- if (2U == node->Tail().Tail().ChildrenSize() && node->Tail().Tail().IsCallable({"Min", "Max", "AggrMin", "AggrMax"})) {
- return ConvertFold1ByConstMinMax(node, ctx);
+ if (2U == node->Tail().Tail().ChildrenSize() && node->Tail().Tail().IsCallable({"Min", "Max", "AggrMin", "AggrMax"})) {
+ return ConvertFold1ByConstMinMax(node, ctx);
}
return node;
};
- map["Condense"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ map["Condense"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- const auto itemType = GetSeqItemType(node->GetTypeAnn());
- if (itemType->GetKind() == ETypeAnnotationKind::Struct &&
- 1U == itemType->Cast<TStructExprType>()->GetSize()) {
- return ExtractOneItemStructFromCondense(*node, ctx);
- } else if (itemType->GetKind() == ETypeAnnotationKind::Tuple &&
- 1U == itemType->Cast<TTupleExprType>()->GetSize()) {
- return ExtractOneItemTupleFromCondense(*node, ctx);
- }
-
- if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- return PropagateMapToCondense(*node, ctx);
- }
-
+ return node;
+ }
+
+ const auto itemType = GetSeqItemType(node->GetTypeAnn());
+ if (itemType->GetKind() == ETypeAnnotationKind::Struct &&
+ 1U == itemType->Cast<TStructExprType>()->GetSize()) {
+ return ExtractOneItemStructFromCondense(*node, ctx);
+ } else if (itemType->GetKind() == ETypeAnnotationKind::Tuple &&
+ 1U == itemType->Cast<TTupleExprType>()->GetSize()) {
+ return ExtractOneItemTupleFromCondense(*node, ctx);
+ }
+
+ if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ return PropagateMapToCondense(*node, ctx);
+ }
+
if (node->Head().IsCallable({"ForwardList", "FromFlow"})) {
YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
return ctx.SwapWithHead(*node);
}
- return node;
- };
-
- map["Condense1"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ return node;
+ };
+
+ map["Condense1"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- const auto itemType = GetSeqItemType(node->GetTypeAnn());
- if (itemType->GetKind() == ETypeAnnotationKind::Struct &&
- 1U == itemType->Cast<TStructExprType>()->GetSize()) {
- return ExtractOneItemStructFromCondense1(*node, ctx);
- } else if (itemType->GetKind() == ETypeAnnotationKind::Tuple &&
- 1U == itemType->Cast<TTupleExprType>()->GetSize()) {
- return ExtractOneItemTupleFromCondense1(*node, ctx);
- }
-
- if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
- return PropagateMapToCondense1(*node, ctx);
- }
-
+ return node;
+ }
+
+ const auto itemType = GetSeqItemType(node->GetTypeAnn());
+ if (itemType->GetKind() == ETypeAnnotationKind::Struct &&
+ 1U == itemType->Cast<TStructExprType>()->GetSize()) {
+ return ExtractOneItemStructFromCondense1(*node, ctx);
+ } else if (itemType->GetKind() == ETypeAnnotationKind::Tuple &&
+ 1U == itemType->Cast<TTupleExprType>()->GetSize()) {
+ return ExtractOneItemTupleFromCondense1(*node, ctx);
+ }
+
+ if (node->Head().IsCallable({"FlatMap", "OrderedFlatMap"}) && IsJustOrSingleAsList(node->Head().Tail().Tail())) {
+ return PropagateMapToCondense1(*node, ctx);
+ }
+
if (node->Head().IsCallable({"ForwardList", "FromFlow"})) {
YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
return ctx.SwapWithHead(*node);
}
- return node;
- };
-
+ return node;
+ };
+
map["CombineByKey"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
return node;
@@ -2019,19 +2019,19 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return FuseCombineByKeyOverFlatmap(self, ctx);
}
- const auto preMap = self.PreMapLambda();
- if (IsConstMapLambda(preMap) &&
- (
- IsDepended(node->Child(2)->Tail(), *node->Child(2)->Head().Child(0)) ||
- IsDepended(node->Child(3)->Tail(), *node->Child(3)->Head().Child(1)) ||
- IsDepended(node->Child(4)->Tail(), *node->Child(4)->Head().Child(1))
- )
- ) {
- return PropagateConstPremapIntoCombineByKey(*node, ctx);
+ const auto preMap = self.PreMapLambda();
+ if (IsConstMapLambda(preMap) &&
+ (
+ IsDepended(node->Child(2)->Tail(), *node->Child(2)->Head().Child(0)) ||
+ IsDepended(node->Child(3)->Tail(), *node->Child(3)->Head().Child(1)) ||
+ IsDepended(node->Child(4)->Tail(), *node->Child(4)->Head().Child(1))
+ )
+ ) {
+ return PropagateConstPremapIntoCombineByKey(*node, ctx);
}
if (preMap.Body().Ref().IsCallable("ToList")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " premap ToList elimination";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " premap ToList elimination";
TExprNode::TPtr newPreMapLambda = ctx.DeepCopyLambda(preMap.Ref());
newPreMapLambda = ctx.ChangeChild(*newPreMapLambda, 1, newPreMapLambda->Child(1)->Child(0));
return Build<TCoCombineByKey>(ctx, node->Pos())
@@ -2062,14 +2062,14 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["Reverse"] = std::bind(&OptimizeReverse, _1, _2, _3);
+ map["Reverse"] = std::bind(&OptimizeReverse, _1, _2, _3);
map["Visit"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
return node;
}
- if (!TCoVisit::Match(&node->Head())) {
+ if (!TCoVisit::Match(&node->Head())) {
return node;
}
@@ -2079,11 +2079,11 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
TStringBuf defOutIndex;
TSet<TString> defInnerIndicies;
- const auto& innerVisit = node->Head();
+ const auto& innerVisit = node->Head();
- if (innerVisit.ChildrenSize() % 2 == 0) {
+ if (innerVisit.ChildrenSize() % 2 == 0) {
// Has default value
- auto innerVarType = innerVisit.GetTypeAnn()->Cast<TVariantExprType>();
+ auto innerVarType = innerVisit.GetTypeAnn()->Cast<TVariantExprType>();
if (innerVarType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Struct) {
for (auto item: innerVarType->GetUnderlyingType()->Cast<TStructExprType>()->GetItems()) {
defInnerIndicies.emplace(item->GetName());
@@ -2096,12 +2096,12 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
}
}
- for (ui32 index = 1; index < innerVisit.ChildrenSize(); ++index) {
- if (innerVisit.Child(index)->IsAtom()) {
- const auto itemIndex = innerVisit.Child(index)->Content();
+ for (ui32 index = 1; index < innerVisit.ChildrenSize(); ++index) {
+ if (innerVisit.Child(index)->IsAtom()) {
+ const auto itemIndex = innerVisit.Child(index)->Content();
defInnerIndicies.erase(TString(itemIndex));
++index;
- auto lambda = innerVisit.ChildPtr(index);
+ auto lambda = innerVisit.ChildPtr(index);
if (auto var = TMaybeNode<TCoVariant>(lambda->Child(1))) {
innerLambdas[var.Cast().Index().Value()] = std::make_pair(itemIndex, std::move(lambda));
}
@@ -2110,7 +2110,7 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
}
}
else {
- if (auto var = TMaybeNode<TCoVariant>(innerVisit.Child(index))) {
+ if (auto var = TMaybeNode<TCoVariant>(innerVisit.Child(index))) {
defOutIndex = var.Cast().Index().Value();
defValue = var.Cast().Item().Ptr();
}
@@ -2133,10 +2133,10 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
}
}
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return ctx.Builder(node->Pos())
.Callable("Visit")
- .Add(0, innerVisit.HeadPtr())
+ .Add(0, innerVisit.HeadPtr())
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
ui32 index = 0;
for (ui32 i = 1; i < node->ChildrenSize(); ++i) {
@@ -2147,9 +2147,9 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
lambda = ctx.Builder(lambda->Pos())
.Lambda()
.Param("item")
- .Apply(*lambda)
+ .Apply(*lambda)
.With(0)
- .ApplyPartial(p->second->HeadPtr(), p->second->Child(1)->ChildPtr(TCoVariant::idx_Item))
+ .ApplyPartial(p->second->HeadPtr(), p->second->Child(1)->ChildPtr(TCoVariant::idx_Item))
.With(0, "item")
.Seal()
.Done()
@@ -2164,7 +2164,7 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
lambda = ctx.Builder(lambda->Pos())
.Lambda()
.Param("item")
- .Apply(*lambda)
+ .Apply(*lambda)
.With(0, defValue)
.Seal()
.Seal()
@@ -2191,44 +2191,44 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
}
- if (!TCoVisit::Match(&node->Head())) {
+ if (!TCoVisit::Match(&node->Head())) {
return node;
}
- const auto& visit = node->Head();
- for (ui32 index = 1; index < visit.ChildrenSize(); ++index) {
- if (visit.Child(index)->IsAtom()) {
+ const auto& visit = node->Head();
+ for (ui32 index = 1; index < visit.ChildrenSize(); ++index) {
+ if (visit.Child(index)->IsAtom()) {
++index;
- if (!TCoVariant::Match(visit.Child(index)->Child(1))) {
+ if (!TCoVariant::Match(visit.Child(index)->Child(1))) {
return node;
}
}
else {
- if (!TCoVariant::Match(visit.Child(index))) {
+ if (!TCoVariant::Match(visit.Child(index))) {
return node;
}
}
}
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.Builder(visit.Pos())
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.Builder(visit.Pos())
.Callable("Visit")
- .Add(0, visit.HeadPtr())
+ .Add(0, visit.HeadPtr())
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 1; i < visit.ChildrenSize(); ++i) {
- if (visit.Child(i)->IsAtom()) {
- parent.Add(i, visit.ChildPtr(i));
- auto visitLambda = visit.Child(i + 1);
+ for (ui32 i = 1; i < visit.ChildrenSize(); ++i) {
+ if (visit.Child(i)->IsAtom()) {
+ parent.Add(i, visit.ChildPtr(i));
+ auto visitLambda = visit.Child(i + 1);
parent.Lambda(i + 1, visitLambda->Pos())
.Param("item")
- .ApplyPartial(visitLambda->HeadPtr(), visitLambda->Child(1)->ChildPtr(TCoVariant::idx_Item))
+ .ApplyPartial(visitLambda->HeadPtr(), visitLambda->Child(1)->ChildPtr(TCoVariant::idx_Item))
.With(0, "item")
.Seal()
.Seal();
++i;
}
else {
- parent.Add(i, visit.Child(i)->ChildPtr(TCoVariant::idx_Item));
+ parent.Add(i, visit.Child(i)->ChildPtr(TCoVariant::idx_Item));
}
}
return parent;
@@ -2288,25 +2288,25 @@ void RegisterCoFlowCallables1(TCallableOptimizerMap& map) {
return node;
};
-
- map["Exists"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+
+ map["Exists"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- if (node->Head().IsCallable("Lookup")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node;
+ }
+
+ if (node->Head().IsCallable("Lookup")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return ctx.RenameNode(node->Head(), "Contains");
- }
-
- return node;
- };
+ }
+
+ return node;
+ };
- map["Sort"] = map["Top"] = map["TopSort"] =
+ map["Sort"] = map["Top"] = map["TopSort"] =
map["TakeWhile"] = map["SkipWhile"] = map["TakeWhileInclusive"] = map["SkipWhileInclusive"] =
map["SkipNullElements"] = map["FilterNullMembers"] = map["FilterNullElements"] = map["ExtractMembers"] =
- map["Chain1Map"] = map["Fold1Map"] = map["FoldMap"] =
- map["Map"] = map["OrderedMap"] = map["MultiMap"] = map["OrderedMultiMap"] =
+ map["Chain1Map"] = map["Fold1Map"] = map["FoldMap"] =
+ map["Map"] = map["OrderedMap"] = map["MultiMap"] = map["OrderedMultiMap"] =
[](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx)
{
if (!optCtx.IsSingleUsage(node->Head())) {
diff --git a/ydb/library/yql/core/common_opt/yql_co_flow2.cpp b/ydb/library/yql/core/common_opt/yql_co_flow2.cpp
index b25b22dd77..88f9140031 100644
--- a/ydb/library/yql/core/common_opt/yql_co_flow2.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_flow2.cpp
@@ -113,15 +113,15 @@ TExprNode::TPtr AggregateSubsetFieldsAnalyzer(const TCoAggregate& node, TExprCon
return ret;
}
-void GatherAndTerms(TExprNode::TPtr&& predicate, TExprNode::TListType& andTerms) {
+void GatherAndTerms(TExprNode::TPtr&& predicate, TExprNode::TListType& andTerms) {
if (!predicate->IsCallable("And")) {
- andTerms.emplace_back(std::move(predicate));
+ andTerms.emplace_back(std::move(predicate));
return;
}
- for (auto& child : predicate->ChildrenList()) {
- GatherAndTerms(std::move(child), andTerms);
- }
+ for (auto& child : predicate->ChildrenList()) {
+ GatherAndTerms(std::move(child), andTerms);
+ }
}
TExprNode::TPtr FuseAndTerms(TPositionHandle position, const TExprNode::TListType& andTerms, TExprNode::TPtr exclude, TExprContext& ctx) {
@@ -315,7 +315,7 @@ TExprNode::TPtr SingleInputPredicatePushdownOverEquiJoin(TExprNode::TPtr equiJoi
TSet<TString> optionalKeyColumns;
GatherOptionalKeyColumns(joinTree, labels, inputIndex, optionalKeyColumns);
newInput = FilterOutNullJoinColumns(predicate->Pos(),
- prevInput, labels.Inputs[inputIndex], optionalKeyColumns, ctx);
+ prevInput, labels.Inputs[inputIndex], optionalKeyColumns, ctx);
}
// then apply predicate
@@ -484,7 +484,7 @@ TExprNode::TPtr FlatMapOverEquiJoin(const TCoFlatMapBase& node, TExprContext& ct
if (IsPredicateFlatMap(node.Lambda().Body().Ref())) {
// predicate pushdown
- const auto& row = node.Lambda().Args().Arg(0).Ref();
+ const auto& row = node.Lambda().Args().Arg(0).Ref();
auto predicate = node.Lambda().Body().Ref().ChildPtr(0);
auto value = node.Lambda().Body().Ref().ChildPtr(1);
TJoinLabels labels;
@@ -499,9 +499,9 @@ TExprNode::TPtr FlatMapOverEquiJoin(const TCoFlatMapBase& node, TExprContext& ct
}
TExprNode::TListType andTerms;
- GatherAndTerms(std::move(predicate), andTerms);
- TExprNode::TPtr ret;
- TExprNode::TPtr extraPredicate;
+ GatherAndTerms(std::move(predicate), andTerms);
+ TExprNode::TPtr ret;
+ TExprNode::TPtr extraPredicate;
auto joinSettings = equiJoin.Ref().Child(equiJoin.Ref().ChildrenSize() - 1);
auto renameMap = LoadJoinRenameMap(*joinSettings);
THashMap<TString, TString> backRenameMap;
@@ -522,7 +522,7 @@ TExprNode::TPtr FlatMapOverEquiJoin(const TCoFlatMapBase& node, TExprContext& ct
TSet<TStringBuf> usedFields;
TSet<ui32> inputs;
- if (!HaveFieldsSubset(andTerm, row, usedFields, parentsMap, false)) {
+ if (!HaveFieldsSubset(andTerm, row, usedFields, parentsMap, false)) {
continue;
}
@@ -572,26 +572,26 @@ TExprNode::TPtr FlatMapOverEquiJoin(const TCoFlatMapBase& node, TExprContext& ct
if (extraPredicate) {
ret = ctx.Builder(node.Pos())
.Callable(ordered ? "OrderedFilter" : "Filter")
- .Add(0, std::move(ret))
+ .Add(0, std::move(ret))
.Lambda(1)
.Param("item")
- .ApplyPartial(node.Lambda().Args().Ptr(), std::move(extraPredicate)).WithNode(row, "item").Seal()
+ .ApplyPartial(node.Lambda().Args().Ptr(), std::move(extraPredicate)).WithNode(row, "item").Seal()
.Seal()
.Seal()
.Build();
}
- if (value != &row) {
+ if (value != &row) {
TString name = node.Lambda().Body().Ref().Content().StartsWith("Flat") ? "FlatMap" : "Map";
if (ordered) {
name.prepend("Ordered");
}
ret = ctx.Builder(node.Pos())
.Callable(name)
- .Add(0, std::move(ret))
+ .Add(0, std::move(ret))
.Lambda(1)
.Param("item")
- .ApplyPartial(node.Lambda().Args().Ptr(), std::move(value)).With(0, "item").Seal()
+ .ApplyPartial(node.Lambda().Args().Ptr(), std::move(value)).With(0, "item").Seal()
.Seal()
.Seal()
.Build();
@@ -1205,7 +1205,7 @@ TExprNode::TPtr BuildOutputFlattenMembersArg(const TCoEquiJoinInput& input, cons
auto flatMap = input.List().Cast<TCoFlatMapBase>();
auto lambda = flatMap.Lambda();
YQL_ENSURE(IsJustOrSingleAsList(lambda.Body().Ref()));
- auto strippedLambdaBody = lambda.Body().Ref().HeadPtr();
+ auto strippedLambdaBody = lambda.Body().Ref().HeadPtr();
const TString labelPrefix = TString::Join(label, ".");
const TString fullCanaryName = FullColumnName(label, canaryName);
@@ -1234,8 +1234,8 @@ TExprNode::TPtr BuildOutputFlattenMembersArg(const TCoEquiJoinInput& input, cons
return ctx.Builder(input.Pos())
.List()
.Atom(0, labelPrefix)
- .ApplyPartial(1, lambda.Args().Ptr(), std::move(strippedLambdaBody))
- .With(0, std::move(myStruct))
+ .ApplyPartial(1, lambda.Args().Ptr(), std::move(strippedLambdaBody))
+ .With(0, std::move(myStruct))
.Seal()
.Seal()
.Build();
@@ -1243,31 +1243,31 @@ TExprNode::TPtr BuildOutputFlattenMembersArg(const TCoEquiJoinInput& input, cons
YQL_ENSURE(canaryOutType->GetKind() == ETypeAnnotationKind::Optional);
- TExprNode::TListType membersForCheck;
+ TExprNode::TListType membersForCheck;
auto flatMapInputItems = flatMapInputItem->Cast<TStructExprType>()->GetItems();
if (!keepSys) {
EraseIf(flatMapInputItems, [](const TItemExprType* item) { return item->GetName().StartsWith("_yql_sys_"); });
}
flatMapInputItems.push_back(ctx.MakeType<TItemExprType>(canaryName, ctx.MakeType<TDataExprType>(EDataSlot::Bool)));
for (auto& item : flatMapInputItems) {
- if (item->GetItemType()->GetKind() != ETypeAnnotationKind::Optional) {
- membersForCheck.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
+ if (item->GetItemType()->GetKind() != ETypeAnnotationKind::Optional) {
+ membersForCheck.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
}
}
- auto checkedMembersList = ctx.NewList(input.Pos(), std::move(membersForCheck));
+ auto checkedMembersList = ctx.NewList(input.Pos(), std::move(membersForCheck));
return ctx.Builder(input.Pos())
.List()
.Atom(0, labelPrefix)
.Callable(1, "IfPresent")
- .Callable(0, "FilterNullMembers")
+ .Callable(0, "FilterNullMembers")
.Callable(0, "AssumeAllMembersNullableAtOnce")
.Callable(0, "Just")
.Add(0, std::move(myStruct))
.Seal()
- .Seal()
- .Add(1, std::move(checkedMembersList))
+ .Seal()
+ .Add(1, std::move(checkedMembersList))
.Seal()
.Lambda(1)
.Param("canaryInput")
@@ -1275,7 +1275,7 @@ TExprNode::TPtr BuildOutputFlattenMembersArg(const TCoEquiJoinInput& input, cons
.List(0)
.Atom(0, "")
.Callable(1, "Just")
- .ApplyPartial(0, lambda.Args().Ptr(), std::move(strippedLambdaBody))
+ .ApplyPartial(0, lambda.Args().Ptr(), std::move(strippedLambdaBody))
.With(0)
.Callable("RemoveMember")
.Arg(0, "canaryInput")
@@ -1502,15 +1502,15 @@ TExprNode::TPtr PullUpFlatMapOverEquiJoin(const TExprNode::TPtr& node, TExprCont
TExprNode::TPtr OptimizeFromFlow(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- if (node->Head().IsCallable("ToFlow") &&
- node->Head().Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with " << node->Head().Content();
- return node->Head().HeadPtr();
- }
-
+ return node;
+ }
+
+ if (node->Head().IsCallable("ToFlow") &&
+ node->Head().Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
+
if (node->Head().IsCallable("ToFlow") &&
node->Head().Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
YQL_CLOG(DEBUG, Core) << "Replace " << node->Content() << " with Iterator";
@@ -1521,31 +1521,31 @@ TExprNode::TPtr OptimizeFromFlow(const TExprNode::TPtr& node, TExprContext& ctx,
.Ptr();
}
- return node;
+ return node;
}
-TExprNode::TPtr OptimizeCollect(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+TExprNode::TPtr OptimizeCollect(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (!optCtx.IsSingleUsage(node->Head())) {
- return node;
- }
-
- if (node->Head().IsCallable({"ToFlow", "FromFlow"}) &&
- node->Head().Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChildren(*node, node->Head().ChildrenList());
- }
-
- return node;
-}
-
-}
-
+ return node;
+ }
+
+ if (node->Head().IsCallable({"ToFlow", "FromFlow"}) &&
+ node->Head().Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChildren(*node, node->Head().ChildrenList());
+ }
+
+ return node;
+}
+
+}
+
void RegisterCoFlowCallables2(TCallableOptimizerMap& map) {
- using namespace std::placeholders;
-
+ using namespace std::placeholders;
+
map["FromFlow"] = std::bind(&OptimizeFromFlow, _1, _2, _3);
- map["Collect"] = std::bind(&OptimizeCollect, _1, _2, _3);
-
+ map["Collect"] = std::bind(&OptimizeCollect, _1, _2, _3);
+
map["FlatMap"] = map["OrderedFlatMap"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
TCoFlatMapBase self(node);
if (!optCtx.IsSingleUsage(self.Input().Ref())) {
@@ -1916,13 +1916,13 @@ void RegisterCoFlowCallables2(TCallableOptimizerMap& map) {
return node;
}
- if (self.Input().Maybe<TCoChopper>()) {
- if (auto res = ApplyExtractMembersToChopper(self.Input().Ptr(), self.Members().Ptr(), ctx, {})) {
- return res;
- }
- return node;
- }
-
+ if (self.Input().Maybe<TCoChopper>()) {
+ if (auto res = ApplyExtractMembersToChopper(self.Input().Ptr(), self.Members().Ptr(), ctx, {})) {
+ return res;
+ }
+ return node;
+ }
+
if (self.Input().Maybe<TCoCollect>()) {
if (auto res = ApplyExtractMembersToCollect(self.Input().Ptr(), self.Members().Ptr(), ctx, {})) {
return res;
@@ -1930,17 +1930,17 @@ void RegisterCoFlowCallables2(TCallableOptimizerMap& map) {
return node;
}
- if (self.Input().Maybe<TCoMapJoinCore>()) {
- if (auto res = ApplyExtractMembersToMapJoinCore(self.Input().Ptr(), self.Members().Ptr(), ctx, {})) {
- return res;
- }
- return node;
- }
-
+ if (self.Input().Maybe<TCoMapJoinCore>()) {
+ if (auto res = ApplyExtractMembersToMapJoinCore(self.Input().Ptr(), self.Members().Ptr(), ctx, {})) {
+ return res;
+ }
+ return node;
+ }
+
return node;
};
- map[TCoChopper::CallableName()] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ map[TCoChopper::CallableName()] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
const TCoChopper chopper(node);
const auto arg = chopper.Handler().Args().Arg(1).Raw();
if (const auto parents = optCtx.ParentsMap->find(arg); parents != optCtx.ParentsMap->cend()
@@ -1949,35 +1949,35 @@ void RegisterCoFlowCallables2(TCallableOptimizerMap& map) {
&& arg == &(*parents->second.begin())->Head())
{
const auto extract = *parents->second.begin();
- std::map<std::string_view, TExprNode::TPtr> usedFields;
+ std::map<std::string_view, TExprNode::TPtr> usedFields;
auto fields = extract->Tail().ChildrenList();
- std::for_each(fields.cbegin(), fields.cend(), [&](const TExprNode::TPtr& field){ usedFields.emplace(field->Content(), field); });
-
- if (HaveFieldsSubset(chopper.KeyExtractor().Body().Ptr(), chopper.KeyExtractor().Args().Arg(0).Ref(), usedFields, *optCtx.ParentsMap, false) && !usedFields.empty() &&
- HaveFieldsSubset(chopper.GroupSwitch().Body().Ptr(), chopper.GroupSwitch().Args().Arg(1).Ref(), usedFields, *optCtx.ParentsMap, false) && !usedFields.empty() &&
- usedFields.size() < GetSeqItemType(chopper.Input().Ref().GetTypeAnn())->Cast<TStructExprType>()->GetSize()) {
- if (usedFields.size() != fields.size()) {
- fields.reserve(usedFields.size());
- fields.clear();
- std::transform(usedFields.begin(), usedFields.end(), std::back_inserter(fields),
- [](std::pair<const std::string_view, TExprNode::TPtr>& item){ return std::move(item.second); });
- }
-
+ std::for_each(fields.cbegin(), fields.cend(), [&](const TExprNode::TPtr& field){ usedFields.emplace(field->Content(), field); });
+
+ if (HaveFieldsSubset(chopper.KeyExtractor().Body().Ptr(), chopper.KeyExtractor().Args().Arg(0).Ref(), usedFields, *optCtx.ParentsMap, false) && !usedFields.empty() &&
+ HaveFieldsSubset(chopper.GroupSwitch().Body().Ptr(), chopper.GroupSwitch().Args().Arg(1).Ref(), usedFields, *optCtx.ParentsMap, false) && !usedFields.empty() &&
+ usedFields.size() < GetSeqItemType(chopper.Input().Ref().GetTypeAnn())->Cast<TStructExprType>()->GetSize()) {
+ if (usedFields.size() != fields.size()) {
+ fields.reserve(usedFields.size());
+ fields.clear();
+ std::transform(usedFields.begin(), usedFields.end(), std::back_inserter(fields),
+ [](std::pair<const std::string_view, TExprNode::TPtr>& item){ return std::move(item.second); });
+ }
+
YQL_CLOG(DEBUG, Core) << "Pull out " << extract->Content() << " from " << node->Content();
- return Build<TCoChopper>(ctx, chopper.Pos())
- .Input<TCoExtractMembers>()
- .Input(chopper.Input())
- .Members().Add(std::move(fields)).Build()
- .Build()
- .KeyExtractor(ctx.DeepCopyLambda(chopper.KeyExtractor().Ref()))
- .GroupSwitch(ctx.DeepCopyLambda(chopper.GroupSwitch().Ref()))
- .Handler(ctx.DeepCopyLambda(chopper.Handler().Ref()))
- .Done().Ptr();
- }
- }
- return node;
- };
-
+ return Build<TCoChopper>(ctx, chopper.Pos())
+ .Input<TCoExtractMembers>()
+ .Input(chopper.Input())
+ .Members().Add(std::move(fields)).Build()
+ .Build()
+ .KeyExtractor(ctx.DeepCopyLambda(chopper.KeyExtractor().Ref()))
+ .GroupSwitch(ctx.DeepCopyLambda(chopper.GroupSwitch().Ref()))
+ .Handler(ctx.DeepCopyLambda(chopper.Handler().Ref()))
+ .Done().Ptr();
+ }
+ }
+ return node;
+ };
+
map["WindowTraits"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
auto structType = node->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
TSet<TStringBuf> usedFields;
diff --git a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
index 5f0519c587..a32a6c3dab 100644
--- a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
@@ -53,16 +53,16 @@ TExprNode::TPtr KeepSortedConstraint(TExprNode::TPtr node, const TSortedConstrai
if (!sorted) {
return node;
}
- const auto& constent = sorted->GetContent();
+ const auto& constent = sorted->GetContent();
return ctx.Builder(node->Pos())
.Callable("AssumeSorted")
.Add(0, std::move(node))
.List(1)
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
size_t index = 0;
- for (auto c : constent) {
+ for (auto c : constent) {
parent.Callable(index++, "Bool")
- .Atom(0, ToString(c.second), TNodeFlags::Default)
+ .Atom(0, ToString(c.second), TNodeFlags::Default)
.Seal();
}
return parent;
@@ -73,10 +73,10 @@ TExprNode::TPtr KeepSortedConstraint(TExprNode::TPtr node, const TSortedConstrai
.List()
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
size_t index = 0;
- for (auto c : constent) {
+ for (auto c : constent) {
parent.Callable(index++, "Member")
.Arg(0, "item")
- .Atom(1, c.first.front())
+ .Atom(1, c.first.front())
.Seal();
}
return parent;
@@ -210,7 +210,7 @@ TExprNode::TPtr ExpandFlattenEquiJoin(const TExprNode::TPtr& node, TExprContext&
TExprNode::TListType settingsChildren;
bool hasFlatten = false;
for (auto& child : settings->Children()) {
- if (child->ChildrenSize() > 0 && child->Head().Content() == "flatten") {
+ if (child->ChildrenSize() > 0 && child->Head().Content() == "flatten") {
hasFlatten = true;
continue;
}
@@ -225,8 +225,8 @@ TExprNode::TPtr ExpandFlattenEquiJoin(const TExprNode::TPtr& node, TExprContext&
const size_t numLists = node->ChildrenSize() - 2;
TJoinLabels labels;
for (ui32 idx = 0; idx < numLists; ++idx) {
- const auto& listPair = *node->Child(idx);
- const auto& list = listPair.Head();
+ const auto& listPair = *node->Child(idx);
+ const auto& list = listPair.Head();
const TTypeAnnotationNode* itemType = list.GetTypeAnn()->Cast<TListExprType>()->GetItemType();
auto structType = itemType->Cast<TStructExprType>();
if (auto err = labels.Add(ctx, *listPair.Child(1), structType)) {
@@ -298,7 +298,7 @@ TExprNode::TPtr ExpandFlattenEquiJoin(const TExprNode::TPtr& node, TExprContext&
auto newSettings = ctx.ChangeChildren(*settings, std::move(settingsChildren));
auto newJoin = ctx.ChangeChild(*node, node->ChildrenSize() - 1, std::move(newSettings));
- return ctx.NewCallable(node->Pos(), "Map", { std::move(newJoin), std::move(mapLambda) });
+ return ctx.NewCallable(node->Pos(), "Map", { std::move(newJoin), std::move(mapLambda) });
}
void GatherEquiJoinKeyColumnsFromEquality(TExprNode::TPtr columns, THashSet<TString>& keyColumns) {
@@ -337,7 +337,7 @@ void GatherDroppedSingleTableColumns(TExprNode::TPtr joinTree, const TJoinLabels
GatherDroppedSingleTableColumns(right, labels, drops);
}
- auto mode = joinTree->Head().Content();
+ auto mode = joinTree->Head().Content();
TExprNode::TPtr columns = nullptr;
if (mode == "LeftSemi" || mode == "LeftOnly") {
// drop right table columns
@@ -349,7 +349,7 @@ void GatherDroppedSingleTableColumns(TExprNode::TPtr joinTree, const TJoinLabels
}
if (columns) {
- auto label = *labels.FindInput(columns->Head().Content());
+ auto label = *labels.FindInput(columns->Head().Content());
for (auto column : label->EnumerateAllColumns()) {
drops.insert(column);
}
@@ -360,7 +360,7 @@ TExprNode::TPtr RemoveDeadPayloadColumns(const TExprNode::TPtr& node, TExprConte
auto settings = node->Children().back();
TSet<TString> drops;
for (auto& setting : settings->Children()) {
- auto name = setting->Head().Content();
+ auto name = setting->Head().Content();
if (name == "rename") {
if (setting->Child(2)->Content().empty()) {
drops.insert(TString(setting->Child(1)->Content()));
@@ -369,7 +369,7 @@ TExprNode::TPtr RemoveDeadPayloadColumns(const TExprNode::TPtr& node, TExprConte
}
for (auto& setting : settings->Children()) {
- auto name = setting->Head().Content();
+ auto name = setting->Head().Content();
if (name == "rename") {
if (!setting->Child(2)->Content().empty()) {
drops.erase(TString(setting->Child(1)->Content()));
@@ -380,7 +380,7 @@ TExprNode::TPtr RemoveDeadPayloadColumns(const TExprNode::TPtr& node, TExprConte
TJoinLabels labels;
for (ui32 i = 0; i < node->ChildrenSize() - 2; ++i) {
auto err = labels.Add(ctx, *node->Child(i)->Child(1),
- node->Child(i)->Head().GetTypeAnn()->Cast<TListExprType>()
+ node->Child(i)->Head().GetTypeAnn()->Cast<TListExprType>()
->GetItemType()->Cast<TStructExprType>());
if (err) {
ctx.AddError(*err);
@@ -441,7 +441,7 @@ TExprNode::TPtr RemoveDeadPayloadColumns(const TExprNode::TPtr& node, TExprConte
TExprNode::TListType settingsChildren;
for (const auto& setting : settings->Children()) {
- auto name = setting->Head().Content();
+ auto name = setting->Head().Content();
if (name != "rename" || !setting->Child(2)->Content().empty() || !drops.contains(setting->Child(1)->Content())) {
settingsChildren.push_back(setting);
}
@@ -454,7 +454,7 @@ TExprNode::TPtr RemoveDeadPayloadColumns(const TExprNode::TPtr& node, TExprConte
TExprNode::TPtr HandleEmptyListInJoin(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& typeCtx) {
TMaybe<TJoinLabels> labels;
for (ui32 inputIndex = 0; inputIndex < node->ChildrenSize() - 2; ++inputIndex) {
- auto& input = SkipCallables(node->Child(inputIndex)->Head(), SkippableCallables);
+ auto& input = SkipCallables(node->Child(inputIndex)->Head(), SkippableCallables);
if (!IsEmptyContainer(input) && !IsEmpty(input, typeCtx)) {
continue;
}
@@ -474,7 +474,7 @@ TExprNode::TPtr HandleEmptyListInJoin(const TExprNode::TPtr& node, TExprContext&
}
if (IsRequiredSide(joinTree, *labels, inputIndex).first) {
- return ctx.NewCallable(node->Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ return ctx.NewCallable(node->Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
}
}
@@ -594,42 +594,42 @@ bool IsOptBoolType(const TExprNode& node) {
return node.GetTypeAnn() && IsOptBoolType(*node.GetTypeAnn());
}
-template <bool AppendOrPrepend>
+template <bool AppendOrPrepend>
TExprNode::TPtr OptimizeInsert(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- const auto& list = AppendOrPrepend ? node->Head() : node->Tail();
+ const auto& list = AppendOrPrepend ? node->Head() : node->Tail();
if (IsEmptyContainer(list) || IsEmpty(list, *optCtx.Types)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << list.Content();
- return ctx.NewCallable(node->Pos(), "AsList", {AppendOrPrepend ? node->TailPtr() : node->HeadPtr()});
- }
-
- if (list.IsCallable("AsList")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << list.Content();
- auto children = list.ChildrenList();
- if (AppendOrPrepend) {
- children.emplace_back(node->TailPtr());
- } else {
- children.emplace(children.cbegin(), node->HeadPtr());
- }
- return ctx.ChangeChildren(list, std::move(children));
- }
- return node;
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << list.Content();
+ return ctx.NewCallable(node->Pos(), "AsList", {AppendOrPrepend ? node->TailPtr() : node->HeadPtr()});
+ }
+
+ if (list.IsCallable("AsList")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << list.Content();
+ auto children = list.ChildrenList();
+ if (AppendOrPrepend) {
+ children.emplace_back(node->TailPtr());
+ } else {
+ children.emplace(children.cbegin(), node->HeadPtr());
+ }
+ return ctx.ChangeChildren(list, std::move(children));
+ }
+ return node;
}
-template <bool Ordered>
+template <bool Ordered>
TExprNode::TPtr ExpandExtract(const TExprNode::TPtr& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Expand " << node->Content();
- const bool isStruct = ETypeAnnotationKind::Struct == GetSeqItemType(node->Head().GetTypeAnn())->GetKind();
- return ctx.Builder(node->Pos())
- .Callable(Ordered ? "OrderedMap" : "Map")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("x")
- .Callable(isStruct ? "Member" : "Nth")
- .Arg(0, "x")
- .Add(1, node->TailPtr())
- .Seal()
- .Seal()
- .Seal().Build();
+ YQL_CLOG(DEBUG, Core) << "Expand " << node->Content();
+ const bool isStruct = ETypeAnnotationKind::Struct == GetSeqItemType(node->Head().GetTypeAnn())->GetKind();
+ return ctx.Builder(node->Pos())
+ .Callable(Ordered ? "OrderedMap" : "Map")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("x")
+ .Callable(isStruct ? "Member" : "Nth")
+ .Arg(0, "x")
+ .Add(1, node->TailPtr())
+ .Seal()
+ .Seal()
+ .Seal().Build();
}
std::vector<TExprNode::TListType> GroupNodeChildrenByType(const TExprNode::TPtr& node) {
@@ -647,16 +647,16 @@ std::vector<TExprNode::TListType> GroupNodeChildrenByType(const TExprNode::TPtr&
return groups;
}
-template <bool Ordered>
+template <bool Ordered>
TExprNode::TPtr ExpandUnionAll(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- YQL_CLOG(DEBUG, Core) << "Expand " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Expand " << node->Content();
if (node->ChildrenSize() == 1) {
- return node->HeadPtr();
+ return node->HeadPtr();
}
auto resultStructType = node->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
TVector<TExprNode::TPtr> nulls(resultStructType->GetSize());
- auto remapList = [&ctx, &nulls, resultStructType](TExprNode::TPtr input, const TTypeAnnotationNode* inputType) -> TExprNode::TPtr {
+ auto remapList = [&ctx, &nulls, resultStructType](TExprNode::TPtr input, const TTypeAnnotationNode* inputType) -> TExprNode::TPtr {
auto pos = input->Pos();
auto arg = ctx.NewArgument(pos, "item");
auto inputStructType = inputType->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
@@ -704,7 +704,7 @@ TExprNode::TPtr ExpandUnionAll(const TExprNode::TPtr& node, TExprContext& ctx, T
}
auto body = ctx.NewCallable(pos, "AsStruct", std::move(bodyItems));
- return ctx.NewCallable(pos, Ordered ? "OrderedMap" : "Map", { input, ctx.NewLambda(
+ return ctx.NewCallable(pos, Ordered ? "OrderedMap" : "Map", { input, ctx.NewLambda(
pos,
ctx.NewArguments(pos, { arg }),
std::move(body)
@@ -742,16 +742,16 @@ TExprNode::TPtr RemoveNothingFromCoalesce(const TExprNode& node, TExprContext& c
return ctx.ChangeChildren(node, std::move(newChildren));
}
-TExprNode::TPtr OptimizeTryMember(const TExprNode::TPtr& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Optimize " << node->Content();
+TExprNode::TPtr OptimizeTryMember(const TExprNode::TPtr& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Optimize " << node->Content();
const bool isStructOptional = node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
const TStructExprType* structType = RemoveOptionalType(node->Head().GetTypeAnn())->Cast<TStructExprType>();
- const bool isOptional = node->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
- const auto memberName = node->Child(1)->Content();
+ const bool isOptional = node->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
+ const auto memberName = node->Child(1)->Content();
const auto wrappedDefault = ctx.WrapByCallableIf(isStructOptional && !node->TailPtr()->IsCallable("Null") &&
node->TailPtr()->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional, "Just", node->TailPtr());
- for (const auto& field : structType->GetItems()) {
+ for (const auto& field : structType->GetItems()) {
if (field->GetName() == memberName) {
const bool just = (isStructOptional || isOptional) && field->GetItemType()->GetKind() != ETypeAnnotationKind::Optional;
auto memberArg = isStructOptional ? ctx.NewArgument(node->Pos(), "x") : node->HeadPtr();
@@ -785,27 +785,27 @@ TExprNode::TPtr OptimizeTryMember(const TExprNode::TPtr& node, TExprContext& ctx
}
TExprNode::TPtr RemoveOptionalReduceOverData(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
- YQL_CLOG(DEBUG, Core) << "Remove " << node->Content() << " over data";
- const auto& lambda = node->Tail();
- const auto& arg1 = lambda.Head().Head();
- const auto& arg2 = lambda.Head().Tail();
- return ctx.ReplaceNodes(lambda.TailPtr(), {{&arg1, node->HeadPtr()}, {&arg2, node->ChildPtr(1)}});
+ if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
+ YQL_CLOG(DEBUG, Core) << "Remove " << node->Content() << " over data";
+ const auto& lambda = node->Tail();
+ const auto& arg1 = lambda.Head().Head();
+ const auto& arg2 = lambda.Head().Tail();
+ return ctx.ReplaceNodes(lambda.TailPtr(), {{&arg1, node->HeadPtr()}, {&arg2, node->ChildPtr(1)}});
}
return node;
}
TExprNode::TPtr PropagateCoalesceWithConstIntoLogicalOps(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Likely")) {
- const auto value = FromString<bool>(node->Child(1)->Head().Content());
+ if (node->Head().IsCallable("Likely")) {
+ const auto value = FromString<bool>(node->Child(1)->Head().Content());
if (!value) {
- YQL_CLOG(DEBUG, Core) << "PropagateCoalesceWithConst over " << node->Head().Content() << " (false)";
+ YQL_CLOG(DEBUG, Core) << "PropagateCoalesceWithConst over " << node->Head().Content() << " (false)";
auto ret = ctx.Builder(node->Pos())
.Callable("Likely")
.Callable(0, "Coalesce")
- .Add(0, node->Head().HeadPtr())
- .Add(1, node->ChildPtr(1))
+ .Add(0, node->Head().HeadPtr())
+ .Add(1, node->ChildPtr(1))
.Seal()
.Seal()
.Build();
@@ -813,14 +813,14 @@ TExprNode::TPtr PropagateCoalesceWithConstIntoLogicalOps(const TExprNode::TPtr&
}
}
- if (node->Head().IsCallable("Not")) {
+ if (node->Head().IsCallable("Not")) {
YQL_CLOG(DEBUG, Core) << "PropagateCoalesceWithConst over Not";
auto ret = ctx.Builder(node->Pos())
.Callable("Not")
.Callable(0, "Coalesce")
- .Add(0, node->Head().HeadPtr())
+ .Add(0, node->Head().HeadPtr())
.Callable(1, "Not")
- .Add(0, node->ChildPtr(1))
+ .Add(0, node->ChildPtr(1))
.Seal()
.Seal()
.Seal()
@@ -829,7 +829,7 @@ TExprNode::TPtr PropagateCoalesceWithConstIntoLogicalOps(const TExprNode::TPtr&
return ret;
}
- if (node->Head().IsCallable({"And", "Or"})) {
+ if (node->Head().IsCallable({"And", "Or"})) {
YQL_CLOG(DEBUG, Core) << "PropagateCoalesceWithConst over " << node->Head().Content();
auto children = node->Head().ChildrenList();
for (auto& child : children) {
@@ -841,194 +841,194 @@ TExprNode::TPtr PropagateCoalesceWithConstIntoLogicalOps(const TExprNode::TPtr&
return node;
}
-template<bool AndOr>
-TExprNode::TPtr SimplifyLogical(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto size = node->ChildrenSize();
- ui32 nothings = 0U, same = 0U, justs = 0U, negations = 0U, literals = 0U, bools = 0U;
- node->ForEachChild([&](const TExprNode& child) {
- if (child.IsCallable(node->Content()))
- ++same;
- if (child.IsCallable("Nothing"))
- ++nothings;
- if (child.IsCallable("Not"))
- ++negations;
- if (child.IsCallable("Just"))
- ++justs;
- if (child.IsCallable("Bool"))
- ++literals;
- if (IsBoolType(child))
- ++bools;
- });
-
- if (size == nothings) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing";
- return node->HeadPtr();
- }
-/*TODO Move to peephole
- if (size == negations) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over negations";
- TExprNode::TListType children;
- children.reserve(size);
- node->ForEachChild([&](const TExprNode& child) {
- children.emplace_back(child.HeadPtr());
- });
- return ctx.NewCallable(node->Pos(), "Not", {ctx.NewCallable(node->Pos(), AndOr ? "Or" : "And" , std::move(children))});
- }
-*/
- if (same) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Content();
- TExprNode::TListType children;
- children.reserve(size);
- node->ForEachChild([&](TExprNode& child) {
- if (child.IsCallable(node->Content())) {
- child.ForEachChild([&](TExprNode& sub) {
- children.emplace_back(&sub);
- });
- } else {
- children.emplace_back(&child);
- }
- });
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (justs && size == justs + bools) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Just";
- TExprNode::TListType children;
- children.reserve(size);
- node->ForEachChild([&](TExprNode& child) {
- children.emplace_back(child.IsCallable("Just") ? &child.Head() : &child);
- });
- return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChildren(*node, std::move(children))});
- }
-
- if (literals) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over literal bools";
- TExprNode::TListType children;
- children.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- if (node->Child(i)->IsCallable("Bool")) {
- const bool value = FromString<bool>(node->Child(i)->Head().Content());
- if (AndOr != value) {
- return ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", node->ChildPtr(i));
- }
- } else {
- children.emplace_back(node->ChildPtr(i));
- }
- }
-
- return children.empty() ?
- ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", MakeBool(node->Pos(), AndOr, ctx)):
- ctx.ChangeChildren(*node, std::move(children));
- }
-
- return node;
-};
-
-TExprNode::TPtr SimplifyLogicalXor(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto size = node->ChildrenSize();
- ui32 same = 0U, justs = 0U, negations = 0U, literals = 0U, bools = 0U;
- for (ui32 i = 0U; i < size; ++i) {
- const auto child = node->Child(i);
- if (child->IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing";
- return node->ChildPtr(i);
- }
- if (child->IsCallable(node->Content()))
- ++same;
- if (child->IsCallable("Not"))
- ++negations;
- if (child->IsCallable("Just"))
- ++justs;
- if (child->IsCallable("Bool"))
- ++literals;
- if (IsBoolType(*child))
- ++bools;
- };
-
- if (same) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Content();
- TExprNode::TListType children;
- children.reserve(size);
- node->ForEachChild([&](TExprNode& child) {
- if (child.IsCallable(node->Content())) {
- child.ForEachChild([&](TExprNode& sub) {
- children.emplace_back(&sub);
- });
- } else {
- children.emplace_back(&child);
- }
- });
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (justs && size == justs + bools) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Just";
- TExprNode::TListType children;
- children.reserve(size);
- node->ForEachChild([&](TExprNode& child) {
- children.emplace_back(child.IsCallable("Just") ? child.HeadPtr() : &child);
- });
- return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChildren(*node, std::move(children))});
- }
-
- if (literals || negations) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over negations or literal bools";
- TExprNode::TListType children;
- children.reserve(size);
- bool inverse = false;
- node->ForEachChild([&](TExprNode& child) {
- if (child.IsCallable("Not")) {
- children.emplace_back(child.HeadPtr());
- inverse = !inverse;
- } else if (child.IsCallable("Bool")) {
- if (FromString<bool>(child.Head().Content())) {
- inverse = !inverse;
- }
- } else {
- children.emplace_back(&child);
- }
- });
-
- return children.empty() ?
- ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", MakeBool(node->Pos(), inverse, ctx)):
- ctx.WrapByCallableIf(inverse, "Not", ctx.ChangeChildren(*node, std::move(children)));
- }
-
- return node;
-};
-
-TExprNode::TPtr SimplifyLogicalNot(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->HeadPtr();
- }
-
- if (node->Head().IsCallable("Not")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
- }
-
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ctx.ChangeChild(*node, 0U, node->Head().HeadPtr()));
- }
-
- if (node->Head().IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
- const auto value = FromString<bool>(node->Head().Head().Content());
- return MakeBool(node->Pos(), !value, ctx);
- }
-
- return node;
-}
-
-template <bool Equal>
-TExprNode::TPtr OptimizeEquality(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing") || node->Tail().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' over Nothing";
- return MakeBoolNothing(node->Pos(), ctx);
- }
-
+template<bool AndOr>
+TExprNode::TPtr SimplifyLogical(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto size = node->ChildrenSize();
+ ui32 nothings = 0U, same = 0U, justs = 0U, negations = 0U, literals = 0U, bools = 0U;
+ node->ForEachChild([&](const TExprNode& child) {
+ if (child.IsCallable(node->Content()))
+ ++same;
+ if (child.IsCallable("Nothing"))
+ ++nothings;
+ if (child.IsCallable("Not"))
+ ++negations;
+ if (child.IsCallable("Just"))
+ ++justs;
+ if (child.IsCallable("Bool"))
+ ++literals;
+ if (IsBoolType(child))
+ ++bools;
+ });
+
+ if (size == nothings) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing";
+ return node->HeadPtr();
+ }
+/*TODO Move to peephole
+ if (size == negations) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over negations";
+ TExprNode::TListType children;
+ children.reserve(size);
+ node->ForEachChild([&](const TExprNode& child) {
+ children.emplace_back(child.HeadPtr());
+ });
+ return ctx.NewCallable(node->Pos(), "Not", {ctx.NewCallable(node->Pos(), AndOr ? "Or" : "And" , std::move(children))});
+ }
+*/
+ if (same) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Content();
+ TExprNode::TListType children;
+ children.reserve(size);
+ node->ForEachChild([&](TExprNode& child) {
+ if (child.IsCallable(node->Content())) {
+ child.ForEachChild([&](TExprNode& sub) {
+ children.emplace_back(&sub);
+ });
+ } else {
+ children.emplace_back(&child);
+ }
+ });
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (justs && size == justs + bools) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Just";
+ TExprNode::TListType children;
+ children.reserve(size);
+ node->ForEachChild([&](TExprNode& child) {
+ children.emplace_back(child.IsCallable("Just") ? &child.Head() : &child);
+ });
+ return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChildren(*node, std::move(children))});
+ }
+
+ if (literals) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over literal bools";
+ TExprNode::TListType children;
+ children.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ if (node->Child(i)->IsCallable("Bool")) {
+ const bool value = FromString<bool>(node->Child(i)->Head().Content());
+ if (AndOr != value) {
+ return ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", node->ChildPtr(i));
+ }
+ } else {
+ children.emplace_back(node->ChildPtr(i));
+ }
+ }
+
+ return children.empty() ?
+ ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", MakeBool(node->Pos(), AndOr, ctx)):
+ ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ return node;
+};
+
+TExprNode::TPtr SimplifyLogicalXor(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto size = node->ChildrenSize();
+ ui32 same = 0U, justs = 0U, negations = 0U, literals = 0U, bools = 0U;
+ for (ui32 i = 0U; i < size; ++i) {
+ const auto child = node->Child(i);
+ if (child->IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing";
+ return node->ChildPtr(i);
+ }
+ if (child->IsCallable(node->Content()))
+ ++same;
+ if (child->IsCallable("Not"))
+ ++negations;
+ if (child->IsCallable("Just"))
+ ++justs;
+ if (child->IsCallable("Bool"))
+ ++literals;
+ if (IsBoolType(*child))
+ ++bools;
+ };
+
+ if (same) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Content();
+ TExprNode::TListType children;
+ children.reserve(size);
+ node->ForEachChild([&](TExprNode& child) {
+ if (child.IsCallable(node->Content())) {
+ child.ForEachChild([&](TExprNode& sub) {
+ children.emplace_back(&sub);
+ });
+ } else {
+ children.emplace_back(&child);
+ }
+ });
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (justs && size == justs + bools) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Just";
+ TExprNode::TListType children;
+ children.reserve(size);
+ node->ForEachChild([&](TExprNode& child) {
+ children.emplace_back(child.IsCallable("Just") ? child.HeadPtr() : &child);
+ });
+ return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChildren(*node, std::move(children))});
+ }
+
+ if (literals || negations) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over negations or literal bools";
+ TExprNode::TListType children;
+ children.reserve(size);
+ bool inverse = false;
+ node->ForEachChild([&](TExprNode& child) {
+ if (child.IsCallable("Not")) {
+ children.emplace_back(child.HeadPtr());
+ inverse = !inverse;
+ } else if (child.IsCallable("Bool")) {
+ if (FromString<bool>(child.Head().Content())) {
+ inverse = !inverse;
+ }
+ } else {
+ children.emplace_back(&child);
+ }
+ });
+
+ return children.empty() ?
+ ctx.WrapByCallableIf(IsOptBoolType(*node), "Just", MakeBool(node->Pos(), inverse, ctx)):
+ ctx.WrapByCallableIf(inverse, "Not", ctx.ChangeChildren(*node, std::move(children)));
+ }
+
+ return node;
+};
+
+TExprNode::TPtr SimplifyLogicalNot(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->HeadPtr();
+ }
+
+ if (node->Head().IsCallable("Not")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
+
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ctx.ChangeChild(*node, 0U, node->Head().HeadPtr()));
+ }
+
+ if (node->Head().IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ const auto value = FromString<bool>(node->Head().Head().Content());
+ return MakeBool(node->Pos(), !value, ctx);
+ }
+
+ return node;
+}
+
+template <bool Equal>
+TExprNode::TPtr OptimizeEquality(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing") || node->Tail().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' over Nothing";
+ return MakeBoolNothing(node->Pos(), ctx);
+ }
+
if (node->Head().IsCallable("Just")) {
TCoJust just(node->HeadPtr());
if (IsDataType(just.Input().Ref())) {
@@ -1036,8 +1036,8 @@ TExprNode::TPtr OptimizeEquality(const TExprNode::TPtr& node, TExprContext& ctx)
auto ret = ctx.ChangeChild(*node, 0U, just.Input().Ptr());
return ctx.WrapByCallableIf(IsDataType(node->Tail()), "Just", std::move(ret));
}
- }
-
+ }
+
if (node->Tail().IsCallable("Just")) {
TCoJust just(node->TailPtr());
if (IsDataType(just.Input().Ref())) {
@@ -1045,76 +1045,76 @@ TExprNode::TPtr OptimizeEquality(const TExprNode::TPtr& node, TExprContext& ctx)
auto ret = ctx.ChangeChild(*node, 1U, just.Input().Ptr());
return ctx.WrapByCallableIf(IsDataType(node->Head()), "Just", std::move(ret));
}
- }
-
- if (IsBoolType(*node) || IsOptBoolType(*node)) {
- if (node->Head().IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' with " << node->Head().Content() << " '" << node->Head().Head().Content();
- const auto value = FromString<bool>(node->Head().Head().Content());
- return ctx.WrapByCallableIf(Equal != value, "Not", node->TailPtr());
- }
-
- if (node->Tail().IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
- const auto value = FromString<bool>(node->Tail().Head().Content());
- return ctx.WrapByCallableIf(Equal != value, "Not", node->HeadPtr());
- }
- }
-
- return node;
-}
-
-template <bool IsList, bool IsLookup = false>
-TExprNode::TPtr OptimizeContains(const TExprNode::TPtr& node, TExprContext& ctx) {
- static_assert(!IsList || !IsLookup, "List or Lookup");
+ }
+
+ if (IsBoolType(*node) || IsOptBoolType(*node)) {
+ if (node->Head().IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' with " << node->Head().Content() << " '" << node->Head().Head().Content();
+ const auto value = FromString<bool>(node->Head().Head().Content());
+ return ctx.WrapByCallableIf(Equal != value, "Not", node->TailPtr());
+ }
+
+ if (node->Tail().IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
+ const auto value = FromString<bool>(node->Tail().Head().Content());
+ return ctx.WrapByCallableIf(Equal != value, "Not", node->HeadPtr());
+ }
+ }
+
+ return node;
+}
+
+template <bool IsList, bool IsLookup = false>
+TExprNode::TPtr OptimizeContains(const TExprNode::TPtr& node, TExprContext& ctx) {
+ static_assert(!IsList || !IsLookup, "List or Lookup");
if constexpr (!(IsLookup || IsList)) {
if (IsDataOrOptionalOfData(node->Head().GetTypeAnn())) {
return OptimizeEquality<true>(node, ctx);
}
}
- if (const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables); nodeToCheck.IsCallable(IsList ? "AsList" : "AsDict")) {
- for (ui32 i = 0U; i < nodeToCheck.ChildrenSize(); ++i) {
- if ((IsList ? nodeToCheck.Child(i) : &nodeToCheck.Child(i)->Head()) == &node->Tail()) {
- YQL_CLOG(DEBUG, Core) << "Instant " << node->Content() << " in " << nodeToCheck.Content();
- return IsLookup ?
- ctx.NewCallable(node->Pos(), "Just", {nodeToCheck.Child(i)->TailPtr()}):
- MakeBool<true>(node->Pos(), ctx);
- }
- }
- } else if (nodeToCheck.IsCallable(IsList ? "List" : "Dict")) {
- if (1U == nodeToCheck.ChildrenSize()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << nodeToCheck.Content();
- return IsLookup ?
- ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)}):
- MakeBool<false>(node->Pos(), ctx);
- }
-
- for (ui32 i = 1U; i < nodeToCheck.ChildrenSize(); ++i) {
- if ((IsList ? nodeToCheck.Child(i) : &nodeToCheck.Child(i)->Head()) == &node->Tail()) {
- YQL_CLOG(DEBUG, Core) << "Instant " << node->Content() << " in " << nodeToCheck.Content();
- return IsLookup ?
- ctx.NewCallable(node->Pos(), "Just", {nodeToCheck.Child(i)->TailPtr()}):
- MakeBool<true>(node->Pos(), ctx);
- }
- }
- }
- return node;
-}
-
-TExprNode::TPtr OptimizeDictItems(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Dict")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << node->Head().Content();
- return ctx.NewCallable(node->Head().Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
- return node;
-}
-
-template <bool IsList>
-TExprNode::TPtr OptimizeContainerIf(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
- const auto value = FromString<bool>(node->Head().Head().Content());
+ if (const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables); nodeToCheck.IsCallable(IsList ? "AsList" : "AsDict")) {
+ for (ui32 i = 0U; i < nodeToCheck.ChildrenSize(); ++i) {
+ if ((IsList ? nodeToCheck.Child(i) : &nodeToCheck.Child(i)->Head()) == &node->Tail()) {
+ YQL_CLOG(DEBUG, Core) << "Instant " << node->Content() << " in " << nodeToCheck.Content();
+ return IsLookup ?
+ ctx.NewCallable(node->Pos(), "Just", {nodeToCheck.Child(i)->TailPtr()}):
+ MakeBool<true>(node->Pos(), ctx);
+ }
+ }
+ } else if (nodeToCheck.IsCallable(IsList ? "List" : "Dict")) {
+ if (1U == nodeToCheck.ChildrenSize()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << nodeToCheck.Content();
+ return IsLookup ?
+ ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)}):
+ MakeBool<false>(node->Pos(), ctx);
+ }
+
+ for (ui32 i = 1U; i < nodeToCheck.ChildrenSize(); ++i) {
+ if ((IsList ? nodeToCheck.Child(i) : &nodeToCheck.Child(i)->Head()) == &node->Tail()) {
+ YQL_CLOG(DEBUG, Core) << "Instant " << node->Content() << " in " << nodeToCheck.Content();
+ return IsLookup ?
+ ctx.NewCallable(node->Pos(), "Just", {nodeToCheck.Child(i)->TailPtr()}):
+ MakeBool<true>(node->Pos(), ctx);
+ }
+ }
+ }
+ return node;
+}
+
+TExprNode::TPtr OptimizeDictItems(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Dict")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << node->Head().Content();
+ return ctx.NewCallable(node->Head().Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+ return node;
+}
+
+template <bool IsList>
+TExprNode::TPtr OptimizeContainerIf(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ const auto value = FromString<bool>(node->Head().Head().Content());
auto res = value
? ctx.NewCallable(node->Tail().Pos(), IsList ? "AsList" : "Just", {node->TailPtr()})
: //TODO: ctx.NewCallable(node->Head().Pos(), IsList ? "List" : "Nothing", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)})
@@ -1132,24 +1132,24 @@ TExprNode::TPtr OptimizeContainerIf(const TExprNode::TPtr& node, TExprContext& c
return res;
}
- return node;
-}
-
-template <bool IsList>
-TExprNode::TPtr OptimizeFlatContainerIf(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (IsPredicateFlatMap(node->Tail())) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " with " << node->Tail().Content() << " '" << node->Head().Head().Content();
- return ctx.Builder(node->Pos())
- .Callable(node->Tail().Content())
- .Callable(0, "And")
- .Add(0, node->HeadPtr())
- .Add(1, node->Tail().HeadPtr())
- .Seal()
- .Add(1, node->Tail().TailPtr())
- .Seal().Build();
- }
-
- const auto& nodeToCheck = SkipCallables(node->Tail(), SkippableCallables);
+ return node;
+}
+
+template <bool IsList>
+TExprNode::TPtr OptimizeFlatContainerIf(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (IsPredicateFlatMap(node->Tail())) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " with " << node->Tail().Content() << " '" << node->Head().Head().Content();
+ return ctx.Builder(node->Pos())
+ .Callable(node->Tail().Content())
+ .Callable(0, "And")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->Tail().HeadPtr())
+ .Seal()
+ .Add(1, node->Tail().TailPtr())
+ .Seal().Build();
+ }
+
+ const auto& nodeToCheck = SkipCallables(node->Tail(), SkippableCallables);
if (1U == nodeToCheck.ChildrenSize() && nodeToCheck.IsCallable(IsList ? "AsList" : "Just")) {
YQL_CLOG(DEBUG, Core) << node->Content() << " with " << nodeToCheck.Content();
auto res = ctx.NewCallable(node->Pos(), IsList ? "ListIf" : "OptionalIf", {node->HeadPtr(), nodeToCheck.HeadPtr()});
@@ -1157,81 +1157,81 @@ TExprNode::TPtr OptimizeFlatContainerIf(const TExprNode::TPtr& node, TExprContex
res = KeepSortedConstraint(res, node->GetConstraint<TSortedConstraintNode>(), ctx);
}
return res;
- }
-
+ }
+
if (1U == nodeToCheck.ChildrenSize() && nodeToCheck.IsCallable(IsList ? "List" : "Nothing")) {
YQL_CLOG(DEBUG, Core) << node->Content() << " with " << nodeToCheck.Content();
auto res = node->TailPtr();
- }
-
- if (node->Head().IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
- const auto value = FromString<bool>(node->Head().Head().Content());
+ }
+
+ if (node->Head().IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ const auto value = FromString<bool>(node->Head().Head().Content());
return value
? node->TailPtr()
: KeepConstraints(
ctx.NewCallable(node->Head().Pos(), IsList ? "List" : "Nothing", {ExpandType(node->Tail().Pos(), *node->GetTypeAnn(), ctx)}),
*node,
ctx);
- }
-
- return node;
+ }
+
+ return node;
}
-template <bool HeadOrTail>
-TExprNode::TPtr OptimizeToOptional(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("ToList")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
- }
+template <bool HeadOrTail>
+TExprNode::TPtr OptimizeToOptional(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("ToList")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
if (nodeToCheck.IsCallable("AsList")) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over " << nodeToCheck.Content();
return ctx.NewCallable(node->Head().Pos(), "Just", {HeadOrTail ? nodeToCheck.HeadPtr() : nodeToCheck.TailPtr()});
}
- if (1U == nodeToCheck.ChildrenSize() && nodeToCheck.IsCallable("List")) {
+ if (1U == nodeToCheck.ChildrenSize() && nodeToCheck.IsCallable("List")) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << nodeToCheck.Content();
- return ctx.NewCallable(node->Head().Pos(), "Nothing", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
-
- return node;
+ return ctx.NewCallable(node->Head().Pos(), "Nothing", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+
+ return node;
}
-TExprNode::TPtr ExtractMember(const TExprNode& node) {
- auto memberName = node.Tail().Content();
- for (ui32 index = 0; index < node.Head().ChildrenSize(); ++index) {
- auto tuple = node.Head().Child(index);
- if (tuple->Head().Content() == memberName) {
- return tuple->TailPtr();
- }
+TExprNode::TPtr ExtractMember(const TExprNode& node) {
+ auto memberName = node.Tail().Content();
+ for (ui32 index = 0; index < node.Head().ChildrenSize(); ++index) {
+ auto tuple = node.Head().Child(index);
+ if (tuple->Head().Content() == memberName) {
+ return tuple->TailPtr();
+ }
}
- YQL_ENSURE(false, "Unexpected member name: " << memberName);
+ YQL_ENSURE(false, "Unexpected member name: " << memberName);
+}
+
+template <bool RightOrLeft>
+TExprNode::TPtr OptimizeDirection(const TExprNode::TPtr& node) {
+ if (node->Head().IsCallable(ConsName)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return RightOrLeft ? node->Head().TailPtr() : node->Head().HeadPtr();
+ }
+ return node;
}
-template <bool RightOrLeft>
-TExprNode::TPtr OptimizeDirection(const TExprNode::TPtr& node) {
- if (node->Head().IsCallable(ConsName)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return RightOrLeft ? node->Head().TailPtr() : node->Head().HeadPtr();
- }
- return node;
-}
-
TExprNode::TPtr OptimizeAsStruct(const TExprNode::TPtr& node, TExprContext& ctx) {
TExprNode::TPtr singleFrom;
- for (const auto& member : node->Children()) {
+ for (const auto& member : node->Children()) {
if (!member->Child(1)->IsCallable("Member")) {
return node;
}
- if (member->Head().Content() != member->Child(1)->Child(1)->Content()) {
+ if (member->Head().Content() != member->Child(1)->Child(1)->Content()) {
return node;
}
- auto from = member->Child(1)->HeadPtr();
+ auto from = member->Child(1)->HeadPtr();
if (!singleFrom) {
if (from->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Struct) {
return node;
@@ -1290,11 +1290,11 @@ TExprNode::TPtr OptimizeAsStruct(const TExprNode::TPtr& node, TExprContext& ctx)
return node;
}
-TExprNode::TPtr RemoveToStringFromString(const TExprNode::TPtr& node) {
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Data &&
- node->Head().GetTypeAnn()->Cast<TDataExprType>()->GetSlot() == EDataSlot::String) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->HeadPtr();
+TExprNode::TPtr RemoveToStringFromString(const TExprNode::TPtr& node) {
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Data &&
+ node->Head().GetTypeAnn()->Cast<TDataExprType>()->GetSlot() == EDataSlot::String) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->HeadPtr();
}
return node;
@@ -1323,21 +1323,21 @@ TExprNode::TPtr ConvertMapToFlatmap(TMapType map, TExprContext& ctx) {
template <typename TFilterType, typename TFlatMapType>
TExprNode::TPtr ConvertFilterToFlatmap(TFilterType filter, TExprContext& ctx, TOptimizeContext& optCtx) {
- const auto& list = filter.Input();
- const auto& lambda = filter.Lambda();
-
- if (const auto& limit = filter.Limit()) {
- const auto ret = Build<TCoTake>(ctx, filter.Pos())
- .template Input<TFilterType>()
- .Input(list)
- .Lambda(lambda)
- .Build()
- .Count(limit.Cast())
- .Done();
- return ret.Ptr();
- }
-
- const auto ret = Build<TFlatMapType>(ctx, filter.Pos())
+ const auto& list = filter.Input();
+ const auto& lambda = filter.Lambda();
+
+ if (const auto& limit = filter.Limit()) {
+ const auto ret = Build<TCoTake>(ctx, filter.Pos())
+ .template Input<TFilterType>()
+ .Input(list)
+ .Lambda(lambda)
+ .Build()
+ .Count(limit.Cast())
+ .Done();
+ return ret.Ptr();
+ }
+
+ const auto ret = Build<TFlatMapType>(ctx, filter.Pos())
.Input(list)
.Lambda()
.Args({ "item" })
@@ -1354,33 +1354,33 @@ TExprNode::TPtr ConvertFilterToFlatmap(TFilterType filter, TExprContext& ctx, TO
}
TExprNode::TPtr ExtractPredicateFromFlatmapOverListIf(const TExprNode& node, TExprContext& ctx) {
- const bool isOptional = node.Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
- const bool needWrap = !isOptional && node.Tail().GetTypeAnn()->GetKind() != ETypeAnnotationKind::List;
+ const bool isOptional = node.Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
+ const bool needWrap = !isOptional && node.Tail().GetTypeAnn()->GetKind() != ETypeAnnotationKind::List;
- auto item = ctx.ReplaceNode(node.Tail().TailPtr(), node.Tail().Head().Head(), node.Head().TailPtr());
- item = ctx.WrapByCallableIf(needWrap, "ForwardList", std::move(item));
+ auto item = ctx.ReplaceNode(node.Tail().TailPtr(), node.Tail().Head().Head(), node.Head().TailPtr());
+ item = ctx.WrapByCallableIf(needWrap, "ForwardList", std::move(item));
- auto ret = ctx.NewCallable(node.Head().Pos(), isOptional ? "FlatOptionalIf" : "FlatListIf",
- { node.Head().HeadPtr(), std::move(item) });
+ auto ret = ctx.NewCallable(node.Head().Pos(), isOptional ? "FlatOptionalIf" : "FlatListIf",
+ { node.Head().HeadPtr(), std::move(item) });
if (isOptional && node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
- ret = ctx.NewCallable(node.Head().Pos(), "ToList", { std::move(ret) });
- } else if (node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
- ret = ctx.NewCallable(node.Head().Pos(), "ToFlow", { std::move(ret) });
+ ret = ctx.NewCallable(node.Head().Pos(), "ToList", { std::move(ret) });
+ } else if (node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
+ ret = ctx.NewCallable(node.Head().Pos(), "ToFlow", { std::move(ret) });
} else if (node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
- ret = ctx.NewCallable(node.Head().Pos(), "ToStream", { std::move(ret) });
+ ret = ctx.NewCallable(node.Head().Pos(), "ToStream", { std::move(ret) });
}
return ret;
}
TExprNode::TPtr ExtractPredicateFromFlatmapOverFlatListIf(const TExprNode& node, TExprContext& ctx) {
- auto newFlatMap = ctx.ChangeChild(node, 0U, node.Head().TailPtr());
- return ctx.NewCallable(node.Head().Pos(),
- node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::List ?
- "FlatListIf" : node.Head().Content(), {
- node.Head().HeadPtr(),
- std::move(newFlatMap)
+ auto newFlatMap = ctx.ChangeChild(node, 0U, node.Head().TailPtr());
+ return ctx.NewCallable(node.Head().Pos(),
+ node.GetTypeAnn()->GetKind() == ETypeAnnotationKind::List ?
+ "FlatListIf" : node.Head().Content(), {
+ node.Head().HeadPtr(),
+ std::move(newFlatMap)
});
}
@@ -1634,7 +1634,7 @@ TPredicateChainNode ParsePredicateChainNode(const TExprNode::TPtr& predicate, co
auto curr = predicate;
TExprNode::TPtr pred;
if (curr->IsCallable("Not")) {
- curr = curr->HeadPtr();
+ curr = curr->HeadPtr();
result.Negated = true;
}
@@ -1643,11 +1643,11 @@ TPredicateChainNode ParsePredicateChainNode(const TExprNode::TPtr& predicate, co
if (curr->IsCallable("SqlIn")) {
leftArg = curr->ChildPtr(1);
} else if (curr->IsCallable("Coalesce") &&
- curr->Head().IsCallable("SqlIn") &&
+ curr->Head().IsCallable("SqlIn") &&
curr->Child(1)->IsCallable("Bool")) {
- bool coalesceVal = FromString<bool>(curr->Child(1)->Head().Content());
+ bool coalesceVal = FromString<bool>(curr->Child(1)->Head().Content());
if (coalesceVal == result.Negated) {
- curr = curr->HeadPtr();
+ curr = curr->HeadPtr();
leftArg = curr->ChildPtr(1);
}
hasCoalesce = true;
@@ -1723,7 +1723,7 @@ TPredicateChainNode ParsePredicateChainNode(const TExprNode::TPtr& predicate, co
}
auto isMemberOf = [](const TExprNode::TPtr& node, const TExprNode::TPtr& arg) {
- return node->IsCallable("Member") && node->HeadPtr() == arg;
+ return node->IsCallable("Member") && node->HeadPtr() == arg;
};
if (isMemberOf(leftArg, topLambdaArg)) {
@@ -1895,38 +1895,38 @@ TExprNode::TPtr SplitPredicateChain(TExprNode::TPtr&& node, const TExprNode::TPt
TPredicateChainNode curr = ParsePredicateChainNode(node, topLambdaArg, shouldConvertSqlInToJoin, ctx);
if (!prefix.empty() && prefix.back().ConvertibleToJoin != curr.ConvertibleToJoin) {
// stop splitting
- return std::move(node);
+ return std::move(node);
}
- prefix.emplace_back(curr);
+ prefix.emplace_back(curr);
return {};
}
- auto children = node->ChildrenList();
-
- for (auto& child : children) {
+ auto children = node->ChildrenList();
+
+ for (auto& child : children) {
child = SplitPredicateChain(std::move(child), topLambdaArg, shouldConvertSqlInToJoin, prefix, ctx);
if (child) {
- break;
- }
+ break;
+ }
}
-
- if (children.front().Get() == &node->Head()) {
- return std::move(node);
+
+ if (children.front().Get() == &node->Head()) {
+ return std::move(node);
}
- children.erase(std::remove_if(children.begin(), children.end(), std::logical_not<TExprNode::TPtr>()), children.end());
+ children.erase(std::remove_if(children.begin(), children.end(), std::logical_not<TExprNode::TPtr>()), children.end());
- if (children.empty()) {
- return {};
+ if (children.empty()) {
+ return {};
}
- return 1U == children.size() ? std::move(children.front()) : ctx.ChangeChildren(*node, std::move(children));
+ return 1U == children.size() ? std::move(children.front()) : ctx.ChangeChildren(*node, std::move(children));
}
TExprNode::TPtr RebuildFlatmapOverPartOfPredicate(const TExprNode::TPtr& origFlatMap, const TExprNode::TPtr& input,
const TExprNode::TPtr& pred, bool isOuter, TExprContext& ctx)
{
- auto origLambdaArgs = origFlatMap->Child(1)->HeadPtr();
+ auto origLambdaArgs = origFlatMap->Child(1)->HeadPtr();
TCoConditionalValueBase origConditional(origFlatMap->Child(1)->TailPtr());
auto newLambdaBody = isOuter ?
ctx.ChangeChild(origConditional.Ref(), TCoConditionalValueBase::idx_Predicate, TExprNode::TPtr(pred)) :
@@ -1951,9 +1951,9 @@ TExprNode::TPtr RebuildFlatmapOverPartOfPredicate(const TExprNode::TPtr& origFla
TExprNode::TPtr BuildEquiJoinForSqlInChain(const TExprNode::TPtr& flatMapNode, const TPredicateChain& chain, TExprContext& ctx) {
YQL_ENSURE(!chain.empty());
- auto input = flatMapNode->HeadPtr();
+ auto input = flatMapNode->HeadPtr();
bool isOrdered = flatMapNode->IsCallable({"OrderedFlatMap", "OrderedFlatMapToEquiJoin"});
- auto origLambdaArgs = flatMapNode->Child(1)->HeadPtr();
+ auto origLambdaArgs = flatMapNode->Child(1)->HeadPtr();
// placeholder for input table
TExprNode::TListType equiJoinArgs(1);
@@ -2025,7 +2025,7 @@ TExprNode::TPtr BuildEquiJoinForSqlInChain(const TExprNode::TPtr& flatMapNode, c
addMemberChain = ctx.Builder(chain[i].SqlInPos)
.Callable("AddMember")
- .Add(0, addMemberChain ? addMemberChain : origLambdaArgs->HeadPtr())
+ .Add(0, addMemberChain ? addMemberChain : origLambdaArgs->HeadPtr())
.Atom(1, columnName)
.Add(2, chain[i].Left)
.Seal()
@@ -2080,68 +2080,68 @@ TExprNode::TPtr BuildEquiJoinForSqlInChain(const TExprNode::TPtr& flatMapNode, c
return ctx.NewCallable(input->Pos(), "EquiJoin", std::move(equiJoinArgs));
}
-TStringBuf GetEmptyCollectionName(ETypeAnnotationKind kind) {
- switch (kind) {
- case ETypeAnnotationKind::Flow:
- case ETypeAnnotationKind::Stream: return "EmptyIterator";
- case ETypeAnnotationKind::List: return "List";
- case ETypeAnnotationKind::Optional: return "Nothing";
- case ETypeAnnotationKind::Dict: return "Dict";
- default: break;
- }
- return {};
-}
-
-TStringBuf GetEmptyCollectionName(const TTypeAnnotationNode* type) {
- return GetEmptyCollectionName(type->GetKind());
-}
-
-template <bool Ordered>
+TStringBuf GetEmptyCollectionName(ETypeAnnotationKind kind) {
+ switch (kind) {
+ case ETypeAnnotationKind::Flow:
+ case ETypeAnnotationKind::Stream: return "EmptyIterator";
+ case ETypeAnnotationKind::List: return "List";
+ case ETypeAnnotationKind::Optional: return "Nothing";
+ case ETypeAnnotationKind::Dict: return "Dict";
+ default: break;
+ }
+ return {};
+}
+
+TStringBuf GetEmptyCollectionName(const TTypeAnnotationNode* type) {
+ return GetEmptyCollectionName(type->GetKind());
+}
+
+template <bool Ordered>
TExprNode::TPtr SimpleFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
const TCoFlatMapBase self(node);
const auto& lambdaBody = self.Lambda().Body().Ref();
const auto& lambdaArg = self.Lambda().Args().Arg(0).Ref();
- if (!Ordered && IsListReorder(node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ if (!Ordered && IsListReorder(node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
}
- if (node->Head().IsCallable({"ListIf", "OptionalIf"})) {
- YQL_CLOG(DEBUG, Core) << "Extract predicate from " << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable({"ListIf", "OptionalIf"})) {
+ YQL_CLOG(DEBUG, Core) << "Extract predicate from " << node->Content() << " over " << node->Head().Content();
return ExtractPredicateFromFlatmapOverListIf(*node, ctx);
}
- if (node->Head().IsCallable({"FlatListIf", "FlatOptionalIf"})) {
- YQL_CLOG(DEBUG, Core) << "Extract predicate from " << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable({"FlatListIf", "FlatOptionalIf"})) {
+ YQL_CLOG(DEBUG, Core) << "Extract predicate from " << node->Content() << " over " << node->Head().Content();
return ExtractPredicateFromFlatmapOverFlatListIf(*node, ctx);
}
- if (node->Head().IsCallable({"ToStream", "ToFlow"}) && IsJustOrSingleAsList(node->Head().Head()) && !lambdaArg.IsUsedInDependsOn()) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content() << " over " << node->Head().Head().Content();
- return ctx.SwapWithHead(*node);
+ if (node->Head().IsCallable({"ToStream", "ToFlow"}) && IsJustOrSingleAsList(node->Head().Head()) && !lambdaArg.IsUsedInDependsOn()) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content() << " over " << node->Head().Head().Content();
+ return ctx.SwapWithHead(*node);
}
- if (IsJustOrSingleAsList(node->Head()) && !lambdaArg.IsUsedInDependsOn()) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ if (IsJustOrSingleAsList(node->Head()) && !lambdaArg.IsUsedInDependsOn()) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
return FuseJustOrSingleAsListWithFlatmap(node, ctx);
- }
-
- if (node->Head().IsCallable("ToList")) {
- YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
+ }
+
+ if (node->Head().IsCallable("ToList")) {
+ YQL_CLOG(DEBUG, Core) << "Fuse " << node->Content() << " over " << node->Head().Content();
return FuseToListWithFlatmap(node, ctx);
}
- if (node->Head().IsCallable("FromFlow")) {
- if (ETypeAnnotationKind::Stream == node->GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
- return ctx.SwapWithHead(*node);
- } else {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- }
- }
-
+ if (node->Head().IsCallable("FromFlow")) {
+ if (ETypeAnnotationKind::Stream == node->GetTypeAnn()->GetKind()) {
+ YQL_CLOG(DEBUG, Core) << "Swap " << node->Content() << " with " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
+ } else {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ }
+ }
+
if (lambdaBody.IsCallable("AsList") && lambdaBody.ChildrenSize() == 1 &&
node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional)
{
@@ -2207,14 +2207,14 @@ TExprNode::TPtr SimpleFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TO
}
if (CanRewriteToEmptyContainer(*node)) {
- const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables);
+ const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables);
if (IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
YQL_CLOG(DEBUG, Core) << "Empty " << node->Content() << " over " << inputToCheck.Content();
auto res = ctx.NewCallable(inputToCheck.Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
return KeepConstraints(res, *node, ctx);
}
- const auto& lambdaRootToCheck = SkipCallables(node->Tail().Tail(), SkippableCallables);
+ const auto& lambdaRootToCheck = SkipCallables(node->Tail().Tail(), SkippableCallables);
if (IsEmptyContainer(lambdaRootToCheck) || IsEmpty(lambdaRootToCheck, *optCtx.Types)) {
YQL_CLOG(DEBUG, Core) << "Empty " << node->Content() << " with " << lambdaRootToCheck.Content();
auto res = ctx.NewCallable(lambdaRootToCheck.Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
@@ -2223,9 +2223,9 @@ TExprNode::TPtr SimpleFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TO
}
// rewrite in 'canonical' way (prefer OptionalIf to ListIf)
- if (self.Input().Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && self.Lambda().Body().Maybe<TCoListIf>())
+ if (self.Input().Ref().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && self.Lambda().Body().Maybe<TCoListIf>())
{
- YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " lambda ListIf to OptionalIf";
+ YQL_CLOG(DEBUG, Core) << "Convert " << node->Content() << " lambda ListIf to OptionalIf";
auto listIf = self.Lambda().Body().Cast<TCoListIf>();
auto newLambda = Build<TCoLambda>(ctx, node->Pos())
@@ -2240,9 +2240,9 @@ TExprNode::TPtr SimpleFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TO
.With(self.Lambda().Args().Arg(0), "item")
.Build()
.Build()
- .Done().Ptr();
+ .Done().Ptr();
- return ctx.ChangeChild(*node, 1U, std::move(newLambda));
+ return ctx.ChangeChild(*node, 1U, std::move(newLambda));
}
if (auto expr = TryConvertSqlInPredicatesToJoins(self, ShouldConvertSqlInToJoin, ctx)) {
@@ -2296,7 +2296,7 @@ TExprNode::TPtr SimpleFlatMap(const TExprNode::TPtr& node, TExprContext& ctx, TO
}
TExprNode::TPtr HasNullOverTuple(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto value = node->HeadPtr();
+ auto value = node->HeadPtr();
TExprNode::TListType predicates;
for (auto i : xrange(value->GetTypeAnn()->Cast<TTupleExprType>()->GetSize())) {
@@ -2304,21 +2304,21 @@ TExprNode::TPtr HasNullOverTuple(const TExprNode::TPtr& node, TExprContext& ctx)
.Callable("HasNull")
.Callable(0, "Nth")
.Add(0, value)
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Seal()
.Seal()
.Build());
}
if (predicates.empty()) {
- return MakeBool<false>(node->Pos(), ctx);
+ return MakeBool<false>(node->Pos(), ctx);
}
- return ctx.NewCallable(node->Pos(), "Or", std::move(predicates));
+ return ctx.NewCallable(node->Pos(), "Or", std::move(predicates));
}
TExprNode::TPtr HasNullOverStruct(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto value = node->HeadPtr();
+ auto value = node->HeadPtr();
TExprNode::TListType predicates;
for (auto& item : value->GetTypeAnn()->Cast<TStructExprType>()->GetItems()) {
@@ -2333,14 +2333,14 @@ TExprNode::TPtr HasNullOverStruct(const TExprNode::TPtr& node, TExprContext& ctx
}
if (predicates.empty()) {
- return MakeBool<false>(node->Pos(), ctx);
+ return MakeBool<false>(node->Pos(), ctx);
}
- return ctx.NewCallable(node->Pos(), "Or", std::move(predicates));
+ return ctx.NewCallable(node->Pos(), "Or", std::move(predicates));
}
TExprNode::TPtr HasNullOverVariant(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto value = node->HeadPtr();
+ auto value = node->HeadPtr();
auto underlyingType = value->GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
@@ -2376,96 +2376,96 @@ TExprNode::TPtr HasNullOverVariant(const TExprNode::TPtr& node, TExprContext& ct
}
-TExprNode::TPtr OptimizeToFlow(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
-
- if (node->Head().IsCallable({"ForwardList", "LazyList", "ToStream"})) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChildren(*node, node->Head().ChildrenList());
- }
-
- if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Iterator") && ETypeAnnotationKind::List == node->Head().Head().GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChildren(*node, node->Head().ChildrenList());
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeCollect(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable({"ForwardList", "LazyList"})) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChildren(*node, node->Head().ChildrenList());
- }
-
- if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Iterator") && ETypeAnnotationKind::List == node->Head().Head().GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
- return ctx.ChangeChildren(*node, node->Head().ChildrenList());
- }
-
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+TExprNode::TPtr OptimizeToFlow(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+
+ if (node->Head().IsCallable({"ForwardList", "LazyList", "ToStream"})) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChildren(*node, node->Head().ChildrenList());
+ }
+
+ if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Iterator") && ETypeAnnotationKind::List == node->Head().Head().GetTypeAnn()->GetKind()) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChildren(*node, node->Head().ChildrenList());
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeCollect(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable({"ForwardList", "LazyList"})) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChildren(*node, node->Head().ChildrenList());
+ }
+
+ if (1U == node->Head().ChildrenSize() && node->Head().IsCallable("Iterator") && ETypeAnnotationKind::List == node->Head().Head().GetTypeAnn()->GetKind()) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Head().Content() << " under " << node->Content();
+ return ctx.ChangeChildren(*node, node->Head().ChildrenList());
+ }
+
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
if (nodeToCheck.IsCallable({node->Content(), "List", "ListIf", "AsList"})) {
YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " over " << nodeToCheck.Content();
- return node->HeadPtr();
- }
-
- return node;
-}
-
-TExprNode::TPtr DropDuplicate(const TExprNode::TPtr& node, TExprContext&) {
- if (node->Head().IsCallable(node->Content())) {
- YQL_CLOG(DEBUG, Core) << "Drop duplicate of " << node->Content();
- return node->Head().HeadPtr();
- }
-
- return node;
-}
-
-template <bool Strong>
-TExprNode::TPtr OptimizeCast(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing") && GetOptionalLevel(node->GetTypeAnn()) <= GetOptionalLevel(node->Head().GetTypeAnn())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- if (ETypeAnnotationKind::Null == node->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()->GetKind()) {
- return ctx.NewCallable(node->Head().Pos(), "Just", {ctx.NewCallable(node->Head().Pos(), "Null", {})});
- }
-
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
- }
-
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- auto type = ExpandType(node->Pos(), *node->GetTypeAnn(), ctx);
- return ctx.ChangeChildren(*node, {node->Head().HeadPtr(), std::move(type)});
- }
-
- if (GetOptionalLevel(node->GetTypeAnn()) > GetOptionalLevel(node->Head().GetTypeAnn())) {
- const auto itemType = node->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!(NKikimr::NUdf::ECastOptions::MayFail & CastResult<Strong>(node->Head().GetTypeAnn(), itemType))) {
- YQL_CLOG(DEBUG, Core) << "Pull out Just from " << node->Content();
- auto type = ExpandType(node->Pos(), *itemType, ctx);
- return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChild(*node, 1U, std::move(type))});
- }
- }
-
- return node;
-}
-
-template <bool TakeOrSkip, bool Inclusive = false>
-TExprNode::TPtr OptimizeWhile(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& emptyCollectionName = GetEmptyCollectionName(node->GetTypeAnn());
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+ return node->HeadPtr();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr DropDuplicate(const TExprNode::TPtr& node, TExprContext&) {
+ if (node->Head().IsCallable(node->Content())) {
+ YQL_CLOG(DEBUG, Core) << "Drop duplicate of " << node->Content();
+ return node->Head().HeadPtr();
+ }
+
+ return node;
+}
+
+template <bool Strong>
+TExprNode::TPtr OptimizeCast(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing") && GetOptionalLevel(node->GetTypeAnn()) <= GetOptionalLevel(node->Head().GetTypeAnn())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (ETypeAnnotationKind::Null == node->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()->GetKind()) {
+ return ctx.NewCallable(node->Head().Pos(), "Just", {ctx.NewCallable(node->Head().Pos(), "Null", {})});
+ }
+
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ }
+
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ auto type = ExpandType(node->Pos(), *node->GetTypeAnn(), ctx);
+ return ctx.ChangeChildren(*node, {node->Head().HeadPtr(), std::move(type)});
+ }
+
+ if (GetOptionalLevel(node->GetTypeAnn()) > GetOptionalLevel(node->Head().GetTypeAnn())) {
+ const auto itemType = node->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!(NKikimr::NUdf::ECastOptions::MayFail & CastResult<Strong>(node->Head().GetTypeAnn(), itemType))) {
+ YQL_CLOG(DEBUG, Core) << "Pull out Just from " << node->Content();
+ auto type = ExpandType(node->Pos(), *itemType, ctx);
+ return ctx.NewCallable(node->Pos(), "Just", {ctx.ChangeChild(*node, 1U, std::move(type))});
+ }
+ }
+
+ return node;
+}
+
+template <bool TakeOrSkip, bool Inclusive = false>
+TExprNode::TPtr OptimizeWhile(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto& emptyCollectionName = GetEmptyCollectionName(node->GetTypeAnn());
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
if (1U == nodeToCheck.ChildrenSize() && nodeToCheck.IsCallable(emptyCollectionName)) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over empty " << nodeToCheck.Content();
- return node->HeadPtr();
- }
-
- const auto& lambdaBody = node->Tail().Tail();
- if (lambdaBody.IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with lambda " << lambdaBody.Content() << " '" << lambdaBody.Head().Content();
- const bool isAll = FromString<bool>(lambdaBody.Head().Content());
+ return node->HeadPtr();
+ }
+
+ const auto& lambdaBody = node->Tail().Tail();
+ if (lambdaBody.IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with lambda " << lambdaBody.Content() << " '" << lambdaBody.Head().Content();
+ const bool isAll = FromString<bool>(lambdaBody.Head().Content());
return TakeOrSkip == isAll
? node->HeadPtr()
: Inclusive
@@ -2479,221 +2479,221 @@ TExprNode::TPtr OptimizeWhile(const TExprNode::TPtr& node, TExprContext& ctx) {
: KeepConstraints(
ctx.NewCallable(lambdaBody.Pos(), emptyCollectionName, {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)}),
*node, ctx);
- }
- return node;
-}
-
-template <bool MinOrMax>
-TExprNode::TPtr OptimizeMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
- bool constIntsOnly = true;
- for (ui32 i = 0; i < node->ChildrenSize(); ++i) {
- if (node->Child(i)->IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->ChildPtr(i);
- }
- constIntsOnly = constIntsOnly && TMaybeNode<TCoIntegralCtor>(node->Child(i));
- }
-
- if (constIntsOnly && node->ChildrenSize() > 0) {
- auto result = (MinOrMax ? &ConstFoldNodeIntAggregate<TMinAggregate> : &ConstFoldNodeIntAggregate<TMaxAggregate>)(node, ctx);
- if (result != node) {
- YQL_CLOG(DEBUG, Core) << "Constant fold " << node->Content() << " over integrals.";
- return result;
- }
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing") || node->Tail().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' over Nothing";
- return MakeBoolNothing(node->Pos(), ctx);
- }
-
- return node;
-}
-
-TExprNode::TPtr DropReorder(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (IsListReorder(node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- }
-
- return node;
-}
-
-template <bool IsTop, bool IsSort>
+ }
+ return node;
+}
+
+template <bool MinOrMax>
+TExprNode::TPtr OptimizeMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
+ bool constIntsOnly = true;
+ for (ui32 i = 0; i < node->ChildrenSize(); ++i) {
+ if (node->Child(i)->IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->ChildPtr(i);
+ }
+ constIntsOnly = constIntsOnly && TMaybeNode<TCoIntegralCtor>(node->Child(i));
+ }
+
+ if (constIntsOnly && node->ChildrenSize() > 0) {
+ auto result = (MinOrMax ? &ConstFoldNodeIntAggregate<TMinAggregate> : &ConstFoldNodeIntAggregate<TMaxAggregate>)(node, ctx);
+ if (result != node) {
+ YQL_CLOG(DEBUG, Core) << "Constant fold " << node->Content() << " over integrals.";
+ return result;
+ }
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing") || node->Tail().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << "Compare '" << node->Content() << "' over Nothing";
+ return MakeBoolNothing(node->Pos(), ctx);
+ }
+
+ return node;
+}
+
+TExprNode::TPtr DropReorder(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (IsListReorder(node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ }
+
+ return node;
+}
+
+template <bool IsTop, bool IsSort>
TExprNode::TPtr OptimizeReorder(const TExprNode::TPtr& node, TExprContext& ctx) {
- const ui32 ascIndex = node->ChildrenSize() - 2U;
- if ((IsSort || IsTop) && 1U == node->Head().ChildrenSize() && node->Head().IsCallable(GetEmptyCollectionName(node->Head().GetTypeAnn()))) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return IsSort ?
- ctx.Builder(node->Pos())
- .Callable("AssumeSorted")
- .Add(0, node->HeadPtr())
- .Add(1, node->ChildPtr(ascIndex))
- .Add(2, node->TailPtr())
- .Seal().Build():
- node->HeadPtr();
- }
-
- if (IsSort && IsListReorder(node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- }
-
- if (const auto& lambda = node->Tail(); lambda.Tail().GetDependencyScope()->second != &lambda) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " by constant";
- return IsTop ?
- ctx.Builder(node->Pos())
- .Callable("Take")
- .Add(0, node->HeadPtr())
- .Add(1, node->ChildPtr(1))
- .Seal().Build():
- node->HeadPtr();
- }
-
- if (node->Child(ascIndex)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
- node->Child(ascIndex)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize() == 1U) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " unpack single item ascending";
- auto unpack = node->Child(ascIndex)->IsList() ?
- node->Child(ascIndex)->HeadPtr():
- ctx.Builder(node->Pos())
- .Callable("Nth")
- .Add(0, node->ChildPtr(ascIndex))
- .Atom(1, "0", TNodeFlags::Default)
- .Seal().Build();
- return ctx.ChangeChild(*node, ascIndex, {std::move(unpack)});
- }
-
- if (node->Tail().Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- const auto keyType = node->Tail().Tail().GetTypeAnn()->Cast<TTupleExprType>();
- if (1U == keyType->GetSize()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " unpack single item tuple";
- auto unpack = node->Tail().Tail().IsList() ?
- ctx.Builder(node->Tail().Pos())
- .Lambda()
- .Param("input")
- .ApplyPartial(node->Tail().HeadPtr(), node->Tail().Tail().HeadPtr())
- .With(0, "input")
- .Seal()
- .Seal().Build():
- ctx.Builder(node->Tail().Pos())
- .Lambda()
- .Param("input")
- .Callable("Nth")
- .Apply(0, node->TailPtr()).With(0, "input").Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal().Build();
- return ctx.ChangeChild(*node, node->ChildrenSize() - 1U, {std::move(unpack)});
- }
- }
-
- if (IsTop) {
- if (node->Child(1)->IsCallable("Uint64")) {
- const ui64 count = FromString<ui64>(node->Child(1)->Head().Content());
- if (0 == count) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with zero count";
- auto res = ctx.NewCallable(node->Pos(), GetEmptyCollectionName(node->Head().GetTypeAnn()), {ExpandType(node->Pos(), *node->Head().GetTypeAnn(), ctx)});
- if (IsSort) {
- res = ctx.Builder(node->Pos())
- .Callable("AssumeSorted")
- .Add(0, std::move(res))
- .Add(1, node->ChildPtr(ascIndex))
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
- return res;
- }
-
- if (node->Head().IsCallable({"List", "AsList"})) {
- size_t listSize = node->Head().ChildrenSize();
- if (node->Head().IsCallable("List")) {
- --listSize;
- }
-
- if (listSize <= count) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << listSize << " literals";
- return IsSort ?
- ctx.Builder(node->Pos())
- .Callable(listSize > 1U ? "Sort" : "AssumeSorted")
- .Add(0, node->HeadPtr())
- .Add(1, node->ChildPtr(ascIndex))
- .Add(2, node->TailPtr())
- .Seal().Build():
- node->HeadPtr();
- }
- }
- }
-
- if (auto inputConstr = node->Head().GetConstraint<TSortedConstraintNode>()) {
- if (auto topConstr = node->GetConstraint<TSortedConstraintNode>()) {
- if (topConstr->IsPrefixOf(*inputConstr)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over sorted input";
-
- auto res = ctx.Builder(node->Pos())
- .Callable("Take")
- .Add(0, node->HeadPtr())
- .Add(1, node->ChildPtr(1))
- .Seal()
- .Build();
-
+ const ui32 ascIndex = node->ChildrenSize() - 2U;
+ if ((IsSort || IsTop) && 1U == node->Head().ChildrenSize() && node->Head().IsCallable(GetEmptyCollectionName(node->Head().GetTypeAnn()))) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return IsSort ?
+ ctx.Builder(node->Pos())
+ .Callable("AssumeSorted")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->ChildPtr(ascIndex))
+ .Add(2, node->TailPtr())
+ .Seal().Build():
+ node->HeadPtr();
+ }
+
+ if (IsSort && IsListReorder(node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ }
+
+ if (const auto& lambda = node->Tail(); lambda.Tail().GetDependencyScope()->second != &lambda) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " by constant";
+ return IsTop ?
+ ctx.Builder(node->Pos())
+ .Callable("Take")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->ChildPtr(1))
+ .Seal().Build():
+ node->HeadPtr();
+ }
+
+ if (node->Child(ascIndex)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple &&
+ node->Child(ascIndex)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize() == 1U) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " unpack single item ascending";
+ auto unpack = node->Child(ascIndex)->IsList() ?
+ node->Child(ascIndex)->HeadPtr():
+ ctx.Builder(node->Pos())
+ .Callable("Nth")
+ .Add(0, node->ChildPtr(ascIndex))
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal().Build();
+ return ctx.ChangeChild(*node, ascIndex, {std::move(unpack)});
+ }
+
+ if (node->Tail().Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ const auto keyType = node->Tail().Tail().GetTypeAnn()->Cast<TTupleExprType>();
+ if (1U == keyType->GetSize()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " unpack single item tuple";
+ auto unpack = node->Tail().Tail().IsList() ?
+ ctx.Builder(node->Tail().Pos())
+ .Lambda()
+ .Param("input")
+ .ApplyPartial(node->Tail().HeadPtr(), node->Tail().Tail().HeadPtr())
+ .With(0, "input")
+ .Seal()
+ .Seal().Build():
+ ctx.Builder(node->Tail().Pos())
+ .Lambda()
+ .Param("input")
+ .Callable("Nth")
+ .Apply(0, node->TailPtr()).With(0, "input").Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal().Build();
+ return ctx.ChangeChild(*node, node->ChildrenSize() - 1U, {std::move(unpack)});
+ }
+ }
+
+ if (IsTop) {
+ if (node->Child(1)->IsCallable("Uint64")) {
+ const ui64 count = FromString<ui64>(node->Child(1)->Head().Content());
+ if (0 == count) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with zero count";
+ auto res = ctx.NewCallable(node->Pos(), GetEmptyCollectionName(node->Head().GetTypeAnn()), {ExpandType(node->Pos(), *node->Head().GetTypeAnn(), ctx)});
+ if (IsSort) {
+ res = ctx.Builder(node->Pos())
+ .Callable("AssumeSorted")
+ .Add(0, std::move(res))
+ .Add(1, node->ChildPtr(ascIndex))
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+ return res;
+ }
+
+ if (node->Head().IsCallable({"List", "AsList"})) {
+ size_t listSize = node->Head().ChildrenSize();
+ if (node->Head().IsCallable("List")) {
+ --listSize;
+ }
+
+ if (listSize <= count) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << listSize << " literals";
+ return IsSort ?
+ ctx.Builder(node->Pos())
+ .Callable(listSize > 1U ? "Sort" : "AssumeSorted")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->ChildPtr(ascIndex))
+ .Add(2, node->TailPtr())
+ .Seal().Build():
+ node->HeadPtr();
+ }
+ }
+ }
+
+ if (auto inputConstr = node->Head().GetConstraint<TSortedConstraintNode>()) {
+ if (auto topConstr = node->GetConstraint<TSortedConstraintNode>()) {
+ if (topConstr->IsPrefixOf(*inputConstr)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over sorted input";
+
+ auto res = ctx.Builder(node->Pos())
+ .Callable("Take")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->ChildPtr(1))
+ .Seal()
+ .Build();
+
if (topConstr->Equals(*inputConstr)) {
- return res;
- }
-
- return KeepSortedConstraint(res, topConstr, ctx);
- }
- }
- }
- }
-
- if (IsSort) {
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
- if (nodeToCheck.IsCallable({"List", "AsList"})) {
- ui32 count = nodeToCheck.ChildrenSize();
- if (nodeToCheck.IsCallable("List")) {
- --count;
- }
-
- if (count <= 1) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over 0/1 literals";
- return ctx.RenameNode(*node, "AssumeSorted");
- }
- }
-
- if (const auto inputConstr = node->Head().GetConstraint<TSortedConstraintNode>()) {
- if (const auto sortConstr = node->GetConstraint<TSortedConstraintNode>()) {
- if (sortConstr->IsPrefixOf(*inputConstr)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over sorted input";
+ return res;
+ }
+
+ return KeepSortedConstraint(res, topConstr, ctx);
+ }
+ }
+ }
+ }
+
+ if (IsSort) {
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+ if (nodeToCheck.IsCallable({"List", "AsList"})) {
+ ui32 count = nodeToCheck.ChildrenSize();
+ if (nodeToCheck.IsCallable("List")) {
+ --count;
+ }
+
+ if (count <= 1) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over 0/1 literals";
+ return ctx.RenameNode(*node, "AssumeSorted");
+ }
+ }
+
+ if (const auto inputConstr = node->Head().GetConstraint<TSortedConstraintNode>()) {
+ if (const auto sortConstr = node->GetConstraint<TSortedConstraintNode>()) {
+ if (sortConstr->IsPrefixOf(*inputConstr)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over sorted input";
return KeepSortedConstraint(node->HeadPtr(), sortConstr, ctx);
- }
- }
- }
- } else if (!IsTop) {
- if (node->Head().IsCallable(node->Content())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- }
- }
-
- return node;
-}
-
+ }
+ }
+ }
+ } else if (!IsTop) {
+ if (node->Head().IsCallable(node->Content())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ }
+ }
+
+ return node;
+}
+
void FixSortness(const TExprNode& origNode, TExprNode::TPtr& node, TExprContext& ctx) {
if (auto sorted = origNode.GetConstraint<TSortedConstraintNode>()) {
- const auto& content = sorted->GetContent();
+ const auto& content = sorted->GetContent();
node = ctx.Builder(origNode.Pos())
.Callable("Sort")
.Add(0, std::move(node))
.List(1)
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
size_t index = 0;
- for (auto c : content) {
+ for (auto c : content) {
parent.Callable(index++, "Bool")
- .Atom(0, ToString(c.second), TNodeFlags::Default)
+ .Atom(0, ToString(c.second), TNodeFlags::Default)
.Seal();
}
return parent;
@@ -2704,10 +2704,10 @@ void FixSortness(const TExprNode& origNode, TExprNode::TPtr& node, TExprContext&
.List()
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
size_t index = 0;
- for (auto c : content) {
+ for (auto c : content) {
parent.Callable(index++, "Member")
.Arg(0, "item")
- .Atom(1, c.first.front())
+ .Atom(1, c.first.front())
.Seal();
}
return parent;
@@ -2991,7 +2991,7 @@ TExprNode::TPtr TryConvertSqlInPredicatesToJoins(const TCoFlatMapBase& flatMap,
TCoConditionalValueBase conditional(lambda.Body().Ptr());
TPredicateChain chain;
- auto lambdaArg = lambda.Ptr()->Head().HeadPtr();
+ auto lambdaArg = lambda.Ptr()->Head().HeadPtr();
auto sqlInTail = SplitPredicateChain(conditional.Predicate().Ptr(), lambdaArg, shouldConvertSqlInToJoin, chain, ctx);
if (!chain.empty()) {
@@ -3038,7 +3038,7 @@ TExprNode::TPtr FoldParseAfterSerialize(const TExprNode::TPtr& node, const TStri
return node;
}
- YQL_CLOG(DEBUG, Core) << "Drop " << outerUdf.Cast().MethodName().Value() << " over " << maybePairUdf.Cast().MethodName().Value();
+ YQL_CLOG(DEBUG, Core) << "Drop " << outerUdf.Cast().MethodName().Value() << " over " << maybePairUdf.Cast().MethodName().Value();
return maybeUdfApply.Cast().Arg(1).Ptr();
};
@@ -3081,11 +3081,11 @@ TExprNode::TPtr FoldYsonParseAfterSerialize(const TExprNode::TPtr& node) {
return FoldParseAfterSerialize(node, "Yson.Parse", serializeUdfNames);
}
-TExprNode::TPtr FoldYson2ParseAfterSerialize(const TExprNode::TPtr& node) {
- static const THashSet<TStringBuf> serializeUdfNames = {"Yson2.Serialize", "Yson2.SerializeText", "Yson2.SerializePretty"};
- return FoldParseAfterSerialize(node, "Yson2.Parse", serializeUdfNames);
-}
-
+TExprNode::TPtr FoldYson2ParseAfterSerialize(const TExprNode::TPtr& node) {
+ static const THashSet<TStringBuf> serializeUdfNames = {"Yson2.Serialize", "Yson2.SerializeText", "Yson2.SerializePretty"};
+ return FoldParseAfterSerialize(node, "Yson2.Parse", serializeUdfNames);
+}
+
TExprNode::TPtr FoldJsonParseAfterSerialize(const TExprNode::TPtr& node) {
static const THashSet<TStringBuf> serializeUdfNames = {"Json2.Serialize"};
return FoldParseAfterSerialize(node, "Json2.Parse", serializeUdfNames);
@@ -3114,7 +3114,7 @@ TExprNode::TPtr FoldSeralizeAfterParse(const TExprNode::TPtr& node, const TStrin
return node;
}
- YQL_CLOG(DEBUG, Core) << "Drop " << outerUdf.Cast().MethodName().Value() << " over " << maybePairUdf.Cast().MethodName().Value();
+ YQL_CLOG(DEBUG, Core) << "Drop " << outerUdf.Cast().MethodName().Value() << " over " << maybePairUdf.Cast().MethodName().Value();
return innerInput;
}
@@ -3122,10 +3122,10 @@ TExprNode::TPtr FoldYsonSeralizeAfterParse(const TExprNode::TPtr& node) {
return FoldSeralizeAfterParse(node, "Yson.Parse", "Yson.Serialize");
}
-TExprNode::TPtr FoldYson2SeralizeAfterParse(const TExprNode::TPtr& node) {
- return FoldSeralizeAfterParse(node, "Yson2.Parse", "Yson2.Serialize");
-}
-
+TExprNode::TPtr FoldYson2SeralizeAfterParse(const TExprNode::TPtr& node) {
+ return FoldSeralizeAfterParse(node, "Yson2.Parse", "Yson2.Serialize");
+}
+
TExprNode::TPtr FoldJsonSeralizeAfterParse(const TExprNode::TPtr& node) {
return FoldSeralizeAfterParse(node, "Json2.Parse", "Json2.Serialize");
}
@@ -3241,60 +3241,60 @@ TExprNode::TPtr BuildJsonCompilePath(const TCoJsonQueryBase& jsonExpr, TExprCont
.Done().Ptr();
}
-template<bool Ordered>
-TExprNode::TPtr CanonizeMultiMap(const TExprNode::TPtr& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content() << " of width " << node->Tail().ChildrenSize() - 1U;
- return ctx.Builder(node->Pos())
- .Callable(Ordered ? "OrderedFlatMap" : "FlatMap")
- .Add(0, node->HeadPtr())
- .Add(1, ctx.DeepCopyLambda(node->Tail(), {ctx.NewCallable(node->Tail().Pos(), "AsList", GetLambdaBody(node->Tail()))}))
- .Seal().Build();
-}
-
-template<bool Not>
-TExprNode::TPtr OptimizeDistinctFrom(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto leftType = node->Head().GetTypeAnn();
- const auto rightType = node->Tail().GetTypeAnn();
- if (IsSameAnnotation(*leftType, *rightType)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with arguments of same type";
- return ctx.RenameNode(*node, Not ? "AggrEquals" : "AggrNotEquals");
- }
-
- if (CanCompare<true>(leftType, rightType) == ECompareOptions::Comparable) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with non-Optional arguments";
- return ctx.RenameNode(*node, Not ? "==" : "!=");
- }
-
- if (leftType->GetKind() == ETypeAnnotationKind::Null && rightType->GetKind() != ETypeAnnotationKind::Optional ||
- rightType->GetKind() == ETypeAnnotationKind::Null && leftType->GetKind() != ETypeAnnotationKind::Optional) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with Null and non-Optional args";
- return MakeBool<!Not>(node->Pos(), ctx);
- }
- return node;
-}
-
-template<bool ByPrefix>
-TExprNode::TPtr ExpandSelectMembers(const TExprNode::TPtr& node, TExprContext& ctx) {
- std::set<std::string_view> prefixes;
- node->Child(1)->ForEachChild([&](const TExprNode& prefixNode){ prefixes.emplace(prefixNode.Content()); });
-
- const MemberUpdaterFunc filterByPrefixFunc = [&prefixes](const std::string_view& memberName, const TTypeAnnotationNode*) {
- if constexpr (ByPrefix)
- return std::any_of(prefixes.cbegin(), prefixes.cend(), [&memberName](const std::string_view& prefix){ return memberName.starts_with(prefix); });
- else
- return prefixes.contains(memberName);
- };
- TExprNode::TListType members;
- UpdateStructMembers(ctx, node->HeadPtr(), ByPrefix ? "SelectMembers" : "FilterMembers", members, filterByPrefixFunc);
- return ctx.NewCallable(node->Pos(), "AsStruct", std::move(members));
-}
-
+template<bool Ordered>
+TExprNode::TPtr CanonizeMultiMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content() << " of width " << node->Tail().ChildrenSize() - 1U;
+ return ctx.Builder(node->Pos())
+ .Callable(Ordered ? "OrderedFlatMap" : "FlatMap")
+ .Add(0, node->HeadPtr())
+ .Add(1, ctx.DeepCopyLambda(node->Tail(), {ctx.NewCallable(node->Tail().Pos(), "AsList", GetLambdaBody(node->Tail()))}))
+ .Seal().Build();
+}
+
+template<bool Not>
+TExprNode::TPtr OptimizeDistinctFrom(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto leftType = node->Head().GetTypeAnn();
+ const auto rightType = node->Tail().GetTypeAnn();
+ if (IsSameAnnotation(*leftType, *rightType)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with arguments of same type";
+ return ctx.RenameNode(*node, Not ? "AggrEquals" : "AggrNotEquals");
+ }
+
+ if (CanCompare<true>(leftType, rightType) == ECompareOptions::Comparable) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with non-Optional arguments";
+ return ctx.RenameNode(*node, Not ? "==" : "!=");
+ }
+
+ if (leftType->GetKind() == ETypeAnnotationKind::Null && rightType->GetKind() != ETypeAnnotationKind::Optional ||
+ rightType->GetKind() == ETypeAnnotationKind::Null && leftType->GetKind() != ETypeAnnotationKind::Optional) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with Null and non-Optional args";
+ return MakeBool<!Not>(node->Pos(), ctx);
+ }
+ return node;
+}
+
+template<bool ByPrefix>
+TExprNode::TPtr ExpandSelectMembers(const TExprNode::TPtr& node, TExprContext& ctx) {
+ std::set<std::string_view> prefixes;
+ node->Child(1)->ForEachChild([&](const TExprNode& prefixNode){ prefixes.emplace(prefixNode.Content()); });
+
+ const MemberUpdaterFunc filterByPrefixFunc = [&prefixes](const std::string_view& memberName, const TTypeAnnotationNode*) {
+ if constexpr (ByPrefix)
+ return std::any_of(prefixes.cbegin(), prefixes.cend(), [&memberName](const std::string_view& prefix){ return memberName.starts_with(prefix); });
+ else
+ return prefixes.contains(memberName);
+ };
+ TExprNode::TListType members;
+ UpdateStructMembers(ctx, node->HeadPtr(), ByPrefix ? "SelectMembers" : "FilterMembers", members, filterByPrefixFunc);
+ return ctx.NewCallable(node->Pos(), "AsStruct", std::move(members));
+}
+
void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
- using namespace std::placeholders;
-
- map["SafeCast"] = std::bind(&OptimizeCast<false>, _1, _2);
- map["StrictCast"] = std::bind(&OptimizeCast<true>, _1, _2);
-
+ using namespace std::placeholders;
+
+ map["SafeCast"] = std::bind(&OptimizeCast<false>, _1, _2);
+ map["StrictCast"] = std::bind(&OptimizeCast<true>, _1, _2);
+
map["AuthTokens"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) -> TExprNode::TPtr {
YQL_CLOG(DEBUG, Core) << "AuthTokensResult";
@@ -3345,7 +3345,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
const auto urlType = ExpandType(node->Pos(), *structure->GetItems()[structure->FindItem("Url").GetRef()]->GetItemType(), ctx);
const auto pathType = ExpandType(node->Pos(), *structure->GetItems()[structure->FindItem("Path").GetRef()]->GetItemType(), ctx);
- const auto& items = optCtx.Types->UserDataStorage->GetDirectoryContent(node->Head().Content());
+ const auto& items = optCtx.Types->UserDataStorage->GetDirectoryContent(node->Head().Content());
ui32 i = 0U;
for (const auto& item : items) {
listBuilder.Callable(++i, "Struct")
@@ -3359,7 +3359,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.List(2U)
.Atom(0U, "IsFolder")
.Callable(1U, "Bool")
- .Atom(0U, item.second ? "false" : "true", TNodeFlags::Default)
+ .Atom(0U, item.second ? "false" : "true", TNodeFlags::Default)
.Seal()
.Seal()
.List(3U)
@@ -3405,27 +3405,27 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return result.Build();
};
- map["ToFlow"] = std::bind(&OptimizeToFlow, _1, _2);
-
- map["Collect"] = std::bind(&OptimizeCollect, _1, _2);
- map["LazyList"] = std::bind(&DropDuplicate, _1, _2);
-
+ map["ToFlow"] = std::bind(&OptimizeToFlow, _1, _2);
+
+ map["Collect"] = std::bind(&OptimizeCollect, _1, _2);
+ map["LazyList"] = std::bind(&DropDuplicate, _1, _2);
+
map["FlatMap"] = std::bind(&SimpleFlatMap<false>, _1, _2, _3);
map["OrderedFlatMap"] = std::bind(&SimpleFlatMap<true>, _1, _2, _3);
-
- map["MultiMap"] = std::bind(&CanonizeMultiMap<false>, _1, _2);
- map["OrderedMultiMap"] = std::bind(&CanonizeMultiMap<true>, _1, _2);
-
+
+ map["MultiMap"] = std::bind(&CanonizeMultiMap<false>, _1, _2);
+ map["OrderedMultiMap"] = std::bind(&CanonizeMultiMap<true>, _1, _2);
+
map["LMap"] = map["OrderedLMap"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (CanRewriteToEmptyContainer(*node)) {
- const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables);
+ const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables);
if (IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
YQL_CLOG(DEBUG, Core) << "Empty " << node->Content() << " over " << inputToCheck.Content();
auto res = ctx.NewCallable(inputToCheck.Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
return KeepConstraints(res, *node, ctx);
}
- const auto& lambdaRootToCheck = SkipCallables(node->Tail().Tail(), SkippableCallables);
+ const auto& lambdaRootToCheck = SkipCallables(node->Tail().Tail(), SkippableCallables);
if (IsEmptyContainer(lambdaRootToCheck) || IsEmpty(lambdaRootToCheck, *optCtx.Types)) {
YQL_CLOG(DEBUG, Core) << "Empty " << node->Content() << " with " << lambdaRootToCheck.Content();
auto res = ctx.NewCallable(lambdaRootToCheck.Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
@@ -3443,25 +3443,25 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["SkipNullMembers"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- const auto skipNullMembers = TCoSkipNullMembers(node);
- if (!skipNullMembers.Members()) {
- return node;
- }
-
- if (const auto maybeInnerSkip = skipNullMembers.Input().Maybe<TCoSkipNullMembers>()) {
- const auto innerSkip = maybeInnerSkip.Cast();
-
- if (!innerSkip.Members()) {
- return node;
- }
-
+ const auto skipNullMembers = TCoSkipNullMembers(node);
+ if (!skipNullMembers.Members()) {
+ return node;
+ }
+
+ if (const auto maybeInnerSkip = skipNullMembers.Input().Maybe<TCoSkipNullMembers>()) {
+ const auto innerSkip = maybeInnerSkip.Cast();
+
+ if (!innerSkip.Members()) {
+ return node;
+ }
+
TSet<TStringBuf> members;
- for (const auto& member : skipNullMembers.Members().Cast()) {
+ for (const auto& member : skipNullMembers.Members().Cast()) {
members.insert(member.Value());
}
- for (const auto& member : innerSkip.Members().Cast()) {
+ for (const auto& member : innerSkip.Members().Cast()) {
members.insert(member.Value());
}
@@ -3483,64 +3483,64 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["SkipNullElements"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- const auto skipNullElements = TCoSkipNullElements(node);
- if (!skipNullElements.Elements()) {
- return node;
- }
-
- if (const auto maybeInnerSkip = skipNullElements.Input().Maybe<TCoSkipNullElements>()) {
- const auto innerSkip = maybeInnerSkip.Cast();
-
- if (!innerSkip.Elements()) {
- return node;
- }
-
- TSet<TStringBuf> elements;
-
- for (const auto& element : skipNullElements.Elements().Cast()) {
- elements.emplace(element.Value());
- }
-
- for (const auto& element : innerSkip.Elements().Cast()) {
- elements.emplace(element.Value());
- }
-
- TExprNode::TListType elementsList;
- for (const auto& elementIndex : elements) {
- elementsList.emplace_back(ctx.NewAtom(innerSkip.Pos(), elementIndex));
- }
-
- YQL_CLOG(DEBUG, Core) << "FuseSkipNullElements";
- return Build<TCoSkipNullElements>(ctx, innerSkip.Pos())
- .Input(innerSkip.Input())
- .Elements()
- .Add(elementsList)
- .Build()
- .Done()
- .Ptr();
- }
-
- return node;
- };
-
+ map["SkipNullElements"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ const auto skipNullElements = TCoSkipNullElements(node);
+ if (!skipNullElements.Elements()) {
+ return node;
+ }
+
+ if (const auto maybeInnerSkip = skipNullElements.Input().Maybe<TCoSkipNullElements>()) {
+ const auto innerSkip = maybeInnerSkip.Cast();
+
+ if (!innerSkip.Elements()) {
+ return node;
+ }
+
+ TSet<TStringBuf> elements;
+
+ for (const auto& element : skipNullElements.Elements().Cast()) {
+ elements.emplace(element.Value());
+ }
+
+ for (const auto& element : innerSkip.Elements().Cast()) {
+ elements.emplace(element.Value());
+ }
+
+ TExprNode::TListType elementsList;
+ for (const auto& elementIndex : elements) {
+ elementsList.emplace_back(ctx.NewAtom(innerSkip.Pos(), elementIndex));
+ }
+
+ YQL_CLOG(DEBUG, Core) << "FuseSkipNullElements";
+ return Build<TCoSkipNullElements>(ctx, innerSkip.Pos())
+ .Input(innerSkip.Input())
+ .Elements()
+ .Add(elementsList)
+ .Build()
+ .Done()
+ .Ptr();
+ }
+
+ return node;
+ };
+
map["Filter"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
return ConvertFilterToFlatmap<TCoFilter, TCoFlatMap>(TCoFilter(node), ctx, optCtx);
};
map["OrderedFilter"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
return ConvertFilterToFlatmap<TCoOrderedFilter, TCoOrderedFlatMap>(TCoOrderedFilter(node), ctx, optCtx);
};
map["Map"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
return ConvertMapToFlatmap<TCoMap, TCoFlatMap>(TCoMap(node), ctx);
};
map["OrderedMap"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Canonize " << node->Content();
return ConvertMapToFlatmap<TCoOrderedMap, TCoOrderedFlatMap>(TCoOrderedMap(node), ctx);
};
@@ -3550,29 +3550,29 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node->HeadPtr();
}
- if (node->Head().IsCallable(node->Content())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ if (node->Head().IsCallable(node->Content())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
}
if (node->Head().IsCallable({"Nothing", "List"}) && 1U == node->Head().ChildrenSize()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
}
- if (node->Head().IsCallable({"Just", "AsList"})) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable({"Just", "AsList"})) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
TSet<TString> fields;
- node->Tail().ForEachChild([&fields](const TExprNode& child) {
- fields.emplace(child.Content());
- });
+ node->Tail().ForEachChild([&fields](const TExprNode& child) {
+ fields.emplace(child.Content());
+ });
- auto args = node->Head().ChildrenList();
- for (auto& arg : args) {
- arg = FilterByFields(node->Pos(), arg, fields, ctx, true);
+ auto args = node->Head().ChildrenList();
+ for (auto& arg : args) {
+ arg = FilterByFields(node->Pos(), arg, fields, ctx, true);
}
- return ctx.ChangeChildren(node->Head(), std::move(args));
+ return ctx.ChangeChildren(node->Head(), std::move(args));
}
if (node->Head().IsCallable("AssumeAllMembersNullableAtOnce")) {
@@ -3583,9 +3583,9 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["Lookup"] = std::bind(&OptimizeContains<false, true>, _1, _2);
+ map["Lookup"] = std::bind(&OptimizeContains<false, true>, _1, _2);
map["Contains"] = std::bind(&OptimizeContains<false>, _1, _2);
- map["ListHas"] = std::bind(&OptimizeContains<true>, _1, _2);
+ map["ListHas"] = std::bind(&OptimizeContains<true>, _1, _2);
map["SqlIn"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext&) {
auto collection = node->HeadPtr();
auto lookup = node->ChildPtr(1);
@@ -3709,22 +3709,22 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["DictItems"] = std::bind(&OptimizeDictItems, _1, _2);
- map["DictKeys"] = std::bind(&OptimizeDictItems, _1, _2);
- map["DictPayloads"] = std::bind(&OptimizeDictItems, _1, _2);
+ map["DictItems"] = std::bind(&OptimizeDictItems, _1, _2);
+ map["DictKeys"] = std::bind(&OptimizeDictItems, _1, _2);
+ map["DictPayloads"] = std::bind(&OptimizeDictItems, _1, _2);
- map["ListIf"] = std::bind(&OptimizeContainerIf<true>, _1, _2);
- map["OptionalIf"] = std::bind(&OptimizeContainerIf<false>, _1, _2);
+ map["ListIf"] = std::bind(&OptimizeContainerIf<true>, _1, _2);
+ map["OptionalIf"] = std::bind(&OptimizeContainerIf<false>, _1, _2);
- map["FlatListIf"] = std::bind(&OptimizeFlatContainerIf<true>, _1, _2);
- map["FlatOptionalIf"] = std::bind(&OptimizeFlatContainerIf<false>, _1, _2);
+ map["FlatListIf"] = std::bind(&OptimizeFlatContainerIf<true>, _1, _2);
+ map["FlatOptionalIf"] = std::bind(&OptimizeFlatContainerIf<false>, _1, _2);
map["Skip"] = [](const TExprNode::TPtr& node, TExprContext& /*ctx*/, TOptimizeContext& /*optCtx*/) {
- if (node->Tail().IsCallable("Uint64")) {
- const auto value = FromString<ui64>(node->Tail().Head().Content());
+ if (node->Tail().IsCallable("Uint64")) {
+ const auto value = FromString<ui64>(node->Tail().Head().Content());
if (!value) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
- return node->HeadPtr();
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
+ return node->HeadPtr();
}
}
@@ -3732,11 +3732,11 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Take"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- if (node->Tail().IsCallable("Uint64")) {
- const auto value = FromString<ui64>(node->Tail().Head().Content());
+ if (node->Tail().IsCallable("Uint64")) {
+ const auto value = FromString<ui64>(node->Tail().Head().Content());
if (!value) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
- auto res = ctx.NewCallable(node->Tail().Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Tail().Content() << " '" << node->Tail().Head().Content();
+ auto res = ctx.NewCallable(node->Tail().Pos(), GetEmptyCollectionName(node->GetTypeAnn()), {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
res = KeepConstraints(res, *node, ctx);
return KeepColumnOrder(res, *node, ctx, *optCtx.Types);
}
@@ -3745,20 +3745,20 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["TakeWhile"] = std::bind(&OptimizeWhile<true>, _1, _2);
- map["SkipWhile"] = std::bind(&OptimizeWhile<false>, _1, _2);
+ map["TakeWhile"] = std::bind(&OptimizeWhile<true>, _1, _2);
+ map["SkipWhile"] = std::bind(&OptimizeWhile<false>, _1, _2);
- map["TakeWhileInclusive"] = std::bind(&OptimizeWhile<true, true>, _1, _2);
- map["SkipWhileInclusive"] = std::bind(&OptimizeWhile<false, true>, _1, _2);
+ map["TakeWhileInclusive"] = std::bind(&OptimizeWhile<true, true>, _1, _2);
+ map["SkipWhileInclusive"] = std::bind(&OptimizeWhile<false, true>, _1, _2);
map[TCoExtend::CallableName()] = map[TCoOrderedExtend::CallableName()] = map[TCoMerge::CallableName()] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (node->ChildrenSize() == 1) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over one child";
- return node->HeadPtr();
+ return node->HeadPtr();
}
for (ui32 i = 0; i < node->ChildrenSize(); ++i) {
- auto& child = SkipCallables(*node->Child(i), SkippableCallables);
+ auto& child = SkipCallables(*node->Child(i), SkippableCallables);
if (IsEmptyContainer(child) || IsEmpty(child, *optCtx.Types)) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over empty list";
if (node->ChildrenSize() == 2) {
@@ -3810,31 +3810,31 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["ForwardList"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Iterator")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
+ map["ForwardList"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ if (node->Head().IsCallable("Iterator")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
+
+ if (node->Head().IsCallable("ToFlow")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.WrapByCallableIf(ETypeAnnotationKind::Stream == node->Head().Head().GetTypeAnn()->GetKind(), node->Content(), node->Head().HeadPtr());
}
- if (node->Head().IsCallable("ToFlow")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.WrapByCallableIf(ETypeAnnotationKind::Stream == node->Head().Head().GetTypeAnn()->GetKind(), node->Content(), node->Head().HeadPtr());
- }
-
return node;
};
- map["Iterator"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->ChildrenSize() == 1 && node->Head().IsCallable("ForwardList")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.WrapByCallableIf(ETypeAnnotationKind::Flow == node->Head().Head().GetTypeAnn()->GetKind(), "FromFlow", node->Head().HeadPtr());
+ map["Iterator"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ if (node->ChildrenSize() == 1 && node->Head().IsCallable("ForwardList")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.WrapByCallableIf(ETypeAnnotationKind::Flow == node->Head().Head().GetTypeAnn()->GetKind(), "FromFlow", node->Head().HeadPtr());
}
return node;
};
map["Length"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
if (nodeToCheck.IsCallable("AsList")) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over " << nodeToCheck.Content();
return ctx.NewCallable(node->Pos(), "Uint64",
@@ -3891,18 +3891,18 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["HasItems"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable({"Append", "Insert", "Prepend"})) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return MakeBool<true>(node->Pos(), ctx);
+ if (node->Head().IsCallable({"Append", "Insert", "Prepend"})) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return MakeBool<true>(node->Pos(), ctx);
}
- const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
- if (nodeToCheck.IsCallable({"AsList","AsDict"})) {
+ const auto& nodeToCheck = SkipCallables(node->Head(), SkippableCallables);
+ if (nodeToCheck.IsCallable({"AsList","AsDict"})) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over " << nodeToCheck.Content();
return MakeBool(node->Pos(), nodeToCheck.ChildrenSize() > 0U, ctx);
}
- if (nodeToCheck.IsCallable({"List","Dict"})) {
+ if (nodeToCheck.IsCallable({"List","Dict"})) {
YQL_CLOG(DEBUG, Core) << node->Content() << " over " << nodeToCheck.Content();
return MakeBool(node->Pos(), nodeToCheck.ChildrenSize() > 1U, ctx);
}
@@ -3959,29 +3959,29 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
TExprNode::TListType asStructChildren(node->ChildrenList());
if (node->ChildrenSize() > 0) {
- asStructChildren.erase(asStructChildren.cbegin());
+ asStructChildren.erase(asStructChildren.cbegin());
}
return ctx.NewCallable(node->Pos(), "AsStruct", std::move(asStructChildren));
};
map["Member"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("AsStruct")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable("AsStruct")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return ExtractMember(*node);
}
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- const auto structType = node->Head().Head().GetTypeAnn()->Cast<TStructExprType>();
- const auto memberType = structType->GetItems()[*structType->FindItem(node->Tail().Content())]->GetItemType();
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ const auto structType = node->Head().Head().GetTypeAnn()->Cast<TStructExprType>();
+ const auto memberType = structType->GetItems()[*structType->FindItem(node->Tail().Content())]->GetItemType();
return ctx.WrapByCallableIf(!memberType->IsOptionalOrNull(), "Just", std::move(ret));
}
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
}
if (node->Head().IsCallable("ExtractMembers")) {
@@ -3992,101 +3992,101 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["RemoveMember"] = std::bind(&ExpandRemoveMember, _1, _2);
- map["ForceRemoveMember"] = std::bind(&ExpandRemoveMember, _1, _2);
- map["FlattenMembers"] = std::bind(&ExpandFlattenMembers, _1, _2);
- map["FlattenStructs"] = std::bind(&ExpandFlattenStructs, _1, _2);
- map["SelectMembers"] = std::bind(&ExpandSelectMembers<true>, _1, _2);
- map["FilterMembers"] = std::bind(&ExpandSelectMembers<false>, _1, _2);
- map["DivePrefixMembers"] = std::bind(&ExpandDivePrefixMembers, _1, _2);
- map["AddMember"] = std::bind(&ExpandAddMember, _1, _2);
- map["ReplaceMember"] = std::bind(&ExpandReplaceMember, _1, _2);
+ map["RemoveMember"] = std::bind(&ExpandRemoveMember, _1, _2);
+ map["ForceRemoveMember"] = std::bind(&ExpandRemoveMember, _1, _2);
+ map["FlattenMembers"] = std::bind(&ExpandFlattenMembers, _1, _2);
+ map["FlattenStructs"] = std::bind(&ExpandFlattenStructs, _1, _2);
+ map["SelectMembers"] = std::bind(&ExpandSelectMembers<true>, _1, _2);
+ map["FilterMembers"] = std::bind(&ExpandSelectMembers<false>, _1, _2);
+ map["DivePrefixMembers"] = std::bind(&ExpandDivePrefixMembers, _1, _2);
+ map["AddMember"] = std::bind(&ExpandAddMember, _1, _2);
+ map["ReplaceMember"] = std::bind(&ExpandReplaceMember, _1, _2);
map["RemovePrefixMembers"] = std::bind(&ExpandRemovePrefixMembers, _1, _2);
- map["FlattenByColumns"] = std::bind(&ExpandFlattenByColumns, _1, _2);
+ map["FlattenByColumns"] = std::bind(&ExpandFlattenByColumns, _1, _2);
map["AsStruct"] = std::bind(&OptimizeAsStruct, _1, _2);
map["Nth"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().Type() == TExprNode::List) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over tuple literal";
- const auto index = FromString<ui32>(node->Tail().Content());
- return node->Head().ChildPtr(index);
+ if (node->Head().Type() == TExprNode::List) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over tuple literal";
+ const auto index = FromString<ui32>(node->Tail().Content());
+ return node->Head().ChildPtr(index);
}
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- const auto tupleType = node->Head().Head().GetTypeAnn()->Cast<TTupleExprType>();
- const auto elemType = tupleType->GetItems()[FromString<ui32>(node->Tail().Content())];
- return ctx.WrapByCallableIf(elemType->GetKind() != ETypeAnnotationKind::Optional, "Just", std::move(ret));
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ const auto tupleType = node->Head().Head().GetTypeAnn()->Cast<TTupleExprType>();
+ const auto elemType = tupleType->GetItems()[FromString<ui32>(node->Tail().Content())];
+ return ctx.WrapByCallableIf(elemType->GetKind() != ETypeAnnotationKind::Optional, "Just", std::move(ret));
}
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
}
return node;
};
- map["ToString"] = std::bind(&RemoveToStringFromString, _1);
+ map["ToString"] = std::bind(&RemoveToStringFromString, _1);
map["Coalesce"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return RemoveNothingFromCoalesce(*node, ctx);
}
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- if (IsSameAnnotation(*node->Head().GetTypeAnn(), *node->Child(node->ChildrenSize() - 1)->GetTypeAnn())) {
- return node->HeadPtr();
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (IsSameAnnotation(*node->Head().GetTypeAnn(), *node->Child(node->ChildrenSize() - 1)->GetTypeAnn())) {
+ return node->HeadPtr();
} else {
- return node->Head().HeadPtr();
+ return node->Head().HeadPtr();
}
}
- if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
- if (auto lambda = IsSameAnnotation(*input.GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), *node->Tail().GetTypeAnn()) ?
- ctx.DeepCopyLambda(*input.Child(1), input.Child(1)->Tail().HeadPtr()) :
- IsSameAnnotation(*input.GetTypeAnn(), *node->Tail().GetTypeAnn()) ? input.ChildPtr(1) : nullptr) {
-
- YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, input.HeadPtr())
- .Add(1, std::move(lambda))
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
- }
-
- if (node->Tail().IsCallable("Bool")) {
- return PropagateCoalesceWithConstIntoLogicalOps(node, ctx);
+ if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
+ if (auto lambda = IsSameAnnotation(*input.GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), *node->Tail().GetTypeAnn()) ?
+ ctx.DeepCopyLambda(*input.Child(1), input.Child(1)->Tail().HeadPtr()) :
+ IsSameAnnotation(*input.GetTypeAnn(), *node->Tail().GetTypeAnn()) ? input.ChildPtr(1) : nullptr) {
+
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, input.HeadPtr())
+ .Add(1, std::move(lambda))
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+ }
+
+ if (node->Tail().IsCallable("Bool")) {
+ return PropagateCoalesceWithConstIntoLogicalOps(node, ctx);
}
return node;
};
- map["Exists"] = std::bind(&OptimizeExists, _1, _2);
+ map["Exists"] = std::bind(&OptimizeExists, _1, _2);
map["Convert"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Data) {
- const auto targetType = node->GetTypeAnn()->Cast<TDataExprType>();
- if (node->Head().IsCallable("Bool") && IsDataTypeNumeric(targetType->GetSlot())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
- return ctx.NewCallable(node->Pos(), targetType->GetName(),
- {ctx.NewAtom(node->Pos(), FromString<bool>(node->Head().Head().Content()) ? "1" : "0", TNodeFlags::Default)});
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Data) {
+ const auto targetType = node->GetTypeAnn()->Cast<TDataExprType>();
+ if (node->Head().IsCallable("Bool") && IsDataTypeNumeric(targetType->GetSlot())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ return ctx.NewCallable(node->Pos(), targetType->GetName(),
+ {ctx.NewAtom(node->Pos(), FromString<bool>(node->Head().Head().Content()) ? "1" : "0", TNodeFlags::Default)});
}
- if (const auto maybeInt = TMaybeNode<TCoIntegralCtor>(&node->Head())) {
+ if (const auto maybeInt = TMaybeNode<TCoIntegralCtor>(&node->Head())) {
TString atomValue;
- if (AllowIntegralConversion(maybeInt.Cast(), false, targetType->GetSlot(), &atomValue)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
- return ctx.NewCallable(node->Pos(), targetType->GetName(),
- {ctx.NewAtom(node->Pos(), atomValue, TNodeFlags::Default)});
+ if (AllowIntegralConversion(maybeInt.Cast(), false, targetType->GetSlot(), &atomValue)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ return ctx.NewCallable(node->Pos(), targetType->GetName(),
+ {ctx.NewAtom(node->Pos(), atomValue, TNodeFlags::Default)});
}
}
}
@@ -4096,128 +4096,128 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
map[IfName] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
if (node->Child(1)->IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with literal predicate";
- const auto value = FromString<bool>(node->Child(1)->Head().Content());
- return ctx.NewCallable(node->Pos(), SyncName, { node->HeadPtr(), node->ChildPtr(value ? 2 : 3) });
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with literal predicate";
+ const auto value = FromString<bool>(node->Child(1)->Head().Content());
+ return ctx.NewCallable(node->Pos(), SyncName, { node->HeadPtr(), node->ChildPtr(value ? 2 : 3) });
}
return node;
};
map["If"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- for (auto i = 0U; i < node->ChildrenSize() - 1U; ++++i) {
- if (node->Child(i)->IsCallable("Bool")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Child(i)->Content() << " '" << node->Child(i)->Head().Content();
- auto children = node->ChildrenList();
- if (FromString<bool>(children[i]->Head().Content())) {
- const auto last = i;
- children[last] = std::move(children[++i]);
- children.resize(i);
- } else {
- auto it = children.cbegin();
- std::advance(it, i);
- children.erase(it, it + 2U);
- }
- return children.size() > 1U ? ctx.ChangeChildren(*node, std::move(children)) : children.front();
- }
- }
-
- if (const auto lastPredicateIndex = node->ChildrenSize() - 3U; node->Child(lastPredicateIndex)->IsCallable("Not")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Child(lastPredicateIndex)->Content();
- auto children = node->ChildrenList();
- children[lastPredicateIndex] = children[lastPredicateIndex]->HeadPtr();
- std::swap(children[lastPredicateIndex + 1U], children[lastPredicateIndex + 2U]);
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (3U == node->ChildrenSize() && node->Child(1)->IsCallable("Bool") && node->Child(2)->IsCallable("Bool")) {
- const auto thenValue = FromString<bool>(node->Child(1)->Head().Content());
- const auto elseValue = FromString<bool>(node->Child(2)->Head().Content());
-
- if (thenValue != elseValue) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with literals in branches";
- return ctx.WrapByCallableIf(elseValue, "Not", node->HeadPtr());
+ for (auto i = 0U; i < node->ChildrenSize() - 1U; ++++i) {
+ if (node->Child(i)->IsCallable("Bool")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Child(i)->Content() << " '" << node->Child(i)->Head().Content();
+ auto children = node->ChildrenList();
+ if (FromString<bool>(children[i]->Head().Content())) {
+ const auto last = i;
+ children[last] = std::move(children[++i]);
+ children.resize(i);
+ } else {
+ auto it = children.cbegin();
+ std::advance(it, i);
+ children.erase(it, it + 2U);
+ }
+ return children.size() > 1U ? ctx.ChangeChildren(*node, std::move(children)) : children.front();
+ }
+ }
+
+ if (const auto lastPredicateIndex = node->ChildrenSize() - 3U; node->Child(lastPredicateIndex)->IsCallable("Not")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Child(lastPredicateIndex)->Content();
+ auto children = node->ChildrenList();
+ children[lastPredicateIndex] = children[lastPredicateIndex]->HeadPtr();
+ std::swap(children[lastPredicateIndex + 1U], children[lastPredicateIndex + 2U]);
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (3U == node->ChildrenSize() && node->Child(1)->IsCallable("Bool") && node->Child(2)->IsCallable("Bool")) {
+ const auto thenValue = FromString<bool>(node->Child(1)->Head().Content());
+ const auto elseValue = FromString<bool>(node->Child(2)->Head().Content());
+
+ if (thenValue != elseValue) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with literals in branches";
+ return ctx.WrapByCallableIf(elseValue, "Not", node->HeadPtr());
}
}
return node;
};
- map["Chopper"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext&) {
- if (!IsDepended(node->Tail().Tail(), node->Tail().Head().Tail())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " where handler isn't depended on group stream";
- return ctx.Builder(node->Pos())
- .Callable("OrderedFlatMap")
- .Callable(0, "Condense1")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(*node->Child(1))
- .With(0, "item")
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("key")
- .Apply(*node->Child(2))
- .With(0, "key")
- .With(1, "item")
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("key")
- .Arg("key")
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("key")
- .Apply(node->Tail())
- .With(0, "key")
- .With(1, node->HeadPtr())
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
- };
-
- map["IfPresent"] = std::bind(&OptimizeIfPresent<true>, _1, _2);
-
- map["TryMember"] = std::bind(&OptimizeTryMember, _1, _2);
+ map["Chopper"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext&) {
+ if (!IsDepended(node->Tail().Tail(), node->Tail().Head().Tail())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " where handler isn't depended on group stream";
+ return ctx.Builder(node->Pos())
+ .Callable("OrderedFlatMap")
+ .Callable(0, "Condense1")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(*node->Child(1))
+ .With(0, "item")
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("key")
+ .Apply(*node->Child(2))
+ .With(0, "key")
+ .With(1, "item")
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("key")
+ .Arg("key")
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("key")
+ .Apply(node->Tail())
+ .With(0, "key")
+ .With(1, node->HeadPtr())
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+ };
+
+ map["IfPresent"] = std::bind(&OptimizeIfPresent<true>, _1, _2);
+
+ map["TryMember"] = std::bind(&OptimizeTryMember, _1, _2);
map["Optional"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- YQL_CLOG(DEBUG, Core) << node->Content();
- return ctx.NewCallable(node->Pos(), "Just", {node->TailPtr()});
+ YQL_CLOG(DEBUG, Core) << node->Content();
+ return ctx.NewCallable(node->Pos(), "Just", {node->TailPtr()});
};
map["List"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
if (node->ChildrenSize() > 1) {
- YQL_CLOG(DEBUG, Core) << "Non empty " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Non empty " << node->Content();
TExprNode::TListType asListChildren(node->ChildrenList());
asListChildren.erase(asListChildren.begin());
- return ctx.NewCallable(node->Pos(), "AsList", std::move(asListChildren));
+ return ctx.NewCallable(node->Pos(), "AsList", std::move(asListChildren));
}
return node;
};
- map["OptionalReduce"] = std::bind(&RemoveOptionalReduceOverData, _1, _2);
+ map["OptionalReduce"] = std::bind(&RemoveOptionalReduceOverData, _1, _2);
map["Fold"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
Y_UNUSED(ctx);
if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct) {
- const auto count = node->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize();
+ const auto count = node->Child(1)->GetTypeAnn()->Cast<TStructExprType>()->GetSize();
if (count == 0) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty struct as state";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty struct as state";
return node->ChildPtr(1); // singleton
}
}
else if (node->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- const auto count = node->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ const auto count = node->Child(1)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
if (count == 0) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty tuple as state";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty tuple as state";
return node->ChildPtr(1); // singleton
}
}
@@ -4226,14 +4226,14 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Fold1"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Child(1)->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct) {
- const auto count = node->Child(1)->Tail().GetTypeAnn()->Cast<TStructExprType>()->GetSize();
+ if (node->Child(1)->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct) {
+ const auto count = node->Child(1)->Tail().GetTypeAnn()->Cast<TStructExprType>()->GetSize();
if (count == 0) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty struct as state";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty struct as state";
return ctx.Builder(node->Pos())
.Callable("OptionalIf")
.Callable(0, "HasItems")
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Seal()
.Callable(1, "AsStruct")
.Seal()
@@ -4241,14 +4241,14 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Build();
}
}
- else if (node->Child(1)->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- const auto count = node->Child(1)->Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ else if (node->Child(1)->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ const auto count = node->Child(1)->Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
if (count == 0) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty tuple as state";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty tuple as state";
return ctx.Builder(node->Pos())
.Callable("OptionalIf")
.Callable(0, "HasItems")
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Seal()
.List(1)
.Seal()
@@ -4260,27 +4260,27 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map["GroupByKey"] = std::bind(&DropReorder, _1, _2);
- map["CombineByKey"] = std::bind(&DropReorder, _1, _2);
+ map["GroupByKey"] = std::bind(&DropReorder, _1, _2);
+ map["CombineByKey"] = std::bind(&DropReorder, _1, _2);
map["ToList"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
-
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Head().Pos(), "AsList", {node->Head().HeadPtr()});
- }
-
- if (node->Head().IsCallable({"Head", "ToOptional"})) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Pos(), "List", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Head().Pos(), "AsList", {node->Head().HeadPtr()});
+ }
+
+ if (node->Head().IsCallable({"Head", "ToOptional"})) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
auto ret = ctx.Builder(node->Pos())
.Callable("Take")
- .Add(0, node->Head().HeadPtr())
+ .Add(0, node->Head().HeadPtr())
.Callable(1, "Uint64")
- .Atom(0, "1", TNodeFlags::Default)
+ .Atom(0, "1", TNodeFlags::Default)
.Seal()
.Seal()
.Build();
@@ -4288,41 +4288,41 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return ret;
}
- if (node->Head().IsCallable("OptionalIf")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.RenameNode(node->Head(), "ListIf");
+ if (node->Head().IsCallable("OptionalIf")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.RenameNode(node->Head(), "ListIf");
}
return node;
};
- map["ToStream"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
- return node;
- };
-
- map["ToOptional"] = std::bind(OptimizeToOptional<true>, _1, _2);
- map["Head"] = std::bind(OptimizeToOptional<true>, _1, _2);
- map["Last"] = std::bind(OptimizeToOptional<false>, _1, _2);
-
- map["Not"] = std::bind(&SimplifyLogicalNot, _1, _2);
- map["And"] = std::bind(&SimplifyLogical<true>, _1, _2);
- map["Or"] = std::bind(&SimplifyLogical<false>, _1, _2);
- map["Xor"] = std::bind(&SimplifyLogicalXor, _1, _2);
-
- map["=="] = std::bind(&OptimizeEquality<true>, _1, _2);
- map["!="] = std::bind(&OptimizeEquality<false>, _1, _2);
-
- map["IsNotDistinctFrom"] = std::bind(&OptimizeDistinctFrom<true>, _1, _2);
- map["IsDistinctFrom"] = std::bind(&OptimizeDistinctFrom<false>, _1, _2);
-
- map["StartsWith"] = std::bind(&OptimizeEquality<true>, _1, _2);
- map["EndsWith"] = std::bind(&OptimizeEquality<true>, _1, _2);
-
- map["<"] = map["<="] = map[">"] = map[">="] = std::bind(&OptimizeCompare, _1, _2);;
+ map["ToStream"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+ return node;
+ };
+
+ map["ToOptional"] = std::bind(OptimizeToOptional<true>, _1, _2);
+ map["Head"] = std::bind(OptimizeToOptional<true>, _1, _2);
+ map["Last"] = std::bind(OptimizeToOptional<false>, _1, _2);
+
+ map["Not"] = std::bind(&SimplifyLogicalNot, _1, _2);
+ map["And"] = std::bind(&SimplifyLogical<true>, _1, _2);
+ map["Or"] = std::bind(&SimplifyLogical<false>, _1, _2);
+ map["Xor"] = std::bind(&SimplifyLogicalXor, _1, _2);
+
+ map["=="] = std::bind(&OptimizeEquality<true>, _1, _2);
+ map["!="] = std::bind(&OptimizeEquality<false>, _1, _2);
+
+ map["IsNotDistinctFrom"] = std::bind(&OptimizeDistinctFrom<true>, _1, _2);
+ map["IsDistinctFrom"] = std::bind(&OptimizeDistinctFrom<false>, _1, _2);
+
+ map["StartsWith"] = std::bind(&OptimizeEquality<true>, _1, _2);
+ map["EndsWith"] = std::bind(&OptimizeEquality<true>, _1, _2);
+
+ map["<"] = map["<="] = map[">"] = map[">="] = std::bind(&OptimizeCompare, _1, _2);;
map["Sort"] = std::bind(&OptimizeReorder<false, true>, _1, _2);
map["AssumeSorted"] = std::bind(&OptimizeReorder<false, false>, _1, _2);
@@ -4331,36 +4331,36 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
map["TopSort"] = std::bind(&OptimizeReorder<true, true>, _1, _2);
map["Minus"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Minus")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
+ if (node->Head().IsCallable("Minus")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
}
- if (TCoIntegralCtor::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Constant fold " << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
+ if (TCoIntegralCtor::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Constant fold " << node->Content() << " over " << node->Head().Content() << " '" << node->Head().Head().Content();
ui64 extracted;
- bool hasSign, isSigned;
- ExtractIntegralValue(node->Head(), true, hasSign, isSigned, extracted);
- const auto atomValue = GetIntegralAtomValue(extracted, hasSign && isSigned);
- return ctx.ChangeChild(node->Head(), 0U, ctx.NewAtom(node->Pos(), atomValue, TNodeFlags::Default));
+ bool hasSign, isSigned;
+ ExtractIntegralValue(node->Head(), true, hasSign, isSigned, extracted);
+ const auto atomValue = GetIntegralAtomValue(extracted, hasSign && isSigned);
+ return ctx.ChangeChild(node->Head(), 0U, ctx.NewAtom(node->Pos(), atomValue, TNodeFlags::Default));
}
return node;
};
map["Plus"] = [](const TExprNode::TPtr& node, TExprContext& /*ctx*/, TOptimizeContext& /*optCtx*/) {
- YQL_CLOG(DEBUG, Core) << node->Content();
- return node->HeadPtr();
+ YQL_CLOG(DEBUG, Core) << node->Content();
+ return node->HeadPtr();
};
- map["CastStruct"] = std::bind(&ExpandCastStruct, _1, _2);
+ map["CastStruct"] = std::bind(&ExpandCastStruct, _1, _2);
map["Append"] = std::bind(&OptimizeInsert<true>, _1, _2, _3);
map["Insert"] = std::bind(&OptimizeInsert<true>, _1, _2, _3);
map["Prepend"] = std::bind(&OptimizeInsert<false>, _1, _2, _3);
- map["Extract"] = std::bind(&ExpandExtract<false>, _1, _2);
- map["OrderedExtract"] = std::bind(&ExpandExtract<true>, _1, _2);
+ map["Extract"] = std::bind(&ExpandExtract<false>, _1, _2);
+ map["OrderedExtract"] = std::bind(&ExpandExtract<true>, _1, _2);
map["UnionAll"] = std::bind(&ExpandUnionAll<false>, _1, _2, _3);
map["UnionMerge"] = std::bind(&ExpandUnionAll<true>, _1, _2, _3);
@@ -4368,8 +4368,8 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
map["Aggregate"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
TCoAggregate self(node);
if (self.Keys().Size() == 0 && !HasPayload(self)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty fields";
- return ctx.NewCallable(node->Pos(), "AsList", {ctx.NewCallable(node->Pos(), "AsStruct", {})});
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty fields";
+ return ctx.NewCallable(node->Pos(), "AsList", {ctx.NewCallable(node->Pos(), "AsStruct", {})});
}
if (auto maybeAggregate = self.Input().Maybe<TCoAggregate>()) {
@@ -4380,57 +4380,57 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
}
- return DropReorder(node, ctx);
+ return DropReorder(node, ctx);
};
- map["Min"] = std::bind(&OptimizeMinMax<true>, _1, _2);
- map["Max"] = std::bind(&OptimizeMinMax<false>, _1, _2);
+ map["Min"] = std::bind(&OptimizeMinMax<true>, _1, _2);
+ map["Max"] = std::bind(&OptimizeMinMax<false>, _1, _2);
- map["Unwrap"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (const auto& input = node->Head(); input.IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << input.Content();
- return node->Head().HeadPtr();
- } else if (IsTransparentIfPresent(input)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
- return ctx.Builder(node->Pos())
- .ApplyPartial(input.Child(1U)->HeadPtr(), input.Child(1U)->Tail().HeadPtr())
- .With(0U, ctx.ChangeChild(*node, 0U, input.HeadPtr()))
- .Seal().Build();
+ map["Unwrap"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ if (const auto& input = node->Head(); input.IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << input.Content();
+ return node->Head().HeadPtr();
+ } else if (IsTransparentIfPresent(input)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
+ return ctx.Builder(node->Pos())
+ .ApplyPartial(input.Child(1U)->HeadPtr(), input.Child(1U)->Tail().HeadPtr())
+ .With(0U, ctx.ChangeChild(*node, 0U, input.HeadPtr()))
+ .Seal().Build();
}
return node;
};
- map["Reverse"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Reverse")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
+ map["Reverse"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
+ if (node->Head().IsCallable("Reverse")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
+ }
+
+ if (node->Head().IsCallable({"Map", "FlatMap", "Filter", "Extend"})) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " over unordered " << node->Head().Content();
+ return node->HeadPtr();
}
- if (node->Head().IsCallable({"Map", "FlatMap", "Filter", "Extend"})) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " over unordered " << node->Head().Content();
- return node->HeadPtr();
- }
-
- if (node->Head().IsCallable("List") || node->Head().IsCallable("AsList")) {
- ui32 count = node->Head().ChildrenSize();
- if (node->Head().IsCallable("List")) {
+ if (node->Head().IsCallable("List") || node->Head().IsCallable("AsList")) {
+ ui32 count = node->Head().ChildrenSize();
+ if (node->Head().IsCallable("List")) {
--count;
}
if (count <= 1) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over 0/1 literals";
- return node->HeadPtr();
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over 0/1 literals";
+ return node->HeadPtr();
}
}
- if (node->Head().IsCallable("AsList") && node->Head().ChildrenSize() > 1U) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- auto children = node->Head().ChildrenList();
- std::reverse(children.begin(), children.end());
- return ctx.ChangeChildren(node->Head(), std::move(children));
- }
-
+ if (node->Head().IsCallable("AsList") && node->Head().ChildrenSize() > 1U) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ auto children = node->Head().ChildrenList();
+ std::reverse(children.begin(), children.end());
+ return ctx.ChangeChildren(node->Head(), std::move(children));
+ }
+
return node;
};
@@ -4449,9 +4449,9 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
ui32 inputsCount = node->ChildrenSize() - 2;
for (ui32 i = 0; i < inputsCount; ++i) {
- if (IsListReorder(node->Child(i)->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Child(i)->Content();
- return ctx.ChangeChild(*node, i, ctx.ChangeChild(*node->Child(i), 0, node->Child(i)->Head().HeadPtr()));
+ if (IsListReorder(node->Child(i)->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->Child(i)->Content();
+ return ctx.ChangeChild(*node, i, ctx.ChangeChild(*node->Child(i), 0, node->Child(i)->Head().HeadPtr()));
}
}
@@ -4477,64 +4477,64 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Join"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (IsListReorder(node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0, node->Head().HeadPtr());
+ if (IsListReorder(node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0, node->Head().HeadPtr());
}
- if (IsListReorder(node->Tail())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Tail().Content();
- return ctx.ChangeChild(*node, 1, node->Tail().HeadPtr());
+ if (IsListReorder(node->Tail())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Tail().Content();
+ return ctx.ChangeChild(*node, 1, node->Tail().HeadPtr());
}
return node;
};
map["AggrCountInit"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - 1";
- return ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
+ if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - 1";
+ return ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "1", TNodeFlags::Default) });
}
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - 0";
- return ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "0", TNodeFlags::Default) });
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - 0";
+ return ctx.NewCallable(node->Pos(), "Uint64", { ctx.NewAtom(node->Pos(), "0", TNodeFlags::Default) });
}
return node;
};
map["AggrCountUpdate"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - Inc";
- return ctx.NewCallable(node->Pos(), "Inc", { node->TailPtr() });
+ if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - Inc";
+ return ctx.NewCallable(node->Pos(), "Inc", { node->TailPtr() });
}
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - None";
- return node->TailPtr();
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - None";
+ return node->TailPtr();
}
return node;
};
map["Guess"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
}
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
}
- if (node->Head().IsCallable("Variant")) {
- if (node->Tail().Content() == node->Head().Child(1)->Content()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " - same index";
- return ctx.NewCallable(node->Pos(), "Just", { node->Head().HeadPtr() });
+ if (node->Head().IsCallable("Variant")) {
+ if (node->Tail().Content() == node->Head().Child(1)->Content()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " - same index";
+ return ctx.NewCallable(node->Pos(), "Just", { node->Head().HeadPtr() });
} else {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " - different index";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content() << " - different index";
return ctx.NewCallable(node->Pos(), "Nothing", { ExpandType(node->Pos(), *node->GetTypeAnn(), ctx) });
}
}
@@ -4543,22 +4543,22 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Way"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return ctx.NewCallable(node->Pos(), "Nothing", { ExpandType(node->Pos(), *node->GetTypeAnn(), ctx) });
}
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return ctx.NewCallable(node->Pos(), "Just", { ctx.NewCallable(node->Pos(), "Way", { node->Head().HeadPtr() }) });
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return ctx.NewCallable(node->Pos(), "Just", { ctx.NewCallable(node->Pos(), "Way", { node->Head().HeadPtr() }) });
}
- if (node->Head().IsCallable("Variant")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- if (node->Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
- return ctx.NewCallable(node->Pos(), "Uint32", { node->Head().ChildPtr(1) });
+ if (node->Head().IsCallable("Variant")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (node->Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
+ return ctx.NewCallable(node->Pos(), "Uint32", { node->Head().ChildPtr(1) });
} else {
- return ctx.NewCallable(node->Pos(), "Utf8", { node->Head().ChildPtr(1) });
+ return ctx.NewCallable(node->Pos(), "Utf8", { node->Head().ChildPtr(1) });
}
}
@@ -4567,21 +4567,21 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
map["Visit"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
if (node->ChildrenSize() == 2) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - only default value";
- return node->TailPtr();
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - only default value";
+ return node->TailPtr();
}
if (node->ChildrenSize() == 4) {
// one handler and default value
auto lambda = node->Child(2);
auto defaultValue = node->Child(3);
- if (defaultValue->IsCallable("Nothing") && lambda->Tail().IsCallable("Just") &&
- &lambda->Tail().Tail() == &lambda->Head().Head()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - convert to Guess";
- return ctx.NewCallable(node->Pos(), "Guess", { node->HeadPtr(), node->ChildPtr(1) });
+ if (defaultValue->IsCallable("Nothing") && lambda->Tail().IsCallable("Just") &&
+ &lambda->Tail().Tail() == &lambda->Head().Head()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - convert to Guess";
+ return ctx.NewCallable(node->Pos(), "Guess", { node->HeadPtr(), node->ChildPtr(1) });
}
- auto varType = node->Head().GetTypeAnn()->Cast<TVariantExprType>();
+ auto varType = node->Head().GetTypeAnn()->Cast<TVariantExprType>();
bool removeDefaultValue;
if (varType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
removeDefaultValue = (varType->GetUnderlyingType()->Cast<TTupleExprType>()->GetSize() == 1);
@@ -4590,27 +4590,27 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
if (removeDefaultValue) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - remove default value";
- return ctx.NewCallable(node->Pos(), "Visit", { node->HeadPtr(), node->ChildPtr(1), node->ChildPtr(2) });
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - remove default value";
+ return ctx.NewCallable(node->Pos(), "Visit", { node->HeadPtr(), node->ChildPtr(1), node->ChildPtr(2) });
}
}
- if (node->Head().IsCallable("Variant")) {
- const auto& var = node->Head();
+ if (node->Head().IsCallable("Variant")) {
+ const auto& var = node->Head();
for (ui32 index = 1; index < node->ChildrenSize(); index += 2) {
auto child = node->ChildPtr(index);
if (!child->IsAtom()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - substitute the default value";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - substitute the default value";
return child;
}
- if (child->Content() == var.Child(1)->Content()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - substitute the alternative";
+ if (child->Content() == var.Child(1)->Content()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - substitute the alternative";
// one handler and no default value
auto lambda = node->Child(index + 1);
return ctx.Builder(node->Pos())
.Apply(lambda)
- .With(0, var.HeadPtr())
+ .With(0, var.HeadPtr())
.Seal()
.Build();
}
@@ -4628,12 +4628,12 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
if (uniqLambdas.size() == 1 && node->ChildrenSize() > 3) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - all equal lambdas";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - all equal lambdas";
return ctx.Builder(node->Pos())
.Apply(node->ChildPtr(2))
.With(0)
.Callable("VariantItem")
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Seal()
.Done()
.Seal()
@@ -4641,18 +4641,18 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
if (allJust) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " - extract Just";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " - extract Just";
return ctx.Builder(node->Pos())
.Callable("Just")
.Callable(0, "Visit")
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
for (ui32 i = 1; i < node->ChildrenSize(); i += 2) {
parent.Add(i, node->ChildPtr(i));
auto visitLambda = node->Child(i + 1);
parent.Lambda(i + 1, visitLambda->Pos())
.Param("item")
- .ApplyPartial(visitLambda->HeadPtr(), visitLambda->Tail().HeadPtr())
+ .ApplyPartial(visitLambda->HeadPtr(), visitLambda->Tail().HeadPtr())
.With(0, "item")
.Seal()
.Seal();
@@ -4668,8 +4668,8 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map[LeftName] = std::bind(&OptimizeDirection<false>, _1);
- map[RightName] = std::bind(&OptimizeDirection<true>, _1);
+ map[LeftName] = std::bind(&OptimizeDirection<false>, _1);
+ map[RightName] = std::bind(&OptimizeDirection<true>, _1);
map["Apply"] = [](const TExprNode::TPtr& node, TExprContext& /*ctx*/, TOptimizeContext& /*optCtx*/) {
auto ret = FoldYsonParseAfterSerialize(node);
@@ -4677,21 +4677,21 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return ret;
}
- ret = FoldYson2ParseAfterSerialize(node);
- if (ret != node) {
- return ret;
- }
-
+ ret = FoldYson2ParseAfterSerialize(node);
+ if (ret != node) {
+ return ret;
+ }
+
ret = FoldYsonSeralizeAfterParse(node);
if (ret != node) {
return ret;
}
- ret = FoldYson2SeralizeAfterParse(node);
- if (ret != node) {
- return ret;
- }
-
+ ret = FoldYson2SeralizeAfterParse(node);
+ if (ret != node) {
+ return ret;
+ }
+
ret = FoldJsonParseAfterSerialize(node);
if (ret != node) {
return ret;
@@ -4706,32 +4706,32 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Switch"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- TExprNode::TPtr flatMap;
- for (auto i = 3U; !flatMap && i < node->ChildrenSize(); ++++i) {
- flatMap = FindNode(node->Child(i)->TailPtr(),
- [handler = node->Child(i)](const TExprNode::TPtr& child) {
- return child->IsCallable({"FlatMap", "OrderedFlatMap"}) && child->Head().IsCallable() && child->Head().IsComplete() && child->Tail().GetDependencyScope()->first == handler
- && (ETypeAnnotationKind::Flow == child->Head().GetTypeAnn()->GetKind() || ETypeAnnotationKind::Stream == child->Head().GetTypeAnn()->GetKind());
- }
- );
- }
-
- if (flatMap) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " bring out " << flatMap->Content() << " by independent " << flatMap->Head().Content() << " from handler.";
- auto children = node->ChildrenList();
- const auto arg = ctx.NewArgument(flatMap->Tail().Head().Head().Pos(), "outsider");
- TNodeOnNodeOwnedMap replaces((children.size() >> 1U) - 1U);
- for (auto i = 3U; i < children.size(); ++++i) {
- const auto ins = replaces.emplace(children[i].Get(), TExprNode::TPtr());
- if (ins.second) {
- ins.first->second = ctx.DeepCopyLambda(*ins.first->first, ctx.ReplaceNode(ins.first->first->TailPtr(), *flatMap, ctx.ReplaceNode(flatMap->Tail().TailPtr(), flatMap->Tail().Head().Head(), arg)));
- }
- children[i] = ins.first->second;
- }
- return ctx.ChangeChildren(*flatMap, {CloneCompleteFlow(flatMap->HeadPtr(), ctx), ctx.NewLambda(flatMap->Tail().Pos(), ctx.NewArguments(flatMap->Tail().Head().Pos(), {arg}), ctx.ChangeChildren(*node, std::move(children)))});
- }
-
- const auto inputItemType = GetSeqItemType(node->Head().GetTypeAnn());
+ TExprNode::TPtr flatMap;
+ for (auto i = 3U; !flatMap && i < node->ChildrenSize(); ++++i) {
+ flatMap = FindNode(node->Child(i)->TailPtr(),
+ [handler = node->Child(i)](const TExprNode::TPtr& child) {
+ return child->IsCallable({"FlatMap", "OrderedFlatMap"}) && child->Head().IsCallable() && child->Head().IsComplete() && child->Tail().GetDependencyScope()->first == handler
+ && (ETypeAnnotationKind::Flow == child->Head().GetTypeAnn()->GetKind() || ETypeAnnotationKind::Stream == child->Head().GetTypeAnn()->GetKind());
+ }
+ );
+ }
+
+ if (flatMap) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " bring out " << flatMap->Content() << " by independent " << flatMap->Head().Content() << " from handler.";
+ auto children = node->ChildrenList();
+ const auto arg = ctx.NewArgument(flatMap->Tail().Head().Head().Pos(), "outsider");
+ TNodeOnNodeOwnedMap replaces((children.size() >> 1U) - 1U);
+ for (auto i = 3U; i < children.size(); ++++i) {
+ const auto ins = replaces.emplace(children[i].Get(), TExprNode::TPtr());
+ if (ins.second) {
+ ins.first->second = ctx.DeepCopyLambda(*ins.first->first, ctx.ReplaceNode(ins.first->first->TailPtr(), *flatMap, ctx.ReplaceNode(flatMap->Tail().TailPtr(), flatMap->Tail().Head().Head(), arg)));
+ }
+ children[i] = ins.first->second;
+ }
+ return ctx.ChangeChildren(*flatMap, {CloneCompleteFlow(flatMap->HeadPtr(), ctx), ctx.NewLambda(flatMap->Tail().Pos(), ctx.NewArguments(flatMap->Tail().Head().Pos(), {arg}), ctx.ChangeChildren(*node, std::move(children)))});
+ }
+
+ const auto inputItemType = GetSeqItemType(node->Head().GetTypeAnn());
const bool singleInput = inputItemType->GetKind() != ETypeAnnotationKind::Variant;
TDynBitMap usedIndicies;
@@ -4743,10 +4743,10 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
bool ordered = false;
if (singleInput && singleHandler && node->Child(2)->ChildrenSize() == 1) { // Exactly one index
- YQL_CLOG(DEBUG, Core) << node->Content() << " with single input and single handler";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with single input and single handler";
return ctx.Builder(node->Pos())
.Apply(node->ChildPtr(3)) // handler lambda
- .With(0, node->HeadPtr()) // Switch input
+ .With(0, node->HeadPtr()) // Switch input
.Seal()
.Build();
}
@@ -4756,16 +4756,16 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
}
if (!singleInput) {
- ui32 index = FromString<ui32>(node->Child(i)->Head().Content());
+ ui32 index = FromString<ui32>(node->Child(i)->Head().Content());
if (usedIndicies.Test(index)) {
return node;
}
usedIndicies.Set(index);
- indicies.push_back(node->Child(i)->HeadPtr());
+ indicies.push_back(node->Child(i)->HeadPtr());
}
auto lambda = node->Child(i + 1);
- if (&lambda->Head().Head() == &lambda->Tail()) {
+ if (&lambda->Head().Head() == &lambda->Tail()) {
// Trivial lambda
ordered = ordered || lambda->GetConstraint<TSortedConstraintNode>();
lambdas.emplace_back();
@@ -4776,11 +4776,11 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
auto flatMapInput = lambda->Child(1)->Child(0);
const TTypeAnnotationNode* castType = nullptr;
if (TCoExtractMembers::Match(flatMapInput)) {
- castType = GetSeqItemType(flatMapInput->GetTypeAnn());
+ castType = GetSeqItemType(flatMapInput->GetTypeAnn());
flatMapInput = flatMapInput->Child(0);
}
- if (flatMapInput != lambda->Head().Child(0)) { // FlatMap input == Switch lambda arg
+ if (flatMapInput != lambda->Head().Child(0)) { // FlatMap input == Switch lambda arg
return node;
}
@@ -4805,12 +4805,12 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
targetType = ETypeAnnotationKind::Stream;
break;
- case ETypeAnnotationKind::Flow:
- if (!singleHandler && flatMapLambda->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() == ETypeAnnotationKind::Variant) {
- return node;
- }
- targetType = ETypeAnnotationKind::Flow;
- break;
+ case ETypeAnnotationKind::Flow:
+ if (!singleHandler && flatMapLambda->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() == ETypeAnnotationKind::Variant) {
+ return node;
+ }
+ targetType = ETypeAnnotationKind::Flow;
+ break;
default:
YQL_ENSURE(false, "Unsupported FlatMap lambda return type: " << flatMapLambda->GetTypeAnn()->GetKind());
}
@@ -4825,12 +4825,12 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
const auto flatMapName = ordered ? TCoOrderedFlatMap::CallableName() : TCoFlatMap::CallableName();
const auto mapName = ordered ? TCoOrderedMap::CallableName() : TCoMap::CallableName();
if (indicies.size() == 1) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with single trivial or FlatMap lambda";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with single trivial or FlatMap lambda";
if (lambdas.front()) {
return ctx.Builder(node->Pos())
.Callable(flatMapName)
.Callable(0, flatMapName)
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Lambda(1)
.Param("item")
.Callable("Guess")
@@ -4863,7 +4863,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
else {
return ctx.Builder(node->Pos())
.Callable(flatMapName)
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Lambda(1)
.Param("item")
.Callable("Guess")
@@ -4876,7 +4876,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
}
}
- const auto outVarType = ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx);
+ const auto outVarType = ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx);
TExprNode::TListType updatedLambdas;
for (size_t i = 0; i < lambdas.size(); ++i) {
@@ -4904,25 +4904,25 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Param("mapItem")
.Callable("Variant")
.Arg(0, "mapItem")
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Add(2, outVarType)
.Seal()
.Seal()
.Seal()
.Build();
if (lambdas[i]->GetTypeAnn()->GetKind() != targetType) {
- switch (targetType) {
- case ETypeAnnotationKind::Flow:
- body = ctx.NewCallable(node->Pos(), "ToFlow", {std::move(body)});
- break;
- case ETypeAnnotationKind::Stream:
- body = ctx.NewCallable(node->Pos(), "ToStream", {std::move(body)});
- break;
- case ETypeAnnotationKind::List:
- body = ctx.NewCallable(node->Pos(), "ToList", {std::move(body)});
- break;
- default:
- break;
+ switch (targetType) {
+ case ETypeAnnotationKind::Flow:
+ body = ctx.NewCallable(node->Pos(), "ToFlow", {std::move(body)});
+ break;
+ case ETypeAnnotationKind::Stream:
+ body = ctx.NewCallable(node->Pos(), "ToStream", {std::move(body)});
+ break;
+ case ETypeAnnotationKind::List:
+ body = ctx.NewCallable(node->Pos(), "ToList", {std::move(body)});
+ break;
+ default:
+ break;
}
}
}
@@ -4930,37 +4930,37 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
body = ctx.Builder(node->Pos())
.Callable("Variant")
.Add(0, arg)
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Add(2, outVarType)
.Seal()
.Build();
if (ETypeAnnotationKind::List == targetType) {
- body = ctx.NewCallable(node->Pos(), "AsList", {std::move(body)});
+ body = ctx.NewCallable(node->Pos(), "AsList", {std::move(body)});
}
else {
- body = ctx.NewCallable(node->Pos(), "Just", {std::move(body)});
- if (ETypeAnnotationKind::Flow == targetType) {
- body = ctx.NewCallable(node->Pos(), "ToFlow", {std::move(body)});
- }
- else if (ETypeAnnotationKind::Stream == targetType) {
- body = ctx.NewCallable(node->Pos(), "ToStream", {std::move(body)});
+ body = ctx.NewCallable(node->Pos(), "Just", {std::move(body)});
+ if (ETypeAnnotationKind::Flow == targetType) {
+ body = ctx.NewCallable(node->Pos(), "ToFlow", {std::move(body)});
+ }
+ else if (ETypeAnnotationKind::Stream == targetType) {
+ body = ctx.NewCallable(node->Pos(), "ToStream", {std::move(body)});
}
}
}
- updatedLambdas.push_back(ctx.NewLambda(node->Pos(), ctx.NewArguments(node->Pos(), {std::move(arg)}), std::move(body)));
+ updatedLambdas.push_back(ctx.NewLambda(node->Pos(), ctx.NewArguments(node->Pos(), {std::move(arg)}), std::move(body)));
}
if (singleInput) {
- YQL_CLOG(DEBUG, Core) << "Replicating " << node->Content() << " with trivial or FlatMap lambdas";
+ YQL_CLOG(DEBUG, Core) << "Replicating " << node->Content() << " with trivial or FlatMap lambdas";
return ctx.Builder(node->Pos())
.Callable(flatMapName)
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Lambda(1)
.Param("item")
- .Callable(ordered ? TCoOrderedExtend::CallableName() : TCoExtend::CallableName())
+ .Callable(ordered ? TCoOrderedExtend::CallableName() : TCoExtend::CallableName())
.Do([&](TExprNodeBuilder& builder) -> TExprNodeBuilder& {
for (size_t i = 0; i < updatedLambdas.size(); ++i) {
- builder.Apply(i, *updatedLambdas[i])
+ builder.Apply(i, *updatedLambdas[i])
.With(0, "item")
.Seal();
}
@@ -4972,12 +4972,12 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Build();
}
- const auto inputVarTupleType = inputItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
+ const auto inputVarTupleType = inputItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
- YQL_CLOG(DEBUG, Core) << node->Content() << " with trivial or FlatMap lambdas";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with trivial or FlatMap lambdas";
return ctx.Builder(node->Pos())
.Callable(flatMapName)
- .Add(0, node->HeadPtr())
+ .Add(0, node->HeadPtr())
.Lambda(1)
.Param("item")
.Callable("Visit")
@@ -4988,9 +4988,9 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
builder.Add(i * 2 + 2, updatedLambdas[i]);
}
if (indicies.size() < inputVarTupleType->GetSize()) {
- builder.Callable(indicies.size() * 2 + 1, GetEmptyCollectionName(targetType))
- .Add(0, ExpandType(node->Pos(), *MakeSequenceType(targetType, *GetSeqItemType(node->GetTypeAnn()), ctx), ctx))
- .Seal();
+ builder.Callable(indicies.size() * 2 + 1, GetEmptyCollectionName(targetType))
+ .Add(0, ExpandType(node->Pos(), *MakeSequenceType(targetType, *GetSeqItemType(node->GetTypeAnn()), ctx), ctx))
+ .Seal();
}
return builder;
})
@@ -5001,20 +5001,20 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["VariantItem"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (TCoJust::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.SwapWithHead(*node);
+ if (TCoJust::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.SwapWithHead(*node);
}
- if (TCoOptionalIf::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 1U, ctx.ChangeChild(*node, 0U, node->Head().TailPtr()));
+ if (TCoOptionalIf::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << "Move " << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 1U, ctx.ChangeChild(*node, 0U, node->Head().TailPtr()));
}
- if (TCoVariant::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
+ if (TCoVariant::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
}
- if (TCoNothing::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (TCoNothing::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
return ctx.Builder(node->Pos())
.Callable("Nothing")
.Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
@@ -5026,37 +5026,37 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
map["Untag"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
Y_UNUSED(ctx);
- if (node->Head().IsCallable("AsTagged")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->Head().HeadPtr();
+ if (node->Head().IsCallable("AsTagged")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->Head().HeadPtr();
}
return node;
};
- map["SqueezeToDict"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
- YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
- return ctx.Builder(node->Pos())
- .Callable(ETypeAnnotationKind::Flow == node->GetTypeAnn()->GetKind() ? "ToFlow" : "ToStream")
- .Callable(0, "Just")
- .Callable(0, "Dict")
- .Add(0, ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx))
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
- };
-
- map["ToDict"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
- YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
- return ctx.NewCallable(inputToCheck.Pos(), "Dict", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
-
- if (node->Head().IsCallable("AsList") && node->Child(2)->Child(1)->IsCallable("Void")) {
+ map["SqueezeToDict"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
+ YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
+ return ctx.Builder(node->Pos())
+ .Callable(ETypeAnnotationKind::Flow == node->GetTypeAnn()->GetKind() ? "ToFlow" : "ToStream")
+ .Callable(0, "Just")
+ .Callable(0, "Dict")
+ .Add(0, ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx))
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+ };
+
+ map["ToDict"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
+ YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
+ return ctx.NewCallable(inputToCheck.Pos(), "Dict", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+
+ if (node->Head().IsCallable("AsList") && node->Child(2)->Child(1)->IsCallable("Void")) {
TMaybe<bool> isMany;
TMaybe<bool> isHashed;
TMaybe<ui64> itemsCount;
@@ -5071,9 +5071,9 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Add(0, ExpandType(node->Pos(), *node->GetTypeAnn()->Cast<TDictExprType>()->GetKeyType(), ctx))
.List(1)
.Do([&](TExprNodeBuilder& builder) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < node->Head().ChildrenSize(); ++i) {
+ for (ui32 i = 0; i < node->Head().ChildrenSize(); ++i) {
builder.Apply(i, node->ChildPtr(1))
- .With(0, node->Head().ChildPtr(i))
+ .With(0, node->Head().ChildPtr(i))
.Seal();
}
return builder;
@@ -5110,18 +5110,18 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["HasNull"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- YQL_CLOG(DEBUG, Core) << node->Content();
+ YQL_CLOG(DEBUG, Core) << node->Content();
- auto value = node->HeadPtr();
+ auto value = node->HeadPtr();
auto valueType = value->GetTypeAnn();
if (!valueType->HasOptionalOrNull()) {
- return MakeBool<false>(node->Pos(), ctx);
+ return MakeBool<false>(node->Pos(), ctx);
}
switch (valueType->GetKind()) {
case ETypeAnnotationKind::Null:
- return MakeBool<true>(node->Pos(), ctx);
+ return MakeBool<true>(node->Pos(), ctx);
case ETypeAnnotationKind::Optional:
return ctx.Builder(node->Pos())
.Callable("IfPresent")
@@ -5132,7 +5132,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Arg(0, "item")
.Seal()
.Seal()
- .Add(2, MakeBool<true>(node->Pos(), ctx))
+ .Add(2, MakeBool<true>(node->Pos(), ctx))
.Seal()
.Build();
case ETypeAnnotationKind::Tagged:
@@ -5182,9 +5182,9 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Unordered"] = map["UnorderedSubquery"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (node->Head().IsCallable("AsList")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return node->HeadPtr();
+ if (node->Head().IsCallable("AsList")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return node->HeadPtr();
}
if (node->Head().IsCallable("AssumeSorted")) {
@@ -5196,18 +5196,18 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
};
map["Demux"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& /*optCtx*/) {
- if (TCoExtendBase::Match(&node->Head())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ if (TCoExtendBase::Match(&node->Head())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
TExprNode::TListType demuxChildren;
- std::transform(node->Head().Children().begin(), node->Head().Children().end(),
+ std::transform(node->Head().Children().begin(), node->Head().Children().end(),
std::back_inserter(demuxChildren),
[&] (const TExprNode::TPtr& n) {
return Build<TCoDemux>(ctx, n->Pos()).Input(n).Done().Ptr();
}
);
- auto variantType = node->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TVariantExprType>();
+ auto variantType = node->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TVariantExprType>();
if (variantType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
TExprNode::TListType resChildren;
for (size_t i = 0; i < variantType->GetUnderlyingType()->Cast<TTupleExprType>()->GetSize(); ++i) {
@@ -5220,7 +5220,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Done().Ptr()
);
}
- resChildren.push_back(ctx.NewCallable(node->Pos(), node->Head().Content(), std::move(extendChildren)));
+ resChildren.push_back(ctx.NewCallable(node->Pos(), node->Head().Content(), std::move(extendChildren)));
}
return ctx.NewList(node->Pos(), std::move(resChildren));
}
@@ -5236,7 +5236,7 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
.Done().Ptr()
);
}
- auto extend = ctx.NewCallable(node->Pos(), node->Head().Content(), std::move(extendChildren));
+ auto extend = ctx.NewCallable(node->Pos(), node->Head().Content(), std::move(extendChildren));
resChildren.push_back(ctx.NewList(node->Pos(), {memberName, extend}));
}
return ctx.NewCallable(node->Pos(), TCoAsStruct::CallableName(), std::move(resChildren));
@@ -6129,78 +6129,78 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return ExpandPositionalUnionAll(*node, columnOrders, node->ChildrenList(), ctx, optCtx);
};
- map["MapJoinCore"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
- YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
- return ctx.NewCallable(inputToCheck.Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
- }
-
- if (const TCoMapJoinCore mapJoin(node); IsEmptyContainer(mapJoin.RightDict().Ref())) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with empty " << mapJoin.RightDict().Ref().Content();
-
- if (const auto& joinKind = mapJoin.JoinKind().Value(); joinKind == "Inner" || joinKind == "LeftSemi")
- return ctx.NewCallable(mapJoin.Pos(), "EmptyIterator", {ExpandType(mapJoin.Pos(), *node->GetTypeAnn(), ctx)});
- else if (joinKind == "Left" || joinKind == "LeftOnly") {
- switch (const auto itemType = GetSeqItemType(node->GetTypeAnn()); itemType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto& items = itemType->Cast<TTupleExprType>()->GetItems();
- auto row = ctx.NewArgument(mapJoin.Pos(), "row");
- TExprNode::TListType fields(items.size());
- for (auto i = 1U; i < mapJoin.LeftRenames().Size(); ++++i) {
- const auto index = FromString<ui32>(mapJoin.LeftRenames().Item(i).Value());
- fields[index] = ctx.Builder(mapJoin.LeftRenames().Item(i).Pos())
- .Callable("Nth")
- .Add(0, row)
- .Add(1, mapJoin.LeftRenames().Item(i - 1U).Ptr())
- .Seal().Build();
- }
- for (auto i = 1U; i < mapJoin.RightRenames().Size(); ++++i) {
- const auto index = FromString<ui32>(mapJoin.RightRenames().Item(i).Value());
- fields[index] = ctx.Builder(mapJoin.RightRenames().Item(i).Pos())
- .Callable("Nothing")
- .Add(0, ExpandType(mapJoin.Pos(), *items[index], ctx))
- .Seal().Build();
- }
- auto lambda = ctx.NewLambda(mapJoin.Pos(), ctx.NewArguments(mapJoin.Pos(), {std::move(row)}), ctx.NewList(mapJoin.Pos(), std::move(fields)));
- return ctx.NewCallable(mapJoin.Pos(), "Map", {mapJoin.LeftInput().Ptr(), std::move(lambda)});
- }
- case ETypeAnnotationKind::Struct: {
- const auto structType = itemType->Cast<TStructExprType>();
- const auto& items = structType->GetItems();
- auto row = ctx.NewArgument(mapJoin.Pos(), "row");
- TExprNode::TListType fields(items.size());
- for (auto i = 1U; i < mapJoin.LeftRenames().Size(); ++++i) {
- const auto index = *structType->FindItem(mapJoin.LeftRenames().Item(i).Value());
- fields[index] = ctx.Builder(mapJoin.LeftRenames().Item(i).Pos())
- .List()
- .Add(0, mapJoin.LeftRenames().Item(i).Ptr())
- .Callable(1, "Member")
- .Add(0, row)
- .Add(1, mapJoin.LeftRenames().Item(i - 1U).Ptr())
- .Seal()
- .Seal().Build();
- }
- for (auto i = 1U; i < mapJoin.RightRenames().Size(); ++++i) {
- const auto index = *structType->FindItem(mapJoin.RightRenames().Item(i).Value());
- fields[index] = ctx.Builder(mapJoin.RightRenames().Item(i).Pos())
- .List()
- .Add(0, mapJoin.RightRenames().Item(i).Ptr())
- .Callable(1, "Nothing")
- .Add(0, ExpandType(mapJoin.Pos(), *items[index]->GetItemType(), ctx))
- .Seal()
- .Seal().Build();
- }
- auto lambda = ctx.NewLambda(mapJoin.Pos(), ctx.NewArguments(mapJoin.Pos(), {std::move(row)}), ctx.NewCallable(mapJoin.Pos(), "AsStruct", std::move(fields)));
- return ctx.NewCallable(mapJoin.Pos(), "Map", {mapJoin.LeftInput().Ptr(), std::move(lambda)});
- }
- default: break;
- }
- }
- }
-
- return node;
- };
-
+ map["MapJoinCore"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ if (const auto& inputToCheck = SkipCallables(node->Head(), SkippableCallables); IsEmptyContainer(inputToCheck) || IsEmpty(inputToCheck, *optCtx.Types)) {
+ YQL_CLOG(DEBUG, Core) << "Empty " << node->Content();
+ return ctx.NewCallable(inputToCheck.Pos(), "EmptyIterator", {ExpandType(node->Pos(), *node->GetTypeAnn(), ctx)});
+ }
+
+ if (const TCoMapJoinCore mapJoin(node); IsEmptyContainer(mapJoin.RightDict().Ref())) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with empty " << mapJoin.RightDict().Ref().Content();
+
+ if (const auto& joinKind = mapJoin.JoinKind().Value(); joinKind == "Inner" || joinKind == "LeftSemi")
+ return ctx.NewCallable(mapJoin.Pos(), "EmptyIterator", {ExpandType(mapJoin.Pos(), *node->GetTypeAnn(), ctx)});
+ else if (joinKind == "Left" || joinKind == "LeftOnly") {
+ switch (const auto itemType = GetSeqItemType(node->GetTypeAnn()); itemType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto& items = itemType->Cast<TTupleExprType>()->GetItems();
+ auto row = ctx.NewArgument(mapJoin.Pos(), "row");
+ TExprNode::TListType fields(items.size());
+ for (auto i = 1U; i < mapJoin.LeftRenames().Size(); ++++i) {
+ const auto index = FromString<ui32>(mapJoin.LeftRenames().Item(i).Value());
+ fields[index] = ctx.Builder(mapJoin.LeftRenames().Item(i).Pos())
+ .Callable("Nth")
+ .Add(0, row)
+ .Add(1, mapJoin.LeftRenames().Item(i - 1U).Ptr())
+ .Seal().Build();
+ }
+ for (auto i = 1U; i < mapJoin.RightRenames().Size(); ++++i) {
+ const auto index = FromString<ui32>(mapJoin.RightRenames().Item(i).Value());
+ fields[index] = ctx.Builder(mapJoin.RightRenames().Item(i).Pos())
+ .Callable("Nothing")
+ .Add(0, ExpandType(mapJoin.Pos(), *items[index], ctx))
+ .Seal().Build();
+ }
+ auto lambda = ctx.NewLambda(mapJoin.Pos(), ctx.NewArguments(mapJoin.Pos(), {std::move(row)}), ctx.NewList(mapJoin.Pos(), std::move(fields)));
+ return ctx.NewCallable(mapJoin.Pos(), "Map", {mapJoin.LeftInput().Ptr(), std::move(lambda)});
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto structType = itemType->Cast<TStructExprType>();
+ const auto& items = structType->GetItems();
+ auto row = ctx.NewArgument(mapJoin.Pos(), "row");
+ TExprNode::TListType fields(items.size());
+ for (auto i = 1U; i < mapJoin.LeftRenames().Size(); ++++i) {
+ const auto index = *structType->FindItem(mapJoin.LeftRenames().Item(i).Value());
+ fields[index] = ctx.Builder(mapJoin.LeftRenames().Item(i).Pos())
+ .List()
+ .Add(0, mapJoin.LeftRenames().Item(i).Ptr())
+ .Callable(1, "Member")
+ .Add(0, row)
+ .Add(1, mapJoin.LeftRenames().Item(i - 1U).Ptr())
+ .Seal()
+ .Seal().Build();
+ }
+ for (auto i = 1U; i < mapJoin.RightRenames().Size(); ++++i) {
+ const auto index = *structType->FindItem(mapJoin.RightRenames().Item(i).Value());
+ fields[index] = ctx.Builder(mapJoin.RightRenames().Item(i).Pos())
+ .List()
+ .Add(0, mapJoin.RightRenames().Item(i).Ptr())
+ .Callable(1, "Nothing")
+ .Add(0, ExpandType(mapJoin.Pos(), *items[index]->GetItemType(), ctx))
+ .Seal()
+ .Seal().Build();
+ }
+ auto lambda = ctx.NewLambda(mapJoin.Pos(), ctx.NewArguments(mapJoin.Pos(), {std::move(row)}), ctx.NewCallable(mapJoin.Pos(), "AsStruct", std::move(fields)));
+ return ctx.NewCallable(mapJoin.Pos(), "Map", {mapJoin.LeftInput().Ptr(), std::move(lambda)});
+ }
+ default: break;
+ }
+ }
+ }
+
+ return node;
+ };
+
map["RangeIntersect"] = [](const TExprNode::TPtr& node, TExprContext& /*ctx*/, TOptimizeContext& /*optCtx*/) {
if (node->ChildrenSize() == 1) {
YQL_CLOG(DEBUG, Core) << "Single arg " << node->Content();
diff --git a/ydb/library/yql/core/common_opt/yql_co_simple2.cpp b/ydb/library/yql/core/common_opt/yql_co_simple2.cpp
index 85c5d00249..6d59989b6a 100644
--- a/ydb/library/yql/core/common_opt/yql_co_simple2.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_simple2.cpp
@@ -19,7 +19,7 @@ bool HasTotalOrder(const TTypeAnnotationNode& type) {
if (type.GetKind() == ETypeAnnotationKind::Data) {
auto dataSlot = type.Cast<TDataExprType>()->GetSlot();
- return dataSlot != EDataSlot::Float && dataSlot != EDataSlot::Double && dataSlot != EDataSlot::Decimal;
+ return dataSlot != EDataSlot::Float && dataSlot != EDataSlot::Double && dataSlot != EDataSlot::Decimal;
}
if (type.GetKind() == ETypeAnnotationKind::Struct) {
@@ -82,19 +82,19 @@ bool HasTotalOrder(const TTypeAnnotationNode& type) {
YQL_ENSURE(false, "Unordered type: " << type);
}
-TExprNode::TPtr DeduplicateAggregateSameTraits(const TExprNode::TPtr& node, TExprContext& ctx) {
- const TCoAggregate self(node);
- if (self.Handlers().Size() == 0) {
- return node;
+TExprNode::TPtr DeduplicateAggregateSameTraits(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const TCoAggregate self(node);
+ if (self.Handlers().Size() == 0) {
+ return node;
}
// keep index of main handler or Max if this handler is the main one
- std::vector<ui32> handlersMapping(self.Handlers().Size(), Max<ui32>());
- TNodeMap<ui32> nonDistinctHandlers; // map trait->handler index
+ std::vector<ui32> handlersMapping(self.Handlers().Size(), Max<ui32>());
+ TNodeMap<ui32> nonDistinctHandlers; // map trait->handler index
THashMap<std::pair<TStringBuf, const TExprNode*>, ui32> distinctHandlers; // map column name+trait->handler index
ui32 duplicatesCount = 0;
- for (ui32 index = 0; index < self.Handlers().Size(); ++index) {
- auto& handler = self.Handlers().Item(index).Ref();
+ for (ui32 index = 0; index < self.Handlers().Size(); ++index) {
+ auto& handler = self.Handlers().Item(index).Ref();
auto nameNode = handler.Child(0);
if (nameNode->IsList()) {
// skip multioutput nodes
@@ -119,27 +119,27 @@ TExprNode::TPtr DeduplicateAggregateSameTraits(const TExprNode::TPtr& node, TExp
}
if (!duplicatesCount) {
- return node;
+ return node;
}
TExprNode::TListType filteredHandlers;
filteredHandlers.reserve(handlersMapping.size() - duplicatesCount);
for (ui32 index = 0; index < handlersMapping.size(); ++index) {
if (handlersMapping[index] == Max<ui32>()) {
- filteredHandlers.push_back(self.Handlers().Item(index).Ptr());
+ filteredHandlers.push_back(self.Handlers().Item(index).Ptr());
}
}
- auto dedupedAggregate = Build<TCoAggregate>(ctx, self.Pos())
- .Input(self.Input())
- .Keys(self.Keys())
- .Handlers(ctx.NewList(self.Pos(), std::move(filteredHandlers)))
- .Settings(self.Settings())
+ auto dedupedAggregate = Build<TCoAggregate>(ctx, self.Pos())
+ .Input(self.Input())
+ .Keys(self.Keys())
+ .Handlers(ctx.NewList(self.Pos(), std::move(filteredHandlers)))
+ .Settings(self.Settings())
.Build()
.Value();
- YQL_CLOG(DEBUG, Core) << "Deduplicate " << node->Content() << " traits";
- return ctx.Builder(self.Pos())
+ YQL_CLOG(DEBUG, Core) << "Deduplicate " << node->Content() << " traits";
+ return ctx.Builder(self.Pos())
.Callable("Map")
.Add(0, dedupedAggregate.Ptr())
.Lambda(1)
@@ -147,8 +147,8 @@ TExprNode::TPtr DeduplicateAggregateSameTraits(const TExprNode::TPtr& node, TExp
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
auto structObj = parent.Callable("AsStruct");
ui32 targetIndex = 0;
- for (ui32 index = 0; index < self.Keys().Size(); ++index) {
- auto keyAtom = self.Keys().Item(index).Ptr();
+ for (ui32 index = 0; index < self.Keys().Size(); ++index) {
+ auto keyAtom = self.Keys().Item(index).Ptr();
structObj
.List(targetIndex++)
.Add(0, keyAtom)
@@ -160,10 +160,10 @@ TExprNode::TPtr DeduplicateAggregateSameTraits(const TExprNode::TPtr& node, TExp
}
for (ui32 index = 0; index < handlersMapping.size(); ++index) {
- const auto& columnNode = self.Handlers().Item(index).Ref().Child(0);
+ const auto& columnNode = self.Handlers().Item(index).Ref().Child(0);
if (columnNode->IsAtom()) {
const auto& myColumn = columnNode->Content();
- const auto& originalColumn = self.Handlers().Item(handlersMapping[index] == Max<ui32>() ?
+ const auto& originalColumn = self.Handlers().Item(handlersMapping[index] == Max<ui32>() ?
index : handlersMapping[index]).Ref().Child(0)->Content();
structObj
.List(targetIndex++)
@@ -229,97 +229,97 @@ TExprNode::TPtr SimplifySync(const TExprNode::TPtr& node, TExprContext& ctx) {
}
if (realWorlds.size() == 1) {
- YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content();
+ YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content();
return realWorlds.cbegin()->second;
}
if (flatten || (realWorlds.size() != node->ChildrenSize())) {
if (realWorlds.empty()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " to World";
+ YQL_CLOG(DEBUG, Core) << node->Content() << " to World";
return ctx.NewWorld(node->Pos());
}
- YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content();
- return ctx.NewCallable(node->Pos(), SyncName, std::move(ordered));
+ YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content();
+ return ctx.NewCallable(node->Pos(), SyncName, std::move(ordered));
}
return node;
}
-void DropDups(TExprNode::TListType& children) {
- TNodeSet set(children.size());
- for (auto it = children.cbegin(); children.cend() != it;) {
- if (set.emplace(it->Get()).second) {
- ++it;
- } else {
- it = children.erase(it);
+void DropDups(TExprNode::TListType& children) {
+ TNodeSet set(children.size());
+ for (auto it = children.cbegin(); children.cend() != it;) {
+ if (set.emplace(it->Get()).second) {
+ ++it;
+ } else {
+ it = children.erase(it);
}
}
}
-TExprNode::TPtr OptimizeDups(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto children = node->ChildrenList();
- DropDups(children);
- if (children.size() < node->ChildrenSize()) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->ChildrenSize() - children.size() << " dups";
- return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
+TExprNode::TPtr OptimizeDups(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto children = node->ChildrenList();
+ DropDups(children);
+ if (children.size() < node->ChildrenSize()) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with " << node->ChildrenSize() - children.size() << " dups";
+ return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ return node;
+}
+
+TExprNode::TPtr DropAggrOverSame(const TExprNode::TPtr& node) {
+ if (&node->Head() == &node->Tail()) {
+ YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with same args";
+ return node->TailPtr();
}
return node;
}
-TExprNode::TPtr DropAggrOverSame(const TExprNode::TPtr& node) {
- if (&node->Head() == &node->Tail()) {
- YQL_CLOG(DEBUG, Core) << "Drop " << node->Content() << " with same args";
- return node->TailPtr();
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeXor(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto children = node->ChildrenList();
- DropDups(children);
- if (children.size() < node->ChildrenSize()) {
- const bool inverse = (node->ChildrenSize() - children.size()) % 2U;
- YQL_CLOG(DEBUG, Core) << node->Content() << " over some dups";
- return children.empty() ?
- ctx.WrapByCallableIf(node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "Just", MakeBool(node->Pos(), inverse, ctx)):
- ctx.WrapByCallableIf(inverse, "Not", ctx.ChangeChildren(*node, std::move(children)));
- }
-
- return node;
+TExprNode::TPtr OptimizeXor(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto children = node->ChildrenList();
+ DropDups(children);
+ if (children.size() < node->ChildrenSize()) {
+ const bool inverse = (node->ChildrenSize() - children.size()) % 2U;
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over some dups";
+ return children.empty() ?
+ ctx.WrapByCallableIf(node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "Just", MakeBool(node->Pos(), inverse, ctx)):
+ ctx.WrapByCallableIf(inverse, "Not", ctx.ChangeChildren(*node, std::move(children)));
+ }
+
+ return node;
}
-TExprNode::TPtr OptimizeNot(const TExprNode::TPtr& node, TExprContext& ctx) {
- static const std::unordered_map<std::string_view, std::string_view> InverseComparators = {
- {"==", "!="},
- {"!=", "=="},
- {"<", ">="},
- {">=", "<"},
- {">", "<="},
- {"<=", ">"},
- {"AggrEquals", "AggrNotEquals"},
- {"AggrNotEquals", "AggrEquals"},
- {"AggrLess", "AggrGreaterOrEqual"},
- {"AggrGreaterOrEqual", "AggrLess"},
- {"AggrLessOrEqual", "AggrGreater"},
- {"AggrGreater", "AggrLessOrEqual"},
- };
-
+TExprNode::TPtr OptimizeNot(const TExprNode::TPtr& node, TExprContext& ctx) {
+ static const std::unordered_map<std::string_view, std::string_view> InverseComparators = {
+ {"==", "!="},
+ {"!=", "=="},
+ {"<", ">="},
+ {">=", "<"},
+ {">", "<="},
+ {"<=", ">"},
+ {"AggrEquals", "AggrNotEquals"},
+ {"AggrNotEquals", "AggrEquals"},
+ {"AggrLess", "AggrGreaterOrEqual"},
+ {"AggrGreaterOrEqual", "AggrLess"},
+ {"AggrLessOrEqual", "AggrGreater"},
+ {"AggrGreater", "AggrLessOrEqual"},
+ };
+
auto& arg = node->Head();
const auto it = InverseComparators.find(arg.Content());
- if (InverseComparators.cend() != it && (
+ if (InverseComparators.cend() != it && (
(arg.Content().front() != '<' && arg.Content().front() != '>') ||
(HasTotalOrder(*arg.Head().GetTypeAnn()) && HasTotalOrder(*arg.Tail().GetTypeAnn()))))
{
YQL_CLOG(DEBUG, Core) << node->Content() << " over " << arg.Content();
return ctx.RenameNode(arg, it->second);
- }
-
- return node;
-}
-
+ }
+
+ return node;
+}
+
TExprNode::TPtr OptimizeAnd(const TExprNode::TPtr& node, TExprContext& ctx) {
if (auto opt = OptimizeDups(node, ctx); opt != node) {
return opt;
@@ -369,74 +369,74 @@ TExprNode::TPtr OptimizeAnd(const TExprNode::TPtr& node, TExprContext& ctx) {
return ctx.ChangeChildren(*node, std::move(newChildren));
}
-TExprNode::TPtr CheckIfWorldWithSame(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Child(3U) == node->Child(2U)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches";
- return ctx.NewCallable(node->Pos(), SyncName, {node->HeadPtr(), node->TailPtr()});
- }
-
- return node;
-}
-
-TExprNode::TPtr CheckIfWithSame(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Child(node->ChildrenSize() - 1U) == node->Child(node->ChildrenSize() - 2U)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches.";
- auto children = node->ChildrenList();
- children[children.size() - 3U] = std::move(children.back());
- children.resize(children.size() -2U);
- return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (const auto width = node->ChildrenSize() >> 1U; width > 1U) {
- TNodeSet predicates(width), branches(width);
- for (auto i =0U; i < node->ChildrenSize() - 1U; ++i) {
- predicates.emplace(node->Child(i));
- branches.emplace(node->Child(++i));
- }
-
- if (predicates.size() < width) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with identical predicates.";
- auto children = node->ChildrenList();
- for (auto i = 0U; i < children.size() - 1U;) {
- if (predicates.erase(children[i].Get()))
- i += 2U;
- else
- children.erase(children.cbegin() + i, children.cbegin() + i + 2U);
- }
- return ctx.ChangeChildren(*node, std::move(children));
- }
- if (branches.size() < width) {
- for (auto i = 1U; i < node->ChildrenSize() - 2U; ++++i) {
- if (node->Child(i) == node->Child(i + 2U)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches.";
- auto children = node->ChildrenList();
- auto& prev = children[i - 1U];
- auto& next = children[i + 1U];
- if (prev->IsCallable("Or")) {
- auto many = prev->ChildrenList();
- many.emplace_back(std::move(next));
- prev = ctx.ChangeChildren(*prev, std::move(many));
- } else
- prev = ctx.NewCallable(node->Pos(), "Or", {std::move(prev), std::move(next)});
- children.erase(children.cbegin() + i + 1U, children.cbegin() + i + 3U);
- return ctx.ChangeChildren(*node, std::move(children));
- }
- }
- }
- }
-
- return node;
-}
-
-template <bool Equal, bool Aggr>
-TExprNode::TPtr CheckCompareSame(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (&node->Head() == &node->Tail() && (Aggr || HasTotalOrder(*node->Head().GetTypeAnn()))) {
- YQL_CLOG(DEBUG, Core) << (Equal ? "Equal" : "Unequal") << " '" << node->Content() << "' with same args";
- return MakeBool<Equal>(node->Pos(), ctx);
- }
-
- return node;
-}
+TExprNode::TPtr CheckIfWorldWithSame(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Child(3U) == node->Child(2U)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches";
+ return ctx.NewCallable(node->Pos(), SyncName, {node->HeadPtr(), node->TailPtr()});
+ }
+
+ return node;
+}
+
+TExprNode::TPtr CheckIfWithSame(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Child(node->ChildrenSize() - 1U) == node->Child(node->ChildrenSize() - 2U)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches.";
+ auto children = node->ChildrenList();
+ children[children.size() - 3U] = std::move(children.back());
+ children.resize(children.size() -2U);
+ return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (const auto width = node->ChildrenSize() >> 1U; width > 1U) {
+ TNodeSet predicates(width), branches(width);
+ for (auto i =0U; i < node->ChildrenSize() - 1U; ++i) {
+ predicates.emplace(node->Child(i));
+ branches.emplace(node->Child(++i));
+ }
+
+ if (predicates.size() < width) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with identical predicates.";
+ auto children = node->ChildrenList();
+ for (auto i = 0U; i < children.size() - 1U;) {
+ if (predicates.erase(children[i].Get()))
+ i += 2U;
+ else
+ children.erase(children.cbegin() + i, children.cbegin() + i + 2U);
+ }
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+ if (branches.size() < width) {
+ for (auto i = 1U; i < node->ChildrenSize() - 2U; ++++i) {
+ if (node->Child(i) == node->Child(i + 2U)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with identical branches.";
+ auto children = node->ChildrenList();
+ auto& prev = children[i - 1U];
+ auto& next = children[i + 1U];
+ if (prev->IsCallable("Or")) {
+ auto many = prev->ChildrenList();
+ many.emplace_back(std::move(next));
+ prev = ctx.ChangeChildren(*prev, std::move(many));
+ } else
+ prev = ctx.NewCallable(node->Pos(), "Or", {std::move(prev), std::move(next)});
+ children.erase(children.cbegin() + i + 1U, children.cbegin() + i + 3U);
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+ }
+ }
+ }
+
+ return node;
+}
+
+template <bool Equal, bool Aggr>
+TExprNode::TPtr CheckCompareSame(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (&node->Head() == &node->Tail() && (Aggr || HasTotalOrder(*node->Head().GetTypeAnn()))) {
+ YQL_CLOG(DEBUG, Core) << (Equal ? "Equal" : "Unequal") << " '" << node->Content() << "' with same args";
+ return MakeBool<Equal>(node->Pos(), ctx);
+ }
+
+ return node;
+}
TExprNode::TPtr IfPresentSubsetFields(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
if (3U == node->ChildrenSize() && TCoFilterNullMembers::Match(&node->Head())) {
@@ -454,38 +454,38 @@ TExprNode::TPtr IfPresentSubsetFields(const TExprNode::TPtr& node, TExprContext&
}
return node;
-}
+}
}
-void RegisterCoSimpleCallables2(TCallableOptimizerMap& map) {
- using namespace std::placeholders;
+void RegisterCoSimpleCallables2(TCallableOptimizerMap& map) {
+ using namespace std::placeholders;
- map[SyncName] = std::bind(&SimplifySync, _1, _2);
+ map[SyncName] = std::bind(&SimplifySync, _1, _2);
- map[IfName] = std::bind(&CheckIfWorldWithSame, _1, _2);
+ map[IfName] = std::bind(&CheckIfWorldWithSame, _1, _2);
- map["If"] = std::bind(&CheckIfWithSame, _1, _2);
+ map["If"] = std::bind(&CheckIfWithSame, _1, _2);
- map["Aggregate"] = std::bind(&DeduplicateAggregateSameTraits, _1, _2);
+ map["Aggregate"] = std::bind(&DeduplicateAggregateSameTraits, _1, _2);
- map["Xor"] = std::bind(&OptimizeXor, _1, _2);
- map["Not"] = std::bind(&OptimizeNot, _1, _2);
+ map["Xor"] = std::bind(&OptimizeXor, _1, _2);
+ map["Not"] = std::bind(&OptimizeNot, _1, _2);
map["And"] = std::bind(&OptimizeAnd, _1, _2);
map["Or"] = std::bind(OptimizeDups, _1, _2);
-
- map["Min"] = map["Max"] = std::bind(&OptimizeDups, _1, _2);
- map["AggrMin"] = map["AggrMax"] = map["Coalesce"] = std::bind(&DropAggrOverSame, _1);
+ map["Min"] = map["Max"] = std::bind(&OptimizeDups, _1, _2);
+
+ map["AggrMin"] = map["AggrMax"] = map["Coalesce"] = std::bind(&DropAggrOverSame, _1);
map["StartsWith"] = map["EndsWith"] = std::bind(&CheckCompareSame<true, false>, _1, _2);
-
- map["=="] = map["<="] = map[">="] = std::bind(&CheckCompareSame<true, false>, _1, _2);
- map["!="] = map["<"] = map[">"] = std::bind(&CheckCompareSame<false, false>, _1, _2);
- map["AggrEquals"] = map["AggrLessOrEqual"] = map["AggrGreaterOrEqual"] = std::bind(&CheckCompareSame<true, true>, _1, _2);
- map["AggrNotEquals"] = map["AggrLess"] = map["AggrGreater"] = std::bind(&CheckCompareSame<false, true>, _1, _2);
+ map["=="] = map["<="] = map[">="] = std::bind(&CheckCompareSame<true, false>, _1, _2);
+ map["!="] = map["<"] = map[">"] = std::bind(&CheckCompareSame<false, false>, _1, _2);
+
+ map["AggrEquals"] = map["AggrLessOrEqual"] = map["AggrGreaterOrEqual"] = std::bind(&CheckCompareSame<true, true>, _1, _2);
+ map["AggrNotEquals"] = map["AggrLess"] = map["AggrGreater"] = std::bind(&CheckCompareSame<false, true>, _1, _2);
map["IfPresent"] = std::bind(&IfPresentSubsetFields, _1, _2, _3);
}
diff --git a/ydb/library/yql/core/common_opt/yql_co_transformer.cpp b/ydb/library/yql/core/common_opt/yql_co_transformer.cpp
index 6b9110e325..8a98716eac 100644
--- a/ydb/library/yql/core/common_opt/yql_co_transformer.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_transformer.cpp
@@ -28,7 +28,7 @@ public:
void Rewind() final;
private:
IGraphTransformer::TStatus DoTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx,
- const TCallableOptimizerMap& callables, TProcessedNodesSet& processedNodes,
+ const TCallableOptimizerMap& callables, TProcessedNodesSet& processedNodes,
bool withParents);
IGraphTransformer::TStatus DoTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx,
@@ -96,7 +96,7 @@ void TCommonOptTransformer::Rewind() {
IGraphTransformer::TStatus TCommonOptTransformer::DoTransform(
const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx,
- const TCallableOptimizerMap& callables,
+ const TCallableOptimizerMap& callables,
TProcessedNodesSet& processedNodes, bool withParents)
{
TOptimizeExprSettings settings(TypeCtx);
@@ -117,7 +117,7 @@ IGraphTransformer::TStatus TCommonOptTransformer::DoTransform(
}
return OptimizeExpr(input, output, [&callables, &optCtx, defaultOpt](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
- const auto rule = callables.find(node->Content());
+ const auto rule = callables.find(node->Content());
TExprNode::TPtr result = node;
if (rule != callables.cend()) {
result = (rule->second)(node, ctx, optCtx);
@@ -147,9 +147,9 @@ IGraphTransformer::TStatus TCommonOptTransformer::DoTransform(const TExprNode::T
},
[&callables, &toOptimize, &ctx, &optCtx](const TExprNode::TPtr& node) {
if (toOptimize.empty()) {
- const auto rule = callables.find(node->Content());
- if (callables.cend() != rule) {
- (rule->second)(node, toOptimize, ctx, optCtx);
+ const auto rule = callables.find(node->Content());
+ if (callables.cend() != rule) {
+ (rule->second)(node, toOptimize, ctx, optCtx);
}
}
return toOptimize.empty();
diff --git a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h
index 593b58c749..01cc777118 100644
--- a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h
+++ b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.h
@@ -15,7 +15,7 @@ class TCoAtom : public NGenerated::TCoAtomStub<TExprBase> {
public:
explicit TCoAtom(const TExprNode* node)
: TCoAtomStub(node) {}
-
+
explicit TCoAtom(const TExprNode::TPtr& node)
: TCoAtomStub(node) {}
@@ -36,12 +36,12 @@ class TCoArguments : public NGenerated::TCoArgumentsStub<TExprBase> {
public:
explicit TCoArguments(const TExprNode* node)
: TCoArgumentsStub(node) {}
-
+
explicit TCoArguments(const TExprNode::TPtr& node)
: TCoArgumentsStub(node) {}
TCoArgument Arg(size_t index) const { return TCoArgument(Ref().ChildPtr(index)); }
- size_t Size() const { return Ref().ChildrenSize(); }
+ size_t Size() const { return Ref().ChildrenSize(); }
TChildIterator<TCoArgument> begin() const { return TChildIterator<TCoArgument>(*this); }
TChildIterator<TCoArgument> end() const { return TChildIterator<TCoArgument>(); }
@@ -148,7 +148,7 @@ public:
TNodeBuilder<TParent, TCoLambda>& Args(const TCoArgument& node) {
Y_VERIFY_DEBUG(!this->ArgsHolder.IsValid());
- auto argsNode = this->Ctx.NewArguments(this->Pos, { node.Ptr() });
+ auto argsNode = this->Ctx.NewArguments(this->Pos, { node.Ptr() });
this->ArgsHolder = TCoArguments(argsNode);
return *this;
@@ -174,7 +174,7 @@ public:
ArgsMap->emplace(argName, TExprBase(argNode));
}
- auto argsNode = this->Ctx.NewArguments(this->Pos, std::move(argNodes));
+ auto argsNode = this->Ctx.NewArguments(this->Pos, std::move(argNodes));
this->ArgsHolder = TCoArguments(argsNode);
return *this;
}
@@ -203,7 +203,7 @@ public:
}
TCoLambda DoBuild() {
- auto node = this->Ctx.NewLambda(this->Pos, this->ArgsHolder.Cast().Ptr(), this->BodyHolder.Cast().Ptr());
+ auto node = this->Ctx.NewLambda(this->Pos, this->ArgsHolder.Cast().Ptr(), this->BodyHolder.Cast().Ptr());
return TCoLambda(node);
}
@@ -218,7 +218,7 @@ class TExprApplier : public TExprBase {
template<typename TParent, typename TNode>
friend class TNodeBuilder;
- TExprApplier(const TExprNode::TPtr& node)
+ TExprApplier(const TExprNode::TPtr& node)
: TExprBase(node) {}
TExprApplier(const TExprBase node)
@@ -256,7 +256,7 @@ public:
TParent& Build() {
YQL_ENSURE(Body);
- return BuildFunc(TExprApplier(Body.Cast().Ptr()));
+ return BuildFunc(TExprApplier(Body.Cast().Ptr()));
}
typename TParent::ResultType Done() {
@@ -344,14 +344,14 @@ public:
private:
void DoApply(TExprBase applyFrom, TExprBase applyTo) {
TExprNodeBuilder builder(this->Pos, this->Ctx, [this] (const TStringBuf& argName) {
- return GetArgFunc(argName).Ptr();
+ return GetArgFunc(argName).Ptr();
});
- auto args = Args.IsValid() ? Args.Cast().Ptr() : nullptr;
+ auto args = Args.IsValid() ? Args.Cast().Ptr() : nullptr;
Body = builder
- .ApplyPartial(std::move(args), Body.Cast().Ptr())
- .WithNode(applyFrom.Ref(), applyTo.Ptr())
+ .ApplyPartial(std::move(args), Body.Cast().Ptr())
+ .WithNode(applyFrom.Ref(), applyTo.Ptr())
.Seal().Build();
}
diff --git a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.json b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.json
index 21aef2e087..edfcaa1530 100644
--- a/ydb/library/yql/core/expr_nodes/yql_expr_nodes.json
+++ b/ydb/library/yql/core/expr_nodes/yql_expr_nodes.json
@@ -183,11 +183,11 @@
"Match": {"Type": "Callable", "Name": "OrderedMap"}
},
{
- "Name": "TCoMultiMap",
- "Base": "TCoMapBase",
- "Match": {"Type": "Callable", "Name": "MultiMap"}
- },
- {
+ "Name": "TCoMultiMap",
+ "Base": "TCoMapBase",
+ "Match": {"Type": "Callable", "Name": "MultiMap"}
+ },
+ {
"Name": "TCoLMap",
"Base": "TCoMapBase",
"Match": {"Type": "Callable", "Name": "LMap"}
@@ -203,16 +203,16 @@
"Match": {"Type": "Callable", "Name": "NarrowMap"}
},
{
- "Name": "TCoNarrowFlatMap",
- "Base": "TCoMapBase",
- "Match": {"Type": "Callable", "Name": "NarrowFlatMap"}
- },
- {
- "Name": "TCoNarrowMultiMap",
- "Base": "TCoMapBase",
- "Match": {"Type": "Callable", "Name": "NarrowMultiMap"}
- },
- {
+ "Name": "TCoNarrowFlatMap",
+ "Base": "TCoMapBase",
+ "Match": {"Type": "Callable", "Name": "NarrowFlatMap"}
+ },
+ {
+ "Name": "TCoNarrowMultiMap",
+ "Base": "TCoMapBase",
+ "Match": {"Type": "Callable", "Name": "NarrowMultiMap"}
+ },
+ {
"Name": "TCoWideMap",
"Base": "TCoMapBase",
"Match": {"Type": "Callable", "Name": "WideMap"}
@@ -222,8 +222,8 @@
"Base": "TCoInputBase",
"Match": {"Type": "CallableBase"},
"Children": [
- {"Index": 1, "Name": "Lambda", "Type": "TCoLambda"},
- {"Index": 2, "Name": "Limit", "Type": "TExprBase", "Optional": true}
+ {"Index": 1, "Name": "Lambda", "Type": "TCoLambda"},
+ {"Index": 2, "Name": "Limit", "Type": "TExprBase", "Optional": true}
]
},
{
@@ -247,7 +247,7 @@
"Match": {"Type": "CallableBase"},
"Builder": {"Generate": "None"},
"Children": [
- {"Index": 1, "Name": "Members", "Type": "TCoAtomList", "Optional": true}
+ {"Index": 1, "Name": "Members", "Type": "TCoAtomList", "Optional": true}
]
},
{
@@ -261,25 +261,25 @@
"Match": {"Type": "Callable", "Name": "SkipNullMembers"}
},
{
- "Name": "TCoFilterNullElementsBase",
- "Base": "TCoInputBase",
- "Match": {"Type": "CallableBase"},
- "Builder": {"Generate": "None"},
- "Children": [
- {"Index": 1, "Name": "Elements", "Type": "TCoAtomList", "Optional": true}
- ]
- },
- {
- "Name": "TCoFilterNullElements",
- "Base": "TCoFilterNullElementsBase",
- "Match": {"Type": "Callable", "Name": "FilterNullElements"}
- },
- {
- "Name": "TCoSkipNullElements",
- "Base": "TCoFilterNullElementsBase",
- "Match": {"Type": "Callable", "Name": "SkipNullElements"}
- },
- {
+ "Name": "TCoFilterNullElementsBase",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "CallableBase"},
+ "Builder": {"Generate": "None"},
+ "Children": [
+ {"Index": 1, "Name": "Elements", "Type": "TCoAtomList", "Optional": true}
+ ]
+ },
+ {
+ "Name": "TCoFilterNullElements",
+ "Base": "TCoFilterNullElementsBase",
+ "Match": {"Type": "Callable", "Name": "FilterNullElements"}
+ },
+ {
+ "Name": "TCoSkipNullElements",
+ "Base": "TCoFilterNullElementsBase",
+ "Match": {"Type": "Callable", "Name": "SkipNullElements"}
+ },
+ {
"Name": "TCoRemoveSystemMembers",
"Base": "TCoInputBase",
"Match": {"Type": "Callable", "Name": "RemoveSystemMembers"}
@@ -348,9 +348,9 @@
"Match": {"Type": "Callable", "Name": "Head"}
},
{
- "Name": "TCoLast",
+ "Name": "TCoLast",
"Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Last"}
+ "Match": {"Type": "Callable", "Name": "Last"}
},
{
"Name": "TCoUnorderedBase",
@@ -533,11 +533,11 @@
"Match": {"Type": "Callable", "Name": "PartitionByKey"}
},
{
- "Name": "TCoPartitionsByKeys",
+ "Name": "TCoPartitionsByKeys",
"Base": "TCoPartitionByKeyBase",
"Match": {"Type": "Callable", "Name": "PartitionsByKeys"}
- },
- {
+ },
+ {
"Name": "TCoSortTraits",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "SortTraits"},
@@ -621,15 +621,15 @@
]
},
{
- "Name": "TCoChain1Map",
- "Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Chain1Map"},
- "Children": [
- {"Index": 1, "Name": "InitHandler", "Type": "TCoLambda"},
- {"Index": 2, "Name": "UpdateHandler", "Type": "TCoLambda"}
- ]
- },
- {
+ "Name": "TCoChain1Map",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "Callable", "Name": "Chain1Map"},
+ "Children": [
+ {"Index": 1, "Name": "InitHandler", "Type": "TCoLambda"},
+ {"Index": 2, "Name": "UpdateHandler", "Type": "TCoLambda"}
+ ]
+ },
+ {
"Name": "TCoZip",
"VarArgBase": "TExprBase",
"Match": {"Type": "Callable", "Name": "Zip"}
@@ -982,15 +982,15 @@
]
},
{
- "Name": "TCoSqueezeToList",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "SqueezeToList"},
- "Children": [
- {"Index": 0, "Name": "Stream", "Type": "TExprBase"},
- {"Index": 1, "Name": "Limit", "Type": "TCoLambda", "Optional": true}
- ]
- },
- {
+ "Name": "TCoSqueezeToList",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "SqueezeToList"},
+ "Children": [
+ {"Index": 0, "Name": "Stream", "Type": "TExprBase"},
+ {"Index": 1, "Name": "Limit", "Type": "TCoLambda", "Optional": true}
+ ]
+ },
+ {
"Name": "TCoDictKeys",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "DictKeys"},
@@ -1101,42 +1101,42 @@
"Match": {"Type": "Callable", "Name": "!="}
},
{
- "Name": "TCoAggrEqual",
- "Base": "TCoCompare",
- "Match": {"Type": "Callable", "Name": "AggrEquals"}
- },
- {
- "Name": "TCoAggrNotEqual",
- "Base": "TCoCompare",
- "Match": {"Type": "Callable", "Name": "AggrNotEquals"}
- },
- {
- "Name": "TCoCmpStartsWith",
- "Base": "TCoCompare",
- "Match": {"Type": "Callable", "Name": "StartsWith"}
- },
- {
- "Name": "TCoCmpEndsWith",
- "Base": "TCoCompare",
- "Match": {"Type": "Callable", "Name": "EndsWith"}
- },
- {
- "Name": "TCoInc",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "Inc"},
- "Children": [
- {"Index": 0, "Name": "Value", "Type": "TExprBase"}
- ]
- },
- {
- "Name": "TCoDec",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "Dec"},
- "Children": [
- {"Index": 0, "Name": "Value", "Type": "TExprBase"}
- ]
- },
- {
+ "Name": "TCoAggrEqual",
+ "Base": "TCoCompare",
+ "Match": {"Type": "Callable", "Name": "AggrEquals"}
+ },
+ {
+ "Name": "TCoAggrNotEqual",
+ "Base": "TCoCompare",
+ "Match": {"Type": "Callable", "Name": "AggrNotEquals"}
+ },
+ {
+ "Name": "TCoCmpStartsWith",
+ "Base": "TCoCompare",
+ "Match": {"Type": "Callable", "Name": "StartsWith"}
+ },
+ {
+ "Name": "TCoCmpEndsWith",
+ "Base": "TCoCompare",
+ "Match": {"Type": "Callable", "Name": "EndsWith"}
+ },
+ {
+ "Name": "TCoInc",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "Inc"},
+ "Children": [
+ {"Index": 0, "Name": "Value", "Type": "TExprBase"}
+ ]
+ },
+ {
+ "Name": "TCoDec",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "Dec"},
+ "Children": [
+ {"Index": 0, "Name": "Value", "Type": "TExprBase"}
+ ]
+ },
+ {
"Name": "TCoNot",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "Not"},
@@ -1146,20 +1146,20 @@
},
{
"Name": "TCoAnd",
- "VarArgBase": "TExprBase",
+ "VarArgBase": "TExprBase",
"Match": {"Type": "Callable", "Name": "And"}
},
{
"Name": "TCoOr",
- "VarArgBase": "TExprBase",
+ "VarArgBase": "TExprBase",
"Match": {"Type": "Callable", "Name": "Or"}
},
{
- "Name": "TCoXor",
- "VarArgBase": "TExprBase",
- "Match": {"Type": "Callable", "Name": "Xor"}
- },
- {
+ "Name": "TCoXor",
+ "VarArgBase": "TExprBase",
+ "Match": {"Type": "Callable", "Name": "Xor"}
+ },
+ {
"Name": "TCoBinaryArithmetic",
"Base": "TCallable",
"Match": {"Type": "CallableBase"},
@@ -1170,11 +1170,11 @@
]
},
{
- "Name": "TCoAggrAdd",
- "Base": "TCoBinaryArithmetic",
- "Match": {"Type": "Callable", "Name": "AggrAdd"}
- },
- {
+ "Name": "TCoAggrAdd",
+ "Base": "TCoBinaryArithmetic",
+ "Match": {"Type": "Callable", "Name": "AggrAdd"}
+ },
+ {
"Name": "TCoMinus",
"Base": "TCoBinaryArithmetic",
"Match": {"Type": "Callable", "Name": "-"}
@@ -1261,16 +1261,16 @@
]
},
{
- "Name": "TCoIfStrict",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "IfStrict"},
- "Children": [
- {"Index": 0, "Name": "Predicate", "Type": "TExprBase"},
- {"Index": 1, "Name": "ThenValue", "Type": "TExprBase"},
- {"Index": 2, "Name": "ElseValue", "Type": "TExprBase"}
- ]
- },
- {
+ "Name": "TCoIfStrict",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "IfStrict"},
+ "Children": [
+ {"Index": 0, "Name": "Predicate", "Type": "TExprBase"},
+ {"Index": 1, "Name": "ThenValue", "Type": "TExprBase"},
+ {"Index": 2, "Name": "ElseValue", "Type": "TExprBase"}
+ ]
+ },
+ {
"Name": "TCoIfPresent",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "IfPresent"},
@@ -1373,8 +1373,8 @@
{"Index": 1, "Name": "RightDict", "Type": "TExprBase"},
{"Index": 2, "Name": "JoinKind", "Type": "TCoAtom"},
{"Index": 3, "Name": "LeftKeysColumns", "Type": "TCoAtomList"},
- {"Index": 4, "Name": "LeftRenames", "Type": "TCoAtomList"},
- {"Index": 5, "Name": "RightRenames", "Type": "TCoAtomList"}
+ {"Index": 4, "Name": "LeftRenames", "Type": "TCoAtomList"},
+ {"Index": 5, "Name": "RightRenames", "Type": "TCoAtomList"}
]
},
{
@@ -1384,8 +1384,8 @@
"Children": [
{"Index": 0, "Name": "LeftInput", "Type": "TExprBase"},
{"Index": 1, "Name": "RightInput", "Type": "TExprBase"},
- {"Index": 2, "Name": "JoinKind", "Type": "TCoAtom"},
- {"Index": 3, "Name": "Flags", "Type": "TCoAtomList", "Optional": true}
+ {"Index": 2, "Name": "JoinKind", "Type": "TCoAtom"},
+ {"Index": 3, "Name": "Flags", "Type": "TCoAtomList", "Optional": true}
]
},
{
@@ -1430,17 +1430,17 @@
"Match": {"Type": "Callable", "Name": "TopSort"}
},
{
- "Name": "TCoKeepTop",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "KeepTop"},
- "Children": [
- {"Index": 0, "Name": "Count", "Type": "TExprBase"},
- {"Index": 1, "Name": "List", "Type": "TExprBase"},
- {"Index": 2, "Name": "Item", "Type": "TExprBase"},
- {"Index": 3, "Name": "SortDirections", "Type": "TExprBase"},
- {"Index": 4, "Name": "KeySelectorLambda", "Type": "TCoLambda"}
- ]
- }, {
+ "Name": "TCoKeepTop",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "KeepTop"},
+ "Children": [
+ {"Index": 0, "Name": "Count", "Type": "TExprBase"},
+ {"Index": 1, "Name": "List", "Type": "TExprBase"},
+ {"Index": 2, "Name": "Item", "Type": "TExprBase"},
+ {"Index": 3, "Name": "SortDirections", "Type": "TExprBase"},
+ {"Index": 4, "Name": "KeySelectorLambda", "Type": "TCoLambda"}
+ ]
+ }, {
"Name": "TCoAscending",
"Base": "TCoInputBase",
"Match": {"Type": "Callable", "Name": "Ascending"}
@@ -1641,7 +1641,7 @@
{"Index": 2, "Name": "InitHandler", "Type": "TCoLambda"},
{"Index": 3, "Name": "UpdateHandler", "Type": "TCoLambda"},
{"Index": 4, "Name": "FinishHandler", "Type": "TCoLambda"},
- {"Index": 5, "Name": "MemLimit", "Type": "TCoAtom", "Optional": true}
+ {"Index": 5, "Name": "MemLimit", "Type": "TCoAtom", "Optional": true}
]
},
{
@@ -1675,26 +1675,26 @@
]
},
{
- "Name": "TCoCondense",
- "Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Condense"},
- "Children": [
- {"Index": 1, "Name": "State", "Type": "TExprBase"},
- {"Index": 2, "Name": "SwitchHandler", "Type": "TCoLambda"},
- {"Index": 3, "Name": "UpdateHandler", "Type": "TCoLambda"}
- ]
- },
- {
- "Name": "TCoCondense1",
- "Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Condense1"},
- "Children": [
- {"Index": 1, "Name": "InitHandler", "Type": "TCoLambda"},
- {"Index": 2, "Name": "SwitchHandler", "Type": "TCoLambda"},
- {"Index": 3, "Name": "UpdateHandler", "Type": "TCoLambda"}
- ]
- },
- {
+ "Name": "TCoCondense",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "Callable", "Name": "Condense"},
+ "Children": [
+ {"Index": 1, "Name": "State", "Type": "TExprBase"},
+ {"Index": 2, "Name": "SwitchHandler", "Type": "TCoLambda"},
+ {"Index": 3, "Name": "UpdateHandler", "Type": "TCoLambda"}
+ ]
+ },
+ {
+ "Name": "TCoCondense1",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "Callable", "Name": "Condense1"},
+ "Children": [
+ {"Index": 1, "Name": "InitHandler", "Type": "TCoLambda"},
+ {"Index": 2, "Name": "SwitchHandler", "Type": "TCoLambda"},
+ {"Index": 3, "Name": "UpdateHandler", "Type": "TCoLambda"}
+ ]
+ },
+ {
"Name": "TCoTablePropBase",
"Base": "TCallable",
"Match": {"Type": "CallableBase"},
@@ -1748,11 +1748,11 @@
]
},
{
- "Name": "TCoDiscard",
- "Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Discard"}
- },
- {
+ "Name": "TCoDiscard",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "Callable", "Name": "Discard"}
+ },
+ {
"Name": "TCoToStream",
"Base": "TFreeArgCallable",
"Match": {"Type": "Callable", "Name": "ToStream"},
@@ -1771,24 +1771,24 @@
"Match": {"Type": "Callable", "Name": "FromFlow"}
},
{
- "Name": "TCoBitCast",
+ "Name": "TCoBitCast",
"Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "BitCast"},
+ "Match": {"Type": "Callable", "Name": "BitCast"},
"Children": [
{"Index": 0, "Name": "Value", "Type": "TExprBase"},
{"Index": 1, "Name": "Type", "Type": "TCoAtom"}
]
},
{
- "Name": "TCoSafeCast",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "SafeCast"},
- "Children": [
- {"Index": 0, "Name": "Value", "Type": "TExprBase"},
+ "Name": "TCoSafeCast",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "SafeCast"},
+ "Children": [
+ {"Index": 0, "Name": "Value", "Type": "TExprBase"},
{"Index": 1, "Name": "Type", "Type": "TExprBase"}
- ]
- },
- {
+ ]
+ },
+ {
"Name": "TCoStrictCast",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "StrictCast"},
@@ -1864,16 +1864,16 @@
]
},
{
- "Name": "TCoChopper",
- "Base": "TCoInputBase",
- "Match": {"Type": "Callable", "Name": "Chopper"},
- "Children": [
- {"Index": 1, "Name": "KeyExtractor", "Type": "TCoLambda"},
- {"Index": 2, "Name": "GroupSwitch", "Type": "TCoLambda"},
- {"Index": 3, "Name": "Handler", "Type": "TCoLambda"}
- ]
- },
- {
+ "Name": "TCoChopper",
+ "Base": "TCoInputBase",
+ "Match": {"Type": "Callable", "Name": "Chopper"},
+ "Children": [
+ {"Index": 1, "Name": "KeyExtractor", "Type": "TCoLambda"},
+ {"Index": 2, "Name": "GroupSwitch", "Type": "TCoLambda"},
+ {"Index": 3, "Name": "Handler", "Type": "TCoLambda"}
+ ]
+ },
+ {
"Name": "TCoVariantItem",
"Base": "TCallable",
"Match": {"Type": "Callable", "Name": "VariantItem"},
diff --git a/ydb/library/yql/core/expr_nodes_gen/gen/ya.make b/ydb/library/yql/core/expr_nodes_gen/gen/ya.make
index 980baa62e1..751fb55dee 100644
--- a/ydb/library/yql/core/expr_nodes_gen/gen/ya.make
+++ b/ydb/library/yql/core/expr_nodes_gen/gen/ya.make
@@ -1,4 +1,4 @@
-PY3_PROGRAM()
+PY3_PROGRAM()
OWNER(
spuchin
diff --git a/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h b/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h
index 099d406f31..0974e8d2d3 100644
--- a/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h
+++ b/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h
@@ -20,75 +20,75 @@ class TMaybeNode {};
class TExprBase {
public:
- explicit TExprBase(const TExprNode* node)
- : Raw_(node)
- {
+ explicit TExprBase(const TExprNode* node)
+ : Raw_(node)
+ {
YQL_ENSURE(node);
- }
-
- explicit TExprBase(TExprNode::TPtr&& node)
- : Raw_(node.Get()), Node(std::move(node))
- {
- YQL_ENSURE(Raw_);
- }
-
- explicit TExprBase(const TExprNode::TPtr& node)
- : Raw_(node.Get()), Node(node)
+ }
+
+ explicit TExprBase(TExprNode::TPtr&& node)
+ : Raw_(node.Get()), Node(std::move(node))
+ {
+ YQL_ENSURE(Raw_);
+ }
+
+ explicit TExprBase(const TExprNode::TPtr& node)
+ : Raw_(node.Get()), Node(node)
{
YQL_ENSURE(node);
}
- const TExprNode* Raw() const {
- return Raw_;
- }
+ const TExprNode* Raw() const {
+ return Raw_;
+ }
- TExprNode::TPtr Ptr() const {
- YQL_ENSURE(Node);
- return Node;
+ TExprNode::TPtr Ptr() const {
+ YQL_ENSURE(Node);
+ return Node;
+ }
+
+ const TExprNode& Ref() const {
+ return *Raw_;
}
- const TExprNode& Ref() const {
- return *Raw_;
- }
-
TExprBase NonOwning() const {
return TExprBase(Raw_);
}
TPositionHandle Pos() const {
- return Raw_->Pos();
+ return Raw_->Pos();
}
template<typename TNode>
TMaybeNode<TNode> Maybe() const {
- return Cast<TMaybeNode<TNode>>();
+ return Cast<TMaybeNode<TNode>>();
}
template<typename TNode>
TNode Cast() const {
- return Node ? TNode(Node) : TNode(Raw_);
+ return Node ? TNode(Node) : TNode(Raw_);
}
private:
- const TExprNode* Raw_;
- TExprNode::TPtr Node;
+ const TExprNode* Raw_;
+ TExprNode::TPtr Node;
};
template<>
class TMaybeNode<TExprBase> {
public:
- TMaybeNode(const TExprNode* node = nullptr)
- : Raw_(node) {}
+ TMaybeNode(const TExprNode* node = nullptr)
+ : Raw_(node) {}
+
+ TMaybeNode(const TExprNode::TPtr& node)
+ : Raw_(node.Get()), Node(node) {}
- TMaybeNode(const TExprNode::TPtr& node)
- : Raw_(node.Get()), Node(node) {}
-
TMaybeNode(const TExprBase& node)
- : Raw_(node.Raw()), Node(node.Ptr()) {}
+ : Raw_(node.Raw()), Node(node.Ptr()) {}
- const TExprNode& Ref() const {
+ const TExprNode& Ref() const {
YQL_ENSURE(IsValid());
- return *Raw_;
+ return *Raw_;
}
const TExprNode* Raw() const {
@@ -96,32 +96,32 @@ public:
}
bool IsValid() const {
- return Raw_ != nullptr;
+ return Raw_ != nullptr;
}
- explicit operator bool() const {
+ explicit operator bool() const {
return IsValid();
}
template<typename TNode>
TMaybeNode<TNode> Maybe() const {
- return Node ? TMaybeNode<TNode>(Node) : TMaybeNode<TNode>(Raw_);
+ return Node ? TMaybeNode<TNode>(Node) : TMaybeNode<TNode>(Raw_);
}
template<typename TNode>
TNode Cast() const {
YQL_ENSURE(IsValid());
- return Node ? TNode(Node) : TNode(Raw_);
+ return Node ? TNode(Node) : TNode(Raw_);
}
TExprBase Cast() const {
YQL_ENSURE(IsValid());
- return Node ? TExprBase(Node) : TExprBase(Raw_);
+ return Node ? TExprBase(Node) : TExprBase(Raw_);
}
private:
- const TExprNode* Raw_;
- TExprNode::TPtr Node;
+ const TExprNode* Raw_;
+ TExprNode::TPtr Node;
};
template<typename TNode>
@@ -178,7 +178,7 @@ private:
CurNode = CurIt == EndIt ? nullptr : *CurIt;
}
- TExprNode::TPtr CurNode;
+ TExprNode::TPtr CurNode;
TExprNode::TListType::const_iterator CurIt;
TExprNode::TListType::const_iterator EndIt;
};
@@ -186,43 +186,43 @@ private:
template<typename TItem>
class TListBase : public TExprBase {
public:
- TListBase(const TExprNode* node)
+ TListBase(const TExprNode* node)
: TExprBase(node)
{
YQL_ENSURE(Match(node));
}
- TListBase(const TExprNode::TPtr& node)
- : TExprBase(node)
- {
+ TListBase(const TExprNode::TPtr& node)
+ : TExprBase(node)
+ {
YQL_ENSURE(Match(node.Get()));
- }
+ }
- TItem Item(size_t index) const { return TItem(Ref().ChildPtr(index)); }
- size_t Size() const { return Ref().ChildrenSize(); }
+ TItem Item(size_t index) const { return TItem(Ref().ChildPtr(index)); }
+ size_t Size() const { return Ref().ChildrenSize(); }
bool Empty() const { return Size() == 0; }
TChildIterator<TItem> begin() const { return TChildIterator<TItem>(*this); }
TChildIterator<TItem> end() const { return TChildIterator<TItem>(); }
public:
- static bool Match(const TExprNode* node) {
- return node && node->IsList();
+ static bool Match(const TExprNode* node) {
+ return node && node->IsList();
}
};
template<typename TItem>
class TMaybeNode<TListBase<TItem>> : public TMaybeNode<TExprBase> {
public:
- TMaybeNode(const TExprNode* node)
- : TMaybeNode<TExprBase>(node && TListBase<TItem>::Match(node) ? node : nullptr) {}
-
- TMaybeNode(const TExprNode::TPtr& node)
- : TMaybeNode<TExprBase>(node && TListBase<TItem>::Match(node.Get()) ? node : TExprNode::TPtr()) {}
+ TMaybeNode(const TExprNode* node)
+ : TMaybeNode<TExprBase>(node && TListBase<TItem>::Match(node) ? node : nullptr) {}
+
+ TMaybeNode(const TExprNode::TPtr& node)
+ : TMaybeNode<TExprBase>(node && TListBase<TItem>::Match(node.Get()) ? node : TExprNode::TPtr()) {}
TListBase<TItem> Cast() const {
YQL_ENSURE(IsValid());
- return TMaybeNode<TExprBase>::Cast().template Cast<TListBase<TItem>>();
+ return TMaybeNode<TExprBase>::Cast().template Cast<TListBase<TItem>>();
}
TMaybeNode<TItem> Item(size_t index) const {
@@ -230,36 +230,36 @@ public:
return TMaybeNode<TItem>();
}
- auto list = Cast();
+ auto list = Cast();
if (index >= list.Size()) {
return TMaybeNode<TItem>();
}
- return TMaybeNode<TItem>(Ref().ChildPtr(index));
+ return TMaybeNode<TItem>(Ref().ChildPtr(index));
}
};
class TCallable : public TExprBase {
public:
- explicit TCallable(const TExprNode* node)
+ explicit TCallable(const TExprNode* node)
: TExprBase(node)
{
YQL_ENSURE(Match(node));
}
- explicit TCallable(const TExprNode::TPtr& node)
- : TExprBase(node)
- {
+ explicit TCallable(const TExprNode::TPtr& node)
+ : TExprBase(node)
+ {
YQL_ENSURE(Match(node.Get()));
- }
-
+ }
+
TStringBuf CallableName() const {
- return Ref().Content();
+ return Ref().Content();
}
public:
- static bool Match(const TExprNode* node) {
- return node && node->IsCallable();
+ static bool Match(const TExprNode* node) {
+ return node && node->IsCallable();
}
};
@@ -267,17 +267,17 @@ template<>
class TMaybeNode<TCallable> : public TMaybeNode<TExprBase> {
public:
TMaybeNode(const TExprNode* node = nullptr)
- : TMaybeNode<TExprBase>(node && TCallable::Match(node) ? node : nullptr) {}
-
+ : TMaybeNode<TExprBase>(node && TCallable::Match(node) ? node : nullptr) {}
+
TMaybeNode(const TExprNode::TPtr& node)
- : TMaybeNode<TExprBase>(node && TCallable::Match(node.Get()) ? node : TExprNode::TPtr()) {}
+ : TMaybeNode<TExprBase>(node && TCallable::Match(node.Get()) ? node : TExprNode::TPtr()) {}
TMaybeNode(const TCallable& node)
: TMaybeNode(node.Ptr()) {}
TCallable Cast() const {
YQL_ENSURE(IsValid());
- return TMaybeNode<TExprBase>::Cast().Cast<TCallable>();
+ return TMaybeNode<TExprBase>::Cast().Cast<TCallable>();
}
};
@@ -343,12 +343,12 @@ public:
class TArgs
{
public:
- TArgs(const TExprBase& node, size_t startIndex)
+ TArgs(const TExprBase& node, size_t startIndex)
: Node(node)
, StartIndex(startIndex) {}
- TExprBase Get(size_t index) const { return TExprBase(Node.Ref().ChildPtr(index)); }
- size_t Count() const { return Node.Ref().ChildrenSize(); }
+ TExprBase Get(size_t index) const { return TExprBase(Node.Ref().ChildPtr(index)); }
+ size_t Count() const { return Node.Ref().ChildrenSize(); }
TChildIterator<TExprBase> begin() const { return TChildIterator<TExprBase>(Node, StartIndex); }
TChildIterator<TExprBase> end() const { return TChildIterator<TExprBase>(); }
@@ -360,43 +360,43 @@ private:
template<const size_t FixedArgsCount>
class TFreeArgCallable : public TCallable {
public:
- explicit TFreeArgCallable(const TExprNode* node)
+ explicit TFreeArgCallable(const TExprNode* node)
: TCallable(node)
{
YQL_ENSURE(Match(node));
}
- explicit TFreeArgCallable(const TExprNode::TPtr& node)
- : TCallable(node)
- {
+ explicit TFreeArgCallable(const TExprNode::TPtr& node)
+ : TCallable(node)
+ {
YQL_ENSURE(Match(node.Get()));
- }
-
+ }
+
TArgs Args() const { return TArgs(*this, 0); }
TArgs FreeArgs() const { return TArgs(*this, FixedArgsCount); }
TExprBase Arg(size_t index) const { return TArgs(*this, 0).Get(index); }
- static bool Match(const TExprNode* node) {
- return node && node->IsCallable() && node->ChildrenSize() >= FixedArgsCount;
+ static bool Match(const TExprNode* node) {
+ return node && node->IsCallable() && node->ChildrenSize() >= FixedArgsCount;
}
};
template<const size_t FixedArgsCount>
class TMaybeNode<TFreeArgCallable<FixedArgsCount>> : public TMaybeNode<TExprBase> {
public:
- TMaybeNode(const TExprNode* node)
- : TMaybeNode<TExprBase>(node && TFreeArgCallable<FixedArgsCount>::Match(node) ? node : nullptr) {}
-
+ TMaybeNode(const TExprNode* node)
+ : TMaybeNode<TExprBase>(node && TFreeArgCallable<FixedArgsCount>::Match(node) ? node : nullptr) {}
+
TMaybeNode(const TExprNode::TPtr& node)
- : TMaybeNode<TExprBase>(node && TFreeArgCallable<FixedArgsCount>::Match(node.Get()) ? node : TExprNode::TPtr()) {}
+ : TMaybeNode<TExprBase>(node && TFreeArgCallable<FixedArgsCount>::Match(node.Get()) ? node : TExprNode::TPtr()) {}
TMaybeNode(const TExprBase& node)
- : TMaybeNode(node) {}
+ : TMaybeNode(node) {}
TFreeArgCallable<FixedArgsCount> Cast() const {
YQL_ENSURE(IsValid());
- return TMaybeNode<TExprBase>::Cast().template Cast<TFreeArgCallable<FixedArgsCount>>();
+ return TMaybeNode<TExprBase>::Cast().template Cast<TFreeArgCallable<FixedArgsCount>>();
}
};
@@ -474,7 +474,7 @@ public:
}
TNodeBuilder<TParent, TDerived>& Add(const TStringBuf& argName) {
- return Add(TExprBase(this->GetArgFunc(argName)));
+ return Add(TExprBase(this->GetArgFunc(argName)));
}
template <typename T, typename = std::enable_if_t<!std::is_same<T, TExprBase>::value
@@ -543,7 +543,7 @@ public:
typedef TNode ResultType;
void SetValue(const TNode& node) {
- Node = node.template Maybe<TNode>();
+ Node = node.template Maybe<TNode>();
}
TNode Value() const {
diff --git a/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.jnj b/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.jnj
index 302f5251b1..4b5733693f 100644
--- a/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.jnj
+++ b/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.jnj
@@ -19,15 +19,15 @@ class {{ node.aux.stubName }} :
public {{ node.Base }} {
{%- endif %}
public:
- explicit {{ node.aux.stubName }}(const TExprNode* node)
- : {{ node.Base }}(node)
- {
- {%- if node.Match %}
+ explicit {{ node.aux.stubName }}(const TExprNode* node)
+ : {{ node.Base }}(node)
+ {
+ {%- if node.Match %}
YQL_ENSURE(Match(node));
- {%- endif %}
- }
-
- explicit {{ node.aux.stubName }}(const TExprNode::TPtr& node)
+ {%- endif %}
+ }
+
+ explicit {{ node.aux.stubName }}(const TExprNode::TPtr& node)
: {{ node.Base }}(node)
{
{%- if node.Match %}
@@ -38,7 +38,7 @@ public:
{%- if node.Content %}
{% if node.Content.Type == "TStringBuf" %}
TStringBuf {{ node.Content.Name }}() const {
- return this->Ref().Content();
+ return this->Ref().Content();
}
{% else %}
static_assert(false, "Node {{node.Name}}: {{node.Content.Type}} is not supported as content type.");
@@ -92,10 +92,10 @@ public:
template<template<typename> class TMaybe, typename TDerived, {{ node.aux.typenames | join(", ") }}>
class {{ node.aux.stubMaybeName }} : public TMaybe<{{node.Base}}> {
protected:
- {{ node.aux.stubMaybeName }}(const TExprNode* node)
- : TMaybe<{{ node.Base }}>(node && TDerived::Match(node) ? node : nullptr) {}
- {{ node.aux.stubMaybeName }}(const TExprNode::TPtr& node)
- : TMaybe<{{ node.Base }}>(node && TDerived::Match(node.Get()) ? node : TExprNode::TPtr()) {}
+ {{ node.aux.stubMaybeName }}(const TExprNode* node)
+ : TMaybe<{{ node.Base }}>(node && TDerived::Match(node) ? node : nullptr) {}
+ {{ node.aux.stubMaybeName }}(const TExprNode::TPtr& node)
+ : TMaybe<{{ node.Base }}>(node && TDerived::Match(node.Get()) ? node : TExprNode::TPtr()) {}
public:
{% for child in node.Children %}
TMaybe<{{child.Type}}> {{child.Name}}() const {
@@ -103,7 +103,7 @@ public:
}
{% endfor %}
TDerived Cast() const {
- return TMaybe<{{node.Base}}>::Cast().template Cast<TDerived>();
+ return TMaybe<{{node.Base}}>::Cast().template Cast<TDerived>();
}
};
@@ -202,13 +202,13 @@ public:
{% endif %}
{%- for child in node.aux.allChildren %}
- TBuilder<TParent, TDerived>& {{child.Name}}(const TStringBuf& argName) { {{child.aux.holderName}} = {{child.Type}}(this->GetArgFunc(argName)); return *static_cast<TBuilder<TParent, TDerived>*>(this); }
+ TBuilder<TParent, TDerived>& {{child.Name}}(const TStringBuf& argName) { {{child.aux.holderName}} = {{child.Type}}(this->GetArgFunc(argName)); return *static_cast<TBuilder<TParent, TDerived>*>(this); }
{% if child.Optional %}
TBuilder<TParent, TDerived>& {{child.Name}}(const TMaybe<{{child.Type}}>& node) { {{child.aux.holderName}} = node; return *static_cast<TBuilder<TParent, TDerived>*>(this); }
{% endif %}
TBuilder<TParent, TDerived>& {{child.Name}}(const {{child.Type}}& node) { {{child.aux.holderName}} = node; return *static_cast<TBuilder<TParent, TDerived>*>(this); }
- TBuilder<TParent, TDerived>& {{child.Name}}(const TExprNode::TPtr& node) { {{child.aux.holderName}} = {{child.Type}}(node); return *static_cast<TBuilder<TParent, TDerived>*>(this); }
+ TBuilder<TParent, TDerived>& {{child.Name}}(const TExprNode::TPtr& node) { {{child.aux.holderName}} = {{child.Type}}(node); return *static_cast<TBuilder<TParent, TDerived>*>(this); }
TBuilder<TParent, TDerived>& {{child.Name}}(std::function<void(TExprNodeBuilder&)> fluentFunc) {
TExprNodeBuilder fluentBuilder(this->Pos, this->Ctx, [this] (const TStringBuf& argName) {
@@ -223,8 +223,8 @@ public:
TBuilder<TBuilder<TParent, TDerived>, {{child.Type}}> {{child.Name}}() {
return TBuilder<TBuilder<TParent, TDerived>, {{child.Type}}>(this->Ctx, this->Pos,
[this] (const {{child.Type}}& node) mutable -> TBuilder<TParent, TDerived>& {
- {{child.aux.holderName}} = node;
- return *static_cast<TBuilder<TParent, TDerived>*>(this);
+ {{child.aux.holderName}} = node;
+ return *static_cast<TBuilder<TParent, TDerived>*>(this);
}, this->GetArgFunc);
}
@@ -232,8 +232,8 @@ public:
TBuilder<TBuilder<TParent, TDerived>, TNode> {{child.Name}}() {
return TBuilder<TBuilder<TParent, TDerived>, TNode>(this->Ctx, this->Pos,
[this] (const TNode& node) mutable -> TBuilder<TParent, TDerived>&{
- {{child.aux.holderName}} = node;
- return *static_cast<TBuilder<TParent, TDerived>*>(this);
+ {{child.aux.holderName}} = node;
+ return *static_cast<TBuilder<TParent, TDerived>*>(this);
}, this->GetArgFunc);
}
{%- endfor %}
@@ -258,9 +258,9 @@ using {{ node.Name }} = NGenerated::{{ node.aux.stubName }}<{{ node.aux.usages |
{% elif genType == "Definitions" -%}
{% for node in nodes %}
-static_assert(std::is_constructible<{{ node.Name }}, const TExprNode*>::value,
- "{{ node.Name }} isn't defined correctly.");
-static_assert(std::is_constructible<{{ node.Name }}, const TExprNode::TPtr&>::value,
+static_assert(std::is_constructible<{{ node.Name }}, const TExprNode*>::value,
+ "{{ node.Name }} isn't defined correctly.");
+static_assert(std::is_constructible<{{ node.Name }}, const TExprNode::TPtr&>::value,
"{{ node.Name }} isn't defined correctly.");
{% endfor %}
@@ -270,16 +270,16 @@ class TMaybeNode<{{ node.Name }}> : public NGenerated::
{{ node.aux.stubMaybeName }}<TMaybeNode, {{ node.Name }}, {{ node.aux.usages | join(", ") }}>
{
public:
- TMaybeNode(const TExprNode* node = nullptr) : {{ node.aux.stubMaybeName }}(node) {}
- TMaybeNode(const TExprNode::TPtr& node) : {{ node.aux.stubMaybeName }}(node) {}
- TMaybeNode(const {{ node.Name }}& node) : {{ node.aux.stubMaybeName }}(node.template Maybe<{{ node.Name }}>()) {}
+ TMaybeNode(const TExprNode* node = nullptr) : {{ node.aux.stubMaybeName }}(node) {}
+ TMaybeNode(const TExprNode::TPtr& node) : {{ node.aux.stubMaybeName }}(node) {}
+ TMaybeNode(const {{ node.Name }}& node) : {{ node.aux.stubMaybeName }}(node.template Maybe<{{ node.Name }}>()) {}
};
{% endfor %}
namespace NGenerated {
{% for node in nodes %}
{%- if node.aux.generateBuilderStub %}
- {%- if node.Builder.Kind == "Node" %}
+ {%- if node.Builder.Kind == "Node" %}
template<typename TParent>
using {{ node.aux.stubBuilderAliasName }} =
NGenerated::{{ node.aux.stubBuilderName }}<{{ model.NodeBuilderBase }}, TParent, TNodeBuilder, {{ node.Name }},
@@ -329,7 +329,7 @@ class UnknownBuilder {
}
{%- else %}
{%- for child in node.aux.allChildren %}
- if (this->{{ child.aux.holderName }}) {
+ if (this->{{ child.aux.holderName }}) {
YQL_ENSURE(argsList.size() == {{ child.Index }});
argsList.push_back(this->{{ child.aux.holderName }}.Cast().Ptr());
}
@@ -361,9 +361,9 @@ class UnknownBuilder {
{%- elif node.ListBase and node.Builder.Kind == "List"%}
TExprNode::TListType nodeChildren;
for (auto child : this->Items) {
- nodeChildren.push_back(child.Ptr());
+ nodeChildren.push_back(child.Ptr());
}
- auto node = this->Ctx.NewList(this->Pos, std::move(nodeChildren));
+ auto node = this->Ctx.NewList(this->Pos, std::move(nodeChildren));
return {{ node.Name }}(node);
{%- else %}
static_assert(false, "Don't know how to build {{ node.Name }}.");
diff --git a/ydb/library/yql/core/facade/yql_facade.cpp b/ydb/library/yql/core/facade/yql_facade.cpp
index c9e86b9af2..b74abc1c34 100644
--- a/ydb/library/yql/core/facade/yql_facade.cpp
+++ b/ydb/library/yql/core/facade/yql_facade.cpp
@@ -66,7 +66,7 @@ TProgram::TStatus SyncExecution(
TProgram::TFutureStatus (TProgram::*method)(Params1...),
Params2&&... params) {
TProgram::TFutureStatus future =
- (program->*method)(std::forward<Params2>(params)...);
+ (program->*method)(std::forward<Params2>(params)...);
YQL_ENSURE(future.Initialized());
future.Wait();
YQL_ENSURE(!future.HasException());
@@ -114,12 +114,12 @@ std::function<TMaybe<TString>(const TString&)> BuildCompositeTokenResolver(TVect
TProgramFactory::TProgramFactory(
bool useRepeatableRandomAndTimeProviders,
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
- ui64 nextUniqueId,
+ ui64 nextUniqueId,
const TVector<TDataProviderInitializer>& dataProvidersInit,
const TString& runner)
: UseRepeatableRandomAndTimeProviders_(useRepeatableRandomAndTimeProviders)
, FunctionRegistry_(functionRegistry)
- , NextUniqueId_(nextUniqueId)
+ , NextUniqueId_(nextUniqueId)
, DataProvidersInit_(dataProvidersInit)
, GatewaysConfig_(nullptr)
, Runner_(runner)
@@ -155,10 +155,10 @@ void TProgramFactory::SetGatewaysConfig(const TGatewaysConfig* gatewaysConfig) {
GatewaysConfig_ = gatewaysConfig;
}
-void TProgramFactory::SetModules(IModuleResolver::TPtr modules) {
- Modules_ = modules;
-}
-
+void TProgramFactory::SetModules(IModuleResolver::TPtr modules) {
+ Modules_ = modules;
+}
+
void TProgramFactory::SetUdfResolver(IUdfResolver::TPtr udfResolver) {
UdfResolver_ = udfResolver;
}
@@ -208,12 +208,12 @@ TProgram::TProgram(
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
const TIntrusivePtr<IRandomProvider> randomProvider,
const TIntrusivePtr<ITimeProvider> timeProvider,
- ui64 nextUniqueId,
+ ui64 nextUniqueId,
const TVector<TDataProviderInitializer>& dataProvidersInit,
const TUserDataTable& userDataTable,
const TVector<TCredentialTablePtr>& credentialTables,
const TUserCredentials& userCredentials,
- const IModuleResolver::TPtr& modules,
+ const IModuleResolver::TPtr& modules,
const IUdfResolver::TPtr& udfResolver,
const TUdfIndex::TPtr& udfIndex,
const TUdfIndexPackageSet::TPtr& udfIndexPackageSet,
@@ -228,7 +228,7 @@ TProgram::TProgram(
: FunctionRegistry_(functionRegistry)
, RandomProvider_(randomProvider)
, TimeProvider_(timeProvider)
- , NextUniqueId_(nextUniqueId)
+ , NextUniqueId_(nextUniqueId)
, DataProvidersInit_(dataProvidersInit)
, CredentialTables_(credentialTables)
, UserCredentials_(userCredentials)
@@ -243,7 +243,7 @@ TProgram::TProgram(
, SourceSyntax_(ESourceSyntax::Unknown)
, SyntaxVersion_(0)
, AstRoot_(nullptr)
- , Modules_(modules)
+ , Modules_(modules)
, ExprRoot_(nullptr)
, SessionId_(sessionId)
, ResultFormat_(NYson::EYsonFormat::Binary)
@@ -370,7 +370,7 @@ bool TProgram::FillParseResult(NYql::TAstParseResult&& astRes, NYql::TWarningRul
return false;
}
AstRoot_ = astRes.Root;
- AstPool_ = std::move(astRes.Pool);
+ AstPool_ = std::move(astRes.Pool);
return true;
}
@@ -570,7 +570,7 @@ TProgram::TFutureStatus TProgram::ValidateAsync(const TString& username, IOutput
ExprStream_ = exprOut;
Transformer_ = TTransformationPipeline(TypeCtx_)
- .AddServiceTransformers()
+ .AddServiceTransformers()
.AddParametersEvaluation(*FunctionRegistry_)
.AddPreTypeAnnotation()
.AddExpressionEvaluation(*FunctionRegistry_)
@@ -638,7 +638,7 @@ TProgram::TFutureStatus TProgram::OptimizeAsync(
ExprStream_ = exprOut;
PlanStream_ = tracePlan;
Transformer_ = TTransformationPipeline(TypeCtx_)
- .AddServiceTransformers()
+ .AddServiceTransformers()
.AddParametersEvaluation(*FunctionRegistry_)
.AddPreTypeAnnotation()
.AddExpressionEvaluation(*FunctionRegistry_)
@@ -646,7 +646,7 @@ TProgram::TFutureStatus TProgram::OptimizeAsync(
.AddTypeAnnotation()
.AddPostTypeAnnotation()
.Add(TExprOutputTransformer::Sync(ExprRoot_, traceOut), "ExprOutput")
- .AddOptimization()
+ .AddOptimization()
.Add(CreatePlanInfoTransformer(*TypeCtx_), "PlanInfo")
.Add(TExprOutputTransformer::Sync(ExprRoot_, exprOut, withTypes), "AstOutput")
.Add(TPlanOutputTransformer::Sync(tracePlan, GetPlanBuilder(), OutputFormat_), "PlanOutput")
@@ -701,7 +701,7 @@ TProgram::TFutureStatus TProgram::OptimizeAsyncWithConfig(
TTransformationPipeline pipeline(TypeCtx_);
pipelineConf.AfterCreate(&pipeline);
- pipeline.AddServiceTransformers();
+ pipeline.AddServiceTransformers();
pipeline.AddParametersEvaluation(*FunctionRegistry_);
pipeline.AddPreTypeAnnotation();
pipeline.AddExpressionEvaluation(*FunctionRegistry_);
@@ -710,7 +710,7 @@ TProgram::TFutureStatus TProgram::OptimizeAsyncWithConfig(
pipeline.AddPostTypeAnnotation();
pipelineConf.AfterTypeAnnotation(&pipeline);
- pipeline.AddOptimization();
+ pipeline.AddOptimization();
if (EnableRangeComputeFor_) {
pipeline.Add(MakeExpandRangeComputeForTransformer(pipeline.GetTypeAnnotationContext()),
"ExpandRangeComputeFor", TIssuesIds::CORE_EXEC);
@@ -853,7 +853,7 @@ TProgram::TFutureStatus TProgram::RunAsyncWithConfig(
TTransformationPipeline pipeline(TypeCtx_);
pipelineConf.AfterCreate(&pipeline);
- pipeline.AddServiceTransformers();
+ pipeline.AddServiceTransformers();
pipeline.AddParametersEvaluation(*FunctionRegistry_);
pipeline.AddPreTypeAnnotation();
pipeline.AddExpressionEvaluation(*FunctionRegistry_);
@@ -862,7 +862,7 @@ TProgram::TFutureStatus TProgram::RunAsyncWithConfig(
pipeline.AddPostTypeAnnotation();
pipelineConf.AfterTypeAnnotation(&pipeline);
- pipeline.AddOptimization();
+ pipeline.AddOptimization();
if (EnableRangeComputeFor_) {
pipeline.Add(MakeExpandRangeComputeForTransformer(pipeline.GetTypeAnnotationContext()),
"ExpandRangeComputeFor", TIssuesIds::CORE_EXEC);
@@ -1250,7 +1250,7 @@ TTypeAnnotationContextPtr TProgram::BuildTypeAnnotationContext(const TString& us
typeAnnotationContext->UserDataStorage = UserDataStorage_;
typeAnnotationContext->Credentials = CredentialTables_;
typeAnnotationContext->UserCredentials = UserCredentials_;
- typeAnnotationContext->Modules = Modules_;
+ typeAnnotationContext->Modules = Modules_;
typeAnnotationContext->UdfResolver = UdfResolver_;
typeAnnotationContext->UdfIndex = UdfIndex_;
typeAnnotationContext->UdfIndexPackageSet = UdfIndexPackageSet_;
@@ -1329,7 +1329,7 @@ TTypeAnnotationContextPtr TProgram::BuildTypeAnnotationContext(const TString& us
ResultProviderConfig_ = MakeIntrusive<TResultProviderConfig>(*typeAnnotationContext,
*FunctionRegistry_, IDataProvider::EResultFormat::Yson, ToString((ui32)resultFormat), writerFactory);
ResultProviderConfig_->SupportsResultPosition = SupportsResultPosition_;
- auto resultProvider = CreateResultProvider(ResultProviderConfig_);
+ auto resultProvider = CreateResultProvider(ResultProviderConfig_);
typeAnnotationContext->AddDataSink(ResultProviderName, resultProvider);
typeAnnotationContext->AvailablePureResultDataSources = resultProviderDataSources;
}
diff --git a/ydb/library/yql/core/facade/yql_facade.h b/ydb/library/yql/core/facade/yql_facade.h
index 6681787874..1f8f47681d 100644
--- a/ydb/library/yql/core/facade/yql_facade.h
+++ b/ydb/library/yql/core/facade/yql_facade.h
@@ -40,7 +40,7 @@ public:
TProgramFactory(
bool useRepeatableRandomAndTimeProviders,
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
- ui64 nextUniqueId,
+ ui64 nextUniqueId,
const TVector<TDataProviderInitializer>& dataProvidersInit,
const TString& runner);
@@ -48,7 +48,7 @@ public:
void AddCredentialsTable(TCredentialTablePtr credentialTable);
void SetUserCredentials(const TUserCredentials& userCredentials);
void SetGatewaysConfig(const TGatewaysConfig* gatewaysConfig);
- void SetModules(IModuleResolver::TPtr modules);
+ void SetModules(IModuleResolver::TPtr modules);
void SetUdfResolver(IUdfResolver::TPtr udfResolver);
void SetUdfIndex(TUdfIndex::TPtr udfIndex, TUdfIndexPackageSet::TPtr udfIndexPackageSet);
void SetFileStorage(TFileStoragePtr fileStorage);
@@ -68,13 +68,13 @@ private:
const bool UseRepeatableRandomAndTimeProviders_;
bool UseUnrepeatableRandom = false;
const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry_;
- const ui64 NextUniqueId_;
+ const ui64 NextUniqueId_;
TVector<TDataProviderInitializer> DataProvidersInit_;
TUserDataTable UserDataTable_;
TVector<TCredentialTablePtr> CredentialTables_;
TUserCredentials UserCredentials_;
const TGatewaysConfig* GatewaysConfig_;
- IModuleResolver::TPtr Modules_;
+ IModuleResolver::TPtr Modules_;
IUdfResolver::TPtr UdfResolver_;
TUdfIndex::TPtr UdfIndex_;
TUdfIndexPackageSet::TPtr UdfIndexPackageSet_;
@@ -188,7 +188,7 @@ public:
return AstRoot_;
}
- inline const TExprNode::TPtr& ExprRoot() const {
+ inline const TExprNode::TPtr& ExprRoot() const {
return ExprRoot_;
}
@@ -297,12 +297,12 @@ private:
const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
const TIntrusivePtr<IRandomProvider> randomProvider,
const TIntrusivePtr<ITimeProvider> timeProvider,
- ui64 nextUniqueId,
+ ui64 nextUniqueId,
const TVector<TDataProviderInitializer>& dataProvidersInit,
const TUserDataTable& userDataTable,
const TVector<TCredentialTablePtr>& credentialTables,
const TUserCredentials& userCredentials,
- const IModuleResolver::TPtr& modules,
+ const IModuleResolver::TPtr& modules,
const IUdfResolver::TPtr& udfResolver,
const TUdfIndex::TPtr& udfIndex,
const TUdfIndexPackageSet::TPtr& udfIndexPackageSet,
@@ -338,7 +338,7 @@ private:
const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry_;
const TIntrusivePtr<IRandomProvider> RandomProvider_;
const TIntrusivePtr<ITimeProvider> TimeProvider_;
- const ui64 NextUniqueId_;
+ const ui64 NextUniqueId_;
TVector<TDataProviderInitializer> DataProvidersInit_;
TVector<TDataProviderInfo> DataProviders_;
TYqlOperationOptions OperationOptions_;
@@ -356,10 +356,10 @@ private:
ui16 SyntaxVersion_;
TAstNode* AstRoot_;
- std::unique_ptr<TMemoryPool> AstPool_;
- TAutoPtr<TExprContext> ExprCtx_;
- const IModuleResolver::TPtr Modules_;
- TExprNode::TPtr ExprRoot_;
+ std::unique_ptr<TMemoryPool> AstPool_;
+ TAutoPtr<TExprContext> ExprCtx_;
+ const IModuleResolver::TPtr Modules_;
+ TExprNode::TPtr ExprRoot_;
TExprNode::TPtr SavedExprRoot_;
mutable TAdaptiveLock SessionIdLock_;
TString SessionId_;
diff --git a/ydb/library/yql/core/issue/protos/issue_id.proto b/ydb/library/yql/core/issue/protos/issue_id.proto
index 58d7ac51a5..a2ed91d640 100644
--- a/ydb/library/yql/core/issue/protos/issue_id.proto
+++ b/ydb/library/yql/core/issue/protos/issue_id.proto
@@ -35,7 +35,7 @@ message TIssuesIds {
CORE_IMPLICIT_BITCAST = 1107;
CORE_LEGACY_IN_FOR_EMPTY_OR_NULLABLE = 1108;
CORE_LEGACY_RANK_FOR_NULLABLE_KEYS = 1109;
- CORE_LEGACY_REGEX_ENGINE = 1110;
+ CORE_LEGACY_REGEX_ENGINE = 1110;
CORE_ALIAS_SHADOWS_COLUMN = 1111;
// core errors
@@ -111,8 +111,8 @@ message TIssuesIds {
YQL_DEPRECATED_TINY_INT_LITERAL_SUFFIX = 4508;
YQL_DEPRECATED_DATETIME2 = 4509;
YQL_S_EXPRESSIONS_CALL = 4510;
- YQL_DEPRECATED_INTERVAL_CONSTANT = 4511;
- YQL_DEPRECATED_FUNCTION_OR_SIGNATURE = 4512;
+ YQL_DEPRECATED_INTERVAL_CONSTANT = 4511;
+ YQL_DEPRECATED_FUNCTION_OR_SIGNATURE = 4512;
YQL_DEPRECATED_INLINE_ACTION_TERMINATOR = 4513;
YQL_MULTIWAY_JOIN_WITH_USING = 4514;
YQL_DEPRECATED_V0_SYNTAX = 4515;
@@ -123,7 +123,7 @@ message TIssuesIds {
YQL_RANK_WITHOUT_ORDER_BY = 4521;
YQL_LIMIT_ORDER_BY_WITH_UNION = 4522;
YQL_DISCARD_INTO_RESULT_BY_WITH_UNION = 4523;
- YQL_DEPRECATED_UDF_FUNCTION = 4524;
+ YQL_DEPRECATED_UDF_FUNCTION = 4524;
YQL_EMPTY_TABLENAME_RESULT = 4525;
YQL_HAVING_WITHOUT_AGGREGATION_IN_SELECT_DISTINCT = 4526;
YQL_UNUSED_SYMBOL = 4527;
diff --git a/ydb/library/yql/core/issue/yql_issue.txt b/ydb/library/yql/core/issue/yql_issue.txt
index 914256d8e1..897d5d6f9a 100644
--- a/ydb/library/yql/core/issue/yql_issue.txt
+++ b/ydb/library/yql/core/issue/yql_issue.txt
@@ -112,10 +112,10 @@ ids {
severity: S_WARNING
}
ids {
- code: CORE_LEGACY_REGEX_ENGINE
- severity: S_WARNING
-}
-ids {
+ code: CORE_LEGACY_REGEX_ENGINE
+ severity: S_WARNING
+}
+ids {
code: CORE_ALIAS_SHADOWS_COLUMN
severity: S_WARNING
}
@@ -329,10 +329,10 @@ ids {
severity: S_WARNING
}
ids {
- code: YQL_DEPRECATED_INTERVAL_CONSTANT
- severity: S_WARNING
-}
-ids {
+ code: YQL_DEPRECATED_INTERVAL_CONSTANT
+ severity: S_WARNING
+}
+ids {
code: YQL_DEPRECATED_PRAGMA
severity: S_WARNING
}
@@ -416,10 +416,10 @@ ids {
code: STAT_ACCESS_DENIED
severity: S_ERROR
}
-ids {
- code: YQL_DEPRECATED_FUNCTION_OR_SIGNATURE
- severity: S_WARNING
-}
+ids {
+ code: YQL_DEPRECATED_FUNCTION_OR_SIGNATURE
+ severity: S_WARNING
+}
ids {
code: YQL_DEPRECATED_INLINE_ACTION_TERMINATOR
severity: S_WARNING
@@ -555,11 +555,11 @@ ids {
ids {
code: YQL_DISCARD_INTO_RESULT_BY_WITH_UNION
severity: S_WARNING
-}
-ids {
- code: YQL_DEPRECATED_UDF_FUNCTION
- severity: S_WARNING
-}
+}
+ids {
+ code: YQL_DEPRECATED_UDF_FUNCTION
+ severity: S_WARNING
+}
ids {
code: YQL_EMPTY_TABLENAME_RESULT
severity: S_WARNING
diff --git a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
index fd63e33f23..ce22b12571 100644
--- a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
+++ b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
@@ -18,7 +18,7 @@
#include <ydb/library/yql/core/services/yql_out_transformers.h>
#include <ydb/library/yql/utils/yql_paths.h>
-#include <util/generic/xrange.h>
+#include <util/generic/xrange.h>
#include <library/cpp/yson/writer.h>
@@ -28,61 +28,61 @@ namespace {
using namespace NNodes;
-using TPeepHoleOptimizerPtr = TExprNode::TPtr (*const)(const TExprNode::TPtr&, TExprContext&);
-using TPeepHoleOptimizerMap = std::unordered_map<std::string_view, TPeepHoleOptimizerPtr>;
-
-using TNonDeterministicOptimizerPtr = TExprNode::TPtr (*const)(const TExprNode::TPtr&, TExprContext&, TTypeAnnotationContext& types);
-using TNonDeterministicOptimizerMap = std::unordered_map<std::string_view, TNonDeterministicOptimizerPtr>;
-
+using TPeepHoleOptimizerPtr = TExprNode::TPtr (*const)(const TExprNode::TPtr&, TExprContext&);
+using TPeepHoleOptimizerMap = std::unordered_map<std::string_view, TPeepHoleOptimizerPtr>;
+
+using TNonDeterministicOptimizerPtr = TExprNode::TPtr (*const)(const TExprNode::TPtr&, TExprContext&, TTypeAnnotationContext& types);
+using TNonDeterministicOptimizerMap = std::unordered_map<std::string_view, TNonDeterministicOptimizerPtr>;
+
TExprNode::TPtr MakeNothing(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx) {
- return ctx.NewCallable(pos, "Nothing", {ExpandType(pos, *ctx.MakeType<TOptionalExprType>(&type), ctx)});
-}
-
-std::string_view ToLiteral(const TGUID& uuid) { return std::string_view(reinterpret_cast<const char*>(&uuid), sizeof(uuid)); }
-template <typename T> TString ToLiteral(const T value) { return ToString<T>(value); }
-
-template <typename TRandomType>
-TExprNode::TPtr Random0Arg(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& types) {
- if (node->ChildrenSize() == 0U) {
+ return ctx.NewCallable(pos, "Nothing", {ExpandType(pos, *ctx.MakeType<TOptionalExprType>(&type), ctx)});
+}
+
+std::string_view ToLiteral(const TGUID& uuid) { return std::string_view(reinterpret_cast<const char*>(&uuid), sizeof(uuid)); }
+template <typename T> TString ToLiteral(const T value) { return ToString<T>(value); }
+
+template <typename TRandomType>
+TExprNode::TPtr Random0Arg(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& types) {
+ if (node->ChildrenSize() == 0U) {
YQL_CLOG(DEBUG, CorePeepHole) << "0-arg " << node->Content();
- const auto random = types.GetCachedRandom<TRandomType>();
- return ctx.NewCallable(node->Pos(), node->GetTypeAnn()->Cast<TDataExprType>()->GetName(), { ctx.NewAtom(node->Pos(), ToLiteral(random)) });
- }
- return node;
-}
-
-template <ui64(*Convert)(ui64)>
-TExprNode::TPtr Now0Arg(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& types) {
- if (node->ChildrenSize() == 0U) {
+ const auto random = types.GetCachedRandom<TRandomType>();
+ return ctx.NewCallable(node->Pos(), node->GetTypeAnn()->Cast<TDataExprType>()->GetName(), { ctx.NewAtom(node->Pos(), ToLiteral(random)) });
+ }
+ return node;
+}
+
+template <ui64(*Convert)(ui64)>
+TExprNode::TPtr Now0Arg(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& types) {
+ if (node->ChildrenSize() == 0U) {
YQL_CLOG(DEBUG, CorePeepHole) << "0-arg " << node->Content();
- const auto now = types.GetCachedNow();
- return ctx.NewCallable(node->Pos(), node->GetTypeAnn()->Cast<TDataExprType>()->GetName(), { ctx.NewAtom(node->Pos(), ToString(bool(Convert) ? Convert(now) : now), TNodeFlags::Default) });
- }
- return node;
-}
-
-TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExprNode& joinTree, TExprContext& ctx,
- std::vector<std::string_view>& outLabels, const TExprNode::TPtr& settings) {
- const auto leftSubtree = joinTree.Child(1);
- const auto rightSubtree = joinTree.Child(2);
- TExprNode::TPtr leftList;
- std::vector<std::string_view> leftListLabels;
- TExprNode::TPtr leftLabelsNode;
+ const auto now = types.GetCachedNow();
+ return ctx.NewCallable(node->Pos(), node->GetTypeAnn()->Cast<TDataExprType>()->GetName(), { ctx.NewAtom(node->Pos(), ToString(bool(Convert) ? Convert(now) : now), TNodeFlags::Default) });
+ }
+ return node;
+}
+
+TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExprNode& joinTree, TExprContext& ctx,
+ std::vector<std::string_view>& outLabels, const TExprNode::TPtr& settings) {
+ const auto leftSubtree = joinTree.Child(1);
+ const auto rightSubtree = joinTree.Child(2);
+ TExprNode::TPtr leftList;
+ std::vector<std::string_view> leftListLabels;
+ TExprNode::TPtr leftLabelsNode;
if (leftSubtree->IsAtom()) {
- TExprNode::TPtr listNode;
+ TExprNode::TPtr listNode;
for (ui32 i = 0; !listNode && i < node.ChildrenSize() - 1; ++i) {
if (node.Child(i)->Child(1)->IsAtom()) {
if (node.Child(i)->Child(1)->Content() == leftSubtree->Content()) {
- listNode = node.Child(i)->HeadPtr();
- leftLabelsNode = node.Child(i)->ChildPtr(1);
+ listNode = node.Child(i)->HeadPtr();
+ leftLabelsNode = node.Child(i)->ChildPtr(1);
leftListLabels.push_back(leftSubtree->Content());
break;
}
} else {
for (auto& child : node.Child(i)->Child(1)->Children()) {
if (child->Content() == leftSubtree->Content()) {
- listNode = node.Child(i)->HeadPtr();
- leftLabelsNode = node.Child(i)->ChildPtr(1);
+ listNode = node.Child(i)->HeadPtr();
+ leftLabelsNode = node.Child(i)->ChildPtr(1);
break;
}
}
@@ -99,25 +99,25 @@ TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExpr
leftList = listNode;
}
else {
- leftList = SplitEquiJoinToPairsRecursive(node, *leftSubtree, ctx, leftListLabels, ctx.NewList(node.Pos(), {}));
+ leftList = SplitEquiJoinToPairsRecursive(node, *leftSubtree, ctx, leftListLabels, ctx.NewList(node.Pos(), {}));
TExprNode::TListType leftLabelsChildren;
for (auto& label : leftListLabels) {
leftLabelsChildren.push_back(ctx.NewAtom(node.Pos(), label));
}
- leftLabelsNode = ctx.NewList(node.Pos(), std::move(leftLabelsChildren));
+ leftLabelsNode = ctx.NewList(node.Pos(), std::move(leftLabelsChildren));
}
- TExprNode::TPtr rightList;
- std::vector<std::string_view> rightListLabels;
- TExprNode::TPtr rightLabelsNode;
+ TExprNode::TPtr rightList;
+ std::vector<std::string_view> rightListLabels;
+ TExprNode::TPtr rightLabelsNode;
if (rightSubtree->IsAtom()) {
- TExprNode::TPtr listNode;
+ TExprNode::TPtr listNode;
for (ui32 i = 0; !listNode && i < node.ChildrenSize() - 1; ++i) {
if (node.Child(i)->Child(1)->IsAtom()) {
if (node.Child(i)->Child(1)->Content() == rightSubtree->Content()) {
- listNode = node.Child(i)->HeadPtr();
- rightLabelsNode = node.Child(i)->ChildPtr(1);
+ listNode = node.Child(i)->HeadPtr();
+ rightLabelsNode = node.Child(i)->ChildPtr(1);
rightListLabels.push_back(rightSubtree->Content());
break;
}
@@ -125,8 +125,8 @@ TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExpr
else {
for (auto& child : node.Child(i)->Child(1)->Children()) {
if (child->Content() == rightSubtree->Content()) {
- listNode = node.Child(i)->HeadPtr();
- rightLabelsNode = node.Child(i)->ChildPtr(1);
+ listNode = node.Child(i)->HeadPtr();
+ rightLabelsNode = node.Child(i)->ChildPtr(1);
break;
}
}
@@ -143,20 +143,20 @@ TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExpr
rightList = listNode;
}
else {
- rightList = SplitEquiJoinToPairsRecursive(node, *rightSubtree, ctx, rightListLabels, ctx.NewList(node.Pos(), {}));
+ rightList = SplitEquiJoinToPairsRecursive(node, *rightSubtree, ctx, rightListLabels, ctx.NewList(node.Pos(), {}));
TExprNode::TListType rightLabelsChildren;
for (auto& label : rightListLabels) {
rightLabelsChildren.push_back(ctx.NewAtom(node.Pos(), label));
}
- rightLabelsNode = ctx.NewList(node.Pos(), std::move(rightLabelsChildren));
+ rightLabelsNode = ctx.NewList(node.Pos(), std::move(rightLabelsChildren));
}
outLabels.insert(outLabels.end(), leftListLabels.begin(), leftListLabels.end());
outLabels.insert(outLabels.end(), rightListLabels.begin(), rightListLabels.end());
- auto result = ctx.Builder(node.Pos())
- .Callable(node.Content())
+ auto result = ctx.Builder(node.Pos())
+ .Callable(node.Content())
.List(0)
.Add(0, leftList)
.Add(1, leftLabelsNode)
@@ -166,12 +166,12 @@ TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExpr
.Add(1, rightLabelsNode)
.Seal()
.List(2)
- .Add(0, joinTree.HeadPtr())
- .Atom(1, leftListLabels.front())
- .Atom(2, rightListLabels.front())
- .Add(3, joinTree.ChildPtr(3))
- .Add(4, joinTree.ChildPtr(4))
- .Add(5, joinTree.ChildPtr(5))
+ .Add(0, joinTree.HeadPtr())
+ .Atom(1, leftListLabels.front())
+ .Atom(2, rightListLabels.front())
+ .Add(3, joinTree.ChildPtr(3))
+ .Add(4, joinTree.ChildPtr(4))
+ .Add(5, joinTree.ChildPtr(5))
.Seal()
.Add(3, settings)
.Seal()
@@ -179,86 +179,86 @@ TExprNode::TPtr SplitEquiJoinToPairsRecursive(const TExprNode& node, const TExpr
return result;
}
-TExprNode::TPtr SplitEquiJoinToPairs(const TExprNode& join, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Split " << join.Content() << " to pairs.";
- const auto joinTree = join.Child(join.ChildrenSize() - 2U);
- const auto joinSettings = join.TailPtr();
- std::vector<std::string_view> outLabels;
- return SplitEquiJoinToPairsRecursive(join, *joinTree, ctx, outLabels, joinSettings);
-}
-
-std::optional<std::string_view> CutAlias(const std::string_view& alias, const std::string_view& column) {
- if (!alias.empty() && column.starts_with(alias) && column.length() > alias.length() && '.' == column[alias.length()])
- return column.substr(alias.length() + 1U);
- return std::nullopt;
-}
-
-std::vector<std::tuple<TExprNode::TPtr, bool, TExprNode::TPtr>> GetRenames(const TExprNode& join, TExprContext& ctx) {
- std::unordered_map<std::string_view, std::array<TExprNode::TPtr, 2U>> renames(join.Tail().ChildrenSize());
- join.Tail().ForEachChild([&](const TExprNode& child) {
- if (child.Head().Content() == "rename" && !child.Child(2)->Content().empty())
- renames.emplace(child.Child(2)->Content(), std::array<TExprNode::TPtr, 2U>{child.ChildPtr(1), child.ChildPtr(2)});
- });
-
- const auto& lhs = join.Head();
- const auto& rhs = *join.Child(1);
-
- const std::string_view lAlias = lhs.Tail().IsAtom() ? lhs.Tail().Content() : "";
- const std::string_view rAlias = rhs.Tail().IsAtom() ? rhs.Tail().Content() : "";
-
- const auto lType = lhs.Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
- const auto rType = rhs.Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
- const auto oType = join.GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
-
- std::vector<std::tuple<TExprNode::TPtr, bool, TExprNode::TPtr>> result;
- result.reserve(oType->GetSize());
- for (const auto& item : oType->GetItems()) {
- const auto& name = item->GetName();
- if (const auto it = renames.find(name); renames.cend() != it) {
- const auto& source = it->second.front()->Content();
- if (const auto& part = CutAlias(lAlias, source)) {
- if (const auto itemType = lType->FindItemType(*part))
- result.emplace_back(ctx.NewAtom(join.Pos(), *part), true, std::move(it->second.back()));
- } else if (const auto& part = CutAlias(rAlias, source)) {
- if (const auto itemType = rType->FindItemType(*part))
- result.emplace_back(ctx.NewAtom(join.Pos(), *part), false, std::move(it->second.back()));
- } else if (const auto itemType = lType->FindItemType(source)) {
- result.emplace_back(std::move(it->second.front()), true, std::move(it->second.back()));
- } else if (const auto itemType = rType->FindItemType(source)) {
- result.emplace_back(std::move(it->second.front()), false, std::move(it->second.back()));
- }
- } else {
- auto pass = ctx.NewAtom(join.Pos(), name);
- if (const auto& part = CutAlias(lAlias, name)) {
- if (const auto itemType = lType->FindItemType(*part))
- result.emplace_back(ctx.NewAtom(join.Pos(), *part), true, std::move(pass));
- } else if (const auto& part = CutAlias(rAlias, name)) {
- if (const auto itemType = rType->FindItemType(*part))
- result.emplace_back(ctx.NewAtom(join.Pos(), *part), false, std::move(pass));
- } else if (const auto itemType = lType->FindItemType(name)) {
- result.emplace_back(pass, true, pass);
- } else if (const auto itemType = rType->FindItemType(name)) {
- result.emplace_back(pass, false, pass);
- }
- }
- }
- return result;
-}
-
-TExprNode::TListType GetKeys(const TExprNode& side, const TExprNode& keys, TExprContext& ctx) {
- TExprNode::TListType result;
- result.reserve(keys.ChildrenSize() >> 1U);
-
- const auto alias = side.IsAtom() ? side.Content() : "";
- for (auto i = 0U; i < keys.ChildrenSize(); ++i) {
- if (const auto& al = keys.Child(i++)->Content(); al == alias)
- result.emplace_back(keys.ChildPtr(i));
- else
- result.emplace_back(ctx.NewAtom(keys.Child(i)->Pos(), TStringBuilder() << al << '.' << keys.Child(i)->Content()));
- }
- return result;
-}
-
+TExprNode::TPtr SplitEquiJoinToPairs(const TExprNode& join, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Split " << join.Content() << " to pairs.";
+ const auto joinTree = join.Child(join.ChildrenSize() - 2U);
+ const auto joinSettings = join.TailPtr();
+ std::vector<std::string_view> outLabels;
+ return SplitEquiJoinToPairsRecursive(join, *joinTree, ctx, outLabels, joinSettings);
+}
+
+std::optional<std::string_view> CutAlias(const std::string_view& alias, const std::string_view& column) {
+ if (!alias.empty() && column.starts_with(alias) && column.length() > alias.length() && '.' == column[alias.length()])
+ return column.substr(alias.length() + 1U);
+ return std::nullopt;
+}
+
+std::vector<std::tuple<TExprNode::TPtr, bool, TExprNode::TPtr>> GetRenames(const TExprNode& join, TExprContext& ctx) {
+ std::unordered_map<std::string_view, std::array<TExprNode::TPtr, 2U>> renames(join.Tail().ChildrenSize());
+ join.Tail().ForEachChild([&](const TExprNode& child) {
+ if (child.Head().Content() == "rename" && !child.Child(2)->Content().empty())
+ renames.emplace(child.Child(2)->Content(), std::array<TExprNode::TPtr, 2U>{child.ChildPtr(1), child.ChildPtr(2)});
+ });
+
+ const auto& lhs = join.Head();
+ const auto& rhs = *join.Child(1);
+
+ const std::string_view lAlias = lhs.Tail().IsAtom() ? lhs.Tail().Content() : "";
+ const std::string_view rAlias = rhs.Tail().IsAtom() ? rhs.Tail().Content() : "";
+
+ const auto lType = lhs.Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+ const auto rType = rhs.Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+ const auto oType = join.GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+
+ std::vector<std::tuple<TExprNode::TPtr, bool, TExprNode::TPtr>> result;
+ result.reserve(oType->GetSize());
+ for (const auto& item : oType->GetItems()) {
+ const auto& name = item->GetName();
+ if (const auto it = renames.find(name); renames.cend() != it) {
+ const auto& source = it->second.front()->Content();
+ if (const auto& part = CutAlias(lAlias, source)) {
+ if (const auto itemType = lType->FindItemType(*part))
+ result.emplace_back(ctx.NewAtom(join.Pos(), *part), true, std::move(it->second.back()));
+ } else if (const auto& part = CutAlias(rAlias, source)) {
+ if (const auto itemType = rType->FindItemType(*part))
+ result.emplace_back(ctx.NewAtom(join.Pos(), *part), false, std::move(it->second.back()));
+ } else if (const auto itemType = lType->FindItemType(source)) {
+ result.emplace_back(std::move(it->second.front()), true, std::move(it->second.back()));
+ } else if (const auto itemType = rType->FindItemType(source)) {
+ result.emplace_back(std::move(it->second.front()), false, std::move(it->second.back()));
+ }
+ } else {
+ auto pass = ctx.NewAtom(join.Pos(), name);
+ if (const auto& part = CutAlias(lAlias, name)) {
+ if (const auto itemType = lType->FindItemType(*part))
+ result.emplace_back(ctx.NewAtom(join.Pos(), *part), true, std::move(pass));
+ } else if (const auto& part = CutAlias(rAlias, name)) {
+ if (const auto itemType = rType->FindItemType(*part))
+ result.emplace_back(ctx.NewAtom(join.Pos(), *part), false, std::move(pass));
+ } else if (const auto itemType = lType->FindItemType(name)) {
+ result.emplace_back(pass, true, pass);
+ } else if (const auto itemType = rType->FindItemType(name)) {
+ result.emplace_back(pass, false, pass);
+ }
+ }
+ }
+ return result;
+}
+
+TExprNode::TListType GetKeys(const TExprNode& side, const TExprNode& keys, TExprContext& ctx) {
+ TExprNode::TListType result;
+ result.reserve(keys.ChildrenSize() >> 1U);
+
+ const auto alias = side.IsAtom() ? side.Content() : "";
+ for (auto i = 0U; i < keys.ChildrenSize(); ++i) {
+ if (const auto& al = keys.Child(i++)->Content(); al == alias)
+ result.emplace_back(keys.ChildPtr(i));
+ else
+ result.emplace_back(ctx.NewAtom(keys.Child(i)->Pos(), TStringBuilder() << al << '.' << keys.Child(i)->Content()));
+ }
+ return result;
+}
+
TExprNode::TPtr ExpandPgCall(const TExprNode::TPtr& node, TExprContext& ctx) {
Y_UNUSED(ctx);
auto name = node->Head().Content();
@@ -288,170 +288,170 @@ TExprNode::TPtr ExpandPgCall(const TExprNode::TPtr& node, TExprContext& ctx) {
}
}
-TExprNode::TPtr ExpandEquiJoinImpl(const TExprNode& node, TExprContext& ctx) {
- if (node.ChildrenSize() > 4U) {
- return SplitEquiJoinToPairs(node, ctx);
- }
-
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node.Content();
-
- auto list1 = node.Head().HeadPtr();
- auto list2 = node.Child(1)->HeadPtr();
-
- const auto& renames = GetRenames(node, ctx);
- const auto& joinKind = node.Child(2)->Head().Content();
- if (joinKind == "Cross") {
- return ctx.Builder(node.Pos())
- .Callable("FlatMap")
- .Add(0, std::move(list1))
- .Lambda(1)
- .Param("left")
- .Callable("Map")
- .Add(0, std::move(list2))
- .Lambda(1)
- .Param("right")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (auto& item : renames) {
- parent.List(pos++)
- .Add(0, std::move(std::get<2>(item)))
- .Callable(1, "Member")
- .Arg(0, std::get<bool>(item) ? "left" : "right")
- .Add(1, std::move(std::get<0>(item)))
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- const auto list1type = list1->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
- const auto list2type = list2->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
-
- auto keyMembers1 = GetKeys(node.Head().Tail(), *node.Child(2)->Child(3), ctx);
- auto keyMembers2 = GetKeys(node.Child(1)->Tail(), *node.Child(2)->Child(4), ctx);
-
- MKQL_ENSURE(keyMembers1.size() == keyMembers2.size(), "Expected same key sizes.");
-
- bool optKey = false, badKey = false;
- const bool filter = joinKind == "Inner" || joinKind.ends_with("Semi");
- const bool leftKind = joinKind.starts_with("Left");
- const bool rightKind = joinKind.starts_with("Right");
- TTypeAnnotationNode::TListType keyTypeItems;
- keyTypeItems.reserve(keyMembers1.size());
- for (auto i = 0U; i < keyMembers2.size() && !badKey; ++i) {
- const auto keyType1 = list1type->FindItemType(keyMembers1[i]->Content());
- const auto keyType2 = list2type->FindItemType(keyMembers2[i]->Content());
- if (leftKind) {
- keyTypeItems.emplace_back(JoinDryKeyType(keyType1, keyType2, optKey, ctx));
- } else if (rightKind){
- keyTypeItems.emplace_back(JoinDryKeyType(keyType2, keyType1, optKey, ctx));
- } else {
- keyTypeItems.emplace_back(CommonType<true>(node.Pos(), DryType(keyType1, optKey, ctx), DryType(keyType2, optKey, ctx), ctx));
- optKey = optKey && !filter;
- }
- badKey = !keyTypeItems.back();
- }
-
- if (badKey) {
- if (filter)
- return ctx.NewCallable(node.Pos(), "List", {ExpandType(node.Pos(), *node.GetTypeAnn(), ctx)});
-
- keyTypeItems.clear();
- keyMembers1.clear();
- keyMembers2.clear();
- keyMembers1.emplace_back(MakeBool<true>(node.Pos(), ctx));
- keyMembers2.emplace_back(MakeBool<false>(node.Pos(), ctx));
- }
-
- const bool filter1 = filter || rightKind;
- const bool filter2 = filter || leftKind;
-
- const auto linkSettings = GetEquiJoinLinkSettings(*node.Child(2)->Child(5));
- const bool uniqueLeft = linkSettings.LeftHints.contains("unique") || linkSettings.LeftHints.contains("any");
- const bool uniqueRight = linkSettings.RightHints.contains("unique") || linkSettings.RightHints.contains("any");
-
- TExprNode::TListType flags;
- if (uniqueLeft)
- flags.emplace_back(ctx.NewAtom(node.Pos(), "LeftUnique", TNodeFlags::Default));
- if (uniqueRight)
- flags.emplace_back(ctx.NewAtom(node.Pos(), "RightUnique", TNodeFlags::Default));
-
- TExprNode::TListType payloads1, payloads2;
- for (const auto& rename : renames) {
- (std::get<bool>(rename) ? payloads1 : payloads2).emplace_back(std::get<0>(rename));
- }
-
- const bool payload1 = joinKind != "RightOnly" && joinKind != "RightSemi";
- const bool payload2 = joinKind != "LeftOnly" && joinKind != "LeftSemi";
-
- const bool multi1 = payload1 && !uniqueLeft;
- const bool multi2 = payload2 && !uniqueRight;
-
- list1 = PrepareListForJoin(std::move(list1), keyTypeItems, keyMembers1, payloads1, payload1, optKey, filter1, ctx);
- list2 = PrepareListForJoin(std::move(list2), keyTypeItems, keyMembers2, payloads2, payload2, optKey, filter2, ctx);
-
- return ctx.Builder(node.Pos())
- .Callable("Map")
- .Callable(0, "JoinDict")
- .Add(0, MakeDictForJoin(std::move(list1), payload1, multi1, ctx))
- .Add(1, MakeDictForJoin(std::move(list2), payload2, multi2, ctx))
- .Add(2, node.Child(2)->HeadPtr())
- .List(3).Add(std::move(flags)).Seal()
- .Seal()
- .Lambda(1)
- .Param("row")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- if (payload1 && payload2)
- for (auto& item : renames) {
- parent.List(pos++)
- .Add(0, std::move(std::get<2>(item)))
- .Callable(1, "Member")
- .Callable(0, "Nth")
- .Arg(0, "row")
- .Atom(1, std::get<bool>(item) ? "0" : "1", TNodeFlags::Default)
- .Seal()
- .Add(1, std::move(std::get<0>(item)))
- .Seal()
- .Seal();
- }
- else
- for (auto& item : renames) {
- parent.List(pos++)
- .Add(0, std::move(std::get<2>(item)))
- .Callable(1, "Member")
- .Arg(0, "row")
- .Add(1, std::move(std::get<0>(item)))
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
+TExprNode::TPtr ExpandEquiJoinImpl(const TExprNode& node, TExprContext& ctx) {
+ if (node.ChildrenSize() > 4U) {
+ return SplitEquiJoinToPairs(node, ctx);
+ }
+
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node.Content();
+
+ auto list1 = node.Head().HeadPtr();
+ auto list2 = node.Child(1)->HeadPtr();
+
+ const auto& renames = GetRenames(node, ctx);
+ const auto& joinKind = node.Child(2)->Head().Content();
+ if (joinKind == "Cross") {
+ return ctx.Builder(node.Pos())
+ .Callable("FlatMap")
+ .Add(0, std::move(list1))
+ .Lambda(1)
+ .Param("left")
+ .Callable("Map")
+ .Add(0, std::move(list2))
+ .Lambda(1)
+ .Param("right")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (auto& item : renames) {
+ parent.List(pos++)
+ .Add(0, std::move(std::get<2>(item)))
+ .Callable(1, "Member")
+ .Arg(0, std::get<bool>(item) ? "left" : "right")
+ .Add(1, std::move(std::get<0>(item)))
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ const auto list1type = list1->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+ const auto list2type = list2->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+
+ auto keyMembers1 = GetKeys(node.Head().Tail(), *node.Child(2)->Child(3), ctx);
+ auto keyMembers2 = GetKeys(node.Child(1)->Tail(), *node.Child(2)->Child(4), ctx);
+
+ MKQL_ENSURE(keyMembers1.size() == keyMembers2.size(), "Expected same key sizes.");
+
+ bool optKey = false, badKey = false;
+ const bool filter = joinKind == "Inner" || joinKind.ends_with("Semi");
+ const bool leftKind = joinKind.starts_with("Left");
+ const bool rightKind = joinKind.starts_with("Right");
+ TTypeAnnotationNode::TListType keyTypeItems;
+ keyTypeItems.reserve(keyMembers1.size());
+ for (auto i = 0U; i < keyMembers2.size() && !badKey; ++i) {
+ const auto keyType1 = list1type->FindItemType(keyMembers1[i]->Content());
+ const auto keyType2 = list2type->FindItemType(keyMembers2[i]->Content());
+ if (leftKind) {
+ keyTypeItems.emplace_back(JoinDryKeyType(keyType1, keyType2, optKey, ctx));
+ } else if (rightKind){
+ keyTypeItems.emplace_back(JoinDryKeyType(keyType2, keyType1, optKey, ctx));
+ } else {
+ keyTypeItems.emplace_back(CommonType<true>(node.Pos(), DryType(keyType1, optKey, ctx), DryType(keyType2, optKey, ctx), ctx));
+ optKey = optKey && !filter;
+ }
+ badKey = !keyTypeItems.back();
+ }
+
+ if (badKey) {
+ if (filter)
+ return ctx.NewCallable(node.Pos(), "List", {ExpandType(node.Pos(), *node.GetTypeAnn(), ctx)});
+
+ keyTypeItems.clear();
+ keyMembers1.clear();
+ keyMembers2.clear();
+ keyMembers1.emplace_back(MakeBool<true>(node.Pos(), ctx));
+ keyMembers2.emplace_back(MakeBool<false>(node.Pos(), ctx));
+ }
+
+ const bool filter1 = filter || rightKind;
+ const bool filter2 = filter || leftKind;
+
+ const auto linkSettings = GetEquiJoinLinkSettings(*node.Child(2)->Child(5));
+ const bool uniqueLeft = linkSettings.LeftHints.contains("unique") || linkSettings.LeftHints.contains("any");
+ const bool uniqueRight = linkSettings.RightHints.contains("unique") || linkSettings.RightHints.contains("any");
+
+ TExprNode::TListType flags;
+ if (uniqueLeft)
+ flags.emplace_back(ctx.NewAtom(node.Pos(), "LeftUnique", TNodeFlags::Default));
+ if (uniqueRight)
+ flags.emplace_back(ctx.NewAtom(node.Pos(), "RightUnique", TNodeFlags::Default));
+
+ TExprNode::TListType payloads1, payloads2;
+ for (const auto& rename : renames) {
+ (std::get<bool>(rename) ? payloads1 : payloads2).emplace_back(std::get<0>(rename));
+ }
+
+ const bool payload1 = joinKind != "RightOnly" && joinKind != "RightSemi";
+ const bool payload2 = joinKind != "LeftOnly" && joinKind != "LeftSemi";
+
+ const bool multi1 = payload1 && !uniqueLeft;
+ const bool multi2 = payload2 && !uniqueRight;
+
+ list1 = PrepareListForJoin(std::move(list1), keyTypeItems, keyMembers1, payloads1, payload1, optKey, filter1, ctx);
+ list2 = PrepareListForJoin(std::move(list2), keyTypeItems, keyMembers2, payloads2, payload2, optKey, filter2, ctx);
+
+ return ctx.Builder(node.Pos())
+ .Callable("Map")
+ .Callable(0, "JoinDict")
+ .Add(0, MakeDictForJoin(std::move(list1), payload1, multi1, ctx))
+ .Add(1, MakeDictForJoin(std::move(list2), payload2, multi2, ctx))
+ .Add(2, node.Child(2)->HeadPtr())
+ .List(3).Add(std::move(flags)).Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("row")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ if (payload1 && payload2)
+ for (auto& item : renames) {
+ parent.List(pos++)
+ .Add(0, std::move(std::get<2>(item)))
+ .Callable(1, "Member")
+ .Callable(0, "Nth")
+ .Arg(0, "row")
+ .Atom(1, std::get<bool>(item) ? "0" : "1", TNodeFlags::Default)
+ .Seal()
+ .Add(1, std::move(std::get<0>(item)))
+ .Seal()
+ .Seal();
+ }
+ else
+ for (auto& item : renames) {
+ parent.List(pos++)
+ .Add(0, std::move(std::get<2>(item)))
+ .Callable(1, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(std::get<0>(item)))
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
TExprNode::TPtr PeepHoleConvertGroupBySingleKey(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto keySelectorLambda = node->Child(1);
- if (keySelectorLambda->Tail().GetDependencyScope()->second == keySelectorLambda) {
+ const auto keySelectorLambda = node->Child(1);
+ if (keySelectorLambda->Tail().GetDependencyScope()->second == keySelectorLambda) {
return node;
}
YQL_CLOG(DEBUG, CorePeepHole) << "Convert " << node->Content() << " single key";
- const auto handlerLambda = node->Child(2);
- const auto& keyArg = handlerLambda->Head().Head();
- const auto& listArg = handlerLambda->Head().Tail();
- auto ret = ctx.ReplaceNodes(handlerLambda->TailPtr(), {{&keyArg, keySelectorLambda->TailPtr()}, {&listArg, node->HeadPtr()}});
- return ctx.WrapByCallableIf(handlerLambda->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "ToList", std::move(ret));
+ const auto handlerLambda = node->Child(2);
+ const auto& keyArg = handlerLambda->Head().Head();
+ const auto& listArg = handlerLambda->Head().Tail();
+ auto ret = ctx.ReplaceNodes(handlerLambda->TailPtr(), {{&keyArg, keySelectorLambda->TailPtr()}, {&listArg, node->HeadPtr()}});
+ return ctx.WrapByCallableIf(handlerLambda->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional, "ToList", std::move(ret));
}
TExprNode::TPtr PeepHolePlainKeyForPartitionByKey(const TExprNode::TPtr& node, TExprContext& ctx) {
@@ -481,19 +481,19 @@ TExprNode::TPtr PeepHolePlainKeyForPartitionByKey(const TExprNode::TPtr& node, T
YQL_CLOG(DEBUG, CorePeepHole) << "Plain key for " << node->Content();
return ctx.Builder(node->Pos())
- .Callable(node->Content())
- .Add(0, node->HeadPtr())
+ .Callable(node->Content())
+ .Add(0, node->HeadPtr())
.Lambda(1)
.Param("item")
.Callable("StablePickle")
- .Apply(0, *node->Child(1)).With(0, "item").Seal()
+ .Apply(0, *node->Child(1)).With(0, "item").Seal()
.Seal()
.Seal()
.Add(2, node->ChildPtr(2))
.Add(3, node->ChildPtr(3))
.Lambda(4)
.Param("list")
- .Apply(node->Tail())
+ .Apply(node->Tail())
.With(0)
.Callable("OrderedMap")
.Arg(0, "list")
@@ -504,12 +504,12 @@ TExprNode::TPtr PeepHolePlainKeyForPartitionByKey(const TExprNode::TPtr& node, T
.Add(0, ExpandType(keySelectorLambda->Pos(), *keySelectorLambda->GetTypeAnn(), ctx))
.Callable(1, "Nth")
.Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
+ .Atom(1, "0", TNodeFlags::Default)
.Seal()
.Seal()
.Callable(1, "Nth")
.Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
+ .Atom(1, "1", TNodeFlags::Default)
.Seal()
.Seal()
.Seal()
@@ -521,16 +521,16 @@ TExprNode::TPtr PeepHolePlainKeyForPartitionByKey(const TExprNode::TPtr& node, T
.Build();
}
-TExprNode::TPtr PeepHoleExpandExtractItems(const TExprNode::TPtr& node, TExprContext& ctx) {
+TExprNode::TPtr PeepHoleExpandExtractItems(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
-
- const TCoExtractMembers extract(node);
- const auto& input = extract.Input();
- const auto& members = extract.Members();
- auto arg = ctx.NewArgument(extract.Pos(), "arg");
+
+ const TCoExtractMembers extract(node);
+ const auto& input = extract.Input();
+ const auto& members = extract.Members();
+ auto arg = ctx.NewArgument(extract.Pos(), "arg");
TExprNode::TListType fields;
for (const auto& x : members) {
- fields.emplace_back(ctx.Builder(extract.Pos())
+ fields.emplace_back(ctx.Builder(extract.Pos())
.List()
.Atom(0, x.Value())
.Callable(1, "Member")
@@ -541,30 +541,30 @@ TExprNode::TPtr PeepHoleExpandExtractItems(const TExprNode::TPtr& node, TExprCon
.Build());
}
- auto body = ctx.NewCallable(extract.Pos(), "AsStruct", std::move(fields));
- auto lambda = ctx.NewLambda(extract.Pos(), ctx.NewArguments(extract.Pos(), { std::move(arg) }), std::move(body));
+ auto body = ctx.NewCallable(extract.Pos(), "AsStruct", std::move(fields));
+ auto lambda = ctx.NewLambda(extract.Pos(), ctx.NewArguments(extract.Pos(), { std::move(arg) }), std::move(body));
const bool ordered = input.Ref().GetConstraint<TSortedConstraintNode>();
- return ctx.Builder(extract.Pos())
+ return ctx.Builder(extract.Pos())
.Callable(ordered ? "OrderedMap" : "Map")
.Add(0, input.Ptr())
- .Add(1, std::move(lambda))
+ .Add(1, std::move(lambda))
.Seal()
.Build();
}
-TExprNode::TPtr PeepHoleDictFromKeysToDict(const TExprNode::TPtr& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
-
- const TCoDictFromKeys callable(node);
- const auto itemTypeAnnotation = callable.Type().Ptr()->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- auto list = ctx.Builder(callable.Pos())
+TExprNode::TPtr PeepHoleDictFromKeysToDict(const TExprNode::TPtr& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
+
+ const TCoDictFromKeys callable(node);
+ const auto itemTypeAnnotation = callable.Type().Ptr()->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto list = ctx.Builder(callable.Pos())
.Callable("List")
.Callable(0, "ListType")
- .Add(0, ExpandType(callable.Pos(), *itemTypeAnnotation, ctx))
+ .Add(0, ExpandType(callable.Pos(), *itemTypeAnnotation, ctx))
.Seal()
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
ui32 pos = 0;
- for (auto child : callable.Keys().Ptr()->Children()) {
+ for (auto child : callable.Keys().Ptr()->Children()) {
parent.Add(++pos, child);
}
return parent;
@@ -572,7 +572,7 @@ TExprNode::TPtr PeepHoleDictFromKeysToDict(const TExprNode::TPtr& node, TExprCon
.Seal()
.Build();
- return Build<TCoToDict>(ctx, callable.Pos())
+ return Build<TCoToDict>(ctx, callable.Pos())
.List(list)
.KeySelector()
.Args({"item"})
@@ -590,28 +590,28 @@ TExprNode::TPtr PeepHoleDictFromKeysToDict(const TExprNode::TPtr& node, TExprCon
.Ptr();
}
-TExprNode::TPtr ExpandEquiJoin(const TExprNode::TPtr& input, TExprContext& ctx) {
+TExprNode::TPtr ExpandEquiJoin(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_ENSURE(input->ChildrenSize() >= 4);
- return ExpandEquiJoinImpl(*input, ctx);
+ return ExpandEquiJoinImpl(*input, ctx);
+}
+
+template <bool Strong>
+bool CastMayFail(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target) {
+ return NUdf::ECastOptions::MayFail & CastResult<Strong>(source, target);
}
-template <bool Strong>
-bool CastMayFail(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target) {
- return NUdf::ECastOptions::MayFail & CastResult<Strong>(source, target);
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverData(const TExprNode::TPtr& input, TExprContext& ctx) {
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverData(const TExprNode::TPtr& input, TExprContext& ctx) {
auto from = input->Head().GetTypeAnn()->Cast<TDataExprType>();
auto to = input->GetTypeAnn()->Cast<TDataExprType>();
auto ret = input;
- if constexpr (Strong) {
+ if constexpr (Strong) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content()
- << " for " << *input->Head().GetTypeAnn()
- << " to " << *input->GetTypeAnn();
+ << " for " << *input->Head().GetTypeAnn()
+ << " to " << *input->GetTypeAnn();
ret = ctx.RenameNode(*input, "SafeCast");
- }
-
+ }
+
auto fromFeatures = NUdf::GetDataTypeInfo(from->GetSlot()).Features;
auto toFeatures = NUdf::GetDataTypeInfo(to->GetSlot()).Features;
if ((fromFeatures & NUdf::TzDateType) && (toFeatures & (NUdf::DateType| NUdf::TzDateType)) ||
@@ -627,185 +627,185 @@ TExprNode::TPtr ExpandCastOverData(const TExprNode::TPtr& input, TExprContext& c
.Build();
}
return ret;
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalData(const TExprNode::TPtr& input, TExprContext& ctx) {
- if constexpr (Strong) {
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalData(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if constexpr (Strong) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content()
- << " for " << *input->Head().GetTypeAnn()
- << " to " << *input->GetTypeAnn();
-
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- const auto options = CastResult<false>(sourceType, targetType);
-
- auto casted = options & NUdf::ECastOptions::MayFail ?
- ctx.RenameNode(*input, "SafeCast"):
- ctx.Builder(input->Pos())
- .Callable("Just")
- .Callable(0, "SafeCast")
- .Add(0, input->HeadPtr())
- .Add(1, ExpandType(input->Tail().Pos(), *targetType, ctx))
- .Seal()
- .Seal().Build();
-
- if (options & NUdf::ECastOptions::MayLoseData) {
- casted = ctx.Builder(input->Pos())
- .Callable("Filter")
- .Add(0, std::move(casted))
- .Lambda(1)
- .Param("casted")
- .Callable("==")
- .Add(0, input->HeadPtr())
- .Arg(1, "casted")
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return casted;
- }
-
- return input;
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptional(const TExprNode::TPtr& input, TExprContext& ctx) {
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn();
- const auto sourceItemType = sourceType->Cast<TOptionalExprType>()->GetItemType();
- const auto targetItemType = targetType->Cast<TOptionalExprType>()->GetItemType();
-
- if (ETypeAnnotationKind::Null == targetItemType->GetKind()) {
+ << " for " << *input->Head().GetTypeAnn()
+ << " to " << *input->GetTypeAnn();
+
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ const auto options = CastResult<false>(sourceType, targetType);
+
+ auto casted = options & NUdf::ECastOptions::MayFail ?
+ ctx.RenameNode(*input, "SafeCast"):
+ ctx.Builder(input->Pos())
+ .Callable("Just")
+ .Callable(0, "SafeCast")
+ .Add(0, input->HeadPtr())
+ .Add(1, ExpandType(input->Tail().Pos(), *targetType, ctx))
+ .Seal()
+ .Seal().Build();
+
+ if (options & NUdf::ECastOptions::MayLoseData) {
+ casted = ctx.Builder(input->Pos())
+ .Callable("Filter")
+ .Add(0, std::move(casted))
+ .Lambda(1)
+ .Param("casted")
+ .Callable("==")
+ .Add(0, input->HeadPtr())
+ .Arg(1, "casted")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return casted;
+ }
+
+ return input;
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptional(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn();
+ const auto sourceItemType = sourceType->Cast<TOptionalExprType>()->GetItemType();
+ const auto targetItemType = targetType->Cast<TOptionalExprType>()->GetItemType();
+
+ if (ETypeAnnotationKind::Null == targetItemType->GetKind()) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Null?";
- return ctx.Builder(input->Pos())
- .Callable("If")
- .Callable(0, "Exists")
- .Add(0, input->HeadPtr())
- .Seal()
- .Callable(1, "Null").Seal()
- .Callable(2, "Just")
- .Callable(0, "Null").Seal()
- .Seal()
- .Seal().Build();
- }
-
- const bool opt = CastMayFail<Strong>(sourceItemType, targetItemType);
- const auto sourceLevel = GetOptionalLevel(sourceItemType);
- const auto targetLevel = GetOptionalLevel(targetItemType);
-
- if (opt && targetLevel > 0U) {
+ return ctx.Builder(input->Pos())
+ .Callable("If")
+ .Callable(0, "Exists")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Callable(1, "Null").Seal()
+ .Callable(2, "Just")
+ .Callable(0, "Null").Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ const bool opt = CastMayFail<Strong>(sourceItemType, targetItemType);
+ const auto sourceLevel = GetOptionalLevel(sourceItemType);
+ const auto targetLevel = GetOptionalLevel(targetItemType);
+
+ if (opt && targetLevel > 0U) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content();
- auto stub = ExpandType(input->Tail().Pos(), *targetType, ctx);
- auto type = ExpandType(input->Tail().Pos(), *targetItemType, ctx);
-
- if (sourceLevel == targetLevel) {
- return ctx.Builder(input->Pos())
- .Callable("FlatMap")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("If")
- .Callable(0, "Or")
- .Callable(0, "Exists")
- .Callable(0, input->Content())
- .Arg(0, "item")
- .Add(1, type)
- .Seal()
- .Seal()
- .Callable(1, "Not")
- .Callable(0, "Exists")
- .Arg(0, "item")
- .Seal()
- .Seal()
- .Seal()
- .Callable(1, "Just")
- .Callable(0, input->Content())
- .Arg(0, "item")
- .Add(1, std::move(type))
- .Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, std::move(stub))
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
- } else if (sourceLevel < targetLevel) {
- auto casted = ctx.ChangeChild(*input, 1U, std::move(type));
- return ctx.Builder(input->Pos())
- .Callable("If")
- .Callable(0, "Or")
- .Callable(0, "Exists")
- .Add(0, casted)
- .Seal()
- .Callable(1, "Not")
- .Callable(0, "Exists")
- .Add(0, input->HeadPtr())
- .Seal()
- .Seal()
- .Seal()
- .Callable(1, "Just")
- .Add(0, std::move(casted))
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, std::move(stub))
- .Seal()
- .Seal().Build();
- }
- }
-
- const bool flat = opt || sourceLevel > targetLevel;
- auto type = ExpandType(input->Tail().Pos(), flat ? *targetType : *targetItemType, ctx);
- if (!opt && sourceLevel < targetLevel) {
+ auto stub = ExpandType(input->Tail().Pos(), *targetType, ctx);
+ auto type = ExpandType(input->Tail().Pos(), *targetItemType, ctx);
+
+ if (sourceLevel == targetLevel) {
+ return ctx.Builder(input->Pos())
+ .Callable("FlatMap")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("If")
+ .Callable(0, "Or")
+ .Callable(0, "Exists")
+ .Callable(0, input->Content())
+ .Arg(0, "item")
+ .Add(1, type)
+ .Seal()
+ .Seal()
+ .Callable(1, "Not")
+ .Callable(0, "Exists")
+ .Arg(0, "item")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Callable(1, "Just")
+ .Callable(0, input->Content())
+ .Arg(0, "item")
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, std::move(stub))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ } else if (sourceLevel < targetLevel) {
+ auto casted = ctx.ChangeChild(*input, 1U, std::move(type));
+ return ctx.Builder(input->Pos())
+ .Callable("If")
+ .Callable(0, "Or")
+ .Callable(0, "Exists")
+ .Add(0, casted)
+ .Seal()
+ .Callable(1, "Not")
+ .Callable(0, "Exists")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Callable(1, "Just")
+ .Add(0, std::move(casted))
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, std::move(stub))
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ const bool flat = opt || sourceLevel > targetLevel;
+ auto type = ExpandType(input->Tail().Pos(), flat ? *targetType : *targetItemType, ctx);
+ if (!opt && sourceLevel < targetLevel) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " as Just";
- return ctx.Builder(input->Pos())
- .Callable("Just")
- .Callable(0, input->Content())
- .Add(0, input->HeadPtr())
- .Add(1, std::move(type))
- .Seal()
- .Seal().Build();
- }
-
- const auto worker = flat ? "FlatMap" : "Map";
+ return ctx.Builder(input->Pos())
+ .Callable("Just")
+ .Callable(0, input->Content())
+ .Add(0, input->HeadPtr())
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal().Build();
+ }
+
+ const auto worker = flat ? "FlatMap" : "Map";
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " as " << worker;
- return ctx.Builder(input->Pos())
- .Callable(worker)
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable(input->Content())
- .Arg(0, "item")
- .Add(1, std::move(type))
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverList(const TExprNode::TPtr& input, TExprContext& ctx) {
+ return ctx.Builder(input->Pos())
+ .Callable(worker)
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable(input->Content())
+ .Arg(0, "item")
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverList(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for List";
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn();
- const auto sourceItemType = sourceType->Cast<TListExprType>()->GetItemType();
- const auto targetItemType = targetType->Cast<TListExprType>()->GetItemType();
- const bool opt = CastMayFail<Strong>(sourceItemType, targetItemType);
- auto type = ExpandType(input->Tail().Pos(), opt ? *ctx.MakeType<TOptionalExprType>(targetItemType) : *targetItemType, ctx);
- return ctx.Builder(input->Pos())
- .Callable(opt ? "OrderedFlatMap" : "OrderedMap")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable(input->Content())
- .Arg(0, "item")
- .Add(1, std::move(type))
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn();
+ const auto sourceItemType = sourceType->Cast<TListExprType>()->GetItemType();
+ const auto targetItemType = targetType->Cast<TListExprType>()->GetItemType();
+ const bool opt = CastMayFail<Strong>(sourceItemType, targetItemType);
+ auto type = ExpandType(input->Tail().Pos(), opt ? *ctx.MakeType<TOptionalExprType>(targetItemType) : *targetItemType, ctx);
+ return ctx.Builder(input->Pos())
+ .Callable(opt ? "OrderedFlatMap" : "OrderedMap")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable(input->Content())
+ .Arg(0, "item")
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
template <bool Strong, class TSeqType>
TExprNode::TPtr ExpandCastOverSequence(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for sequence";
@@ -828,769 +828,769 @@ TExprNode::TPtr ExpandCastOverSequence(const TExprNode::TPtr& input, TExprContex
.Seal().Build();
}
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverDict(const TExprNode::TPtr& input, TExprContext& ctx) {
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverDict(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Dict";
- const auto targetType = input->GetTypeAnn();
- const auto targetDictType = targetType->Cast<TDictExprType>();
- const TTypeAnnotationNode::TListType items = {targetDictType->GetKeyType(), targetDictType->GetPayloadType()};
- auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TListExprType>(ctx.MakeType<TTupleExprType>(items)), ctx);
- return ctx.Builder(input->Pos())
- .Callable("ToDict")
- .Callable(0, input->Content())
- .Callable(0, "DictItems")
- .Add(0, input->HeadPtr())
- .Seal()
- .Add(1, std::move(type))
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Callable("Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .List(3)
- .Atom(0, "Hashed", TNodeFlags::Default)
- .Atom(1, "One", TNodeFlags::Default)
- .Seal()
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverTuple(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto targetType = input->GetTypeAnn();
+ const auto targetDictType = targetType->Cast<TDictExprType>();
+ const TTypeAnnotationNode::TListType items = {targetDictType->GetKeyType(), targetDictType->GetPayloadType()};
+ auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TListExprType>(ctx.MakeType<TTupleExprType>(items)), ctx);
+ return ctx.Builder(input->Pos())
+ .Callable("ToDict")
+ .Callable(0, input->Content())
+ .Callable(0, "DictItems")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Callable("Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .List(3)
+ .Atom(0, "Hashed", TNodeFlags::Default)
+ .Atom(1, "One", TNodeFlags::Default)
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverTuple(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Tuple";
- const auto targetType = input->GetTypeAnn();
- const auto& targetItems = targetType->Cast<TTupleExprType>()->GetItems();
- const auto sourceSize = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- TExprNode::TListType castedItems;
- castedItems.reserve(targetItems.size());
- ui32 i = 0U;
- for (const auto& item : targetItems) {
- auto type = ExpandType(input->Tail().Pos(), *item, ctx);
- castedItems.emplace_back(i < sourceSize ?
- ctx.Builder(input->Pos())
- .Callable(input->Content())
- .Callable(0, "Nth")
- .Add(0, input->HeadPtr())
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Add(1, std::move(type))
- .Seal()
- .Build():
- ctx.Builder(input->Pos())
- .Callable("Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Build()
- );
- ++i;
- }
- return ctx.NewList(input->Pos(), std::move(castedItems));
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverStruct(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto targetType = input->GetTypeAnn();
+ const auto& targetItems = targetType->Cast<TTupleExprType>()->GetItems();
+ const auto sourceSize = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ TExprNode::TListType castedItems;
+ castedItems.reserve(targetItems.size());
+ ui32 i = 0U;
+ for (const auto& item : targetItems) {
+ auto type = ExpandType(input->Tail().Pos(), *item, ctx);
+ castedItems.emplace_back(i < sourceSize ?
+ ctx.Builder(input->Pos())
+ .Callable(input->Content())
+ .Callable(0, "Nth")
+ .Add(0, input->HeadPtr())
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal()
+ .Build():
+ ctx.Builder(input->Pos())
+ .Callable("Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Build()
+ );
+ ++i;
+ }
+ return ctx.NewList(input->Pos(), std::move(castedItems));
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverStruct(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Struct";
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn();
- const auto& sourceItems = sourceType->Cast<TStructExprType>()->GetItems();
- std::unordered_set<std::string_view> sourceNames(sourceItems.size());
- for (const auto& item : sourceItems) {
- YQL_ENSURE(sourceNames.emplace(item->GetName()).second);
- }
- const auto& targetItems = targetType->Cast<TStructExprType>()->GetItems();
- TExprNode::TListType castedItems;
- castedItems.reserve(targetItems.size());
- for (const auto& item : targetItems) {
- const auto& name = item->GetName();
- auto type = ExpandType(input->Tail().Pos(), *item->GetItemType(), ctx);
- castedItems.emplace_back(sourceNames.cend() == sourceNames.find(name) ?
- ctx.Builder(input->Pos())
- .List()
- .Atom(0, name)
- .Callable(1, "Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Seal().Build():
- ctx.Builder(input->Pos())
- .List()
- .Atom(0, name)
- .Callable(1, input->Content())
- .Callable(0, "Member")
- .Add(0, input->HeadPtr())
- .Atom(1, name)
- .Seal()
- .Add(1, std::move(type))
- .Seal()
- .Seal().Build()
- );
- }
- return ctx.NewCallable(input->Pos(), "AsStruct", std::move(castedItems));
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverVariant(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn();
+ const auto& sourceItems = sourceType->Cast<TStructExprType>()->GetItems();
+ std::unordered_set<std::string_view> sourceNames(sourceItems.size());
+ for (const auto& item : sourceItems) {
+ YQL_ENSURE(sourceNames.emplace(item->GetName()).second);
+ }
+ const auto& targetItems = targetType->Cast<TStructExprType>()->GetItems();
+ TExprNode::TListType castedItems;
+ castedItems.reserve(targetItems.size());
+ for (const auto& item : targetItems) {
+ const auto& name = item->GetName();
+ auto type = ExpandType(input->Tail().Pos(), *item->GetItemType(), ctx);
+ castedItems.emplace_back(sourceNames.cend() == sourceNames.find(name) ?
+ ctx.Builder(input->Pos())
+ .List()
+ .Atom(0, name)
+ .Callable(1, "Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Seal().Build():
+ ctx.Builder(input->Pos())
+ .List()
+ .Atom(0, name)
+ .Callable(1, input->Content())
+ .Callable(0, "Member")
+ .Add(0, input->HeadPtr())
+ .Atom(1, name)
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal().Build()
+ );
+ }
+ return ctx.NewCallable(input->Pos(), "AsStruct", std::move(castedItems));
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverVariant(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Variant";
- const auto targetType = input->GetTypeAnn();
- const auto targetUnderType = targetType->Cast<TVariantExprType>()->GetUnderlyingType();
- TExprNode::TListType variants, types;
- switch (targetUnderType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto& items = targetUnderType->Cast<TTupleExprType>()->GetItems();
- types.resize(items.size());
- variants.resize(items.size());
- for (ui32 i = 0U; i < variants.size(); ++i) {
- types[i] = ExpandType(input->Tail().Pos(), *items[i], ctx);
- variants[i] = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
- }
- break;
- }
- case ETypeAnnotationKind::Struct: {
- const auto& items = targetUnderType->Cast<TStructExprType>()->GetItems();
- types.resize(items.size());
- variants.resize(items.size());
- for (ui32 i = 0U; i < items.size(); ++i) {
- types[i] = ExpandType(input->Tail().Pos(), *items[i]->GetItemType(), ctx);
- variants[i] = ctx.NewAtom(input->Pos(), items[i]->GetName());
- }
- break;
- }
- default: break;
- }
- const auto type = ExpandType(input->Tail().Pos(), *targetType, ctx);
- return ctx.Builder(input->Pos())
- .Callable("Visit")
- .Add(0, input->HeadPtr())
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < variants.size(); ++i) {
- parent.Add(1 + 2 * i, variants[i]);
- parent.Lambda(2 + 2 * i)
- .Param("item")
- .Callable("Variant")
- .Callable(0, input->Content())
- .Arg(0, "item")
- .Add(1, std::move(types[i]))
- .Seal()
- .Add(1, std::move(variants[i]))
- .Add(2, type)
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalList(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto targetType = input->GetTypeAnn();
+ const auto targetUnderType = targetType->Cast<TVariantExprType>()->GetUnderlyingType();
+ TExprNode::TListType variants, types;
+ switch (targetUnderType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto& items = targetUnderType->Cast<TTupleExprType>()->GetItems();
+ types.resize(items.size());
+ variants.resize(items.size());
+ for (ui32 i = 0U; i < variants.size(); ++i) {
+ types[i] = ExpandType(input->Tail().Pos(), *items[i], ctx);
+ variants[i] = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto& items = targetUnderType->Cast<TStructExprType>()->GetItems();
+ types.resize(items.size());
+ variants.resize(items.size());
+ for (ui32 i = 0U; i < items.size(); ++i) {
+ types[i] = ExpandType(input->Tail().Pos(), *items[i]->GetItemType(), ctx);
+ variants[i] = ctx.NewAtom(input->Pos(), items[i]->GetName());
+ }
+ break;
+ }
+ default: break;
+ }
+ const auto type = ExpandType(input->Tail().Pos(), *targetType, ctx);
+ return ctx.Builder(input->Pos())
+ .Callable("Visit")
+ .Add(0, input->HeadPtr())
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < variants.size(); ++i) {
+ parent.Add(1 + 2 * i, variants[i]);
+ parent.Lambda(2 + 2 * i)
+ .Param("item")
+ .Callable("Variant")
+ .Callable(0, input->Content())
+ .Arg(0, "item")
+ .Add(1, std::move(types[i]))
+ .Seal()
+ .Add(1, std::move(variants[i]))
+ .Add(2, type)
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalList(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for List?";
- const auto targetType = input->GetTypeAnn();
- const auto targetItemType = targetType->Cast<TOptionalExprType>()->GetItemType()->Cast<TListExprType>()->GetItemType();
- auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TOptionalExprType>(targetItemType), ctx);
- auto casted = ctx.Builder(input->Pos())
- .Callable("ListTakeWhile")
- .Callable(0, "ListMap")
- .Callable(0, "LazyList")
- .Add(0, input->HeadPtr())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable(input->Content())
- .Arg(0, "item")
- .Add(1, std::move(type))
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Exists")
- .Arg(0, "item")
- .Seal()
- .Seal()
- .Seal().Build();
-
- auto stub = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
- return ctx.Builder(input->Pos())
- .Callable("If")
- .Callable(0, "==")
- .Callable(0, "Length")
- .Add(0, input->HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, casted)
- .Seal()
- .Seal()
+ const auto targetType = input->GetTypeAnn();
+ const auto targetItemType = targetType->Cast<TOptionalExprType>()->GetItemType()->Cast<TListExprType>()->GetItemType();
+ auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TOptionalExprType>(targetItemType), ctx);
+ auto casted = ctx.Builder(input->Pos())
+ .Callable("ListTakeWhile")
+ .Callable(0, "ListMap")
+ .Callable(0, "LazyList")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable(input->Content())
+ .Arg(0, "item")
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Exists")
+ .Arg(0, "item")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
+ auto stub = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
+ return ctx.Builder(input->Pos())
+ .Callable("If")
+ .Callable(0, "==")
+ .Callable(0, "Length")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, casted)
+ .Seal()
+ .Seal()
.Callable(1, "ListNotNull")
- .Add(0, std::move(casted))
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, std::move(stub))
- .Seal()
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalDict(const TExprNode::TPtr& input, TExprContext& ctx) {
+ .Add(0, std::move(casted))
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, std::move(stub))
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalDict(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Dict?";
- const auto targetType = input->GetTypeAnn();
- const auto targetDictType = targetType->Cast<TOptionalExprType>()->GetItemType()->Cast<TDictExprType>();
- const TTypeAnnotationNode::TListType items = {targetDictType->GetKeyType(), targetDictType->GetPayloadType()};
- auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TOptionalExprType>(ctx.MakeType<TListExprType>(ctx.MakeType<TTupleExprType>(items))), ctx);
- return ctx.Builder(input->Pos())
- .Callable("Map")
- .Callable(0, input->Content())
- .Callable(0, "DictItems")
- .Add(0, input->HeadPtr())
- .Seal()
- .Add(1, std::move(type))
- .Seal()
- .Lambda(1)
- .Param("list")
- .Callable("ToDict")
- .Arg(0, "list")
- .Lambda(1)
- .Param("item")
- .Callable("Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Callable("Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .List(3)
- .Atom(0, "Hashed", TNodeFlags::Default)
- .Atom(1, "One", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-TExprNodeBuilder& BuildExistsChecker(size_t level, TExprNodeBuilder& parent) {
- if (level) {
- parent
- .Callable("IfPresent")
- .Arg(0, "l" + ToString(level))
- .Lambda(1)
- .Param("l" + ToString(--level))
- .Do(std::bind(&BuildExistsChecker, level, std::placeholders::_1))
- .Seal()
- .Callable(2, "Bool")
- .Atom(0, "false", TNodeFlags::Default)
- .Seal()
- .Seal();
- } else {
- parent
- .Callable("Not")
- .Callable(0, "Exists")
- .Arg(0, "l" + ToString(level))
- .Seal()
- .Seal();
- }
- return parent;
-}
-
-TExprNode::TPtr FilterByOptionalItems(TExprNode::TPtr&& casted, TExprNode::TListType&& items, std::vector<size_t>&& levels, TExprContext& ctx) {
- if (items.empty()) {
- return casted;
- }
-
- return ctx.Builder(casted->Pos())
- .Callable("Filter")
- .Add(0, std::move(casted))
- .Lambda(1)
- .Param("casted")
- .Callable("And")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (auto& item : items) {
- const auto& getter = item->Content();
- auto field = item->TailPtr();
- if (auto level = levels[i]) {
- item = ctx.Builder(item->Pos())
- .Callable("IfPresent")
- .Add(0, std::move(item))
- .Lambda(1)
- .Param("l" + ToString(--level))
- .Do(std::bind(&BuildExistsChecker, level, std::placeholders::_1))
- .Seal()
- .Callable(2, "Bool")
- .Atom(0, "false", TNodeFlags::Default)
- .Seal()
- .Seal().Build();
- } else {
- item = ctx.Builder(item->Pos())
- .Callable("Not")
- .Callable(0, "Exists")
- .Add(0, std::move(item))
- .Seal()
- .Seal().Build();
- }
-
- parent
- .Callable(i++, "Or")
- .Callable(0, "Exists")
- .Callable(0, getter)
- .Arg(0, "casted")
- .Add(1, std::move(field))
- .Seal()
- .Seal()
- .Add(1, std::move(item))
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalTuple(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto targetType = input->GetTypeAnn();
+ const auto targetDictType = targetType->Cast<TOptionalExprType>()->GetItemType()->Cast<TDictExprType>();
+ const TTypeAnnotationNode::TListType items = {targetDictType->GetKeyType(), targetDictType->GetPayloadType()};
+ auto type = ExpandType(input->Tail().Pos(), *ctx.MakeType<TOptionalExprType>(ctx.MakeType<TListExprType>(ctx.MakeType<TTupleExprType>(items))), ctx);
+ return ctx.Builder(input->Pos())
+ .Callable("Map")
+ .Callable(0, input->Content())
+ .Callable(0, "DictItems")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Add(1, std::move(type))
+ .Seal()
+ .Lambda(1)
+ .Param("list")
+ .Callable("ToDict")
+ .Arg(0, "list")
+ .Lambda(1)
+ .Param("item")
+ .Callable("Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Callable("Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .List(3)
+ .Atom(0, "Hashed", TNodeFlags::Default)
+ .Atom(1, "One", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNodeBuilder& BuildExistsChecker(size_t level, TExprNodeBuilder& parent) {
+ if (level) {
+ parent
+ .Callable("IfPresent")
+ .Arg(0, "l" + ToString(level))
+ .Lambda(1)
+ .Param("l" + ToString(--level))
+ .Do(std::bind(&BuildExistsChecker, level, std::placeholders::_1))
+ .Seal()
+ .Callable(2, "Bool")
+ .Atom(0, "false", TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ } else {
+ parent
+ .Callable("Not")
+ .Callable(0, "Exists")
+ .Arg(0, "l" + ToString(level))
+ .Seal()
+ .Seal();
+ }
+ return parent;
+}
+
+TExprNode::TPtr FilterByOptionalItems(TExprNode::TPtr&& casted, TExprNode::TListType&& items, std::vector<size_t>&& levels, TExprContext& ctx) {
+ if (items.empty()) {
+ return casted;
+ }
+
+ return ctx.Builder(casted->Pos())
+ .Callable("Filter")
+ .Add(0, std::move(casted))
+ .Lambda(1)
+ .Param("casted")
+ .Callable("And")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (auto& item : items) {
+ const auto& getter = item->Content();
+ auto field = item->TailPtr();
+ if (auto level = levels[i]) {
+ item = ctx.Builder(item->Pos())
+ .Callable("IfPresent")
+ .Add(0, std::move(item))
+ .Lambda(1)
+ .Param("l" + ToString(--level))
+ .Do(std::bind(&BuildExistsChecker, level, std::placeholders::_1))
+ .Seal()
+ .Callable(2, "Bool")
+ .Atom(0, "false", TNodeFlags::Default)
+ .Seal()
+ .Seal().Build();
+ } else {
+ item = ctx.Builder(item->Pos())
+ .Callable("Not")
+ .Callable(0, "Exists")
+ .Add(0, std::move(item))
+ .Seal()
+ .Seal().Build();
+ }
+
+ parent
+ .Callable(i++, "Or")
+ .Callable(0, "Exists")
+ .Callable(0, getter)
+ .Arg(0, "casted")
+ .Add(1, std::move(field))
+ .Seal()
+ .Seal()
+ .Add(1, std::move(item))
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalTuple(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Tuple?";
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- const auto& sourceItems = sourceType->Cast<TTupleExprType>()->GetItems();
- const auto& targetItems = targetType->Cast<TTupleExprType>()->GetItems();
- TExprNode::TListType castedItems, filteredItems, optionalItems;
- std::vector<size_t> optionalLevels;
- castedItems.reserve(targetItems.size());
- filteredItems.reserve(targetItems.size());
- optionalItems.reserve(targetItems.size());
- optionalLevels.reserve(targetItems.size());
- ui32 i = 0U;
- for (const auto& item : targetItems) {
- auto index = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
- auto type = ExpandType(input->Tail().Pos(), *item, ctx);
- if (i >= sourceItems.size()) {
- castedItems.emplace_back(
- ctx.Builder(input->Pos())
- .Callable("Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Build()
- );
- } else {
- auto source = ctx.NewCallable(input->Pos(), "Nth", {input->HeadPtr(), index});
- if (CastMayFail<Strong>(sourceItems[i], targetItems[i])) {
- if (ETypeAnnotationKind::Optional == item->GetKind()) {
- optionalItems.emplace_back(source);
- const auto sourceLevel = GetOptionalLevel(sourceItems[i]);
- const auto targetLevel = GetOptionalLevel(targetItems[i]);
- optionalLevels.emplace_back(sourceLevel > targetLevel ? sourceLevel - targetLevel : 0ULL);
- } else {
- filteredItems.emplace_back(index);
- }
- }
- castedItems.emplace_back(ctx.NewCallable(input->Pos(), input->Content(), {std::move(source), std::move(type)}));
- }
- ++i;
- }
-
- auto casted = ctx.Builder(input->Pos())
- .Callable("Just")
- .List(0)
- .Add(std::move(castedItems))
- .Seal()
- .Seal().Build();
-
- if (!filteredItems.empty()) {
- casted = ctx.Builder(input->Pos())
- .Callable("FilterNullElements")
- .Add(0, std::move(casted))
- .List(1)
- .Add(std::move(filteredItems))
- .Seal()
- .Seal().Build();
- }
-
- casted = FilterByOptionalItems(std::move(casted), std::move(optionalItems), std::move(optionalLevels), ctx);
-
- if (Strong && sourceItems.size() > targetItems.size()) {
- TExprNode::TListType items;
- items.reserve(sourceItems.size() - targetItems.size());
- for (auto i = targetItems.size(); i < sourceItems.size(); ++i) {
- if (sourceItems[i]->GetKind() == ETypeAnnotationKind::Optional) {
- items.emplace_back(ctx.Builder(input->Pos())
- .Callable("Exists")
- .Callable(0, "Nth")
- .Add(0, input->HeadPtr())
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Seal().Build()
- );
- }
- }
-
- if (!items.empty()) {
- auto type = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
- casted = ctx.Builder(input->Pos())
- .Callable("If")
- .Callable(0, "Not")
- .Callable(0, "Or")
- .Add(std::move(items))
- .Seal()
- .Seal()
- .Add(1, std::move(casted))
- .Callable(2, "Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Seal().Build();
- }
- }
-
- return casted;
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalStruct(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ const auto& sourceItems = sourceType->Cast<TTupleExprType>()->GetItems();
+ const auto& targetItems = targetType->Cast<TTupleExprType>()->GetItems();
+ TExprNode::TListType castedItems, filteredItems, optionalItems;
+ std::vector<size_t> optionalLevels;
+ castedItems.reserve(targetItems.size());
+ filteredItems.reserve(targetItems.size());
+ optionalItems.reserve(targetItems.size());
+ optionalLevels.reserve(targetItems.size());
+ ui32 i = 0U;
+ for (const auto& item : targetItems) {
+ auto index = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
+ auto type = ExpandType(input->Tail().Pos(), *item, ctx);
+ if (i >= sourceItems.size()) {
+ castedItems.emplace_back(
+ ctx.Builder(input->Pos())
+ .Callable("Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Build()
+ );
+ } else {
+ auto source = ctx.NewCallable(input->Pos(), "Nth", {input->HeadPtr(), index});
+ if (CastMayFail<Strong>(sourceItems[i], targetItems[i])) {
+ if (ETypeAnnotationKind::Optional == item->GetKind()) {
+ optionalItems.emplace_back(source);
+ const auto sourceLevel = GetOptionalLevel(sourceItems[i]);
+ const auto targetLevel = GetOptionalLevel(targetItems[i]);
+ optionalLevels.emplace_back(sourceLevel > targetLevel ? sourceLevel - targetLevel : 0ULL);
+ } else {
+ filteredItems.emplace_back(index);
+ }
+ }
+ castedItems.emplace_back(ctx.NewCallable(input->Pos(), input->Content(), {std::move(source), std::move(type)}));
+ }
+ ++i;
+ }
+
+ auto casted = ctx.Builder(input->Pos())
+ .Callable("Just")
+ .List(0)
+ .Add(std::move(castedItems))
+ .Seal()
+ .Seal().Build();
+
+ if (!filteredItems.empty()) {
+ casted = ctx.Builder(input->Pos())
+ .Callable("FilterNullElements")
+ .Add(0, std::move(casted))
+ .List(1)
+ .Add(std::move(filteredItems))
+ .Seal()
+ .Seal().Build();
+ }
+
+ casted = FilterByOptionalItems(std::move(casted), std::move(optionalItems), std::move(optionalLevels), ctx);
+
+ if (Strong && sourceItems.size() > targetItems.size()) {
+ TExprNode::TListType items;
+ items.reserve(sourceItems.size() - targetItems.size());
+ for (auto i = targetItems.size(); i < sourceItems.size(); ++i) {
+ if (sourceItems[i]->GetKind() == ETypeAnnotationKind::Optional) {
+ items.emplace_back(ctx.Builder(input->Pos())
+ .Callable("Exists")
+ .Callable(0, "Nth")
+ .Add(0, input->HeadPtr())
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Seal().Build()
+ );
+ }
+ }
+
+ if (!items.empty()) {
+ auto type = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
+ casted = ctx.Builder(input->Pos())
+ .Callable("If")
+ .Callable(0, "Not")
+ .Callable(0, "Or")
+ .Add(std::move(items))
+ .Seal()
+ .Seal()
+ .Add(1, std::move(casted))
+ .Callable(2, "Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ return casted;
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalStruct(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Struct?";
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- const auto& sourceItems = sourceType->Cast<TStructExprType>()->GetItems();
- std::unordered_map<std::string_view, const TTypeAnnotationNode*> sourceNames(sourceItems.size());
- for (const auto& item : sourceItems) {
- YQL_ENSURE(sourceNames.emplace(item->GetName(), item->GetItemType()).second);
- }
- const auto& targetItems = targetType->Cast<TStructExprType>()->GetItems();
- TExprNode::TListType castedItems, filteredItems, optionalItems;
- std::vector<size_t> optionalLevels;
- castedItems.reserve(targetItems.size());
- filteredItems.reserve(targetItems.size());
- optionalItems.reserve(targetItems.size());
- optionalLevels.reserve(targetItems.size());
- for (const auto& item : targetItems) {
- auto name = ctx.NewAtom(input->Pos(), item->GetName());
- auto type = ExpandType(input->Tail().Pos(), *item->GetItemType(), ctx);
- const auto it = sourceNames.find(item->GetName());
- if (sourceNames.cend() == it) {
- castedItems.emplace_back(
- ctx.Builder(input->Pos())
- .List()
- .Add(0, std::move(name))
- .Callable(1, "Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Seal()
- .Build()
- );
- } else {
- auto source = ctx.NewCallable(input->Pos(), "Member", {input->HeadPtr(), name});
- if (CastMayFail<Strong>(it->second, item->GetItemType())) {
- if (ETypeAnnotationKind::Optional == item->GetItemType()->GetKind()) {
- optionalItems.emplace_back(source);
- const auto sourceLevel = GetOptionalLevel(it->second);
- const auto targetLevel = GetOptionalLevel(item->GetItemType());
- optionalLevels.emplace_back(sourceLevel > targetLevel ? sourceLevel - targetLevel : 0ULL);
- } else {
- filteredItems.emplace_back(name);
- }
- }
- sourceNames.erase(it);
- castedItems.emplace_back(
- ctx.Builder(input->Pos())
- .List()
- .Add(0, std::move(name))
- .Callable(1, input->Content())
- .Add(0, std::move(source))
- .Add(1, std::move(type))
- .Seal()
- .Seal()
- .Build()
- );
- }
- }
-
- auto casted = ctx.Builder(input->Pos())
- .Callable("Just")
- .Callable(0, "AsStruct")
- .Add(std::move(castedItems))
- .Seal()
- .Seal().Build();
-
- if (!filteredItems.empty()) {
- casted = ctx.Builder(input->Pos())
- .Callable("FilterNullMembers")
- .Add(0, std::move(casted))
- .List(1)
- .Add(std::move(filteredItems))
- .Seal()
- .Seal().Build();
- }
-
- casted = FilterByOptionalItems(std::move(casted), std::move(optionalItems), std::move(optionalLevels), ctx);
-
- if (Strong && !sourceNames.empty()) {
- TExprNode::TListType items;
- items.reserve(sourceNames.size());
- for (const auto& skipped : sourceNames) {
- if (skipped.second->GetKind() == ETypeAnnotationKind::Optional) {
- items.emplace_back(ctx.Builder(input->Pos())
- .Callable("Exists")
- .Callable(0, "Member")
- .Add(0, input->HeadPtr())
- .Atom(1, skipped.first)
- .Seal()
- .Seal().Build()
- );
- }
- }
-
- if (!items.empty()) {
- auto type = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
- casted = ctx.Builder(input->Pos())
- .Callable("If")
- .Callable(0, "Not")
- .Callable(0, "Or")
- .Add(std::move(items))
- .Seal()
- .Seal()
- .Add(1, std::move(casted))
- .Callable(2, "Nothing")
- .Add(0, std::move(type))
- .Seal()
- .Seal().Build();
- }
- }
-
- return casted;
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCastOverOptionalVariant(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ const auto& sourceItems = sourceType->Cast<TStructExprType>()->GetItems();
+ std::unordered_map<std::string_view, const TTypeAnnotationNode*> sourceNames(sourceItems.size());
+ for (const auto& item : sourceItems) {
+ YQL_ENSURE(sourceNames.emplace(item->GetName(), item->GetItemType()).second);
+ }
+ const auto& targetItems = targetType->Cast<TStructExprType>()->GetItems();
+ TExprNode::TListType castedItems, filteredItems, optionalItems;
+ std::vector<size_t> optionalLevels;
+ castedItems.reserve(targetItems.size());
+ filteredItems.reserve(targetItems.size());
+ optionalItems.reserve(targetItems.size());
+ optionalLevels.reserve(targetItems.size());
+ for (const auto& item : targetItems) {
+ auto name = ctx.NewAtom(input->Pos(), item->GetName());
+ auto type = ExpandType(input->Tail().Pos(), *item->GetItemType(), ctx);
+ const auto it = sourceNames.find(item->GetName());
+ if (sourceNames.cend() == it) {
+ castedItems.emplace_back(
+ ctx.Builder(input->Pos())
+ .List()
+ .Add(0, std::move(name))
+ .Callable(1, "Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Seal()
+ .Build()
+ );
+ } else {
+ auto source = ctx.NewCallable(input->Pos(), "Member", {input->HeadPtr(), name});
+ if (CastMayFail<Strong>(it->second, item->GetItemType())) {
+ if (ETypeAnnotationKind::Optional == item->GetItemType()->GetKind()) {
+ optionalItems.emplace_back(source);
+ const auto sourceLevel = GetOptionalLevel(it->second);
+ const auto targetLevel = GetOptionalLevel(item->GetItemType());
+ optionalLevels.emplace_back(sourceLevel > targetLevel ? sourceLevel - targetLevel : 0ULL);
+ } else {
+ filteredItems.emplace_back(name);
+ }
+ }
+ sourceNames.erase(it);
+ castedItems.emplace_back(
+ ctx.Builder(input->Pos())
+ .List()
+ .Add(0, std::move(name))
+ .Callable(1, input->Content())
+ .Add(0, std::move(source))
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal()
+ .Build()
+ );
+ }
+ }
+
+ auto casted = ctx.Builder(input->Pos())
+ .Callable("Just")
+ .Callable(0, "AsStruct")
+ .Add(std::move(castedItems))
+ .Seal()
+ .Seal().Build();
+
+ if (!filteredItems.empty()) {
+ casted = ctx.Builder(input->Pos())
+ .Callable("FilterNullMembers")
+ .Add(0, std::move(casted))
+ .List(1)
+ .Add(std::move(filteredItems))
+ .Seal()
+ .Seal().Build();
+ }
+
+ casted = FilterByOptionalItems(std::move(casted), std::move(optionalItems), std::move(optionalLevels), ctx);
+
+ if (Strong && !sourceNames.empty()) {
+ TExprNode::TListType items;
+ items.reserve(sourceNames.size());
+ for (const auto& skipped : sourceNames) {
+ if (skipped.second->GetKind() == ETypeAnnotationKind::Optional) {
+ items.emplace_back(ctx.Builder(input->Pos())
+ .Callable("Exists")
+ .Callable(0, "Member")
+ .Add(0, input->HeadPtr())
+ .Atom(1, skipped.first)
+ .Seal()
+ .Seal().Build()
+ );
+ }
+ }
+
+ if (!items.empty()) {
+ auto type = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
+ casted = ctx.Builder(input->Pos())
+ .Callable("If")
+ .Callable(0, "Not")
+ .Callable(0, "Or")
+ .Add(std::move(items))
+ .Seal()
+ .Seal()
+ .Add(1, std::move(casted))
+ .Callable(2, "Nothing")
+ .Add(0, std::move(type))
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ return casted;
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCastOverOptionalVariant(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " for Variant?";
- const auto sourceType = input->Head().GetTypeAnn();
- const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- const auto sourceUnderType = sourceType->Cast<TVariantExprType>()->GetUnderlyingType();
- const auto targetUnderType = targetType->Cast<TVariantExprType>()->GetUnderlyingType();
- TExprNode::TListType variants, types;
- std::vector<std::optional<bool>> checks;
- std::vector<std::optional<ui32>> renumIndex;
- switch (targetUnderType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto& sources = sourceUnderType->Cast<TTupleExprType>()->GetItems();
- const auto& targets = targetUnderType->Cast<TTupleExprType>()->GetItems();
- types.resize(targets.size());
- variants.resize(sources.size());
- checks.resize(sources.size());
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto targetType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ const auto sourceUnderType = sourceType->Cast<TVariantExprType>()->GetUnderlyingType();
+ const auto targetUnderType = targetType->Cast<TVariantExprType>()->GetUnderlyingType();
+ TExprNode::TListType variants, types;
+ std::vector<std::optional<bool>> checks;
+ std::vector<std::optional<ui32>> renumIndex;
+ switch (targetUnderType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto& sources = sourceUnderType->Cast<TTupleExprType>()->GetItems();
+ const auto& targets = targetUnderType->Cast<TTupleExprType>()->GetItems();
+ types.resize(targets.size());
+ variants.resize(sources.size());
+ checks.resize(sources.size());
renumIndex.resize(sources.size());
- for (ui32 i = 0U; i < variants.size(); ++i) {
+ for (ui32 i = 0U; i < variants.size(); ++i) {
renumIndex[i] = i;
- variants[i] = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
- if (i < types.size()) {
- types[i] = ExpandType(input->Tail().Pos(), *targets[i], ctx);
- checks[i] = CastMayFail<Strong>(sources[i], targets[i]);
- }
- }
- break;
- }
- case ETypeAnnotationKind::Struct: {
- const auto sourcesStructType = sourceUnderType->Cast<TStructExprType>();
- const auto targetsStructType = targetUnderType->Cast<TStructExprType>();
- const auto& sources = sourcesStructType->GetItems();
- const auto& targets = targetsStructType->GetItems();
- types.resize(targets.size());
- variants.resize(sources.size());
- checks.resize(sources.size());
+ variants[i] = ctx.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default);
+ if (i < types.size()) {
+ types[i] = ExpandType(input->Tail().Pos(), *targets[i], ctx);
+ checks[i] = CastMayFail<Strong>(sources[i], targets[i]);
+ }
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto sourcesStructType = sourceUnderType->Cast<TStructExprType>();
+ const auto targetsStructType = targetUnderType->Cast<TStructExprType>();
+ const auto& sources = sourcesStructType->GetItems();
+ const auto& targets = targetsStructType->GetItems();
+ types.resize(targets.size());
+ variants.resize(sources.size());
+ checks.resize(sources.size());
renumIndex.resize(sources.size());
- for (ui32 i = 0U; i < variants.size(); ++i) {
- variants[i] = ctx.NewAtom(input->Pos(), sources[i]->GetName());
- if (const auto idx = targetsStructType->FindItem(sources[i]->GetName())) {
- const auto type = targets[*idx]->GetItemType();
+ for (ui32 i = 0U; i < variants.size(); ++i) {
+ variants[i] = ctx.NewAtom(input->Pos(), sources[i]->GetName());
+ if (const auto idx = targetsStructType->FindItem(sources[i]->GetName())) {
+ const auto type = targets[*idx]->GetItemType();
types[*idx] = ExpandType(input->Tail().Pos(), *type, ctx);
- checks[i] = CastMayFail<Strong>(sources[i]->GetItemType(), type);
- renumIndex[i] = *idx;
- }
- }
- break;
- }
- default: break;
- }
- const auto type = ExpandType(input->Tail().Pos(), *targetType, ctx);
- const auto stub = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
- return ctx.Builder(input->Pos())
- .Callable("Visit")
- .Add(0, input->HeadPtr())
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < variants.size(); ++i) {
- parent.Add(1 + 2 * i, variants[i]);
- if (const auto check = checks[i]) {
- if (*check) {
- parent.Lambda(2 + 2 * i)
- .Param("item")
- .Callable("IfPresent")
- .Callable(0, input->Content())
- .Arg(0, "item")
+ checks[i] = CastMayFail<Strong>(sources[i]->GetItemType(), type);
+ renumIndex[i] = *idx;
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+ const auto type = ExpandType(input->Tail().Pos(), *targetType, ctx);
+ const auto stub = ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx);
+ return ctx.Builder(input->Pos())
+ .Callable("Visit")
+ .Add(0, input->HeadPtr())
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < variants.size(); ++i) {
+ parent.Add(1 + 2 * i, variants[i]);
+ if (const auto check = checks[i]) {
+ if (*check) {
+ parent.Lambda(2 + 2 * i)
+ .Param("item")
+ .Callable("IfPresent")
+ .Callable(0, input->Content())
+ .Arg(0, "item")
.Add(1, std::move(types[*renumIndex[i]]))
- .Seal()
- .Lambda(1)
- .Param("casted")
- .Callable("Just")
- .Callable(0, "Variant")
- .Arg(0, "casted")
- .Add(1, std::move(variants[i]))
- .Add(2, type)
- .Seal()
- .Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, stub)
- .Seal()
- .Seal()
- .Seal()
- .Seal();
- } else {
- parent.Lambda(2 + 2 * i)
- .Param("item")
- .Callable("Just")
- .Callable(0, "Variant")
- .Callable(0, input->Content())
- .Arg(0, "item")
+ .Seal()
+ .Lambda(1)
+ .Param("casted")
+ .Callable("Just")
+ .Callable(0, "Variant")
+ .Arg(0, "casted")
+ .Add(1, std::move(variants[i]))
+ .Add(2, type)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, stub)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal();
+ } else {
+ parent.Lambda(2 + 2 * i)
+ .Param("item")
+ .Callable("Just")
+ .Callable(0, "Variant")
+ .Callable(0, input->Content())
+ .Arg(0, "item")
.Add(1, std::move(types[*renumIndex[i]]))
- .Seal()
- .Add(1, std::move(variants[i]))
- .Add(2, type)
- .Seal()
- .Seal()
- .Seal();
- }
- } else {
- parent.Lambda(2 + 2 * i)
- .Param("item")
- .Callable("Nothing")
- .Add(0, stub)
- .Seal()
- .Seal();
- }
- }
- return parent;
- })
- .Seal().Build();
-}
-
-template <bool Strong>
-TExprNode::TPtr ExpandCast(const TExprNode::TPtr& input, TExprContext& ctx) {
- const auto sKind = input->Head().GetTypeAnn()->GetKind();
- const auto tKind = input->GetTypeAnn()->GetKind();
- if (sKind == tKind) {
- switch (sKind) {
- case ETypeAnnotationKind::Data: return ExpandCastOverData<Strong>(input, ctx);
- case ETypeAnnotationKind::Optional: return ExpandCastOverOptional<Strong>(input, ctx);
- case ETypeAnnotationKind::List: return ExpandCastOverList<Strong>(input, ctx);
- case ETypeAnnotationKind::Dict: return ExpandCastOverDict<Strong>(input, ctx);
- case ETypeAnnotationKind::Tuple: return ExpandCastOverTuple<Strong>(input, ctx);
- case ETypeAnnotationKind::Struct: return ExpandCastOverStruct<Strong>(input, ctx);
- case ETypeAnnotationKind::Variant: return ExpandCastOverVariant<Strong>(input, ctx);
+ .Seal()
+ .Add(1, std::move(variants[i]))
+ .Add(2, type)
+ .Seal()
+ .Seal()
+ .Seal();
+ }
+ } else {
+ parent.Lambda(2 + 2 * i)
+ .Param("item")
+ .Callable("Nothing")
+ .Add(0, stub)
+ .Seal()
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal().Build();
+}
+
+template <bool Strong>
+TExprNode::TPtr ExpandCast(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto sKind = input->Head().GetTypeAnn()->GetKind();
+ const auto tKind = input->GetTypeAnn()->GetKind();
+ if (sKind == tKind) {
+ switch (sKind) {
+ case ETypeAnnotationKind::Data: return ExpandCastOverData<Strong>(input, ctx);
+ case ETypeAnnotationKind::Optional: return ExpandCastOverOptional<Strong>(input, ctx);
+ case ETypeAnnotationKind::List: return ExpandCastOverList<Strong>(input, ctx);
+ case ETypeAnnotationKind::Dict: return ExpandCastOverDict<Strong>(input, ctx);
+ case ETypeAnnotationKind::Tuple: return ExpandCastOverTuple<Strong>(input, ctx);
+ case ETypeAnnotationKind::Struct: return ExpandCastOverStruct<Strong>(input, ctx);
+ case ETypeAnnotationKind::Variant: return ExpandCastOverVariant<Strong>(input, ctx);
case ETypeAnnotationKind::Stream: return ExpandCastOverSequence<Strong, TStreamExprType>(input, ctx);
case ETypeAnnotationKind::Flow: return ExpandCastOverSequence<Strong, TFlowExprType>(input, ctx);
- default: break;
- }
- } else if (tKind == ETypeAnnotationKind::Optional) {
- const auto targetItemType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- auto type = ExpandType(input->Tail().Pos(), *targetItemType, ctx);
- if (CastMayFail<Strong>(input->Head().GetTypeAnn(), targetItemType)) {
- if (targetItemType->GetKind() == sKind) {
- switch (sKind) {
- case ETypeAnnotationKind::Data: return ExpandCastOverOptionalData<Strong>(input, ctx);
- case ETypeAnnotationKind::List: return ExpandCastOverOptionalList<Strong>(input, ctx);
- case ETypeAnnotationKind::Dict: return ExpandCastOverOptionalDict<Strong>(input, ctx);
- case ETypeAnnotationKind::Tuple: return ExpandCastOverOptionalTuple<Strong>(input, ctx);
- case ETypeAnnotationKind::Struct: return ExpandCastOverOptionalStruct<Strong>(input, ctx);
- case ETypeAnnotationKind::Variant: return ExpandCastOverOptionalVariant<Strong>(input, ctx);
- default: break;
- }
- } else {
+ default: break;
+ }
+ } else if (tKind == ETypeAnnotationKind::Optional) {
+ const auto targetItemType = input->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ auto type = ExpandType(input->Tail().Pos(), *targetItemType, ctx);
+ if (CastMayFail<Strong>(input->Head().GetTypeAnn(), targetItemType)) {
+ if (targetItemType->GetKind() == sKind) {
+ switch (sKind) {
+ case ETypeAnnotationKind::Data: return ExpandCastOverOptionalData<Strong>(input, ctx);
+ case ETypeAnnotationKind::List: return ExpandCastOverOptionalList<Strong>(input, ctx);
+ case ETypeAnnotationKind::Dict: return ExpandCastOverOptionalDict<Strong>(input, ctx);
+ case ETypeAnnotationKind::Tuple: return ExpandCastOverOptionalTuple<Strong>(input, ctx);
+ case ETypeAnnotationKind::Struct: return ExpandCastOverOptionalStruct<Strong>(input, ctx);
+ case ETypeAnnotationKind::Variant: return ExpandCastOverOptionalVariant<Strong>(input, ctx);
+ default: break;
+ }
+ } else {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " as Map Just";
- return ctx.Builder(input->Pos())
- .Callable("Map")
- .Callable(0, input->Content())
- .Add(0, input->HeadPtr())
- .Add(1, std::move(type))
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Just")
- .Arg(0, "item")
- .Seal()
- .Seal()
- .Seal().Build();
- }
- } else {
+ return ctx.Builder(input->Pos())
+ .Callable("Map")
+ .Callable(0, input->Content())
+ .Add(0, input->HeadPtr())
+ .Add(1, std::move(type))
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Just")
+ .Arg(0, "item")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ } else {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content() << " as Just";
- return ctx.Builder(input->Pos())
- .Callable("Just")
- .Callable(0, input->Content())
- .Add(0, input->HeadPtr())
- .Add(1, std::move(type))
- .Seal()
- .Seal().Build();
- }
+ return ctx.Builder(input->Pos())
+ .Callable("Just")
+ .Callable(0, input->Content())
+ .Add(0, input->HeadPtr())
+ .Add(1, std::move(type))
+ .Seal()
+ .Seal().Build();
+ }
} else if (tKind == ETypeAnnotationKind::List && sKind == ETypeAnnotationKind::EmptyList) {
return ctx.NewCallable(input->Pos(), "List", { ExpandType(input->Pos(), *input->GetTypeAnn(), ctx) });
} else if (tKind == ETypeAnnotationKind::Dict && sKind == ETypeAnnotationKind::EmptyDict) {
return ctx.NewCallable(input->Pos(), "Dict", { ExpandType(input->Pos(), *input->GetTypeAnn(), ctx) });
- }
-
- return input;
-}
-
-TExprNode::TPtr ExpandAlterTo(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto sourceType = node->Head().GetTypeAnn();
- const auto targetType = node->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
-
- if (targetType->GetKind() == ETypeAnnotationKind::Null) {
+ }
+
+ return input;
+}
+
+TExprNode::TPtr ExpandAlterTo(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto sourceType = node->Head().GetTypeAnn();
+ const auto targetType = node->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+
+ if (targetType->GetKind() == ETypeAnnotationKind::Null) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content() << " to " << *targetType;
- return ctx.Builder(node->Pos())
- .Callable("If")
- .Callable(0, "Exists")
- .Add(0, node->HeadPtr())
- .Seal()
- .Add(1, node->TailPtr())
- .Apply(2, *node->Child(2))
- .With(0)
- .Callable("Null").Seal()
- .Done()
- .Seal()
- .Seal().Build();
- }
-
- if (CastMayFail<true>(sourceType, targetType)) {
+ return ctx.Builder(node->Pos())
+ .Callable("If")
+ .Callable(0, "Exists")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Add(1, node->TailPtr())
+ .Apply(2, *node->Child(2))
+ .With(0)
+ .Callable("Null").Seal()
+ .Done()
+ .Seal()
+ .Seal().Build();
+ }
+
+ if (CastMayFail<true>(sourceType, targetType)) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- auto type = ExpandType(node->Child(1)->Pos(), *ctx.MakeType<TOptionalExprType>(targetType), ctx);
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Callable(0, "StrictCast")
- .Add(0, node->HeadPtr())
- .Add(1, std::move(type))
- .Seal()
- .Lambda(1)
- .Param("casted")
- .Apply(*node->Child(2))
- .With(0, "casted")
- .Seal()
- .Seal()
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
-
- auto casted = ctx.NewCallable(node->Pos(), "StrictCast", {node->HeadPtr(), node->ChildPtr(1)});
+ auto type = ExpandType(node->Child(1)->Pos(), *ctx.MakeType<TOptionalExprType>(targetType), ctx);
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Callable(0, "StrictCast")
+ .Add(0, node->HeadPtr())
+ .Add(1, std::move(type))
+ .Seal()
+ .Lambda(1)
+ .Param("casted")
+ .Apply(*node->Child(2))
+ .With(0, "casted")
+ .Seal()
+ .Seal()
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+
+ auto casted = ctx.NewCallable(node->Pos(), "StrictCast", {node->HeadPtr(), node->ChildPtr(1)});
YQL_CLOG(DEBUG, CorePeepHole) << "Replace " << node->Content() << " on " << casted->Content();
- return ctx.ReplaceNode(node->Child(2)->TailPtr(), node->Child(2)->Head().Head(), std::move(casted));
-}
-
+ return ctx.ReplaceNode(node->Child(2)->TailPtr(), node->Child(2)->Head().Head(), std::move(casted));
+}
+
TExprNode::TPtr BuildDictOverListOfStructs(TPositionHandle pos, const TExprNode::TPtr& collection,
const TTypeAnnotationNode*& dictKeyType, TExprContext& ctx)
{
@@ -1621,9 +1621,9 @@ TExprNode::TPtr BuildDictOverListOfStructs(TPositionHandle pos, const TExprNode:
.Seal()
.Seal()
.List(3)
- .Atom(0, "Hashed", TNodeFlags::Default)
- .Atom(1, "One", TNodeFlags::Default)
- .Atom(2, "Compact", TNodeFlags::Default)
+ .Atom(0, "Hashed", TNodeFlags::Default)
+ .Atom(1, "One", TNodeFlags::Default)
+ .Atom(2, "Compact", TNodeFlags::Default)
.Seal()
.Seal()
.Build();
@@ -1646,25 +1646,25 @@ TExprNode::TPtr BuildDictOverList(TPositionHandle pos, const TExprNode::TPtr& co
.Seal()
.Seal()
.List(3)
- .Atom(0, "Hashed", TNodeFlags::Default)
- .Atom(1, "One", TNodeFlags::Default)
- .Atom(2, "Compact", TNodeFlags::Default)
+ .Atom(0, "Hashed", TNodeFlags::Default)
+ .Atom(1, "One", TNodeFlags::Default)
+ .Atom(2, "Compact", TNodeFlags::Default)
.Seal()
.Seal()
.Build();
}
-TExprNode::TPtr BuildDictOverTuple(TExprNode::TPtr&& collection, const TTypeAnnotationNode*& dictKeyType, TExprContext& ctx)
+TExprNode::TPtr BuildDictOverTuple(TExprNode::TPtr&& collection, const TTypeAnnotationNode*& dictKeyType, TExprContext& ctx)
{
- if (!collection->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
- dictKeyType = nullptr;
+ if (!collection->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
+ dictKeyType = nullptr;
return nullptr;
}
- dictKeyType = CommonTypeForChildren(*collection, ctx);
- YQL_ENSURE(dictKeyType, "Uncompatible colllection elements.");
- const auto pos = collection->Pos();
- return ctx.NewCallable(pos, "DictFromKeys", {ExpandType(pos, *dictKeyType, ctx), std::move(collection)});
+ dictKeyType = CommonTypeForChildren(*collection, ctx);
+ YQL_ENSURE(dictKeyType, "Uncompatible colllection elements.");
+ const auto pos = collection->Pos();
+ return ctx.NewCallable(pos, "DictFromKeys", {ExpandType(pos, *dictKeyType, ctx), std::move(collection)});
}
TExprNode::TPtr ExpandSqlIn(const TExprNode::TPtr& input, TExprContext& ctx) {
@@ -1691,16 +1691,16 @@ TExprNode::TPtr ExpandSqlIn(const TExprNode::TPtr& input, TExprContext& ctx) {
if (ansiIn && collectionType->Cast<TTupleExprType>()->GetSize()) {
return ctx.Builder(input->Pos())
.Callable("SqlIn")
- .Callable(0, "AsListStrict")
- .Add(collection->ChildrenList())
- .Seal()
- .Add(1, std::move(lookup))
- .Add(2, std::move(options))
+ .Callable(0, "AsListStrict")
+ .Add(collection->ChildrenList())
+ .Seal()
+ .Add(1, std::move(lookup))
+ .Add(2, std::move(options))
.Seal()
.Build();
}
YQL_CLOG(DEBUG, CorePeepHole) << "IN Tuple";
- dict = BuildDictOverTuple(std::move(collection), dictKeyType, ctx);
+ dict = BuildDictOverTuple(std::move(collection), dictKeyType, ctx);
} else if (collectionType->GetKind() == ETypeAnnotationKind::EmptyDict) {
YQL_CLOG(DEBUG, CorePeepHole) << "IN EmptyDict";
} else if (collectionType->GetKind() == ETypeAnnotationKind::EmptyList) {
@@ -1712,8 +1712,8 @@ TExprNode::TPtr ExpandSqlIn(const TExprNode::TPtr& input, TExprContext& ctx) {
dictKeyType = collectionType->Cast<TDictExprType>()->GetKeyType();
}
- const auto lookupType = lookup->GetTypeAnn();
- const auto falseNode = MakeBool<false>(input->Pos(), ctx);
+ const auto lookupType = lookup->GetTypeAnn();
+ const auto falseNode = MakeBool<false>(input->Pos(), ctx);
const auto justFalseNode = ctx.NewCallable(input->Pos(), "Just", { falseNode });
if (ansiIn && !dict) {
@@ -1724,7 +1724,7 @@ TExprNode::TPtr ExpandSqlIn(const TExprNode::TPtr& input, TExprContext& ctx) {
TExprNode::TPtr contains = falseNode;
if (!dictKeyType) {
YQL_CLOG(DEBUG, CorePeepHole) << "IN: Trivial Contains() due to statically deduced empty collection";
- } else if (NUdf::ECastOptions::Impossible & CastResult<true>(lookupType, dictKeyType)) {
+ } else if (NUdf::ECastOptions::Impossible & CastResult<true>(lookupType, dictKeyType)) {
YQL_CLOG(DEBUG, CorePeepHole) << "IN: Trivial Contains() due to uncompatible type of lookup (" << *lookupType
<< ") and collection item (" << *dictKeyType << ")";
} else {
@@ -1847,102 +1847,102 @@ TExprNode::TPtr ExpandSqlIn(const TExprNode::TPtr& input, TExprContext& ctx) {
return result;
}
-template <ui8 FirstLambdaIndex = 1u, ui8 LastLambdaIndex = FirstLambdaIndex>
-TExprNode::TPtr CleckClosureOnUpperLambdaOverList(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
- for (auto i = FirstLambdaIndex; i <= LastLambdaIndex; ++i) {
- const auto lambda = input->Child(i);
- const auto outerLambda = lambda->GetDependencyScope()->first;
- if (outerLambda && lambda != outerLambda &&
- !SkipCallables(input->Head(), SkippableCallables).IsCallable({"Collect", "AsList", "List", "ListIf"})) {
+template <ui8 FirstLambdaIndex = 1u, ui8 LastLambdaIndex = FirstLambdaIndex>
+TExprNode::TPtr CleckClosureOnUpperLambdaOverList(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
+ for (auto i = FirstLambdaIndex; i <= LastLambdaIndex; ++i) {
+ const auto lambda = input->Child(i);
+ const auto outerLambda = lambda->GetDependencyScope()->first;
+ if (outerLambda && lambda != outerLambda &&
+ !SkipCallables(input->Head(), SkippableCallables).IsCallable({"Collect", "AsList", "List", "ListIf"})) {
YQL_CLOG(DEBUG, CorePeepHole) << input->Content() << " closure on upper lambda over list";
- return ctx.ChangeChild(*input, 0U, ctx.NewCallable(input->Head().Pos(), "Collect", {input->HeadPtr()}));
- }
- }
- }
-
- return input;
-}
-
-template <bool Inverse = false>
-TExprNode::TPtr ExpandFilter(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (ETypeAnnotationKind::Optional == input->GetTypeAnn()->GetKind()) {
+ return ctx.ChangeChild(*input, 0U, ctx.NewCallable(input->Head().Pos(), "Collect", {input->HeadPtr()}));
+ }
+ }
+ }
+
+ return input;
+}
+
+template <bool Inverse = false>
+TExprNode::TPtr ExpandFilter(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (ETypeAnnotationKind::Optional == input->GetTypeAnn()->GetKind()) {
YQL_CLOG(DEBUG, CorePeepHole) << input->Content() << " over Optional";
- auto none = ctx.Builder(input->Pos())
- .Callable("Nothing")
- .Add(0, ExpandType(input->Pos(), *input->GetTypeAnn(), ctx))
- .Seal().Build();
-
- return ctx.Builder(input->Pos())
- .Callable("IfPresent")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("arg")
- .Callable("If")
- .Apply(0, input->Tail()).With(0, "arg").Seal()
- .Add(1, Inverse ? TExprNode::TPtr(none) : input->HeadPtr())
- .Add(2, Inverse ? input->HeadPtr() : TExprNode::TPtr(none))
- .Seal()
- .Seal()
- .Add(2, std::move(none))
- .Seal().Build();
- }
-
- if (input->Head().IsCallable("NarrowMap")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << input->Content() << " with " << input->Head().Content();
- const auto width = input->Head().Tail().Head().ChildrenSize();
- auto children = input->ChildrenList();
- children[1U] = ctx.Builder(children[1U]->Pos())
- .Lambda()
- .Params("items", width)
- .Apply(*children[1U])
- .With(0)
- .Apply(input->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal().Build();
-
- children.front() = input->Head().HeadPtr();
- auto wide = ctx.NewCallable(input->Pos(), "WideFilter", std::move(children));
- return ctx.ChangeChild(input->Head(), 0U, std::move(wide));
- }
-
- return input;
-}
-
+ auto none = ctx.Builder(input->Pos())
+ .Callable("Nothing")
+ .Add(0, ExpandType(input->Pos(), *input->GetTypeAnn(), ctx))
+ .Seal().Build();
+
+ return ctx.Builder(input->Pos())
+ .Callable("IfPresent")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("arg")
+ .Callable("If")
+ .Apply(0, input->Tail()).With(0, "arg").Seal()
+ .Add(1, Inverse ? TExprNode::TPtr(none) : input->HeadPtr())
+ .Add(2, Inverse ? input->HeadPtr() : TExprNode::TPtr(none))
+ .Seal()
+ .Seal()
+ .Add(2, std::move(none))
+ .Seal().Build();
+ }
+
+ if (input->Head().IsCallable("NarrowMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << input->Content() << " with " << input->Head().Content();
+ const auto width = input->Head().Tail().Head().ChildrenSize();
+ auto children = input->ChildrenList();
+ children[1U] = ctx.Builder(children[1U]->Pos())
+ .Lambda()
+ .Params("items", width)
+ .Apply(*children[1U])
+ .With(0)
+ .Apply(input->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal().Build();
+
+ children.front() = input->Head().HeadPtr();
+ auto wide = ctx.NewCallable(input->Pos(), "WideFilter", std::move(children));
+ return ctx.ChangeChild(input->Head(), 0U, std::move(wide));
+ }
+
+ return input;
+}
+
IGraphTransformer::TStatus PeepHoleCommonStage(const TExprNode::TPtr& input, TExprNode::TPtr& output,
- TExprContext& ctx, TTypeAnnotationContext& types, const TPeepHoleOptimizerMap& optimizers)
+ TExprContext& ctx, TTypeAnnotationContext& types, const TPeepHoleOptimizerMap& optimizers)
{
TOptimizeExprSettings settings(&types);
settings.CustomInstantTypeTransformer = types.CustomInstantTypeTransformer.Get();
- return OptimizeExpr(input, output, [&optimizers](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
- if (const auto rule = optimizers.find(node->Content()); optimizers.cend() != rule)
- return (rule->second)(node, ctx);
- return node;
+ return OptimizeExpr(input, output, [&optimizers](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ if (const auto rule = optimizers.find(node->Content()); optimizers.cend() != rule)
+ return (rule->second)(node, ctx);
+ return node;
}, ctx, settings);
}
IGraphTransformer::TStatus PeepHoleFinalStage(const TExprNode::TPtr& input, TExprNode::TPtr& output,
TExprContext& ctx, TTypeAnnotationContext& types, bool* hasNonDeterministicFunctions,
- const TPeepHoleOptimizerMap& optimizers, const TNonDeterministicOptimizerMap& nonDetOptimizers)
+ const TPeepHoleOptimizerMap& optimizers, const TNonDeterministicOptimizerMap& nonDetOptimizers)
{
TOptimizeExprSettings settings(&types);
settings.CustomInstantTypeTransformer = types.CustomInstantTypeTransformer.Get();
- return OptimizeExpr(input, output, [hasNonDeterministicFunctions, &types, &nonDetOptimizers, &optimizers](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
- if (const auto nrule = nonDetOptimizers.find(node->Content()); nonDetOptimizers.cend() != nrule) {
+ return OptimizeExpr(input, output, [hasNonDeterministicFunctions, &types, &nonDetOptimizers, &optimizers](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ if (const auto nrule = nonDetOptimizers.find(node->Content()); nonDetOptimizers.cend() != nrule) {
if (hasNonDeterministicFunctions) {
*hasNonDeterministicFunctions = true;
}
- return (nrule->second)(node, ctx, types);
+ return (nrule->second)(node, ctx, types);
}
- if (const auto rule = optimizers.find(node->Content()); optimizers.cend() != rule)
- return (rule->second)(node, ctx);
- return node;
+ if (const auto rule = optimizers.find(node->Content()); optimizers.cend() != rule)
+ return (rule->second)(node, ctx);
+ return node;
}, ctx, settings);
}
@@ -1960,580 +1960,580 @@ void AddStandardTransformers(TTransformationPipeline& pipelene, IGraphTransforme
"PeepHoleOptTrace", issueCode, "PeepHoleOptTrace");
}
-template<bool FlatOrMulti>
-TExprNode::TPtr FuseNarrowMap(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node.Content() << " with " << node.Head().Content();
- return ctx.Builder(node.Pos())
- .Callable(FlatOrMulti ? "NarrowFlatMap" : "NarrowMultiMap")
- .Add(0, node.Head().HeadPtr())
- .Lambda(1)
- .Params("items", node.Head().Tail().Head().ChildrenSize())
- .Apply(node.Tail())
- .With(0)
- .Apply(node.Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
-}
-
-template <bool Ordered, bool EnableNewOptimizers>
-TExprNode::TPtr ExpandFlatMap(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& lambda = node->Tail();
- const auto& body = lambda.Tail();
- constexpr auto map = Ordered ? "OrderedMap" : "Map";
- if ((node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || body.GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) &&
- body.IsCallable({"Just","AsList"}) && body.ChildrenSize() == 1U) {
-
+template<bool FlatOrMulti>
+TExprNode::TPtr FuseNarrowMap(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node.Content() << " with " << node.Head().Content();
+ return ctx.Builder(node.Pos())
+ .Callable(FlatOrMulti ? "NarrowFlatMap" : "NarrowMultiMap")
+ .Add(0, node.Head().HeadPtr())
+ .Lambda(1)
+ .Params("items", node.Head().Tail().Head().ChildrenSize())
+ .Apply(node.Tail())
+ .With(0)
+ .Apply(node.Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Ordered, bool EnableNewOptimizers>
+TExprNode::TPtr ExpandFlatMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto& lambda = node->Tail();
+ const auto& body = lambda.Tail();
+ constexpr auto map = Ordered ? "OrderedMap" : "Map";
+ if ((node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || body.GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) &&
+ body.IsCallable({"Just","AsList"}) && body.ChildrenSize() == 1U) {
+
YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " to " << map;
- return ctx.Builder(node->Pos())
- .Callable(map)
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With(0, "item").Seal()
- .Seal()
- .Seal().Build();
- }
-
- if constexpr (EnableNewOptimizers) {
- if (const auto kind = node->Head().GetTypeAnn()->GetKind(); (kind == ETypeAnnotationKind::Flow || kind == ETypeAnnotationKind::List) &&
- body.IsCallable("AsList") && body.ChildrenSize() > 1U) {
- constexpr auto multimap = Ordered ? "OrderedMultiMap" : "MultiMap";
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content() << " as " << multimap << " of size " << body.ChildrenSize();
- return ctx.NewCallable(node->Pos(), multimap, {node->HeadPtr(), ctx.DeepCopyLambda(lambda, body.ChildrenList())});
- }
- }
-
- if (body.IsCallable("If") && 3U == body.ChildrenSize() && 1U == body.Tail().ChildrenSize() && body.Tail().IsCallable({"List", "Nothing"}) && (
- (1U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable({"AsList", "Just"})) ||
- (2U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable("List")))) {
- const bool haveSharedCallables = HaveSharedNodes(body.HeadPtr(), body.Child(1)->TailPtr(),
- [&lambda] (const TExprNode::TPtr& node) {
- if (!node->IsCallable())
- return false;
-
- if (node->GetTypeAnn() && node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
- return false;
- }
-
- if (node->IsCallable({"Member", "Nth"}) && node->Head().IsArgument()) {
- return false;
- }
-
- return node->GetDependencyScope()->second == &lambda;
- });
-
- if (!haveSharedCallables) {
- constexpr auto filter = Ordered ? "OrderedFilter" : "Filter";
+ return ctx.Builder(node->Pos())
+ .Callable(map)
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With(0, "item").Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ if constexpr (EnableNewOptimizers) {
+ if (const auto kind = node->Head().GetTypeAnn()->GetKind(); (kind == ETypeAnnotationKind::Flow || kind == ETypeAnnotationKind::List) &&
+ body.IsCallable("AsList") && body.ChildrenSize() > 1U) {
+ constexpr auto multimap = Ordered ? "OrderedMultiMap" : "MultiMap";
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content() << " as " << multimap << " of size " << body.ChildrenSize();
+ return ctx.NewCallable(node->Pos(), multimap, {node->HeadPtr(), ctx.DeepCopyLambda(lambda, body.ChildrenList())});
+ }
+ }
+
+ if (body.IsCallable("If") && 3U == body.ChildrenSize() && 1U == body.Tail().ChildrenSize() && body.Tail().IsCallable({"List", "Nothing"}) && (
+ (1U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable({"AsList", "Just"})) ||
+ (2U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable("List")))) {
+ const bool haveSharedCallables = HaveSharedNodes(body.HeadPtr(), body.Child(1)->TailPtr(),
+ [&lambda] (const TExprNode::TPtr& node) {
+ if (!node->IsCallable())
+ return false;
+
+ if (node->GetTypeAnn() && node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
+ return false;
+ }
+
+ if (node->IsCallable({"Member", "Nth"}) && node->Head().IsArgument()) {
+ return false;
+ }
+
+ return node->GetDependencyScope()->second == &lambda;
+ });
+
+ if (!haveSharedCallables) {
+ constexpr auto filter = Ordered ? "OrderedFilter" : "Filter";
YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over " << body.Content() << " to " << filter;
- auto ret = ctx.Builder(node->Pos())
- .Callable(filter)
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With(0, "item").Seal()
- .Seal()
- .Seal().Build();
-
- if (&body.Child(1)->Tail() != &lambda.Head().Head()) {
- ret = ctx.Builder(node->Pos())
- .Callable(map)
- .Add(0, std::move(ret))
- .Lambda(1)
- .Param("item")
- .ApplyPartial(lambda.HeadPtr(), body.Child(1)->TailPtr()).With(0, "item").Seal()
- .Seal()
- .Seal().Build();
- }
-
- const bool toList = node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::List
- && node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
- return ctx.WrapByCallableIf(toList, "ToList", std::move(ret));
- }
- }
-
- if (ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind()) {
+ auto ret = ctx.Builder(node->Pos())
+ .Callable(filter)
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With(0, "item").Seal()
+ .Seal()
+ .Seal().Build();
+
+ if (&body.Child(1)->Tail() != &lambda.Head().Head()) {
+ ret = ctx.Builder(node->Pos())
+ .Callable(map)
+ .Add(0, std::move(ret))
+ .Lambda(1)
+ .Param("item")
+ .ApplyPartial(lambda.HeadPtr(), body.Child(1)->TailPtr()).With(0, "item").Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ const bool toList = node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::List
+ && node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional;
+ return ctx.WrapByCallableIf(toList, "ToList", std::move(ret));
+ }
+ }
+
+ if (ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind()) {
YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over Optional";
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(node->Tail()).With(0, "item").Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
- .Seal()
- .Seal()
- .Build();
- }
-
- if (node->Head().IsCallable("NarrowMap")) {
- return FuseNarrowMap<true>(*node, ctx);
- }
-
- if (body.IsCallable("NarrowMap") && !IsDepended(body.Tail().Tail(), lambda.Head().Head())) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << body.Content();
- return ctx.ChangeChild(body, 0U, ctx.ChangeChild(*node, 1U, ctx.ChangeChild(lambda, 1U, body.HeadPtr())));
- }
-
- return node;
-}
-
-template<bool Ordered>
-TExprNode::TPtr OptimizeMultiMap(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
- return FuseNarrowMap<false>(*node, ctx);
- } else if (input.IsCallable({"MultiMap", "OrderedMultiMap", "NarrowMultiMap"})) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
- return ctx.NewCallable(node->Pos(), Ordered || input.IsCallable("NarrowMultiMap") ? input.Content() : node->Content(), {input.HeadPtr(), ctx.FuseLambdas(node->Tail(), input.Tail())});
- }
- return node;
-}
-
-TExprNode::TPtr LikelyExclude(const TExprNode::TPtr& node, TExprContext&) {
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(node->Tail()).With(0, "item").Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ if (node->Head().IsCallable("NarrowMap")) {
+ return FuseNarrowMap<true>(*node, ctx);
+ }
+
+ if (body.IsCallable("NarrowMap") && !IsDepended(body.Tail().Tail(), lambda.Head().Head())) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << body.Content();
+ return ctx.ChangeChild(body, 0U, ctx.ChangeChild(*node, 1U, ctx.ChangeChild(lambda, 1U, body.HeadPtr())));
+ }
+
+ return node;
+}
+
+template<bool Ordered>
+TExprNode::TPtr OptimizeMultiMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
+ return FuseNarrowMap<false>(*node, ctx);
+ } else if (input.IsCallable({"MultiMap", "OrderedMultiMap", "NarrowMultiMap"})) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+ return ctx.NewCallable(node->Pos(), Ordered || input.IsCallable("NarrowMultiMap") ? input.Content() : node->Content(), {input.HeadPtr(), ctx.FuseLambdas(node->Tail(), input.Tail())});
+ }
+ return node;
+}
+
+TExprNode::TPtr LikelyExclude(const TExprNode::TPtr& node, TExprContext&) {
YQL_CLOG(DEBUG, CorePeepHole) << "Exclude " << node->Content();
- return node->HeadPtr();
-}
-
-TExprNode::TPtr WrapIteratorForOptionalList(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ return node->HeadPtr();
+}
+
+TExprNode::TPtr WrapIteratorForOptionalList(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
YQL_CLOG(DEBUG, CorePeepHole) << "Wrap " << node->Content() << " for optional list.";
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("list")
- .Callable(node->Content())
- .Arg(0, "list")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 pos = 1U; pos < node->ChildrenSize(); ++pos) {
- parent.Add(pos, node->ChildPtr(pos));
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Callable(2, "EmptyIterator")
- .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-TExprNode::TPtr MapForOptionalContainer(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("list")
+ .Callable(node->Content())
+ .Arg(0, "list")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 pos = 1U; pos < node->ChildrenSize(); ++pos) {
+ parent.Add(pos, node->ChildPtr(pos));
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Callable(2, "EmptyIterator")
+ .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr MapForOptionalContainer(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
YQL_CLOG(DEBUG, CorePeepHole) << "Map " << node->Content() << " for optional container.";
- return ctx.Builder(node->Pos())
- .Callable("Map")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("cont")
- .Callable(node->Content())
- .Arg(0, "cont")
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-template <bool BoolResult, bool ByList = false>
-TExprNode::TPtr RewriteSearchByKeyForTypesMismatch(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto type = node->Head().GetTypeAnn();
+ return ctx.Builder(node->Pos())
+ .Callable("Map")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("cont")
+ .Callable(node->Content())
+ .Arg(0, "cont")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+template <bool BoolResult, bool ByList = false>
+TExprNode::TPtr RewriteSearchByKeyForTypesMismatch(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto type = node->Head().GetTypeAnn();
if constexpr (BoolResult) {
if (IsDataOrOptionalOfData(type)) {
return node;
}
}
- if (type->GetKind() == ETypeAnnotationKind::Optional) {
+ if (type->GetKind() == ETypeAnnotationKind::Optional) {
YQL_CLOG(DEBUG, CorePeepHole) << "Wrap " << node->Content() << " for optional collection.";
- const auto unwrapType = type->Cast<TOptionalExprType>()->GetItemType();
- const auto payloadType = ByList ? unwrapType->Cast<TListExprType>()->GetItemType() : unwrapType->Cast<TDictExprType>()->GetPayloadType();
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("dict")
- .Callable(node->Content())
- .Arg(0, "dict")
- .Add(1, node->TailPtr())
- .Seal()
- .Seal()
- .Add(2, BoolResult ? MakeBool<false>(node->Pos(), ctx) : MakeNothing(node->Pos(), *payloadType, ctx))
- .Seal().Build();
- }
-
- const auto keyType = ByList ? type->Cast<TListExprType>()->GetItemType() : type->Cast<TDictExprType>()->GetKeyType();
-
- if (!IsSameAnnotation(*keyType, *node->Tail().GetTypeAnn())) {
+ const auto unwrapType = type->Cast<TOptionalExprType>()->GetItemType();
+ const auto payloadType = ByList ? unwrapType->Cast<TListExprType>()->GetItemType() : unwrapType->Cast<TDictExprType>()->GetPayloadType();
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("dict")
+ .Callable(node->Content())
+ .Arg(0, "dict")
+ .Add(1, node->TailPtr())
+ .Seal()
+ .Seal()
+ .Add(2, BoolResult ? MakeBool<false>(node->Pos(), ctx) : MakeNothing(node->Pos(), *payloadType, ctx))
+ .Seal().Build();
+ }
+
+ const auto keyType = ByList ? type->Cast<TListExprType>()->GetItemType() : type->Cast<TDictExprType>()->GetKeyType();
+
+ if (!IsSameAnnotation(*keyType, *node->Tail().GetTypeAnn())) {
YQL_CLOG(DEBUG, CorePeepHole) << "Wrap " << node->Content() << " for key type mismatch.";
- const auto payloadType = ByList ? type->Cast<TListExprType>()->GetItemType() : type->Cast<TDictExprType>()->GetPayloadType();
- return ctx.Builder(node->Pos())
- .Callable("AlterTo")
- .Add(0, node->TailPtr())
- .Add(1, ExpandType(node->Pos(), *keyType, ctx))
- .Lambda(2)
- .Param("converted")
- .Callable(node->Content())
- .Add(0, node->HeadPtr())
- .Arg(1, "converted")
- .Seal()
- .Seal()
- .Add(3, BoolResult ? MakeBool<false>(node->Pos(), ctx) : MakeNothing(node->Pos(), *payloadType, ctx))
- .Seal().Build();
- }
-
- return node;
-}
-
-TExprNode::TPtr ExpandListHas(const TExprNode::TPtr& input, TExprContext& ctx) {
- const auto type = input->Head().GetTypeAnn();
- if (ETypeAnnotationKind::List == type->GetKind() &&
- IsSameAnnotation(*type->Cast<TListExprType>()->GetItemType(), *input->Tail().GetTypeAnn())) {
+ const auto payloadType = ByList ? type->Cast<TListExprType>()->GetItemType() : type->Cast<TDictExprType>()->GetPayloadType();
+ return ctx.Builder(node->Pos())
+ .Callable("AlterTo")
+ .Add(0, node->TailPtr())
+ .Add(1, ExpandType(node->Pos(), *keyType, ctx))
+ .Lambda(2)
+ .Param("converted")
+ .Callable(node->Content())
+ .Add(0, node->HeadPtr())
+ .Arg(1, "converted")
+ .Seal()
+ .Seal()
+ .Add(3, BoolResult ? MakeBool<false>(node->Pos(), ctx) : MakeNothing(node->Pos(), *payloadType, ctx))
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr ExpandListHas(const TExprNode::TPtr& input, TExprContext& ctx) {
+ const auto type = input->Head().GetTypeAnn();
+ if (ETypeAnnotationKind::List == type->GetKind() &&
+ IsSameAnnotation(*type->Cast<TListExprType>()->GetItemType(), *input->Tail().GetTypeAnn())) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content();
- return ctx.Builder(input->Pos())
- .Callable("Exists")
- .Callable(0, "Head")
- .Callable(0, "SkipWhile")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("AggrNotEquals")
- .Arg(0, "item")
- .Add(1, input->TailPtr())
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return RewriteSearchByKeyForTypesMismatch<true, true>(input, ctx);
-}
-
-template <bool Flat, bool List>
-TExprNode::TPtr ExpandContainerIf(const TExprNode::TPtr& input, TExprContext& ctx) {
+ return ctx.Builder(input->Pos())
+ .Callable("Exists")
+ .Callable(0, "Head")
+ .Callable(0, "SkipWhile")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("AggrNotEquals")
+ .Arg(0, "item")
+ .Add(1, input->TailPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return RewriteSearchByKeyForTypesMismatch<true, true>(input, ctx);
+}
+
+template <bool Flat, bool List>
+TExprNode::TPtr ExpandContainerIf(const TExprNode::TPtr& input, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content();
- auto item = Flat ? input->TailPtr() : ctx.NewCallable(input->Tail().Pos(), List ? "AsList" : "Just", {input->TailPtr()});
- auto none = ctx.NewCallable(input->Tail().Pos(), List ? "List" : "Nothing", {ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx)});
- return ctx.NewCallable(input->Pos(), "If", {input->HeadPtr(), std::move(item), std::move(none)});
-}
-
-TExprNode::TPtr ExpandPartitionsByKeys(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto item = Flat ? input->TailPtr() : ctx.NewCallable(input->Tail().Pos(), List ? "AsList" : "Just", {input->TailPtr()});
+ auto none = ctx.NewCallable(input->Tail().Pos(), List ? "List" : "Nothing", {ExpandType(input->Tail().Pos(), *input->GetTypeAnn(), ctx)});
+ return ctx.NewCallable(input->Pos(), "If", {input->HeadPtr(), std::move(item), std::move(none)});
+}
+
+TExprNode::TPtr ExpandPartitionsByKeys(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- TExprNode::TPtr sort;
- if (node->Child(2)->IsCallable("Void") || node->Child(3)->IsCallable("Void")) {
- sort = ctx.NewCallable(node->Pos(), "Sort", {node->HeadPtr(), MakeBool<true>(node->Pos(), ctx), node->ChildPtr(1)});
- } else {
- if (node->Child(2)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- if (const auto size = node->Child(2)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
- sort = ctx.Builder(node->Pos())
- .Callable("Sort")
- .Add(0, node->HeadPtr())
- .List(1)
- .Callable(0, "Bool")
- .Atom(0, "true", TNodeFlags::Default)
- .Seal()
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- const bool isList = node->Child(2)->IsList();
- for (ui32 i = 0U; i < size; ++i) {
- if (isList) {
- parent.Add(i + 1U, node->Child(2)->ChildPtr(i));
- } else {
- parent.Callable(i + 1U, "Nth")
- .Add(0, node->ChildPtr(2))
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Lambda(2)
- .Param("item")
- .List()
- .Apply(0, *node->Child(1))
- .With(0, "item")
- .Seal()
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 pos = 0U; pos < size; ++pos) {
- parent.Callable(pos + 1U, "Nth")
- .Apply(0, *node->Child(3))
- .With(0, "item")
- .Seal()
- .Atom(1, ToString(pos), TNodeFlags::Default)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
- } else {
- sort = ctx.Builder(node->Pos())
- .Callable("Sort")
- .Add(0, node->HeadPtr())
- .List(1)
- .Callable(0, "Bool")
- .Atom(0, "true", TNodeFlags::Default)
- .Seal()
- .Add(1, node->ChildPtr(2))
- .Seal()
- .Lambda(2)
- .Param("item")
- .List()
- .Apply(0, *node->Child(1))
- .With(0, "item")
- .Seal()
- .Apply(1, *node->Child(3))
- .With(0, "item")
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
-
- return ctx.ReplaceNode(node->Tail().TailPtr(), node->Tail().Head().Head(), std::move(sort));
-}
-
-TExprNode::TPtr ExpandIsKeySwitch(const TExprNode::TPtr& node, TExprContext& ctx) {
+ TExprNode::TPtr sort;
+ if (node->Child(2)->IsCallable("Void") || node->Child(3)->IsCallable("Void")) {
+ sort = ctx.NewCallable(node->Pos(), "Sort", {node->HeadPtr(), MakeBool<true>(node->Pos(), ctx), node->ChildPtr(1)});
+ } else {
+ if (node->Child(2)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ if (const auto size = node->Child(2)->GetTypeAnn()->Cast<TTupleExprType>()->GetSize()) {
+ sort = ctx.Builder(node->Pos())
+ .Callable("Sort")
+ .Add(0, node->HeadPtr())
+ .List(1)
+ .Callable(0, "Bool")
+ .Atom(0, "true", TNodeFlags::Default)
+ .Seal()
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ const bool isList = node->Child(2)->IsList();
+ for (ui32 i = 0U; i < size; ++i) {
+ if (isList) {
+ parent.Add(i + 1U, node->Child(2)->ChildPtr(i));
+ } else {
+ parent.Callable(i + 1U, "Nth")
+ .Add(0, node->ChildPtr(2))
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .List()
+ .Apply(0, *node->Child(1))
+ .With(0, "item")
+ .Seal()
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 pos = 0U; pos < size; ++pos) {
+ parent.Callable(pos + 1U, "Nth")
+ .Apply(0, *node->Child(3))
+ .With(0, "item")
+ .Seal()
+ .Atom(1, ToString(pos), TNodeFlags::Default)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ } else {
+ sort = ctx.Builder(node->Pos())
+ .Callable("Sort")
+ .Add(0, node->HeadPtr())
+ .List(1)
+ .Callable(0, "Bool")
+ .Atom(0, "true", TNodeFlags::Default)
+ .Seal()
+ .Add(1, node->ChildPtr(2))
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .List()
+ .Apply(0, *node->Child(1))
+ .With(0, "item")
+ .Seal()
+ .Apply(1, *node->Child(3))
+ .With(0, "item")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ return ctx.ReplaceNode(node->Tail().TailPtr(), node->Tail().Head().Head(), std::move(sort));
+}
+
+TExprNode::TPtr ExpandIsKeySwitch(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- return ctx.Builder(node->Pos())
- .Callable("AggrNotEquals")
- .Add(0, ctx.ReplaceNode(node->Child(2)->TailPtr(), node->Child(2)->Head().Head(), node->ChildPtr(0)))
- .Add(1, ctx.ReplaceNode(node->Child(3)->TailPtr(), node->Child(3)->Head().Head(), node->ChildPtr(1)))
- .Seal().Build();
-}
-
-TExprNode::TPtr ExpandMux(const TExprNode::TPtr& node, TExprContext& ctx) {
+ return ctx.Builder(node->Pos())
+ .Callable("AggrNotEquals")
+ .Add(0, ctx.ReplaceNode(node->Child(2)->TailPtr(), node->Child(2)->Head().Head(), node->ChildPtr(0)))
+ .Add(1, ctx.ReplaceNode(node->Child(3)->TailPtr(), node->Child(3)->Head().Head(), node->ChildPtr(1)))
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExpandMux(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- const auto varType = ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx);
- TExprNode::TListType lists;
- switch (node->Head().GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto type = node->Head().GetTypeAnn()->Cast<TTupleExprType>();
- lists.resize(type->GetSize());
- for (ui32 i = 0U; i < lists.size(); ++i) {
- lists[i] = ctx.Builder(node->Head().Pos())
+ const auto varType = ExpandType(node->Pos(), *GetSeqItemType(node->GetTypeAnn()), ctx);
+ TExprNode::TListType lists;
+ switch (node->Head().GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto type = node->Head().GetTypeAnn()->Cast<TTupleExprType>();
+ lists.resize(type->GetSize());
+ for (ui32 i = 0U; i < lists.size(); ++i) {
+ lists[i] = ctx.Builder(node->Head().Pos())
.Callable("OrderedMap")
- .Callable(0, "Nth")
- .Add(0, node->HeadPtr())
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Variant")
- .Arg(0, "item")
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Add(2, varType)
- .Seal()
- .Seal()
- .Seal().Build();
- }
- return ctx.NewCallable(node->Pos(), "Extend", std::move(lists));
- }
- case ETypeAnnotationKind::Struct: {
- const auto type = node->Head().GetTypeAnn()->Cast<TStructExprType>();
- lists.reserve(type->GetSize());
- for (const auto& item : type->GetItems()) {
- lists.emplace_back(
- ctx.Builder(node->Head().Pos())
+ .Callable(0, "Nth")
+ .Add(0, node->HeadPtr())
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Variant")
+ .Arg(0, "item")
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Add(2, varType)
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ return ctx.NewCallable(node->Pos(), "Extend", std::move(lists));
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto type = node->Head().GetTypeAnn()->Cast<TStructExprType>();
+ lists.reserve(type->GetSize());
+ for (const auto& item : type->GetItems()) {
+ lists.emplace_back(
+ ctx.Builder(node->Head().Pos())
.Callable("OrderedMap")
- .Callable(0, "Member")
- .Add(0, node->HeadPtr())
- .Atom(1, item->GetName())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Variant")
- .Arg(0, "item")
- .Atom(1, item->GetName())
- .Add(2, varType)
- .Seal()
- .Seal()
- .Seal().Build()
- );
- }
- return ctx.NewCallable(node->Pos(), "Extend", std::move(lists));
- }
- default: break;
- }
-
- return node;
-}
-
-TExprNode::TPtr ExpandLMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ .Callable(0, "Member")
+ .Add(0, node->HeadPtr())
+ .Atom(1, item->GetName())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Variant")
+ .Arg(0, "item")
+ .Atom(1, item->GetName())
+ .Add(2, varType)
+ .Seal()
+ .Seal()
+ .Seal().Build()
+ );
+ }
+ return ctx.NewCallable(node->Pos(), "Extend", std::move(lists));
+ }
+ default: break;
+ }
+
+ return node;
+}
+
+TExprNode::TPtr ExpandLMap(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- return ctx.Builder(node->Pos())
- .Callable("Collect")
- .Apply(0, node->Tail())
- .With(0)
- .Callable("Iterator")
- .Add(0, node->HeadPtr())
- .Seal()
- .Done()
- .Seal()
- .Seal().Build();
-}
-
-TExprNode::TPtr ExpandDemux(const TExprNode::TPtr& node, TExprContext& ctx) {
+ return ctx.Builder(node->Pos())
+ .Callable("Collect")
+ .Apply(0, node->Tail())
+ .With(0)
+ .Callable("Iterator")
+ .Add(0, node->HeadPtr())
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal().Build();
+}
+
+TExprNode::TPtr ExpandDemux(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- TExprNode::TListType lists;
- switch (node->GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto type = node->GetTypeAnn()->Cast<TTupleExprType>();
- lists.resize(type->GetSize());
- for (ui32 i = 0U; i < lists.size(); ++i) {
- lists[i] = ctx.Builder(node->Head().Pos())
+ TExprNode::TListType lists;
+ switch (node->GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto type = node->GetTypeAnn()->Cast<TTupleExprType>();
+ lists.resize(type->GetSize());
+ for (ui32 i = 0U; i < lists.size(); ++i) {
+ lists[i] = ctx.Builder(node->Head().Pos())
.Callable("OrderedFlatMap")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Guess")
- .Arg(0, "item")
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal().Build();
- }
- return ctx.NewList(node->Pos(), std::move(lists));
- }
- case ETypeAnnotationKind::Struct: {
- const auto type = node->GetTypeAnn()->Cast<TStructExprType>();
- lists.reserve(type->GetSize());
- for (const auto& item : type->GetItems()) {
- lists.emplace_back(
- ctx.Builder(node->Head().Pos())
- .List()
- .Atom(0, item->GetName())
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Guess")
+ .Arg(0, "item")
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ return ctx.NewList(node->Pos(), std::move(lists));
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto type = node->GetTypeAnn()->Cast<TStructExprType>();
+ lists.reserve(type->GetSize());
+ for (const auto& item : type->GetItems()) {
+ lists.emplace_back(
+ ctx.Builder(node->Head().Pos())
+ .List()
+ .Atom(0, item->GetName())
.Callable(1, "OrderedFlatMap")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Guess")
- .Arg(0, "item")
- .Atom(1, item->GetName())
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build()
- );
- }
- return ctx.NewCallable(node->Pos(), "AsStruct", std::move(lists));
- }
- default: break;
- }
-
- return node;
-}
-
-TExprNode::TPtr ExpandOptionalReduce(const TExprNode::TPtr& node, TExprContext& ctx) {
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Guess")
+ .Arg(0, "item")
+ .Atom(1, item->GetName())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build()
+ );
+ }
+ return ctx.NewCallable(node->Pos(), "AsStruct", std::move(lists));
+ }
+ default: break;
+ }
+
+ return node;
+}
+
+TExprNode::TPtr ExpandOptionalReduce(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->ChildPtr(0))
- .Lambda(1)
- .Param("lhs")
- .Callable("IfPresent")
- .Add(0, node->ChildPtr(1))
- .Lambda(1)
- .Param("rhs")
- .Callable("Just")
- .Apply(0, node->Tail())
- .With(0, "lhs")
- .With(1, "rhs")
- .Seal()
- .Seal()
- .Seal()
- .Add(2, node->ChildPtr(0))
- .Seal()
- .Seal()
- .Add(2, node->ChildPtr(1))
- .Seal().Build();
-}
-
-template <bool MinOrMax>
-TExprNode::TPtr ExpandAggrMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (IsDataOrOptionalOfData(node->GetTypeAnn())) {
- return node;
- }
-
- if (ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind()) {
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->ChildPtr(0))
+ .Lambda(1)
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Add(0, node->ChildPtr(1))
+ .Lambda(1)
+ .Param("rhs")
+ .Callable("Just")
+ .Apply(0, node->Tail())
+ .With(0, "lhs")
+ .With(1, "rhs")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, node->ChildPtr(0))
+ .Seal()
+ .Seal()
+ .Add(2, node->ChildPtr(1))
+ .Seal().Build();
+}
+
+template <bool MinOrMax>
+TExprNode::TPtr ExpandAggrMinMax(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (IsDataOrOptionalOfData(node->GetTypeAnn())) {
+ return node;
+ }
+
+ if (ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind()) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content() << " over Optional";
- return ctx.Builder(node->Pos())
- .Callable("OptionalReduce")
- .Add(0, node->HeadPtr())
- .Add(1, node->TailPtr())
- .Lambda(2)
- .Param("lhs")
- .Param("rhs")
- .Callable(node->Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
+ return ctx.Builder(node->Pos())
+ .Callable("OptionalReduce")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->TailPtr())
+ .Lambda(2)
+ .Param("lhs")
+ .Param("rhs")
+ .Callable(node->Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- return ctx.Builder(node->Pos())
- .Callable("If")
- .Callable(0, MinOrMax ? "AggrLessOrEqual" : "AggrGreaterOrEqual")
- .Add(0, node->HeadPtr())
- .Add(1, node->TailPtr())
- .Seal()
- .Add(1, node->HeadPtr())
- .Add(2, node->TailPtr())
- .Seal().Build();
-}
-
-template <bool Ordered, bool EnableNewOptimizers>
-TExprNode::TPtr OptimizeMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ return ctx.Builder(node->Pos())
+ .Callable("If")
+ .Callable(0, MinOrMax ? "AggrLessOrEqual" : "AggrGreaterOrEqual")
+ .Add(0, node->HeadPtr())
+ .Add(1, node->TailPtr())
+ .Seal()
+ .Add(1, node->HeadPtr())
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+}
+
+template <bool Ordered, bool EnableNewOptimizers>
+TExprNode::TPtr OptimizeMap(const TExprNode::TPtr& node, TExprContext& ctx) {
const auto& arg = node->Tail().Head().Head();
- if constexpr (EnableNewOptimizers) {
+ if constexpr (EnableNewOptimizers) {
if (!arg.IsUsedInDependsOn() && ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over Optional";
- return ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("Just")
- .Apply(0, node->TailPtr()).With(0, "item").Seal()
- .Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
- .Seal()
- .Seal()
- .Build();
- }
-
+ YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over Optional";
+ return ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("Just")
+ .Apply(0, node->TailPtr()).With(0, "item").Seal()
+ .Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
if (const auto& input = node->Head(); !arg.IsUsedInDependsOn() && input.IsCallable("AsList")) {
- TNodeSet uniqueItems(input.ChildrenSize());
- input.ForEachChild([&uniqueItems](const TExprNode& item){ uniqueItems.emplace(&item); });
+ TNodeSet uniqueItems(input.ChildrenSize());
+ input.ForEachChild([&uniqueItems](const TExprNode& item){ uniqueItems.emplace(&item); });
if (uniqueItems.size() < 0x10U) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Eliminate " << node->Content() << " over list of " << uniqueItems.size();
- auto list = input.ChildrenList();
- for (auto& item : list) {
- item = ctx.ReplaceNode(node->Tail().TailPtr(), arg, std::move(item));
- }
- return ctx.ChangeChildren(input, std::move(list));
- }
- }
- }
-
- if (node->Head().IsCallable("NarrowMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Eliminate " << node->Content() << " over list of " << uniqueItems.size();
+ auto list = input.ChildrenList();
+ for (auto& item : list) {
+ item = ctx.ReplaceNode(node->Tail().TailPtr(), arg, std::move(item));
+ }
+ return ctx.ChangeChildren(input, std::move(list));
+ }
+ }
+ }
+
+ if (node->Head().IsCallable("NarrowMap")) {
if (!arg.IsUsedInDependsOn()) {
YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << node->Head().Content();
const auto width = node->Head().Tail().Head().ChildrenSize();
@@ -2550,64 +2550,64 @@ TExprNode::TPtr OptimizeMap(const TExprNode::TPtr& node, TExprContext& ctx) {
.Seal().Build();
return ctx.ChangeChild(node->Head(), 1U, std::move(lambda));
}
- }
-
+ }
+
if (1U == node->Head().UseCount() && !arg.IsUsedInDependsOn()) {
- if (node->Head().IsCallable({"Map", "OrderedMap"})) {
+ if (node->Head().IsCallable({"Map", "OrderedMap"})) {
YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " over " << node->Head().Content();
- auto lambda = ctx.Builder(node->Pos())
- .Lambda()
- .Param("it")
- .Apply(node->Tail())
- .With(0)
- .Apply(node->Head().Tail())
- .With(0, "it")
- .Seal()
- .Done()
- .Seal()
- .Seal().Build();
- return ctx.ChangeChildren(Ordered ? node->Head() : *node, {node->Head().HeadPtr(), std::move(lambda)});
- }
- }
- return node;
-}
-
-TExprNode::TPtr OptimizeSkip(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable({"Map", "OrderedMap", "ExpandMap", "WideMap", "NarrowMap"})) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
- return ctx.SwapWithHead(*node);
- }
-
- return node;
-}
-
-template <bool EnableNewOptimizers>
-TExprNode::TPtr OptimizeTake(const TExprNode::TPtr& node, TExprContext& ctx) {
- if constexpr (EnableNewOptimizers) {
- if (const auto& input = node->Head(); input.IsCallable({"Filter", "OrderedFilter", "WideFilter"}) && 2U == input.ChildrenSize()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Inject " << node->Content() << " limit into " << input.Content();
- auto list = input.ChildrenList();
- list.emplace_back(node->TailPtr());
- return ctx.ChangeChildren(input, std::move(list));
- }
-
- if (const auto& input = node->Head(); 1U == input.UseCount()) {
- if (input.IsCallable("Sort")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " over " << input.Content();
- auto children = input.ChildrenList();
- auto it = children.cbegin();
- children.emplace(++it, node->TailPtr());
- return ctx.NewCallable(node->Pos(), "TopSort", std::move(children));
- } else if (input.IsCallable({"Top", "TopSort"})) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " over " << input.Content();
- return ctx.ChangeChild(input, 1U, ctx.NewCallable(node->Pos(), "Min", {node->TailPtr(), input.ChildPtr(1)}));
- }
- }
- }
-
- return OptimizeSkip(node, ctx);
-}
-
+ auto lambda = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("it")
+ .Apply(node->Tail())
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With(0, "it")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal().Build();
+ return ctx.ChangeChildren(Ordered ? node->Head() : *node, {node->Head().HeadPtr(), std::move(lambda)});
+ }
+ }
+ return node;
+}
+
+TExprNode::TPtr OptimizeSkip(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable({"Map", "OrderedMap", "ExpandMap", "WideMap", "NarrowMap"})) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+ return ctx.SwapWithHead(*node);
+ }
+
+ return node;
+}
+
+template <bool EnableNewOptimizers>
+TExprNode::TPtr OptimizeTake(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if constexpr (EnableNewOptimizers) {
+ if (const auto& input = node->Head(); input.IsCallable({"Filter", "OrderedFilter", "WideFilter"}) && 2U == input.ChildrenSize()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Inject " << node->Content() << " limit into " << input.Content();
+ auto list = input.ChildrenList();
+ list.emplace_back(node->TailPtr());
+ return ctx.ChangeChildren(input, std::move(list));
+ }
+
+ if (const auto& input = node->Head(); 1U == input.UseCount()) {
+ if (input.IsCallable("Sort")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " over " << input.Content();
+ auto children = input.ChildrenList();
+ auto it = children.cbegin();
+ children.emplace(++it, node->TailPtr());
+ return ctx.NewCallable(node->Pos(), "TopSort", std::move(children));
+ } else if (input.IsCallable({"Top", "TopSort"})) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " over " << input.Content();
+ return ctx.ChangeChild(input, 1U, ctx.NewCallable(node->Pos(), "Min", {node->TailPtr(), input.ChildPtr(1)}));
+ }
+ }
+ }
+
+ return OptimizeSkip(node, ctx);
+}
+
TExprNode::TPtr ExpandAsSet(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
return ctx.Builder(node->Pos())
@@ -2626,78 +2626,78 @@ TExprNode::TPtr ExpandAsSet(const TExprNode::TPtr& node, TExprContext& ctx) {
.Build();
}
-ui32 GetCommonPartWidth(const TExprNode& lhs, const TExprNode& rhs) {
- ui32 c = 0U;
- while (c < lhs.ChildrenSize() && c < rhs.ChildrenSize() && lhs.Child(c) == rhs.Child(c)) {
- ++c;
- }
- return c;
-}
-
-template<bool AndOr>
-TExprNode::TPtr OptimizeLogicalDups(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto children = node->ChildrenList();
- const auto opposite = AndOr ? "Or" : "And";
- for (auto curr = children.begin(); children.cend() != curr;) {
- if (const auto next = curr + 1U; children.cend() != next) {
- if ((*curr)->IsCallable(opposite) && (*next)->IsCallable(opposite)) {
- if (const auto common = GetCommonPartWidth(**curr, **next)) {
- if ((*next)->ChildrenSize() == common) {
- curr = children.erase(curr);
- } else if ((*curr)->ChildrenSize() == common) {
- children.erase(next);
- } else {
- auto childrenOne = (*curr)->ChildrenList();
- auto childrenTwo = (*next)->ChildrenList();
-
- TExprNode::TListType newChildren(common + 1U);
- std::move(childrenOne.begin(), childrenOne.begin() + common, newChildren.begin());
-
- childrenOne.erase(childrenOne.cbegin(), childrenOne.cbegin() + common);
- childrenTwo.erase(childrenTwo.cbegin(), childrenTwo.cbegin() + common);
-
- auto one = 1U == childrenOne.size() ? std::move(childrenOne.front()) : ctx.ChangeChildren(**curr, std::move(childrenOne));
- auto two = 1U == childrenTwo.size() ? std::move(childrenTwo.front()) : ctx.ChangeChildren(**next, std::move(childrenTwo));
-
- newChildren.back() = ctx.ChangeChildren(*node, {std::move(one), std::move(two)});
- *curr = ctx.ChangeChildren(**curr, std::move(newChildren));
- children.erase(next);
- }
- continue;
- }
- } else if ((*curr)->IsCallable(opposite) && &(*curr)->Head() == next->Get()) {
- curr = children.erase(curr);
- continue;
- } else if ((*next)->IsCallable(opposite) && &(*next)->Head() == curr->Get()) {
- children.erase(next);
- continue;
- } else if ((*curr)->IsCallable() && (*next)->IsCallable() && (*curr)->Content() == (*next)->Content()
- && ((*next)->Content().ends_with("Map") || ((*curr)->IsCallable("IfPresent") && &(*curr)->Tail() == &(*next)->Tail()))
- && &(*curr)->Head() == &(*next)->Head()) {
- auto lambda = ctx.Builder(node->Pos())
- .Lambda()
- .Param("arg")
- .Callable(node->Content())
- .Apply(0, *(*curr)->Child(1U)).With(0, "arg").Seal()
- .Apply(1, *(*next)->Child(1U)).With(0, "arg").Seal()
- .Seal()
- .Seal().Build();
- *curr = ctx.ChangeChild(**curr, 1U, std::move(lambda));
- children.erase(next);
- continue;
- }
- }
- ++curr;
- }
-
- if (children.size() < node->ChildrenSize()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->ChildrenSize() - children.size() << " common parts of " << opposite << "'s under " << node->Content();
- return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
- }
-
- return node;
-}
-
+ui32 GetCommonPartWidth(const TExprNode& lhs, const TExprNode& rhs) {
+ ui32 c = 0U;
+ while (c < lhs.ChildrenSize() && c < rhs.ChildrenSize() && lhs.Child(c) == rhs.Child(c)) {
+ ++c;
+ }
+ return c;
+}
+
+template<bool AndOr>
+TExprNode::TPtr OptimizeLogicalDups(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto children = node->ChildrenList();
+ const auto opposite = AndOr ? "Or" : "And";
+ for (auto curr = children.begin(); children.cend() != curr;) {
+ if (const auto next = curr + 1U; children.cend() != next) {
+ if ((*curr)->IsCallable(opposite) && (*next)->IsCallable(opposite)) {
+ if (const auto common = GetCommonPartWidth(**curr, **next)) {
+ if ((*next)->ChildrenSize() == common) {
+ curr = children.erase(curr);
+ } else if ((*curr)->ChildrenSize() == common) {
+ children.erase(next);
+ } else {
+ auto childrenOne = (*curr)->ChildrenList();
+ auto childrenTwo = (*next)->ChildrenList();
+
+ TExprNode::TListType newChildren(common + 1U);
+ std::move(childrenOne.begin(), childrenOne.begin() + common, newChildren.begin());
+
+ childrenOne.erase(childrenOne.cbegin(), childrenOne.cbegin() + common);
+ childrenTwo.erase(childrenTwo.cbegin(), childrenTwo.cbegin() + common);
+
+ auto one = 1U == childrenOne.size() ? std::move(childrenOne.front()) : ctx.ChangeChildren(**curr, std::move(childrenOne));
+ auto two = 1U == childrenTwo.size() ? std::move(childrenTwo.front()) : ctx.ChangeChildren(**next, std::move(childrenTwo));
+
+ newChildren.back() = ctx.ChangeChildren(*node, {std::move(one), std::move(two)});
+ *curr = ctx.ChangeChildren(**curr, std::move(newChildren));
+ children.erase(next);
+ }
+ continue;
+ }
+ } else if ((*curr)->IsCallable(opposite) && &(*curr)->Head() == next->Get()) {
+ curr = children.erase(curr);
+ continue;
+ } else if ((*next)->IsCallable(opposite) && &(*next)->Head() == curr->Get()) {
+ children.erase(next);
+ continue;
+ } else if ((*curr)->IsCallable() && (*next)->IsCallable() && (*curr)->Content() == (*next)->Content()
+ && ((*next)->Content().ends_with("Map") || ((*curr)->IsCallable("IfPresent") && &(*curr)->Tail() == &(*next)->Tail()))
+ && &(*curr)->Head() == &(*next)->Head()) {
+ auto lambda = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("arg")
+ .Callable(node->Content())
+ .Apply(0, *(*curr)->Child(1U)).With(0, "arg").Seal()
+ .Apply(1, *(*next)->Child(1U)).With(0, "arg").Seal()
+ .Seal()
+ .Seal().Build();
+ *curr = ctx.ChangeChild(**curr, 1U, std::move(lambda));
+ children.erase(next);
+ continue;
+ }
+ }
+ ++curr;
+ }
+
+ if (children.size() < node->ChildrenSize()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->ChildrenSize() - children.size() << " common parts of " << opposite << "'s under " << node->Content();
+ return 1U == children.size() ? children.front() : ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ return node;
+}
+
TExprNode::TPtr ExpandCombineByKey(const TExprNode::TPtr& node, TExprContext& ctx) {
const bool isStreamOrFlow = node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream ||
node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow;
@@ -2732,1783 +2732,1783 @@ TExprNode::TPtr ExpandCombineByKey(const TExprNode::TPtr& node, TExprContext& ct
.Ptr();
}
-template<typename TRowType>
-TExprNode::TPtr MakeWideMapJoinCore(const TExprNode& mapjoin, TExprNode::TPtr&& input, TExprContext& ctx) {
- const auto inStructType = GetSeqItemType(mapjoin.Head().GetTypeAnn())->Cast<TRowType>();
- const auto outStructType = GetSeqItemType(mapjoin.GetTypeAnn())->Cast<TRowType>();
-
- TExprNode::TListType indexes;
- indexes.reserve(mapjoin.Child(3)->ChildrenSize());
- mapjoin.Child(3)->ForEachChild([&](const TExprNode& item){
- indexes.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
- });
-
- TExprNode::TListType leftRenames;
- leftRenames.reserve(mapjoin.Child(4)->ChildrenSize());
- bool split = false;
- mapjoin.Child(4)->ForEachChild([&](const TExprNode& item){
- leftRenames.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*((split = !split) ? inStructType : outStructType), item.Content())), TNodeFlags::Default));
- });
-
- auto rightRenames = mapjoin.Child(5)->ChildrenList();
-
- for (auto i = 1U; i < rightRenames.size(); ++++i)
- rightRenames[i] = ctx.NewAtom(rightRenames[i]->Pos(), ToString(*GetFieldPosition(*outStructType, rightRenames[i]->Content())), TNodeFlags::Default);
-
- auto children = mapjoin.ChildrenList();
-
- children.front() = std::move(input);
- children[3] = ctx.ChangeChildren(*children[3], std::move(indexes));
- children[4] = ctx.ChangeChildren(*children[4], std::move(leftRenames));
- children[5] = ctx.ChangeChildren(*children[5], std::move(rightRenames));
-
- return ctx.ChangeChildren(mapjoin, std::move(children));
-}
-
-template<typename TRowType>
-std::pair<TExprNode::TPtr, TExprNode::TListType> MakeWideCommonJoinCore(const TExprNode& commonJoin, TExprNode::TPtr&& input, TExprContext& ctx) {
- const auto inStructType = GetSeqItemType(commonJoin.Head().GetTypeAnn())->Cast<TRowType>();
-
- TExprNode::TListType leftColumns, rightColumns, requred, keys, outputColumns;
- outputColumns.reserve(commonJoin.Child(2)->ChildrenSize() + commonJoin.Child(3)->ChildrenSize());
-
- leftColumns.reserve(commonJoin.Child(2)->ChildrenSize());
- for (auto& item : commonJoin.Child(2)->ChildrenList()) {
- leftColumns.emplace_back(ctx.NewAtom(item->Pos(), ToString(*GetFieldPosition(*inStructType, item->Content())), TNodeFlags::Default));
- outputColumns.emplace_back(std::move(item));
- }
-
- rightColumns.reserve(commonJoin.Child(3)->ChildrenSize());
- for (auto& item : commonJoin.Child(3)->ChildrenList()) {
- rightColumns.emplace_back(ctx.NewAtom(item->Pos(), ToString(*GetFieldPosition(*inStructType, item->Content())), TNodeFlags::Default));
- outputColumns.emplace_back(std::move(item));
- }
-
- requred.reserve(commonJoin.Child(4)->ChildrenSize());
- commonJoin.Child(4)->ForEachChild([&](const TExprNode& item){
- requred.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
- });
-
- keys.reserve(commonJoin.Child(5)->ChildrenSize());
- commonJoin.Child(5)->ForEachChild([&](const TExprNode& item){
- keys.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
- });
-
- auto children = commonJoin.ChildrenList();
-
- children.front() = std::move(input);
- children[2] = ctx.ChangeChildren(*children[2], std::move(leftColumns));
- children[3] = ctx.ChangeChildren(*children[3], std::move(rightColumns));
- children[4] = ctx.ChangeChildren(*children[4], std::move(requred));
- children[5] = ctx.ChangeChildren(*children[5], std::move(keys));
- children.back() = ctx.NewAtom(commonJoin.Tail().Pos(), ToString(*GetFieldPosition(*inStructType, commonJoin.Tail().Content())), TNodeFlags::Default);
-
- return {ctx.ChangeChildren(commonJoin, std::move(children)), std::move(outputColumns)};
-}
-
-ui32 CollectStateNodes(const TExprNode& initLambda, const TExprNode& updateLambda, TExprNode::TListType& fields, TExprNode::TListType& init, TExprNode::TListType& update, TExprContext& ctx) {
- YQL_ENSURE(IsSameAnnotation(*initLambda.Tail().GetTypeAnn(), *updateLambda.Tail().GetTypeAnn()), "Must be same type.");
-
- if (ETypeAnnotationKind::Struct != initLambda.Tail().GetTypeAnn()->GetKind()) {
- fields.clear();
- init = TExprNode::TListType(1U, initLambda.TailPtr());
- update = TExprNode::TListType(1U, updateLambda.TailPtr());
- return 1U;
- }
-
- const auto structType = initLambda.Tail().GetTypeAnn()->Cast<TStructExprType>();
- const auto size = structType->GetSize();
- fields.reserve(size);
- init.reserve(size);
- update.reserve(size);
- fields.clear();
- init.clear();
- update.clear();
-
- if (initLambda.Tail().IsCallable("AsStruct"))
- initLambda.Tail().ForEachChild([&](const TExprNode& child) { fields.emplace_back(child.HeadPtr()); });
- else if (updateLambda.Tail().IsCallable("AsStruct"))
- updateLambda.Tail().ForEachChild([&](const TExprNode& child) { fields.emplace_back(child.HeadPtr()); });
- else
- for (const auto& item : structType->GetItems())
- fields.emplace_back(ctx.NewAtom(initLambda.Tail().Pos(), item->GetName()));
-
- if (initLambda.Tail().IsCallable("AsStruct"))
- initLambda.Tail().ForEachChild([&](const TExprNode& child) { init.emplace_back(child.TailPtr()); });
- else
- std::transform(fields.cbegin(), fields.cend(), std::back_inserter(init), [&](const TExprNode::TPtr& name) {
- return ctx.NewCallable(name->Pos(), "Member", {initLambda.TailPtr(), name});
- });
-
- if (updateLambda.Tail().IsCallable("AsStruct"))
- updateLambda.Tail().ForEachChild([&](const TExprNode& child) { update.emplace_back(child.TailPtr()); });
- else
- std::transform(fields.cbegin(), fields.cend(), std::back_inserter(update), [&](const TExprNode::TPtr& name) {
- return ctx.NewCallable(name->Pos(), "Member", {updateLambda.TailPtr(), name});
- });
-
- return size;
-}
-
-// TODO: move in context
-using TLiteralStructIndexMap = std::unordered_map<std::string_view, ui32>;
-using TLieralStructsCacheMap = std::unordered_map<const TExprNode*, TLiteralStructIndexMap>;
-const TLiteralStructIndexMap& GetLiteralStructIndexes(const TExprNode& literalStruct, TLieralStructsCacheMap& membersMap) {
- const auto search = membersMap.emplace(&literalStruct, literalStruct.ChildrenSize());
- if (search.second) {
- auto i = 0U;
- literalStruct.ForEachChild([&](const TExprNode& node) { search.first->second.emplace(node.Head().Content(), i++); });
- }
- return search.first->second;
-}
-
-std::array<TExprNode::TPtr, 2U> ApplyNarrowMap(const TExprNode& lambda, TExprContext& ctx) {
- const auto width =lambda.Head().ChildrenSize();
- TNodeOnNodeOwnedMap replaces(width);
- TExprNode::TListType args;
- args.reserve(width);
- for (auto i = 0U; i < width; ++i) {
- args.emplace_back(ctx.NewArgument(lambda.Head().Child(i)->Pos(), TString("fields") += ToString(i)));
- replaces.emplace(lambda.Head().Child(i), args.back());
- }
- return {{ ctx.NewArguments(lambda.Head().Pos(), std::move(args)), ctx.ReplaceNodes(lambda.TailPtr(), replaces) }};
-}
-
-bool IsSimpleExpand(const TExprNode& out, const TExprNode& arg) {
- if (out.IsCallable({"Just", "Member", "Nth"}))
- return IsSimpleExpand(out.Head(), arg);
- return &out == &arg;
-}
-
-TExprNode::TPtr OptimizeExpandMap(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable({"Map", "OrderedMap"})) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
- auto lambda = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Apply(node->Tail())
- .With(0)
- .Apply(input.Tail())
- .With(0, "item")
- .Seal()
- .Done()
- .Seal()
- .Seal().Build();
- return ctx.ChangeChildren(*node, {input.HeadPtr(), std::move(lambda)});
- }
-
- if (const auto& input = node->Head(); input.IsCallable({"Filter", "OrderedFilter"})) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
- auto outs = GetLambdaBody(node->Tail());
-
- TExprNode::TListType args, body;
- args.reserve(outs.size() + 2U);
- body.reserve(outs.size() + 2U);
-
- const auto& arg = node->Tail().Head().Head();
- args.emplace_back(ctx.NewArgument(arg.Pos(), "outer"));
- body.emplace_back(ctx.NewArgument(arg.Pos(), "inner"));
-
- TNodeOnNodeOwnedMap replaces(outs.size() + 1U);
- replaces.emplace(&arg, args.front());
-
- auto x = 0U;
- for (auto& out : outs) {
- if (IsSimpleExpand(*out, arg)) {
- args.emplace_back(ctx.NewArgument(out->Pos(), ToString(x++)));
- replaces.emplace(&*out, args.back());
- body.emplace_back(ctx.ReplaceNode(std::move(out), arg, body.front()));
- out = args.back();
- }
- }
-
- args.emplace_back(ctx.NewArgument(node->Pos(), "_"));
- body.emplace_back(ctx.ReplaceNode(input.Child(1)->TailPtr(), input.Child(1)->Head().Head(), body.front()));
- outs = ctx.ReplaceNodes(std::move(outs), replaces);
- auto row = body.front();
- if (std::none_of(outs.cbegin(), outs.cend(), std::bind(&IsDepended, std::bind(&TExprNode::TPtr::operator*, std::placeholders::_1), std::cref(*args.front())))) {
- args.erase(args.cbegin());
- body.erase(body.cbegin());
- }
- const auto width = body.size();
- auto expand = ctx.NewLambda(node->Tail().Pos(), ctx.NewArguments(node->Tail().Head().Pos(), {std::move(row)}), std::move(body));
- auto filter = ctx.Builder(input.Pos())
- .Callable("WideFilter")
- .Callable(0, node->Content())
- .Add(0, input.HeadPtr())
- .Add(1, std::move(expand))
- .Seal()
- .Lambda(1)
- .Params("items", width)
- .Arg("items", width - 1U)
- .Seal()
- .Seal().Build();
-
- if (3U == input.ChildrenSize()) {
- auto children = filter->ChildrenList();
- children.emplace_back(input.TailPtr());
- filter = ctx.ChangeChildren(*filter, std::move(children));
- }
-
- auto wide = ctx.NewLambda(node->Tail().Pos(), ctx.NewArguments(node->Tail().Head().Pos(), std::move(args)), std::move(outs));
- return ctx.NewCallable(node->Pos(), "WideMap", {std::move(filter), std::move(wide)});
- }
-
- if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
-
- if (input.Tail().Tail().IsCallable("AsStruct")) {
- auto apply = ApplyNarrowMap(input.Tail(), ctx);
- TLieralStructsCacheMap membersMap; // TODO: move to context.
- const auto& members = GetLiteralStructIndexes(*apply.back(), membersMap);
- const auto& oldLambda = node->Tail();
- auto body = GetLambdaBody(oldLambda);
- std::for_each(body.begin(), body.end(), [&](TExprNode::TPtr& item) {
- item = item->IsCallable("Member") && &item->Head() == &oldLambda.Head().Head() ?
- apply.back()->Child(members.find(item->Tail().Content())->second)->TailPtr():
- ctx.ReplaceNode(std::move(item), oldLambda.Head().Head(), apply.back());
- });
-
- auto newLambda = ctx.NewLambda(oldLambda.Pos(), std::move(apply.front()), std::move(body));
-
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, input.HeadPtr())
- .Add(1, std::move(newLambda))
- .Seal().Build();
- } else {
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Params("items", input.Tail().Head().ChildrenSize())
- .Apply(node->Tail())
- .With(0)
- .Apply(input.Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
-
- if (const auto& input = node->Head(); input.IsCallable("MapJoinCore") && !input.Head().IsArgument()) {
- if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()), outItemType = GetSeqItemType(input.GetTypeAnn());
- ETypeAnnotationKind::Struct == inItemType->GetKind() && ETypeAnnotationKind::Struct == outItemType->GetKind()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
-
- auto expand = ctx.Builder(node->Pos())
- .Callable(node->Content())
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("item")
+template<typename TRowType>
+TExprNode::TPtr MakeWideMapJoinCore(const TExprNode& mapjoin, TExprNode::TPtr&& input, TExprContext& ctx) {
+ const auto inStructType = GetSeqItemType(mapjoin.Head().GetTypeAnn())->Cast<TRowType>();
+ const auto outStructType = GetSeqItemType(mapjoin.GetTypeAnn())->Cast<TRowType>();
+
+ TExprNode::TListType indexes;
+ indexes.reserve(mapjoin.Child(3)->ChildrenSize());
+ mapjoin.Child(3)->ForEachChild([&](const TExprNode& item){
+ indexes.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
+ });
+
+ TExprNode::TListType leftRenames;
+ leftRenames.reserve(mapjoin.Child(4)->ChildrenSize());
+ bool split = false;
+ mapjoin.Child(4)->ForEachChild([&](const TExprNode& item){
+ leftRenames.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*((split = !split) ? inStructType : outStructType), item.Content())), TNodeFlags::Default));
+ });
+
+ auto rightRenames = mapjoin.Child(5)->ChildrenList();
+
+ for (auto i = 1U; i < rightRenames.size(); ++++i)
+ rightRenames[i] = ctx.NewAtom(rightRenames[i]->Pos(), ToString(*GetFieldPosition(*outStructType, rightRenames[i]->Content())), TNodeFlags::Default);
+
+ auto children = mapjoin.ChildrenList();
+
+ children.front() = std::move(input);
+ children[3] = ctx.ChangeChildren(*children[3], std::move(indexes));
+ children[4] = ctx.ChangeChildren(*children[4], std::move(leftRenames));
+ children[5] = ctx.ChangeChildren(*children[5], std::move(rightRenames));
+
+ return ctx.ChangeChildren(mapjoin, std::move(children));
+}
+
+template<typename TRowType>
+std::pair<TExprNode::TPtr, TExprNode::TListType> MakeWideCommonJoinCore(const TExprNode& commonJoin, TExprNode::TPtr&& input, TExprContext& ctx) {
+ const auto inStructType = GetSeqItemType(commonJoin.Head().GetTypeAnn())->Cast<TRowType>();
+
+ TExprNode::TListType leftColumns, rightColumns, requred, keys, outputColumns;
+ outputColumns.reserve(commonJoin.Child(2)->ChildrenSize() + commonJoin.Child(3)->ChildrenSize());
+
+ leftColumns.reserve(commonJoin.Child(2)->ChildrenSize());
+ for (auto& item : commonJoin.Child(2)->ChildrenList()) {
+ leftColumns.emplace_back(ctx.NewAtom(item->Pos(), ToString(*GetFieldPosition(*inStructType, item->Content())), TNodeFlags::Default));
+ outputColumns.emplace_back(std::move(item));
+ }
+
+ rightColumns.reserve(commonJoin.Child(3)->ChildrenSize());
+ for (auto& item : commonJoin.Child(3)->ChildrenList()) {
+ rightColumns.emplace_back(ctx.NewAtom(item->Pos(), ToString(*GetFieldPosition(*inStructType, item->Content())), TNodeFlags::Default));
+ outputColumns.emplace_back(std::move(item));
+ }
+
+ requred.reserve(commonJoin.Child(4)->ChildrenSize());
+ commonJoin.Child(4)->ForEachChild([&](const TExprNode& item){
+ requred.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
+ });
+
+ keys.reserve(commonJoin.Child(5)->ChildrenSize());
+ commonJoin.Child(5)->ForEachChild([&](const TExprNode& item){
+ keys.emplace_back(ctx.NewAtom(item.Pos(), ToString(*GetFieldPosition(*inStructType, item.Content())), TNodeFlags::Default));
+ });
+
+ auto children = commonJoin.ChildrenList();
+
+ children.front() = std::move(input);
+ children[2] = ctx.ChangeChildren(*children[2], std::move(leftColumns));
+ children[3] = ctx.ChangeChildren(*children[3], std::move(rightColumns));
+ children[4] = ctx.ChangeChildren(*children[4], std::move(requred));
+ children[5] = ctx.ChangeChildren(*children[5], std::move(keys));
+ children.back() = ctx.NewAtom(commonJoin.Tail().Pos(), ToString(*GetFieldPosition(*inStructType, commonJoin.Tail().Content())), TNodeFlags::Default);
+
+ return {ctx.ChangeChildren(commonJoin, std::move(children)), std::move(outputColumns)};
+}
+
+ui32 CollectStateNodes(const TExprNode& initLambda, const TExprNode& updateLambda, TExprNode::TListType& fields, TExprNode::TListType& init, TExprNode::TListType& update, TExprContext& ctx) {
+ YQL_ENSURE(IsSameAnnotation(*initLambda.Tail().GetTypeAnn(), *updateLambda.Tail().GetTypeAnn()), "Must be same type.");
+
+ if (ETypeAnnotationKind::Struct != initLambda.Tail().GetTypeAnn()->GetKind()) {
+ fields.clear();
+ init = TExprNode::TListType(1U, initLambda.TailPtr());
+ update = TExprNode::TListType(1U, updateLambda.TailPtr());
+ return 1U;
+ }
+
+ const auto structType = initLambda.Tail().GetTypeAnn()->Cast<TStructExprType>();
+ const auto size = structType->GetSize();
+ fields.reserve(size);
+ init.reserve(size);
+ update.reserve(size);
+ fields.clear();
+ init.clear();
+ update.clear();
+
+ if (initLambda.Tail().IsCallable("AsStruct"))
+ initLambda.Tail().ForEachChild([&](const TExprNode& child) { fields.emplace_back(child.HeadPtr()); });
+ else if (updateLambda.Tail().IsCallable("AsStruct"))
+ updateLambda.Tail().ForEachChild([&](const TExprNode& child) { fields.emplace_back(child.HeadPtr()); });
+ else
+ for (const auto& item : structType->GetItems())
+ fields.emplace_back(ctx.NewAtom(initLambda.Tail().Pos(), item->GetName()));
+
+ if (initLambda.Tail().IsCallable("AsStruct"))
+ initLambda.Tail().ForEachChild([&](const TExprNode& child) { init.emplace_back(child.TailPtr()); });
+ else
+ std::transform(fields.cbegin(), fields.cend(), std::back_inserter(init), [&](const TExprNode::TPtr& name) {
+ return ctx.NewCallable(name->Pos(), "Member", {initLambda.TailPtr(), name});
+ });
+
+ if (updateLambda.Tail().IsCallable("AsStruct"))
+ updateLambda.Tail().ForEachChild([&](const TExprNode& child) { update.emplace_back(child.TailPtr()); });
+ else
+ std::transform(fields.cbegin(), fields.cend(), std::back_inserter(update), [&](const TExprNode::TPtr& name) {
+ return ctx.NewCallable(name->Pos(), "Member", {updateLambda.TailPtr(), name});
+ });
+
+ return size;
+}
+
+// TODO: move in context
+using TLiteralStructIndexMap = std::unordered_map<std::string_view, ui32>;
+using TLieralStructsCacheMap = std::unordered_map<const TExprNode*, TLiteralStructIndexMap>;
+const TLiteralStructIndexMap& GetLiteralStructIndexes(const TExprNode& literalStruct, TLieralStructsCacheMap& membersMap) {
+ const auto search = membersMap.emplace(&literalStruct, literalStruct.ChildrenSize());
+ if (search.second) {
+ auto i = 0U;
+ literalStruct.ForEachChild([&](const TExprNode& node) { search.first->second.emplace(node.Head().Content(), i++); });
+ }
+ return search.first->second;
+}
+
+std::array<TExprNode::TPtr, 2U> ApplyNarrowMap(const TExprNode& lambda, TExprContext& ctx) {
+ const auto width =lambda.Head().ChildrenSize();
+ TNodeOnNodeOwnedMap replaces(width);
+ TExprNode::TListType args;
+ args.reserve(width);
+ for (auto i = 0U; i < width; ++i) {
+ args.emplace_back(ctx.NewArgument(lambda.Head().Child(i)->Pos(), TString("fields") += ToString(i)));
+ replaces.emplace(lambda.Head().Child(i), args.back());
+ }
+ return {{ ctx.NewArguments(lambda.Head().Pos(), std::move(args)), ctx.ReplaceNodes(lambda.TailPtr(), replaces) }};
+}
+
+bool IsSimpleExpand(const TExprNode& out, const TExprNode& arg) {
+ if (out.IsCallable({"Just", "Member", "Nth"}))
+ return IsSimpleExpand(out.Head(), arg);
+ return &out == &arg;
+}
+
+TExprNode::TPtr OptimizeExpandMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable({"Map", "OrderedMap"})) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+ auto lambda = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Apply(node->Tail())
+ .With(0)
+ .Apply(input.Tail())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal().Build();
+ return ctx.ChangeChildren(*node, {input.HeadPtr(), std::move(lambda)});
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable({"Filter", "OrderedFilter"})) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+ auto outs = GetLambdaBody(node->Tail());
+
+ TExprNode::TListType args, body;
+ args.reserve(outs.size() + 2U);
+ body.reserve(outs.size() + 2U);
+
+ const auto& arg = node->Tail().Head().Head();
+ args.emplace_back(ctx.NewArgument(arg.Pos(), "outer"));
+ body.emplace_back(ctx.NewArgument(arg.Pos(), "inner"));
+
+ TNodeOnNodeOwnedMap replaces(outs.size() + 1U);
+ replaces.emplace(&arg, args.front());
+
+ auto x = 0U;
+ for (auto& out : outs) {
+ if (IsSimpleExpand(*out, arg)) {
+ args.emplace_back(ctx.NewArgument(out->Pos(), ToString(x++)));
+ replaces.emplace(&*out, args.back());
+ body.emplace_back(ctx.ReplaceNode(std::move(out), arg, body.front()));
+ out = args.back();
+ }
+ }
+
+ args.emplace_back(ctx.NewArgument(node->Pos(), "_"));
+ body.emplace_back(ctx.ReplaceNode(input.Child(1)->TailPtr(), input.Child(1)->Head().Head(), body.front()));
+ outs = ctx.ReplaceNodes(std::move(outs), replaces);
+ auto row = body.front();
+ if (std::none_of(outs.cbegin(), outs.cend(), std::bind(&IsDepended, std::bind(&TExprNode::TPtr::operator*, std::placeholders::_1), std::cref(*args.front())))) {
+ args.erase(args.cbegin());
+ body.erase(body.cbegin());
+ }
+ const auto width = body.size();
+ auto expand = ctx.NewLambda(node->Tail().Pos(), ctx.NewArguments(node->Tail().Head().Pos(), {std::move(row)}), std::move(body));
+ auto filter = ctx.Builder(input.Pos())
+ .Callable("WideFilter")
+ .Callable(0, node->Content())
+ .Add(0, input.HeadPtr())
+ .Add(1, std::move(expand))
+ .Seal()
+ .Lambda(1)
+ .Params("items", width)
+ .Arg("items", width - 1U)
+ .Seal()
+ .Seal().Build();
+
+ if (3U == input.ChildrenSize()) {
+ auto children = filter->ChildrenList();
+ children.emplace_back(input.TailPtr());
+ filter = ctx.ChangeChildren(*filter, std::move(children));
+ }
+
+ auto wide = ctx.NewLambda(node->Tail().Pos(), ctx.NewArguments(node->Tail().Head().Pos(), std::move(args)), std::move(outs));
+ return ctx.NewCallable(node->Pos(), "WideMap", {std::move(filter), std::move(wide)});
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+
+ if (input.Tail().Tail().IsCallable("AsStruct")) {
+ auto apply = ApplyNarrowMap(input.Tail(), ctx);
+ TLieralStructsCacheMap membersMap; // TODO: move to context.
+ const auto& members = GetLiteralStructIndexes(*apply.back(), membersMap);
+ const auto& oldLambda = node->Tail();
+ auto body = GetLambdaBody(oldLambda);
+ std::for_each(body.begin(), body.end(), [&](TExprNode::TPtr& item) {
+ item = item->IsCallable("Member") && &item->Head() == &oldLambda.Head().Head() ?
+ apply.back()->Child(members.find(item->Tail().Content())->second)->TailPtr():
+ ctx.ReplaceNode(std::move(item), oldLambda.Head().Head(), apply.back());
+ });
+
+ auto newLambda = ctx.NewLambda(oldLambda.Pos(), std::move(apply.front()), std::move(body));
+
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, input.HeadPtr())
+ .Add(1, std::move(newLambda))
+ .Seal().Build();
+ } else {
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Params("items", input.Tail().Head().ChildrenSize())
+ .Apply(node->Tail())
+ .With(0)
+ .Apply(input.Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable("MapJoinCore") && !input.Head().IsArgument()) {
+ if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()), outItemType = GetSeqItemType(input.GetTypeAnn());
+ ETypeAnnotationKind::Struct == inItemType->GetKind() && ETypeAnnotationKind::Struct == outItemType->GetKind()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+
+ auto expand = ctx.Builder(node->Pos())
+ .Callable(node->Content())
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("item")
.Do([&inItemType](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : inItemType->Cast<TStructExprType>()->GetItems()) {
- parent.Callable(i++, "Member")
- .Arg(0, "item")
- .Atom(1, item->GetName())
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
-
- const auto structType = outItemType->Cast<TStructExprType>();
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, MakeWideMapJoinCore<TStructExprType>(input, std::move(expand), ctx))
- .Lambda(1)
- .Params("fields", structType->GetSize())
- .Apply(node->Tail())
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : structType->GetItems()) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
-
- if (const auto& input = node->Head(); input.IsCallable("CommonJoinCore") && !input.Head().IsArgument()) {
- if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
-
- auto expand = ctx.Builder(node->Pos())
- .Callable(node->Content())
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("item")
+ ui32 i = 0U;
+ for (const auto& item : inItemType->Cast<TStructExprType>()->GetItems()) {
+ parent.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Atom(1, item->GetName())
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+
+ const auto structType = outItemType->Cast<TStructExprType>();
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, MakeWideMapJoinCore<TStructExprType>(input, std::move(expand), ctx))
+ .Lambda(1)
+ .Params("fields", structType->GetSize())
+ .Apply(node->Tail())
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : structType->GetItems()) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable("CommonJoinCore") && !input.Head().IsArgument()) {
+ if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+
+ auto expand = ctx.Builder(node->Pos())
+ .Callable(node->Content())
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("item")
.Do([&inItemType](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : inItemType->Cast<TStructExprType>()->GetItems()) {
- parent.Callable(i++, "Member")
- .Arg(0, "item")
- .Atom(1, item->GetName())
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
-
- auto wide = MakeWideCommonJoinCore<TStructExprType>(input, std::move(expand), ctx);
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, std::move(wide.first))
- .Lambda(1)
- .Params("fields", wide.second.size())
- .Apply(node->Tail())
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (auto& item : wide.second) {
- parent.List(i)
- .Add(0, std::move(item))
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
-
- if (const auto& input = node->Head(); input.IsCallable("CombineCore") && !input.Head().IsArgument() &&
- (input.Child(2U)->Tail().IsCallable("AsStruct") || input.Child(3U)->Tail().IsCallable("AsStruct")) &&
- input.Child(4U)->Tail().IsCallable("Just") && ETypeAnnotationKind::Struct == input.Child(4U)->Tail().Head().GetTypeAnn()->GetKind()) {
- if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
- if (const auto inStructType = inItemType->Cast<TStructExprType>(); inStructType->GetSize() > 0U) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
-
- const auto& output = input.Child(4U)->Tail().Head();
- const auto structType = output.GetTypeAnn()->Cast<TStructExprType>();
-
- const auto outputWidth = structType->GetSize();
- const auto inputWidth = inStructType->GetSize();
-
- TExprNode::TListType inputFilelds, stateFields, outputFields, init, update, finish;
- inputFilelds.reserve(inputWidth);
- for (const auto& item : inStructType->GetItems()) {
- inputFilelds.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
- }
-
- const auto stateWidth = CollectStateNodes(*input.Child(2U), *input.Child(3U), stateFields, init, update, ctx);
-
- outputFields.reserve(outputWidth);
- finish.reserve(outputWidth);
- if (output.IsCallable("AsStruct")) {
- input.Child(4U)->Tail().Head().ForEachChild([&](const TExprNode& child) {
- outputFields.emplace_back(child.HeadPtr());
- finish.emplace_back(child.TailPtr());
- });
- } else {
- for (const auto& item : structType->GetItems()) {
- outputFields.emplace_back(ctx.NewAtom(output.Pos(), item->GetName()));
- finish.emplace_back(ctx.NewCallable(output.Pos(), "Member", {input.Child(4U)->Tail().HeadPtr(), outputFields.back()}));
- }
- }
-
- auto limit = input.ChildrenSize() > TCoCombineCore::idx_MemLimit ? input.TailPtr() : ctx.NewAtom(input.Pos(), "");
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Callable(0, "WideCombiner")
- .Callable(0, node->Content())
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.Callable(i++, "Member")
- .Arg(0, "item")
- .Add(1, member)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Add(1, std::move(limit))
- .Lambda(2)
- .Params("items", inputWidth)
- .Apply(*input.Child(1U))
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("key")
- .Params("items", inputWidth)
- .ApplyPartial(input.Child(2U)->HeadPtr(), std::move(init))
- .With(0, "key")
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(4)
- .Param("key")
- .Params("items", inputWidth)
- .Params("state", stateWidth)
- .ApplyPartial(input.Child(3U)->HeadPtr(), std::move(update))
- .With(0, "key")
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .With(2)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < stateWidth; ++i) {
- parent.List(i)
- .Add(0, stateFields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(5)
- .Param("key")
- .Params("state", stateWidth)
- .ApplyPartial(input.Child(4U)->HeadPtr(), std::move(finish))
- .With(0, "key")
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < stateWidth; ++i) {
- parent.List(i)
- .Add(0, std::move(stateFields[i]))
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", outputWidth)
- .Apply(node->Tail())
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.List(i)
- .Add(0, std::move(outputFields[i]))
- .Arg(1, "items", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
- }
-
- if (const auto& input = node->Head(); input.IsCallable("Condense1") && !input.Head().IsArgument() &&
- (input.Child(1U)->Tail().IsCallable("AsStruct") || input.Tail().Tail().IsCallable("AsStruct"))) {
- if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
- if (const auto inStructType = inItemType->Cast<TStructExprType>(); inStructType->GetSize() > 0U) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
-
- const auto inputWidth = inStructType->GetSize();
- TExprNode::TListType inputFilelds, stateFields, init, update;
- inputFilelds.reserve(inputWidth);
- for (const auto& item : inStructType->GetItems()) {
- inputFilelds.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
- }
-
- const auto stateWidth = CollectStateNodes(*input.Child(1U), input.Tail(), stateFields, init, update, ctx);
-
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Callable(0, "WideCondense1")
- .Callable(0, node->Content())
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.Callable(i++, "Member")
- .Arg(0, "item")
- .Add(1, member)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", inputWidth)
- .ApplyPartial(input.Child(1U)->HeadPtr(), std::move(init))
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(2)
- .Params("items", inputWidth)
- .Params("state", stateWidth)
- .Apply(*input.Child(2U))
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < stateWidth; ++i) {
- parent.List(i)
- .Add(0, stateFields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Params("items", inputWidth)
- .Params("state", stateWidth)
- .ApplyPartial(input.Tail().HeadPtr(), std::move(update))
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& member : inputFilelds) {
- parent.List(i)
- .Add(0, member)
- .Arg(1, "items", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Done()
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < stateWidth; ++i) {
- parent.List(i)
- .Add(0, stateFields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", stateWidth)
- .Apply(node->Tail())
- .With(0)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < stateWidth; ++i) {
- parent.List(i)
- .Add(0, std::move(stateFields[i]))
- .Arg(1, "items", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
- }
-
- return node;
-}
-
-TExprNode::TPtr JustIf(bool optional, TExprNode::TPtr&& node, TExprContext& ctx) {
- return ctx.WrapByCallableIf(optional, "Just", std::move(node));
-}
-
-template<bool TupleOrStruct>
-TExprNode::TPtr AutoMapGetElementhOfOptionalArray(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over " << node->Head().Content();
- return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
- }
-
- if (const auto headType = node->Head().GetTypeAnn(); ETypeAnnotationKind::Optional == headType->GetKind()) {
- const auto arrayType = headType->Cast<TOptionalExprType>()->GetItemType();
- const auto itemType = TupleOrStruct ?
- arrayType->Cast<TTupleExprType>()->GetItems()[FromString<ui32>(node->Tail().Content())]:
- arrayType->Cast<TStructExprType>()->GetItems()[*arrayType->Cast<TStructExprType>()->FindItem(node->Tail().Content())]->GetItemType();
-
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over " << node->Head().Content();
- auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
- return JustIf(!itemType->IsOptionalOrNull(), std::move(ret), ctx);
- }
-
-/*TODO: constexpr auto typeName = TupleOrStruct ? "tuple" : "struct";
- YQL_CLOG(DEBUG, CorePeepHole) << "Wrap " << node->Content() << " for optional " << typeName << '.';
- return itemType->IsOptionalOrNull() ?
- ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param(typeName)
- .Callable(node->Content())
- .Arg(0, typeName)
- .Add(1, node->TailPtr())
- .Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(node->Pos())
- .Callable("IfPresent")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param(typeName)
- .Callable("Just")
- .Callable(0, node->Content())
- .Arg(0, typeName)
- .Add(1, node->TailPtr())
- .Seal()
- .Seal()
- .Seal()
- .Callable(2, "Nothing")
- .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
- .Seal()
- .Seal()
- .Build();*/
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeNth(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().Type() == TExprNode::List) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Drop " << node->Content() << " over tuple literal";
- const auto index = FromString<ui32>(node->Tail().Content());
- return node->Head().ChildPtr(index);
- }
-
- return AutoMapGetElementhOfOptionalArray<true>(node, ctx);
-}
-
-TExprNode::TPtr OptimizeMember(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("AsStruct")) {
- for (ui32 index = 0U; index < node->Head().ChildrenSize(); ++index) {
- if (const auto tuple = node->Head().Child(index); tuple->Head().Content() == node->Tail().Content()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Drop "<< node->Content() << " over " << node->Head().Content();
- return tuple->TailPtr();
- }
- }
- }
-
- return AutoMapGetElementhOfOptionalArray<false>(node, ctx);
-}
-
-TExprNode::TPtr OptimizeCondense1(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("NarrowMap") &&
- ETypeAnnotationKind::Struct == node->Tail().Tail().GetTypeAnn()->GetKind()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
-
- const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
- TExprNode::TListType fields, init, update;
- const auto outputWidth = CollectStateNodes(*node->Child(1U), node->Tail(), fields, init, update, ctx);
-
- return ctx.Builder(node->Pos())
- .Callable("NarrowMap")
- .Callable(0, "WideCondense1")
- .Add(0, node->Head().HeadPtr())
- .Lambda(1)
- .Params("items", inputWidth)
- .ApplyPartial(node->Child(1U)->HeadPtr(), std::move(init))
- .With(0)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(2)
- .Params("items", inputWidth)
- .Params("state", outputWidth)
- .Apply(*node->Child(2U))
- .With(0)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.List(i)
- .Add(0, fields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Params("items", inputWidth)
- .Params("state", outputWidth)
- .ApplyPartial(node->Tail().HeadPtr(), std::move(update))
- .With(0)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .With(1)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.List(i)
- .Add(0, fields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", outputWidth)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.List(i)
- .Add(0, std::move(fields[i]))
- .Arg(1, "items", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeCombineCore(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("NarrowMap") && node->Child(4U)->Tail().IsCallable("Just")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
-
- const auto& output = node->Child(4U)->Tail().Head();
- const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
-
- const auto structType = ETypeAnnotationKind::Struct == output.GetTypeAnn()->GetKind() ? output.GetTypeAnn()->Cast<TStructExprType>() : nullptr;
- const auto outputWidth = structType ? structType->GetSize() : 1U;
-
- TExprNode::TListType stateFields, outputFields, init, update, finish;
- outputFields.reserve(outputWidth);
- finish.reserve(outputWidth);
-
- const auto stateWidth = CollectStateNodes(*node->Child(2U), *node->Child(3U), stateFields, init, update, ctx);
-
- if (output.IsCallable("AsStruct")) {
- node->Child(4U)->Tail().Head().ForEachChild([&](const TExprNode& child) {
- outputFields.emplace_back(child.HeadPtr());
- finish.emplace_back(child.TailPtr());
- });
- } else if (structType) {
- for (const auto& item : structType->GetItems()) {
- outputFields.emplace_back(ctx.NewAtom(output.Pos(), item->GetName()));
- finish.emplace_back(ctx.NewCallable(output.Pos(), "Member", {node->Child(4U)->Tail().HeadPtr(), outputFields.back()}));
- }
- } else {
- finish.emplace_back(node->Child(4U)->Tail().HeadPtr());
- }
-
- auto limit = node->ChildrenSize() > TCoCombineCore::idx_MemLimit ? node->TailPtr() : ctx.NewAtom(node->Pos(), "");
- return ctx.Builder(node->Pos())
- .Callable("NarrowMap")
- .Callable(0, "WideCombiner")
- .Add(0, node->Head().HeadPtr())
- .Add(1, std::move(limit))
- .Lambda(2)
- .Params("items", inputWidth)
- .Apply(*node->Child(1U))
- .With(0)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("key")
- .Params("items", inputWidth)
- .ApplyPartial(node->Child(2U)->HeadPtr(), std::move(init))
- .With(0, "key")
- .With(1)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(4)
- .Param("key")
- .Params("items", inputWidth)
- .Params("state", stateWidth)
- .ApplyPartial(node->Child(3U)->HeadPtr(), std::move(update))
- .With(0, "key")
- .With(1)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .With(2)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (stateFields.empty())
- parent.Arg("state", 0);
- else {
- auto str = parent.Callable("AsStruct");
- for (ui32 i = 0U; i < stateWidth; ++i) {
- str.List(i)
- .Add(0, stateFields[i])
- .Arg(1, "state", i)
- .Seal();
- }
- str.Seal();
- }
- return parent;
- })
- .Done()
- .Seal()
- .Seal()
- .Lambda(5)
- .Param("key")
- .Params("state", stateWidth)
- .ApplyPartial(node->Child(4U)->HeadPtr(), std::move(finish))
- .With(0, "key")
- .With(1)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (stateFields.empty())
- parent.Arg("state", 0);
- else {
- auto str = parent.Callable("AsStruct");
- for (ui32 i = 0U; i < stateWidth; ++i) {
- str.List(i)
- .Add(0, std::move(stateFields[i]))
- .Arg(1, "state", i)
- .Seal();
- }
- str.Seal();
- }
- return parent;
- })
- .Done()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", outputWidth)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (outputFields.empty())
- parent.Arg("items", 0);
- else {
- auto str = parent.Callable("AsStruct");
- for (ui32 i = 0U; i < outputWidth; ++i) {
- str.List(i)
- .Add(0, std::move(outputFields[i]))
- .Arg(1, "items", i)
- .Seal();
- }
- str.Seal();
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeChopper(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (node->Head().IsCallable("NarrowMap") &&
- node->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
- node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() == ETypeAnnotationKind::Struct &&
- node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TStructExprType>()->GetSize() > 0U) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
-
- const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
- const auto structType = node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TStructExprType>();
- const auto outputWidth = structType->GetSize();
-
- TExprNode::TListType fields;
- fields.reserve(outputWidth);
- for (const auto& item : structType->GetItems())
- fields.emplace_back(ctx.NewAtom(node->Tail().Pos(), item->GetName()));
-
- return ctx.Builder(node->Pos())
- .Callable("NarrowMap")
- .Callable(0, "WideChopper")
- .Add(0, node->Head().HeadPtr())
- .Lambda(1)
- .Params("items", inputWidth)
- .Apply(*node->Child(1U))
- .With(0)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("key")
- .Params("items", inputWidth)
- .Apply(*node->Child(2U))
- .With(0, "key")
- .With(1)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("key")
- .Param("flow")
- .Callable("ExpandMap")
- .Apply(0, node->Tail())
- .With(0, "key")
- .With(1)
- .Callable("NarrowMap")
- .Arg(0, "flow")
- .Lambda(1)
- .Params("items", inputWidth)
- .Apply(node->Head().Tail())
- .With("items")
- .Seal()
- .Seal()
- .Seal()
- .Done()
- .Seal()
- .Lambda(1)
- .Param("item")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.Callable(i, "Member")
- .Arg(0, "item")
- .Add(1, fields[i])
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", outputWidth)
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < outputWidth; ++i) {
- parent.List(i)
- .Add(0, std::move(fields[i]))
- .Arg(1, "items", i)
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-using TTupleExpandMap = std::vector<std::optional<ui32>>;
-using TStructExpandMap = std::vector<std::optional<std::vector<std::string_view>>>;
-
-template<bool LiteralOnly>
-std::array<std::optional<ui32>, 2U> GetExpandMapsForLambda(const TExprNode& lambda, TTupleExpandMap& tupleExpndMap, TStructExpandMap& structExpndMap) {
- const auto original = lambda.ChildrenSize() - 1U;
- tupleExpndMap.resize(original);
-
- bool hasTuple = false, hasStruct = false;
- ui32 flatByTuple = 0U, flatByStruct = 0U;
-
- for (ui32 i = 0U; i < original; ++i) {
- switch (const auto child = lambda.Child(i + 1U); child->GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Tuple:
- if (!LiteralOnly || child->IsList()){
- ++flatByStruct;
- hasTuple = true;
- const auto size = child->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- flatByTuple += size;
- tupleExpndMap[i].emplace(size);
- continue;
- }
- break;
- case ETypeAnnotationKind::Struct:
- if (!LiteralOnly || child->IsCallable("AsStruct")) {
- ++flatByTuple;
- hasStruct = true;
- const auto structType = child->GetTypeAnn()->Cast<TStructExprType>();
- flatByStruct += structType->GetSize();
- structExpndMap[i].emplace(structType->GetSize());
- const auto& items = structType->GetItems();
- std::transform(items.cbegin(), items.cend(), structExpndMap[i]->begin(), std::bind(&TItemExprType::GetName, std::placeholders::_1));
- continue;
- }
- break;
- default:
- break;
- }
-
- ++flatByTuple;
- ++flatByStruct;
- }
-
- return {hasTuple ? std::optional<ui32>(flatByTuple) : std::nullopt, hasStruct ? std::optional<ui32>(flatByStruct) : std::nullopt};
-}
-
-TExprNode::TPtr MakeEmptyWideLambda(TPositionHandle pos, ui32 width, TExprContext& ctx) {
- TExprNode::TListType args(width);
- std::generate_n(args.begin(), width, [&](){ return ctx.NewArgument(pos, "arg"); });
- return ctx.NewLambda(pos, ctx.NewArguments(pos, TExprNode::TListType(args)), std::move(args));
-}
-
-TExprNode::TPtr NarrowToWide(const TExprNode& map, TExprContext& ctx) {
- const auto& root = map.Tail().Tail();
- const auto inStructType = root.GetTypeAnn()->Cast<TStructExprType>();
- if (root.IsCallable("AsStruct")) {
- TLieralStructsCacheMap membersMap; // TODO: move to context.
- const auto& members = GetLiteralStructIndexes(root, membersMap);
- return ctx.Builder(map.Pos())
- .Callable("WideMap")
- .Add(0, map.HeadPtr())
- .Lambda(1)
- .Params("fields", map.Tail().Head().ChildrenSize())
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : inStructType->GetItems()) {
- parent.ApplyPartial(i++, map.Tail().HeadPtr(), root.Child(members.find(item->GetName())->second)->TailPtr())
- .With("fields")
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
- } else {
- auto apply = ApplyNarrowMap(map.Tail(), ctx);
- TExprNode::TListType body;
- body.reserve(inStructType->GetSize());
- const auto pos = map.Tail().Pos();
- const auto& items = inStructType->GetItems();
- std::transform(items.cbegin(), items.cend(), std::back_inserter(body),
- [&](const TItemExprType* item) { return ctx.NewCallable(pos, "Member", {apply.back(), ctx.NewAtom(pos, item->GetName())}); });
- auto lambda = ctx.NewLambda(pos, std::move(apply.front()), std::move(body));
-
- return ctx.Builder(map.Pos())
- .Callable("WideMap")
- .Add(0, map.HeadPtr())
- .Add(1, std::move(lambda))
- .Seal().Build();
- }
-}
-
-void FlattenLambdaBody(TExprNode::TPtr& lambda, const TTupleExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx) {
- TExprNode::TListType flatten;
- flatten.reserve(lambda->Head().ChildrenSize() + newWidth - oldWidth);
- for (ui32 i = 0U; i < oldWidth; ++i) {
- const auto child = lambda->Child(i + 1U);
- if (const auto expand = expandMap.size() > i ? expandMap[i] : std::nullopt) {
- for (ui32 j = 0U; j < *expand; ++j)
- flatten.emplace_back(child->IsList() ? child->ChildPtr(j) : ctx.NewCallable(child->Pos(), "Nth",
- {lambda->ChildPtr(i + 1U), ctx.NewAtom(child->Pos(), ToString(j), TNodeFlags::Default)}
- ));
- } else {
- flatten.emplace_back(lambda->ChildPtr(i + 1U));
- }
- }
-
- lambda = ctx.DeepCopyLambda(*lambda, std::move(flatten));
-}
-
-void FlattenLambdaBody(TExprNode::TPtr& lambda, const TStructExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TLieralStructsCacheMap& membersMap, TExprContext& ctx) {
- TExprNode::TListType flatten;
- flatten.reserve(lambda->Head().ChildrenSize() + newWidth - oldWidth);
- for (ui32 i = 0U; i < oldWidth; ++i) {
- if (const auto expand = expandMap.size() > i ? expandMap[i] : std::nullopt) {
- if (const auto child = lambda->Child(i + 1U); child->IsCallable("AsStruct")) {
- const auto& members = GetLiteralStructIndexes(*child, membersMap);
- for (const auto& member : *expand)
- flatten.emplace_back(child->Child(members.find(member)->second)->TailPtr());
- } else {
- for (const auto& member : *expand)
- flatten.emplace_back(ctx.NewCallable(child->Pos(), "Member", {lambda->ChildPtr(i + 1U), ctx.NewAtom(child->Pos(), member)}));
- }
- } else {
- flatten.emplace_back(lambda->ChildPtr(i + 1U));
- }
- }
-
- lambda = ctx.DeepCopyLambda(*lambda, std::move(flatten));
-}
-
-void FlattenLambdaArgs(TExprNode::TPtr& lambda, const TTupleExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx, ui32 skip = 0U) {
- const auto inputWidth = lambda->Head().ChildrenSize() + newWidth - oldWidth;
- lambda = ctx.Builder(lambda->Pos())
- .Lambda()
- .Params("items", inputWidth)
- .Apply(*lambda)
- .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
- for (ui32 i = 0U, k = 0U; i < lambda->Head().ChildrenSize(); ++i) {
- if (const auto expand = i >= skip && expandMap.size() + skip > i ? expandMap[i - skip] : std::nullopt) {
- parent.With(i).List().Do([&](TExprNodeBuilder& list) -> TExprNodeBuilder& {
- for (ui32 j = 0U; j < *expand; ++j) {
- list.Arg(j, "items", k++);
- }
- return list;
- }).Seal().Done();
- } else {
- parent.With(i, "items", k++);
- }
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
-}
-
-void FlattenLambdaArgs(TExprNode::TPtr& lambda, const TStructExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx, ui32 skip = 0U) {
- const auto inputWidth = lambda->Head().ChildrenSize() + newWidth - oldWidth;
- lambda = ctx.Builder(lambda->Pos())
- .Lambda()
- .Params("items", inputWidth)
- .Apply(*lambda)
- .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
- for (ui32 i = 0U, k = 0U; i < lambda->Head().ChildrenSize(); ++i) {
- if (const auto expand = i >= skip && expandMap.size() + skip > i ? expandMap[i - skip] : std::nullopt) {
- parent.With(i).Callable("AsStruct").Do([&](TExprNodeBuilder& list) -> TExprNodeBuilder& {
- ui32 j = 0U;
- for (const auto& field : *expand) {
- list.List(j++)
- .Atom(0, field)
- .Arg(1, "items", k++)
- .Seal();
- }
- return list;
- }).Seal().Done();
- } else {
- parent.With(i, "items", k++);
- }
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
-}
-
-using TDedupMap = std::vector<std::pair<ui32, ui32>>;
-TDedupMap DedupState(const TExprNode& init, const TExprNode& update) {
- YQL_ENSURE(init.ChildrenSize() == update.ChildrenSize(), "Must be same size.");
- const auto skip = init.Head().ChildrenSize();
- YQL_ENSURE(update.Head().ChildrenSize() + 1U == init.ChildrenSize() + skip, "Wrong update args count.");
-
- TNodeMap<ui32> map;
- map.reserve(update.Head().ChildrenSize());
-
- std::vector<ui32> pos;
- pos.reserve(init.ChildrenSize() - 1U);
-
- for (ui32 i = 1U; i < init.ChildrenSize(); ++i)
- pos.emplace_back(map.emplace(init.Child(i), i - 1U).first->second);
-
- map.clear();
- ui32 i = 0U;
- update.Head().ForEachChild([&](const TExprNode& arg) { map.emplace(&arg, i < skip ? i++ : skip + pos[i++ - skip]); });
-
- TDedupMap dedups;
- for (ui32 j = 1U; j <= pos.size(); ++j) {
- if (const auto i = pos[j - 1U] + 1U; i < j) {
- if (const auto one = update.Child(i), two = update.Child(j); one != two && CompareExprTreeParts(*one, *two, map)) {
- dedups.emplace_back(i - 1U, j - 1U);
- }
- }
- }
-
- return dedups;
-}
-
-TExprNode::TPtr DedupLambdaBody(const TExprNode& lambda, const TDedupMap& dedups, TExprContext& ctx) {
- auto state = GetLambdaBody(lambda);
- std::for_each(dedups.cbegin(), dedups.cend(), [&](const std::pair<ui32, ui32>& pair) { state[pair.second] = state[pair.first]; });
- return ctx.DeepCopyLambda(lambda, std::move(state));
-}
-
-std::vector<ui32> UnusedState(const TExprNode& init, const TExprNode& update, const TExprNode& finish) {
- YQL_ENSURE(init.ChildrenSize() == update.ChildrenSize(), "Must be same size.");
-
- const auto size = init.ChildrenSize() - 1U;
- const auto skipU = update.Head().ChildrenSize() - size;
- const auto skipF = finish.Head().ChildrenSize() - size;
-
- std::vector<ui32> unused;
- unused.reserve(size);
- for (ui32 j = 0U; j < size; ++j) {
- if (update.Head().Child(j + skipU)->Unique() && finish.Head().Child(j + skipF)->Unique()) {
- unused.emplace_back(j);
- }
- }
-
- return unused;
-}
-
-TExprNode::TListType&& DropUnused(TExprNode::TListType&& list, const std::vector<ui32>& unused, ui32 skip = 0U) {
- std::for_each(unused.cbegin(), unused.cend(), [&](const ui32 index) { list[index + skip] = TExprNode::TPtr(); });
- list.erase(std::remove_if(list.begin(), list.end(), std::logical_not<TExprNode::TPtr>()), list.cend());
- return std::move(list);
-}
-
-TExprNode::TPtr OptimizeWideCombiner(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto originalKeySize = node->Child(2U)->ChildrenSize() - 1U;
- TTupleExpandMap tupleExpandMap(originalKeySize);
- TStructExpandMap structExpandMap(originalKeySize);
-
- const auto needKeyFlatten = GetExpandMapsForLambda<false>(*node->Child(2U), tupleExpandMap, structExpandMap);
-
- if (needKeyFlatten.front()) {
- const auto flattenSize = *needKeyFlatten.front();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by tuple for " << node->Content() << " from " << originalKeySize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- FlattenLambdaBody(children[2U], tupleExpandMap, originalKeySize, flattenSize, ctx);
- FlattenLambdaArgs(children[3U], tupleExpandMap, originalKeySize, flattenSize, ctx);
- FlattenLambdaArgs(children[4U], tupleExpandMap, originalKeySize, flattenSize, ctx);
- FlattenLambdaArgs(children[5U], tupleExpandMap, originalKeySize, flattenSize, ctx);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (needKeyFlatten.back()) {
- const auto flattenSize = *needKeyFlatten.back();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by struct for " << node->Content() << " from " << originalKeySize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- TLieralStructsCacheMap membersMap;
- FlattenLambdaBody(children[2U], structExpandMap, originalKeySize, flattenSize, membersMap, ctx);
- FlattenLambdaArgs(children[3U], structExpandMap, originalKeySize, flattenSize, ctx);
- FlattenLambdaArgs(children[4U], structExpandMap, originalKeySize, flattenSize, ctx);
- FlattenLambdaArgs(children[5U], structExpandMap, originalKeySize, flattenSize, ctx);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- tupleExpandMap.clear();
- structExpandMap.clear();
- const auto originalStateSize = node->Child(3U)->ChildrenSize() - 1U;
- tupleExpandMap.resize(originalStateSize);
- structExpandMap.resize(originalStateSize);
-
- const auto needStateFlatten = GetExpandMapsForLambda<true>(*node->Child(3U), tupleExpandMap, structExpandMap);
-
- if (needStateFlatten.front()) {
- const auto flattenSize = *needStateFlatten.front();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten state by tuple for " << node->Content() << " from " << originalStateSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- FlattenLambdaBody(children[3U], tupleExpandMap, originalStateSize, flattenSize, ctx);
- FlattenLambdaBody(children[4U], tupleExpandMap, originalStateSize, flattenSize, ctx);
- FlattenLambdaArgs(children[4U], tupleExpandMap, originalStateSize, flattenSize, ctx, node->Child(3U)->Head().ChildrenSize());
- FlattenLambdaArgs(children[5U], tupleExpandMap, originalStateSize, flattenSize, ctx, node->Child(2U)->ChildrenSize() - 1U);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (needStateFlatten.back()) {
- const auto flattenSize = *needStateFlatten.back();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten state by struct for " << node->Content() << " from " << originalStateSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- TLieralStructsCacheMap membersMap;
- FlattenLambdaBody(children[3U], structExpandMap, originalStateSize, flattenSize, membersMap, ctx);
- FlattenLambdaBody(children[4U], structExpandMap, originalStateSize, flattenSize, membersMap, ctx);
- FlattenLambdaArgs(children[4U], structExpandMap, originalStateSize, flattenSize, ctx, node->Child(3U)->Head().ChildrenSize());
- FlattenLambdaArgs(children[5U], structExpandMap, originalStateSize, flattenSize, ctx, node->Child(2U)->ChildrenSize() - 1U);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (const auto dedups = DedupState(*node->Child(3), *node->Child(4)); !dedups.empty()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->Content() << ' ' << dedups.size() << " states.";
-
- auto children = node->ChildrenList();
- children[4U] = DedupLambdaBody(*children[4U], dedups, ctx);
-
- const auto& finish = node->Tail();
- const auto size = finish.Head().ChildrenSize();
- const auto skip = children[2U]->ChildrenSize() - 1U;
-
- std::vector<ui32> map(size);
- std::iota(map.begin(), map.end(), 0U);
- std::for_each(dedups.cbegin(), dedups.cend(), [&](const std::pair<ui32, ui32>& it){ map[it.second + skip] = it.first + skip; } );
-
- children.back() = ctx.Builder(finish.Pos())
- .Lambda()
- .Params("out", finish.Head().ChildrenSize())
- .Apply(finish)
- .Do([&](TExprNodeReplaceBuilder& inner) -> TExprNodeReplaceBuilder& {
- for (ui32 j = 0U; j < finish.Head().ChildrenSize(); ++j) {
- inner.With(j, "out", map[j]);
- }
- return inner;
- })
- .Seal()
- .Seal().Build();
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (const auto unused = UnusedState(*node->Child(3), *node->Child(4), node->Tail()); !unused.empty()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Unused " << node->Content() << ' ' << unused.size() << " states.";
-
- auto children = node->ChildrenList();
- const auto size = children[3]->ChildrenSize() - 1U;
- children[3] = ctx.DeepCopyLambda(*children[3], DropUnused(GetLambdaBody(*children[3]), unused));
- children[4] = ctx.DeepCopyLambda(*children[4], DropUnused(GetLambdaBody(*children[4]), unused));
- children[4] = ctx.ChangeChild(*children[4], 0U, ctx.NewArguments(children[4]->Head().Pos(), DropUnused(children[4]->Head().ChildrenList(), unused, children[4]->Head().ChildrenSize() - size)));
- children[5] = ctx.ChangeChild(*children[5], 0U, ctx.NewArguments(children[5]->Head().Pos(), DropUnused(children[5]->Head().ChildrenList(), unused, children[5]->Head().ChildrenSize() - size)));
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeWideCondense1(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto originalSize = node->Tail().ChildrenSize() - 1U;
- TTupleExpandMap tupleExpandMap(originalSize);
- TStructExpandMap structExpandMap(originalSize);
-
- const auto inputWidth = node->Child(1U)->Head().ChildrenSize();
- const auto needFlatten = GetExpandMapsForLambda<true>(node->Tail(), tupleExpandMap, structExpandMap);
-
- if (needFlatten.front()) {
- const auto flattenSize = *needFlatten.front();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten " << node->Content() << " tuple outputs from " << originalSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- FlattenLambdaBody(children[1U], tupleExpandMap, originalSize, flattenSize, ctx);
- FlattenLambdaBody(children[3U], tupleExpandMap, originalSize, flattenSize, ctx);
- FlattenLambdaArgs(children[2U], tupleExpandMap, originalSize, flattenSize, ctx, inputWidth);
- FlattenLambdaArgs(children[3U], tupleExpandMap, originalSize, flattenSize, ctx, inputWidth);
-
- auto mapper = MakeEmptyWideLambda(node->Pos(), originalSize, ctx);
- FlattenLambdaArgs(mapper, tupleExpandMap, originalSize, flattenSize, ctx);
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, ctx.ChangeChildren(*node, std::move(children)))
- .Add(1, std::move(mapper))
- .Seal().Build();
- }
-
- if (needFlatten.back()) {
- const auto flattenSize = *needFlatten.back();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten " << node->Content() << " struct outputs from " << originalSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- TLieralStructsCacheMap membersMap;
- FlattenLambdaBody(children[1U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
- FlattenLambdaBody(children[3U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
- FlattenLambdaArgs(children[2U], structExpandMap, originalSize, flattenSize, ctx, inputWidth);
- FlattenLambdaArgs(children[3U], structExpandMap, originalSize, flattenSize, ctx, inputWidth);
-
- auto mapper = MakeEmptyWideLambda(node->Pos(), originalSize, ctx);
- FlattenLambdaArgs(mapper, structExpandMap, originalSize, flattenSize, ctx);
- return ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, ctx.ChangeChildren(*node, std::move(children)))
- .Add(1, std::move(mapper))
- .Seal().Build();
- }
-
- if (const auto dedups = DedupState(*node->Child(1), node->Tail()); !dedups.empty()) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->Content() << ' ' << dedups.size() << " states.";
- return ctx.ChangeChild(*node, 3, DedupLambdaBody(node->Tail(), dedups, ctx));
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeWideChopper(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto originalSize = node->Child(1U)->ChildrenSize() - 1U;
- TTupleExpandMap tupleExpandMap(originalSize);
- TStructExpandMap structExpandMap(originalSize);
-
- const auto needFlatten = GetExpandMapsForLambda<false>(*node->Child(1U), tupleExpandMap, structExpandMap);
-
- if (needFlatten.front()) {
- const auto flattenSize = *needFlatten.front();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by tuple for " << node->Content() << " from " << originalSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- FlattenLambdaBody(children[1U], tupleExpandMap, originalSize, flattenSize, ctx);
- FlattenLambdaArgs(children[2U], tupleExpandMap, originalSize, flattenSize, ctx);
- FlattenLambdaArgs(children[3U], tupleExpandMap, originalSize, flattenSize, ctx);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- if (needFlatten.back()) {
- const auto flattenSize = *needFlatten.back();
- YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by struct for " << node->Content() << " from " << originalSize << " to " << flattenSize;
- auto children = node->ChildrenList();
-
- TLieralStructsCacheMap membersMap;
- FlattenLambdaBody(children[1U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
- FlattenLambdaArgs(children[2U], structExpandMap, originalSize, flattenSize, ctx);
- FlattenLambdaArgs(children[3U], structExpandMap, originalSize, flattenSize, ctx);
-
- return ctx.ChangeChildren(*node, std::move(children));
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeWideMaps(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable("ExpandMap")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
- auto lambda = ctx.FuseLambdas(node->Tail(), input.Tail());
- return ctx.NewCallable(node->Pos(),
- node->Content().starts_with("Narrow") ? TString("Ordered") += node->Content().substr(6U, 16U) : input.Content(),
- {input.HeadPtr(), std::move(lambda)});
- } else if (input.IsCallable("WideMap") && !node->IsCallable("NarrowFlatMap")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
- auto lambda = ctx.FuseLambdas(node->Tail(), input.Tail());
- return ctx.ChangeChildren(*node, {input.HeadPtr(), std::move(lambda)});
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeNarrowFlatMap(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto& lambda = node->Tail();
- const auto& body = lambda.Tail();
-
- if (body.IsCallable("If") && 1U == body.Tail().ChildrenSize() && body.Tail().IsCallable({"List", "Nothing"})) {
- const auto width = lambda.Head().ChildrenSize();
- if (auto shared = FindSharedNode(body.ChildPtr(1), body.HeadPtr(),
- [&lambda] (const TExprNode::TPtr& node) {
- if (!node->IsCallable())
- return false;
-
- if (node->GetTypeAnn() && node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
- return false;
- }
-
- return node->GetDependencyScope()->second == &lambda;
- }); shared.first && shared.second) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Extract " << shared.first->Content() << " from " << node->Content() << " with " << body.Content();
-
- auto argNodes = lambda.Head().ChildrenList();
- argNodes.emplace_back(ctx.NewArgument(lambda.Head().Pos(), TString("extracted") += ToString(argNodes.size())));
-
- auto args = ctx.NewArguments(lambda.Head().Pos(), std::move(argNodes));
- auto body = ctx.ReplaceNode(lambda.TailPtr(), *shared.first, args->TailPtr());
-
- auto children = node->ChildrenList();
- children.back() = ctx.NewLambda(lambda.Pos(), std::move(args), std::move(body));
- children.front() = ctx.Builder(node->Pos())
- .Callable("WideMap")
- .Add(0, std::move(children.front()))
- .Lambda(1)
- .Params("items", width)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < width; ++i) {
- parent.Arg(i, "items", i);
- }
- return parent;
- })
- .ApplyPartial(width, lambda.HeadPtr(), std::move(shared.first))
- .With("items")
- .Seal()
- .Seal()
- .Seal().Build();
-
- return ctx.ChangeChildren(*node, std::move(children));
- } else if (!shared.first) {
- YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " with " << body.Content() << " to WideFilter";
- const bool just = 2U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable("List")
- || 1U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable({"AsList", "Just"});
- return ctx.Builder(node->Pos())
- .Callable(just ? "NarrowMap" : "NarrowFlatMap")
- .Callable(0, "WideFilter")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Params("items", width)
- .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With("items").Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("items", width)
- .ApplyPartial(lambda.HeadPtr(), just ? body.Child(1)->TailPtr() : body.ChildPtr(1)).With("items").Seal()
- .Seal()
- .Seal().Build();
- }
- }
-
- return OptimizeWideMaps(node, ctx);
-}
-
-TExprNode::TPtr OptimizeSqueezeToDict(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
- return ctx.NewCallable(node->Pos(), "NarrowSqueezeToDict", {
- input.HeadPtr(),
- ctx.FuseLambdas(*node->Child(1U), input.Tail()),
- ctx.FuseLambdas(*node->Child(2U), input.Tail()),
- node->TailPtr()
- });
- }
- return node;
-}
-
-TExprNode::TListType GetOptionals(const TPositionHandle& pos, const TStructExprType& type, TExprContext& ctx) {
- TExprNode::TListType result;
- for (const auto& item : type.GetItems())
- if (ETypeAnnotationKind::Optional == item->GetItemType()->GetKind())
- result.emplace_back(ctx.NewAtom(pos, item->GetName()));
- return result;
-}
-
-TExprNode::TListType GetOptionals(const TPositionHandle& pos, const TTupleExprType& type, TExprContext& ctx) {
- TExprNode::TListType result;
- if (const auto& items = type.GetItems(); !items.empty())
- for (ui32 i = 0U; i < items.size(); ++i)
- if (ETypeAnnotationKind::Optional == items[i]->GetKind())
- result.emplace_back(ctx.NewAtom(pos, ToString(i), TNodeFlags::Default));
- return result;
-}
-
-template <bool EnableNewOptimizers, bool TupleOrStruct>
-TExprNode::TPtr ExpandSkipNullFields(const TExprNode::TPtr& node, TExprContext& ctx) {
- if constexpr (EnableNewOptimizers) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- if (auto fields = node->ChildrenSize() > 1U ? node->Tail().ChildrenList() :
- GetOptionals(node->Pos(), *GetSeqItemType(node->Head().GetTypeAnn())->Cast<std::conditional_t<TupleOrStruct, TTupleExprType, TStructExprType>>(), ctx);
- fields.empty()) {
- return node->HeadPtr();
- } else {
- return ctx.Builder(node->Pos())
- .Callable("OrderedFilter")
- .Add(0, node->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Callable("And")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0U; i < fields.size(); ++i) {
- parent
- .Callable(i, "Exists")
- .Callable(0, TupleOrStruct ? "Nth" : "Member")
- .Arg(0, "item")
- .Add(1, std::move(fields[i]))
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
- }
- return node;
-}
-
+ ui32 i = 0U;
+ for (const auto& item : inItemType->Cast<TStructExprType>()->GetItems()) {
+ parent.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Atom(1, item->GetName())
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+
+ auto wide = MakeWideCommonJoinCore<TStructExprType>(input, std::move(expand), ctx);
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, std::move(wide.first))
+ .Lambda(1)
+ .Params("fields", wide.second.size())
+ .Apply(node->Tail())
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (auto& item : wide.second) {
+ parent.List(i)
+ .Add(0, std::move(item))
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable("CombineCore") && !input.Head().IsArgument() &&
+ (input.Child(2U)->Tail().IsCallable("AsStruct") || input.Child(3U)->Tail().IsCallable("AsStruct")) &&
+ input.Child(4U)->Tail().IsCallable("Just") && ETypeAnnotationKind::Struct == input.Child(4U)->Tail().Head().GetTypeAnn()->GetKind()) {
+ if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
+ if (const auto inStructType = inItemType->Cast<TStructExprType>(); inStructType->GetSize() > 0U) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+
+ const auto& output = input.Child(4U)->Tail().Head();
+ const auto structType = output.GetTypeAnn()->Cast<TStructExprType>();
+
+ const auto outputWidth = structType->GetSize();
+ const auto inputWidth = inStructType->GetSize();
+
+ TExprNode::TListType inputFilelds, stateFields, outputFields, init, update, finish;
+ inputFilelds.reserve(inputWidth);
+ for (const auto& item : inStructType->GetItems()) {
+ inputFilelds.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
+ }
+
+ const auto stateWidth = CollectStateNodes(*input.Child(2U), *input.Child(3U), stateFields, init, update, ctx);
+
+ outputFields.reserve(outputWidth);
+ finish.reserve(outputWidth);
+ if (output.IsCallable("AsStruct")) {
+ input.Child(4U)->Tail().Head().ForEachChild([&](const TExprNode& child) {
+ outputFields.emplace_back(child.HeadPtr());
+ finish.emplace_back(child.TailPtr());
+ });
+ } else {
+ for (const auto& item : structType->GetItems()) {
+ outputFields.emplace_back(ctx.NewAtom(output.Pos(), item->GetName()));
+ finish.emplace_back(ctx.NewCallable(output.Pos(), "Member", {input.Child(4U)->Tail().HeadPtr(), outputFields.back()}));
+ }
+ }
+
+ auto limit = input.ChildrenSize() > TCoCombineCore::idx_MemLimit ? input.TailPtr() : ctx.NewAtom(input.Pos(), "");
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Callable(0, "WideCombiner")
+ .Callable(0, node->Content())
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Add(1, member)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Add(1, std::move(limit))
+ .Lambda(2)
+ .Params("items", inputWidth)
+ .Apply(*input.Child(1U))
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("key")
+ .Params("items", inputWidth)
+ .ApplyPartial(input.Child(2U)->HeadPtr(), std::move(init))
+ .With(0, "key")
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(4)
+ .Param("key")
+ .Params("items", inputWidth)
+ .Params("state", stateWidth)
+ .ApplyPartial(input.Child(3U)->HeadPtr(), std::move(update))
+ .With(0, "key")
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .With(2)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ parent.List(i)
+ .Add(0, stateFields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(5)
+ .Param("key")
+ .Params("state", stateWidth)
+ .ApplyPartial(input.Child(4U)->HeadPtr(), std::move(finish))
+ .With(0, "key")
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ parent.List(i)
+ .Add(0, std::move(stateFields[i]))
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", outputWidth)
+ .Apply(node->Tail())
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.List(i)
+ .Add(0, std::move(outputFields[i]))
+ .Arg(1, "items", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+ }
+
+ if (const auto& input = node->Head(); input.IsCallable("Condense1") && !input.Head().IsArgument() &&
+ (input.Child(1U)->Tail().IsCallable("AsStruct") || input.Tail().Tail().IsCallable("AsStruct"))) {
+ if (const auto inItemType = GetSeqItemType(input.Head().GetTypeAnn()); ETypeAnnotationKind::Struct == inItemType->GetKind()) {
+ if (const auto inStructType = inItemType->Cast<TStructExprType>(); inStructType->GetSize() > 0U) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+
+ const auto inputWidth = inStructType->GetSize();
+ TExprNode::TListType inputFilelds, stateFields, init, update;
+ inputFilelds.reserve(inputWidth);
+ for (const auto& item : inStructType->GetItems()) {
+ inputFilelds.emplace_back(ctx.NewAtom(input.Pos(), item->GetName()));
+ }
+
+ const auto stateWidth = CollectStateNodes(*input.Child(1U), input.Tail(), stateFields, init, update, ctx);
+
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Callable(0, "WideCondense1")
+ .Callable(0, node->Content())
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Add(1, member)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", inputWidth)
+ .ApplyPartial(input.Child(1U)->HeadPtr(), std::move(init))
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Params("items", inputWidth)
+ .Params("state", stateWidth)
+ .Apply(*input.Child(2U))
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ parent.List(i)
+ .Add(0, stateFields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Params("items", inputWidth)
+ .Params("state", stateWidth)
+ .ApplyPartial(input.Tail().HeadPtr(), std::move(update))
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& member : inputFilelds) {
+ parent.List(i)
+ .Add(0, member)
+ .Arg(1, "items", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ parent.List(i)
+ .Add(0, stateFields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", stateWidth)
+ .Apply(node->Tail())
+ .With(0)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ parent.List(i)
+ .Add(0, std::move(stateFields[i]))
+ .Arg(1, "items", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+ }
+
+ return node;
+}
+
+TExprNode::TPtr JustIf(bool optional, TExprNode::TPtr&& node, TExprContext& ctx) {
+ return ctx.WrapByCallableIf(optional, "Just", std::move(node));
+}
+
+template<bool TupleOrStruct>
+TExprNode::TPtr AutoMapGetElementhOfOptionalArray(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over " << node->Head().Content();
+ return ctx.ChangeChild(node->Head(), 0U, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx));
+ }
+
+ if (const auto headType = node->Head().GetTypeAnn(); ETypeAnnotationKind::Optional == headType->GetKind()) {
+ const auto arrayType = headType->Cast<TOptionalExprType>()->GetItemType();
+ const auto itemType = TupleOrStruct ?
+ arrayType->Cast<TTupleExprType>()->GetItems()[FromString<ui32>(node->Tail().Content())]:
+ arrayType->Cast<TStructExprType>()->GetItems()[*arrayType->Cast<TStructExprType>()->FindItem(node->Tail().Content())]->GetItemType();
+
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " over " << node->Head().Content();
+ auto ret = ctx.ChangeChild(*node, 0U, node->Head().HeadPtr());
+ return JustIf(!itemType->IsOptionalOrNull(), std::move(ret), ctx);
+ }
+
+/*TODO: constexpr auto typeName = TupleOrStruct ? "tuple" : "struct";
+ YQL_CLOG(DEBUG, CorePeepHole) << "Wrap " << node->Content() << " for optional " << typeName << '.';
+ return itemType->IsOptionalOrNull() ?
+ ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param(typeName)
+ .Callable(node->Content())
+ .Arg(0, typeName)
+ .Add(1, node->TailPtr())
+ .Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(node->Pos())
+ .Callable("IfPresent")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param(typeName)
+ .Callable("Just")
+ .Callable(0, node->Content())
+ .Arg(0, typeName)
+ .Add(1, node->TailPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Callable(2, "Nothing")
+ .Add(0, ExpandType(node->Pos(), *node->GetTypeAnn(), ctx))
+ .Seal()
+ .Seal()
+ .Build();*/
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeNth(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().Type() == TExprNode::List) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Drop " << node->Content() << " over tuple literal";
+ const auto index = FromString<ui32>(node->Tail().Content());
+ return node->Head().ChildPtr(index);
+ }
+
+ return AutoMapGetElementhOfOptionalArray<true>(node, ctx);
+}
+
+TExprNode::TPtr OptimizeMember(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("AsStruct")) {
+ for (ui32 index = 0U; index < node->Head().ChildrenSize(); ++index) {
+ if (const auto tuple = node->Head().Child(index); tuple->Head().Content() == node->Tail().Content()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Drop "<< node->Content() << " over " << node->Head().Content();
+ return tuple->TailPtr();
+ }
+ }
+ }
+
+ return AutoMapGetElementhOfOptionalArray<false>(node, ctx);
+}
+
+TExprNode::TPtr OptimizeCondense1(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("NarrowMap") &&
+ ETypeAnnotationKind::Struct == node->Tail().Tail().GetTypeAnn()->GetKind()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
+
+ const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
+ TExprNode::TListType fields, init, update;
+ const auto outputWidth = CollectStateNodes(*node->Child(1U), node->Tail(), fields, init, update, ctx);
+
+ return ctx.Builder(node->Pos())
+ .Callable("NarrowMap")
+ .Callable(0, "WideCondense1")
+ .Add(0, node->Head().HeadPtr())
+ .Lambda(1)
+ .Params("items", inputWidth)
+ .ApplyPartial(node->Child(1U)->HeadPtr(), std::move(init))
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Params("items", inputWidth)
+ .Params("state", outputWidth)
+ .Apply(*node->Child(2U))
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.List(i)
+ .Add(0, fields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Params("items", inputWidth)
+ .Params("state", outputWidth)
+ .ApplyPartial(node->Tail().HeadPtr(), std::move(update))
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.List(i)
+ .Add(0, fields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", outputWidth)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.List(i)
+ .Add(0, std::move(fields[i]))
+ .Arg(1, "items", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeCombineCore(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("NarrowMap") && node->Child(4U)->Tail().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
+
+ const auto& output = node->Child(4U)->Tail().Head();
+ const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
+
+ const auto structType = ETypeAnnotationKind::Struct == output.GetTypeAnn()->GetKind() ? output.GetTypeAnn()->Cast<TStructExprType>() : nullptr;
+ const auto outputWidth = structType ? structType->GetSize() : 1U;
+
+ TExprNode::TListType stateFields, outputFields, init, update, finish;
+ outputFields.reserve(outputWidth);
+ finish.reserve(outputWidth);
+
+ const auto stateWidth = CollectStateNodes(*node->Child(2U), *node->Child(3U), stateFields, init, update, ctx);
+
+ if (output.IsCallable("AsStruct")) {
+ node->Child(4U)->Tail().Head().ForEachChild([&](const TExprNode& child) {
+ outputFields.emplace_back(child.HeadPtr());
+ finish.emplace_back(child.TailPtr());
+ });
+ } else if (structType) {
+ for (const auto& item : structType->GetItems()) {
+ outputFields.emplace_back(ctx.NewAtom(output.Pos(), item->GetName()));
+ finish.emplace_back(ctx.NewCallable(output.Pos(), "Member", {node->Child(4U)->Tail().HeadPtr(), outputFields.back()}));
+ }
+ } else {
+ finish.emplace_back(node->Child(4U)->Tail().HeadPtr());
+ }
+
+ auto limit = node->ChildrenSize() > TCoCombineCore::idx_MemLimit ? node->TailPtr() : ctx.NewAtom(node->Pos(), "");
+ return ctx.Builder(node->Pos())
+ .Callable("NarrowMap")
+ .Callable(0, "WideCombiner")
+ .Add(0, node->Head().HeadPtr())
+ .Add(1, std::move(limit))
+ .Lambda(2)
+ .Params("items", inputWidth)
+ .Apply(*node->Child(1U))
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("key")
+ .Params("items", inputWidth)
+ .ApplyPartial(node->Child(2U)->HeadPtr(), std::move(init))
+ .With(0, "key")
+ .With(1)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(4)
+ .Param("key")
+ .Params("items", inputWidth)
+ .Params("state", stateWidth)
+ .ApplyPartial(node->Child(3U)->HeadPtr(), std::move(update))
+ .With(0, "key")
+ .With(1)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .With(2)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (stateFields.empty())
+ parent.Arg("state", 0);
+ else {
+ auto str = parent.Callable("AsStruct");
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ str.List(i)
+ .Add(0, stateFields[i])
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ str.Seal();
+ }
+ return parent;
+ })
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(5)
+ .Param("key")
+ .Params("state", stateWidth)
+ .ApplyPartial(node->Child(4U)->HeadPtr(), std::move(finish))
+ .With(0, "key")
+ .With(1)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (stateFields.empty())
+ parent.Arg("state", 0);
+ else {
+ auto str = parent.Callable("AsStruct");
+ for (ui32 i = 0U; i < stateWidth; ++i) {
+ str.List(i)
+ .Add(0, std::move(stateFields[i]))
+ .Arg(1, "state", i)
+ .Seal();
+ }
+ str.Seal();
+ }
+ return parent;
+ })
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", outputWidth)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (outputFields.empty())
+ parent.Arg("items", 0);
+ else {
+ auto str = parent.Callable("AsStruct");
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ str.List(i)
+ .Add(0, std::move(outputFields[i]))
+ .Arg(1, "items", i)
+ .Seal();
+ }
+ str.Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeChopper(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (node->Head().IsCallable("NarrowMap") &&
+ node->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow &&
+ node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() == ETypeAnnotationKind::Struct &&
+ node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TStructExprType>()->GetSize() > 0U) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << node->Head().Content();
+
+ const auto inputWidth = node->Head().Tail().Head().ChildrenSize();
+ const auto structType = node->Tail().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TStructExprType>();
+ const auto outputWidth = structType->GetSize();
+
+ TExprNode::TListType fields;
+ fields.reserve(outputWidth);
+ for (const auto& item : structType->GetItems())
+ fields.emplace_back(ctx.NewAtom(node->Tail().Pos(), item->GetName()));
+
+ return ctx.Builder(node->Pos())
+ .Callable("NarrowMap")
+ .Callable(0, "WideChopper")
+ .Add(0, node->Head().HeadPtr())
+ .Lambda(1)
+ .Params("items", inputWidth)
+ .Apply(*node->Child(1U))
+ .With(0)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("key")
+ .Params("items", inputWidth)
+ .Apply(*node->Child(2U))
+ .With(0, "key")
+ .With(1)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("key")
+ .Param("flow")
+ .Callable("ExpandMap")
+ .Apply(0, node->Tail())
+ .With(0, "key")
+ .With(1)
+ .Callable("NarrowMap")
+ .Arg(0, "flow")
+ .Lambda(1)
+ .Params("items", inputWidth)
+ .Apply(node->Head().Tail())
+ .With("items")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Done()
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.Callable(i, "Member")
+ .Arg(0, "item")
+ .Add(1, fields[i])
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", outputWidth)
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < outputWidth; ++i) {
+ parent.List(i)
+ .Add(0, std::move(fields[i]))
+ .Arg(1, "items", i)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+using TTupleExpandMap = std::vector<std::optional<ui32>>;
+using TStructExpandMap = std::vector<std::optional<std::vector<std::string_view>>>;
+
+template<bool LiteralOnly>
+std::array<std::optional<ui32>, 2U> GetExpandMapsForLambda(const TExprNode& lambda, TTupleExpandMap& tupleExpndMap, TStructExpandMap& structExpndMap) {
+ const auto original = lambda.ChildrenSize() - 1U;
+ tupleExpndMap.resize(original);
+
+ bool hasTuple = false, hasStruct = false;
+ ui32 flatByTuple = 0U, flatByStruct = 0U;
+
+ for (ui32 i = 0U; i < original; ++i) {
+ switch (const auto child = lambda.Child(i + 1U); child->GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Tuple:
+ if (!LiteralOnly || child->IsList()){
+ ++flatByStruct;
+ hasTuple = true;
+ const auto size = child->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ flatByTuple += size;
+ tupleExpndMap[i].emplace(size);
+ continue;
+ }
+ break;
+ case ETypeAnnotationKind::Struct:
+ if (!LiteralOnly || child->IsCallable("AsStruct")) {
+ ++flatByTuple;
+ hasStruct = true;
+ const auto structType = child->GetTypeAnn()->Cast<TStructExprType>();
+ flatByStruct += structType->GetSize();
+ structExpndMap[i].emplace(structType->GetSize());
+ const auto& items = structType->GetItems();
+ std::transform(items.cbegin(), items.cend(), structExpndMap[i]->begin(), std::bind(&TItemExprType::GetName, std::placeholders::_1));
+ continue;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ++flatByTuple;
+ ++flatByStruct;
+ }
+
+ return {hasTuple ? std::optional<ui32>(flatByTuple) : std::nullopt, hasStruct ? std::optional<ui32>(flatByStruct) : std::nullopt};
+}
+
+TExprNode::TPtr MakeEmptyWideLambda(TPositionHandle pos, ui32 width, TExprContext& ctx) {
+ TExprNode::TListType args(width);
+ std::generate_n(args.begin(), width, [&](){ return ctx.NewArgument(pos, "arg"); });
+ return ctx.NewLambda(pos, ctx.NewArguments(pos, TExprNode::TListType(args)), std::move(args));
+}
+
+TExprNode::TPtr NarrowToWide(const TExprNode& map, TExprContext& ctx) {
+ const auto& root = map.Tail().Tail();
+ const auto inStructType = root.GetTypeAnn()->Cast<TStructExprType>();
+ if (root.IsCallable("AsStruct")) {
+ TLieralStructsCacheMap membersMap; // TODO: move to context.
+ const auto& members = GetLiteralStructIndexes(root, membersMap);
+ return ctx.Builder(map.Pos())
+ .Callable("WideMap")
+ .Add(0, map.HeadPtr())
+ .Lambda(1)
+ .Params("fields", map.Tail().Head().ChildrenSize())
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : inStructType->GetItems()) {
+ parent.ApplyPartial(i++, map.Tail().HeadPtr(), root.Child(members.find(item->GetName())->second)->TailPtr())
+ .With("fields")
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+ } else {
+ auto apply = ApplyNarrowMap(map.Tail(), ctx);
+ TExprNode::TListType body;
+ body.reserve(inStructType->GetSize());
+ const auto pos = map.Tail().Pos();
+ const auto& items = inStructType->GetItems();
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(body),
+ [&](const TItemExprType* item) { return ctx.NewCallable(pos, "Member", {apply.back(), ctx.NewAtom(pos, item->GetName())}); });
+ auto lambda = ctx.NewLambda(pos, std::move(apply.front()), std::move(body));
+
+ return ctx.Builder(map.Pos())
+ .Callable("WideMap")
+ .Add(0, map.HeadPtr())
+ .Add(1, std::move(lambda))
+ .Seal().Build();
+ }
+}
+
+void FlattenLambdaBody(TExprNode::TPtr& lambda, const TTupleExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx) {
+ TExprNode::TListType flatten;
+ flatten.reserve(lambda->Head().ChildrenSize() + newWidth - oldWidth);
+ for (ui32 i = 0U; i < oldWidth; ++i) {
+ const auto child = lambda->Child(i + 1U);
+ if (const auto expand = expandMap.size() > i ? expandMap[i] : std::nullopt) {
+ for (ui32 j = 0U; j < *expand; ++j)
+ flatten.emplace_back(child->IsList() ? child->ChildPtr(j) : ctx.NewCallable(child->Pos(), "Nth",
+ {lambda->ChildPtr(i + 1U), ctx.NewAtom(child->Pos(), ToString(j), TNodeFlags::Default)}
+ ));
+ } else {
+ flatten.emplace_back(lambda->ChildPtr(i + 1U));
+ }
+ }
+
+ lambda = ctx.DeepCopyLambda(*lambda, std::move(flatten));
+}
+
+void FlattenLambdaBody(TExprNode::TPtr& lambda, const TStructExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TLieralStructsCacheMap& membersMap, TExprContext& ctx) {
+ TExprNode::TListType flatten;
+ flatten.reserve(lambda->Head().ChildrenSize() + newWidth - oldWidth);
+ for (ui32 i = 0U; i < oldWidth; ++i) {
+ if (const auto expand = expandMap.size() > i ? expandMap[i] : std::nullopt) {
+ if (const auto child = lambda->Child(i + 1U); child->IsCallable("AsStruct")) {
+ const auto& members = GetLiteralStructIndexes(*child, membersMap);
+ for (const auto& member : *expand)
+ flatten.emplace_back(child->Child(members.find(member)->second)->TailPtr());
+ } else {
+ for (const auto& member : *expand)
+ flatten.emplace_back(ctx.NewCallable(child->Pos(), "Member", {lambda->ChildPtr(i + 1U), ctx.NewAtom(child->Pos(), member)}));
+ }
+ } else {
+ flatten.emplace_back(lambda->ChildPtr(i + 1U));
+ }
+ }
+
+ lambda = ctx.DeepCopyLambda(*lambda, std::move(flatten));
+}
+
+void FlattenLambdaArgs(TExprNode::TPtr& lambda, const TTupleExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx, ui32 skip = 0U) {
+ const auto inputWidth = lambda->Head().ChildrenSize() + newWidth - oldWidth;
+ lambda = ctx.Builder(lambda->Pos())
+ .Lambda()
+ .Params("items", inputWidth)
+ .Apply(*lambda)
+ .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
+ for (ui32 i = 0U, k = 0U; i < lambda->Head().ChildrenSize(); ++i) {
+ if (const auto expand = i >= skip && expandMap.size() + skip > i ? expandMap[i - skip] : std::nullopt) {
+ parent.With(i).List().Do([&](TExprNodeBuilder& list) -> TExprNodeBuilder& {
+ for (ui32 j = 0U; j < *expand; ++j) {
+ list.Arg(j, "items", k++);
+ }
+ return list;
+ }).Seal().Done();
+ } else {
+ parent.With(i, "items", k++);
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+}
+
+void FlattenLambdaArgs(TExprNode::TPtr& lambda, const TStructExpandMap& expandMap, ui32 oldWidth, ui32 newWidth, TExprContext& ctx, ui32 skip = 0U) {
+ const auto inputWidth = lambda->Head().ChildrenSize() + newWidth - oldWidth;
+ lambda = ctx.Builder(lambda->Pos())
+ .Lambda()
+ .Params("items", inputWidth)
+ .Apply(*lambda)
+ .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
+ for (ui32 i = 0U, k = 0U; i < lambda->Head().ChildrenSize(); ++i) {
+ if (const auto expand = i >= skip && expandMap.size() + skip > i ? expandMap[i - skip] : std::nullopt) {
+ parent.With(i).Callable("AsStruct").Do([&](TExprNodeBuilder& list) -> TExprNodeBuilder& {
+ ui32 j = 0U;
+ for (const auto& field : *expand) {
+ list.List(j++)
+ .Atom(0, field)
+ .Arg(1, "items", k++)
+ .Seal();
+ }
+ return list;
+ }).Seal().Done();
+ } else {
+ parent.With(i, "items", k++);
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+}
+
+using TDedupMap = std::vector<std::pair<ui32, ui32>>;
+TDedupMap DedupState(const TExprNode& init, const TExprNode& update) {
+ YQL_ENSURE(init.ChildrenSize() == update.ChildrenSize(), "Must be same size.");
+ const auto skip = init.Head().ChildrenSize();
+ YQL_ENSURE(update.Head().ChildrenSize() + 1U == init.ChildrenSize() + skip, "Wrong update args count.");
+
+ TNodeMap<ui32> map;
+ map.reserve(update.Head().ChildrenSize());
+
+ std::vector<ui32> pos;
+ pos.reserve(init.ChildrenSize() - 1U);
+
+ for (ui32 i = 1U; i < init.ChildrenSize(); ++i)
+ pos.emplace_back(map.emplace(init.Child(i), i - 1U).first->second);
+
+ map.clear();
+ ui32 i = 0U;
+ update.Head().ForEachChild([&](const TExprNode& arg) { map.emplace(&arg, i < skip ? i++ : skip + pos[i++ - skip]); });
+
+ TDedupMap dedups;
+ for (ui32 j = 1U; j <= pos.size(); ++j) {
+ if (const auto i = pos[j - 1U] + 1U; i < j) {
+ if (const auto one = update.Child(i), two = update.Child(j); one != two && CompareExprTreeParts(*one, *two, map)) {
+ dedups.emplace_back(i - 1U, j - 1U);
+ }
+ }
+ }
+
+ return dedups;
+}
+
+TExprNode::TPtr DedupLambdaBody(const TExprNode& lambda, const TDedupMap& dedups, TExprContext& ctx) {
+ auto state = GetLambdaBody(lambda);
+ std::for_each(dedups.cbegin(), dedups.cend(), [&](const std::pair<ui32, ui32>& pair) { state[pair.second] = state[pair.first]; });
+ return ctx.DeepCopyLambda(lambda, std::move(state));
+}
+
+std::vector<ui32> UnusedState(const TExprNode& init, const TExprNode& update, const TExprNode& finish) {
+ YQL_ENSURE(init.ChildrenSize() == update.ChildrenSize(), "Must be same size.");
+
+ const auto size = init.ChildrenSize() - 1U;
+ const auto skipU = update.Head().ChildrenSize() - size;
+ const auto skipF = finish.Head().ChildrenSize() - size;
+
+ std::vector<ui32> unused;
+ unused.reserve(size);
+ for (ui32 j = 0U; j < size; ++j) {
+ if (update.Head().Child(j + skipU)->Unique() && finish.Head().Child(j + skipF)->Unique()) {
+ unused.emplace_back(j);
+ }
+ }
+
+ return unused;
+}
+
+TExprNode::TListType&& DropUnused(TExprNode::TListType&& list, const std::vector<ui32>& unused, ui32 skip = 0U) {
+ std::for_each(unused.cbegin(), unused.cend(), [&](const ui32 index) { list[index + skip] = TExprNode::TPtr(); });
+ list.erase(std::remove_if(list.begin(), list.end(), std::logical_not<TExprNode::TPtr>()), list.cend());
+ return std::move(list);
+}
+
+TExprNode::TPtr OptimizeWideCombiner(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto originalKeySize = node->Child(2U)->ChildrenSize() - 1U;
+ TTupleExpandMap tupleExpandMap(originalKeySize);
+ TStructExpandMap structExpandMap(originalKeySize);
+
+ const auto needKeyFlatten = GetExpandMapsForLambda<false>(*node->Child(2U), tupleExpandMap, structExpandMap);
+
+ if (needKeyFlatten.front()) {
+ const auto flattenSize = *needKeyFlatten.front();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by tuple for " << node->Content() << " from " << originalKeySize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ FlattenLambdaBody(children[2U], tupleExpandMap, originalKeySize, flattenSize, ctx);
+ FlattenLambdaArgs(children[3U], tupleExpandMap, originalKeySize, flattenSize, ctx);
+ FlattenLambdaArgs(children[4U], tupleExpandMap, originalKeySize, flattenSize, ctx);
+ FlattenLambdaArgs(children[5U], tupleExpandMap, originalKeySize, flattenSize, ctx);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (needKeyFlatten.back()) {
+ const auto flattenSize = *needKeyFlatten.back();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by struct for " << node->Content() << " from " << originalKeySize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ TLieralStructsCacheMap membersMap;
+ FlattenLambdaBody(children[2U], structExpandMap, originalKeySize, flattenSize, membersMap, ctx);
+ FlattenLambdaArgs(children[3U], structExpandMap, originalKeySize, flattenSize, ctx);
+ FlattenLambdaArgs(children[4U], structExpandMap, originalKeySize, flattenSize, ctx);
+ FlattenLambdaArgs(children[5U], structExpandMap, originalKeySize, flattenSize, ctx);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ tupleExpandMap.clear();
+ structExpandMap.clear();
+ const auto originalStateSize = node->Child(3U)->ChildrenSize() - 1U;
+ tupleExpandMap.resize(originalStateSize);
+ structExpandMap.resize(originalStateSize);
+
+ const auto needStateFlatten = GetExpandMapsForLambda<true>(*node->Child(3U), tupleExpandMap, structExpandMap);
+
+ if (needStateFlatten.front()) {
+ const auto flattenSize = *needStateFlatten.front();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten state by tuple for " << node->Content() << " from " << originalStateSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ FlattenLambdaBody(children[3U], tupleExpandMap, originalStateSize, flattenSize, ctx);
+ FlattenLambdaBody(children[4U], tupleExpandMap, originalStateSize, flattenSize, ctx);
+ FlattenLambdaArgs(children[4U], tupleExpandMap, originalStateSize, flattenSize, ctx, node->Child(3U)->Head().ChildrenSize());
+ FlattenLambdaArgs(children[5U], tupleExpandMap, originalStateSize, flattenSize, ctx, node->Child(2U)->ChildrenSize() - 1U);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (needStateFlatten.back()) {
+ const auto flattenSize = *needStateFlatten.back();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten state by struct for " << node->Content() << " from " << originalStateSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ TLieralStructsCacheMap membersMap;
+ FlattenLambdaBody(children[3U], structExpandMap, originalStateSize, flattenSize, membersMap, ctx);
+ FlattenLambdaBody(children[4U], structExpandMap, originalStateSize, flattenSize, membersMap, ctx);
+ FlattenLambdaArgs(children[4U], structExpandMap, originalStateSize, flattenSize, ctx, node->Child(3U)->Head().ChildrenSize());
+ FlattenLambdaArgs(children[5U], structExpandMap, originalStateSize, flattenSize, ctx, node->Child(2U)->ChildrenSize() - 1U);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (const auto dedups = DedupState(*node->Child(3), *node->Child(4)); !dedups.empty()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->Content() << ' ' << dedups.size() << " states.";
+
+ auto children = node->ChildrenList();
+ children[4U] = DedupLambdaBody(*children[4U], dedups, ctx);
+
+ const auto& finish = node->Tail();
+ const auto size = finish.Head().ChildrenSize();
+ const auto skip = children[2U]->ChildrenSize() - 1U;
+
+ std::vector<ui32> map(size);
+ std::iota(map.begin(), map.end(), 0U);
+ std::for_each(dedups.cbegin(), dedups.cend(), [&](const std::pair<ui32, ui32>& it){ map[it.second + skip] = it.first + skip; } );
+
+ children.back() = ctx.Builder(finish.Pos())
+ .Lambda()
+ .Params("out", finish.Head().ChildrenSize())
+ .Apply(finish)
+ .Do([&](TExprNodeReplaceBuilder& inner) -> TExprNodeReplaceBuilder& {
+ for (ui32 j = 0U; j < finish.Head().ChildrenSize(); ++j) {
+ inner.With(j, "out", map[j]);
+ }
+ return inner;
+ })
+ .Seal()
+ .Seal().Build();
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (const auto unused = UnusedState(*node->Child(3), *node->Child(4), node->Tail()); !unused.empty()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Unused " << node->Content() << ' ' << unused.size() << " states.";
+
+ auto children = node->ChildrenList();
+ const auto size = children[3]->ChildrenSize() - 1U;
+ children[3] = ctx.DeepCopyLambda(*children[3], DropUnused(GetLambdaBody(*children[3]), unused));
+ children[4] = ctx.DeepCopyLambda(*children[4], DropUnused(GetLambdaBody(*children[4]), unused));
+ children[4] = ctx.ChangeChild(*children[4], 0U, ctx.NewArguments(children[4]->Head().Pos(), DropUnused(children[4]->Head().ChildrenList(), unused, children[4]->Head().ChildrenSize() - size)));
+ children[5] = ctx.ChangeChild(*children[5], 0U, ctx.NewArguments(children[5]->Head().Pos(), DropUnused(children[5]->Head().ChildrenList(), unused, children[5]->Head().ChildrenSize() - size)));
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeWideCondense1(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto originalSize = node->Tail().ChildrenSize() - 1U;
+ TTupleExpandMap tupleExpandMap(originalSize);
+ TStructExpandMap structExpandMap(originalSize);
+
+ const auto inputWidth = node->Child(1U)->Head().ChildrenSize();
+ const auto needFlatten = GetExpandMapsForLambda<true>(node->Tail(), tupleExpandMap, structExpandMap);
+
+ if (needFlatten.front()) {
+ const auto flattenSize = *needFlatten.front();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten " << node->Content() << " tuple outputs from " << originalSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ FlattenLambdaBody(children[1U], tupleExpandMap, originalSize, flattenSize, ctx);
+ FlattenLambdaBody(children[3U], tupleExpandMap, originalSize, flattenSize, ctx);
+ FlattenLambdaArgs(children[2U], tupleExpandMap, originalSize, flattenSize, ctx, inputWidth);
+ FlattenLambdaArgs(children[3U], tupleExpandMap, originalSize, flattenSize, ctx, inputWidth);
+
+ auto mapper = MakeEmptyWideLambda(node->Pos(), originalSize, ctx);
+ FlattenLambdaArgs(mapper, tupleExpandMap, originalSize, flattenSize, ctx);
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, ctx.ChangeChildren(*node, std::move(children)))
+ .Add(1, std::move(mapper))
+ .Seal().Build();
+ }
+
+ if (needFlatten.back()) {
+ const auto flattenSize = *needFlatten.back();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten " << node->Content() << " struct outputs from " << originalSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ TLieralStructsCacheMap membersMap;
+ FlattenLambdaBody(children[1U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
+ FlattenLambdaBody(children[3U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
+ FlattenLambdaArgs(children[2U], structExpandMap, originalSize, flattenSize, ctx, inputWidth);
+ FlattenLambdaArgs(children[3U], structExpandMap, originalSize, flattenSize, ctx, inputWidth);
+
+ auto mapper = MakeEmptyWideLambda(node->Pos(), originalSize, ctx);
+ FlattenLambdaArgs(mapper, structExpandMap, originalSize, flattenSize, ctx);
+ return ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, ctx.ChangeChildren(*node, std::move(children)))
+ .Add(1, std::move(mapper))
+ .Seal().Build();
+ }
+
+ if (const auto dedups = DedupState(*node->Child(1), node->Tail()); !dedups.empty()) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Dedup " << node->Content() << ' ' << dedups.size() << " states.";
+ return ctx.ChangeChild(*node, 3, DedupLambdaBody(node->Tail(), dedups, ctx));
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeWideChopper(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto originalSize = node->Child(1U)->ChildrenSize() - 1U;
+ TTupleExpandMap tupleExpandMap(originalSize);
+ TStructExpandMap structExpandMap(originalSize);
+
+ const auto needFlatten = GetExpandMapsForLambda<false>(*node->Child(1U), tupleExpandMap, structExpandMap);
+
+ if (needFlatten.front()) {
+ const auto flattenSize = *needFlatten.front();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by tuple for " << node->Content() << " from " << originalSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ FlattenLambdaBody(children[1U], tupleExpandMap, originalSize, flattenSize, ctx);
+ FlattenLambdaArgs(children[2U], tupleExpandMap, originalSize, flattenSize, ctx);
+ FlattenLambdaArgs(children[3U], tupleExpandMap, originalSize, flattenSize, ctx);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ if (needFlatten.back()) {
+ const auto flattenSize = *needFlatten.back();
+ YQL_CLOG(DEBUG, CorePeepHole) << "Flatten key by struct for " << node->Content() << " from " << originalSize << " to " << flattenSize;
+ auto children = node->ChildrenList();
+
+ TLieralStructsCacheMap membersMap;
+ FlattenLambdaBody(children[1U], structExpandMap, originalSize, flattenSize, membersMap, ctx);
+ FlattenLambdaArgs(children[2U], structExpandMap, originalSize, flattenSize, ctx);
+ FlattenLambdaArgs(children[3U], structExpandMap, originalSize, flattenSize, ctx);
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeWideMaps(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable("ExpandMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+ auto lambda = ctx.FuseLambdas(node->Tail(), input.Tail());
+ return ctx.NewCallable(node->Pos(),
+ node->Content().starts_with("Narrow") ? TString("Ordered") += node->Content().substr(6U, 16U) : input.Content(),
+ {input.HeadPtr(), std::move(lambda)});
+ } else if (input.IsCallable("WideMap") && !node->IsCallable("NarrowFlatMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+ auto lambda = ctx.FuseLambdas(node->Tail(), input.Tail());
+ return ctx.ChangeChildren(*node, {input.HeadPtr(), std::move(lambda)});
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeNarrowFlatMap(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto& lambda = node->Tail();
+ const auto& body = lambda.Tail();
+
+ if (body.IsCallable("If") && 1U == body.Tail().ChildrenSize() && body.Tail().IsCallable({"List", "Nothing"})) {
+ const auto width = lambda.Head().ChildrenSize();
+ if (auto shared = FindSharedNode(body.ChildPtr(1), body.HeadPtr(),
+ [&lambda] (const TExprNode::TPtr& node) {
+ if (!node->IsCallable())
+ return false;
+
+ if (node->GetTypeAnn() && node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
+ return false;
+ }
+
+ return node->GetDependencyScope()->second == &lambda;
+ }); shared.first && shared.second) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Extract " << shared.first->Content() << " from " << node->Content() << " with " << body.Content();
+
+ auto argNodes = lambda.Head().ChildrenList();
+ argNodes.emplace_back(ctx.NewArgument(lambda.Head().Pos(), TString("extracted") += ToString(argNodes.size())));
+
+ auto args = ctx.NewArguments(lambda.Head().Pos(), std::move(argNodes));
+ auto body = ctx.ReplaceNode(lambda.TailPtr(), *shared.first, args->TailPtr());
+
+ auto children = node->ChildrenList();
+ children.back() = ctx.NewLambda(lambda.Pos(), std::move(args), std::move(body));
+ children.front() = ctx.Builder(node->Pos())
+ .Callable("WideMap")
+ .Add(0, std::move(children.front()))
+ .Lambda(1)
+ .Params("items", width)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < width; ++i) {
+ parent.Arg(i, "items", i);
+ }
+ return parent;
+ })
+ .ApplyPartial(width, lambda.HeadPtr(), std::move(shared.first))
+ .With("items")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
+ return ctx.ChangeChildren(*node, std::move(children));
+ } else if (!shared.first) {
+ YQL_CLOG(DEBUG, CorePeepHole) << node->Content() << " with " << body.Content() << " to WideFilter";
+ const bool just = 2U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable("List")
+ || 1U == body.Child(1)->ChildrenSize() && body.Child(1)->IsCallable({"AsList", "Just"});
+ return ctx.Builder(node->Pos())
+ .Callable(just ? "NarrowMap" : "NarrowFlatMap")
+ .Callable(0, "WideFilter")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Params("items", width)
+ .ApplyPartial(lambda.HeadPtr(), body.HeadPtr()).With("items").Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("items", width)
+ .ApplyPartial(lambda.HeadPtr(), just ? body.Child(1)->TailPtr() : body.ChildPtr(1)).With("items").Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+
+ return OptimizeWideMaps(node, ctx);
+}
+
+TExprNode::TPtr OptimizeSqueezeToDict(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable("NarrowMap")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Fuse " << node->Content() << " with " << input.Content();
+ return ctx.NewCallable(node->Pos(), "NarrowSqueezeToDict", {
+ input.HeadPtr(),
+ ctx.FuseLambdas(*node->Child(1U), input.Tail()),
+ ctx.FuseLambdas(*node->Child(2U), input.Tail()),
+ node->TailPtr()
+ });
+ }
+ return node;
+}
+
+TExprNode::TListType GetOptionals(const TPositionHandle& pos, const TStructExprType& type, TExprContext& ctx) {
+ TExprNode::TListType result;
+ for (const auto& item : type.GetItems())
+ if (ETypeAnnotationKind::Optional == item->GetItemType()->GetKind())
+ result.emplace_back(ctx.NewAtom(pos, item->GetName()));
+ return result;
+}
+
+TExprNode::TListType GetOptionals(const TPositionHandle& pos, const TTupleExprType& type, TExprContext& ctx) {
+ TExprNode::TListType result;
+ if (const auto& items = type.GetItems(); !items.empty())
+ for (ui32 i = 0U; i < items.size(); ++i)
+ if (ETypeAnnotationKind::Optional == items[i]->GetKind())
+ result.emplace_back(ctx.NewAtom(pos, ToString(i), TNodeFlags::Default));
+ return result;
+}
+
+template <bool EnableNewOptimizers, bool TupleOrStruct>
+TExprNode::TPtr ExpandSkipNullFields(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if constexpr (EnableNewOptimizers) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
+ if (auto fields = node->ChildrenSize() > 1U ? node->Tail().ChildrenList() :
+ GetOptionals(node->Pos(), *GetSeqItemType(node->Head().GetTypeAnn())->Cast<std::conditional_t<TupleOrStruct, TTupleExprType, TStructExprType>>(), ctx);
+ fields.empty()) {
+ return node->HeadPtr();
+ } else {
+ return ctx.Builder(node->Pos())
+ .Callable("OrderedFilter")
+ .Add(0, node->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Callable("And")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0U; i < fields.size(); ++i) {
+ parent
+ .Callable(i, "Exists")
+ .Callable(0, TupleOrStruct ? "Nth" : "Member")
+ .Arg(0, "item")
+ .Add(1, std::move(fields[i]))
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+ }
+ return node;
+}
+
TExprNode::TPtr ExpandConstraintsOf(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << node->Content();
- TString json;
- TStringOutput out(json);
- NJson::TJsonWriter jsonWriter(&out, true);
- node->Head().GetConstraintSet().ToJson(jsonWriter);
- jsonWriter.Flush();
+ TString json;
+ TStringOutput out(json);
+ NJson::TJsonWriter jsonWriter(&out, true);
+ node->Head().GetConstraintSet().ToJson(jsonWriter);
+ jsonWriter.Flush();
return ctx.Builder(node->Pos())
- .Callable("Json")
- .Atom(0, json, TNodeFlags::MultilineContent)
+ .Callable("Json")
+ .Atom(0, json, TNodeFlags::MultilineContent)
.Seal()
.Build();
}
-TExprNode::TPtr OptimizeMapJoinCore(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable("NarrowMap") && input.Tail().Tail().IsCallable("AsStruct")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
- auto map = NarrowToWide(input, ctx);
- const auto outStructType = GetSeqItemType(node->GetTypeAnn())->Cast<TStructExprType>();
- return ctx.Builder(input.Pos())
- .Callable(input.Content())
- .Add(0, MakeWideMapJoinCore<TStructExprType>(*node, std::move(map), ctx))
- .Lambda(1)
- .Params("fields", outStructType->GetSize())
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : outStructType->GetItems()) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
-TExprNode::TPtr OptimizeCommonJoinCore(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (const auto& input = node->Head(); input.IsCallable("NarrowMap") && input.Tail().Tail().IsCallable("AsStruct")) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
- auto map = NarrowToWide(input, ctx);
- auto wide = MakeWideCommonJoinCore<TStructExprType>(*node, std::move(map), ctx);
- return ctx.Builder(input.Pos())
- .Callable(input.Content())
- .Add(0, std::move(wide.first))
- .Lambda(1)
- .Params("fields", wide.second.size())
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (auto& item : wide.second) {
- parent.List(i)
- .Add(0, std::move(item))
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build();
- }
-
- return node;
-}
-
+TExprNode::TPtr OptimizeMapJoinCore(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable("NarrowMap") && input.Tail().Tail().IsCallable("AsStruct")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+ auto map = NarrowToWide(input, ctx);
+ const auto outStructType = GetSeqItemType(node->GetTypeAnn())->Cast<TStructExprType>();
+ return ctx.Builder(input.Pos())
+ .Callable(input.Content())
+ .Add(0, MakeWideMapJoinCore<TStructExprType>(*node, std::move(map), ctx))
+ .Lambda(1)
+ .Params("fields", outStructType->GetSize())
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : outStructType->GetItems()) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
+TExprNode::TPtr OptimizeCommonJoinCore(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (const auto& input = node->Head(); input.IsCallable("NarrowMap") && input.Tail().Tail().IsCallable("AsStruct")) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Swap " << node->Content() << " with " << input.Content();
+ auto map = NarrowToWide(input, ctx);
+ auto wide = MakeWideCommonJoinCore<TStructExprType>(*node, std::move(map), ctx);
+ return ctx.Builder(input.Pos())
+ .Callable(input.Content())
+ .Add(0, std::move(wide.first))
+ .Lambda(1)
+ .Params("fields", wide.second.size())
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (auto& item : wide.second) {
+ parent.List(i)
+ .Add(0, std::move(item))
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ }
+
+ return node;
+}
+
TExprNode::TPtr DoBuildTablePath(const TExprNode::TPtr& node, TExprContext& ctx) {
YQL_ENSURE(node->Head().IsCallable("String"),
"BuildTablePath: expecting string literal as first argument, got: " << node->Head().Content());
@@ -4522,187 +4522,187 @@ TExprNode::TPtr DoBuildTablePath(const TExprNode::TPtr& node, TExprContext& ctx)
.Build();
}
-template <bool Equality>
-TExprNode::TPtr ReduceBothArgs(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with both Optionals.";
- return ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), node.Tail().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()) ?
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("lhs")
- .Callable("IfPresent")
- .Add(0, node.TailPtr())
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Add(2, MakeBoolNothing(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(2, MakeBoolNothing(node.Pos(), ctx))
- .Seal()
- .Build():
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("lhs")
- .Callable("IfPresent")
- .Add(0, node.TailPtr())
- .Lambda(1)
- .Param("rhs")
- .Callable("Just")
- .Callable(0, node.Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Seal()
- .Add(2, MakeBoolNothing(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(2, MakeBoolNothing(node.Pos(), ctx))
- .Seal()
- .Build();
-}
-
-template <bool Equality, bool Equals, bool IsDistinct>
-TExprNode::TPtr ReduceLeftArg(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with left Optional.";
- auto stub = IsDistinct ? ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.TailPtr()})) : MakeBoolNothing(node.Pos(), ctx);
- return IsDistinct || ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), node.Tail().GetTypeAnn()) ?
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("lhs")
- .Callable(node.Content())
- .Arg(0, "lhs")
- .Add(1, node.TailPtr())
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal()
- .Build():
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("lhs")
- .Callable("Just")
- .Callable(0, node.Content())
- .Arg(0, "lhs")
- .Add(1, node.TailPtr())
- .Seal()
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal()
- .Build();
-}
-
-template <bool Equality, bool Equals, bool IsDistinct>
-TExprNode::TPtr ReduceRightArg(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with right Optional.";
- auto stub = IsDistinct ? ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.HeadPtr()})) : MakeBoolNothing(node.Pos(), ctx);
- return IsDistinct || ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn(), node.Tail().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()) ?
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.TailPtr())
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Add(0, node.HeadPtr())
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal()
- .Build():
- ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.TailPtr())
- .Lambda(1)
- .Param("rhs")
- .Callable("Just")
- .Callable(0, node.Content())
- .Add(0, node.HeadPtr())
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal()
- .Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrEqualOpt(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with optional args.";
- auto stub = ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.TailPtr()}));
- return ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, node.HeadPtr())
- .Lambda(1)
- .Param("lhs")
- .Callable("IfPresent")
- .Add(0, node.TailPtr())
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Add(2, MakeBool<!Equals>(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal().Build();
-}
-
-template <bool Asc, bool Equals>
-TExprNode::TPtr AggrCompareOpt(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with optional args.";
- constexpr bool order = Asc == Equals;
- return ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Add(0, order ? node.HeadPtr() : node.TailPtr())
- .Lambda(1)
- .Param(order ? "lhs" : "rhs")
- .Callable("IfPresent")
- .Add(0, order ? node.TailPtr() : node.HeadPtr())
- .Lambda(1)
- .Param(order ? "rhs" : "lhs")
- .Callable(node.Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Add(2, MakeBool<!Equals>(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(2, MakeBool<Equals>(node.Pos(), ctx))
- .Seal().Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr SqlEqualTuples(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
-
- const auto lSize = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- const auto rSize = node.Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+template <bool Equality>
+TExprNode::TPtr ReduceBothArgs(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with both Optionals.";
+ return ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), node.Tail().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()) ?
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Add(0, node.TailPtr())
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, MakeBoolNothing(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(2, MakeBoolNothing(node.Pos(), ctx))
+ .Seal()
+ .Build():
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Add(0, node.TailPtr())
+ .Lambda(1)
+ .Param("rhs")
+ .Callable("Just")
+ .Callable(0, node.Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, MakeBoolNothing(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(2, MakeBoolNothing(node.Pos(), ctx))
+ .Seal()
+ .Build();
+}
+
+template <bool Equality, bool Equals, bool IsDistinct>
+TExprNode::TPtr ReduceLeftArg(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with left Optional.";
+ auto stub = IsDistinct ? ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.TailPtr()})) : MakeBoolNothing(node.Pos(), ctx);
+ return IsDistinct || ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType(), node.Tail().GetTypeAnn()) ?
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("lhs")
+ .Callable(node.Content())
+ .Arg(0, "lhs")
+ .Add(1, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal()
+ .Build():
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("lhs")
+ .Callable("Just")
+ .Callable(0, node.Content())
+ .Arg(0, "lhs")
+ .Add(1, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal()
+ .Build();
+}
+
+template <bool Equality, bool Equals, bool IsDistinct>
+TExprNode::TPtr ReduceRightArg(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with right Optional.";
+ auto stub = IsDistinct ? ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.HeadPtr()})) : MakeBoolNothing(node.Pos(), ctx);
+ return IsDistinct || ECompareOptions::Optional == CanCompare<Equality>(node.Head().GetTypeAnn(), node.Tail().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType()) ?
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.TailPtr())
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Add(0, node.HeadPtr())
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal()
+ .Build():
+ ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.TailPtr())
+ .Lambda(1)
+ .Param("rhs")
+ .Callable("Just")
+ .Callable(0, node.Content())
+ .Add(0, node.HeadPtr())
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal()
+ .Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrEqualOpt(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with optional args.";
+ auto stub = ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node.Pos(), "Exists", {node.TailPtr()}));
+ return ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, node.HeadPtr())
+ .Lambda(1)
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Add(0, node.TailPtr())
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, MakeBool<!Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal().Build();
+}
+
+template <bool Asc, bool Equals>
+TExprNode::TPtr AggrCompareOpt(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' with optional args.";
+ constexpr bool order = Asc == Equals;
+ return ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Add(0, order ? node.HeadPtr() : node.TailPtr())
+ .Lambda(1)
+ .Param(order ? "lhs" : "rhs")
+ .Callable("IfPresent")
+ .Add(0, order ? node.TailPtr() : node.HeadPtr())
+ .Lambda(1)
+ .Param(order ? "rhs" : "lhs")
+ .Callable(node.Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, MakeBool<!Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(2, MakeBool<Equals>(node.Pos(), ctx))
+ .Seal().Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr SqlEqualTuples(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
+
+ const auto lSize = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ const auto rSize = node.Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
const auto size = std::max(lSize, rSize);
-
- TExprNode::TListType compares;
+
+ TExprNode::TListType compares;
compares.reserve(size);
-
+
TExprNode::TPtr nullNode = MakeNull(node.Pos(), ctx);
- for (ui32 i = 0U; i < size; ++i) {
+ for (ui32 i = 0U; i < size; ++i) {
TExprNode::TPtr left = (i >= lSize) ? nullNode : ctx.Builder(node.Pos())
.Callable("Nth")
.Add(0, node.HeadPtr())
@@ -4717,181 +4717,181 @@ TExprNode::TPtr SqlEqualTuples(const TExprNode& node, TExprContext& ctx) {
.Seal()
.Build();
- compares.emplace_back(ctx.Builder(node.Pos())
- .Callable(node.Content())
+ compares.emplace_back(ctx.Builder(node.Pos())
+ .Callable(node.Content())
.Add(0, left)
.Add(1, right)
- .Seal()
- .Build());
- }
-
+ .Seal()
+ .Build());
+ }
+
if (compares.empty()) {
- return MakeBool<Equals>(node.Pos(), ctx);
- }
-
- return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrEqualTuples(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
-
- const auto size = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- if (!size)
- return MakeBool<Equals>(node.Pos(), ctx);
-
- TExprNode::TListType compares;
- compares.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- compares.emplace_back(ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(i), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Build());
- }
-
- return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
-}
-
-TExprNode::TPtr SqlCompareTuplesImpl(ui32 index, ui32 min, ui32 max, const TExprNode& node, TExprContext& ctx) {
- if (const auto next = index + 1U; next < min) {
- return ctx.Builder(node.Pos())
- .Callable("If")
- .Callable(0, "Coalesce")
- .Callable(0, "==")
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, MakeBool<false>(node.Pos(), ctx))
- .Seal()
- .Add(1, SqlCompareTuplesImpl(next, min, max, node, ctx))
- .Callable(2, node.Content().SubString(0U, 1U))
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Build();
- } else if (next < max) {
- return ctx.Builder(node.Pos())
- .Callable("Or")
- .Callable(0, node.Content().SubString(0U, 1U))
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, MakeBoolNothing(node.Pos(), ctx))
- .Seal()
- .Build();
- } else {
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Build();
- }
-}
-
-TExprNode::TPtr SqlCompareTuples(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
- const auto lSize = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- const auto rSize = node.Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
- const auto sizes = std::minmax(lSize, rSize);
- return SqlCompareTuplesImpl(0U, sizes.first, sizes.second, node, ctx);
-}
-
-template<bool Asc>
-TExprNode::TPtr AggrCompareTuplesImpl(ui32 index, ui32 count, const TExprNode& node, TExprContext& ctx) {
- if (const auto next = index + 1U; next < count) {
- return ctx.Builder(node.Pos())
- .Callable("If")
- .Callable(0, "AggrEquals")
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, AggrCompareTuplesImpl<Asc>(next, count, node, ctx))
- .Callable(2, Asc ? "AggrLess" : "AggrGreater")
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Build();
- } else {
- return ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Add(0, node.HeadPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Add(0, node.TailPtr())
- .Atom(1, ToString(index), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Build();
- }
-}
-
-template<bool Asc>
-TExprNode::TPtr AggrCompareTuples(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
- return AggrCompareTuplesImpl<Asc>(0U, node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize(), node, ctx);
-}
-
-template <bool Equals>
-TExprNode::TPtr SqlEqualStructs(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Structs.";
-
- const auto lType = node.Head().GetTypeAnn()->Cast<TStructExprType>();
- const auto rType = node.Tail().GetTypeAnn()->Cast<TStructExprType>();
-
- TExprNode::TListType compares;
- compares.reserve(std::max(lType->GetSize(), rType->GetSize()));
-
+ return MakeBool<Equals>(node.Pos(), ctx);
+ }
+
+ return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrEqualTuples(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
+
+ const auto size = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ if (!size)
+ return MakeBool<Equals>(node.Pos(), ctx);
+
+ TExprNode::TListType compares;
+ compares.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ compares.emplace_back(ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Build());
+ }
+
+ return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
+}
+
+TExprNode::TPtr SqlCompareTuplesImpl(ui32 index, ui32 min, ui32 max, const TExprNode& node, TExprContext& ctx) {
+ if (const auto next = index + 1U; next < min) {
+ return ctx.Builder(node.Pos())
+ .Callable("If")
+ .Callable(0, "Coalesce")
+ .Callable(0, "==")
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, MakeBool<false>(node.Pos(), ctx))
+ .Seal()
+ .Add(1, SqlCompareTuplesImpl(next, min, max, node, ctx))
+ .Callable(2, node.Content().SubString(0U, 1U))
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ } else if (next < max) {
+ return ctx.Builder(node.Pos())
+ .Callable("Or")
+ .Callable(0, node.Content().SubString(0U, 1U))
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, MakeBoolNothing(node.Pos(), ctx))
+ .Seal()
+ .Build();
+ } else {
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Build();
+ }
+}
+
+TExprNode::TPtr SqlCompareTuples(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
+ const auto lSize = node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ const auto rSize = node.Tail().GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ const auto sizes = std::minmax(lSize, rSize);
+ return SqlCompareTuplesImpl(0U, sizes.first, sizes.second, node, ctx);
+}
+
+template<bool Asc>
+TExprNode::TPtr AggrCompareTuplesImpl(ui32 index, ui32 count, const TExprNode& node, TExprContext& ctx) {
+ if (const auto next = index + 1U; next < count) {
+ return ctx.Builder(node.Pos())
+ .Callable("If")
+ .Callable(0, "AggrEquals")
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, AggrCompareTuplesImpl<Asc>(next, count, node, ctx))
+ .Callable(2, Asc ? "AggrLess" : "AggrGreater")
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ } else {
+ return ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Add(0, node.HeadPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Add(0, node.TailPtr())
+ .Atom(1, ToString(index), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Build();
+ }
+}
+
+template<bool Asc>
+TExprNode::TPtr AggrCompareTuples(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Tuples.";
+ return AggrCompareTuplesImpl<Asc>(0U, node.Head().GetTypeAnn()->Cast<TTupleExprType>()->GetSize(), node, ctx);
+}
+
+template <bool Equals>
+TExprNode::TPtr SqlEqualStructs(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Structs.";
+
+ const auto lType = node.Head().GetTypeAnn()->Cast<TStructExprType>();
+ const auto rType = node.Tail().GetTypeAnn()->Cast<TStructExprType>();
+
+ TExprNode::TListType compares;
+ compares.reserve(std::max(lType->GetSize(), rType->GetSize()));
+
TExprNode::TPtr nullNode = MakeNull(node.Pos(), ctx);
- for (const auto& item : lType->GetItems()) {
+ for (const auto& item : lType->GetItems()) {
const auto& name = item->GetName();
TExprNode::TPtr right = !rType->FindItem(name) ? nullNode : ctx.Builder(node.Pos())
.Callable("Member")
@@ -4914,855 +4914,855 @@ TExprNode::TPtr SqlEqualStructs(const TExprNode& node, TExprContext& ctx) {
for (const auto& item : rType->GetItems()) {
const auto& name = item->GetName();
if (!lType->FindItem(name)) {
- compares.emplace_back(ctx.Builder(node.Pos())
- .Callable(node.Content())
+ compares.emplace_back(ctx.Builder(node.Pos())
+ .Callable(node.Content())
.Add(0, nullNode)
- .Callable(1, "Member")
- .Add(0, node.TailPtr())
- .Atom(1, name)
- .Seal()
- .Seal()
+ .Callable(1, "Member")
+ .Add(0, node.TailPtr())
+ .Atom(1, name)
+ .Seal()
+ .Seal()
.Build());
- }
- }
-
+ }
+ }
+
if (compares.empty()) {
- return MakeBool<Equals>(node.Pos(), ctx);
- }
-
- return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrEqualStructs(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Structs.";
-
- const auto type = node.Head().GetTypeAnn()->Cast<TStructExprType>();
- if (!type->GetSize())
- return MakeBool<Equals>(node.Pos(), ctx);
-
- TExprNode::TListType compares;
- compares.reserve(type->GetSize());
-
- for (const auto& item : type->GetItems()) {
- compares.emplace_back(ctx.Builder(node.Pos())
- .Callable(node.Content())
- .Callable(0, "Member")
- .Add(0, node.HeadPtr())
- .Atom(1, item->GetName())
- .Seal()
- .Callable(1, "Member")
- .Add(0, node.TailPtr())
- .Atom(1, item->GetName())
- .Seal()
- .Seal()
- .Build());
- }
-
- return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
-}
-
-template <bool Equals>
-TExprNode::TPtr MakeStopper(const TPositionHandle pos, TExprContext& ctx) {
- return Equals ?
- ctx.Builder(pos)
- .Lambda()
- .Param("result")
- .Callable("Coalesce")
- .Arg(0, "result")
- .Add(1, MakeBool<Equals>(pos, ctx))
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Lambda()
- .Param("result")
- .Callable("Not")
- .Callable(0, "Coalesce")
- .Arg(0, "result")
- .Add(1, MakeBool<Equals>(pos, ctx))
- .Seal()
- .Seal()
- .Seal()
- .Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr SqlEqualLists(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
-
- return ctx.Builder(node.Pos())
- .Callable(Equals ? "And" : "Or")
- .Callable(0, Equals ? "AggrEquals" : "AggrNotEquals")
- .Callable(0, "Length")
- .Add(0, node.HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Callable(1, "Coalesce")
- .Callable(0, "Last")
- .Callable(0, "TakeWhileInclusive")
- .Callable(0, "Chain1Map")
- .Callable(0, "Zip")
- .Add(node.ChildrenList())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable(Equals ? "And" : "Or")
- .Arg(0, "state")
- .Callable(1, node.Content())
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Add(1, MakeStopper<Equals>(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(1, MakeBool<Equals>(node.Pos(), ctx))
- .Seal()
- .Seal().Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrEqualLists(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
- auto all = ctx.Builder(node.Pos())
- .Callable("Exists")
- .Callable(0, "Head")
- .Callable(0, "SkipWhile")
- .Callable(0, "Zip")
- .Add(node.ChildrenList())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("AggrEquals")
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-
- return ctx.Builder(node.Pos())
- .Callable(Equals ? "And" : "Or")
- .Callable(0, node.Content())
- .Callable(0, "Length")
- .Add(0, node.HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Add(1, ctx.WrapByCallableIf(Equals, "Not", std::move(all)))
- .Seal().Build();
-}
-
-template <bool Asc, bool Equals>
-TExprNode::TPtr SqlCompareLists(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
- auto lenCompare = JustIf(ETypeAnnotationKind::Optional == node.GetTypeAnn()->GetKind(),
- ctx.Builder(node.Pos())
- .Callable(Asc ? (Equals ? "AggrLessOrEqual" : "AggrLess") : (Equals ? "AggrGreaterOrEqual" : "AggrGreater"))
- .Callable(0, "Length")
- .Add(0, node.HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Build(), ctx);
-
- return ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Callable(0, "Head")
- .Callable(0, "SkipWhile")
- .Callable(0, "Zip")
- .Add(node.ChildrenList())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("Coalesce")
- .Callable(0, "==")
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, MakeBool<false>(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable(node.Content().SubString(0U, 1U))
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Add(2, std::move(lenCompare))
- .Seal().Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrCompareLists(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
- return ctx.Builder(node.Pos())
- .Callable("IfPresent")
- .Callable(0, "Head")
- .Callable(0, "SkipWhile")
- .Callable(0, "ZipAll")
- .Add(node.ChildrenList())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("AggrEquals")
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Add(2, MakeBool<Equals>(node.Pos(), ctx))
- .Seal().Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr CheckHasItems(const TExprNode::TPtr& node, TExprContext& ctx) {
- return ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node->Pos(), "HasItems", {node}));
-}
-
-template <bool Equals, bool IsDistinct>
-TExprNode::TPtr SqlEqualDicts(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Dicts.";
-
- const auto can = CanCompare<true>(node.Head().GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType(), node.Tail().GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType());
- const auto stub = JustIf(ECompareOptions::Optional == can && !IsDistinct, MakeBool<!Equals>(node.Pos(), ctx), ctx);
- return ctx.Builder(node.Pos())
- .Callable(Equals ? "And" : "Or")
- .Callable(0, Equals ? "AggrEquals" : "AggrNotEquals")
- .Callable(0, "Length")
- .Add(0, node.HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Callable(1, "Coalesce")
- .Callable(0, "Last")
- .Callable(0, "TakeWhileInclusive")
- .Callable(0, "Chain1Map")
- .Callable(0, "DictItems")
- .Add(0, node.HeadPtr())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("IfPresent")
- .Callable(0, "Lookup")
- .Add(0, node.TailPtr())
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("payload")
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Arg(1, "payload")
- .Seal()
- .Seal()
- .Add(2, stub)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable(Equals ? "And" : "Or")
- .Arg(0, "state")
- .Callable(1, "IfPresent")
- .Callable(0, "Lookup")
- .Add(0, node.TailPtr())
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("payload")
- .Callable(node.Content())
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Arg(1, "payload")
- .Seal()
- .Seal()
- .Add(2, stub)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Add(1, MakeStopper<Equals>(node.Pos(), ctx))
- .Seal()
- .Seal()
- .Add(1, MakeBool<Equals>(node.Pos(), ctx))
- .Seal()
- .Seal().Build();
-}
-
-template <bool Equals>
-TExprNode::TPtr AggrEqualDicts(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Dicts.";
- auto all = ctx.Builder(node.Pos())
- .Callable("Exists")
- .Callable(0, "Head")
- .Callable(0, "SkipWhile")
- .Callable(0, "DictItems")
- .Add(0, node.HeadPtr())
- .Seal()
- .Lambda(1)
- .Param("item")
- .Callable("IfPresent")
- .Callable(0, "Lookup")
- .Add(0, node.TailPtr())
- .Callable(1, "Nth")
- .Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("payload")
- .Callable("AggrEquals")
- .Callable(0, "Nth")
- .Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Arg(1, "payload")
- .Seal()
- .Seal()
- .Callable(2, "Bool")
- .Atom(0, "false", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-
- return ctx.Builder(node.Pos())
- .Callable(Equals ? "And" : "Or")
- .Callable(0, node.Content())
- .Callable(0, "Length")
- .Add(0, node.HeadPtr())
- .Seal()
- .Callable(1, "Length")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Add(1, ctx.WrapByCallableIf(Equals, "Not", std::move(all)))
- .Seal().Build();
-}
-
-template <bool Equality, bool Order, bool IsDistinct>
-TExprNode::TPtr SqlCompareVariants(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Variants.";
-
- auto lhs = node.HeadPtr();
- auto rhs = node.TailPtr();
-
- const auto lType = lhs->GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
- const auto rType = rhs->GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
-
- std::vector<std::pair<TExprNode::TPtr, std::optional<bool>>> variants;
- bool swap, byStruct;
- switch (rType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- byStruct = false;
- const auto lTuple = lType->Cast<TTupleExprType>();
- const auto rTuple = rType->Cast<TTupleExprType>();
-
- if (swap = lTuple->GetSize() > rTuple->GetSize())
- std::swap(lhs, rhs);
-
- const auto tupleType = lTuple->GetSize() <= rTuple->GetSize() ? lTuple : rTuple;
- variants.reserve(tupleType->GetSize());
-
- const auto& lItems = lTuple->GetItems();
- const auto& rItems = rTuple->GetItems();
- for (ui32 i = 0U; i < tupleType->GetSize(); ++i) {
+ return MakeBool<Equals>(node.Pos(), ctx);
+ }
+
+ return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrEqualStructs(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Structs.";
+
+ const auto type = node.Head().GetTypeAnn()->Cast<TStructExprType>();
+ if (!type->GetSize())
+ return MakeBool<Equals>(node.Pos(), ctx);
+
+ TExprNode::TListType compares;
+ compares.reserve(type->GetSize());
+
+ for (const auto& item : type->GetItems()) {
+ compares.emplace_back(ctx.Builder(node.Pos())
+ .Callable(node.Content())
+ .Callable(0, "Member")
+ .Add(0, node.HeadPtr())
+ .Atom(1, item->GetName())
+ .Seal()
+ .Callable(1, "Member")
+ .Add(0, node.TailPtr())
+ .Atom(1, item->GetName())
+ .Seal()
+ .Seal()
+ .Build());
+ }
+
+ return ctx.NewCallable(node.Pos(), Equals ? "And" : "Or", std::move(compares));
+}
+
+template <bool Equals>
+TExprNode::TPtr MakeStopper(const TPositionHandle pos, TExprContext& ctx) {
+ return Equals ?
+ ctx.Builder(pos)
+ .Lambda()
+ .Param("result")
+ .Callable("Coalesce")
+ .Arg(0, "result")
+ .Add(1, MakeBool<Equals>(pos, ctx))
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Lambda()
+ .Param("result")
+ .Callable("Not")
+ .Callable(0, "Coalesce")
+ .Arg(0, "result")
+ .Add(1, MakeBool<Equals>(pos, ctx))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr SqlEqualLists(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
+
+ return ctx.Builder(node.Pos())
+ .Callable(Equals ? "And" : "Or")
+ .Callable(0, Equals ? "AggrEquals" : "AggrNotEquals")
+ .Callable(0, "Length")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Callable(1, "Coalesce")
+ .Callable(0, "Last")
+ .Callable(0, "TakeWhileInclusive")
+ .Callable(0, "Chain1Map")
+ .Callable(0, "Zip")
+ .Add(node.ChildrenList())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable(Equals ? "And" : "Or")
+ .Arg(0, "state")
+ .Callable(1, node.Content())
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, MakeStopper<Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(1, MakeBool<Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrEqualLists(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
+ auto all = ctx.Builder(node.Pos())
+ .Callable("Exists")
+ .Callable(0, "Head")
+ .Callable(0, "SkipWhile")
+ .Callable(0, "Zip")
+ .Add(node.ChildrenList())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("AggrEquals")
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
+ return ctx.Builder(node.Pos())
+ .Callable(Equals ? "And" : "Or")
+ .Callable(0, node.Content())
+ .Callable(0, "Length")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Add(1, ctx.WrapByCallableIf(Equals, "Not", std::move(all)))
+ .Seal().Build();
+}
+
+template <bool Asc, bool Equals>
+TExprNode::TPtr SqlCompareLists(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
+ auto lenCompare = JustIf(ETypeAnnotationKind::Optional == node.GetTypeAnn()->GetKind(),
+ ctx.Builder(node.Pos())
+ .Callable(Asc ? (Equals ? "AggrLessOrEqual" : "AggrLess") : (Equals ? "AggrGreaterOrEqual" : "AggrGreater"))
+ .Callable(0, "Length")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Build(), ctx);
+
+ return ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Callable(0, "Head")
+ .Callable(0, "SkipWhile")
+ .Callable(0, "Zip")
+ .Add(node.ChildrenList())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("Coalesce")
+ .Callable(0, "==")
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, MakeBool<false>(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable(node.Content().SubString(0U, 1U))
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, std::move(lenCompare))
+ .Seal().Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrCompareLists(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Lists.";
+ return ctx.Builder(node.Pos())
+ .Callable("IfPresent")
+ .Callable(0, "Head")
+ .Callable(0, "SkipWhile")
+ .Callable(0, "ZipAll")
+ .Add(node.ChildrenList())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("AggrEquals")
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(2, MakeBool<Equals>(node.Pos(), ctx))
+ .Seal().Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr CheckHasItems(const TExprNode::TPtr& node, TExprContext& ctx) {
+ return ctx.WrapByCallableIf(Equals, "Not", ctx.NewCallable(node->Pos(), "HasItems", {node}));
+}
+
+template <bool Equals, bool IsDistinct>
+TExprNode::TPtr SqlEqualDicts(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Dicts.";
+
+ const auto can = CanCompare<true>(node.Head().GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType(), node.Tail().GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType());
+ const auto stub = JustIf(ECompareOptions::Optional == can && !IsDistinct, MakeBool<!Equals>(node.Pos(), ctx), ctx);
+ return ctx.Builder(node.Pos())
+ .Callable(Equals ? "And" : "Or")
+ .Callable(0, Equals ? "AggrEquals" : "AggrNotEquals")
+ .Callable(0, "Length")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Callable(1, "Coalesce")
+ .Callable(0, "Last")
+ .Callable(0, "TakeWhileInclusive")
+ .Callable(0, "Chain1Map")
+ .Callable(0, "DictItems")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("IfPresent")
+ .Callable(0, "Lookup")
+ .Add(0, node.TailPtr())
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("payload")
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Arg(1, "payload")
+ .Seal()
+ .Seal()
+ .Add(2, stub)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable(Equals ? "And" : "Or")
+ .Arg(0, "state")
+ .Callable(1, "IfPresent")
+ .Callable(0, "Lookup")
+ .Add(0, node.TailPtr())
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("payload")
+ .Callable(node.Content())
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Arg(1, "payload")
+ .Seal()
+ .Seal()
+ .Add(2, stub)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, MakeStopper<Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal()
+ .Add(1, MakeBool<Equals>(node.Pos(), ctx))
+ .Seal()
+ .Seal().Build();
+}
+
+template <bool Equals>
+TExprNode::TPtr AggrEqualDicts(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Dicts.";
+ auto all = ctx.Builder(node.Pos())
+ .Callable("Exists")
+ .Callable(0, "Head")
+ .Callable(0, "SkipWhile")
+ .Callable(0, "DictItems")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Callable("IfPresent")
+ .Callable(0, "Lookup")
+ .Add(0, node.TailPtr())
+ .Callable(1, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("payload")
+ .Callable("AggrEquals")
+ .Callable(0, "Nth")
+ .Arg(0, "item")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Arg(1, "payload")
+ .Seal()
+ .Seal()
+ .Callable(2, "Bool")
+ .Atom(0, "false", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
+ return ctx.Builder(node.Pos())
+ .Callable(Equals ? "And" : "Or")
+ .Callable(0, node.Content())
+ .Callable(0, "Length")
+ .Add(0, node.HeadPtr())
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Add(1, ctx.WrapByCallableIf(Equals, "Not", std::move(all)))
+ .Seal().Build();
+}
+
+template <bool Equality, bool Order, bool IsDistinct>
+TExprNode::TPtr SqlCompareVariants(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Variants.";
+
+ auto lhs = node.HeadPtr();
+ auto rhs = node.TailPtr();
+
+ const auto lType = lhs->GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
+ const auto rType = rhs->GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
+
+ std::vector<std::pair<TExprNode::TPtr, std::optional<bool>>> variants;
+ bool swap, byStruct;
+ switch (rType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ byStruct = false;
+ const auto lTuple = lType->Cast<TTupleExprType>();
+ const auto rTuple = rType->Cast<TTupleExprType>();
+
+ if (swap = lTuple->GetSize() > rTuple->GetSize())
+ std::swap(lhs, rhs);
+
+ const auto tupleType = lTuple->GetSize() <= rTuple->GetSize() ? lTuple : rTuple;
+ variants.reserve(tupleType->GetSize());
+
+ const auto& lItems = lTuple->GetItems();
+ const auto& rItems = rTuple->GetItems();
+ for (ui32 i = 0U; i < tupleType->GetSize(); ++i) {
variants.emplace_back(ctx.NewAtom(node.Pos(), ToString(i), TNodeFlags::Default),
- !IsDistinct && ECompareOptions::Optional == CanCompare<true>(lItems[i], rItems[i]));
- }
-
- break;
- }
- case ETypeAnnotationKind::Struct: {
- byStruct = true;
- const auto lStruct = lType->Cast<TStructExprType>();
- const auto rStruct = rType->Cast<TStructExprType>();
-
- if (swap = lStruct->GetSize() > rStruct->GetSize())
- std::swap(lhs, rhs);
-
- const auto structType = lStruct->GetSize() <= rStruct->GetSize() ? lStruct : rStruct;
- variants.reserve(structType->GetSize());
- const auto oppositeType = lStruct->GetSize() > rStruct->GetSize() ? lStruct : rStruct;
-
- const auto& items = oppositeType->GetItems();
- for (const auto& item : structType->GetItems()) {
- variants.emplace_back(ctx.NewAtom(node.Pos(), item->GetName()), std::nullopt);
- if (const auto idx = oppositeType->FindItem(item->GetName())) {
- variants.back().second.emplace(!IsDistinct && ECompareOptions::Optional == CanCompare<true>(item->GetItemType(), items[*idx]->GetItemType()));
- }
- }
-
- break;
- }
- default:
- return {};
- }
-
- TExprNode::TListType children;
- children.reserve((variants.size() << 1U) + 1U);
- children.emplace_back(std::move(lhs));
- const bool optResult = ETypeAnnotationKind::Optional == node.GetTypeAnn()->GetKind();
- for (auto& variant : variants) {
- children.emplace_back(variant.first);
- auto stub = Equality ? MakeBool<Order>(node.Pos(), ctx) :
- ctx.Builder(node.Pos())
- .Callable(Order ^ swap ? "AggrLess" : "AggrGreater")
- .Callable(0, byStruct ? "Utf8" : "Uint32")
- .Add(0, variant.first)
- .Seal()
- .Callable(1, "Way")
- .Add(0, rhs)
- .Seal()
- .Seal()
- .Build();
- if (const auto opt = variant.second) {
- children.emplace_back(optResult && !*opt ?
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("lhs")
- .Callable("Just")
- .Callable(0, "IfPresent")
- .Callable(0, "Guess")
- .Add(0, rhs)
- .Add(1, std::move(variant.first))
- .Seal()
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Arg(0, swap ? "rhs" : "lhs")
- .Arg(1, swap ? "lhs" : "rhs")
- .Seal()
- .Seal()
- .Add(2, JustIf(*opt, std::move(stub), ctx))
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("lhs")
- .Callable("IfPresent")
- .Callable(0, "Guess")
- .Add(0, rhs)
- .Add(1, std::move(variant.first))
- .Seal()
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Arg(0, swap ? "rhs" : "lhs")
- .Arg(1, swap ? "lhs" : "rhs")
- .Seal()
- .Seal()
- .Add(2, JustIf(*opt, std::move(stub), ctx))
- .Seal()
- .Seal()
- .Build()
- );
- } else {
- children.emplace_back(ctx.NewLambda(node.Pos(), ctx.NewArguments(node.Pos(), {ctx.NewArgument(node.Pos(), "unused")}), JustIf(optResult, std::move(stub), ctx)));
- }
- }
-
- return ctx.NewCallable(node.Pos(), "Visit", std::move(children));
-}
-
-template <bool Equality, bool Order>
-TExprNode::TPtr AggrCompareVariants(const TExprNode& node, TExprContext& ctx) {
- YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Variants.";
-
- const auto type = node.Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
-
- TExprNode::TListType variants;
- bool byStruct;
- switch (type->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- byStruct = false;
- const auto size = type->Cast<TTupleExprType>()->GetSize();
- variants.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- variants.emplace_back(ctx.NewAtom(node.Pos(), ToString(i), TNodeFlags::Default));
- }
- break;
- }
- case ETypeAnnotationKind::Struct: {
- byStruct = true;
- const auto structType = type->Cast<TStructExprType>();
- variants.reserve(structType->GetSize());
- for (const auto& item : structType->GetItems()) {
- variants.emplace_back(ctx.NewAtom(node.Pos(), item->GetName()));
- }
- break;
- }
- default:
- return {};
- }
-
- TExprNode::TListType children;
- children.reserve((variants.size() << 1U) + 1U);
- children.emplace_back(node.HeadPtr());
- for (auto& variant : variants) {
- children.emplace_back(variant);
- auto stub = Equality ? MakeBool<Order>(node.Pos(), ctx) :
- ctx.Builder(node.Pos())
- .Callable(Order ? "AggrLess" : "AggrGreater")
- .Callable(0, byStruct ? "Utf8" : "Uint32")
- .Add(0, variant)
- .Seal()
- .Callable(1, "Way")
- .Add(0, node.TailPtr())
- .Seal()
- .Seal()
- .Build();
- children.emplace_back(
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("lhs")
- .Callable("IfPresent")
- .Callable(0, "Guess")
- .Add(0, node.TailPtr())
- .Add(1, std::move(variant))
- .Seal()
- .Lambda(1)
- .Param("rhs")
- .Callable(node.Content())
- .Arg(0, "lhs")
- .Arg(1, "rhs")
- .Seal()
- .Seal()
- .Add(2, std::move(stub))
- .Seal()
- .Seal()
- .Build()
- );
- }
-
- return ctx.NewCallable(node.Pos(), "Visit", std::move(children));
-}
-
-
-TExprNode::TPtr CompareTagged(const TExprNode& node, TExprContext& ctx) {
- auto children = node.ChildrenList();
- std::for_each(children.begin(), children.end(), [&](TExprNode::TPtr& child) {
- if (const auto type = child->GetTypeAnn(); ETypeAnnotationKind::Tagged == type->GetKind()) {
- const auto pos = child->Pos();
- child = ctx.NewCallable(pos, "Untag", {std::move(child), ctx.NewAtom(pos, type->Cast<TTaggedExprType>()->GetTag())});
- }
- });
- return ctx.ChangeChildren(node, std::move(children));
-}
-
-template <bool Equals, bool IsDistinct>
-TExprNode::TPtr ExpandSqlEqual(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto lType = node->Head().GetTypeAnn();
- const auto rType = node->Tail().GetTypeAnn();
- if (const auto lKind = lType->GetKind(), rKind = rType->GetKind(); lKind == rKind) {
- switch (rKind) {
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::EmptyList:
- case ETypeAnnotationKind::EmptyDict:
- return MakeBool<Equals>(node->Pos(), ctx);
- case ETypeAnnotationKind::Null:
- return IsDistinct ? MakeBool<Equals>(node->Pos(), ctx) : MakeBoolNothing(node->Pos(), ctx);
- case ETypeAnnotationKind::Tuple:
- return SqlEqualTuples<Equals>(*node, ctx);
- case ETypeAnnotationKind::Struct:
- return SqlEqualStructs<Equals>(*node, ctx);
- case ETypeAnnotationKind::List:
- return SqlEqualLists<Equals>(*node, ctx);
- case ETypeAnnotationKind::Dict:
- return SqlEqualDicts<Equals, IsDistinct>(*node, ctx);
- case ETypeAnnotationKind::Variant:
- return SqlCompareVariants<true, !Equals, IsDistinct>(*node, ctx);
- case ETypeAnnotationKind::Tagged:
- return CompareTagged(*node, ctx);
- case ETypeAnnotationKind::Optional:
- if constexpr (IsDistinct)
- return AggrEqualOpt<Equals>(*node, ctx);
- else
- return ReduceBothArgs<true>(*node, ctx);
- default:
- break;
- }
- } else if (ETypeAnnotationKind::List == lKind && ETypeAnnotationKind::EmptyList == rKind
- || ETypeAnnotationKind::Dict == lKind && ETypeAnnotationKind::EmptyDict == rKind) {
- return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), CheckHasItems<Equals>(node->HeadPtr(), ctx), ctx);
- } else if (ETypeAnnotationKind::EmptyList == lKind && ETypeAnnotationKind::List == rKind
- || ETypeAnnotationKind::EmptyDict == lKind && ETypeAnnotationKind::Dict == rKind) {
- return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), CheckHasItems<Equals>(node->TailPtr(), ctx), ctx);
- } else if (ETypeAnnotationKind::Optional == lKind) {
- return ReduceLeftArg<true, Equals, IsDistinct>(*node, ctx);
- } else if (ETypeAnnotationKind::Optional == rKind) {
- return ReduceRightArg<true, Equals, IsDistinct>(*node, ctx);
- }
-
- return node;
-}
-
-template<bool Asc, bool Equals>
-TExprNode::TPtr ExpandSqlCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto lType = node->Head().GetTypeAnn();
- const auto rType = node->Tail().GetTypeAnn();
- if (const auto lKind = lType->GetKind(), rKind = rType->GetKind(); lKind == rKind) {
- switch (rKind) {
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::EmptyList:
- case ETypeAnnotationKind::EmptyDict:
- return MakeBool<Equals>(node->Pos(), ctx);
- case ETypeAnnotationKind::Null:
- return MakeBoolNothing(node->Pos(), ctx);
- case ETypeAnnotationKind::Tuple:
- return SqlCompareTuples(*node, ctx);
- case ETypeAnnotationKind::List:
- return SqlCompareLists<Asc, Equals>(*node, ctx);
- case ETypeAnnotationKind::Variant:
- return SqlCompareVariants<false, Asc, false>(*node, ctx);
- case ETypeAnnotationKind::Tagged:
- return CompareTagged(*node, ctx);
- case ETypeAnnotationKind::Optional:
- return ReduceBothArgs<false>(*node, ctx);
- default:
- break;
- }
- } else if (ETypeAnnotationKind::List == lKind && ETypeAnnotationKind::EmptyList == rKind) {
- return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), Asc != Equals ? MakeBool<!Asc>(node->Pos(), ctx) : CheckHasItems<Asc>(node->HeadPtr(), ctx), ctx);
- } else if (ETypeAnnotationKind::EmptyList == lKind && ETypeAnnotationKind::List == rKind) {
- return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), Asc == Equals ? MakeBool<Asc>(node->Pos(), ctx) : CheckHasItems<!Asc>(node->TailPtr(), ctx), ctx);
- } else if (ETypeAnnotationKind::Optional == lKind) {
- return ReduceLeftArg<false, Equals, false>(*node, ctx);
- } else if (ETypeAnnotationKind::Optional == rKind) {
- return ReduceRightArg<false, Equals, false>(*node, ctx);
- }
-
- return node;
-}
-
-template <bool Equals>
-TExprNode::TPtr ExpandAggrEqual(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto type = node->Head().GetTypeAnn();
- YQL_ENSURE(IsSameAnnotation(*type, *node->Tail().GetTypeAnn()), "Expected same type.");
- switch (type->GetKind()) {
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::Null:
- case ETypeAnnotationKind::EmptyList:
- case ETypeAnnotationKind::EmptyDict:
- return MakeBool<Equals>(node->Pos(), ctx);
- case ETypeAnnotationKind::Tuple:
- return AggrEqualTuples<Equals>(*node, ctx);
- case ETypeAnnotationKind::Struct:
- return AggrEqualStructs<Equals>(*node, ctx);
- case ETypeAnnotationKind::List:
- return AggrEqualLists<Equals>(*node, ctx);
- case ETypeAnnotationKind::Dict:
- return AggrEqualDicts<Equals>(*node, ctx);
- case ETypeAnnotationKind::Variant:
- return AggrCompareVariants<true, !Equals>(*node, ctx);
- case ETypeAnnotationKind::Tagged:
- return CompareTagged(*node, ctx);
- case ETypeAnnotationKind::Optional:
- if (type->Cast<TOptionalExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Data)
- return AggrEqualOpt<Equals>(*node, ctx);
- [[fallthrough]];
- default:
- break;
- }
- return node;
-}
-
-template<bool Asc, bool Equals>
-TExprNode::TPtr ExpandAggrCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
- const auto type = node->Head().GetTypeAnn();
- YQL_ENSURE(IsSameAnnotation(*type, *node->Tail().GetTypeAnn()), "Expected same type.");
- switch (type->GetKind()) {
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::Null:
- case ETypeAnnotationKind::EmptyList:
- case ETypeAnnotationKind::EmptyDict:
- return MakeBool<Equals>(node->Pos(), ctx);
- case ETypeAnnotationKind::Tuple:
- return AggrCompareTuples<Asc>(*node, ctx);
- case ETypeAnnotationKind::List:
- return AggrCompareLists<Equals>(*node, ctx);
- case ETypeAnnotationKind::Variant:
- return AggrCompareVariants<false, Asc>(*node, ctx);
- case ETypeAnnotationKind::Tagged:
- return CompareTagged(*node, ctx);
- case ETypeAnnotationKind::Optional:
- if (type->Cast<TOptionalExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Data)
- return AggrCompareOpt<Asc, Equals>(*node, ctx);
- [[fallthrough]];
- default:
- break;
- }
-
- return node;
-}
-
-ui64 ToDate(ui64 now) { return std::min<ui64>(NUdf::MAX_DATE - 1U, now / 86400000000ull); }
-ui64 ToDatetime(ui64 now) { return std::min<ui64>(NUdf::MAX_DATETIME - 1U, now / 1000000ull); }
-ui64 ToTimestamp(ui64 now) { return std::min<ui64>(NUdf::MAX_TIMESTAMP - 1ULL, now); }
-
-template <bool EnableNewOptimizers>
-struct TPeepHoleRules {
- static constexpr std::initializer_list<TPeepHoleOptimizerMap::value_type> CommonStageRulesInit = {
- {"EquiJoin", &ExpandEquiJoin},
- {"SafeCast", &ExpandCast<false>},
- {"StrictCast", &ExpandCast<true>},
- {"AlterTo", &ExpandAlterTo},
+ !IsDistinct && ECompareOptions::Optional == CanCompare<true>(lItems[i], rItems[i]));
+ }
+
+ break;
+ }
+ case ETypeAnnotationKind::Struct: {
+ byStruct = true;
+ const auto lStruct = lType->Cast<TStructExprType>();
+ const auto rStruct = rType->Cast<TStructExprType>();
+
+ if (swap = lStruct->GetSize() > rStruct->GetSize())
+ std::swap(lhs, rhs);
+
+ const auto structType = lStruct->GetSize() <= rStruct->GetSize() ? lStruct : rStruct;
+ variants.reserve(structType->GetSize());
+ const auto oppositeType = lStruct->GetSize() > rStruct->GetSize() ? lStruct : rStruct;
+
+ const auto& items = oppositeType->GetItems();
+ for (const auto& item : structType->GetItems()) {
+ variants.emplace_back(ctx.NewAtom(node.Pos(), item->GetName()), std::nullopt);
+ if (const auto idx = oppositeType->FindItem(item->GetName())) {
+ variants.back().second.emplace(!IsDistinct && ECompareOptions::Optional == CanCompare<true>(item->GetItemType(), items[*idx]->GetItemType()));
+ }
+ }
+
+ break;
+ }
+ default:
+ return {};
+ }
+
+ TExprNode::TListType children;
+ children.reserve((variants.size() << 1U) + 1U);
+ children.emplace_back(std::move(lhs));
+ const bool optResult = ETypeAnnotationKind::Optional == node.GetTypeAnn()->GetKind();
+ for (auto& variant : variants) {
+ children.emplace_back(variant.first);
+ auto stub = Equality ? MakeBool<Order>(node.Pos(), ctx) :
+ ctx.Builder(node.Pos())
+ .Callable(Order ^ swap ? "AggrLess" : "AggrGreater")
+ .Callable(0, byStruct ? "Utf8" : "Uint32")
+ .Add(0, variant.first)
+ .Seal()
+ .Callable(1, "Way")
+ .Add(0, rhs)
+ .Seal()
+ .Seal()
+ .Build();
+ if (const auto opt = variant.second) {
+ children.emplace_back(optResult && !*opt ?
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("lhs")
+ .Callable("Just")
+ .Callable(0, "IfPresent")
+ .Callable(0, "Guess")
+ .Add(0, rhs)
+ .Add(1, std::move(variant.first))
+ .Seal()
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Arg(0, swap ? "rhs" : "lhs")
+ .Arg(1, swap ? "lhs" : "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, JustIf(*opt, std::move(stub), ctx))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Callable(0, "Guess")
+ .Add(0, rhs)
+ .Add(1, std::move(variant.first))
+ .Seal()
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Arg(0, swap ? "rhs" : "lhs")
+ .Arg(1, swap ? "lhs" : "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, JustIf(*opt, std::move(stub), ctx))
+ .Seal()
+ .Seal()
+ .Build()
+ );
+ } else {
+ children.emplace_back(ctx.NewLambda(node.Pos(), ctx.NewArguments(node.Pos(), {ctx.NewArgument(node.Pos(), "unused")}), JustIf(optResult, std::move(stub), ctx)));
+ }
+ }
+
+ return ctx.NewCallable(node.Pos(), "Visit", std::move(children));
+}
+
+template <bool Equality, bool Order>
+TExprNode::TPtr AggrCompareVariants(const TExprNode& node, TExprContext& ctx) {
+ YQL_CLOG(DEBUG, CorePeepHole) << "Expand '" << node.Content() << "' over Variants.";
+
+ const auto type = node.Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
+
+ TExprNode::TListType variants;
+ bool byStruct;
+ switch (type->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ byStruct = false;
+ const auto size = type->Cast<TTupleExprType>()->GetSize();
+ variants.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ variants.emplace_back(ctx.NewAtom(node.Pos(), ToString(i), TNodeFlags::Default));
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Struct: {
+ byStruct = true;
+ const auto structType = type->Cast<TStructExprType>();
+ variants.reserve(structType->GetSize());
+ for (const auto& item : structType->GetItems()) {
+ variants.emplace_back(ctx.NewAtom(node.Pos(), item->GetName()));
+ }
+ break;
+ }
+ default:
+ return {};
+ }
+
+ TExprNode::TListType children;
+ children.reserve((variants.size() << 1U) + 1U);
+ children.emplace_back(node.HeadPtr());
+ for (auto& variant : variants) {
+ children.emplace_back(variant);
+ auto stub = Equality ? MakeBool<Order>(node.Pos(), ctx) :
+ ctx.Builder(node.Pos())
+ .Callable(Order ? "AggrLess" : "AggrGreater")
+ .Callable(0, byStruct ? "Utf8" : "Uint32")
+ .Add(0, variant)
+ .Seal()
+ .Callable(1, "Way")
+ .Add(0, node.TailPtr())
+ .Seal()
+ .Seal()
+ .Build();
+ children.emplace_back(
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("lhs")
+ .Callable("IfPresent")
+ .Callable(0, "Guess")
+ .Add(0, node.TailPtr())
+ .Add(1, std::move(variant))
+ .Seal()
+ .Lambda(1)
+ .Param("rhs")
+ .Callable(node.Content())
+ .Arg(0, "lhs")
+ .Arg(1, "rhs")
+ .Seal()
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal()
+ .Seal()
+ .Build()
+ );
+ }
+
+ return ctx.NewCallable(node.Pos(), "Visit", std::move(children));
+}
+
+
+TExprNode::TPtr CompareTagged(const TExprNode& node, TExprContext& ctx) {
+ auto children = node.ChildrenList();
+ std::for_each(children.begin(), children.end(), [&](TExprNode::TPtr& child) {
+ if (const auto type = child->GetTypeAnn(); ETypeAnnotationKind::Tagged == type->GetKind()) {
+ const auto pos = child->Pos();
+ child = ctx.NewCallable(pos, "Untag", {std::move(child), ctx.NewAtom(pos, type->Cast<TTaggedExprType>()->GetTag())});
+ }
+ });
+ return ctx.ChangeChildren(node, std::move(children));
+}
+
+template <bool Equals, bool IsDistinct>
+TExprNode::TPtr ExpandSqlEqual(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto lType = node->Head().GetTypeAnn();
+ const auto rType = node->Tail().GetTypeAnn();
+ if (const auto lKind = lType->GetKind(), rKind = rType->GetKind(); lKind == rKind) {
+ switch (rKind) {
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::EmptyList:
+ case ETypeAnnotationKind::EmptyDict:
+ return MakeBool<Equals>(node->Pos(), ctx);
+ case ETypeAnnotationKind::Null:
+ return IsDistinct ? MakeBool<Equals>(node->Pos(), ctx) : MakeBoolNothing(node->Pos(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return SqlEqualTuples<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Struct:
+ return SqlEqualStructs<Equals>(*node, ctx);
+ case ETypeAnnotationKind::List:
+ return SqlEqualLists<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Dict:
+ return SqlEqualDicts<Equals, IsDistinct>(*node, ctx);
+ case ETypeAnnotationKind::Variant:
+ return SqlCompareVariants<true, !Equals, IsDistinct>(*node, ctx);
+ case ETypeAnnotationKind::Tagged:
+ return CompareTagged(*node, ctx);
+ case ETypeAnnotationKind::Optional:
+ if constexpr (IsDistinct)
+ return AggrEqualOpt<Equals>(*node, ctx);
+ else
+ return ReduceBothArgs<true>(*node, ctx);
+ default:
+ break;
+ }
+ } else if (ETypeAnnotationKind::List == lKind && ETypeAnnotationKind::EmptyList == rKind
+ || ETypeAnnotationKind::Dict == lKind && ETypeAnnotationKind::EmptyDict == rKind) {
+ return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), CheckHasItems<Equals>(node->HeadPtr(), ctx), ctx);
+ } else if (ETypeAnnotationKind::EmptyList == lKind && ETypeAnnotationKind::List == rKind
+ || ETypeAnnotationKind::EmptyDict == lKind && ETypeAnnotationKind::Dict == rKind) {
+ return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), CheckHasItems<Equals>(node->TailPtr(), ctx), ctx);
+ } else if (ETypeAnnotationKind::Optional == lKind) {
+ return ReduceLeftArg<true, Equals, IsDistinct>(*node, ctx);
+ } else if (ETypeAnnotationKind::Optional == rKind) {
+ return ReduceRightArg<true, Equals, IsDistinct>(*node, ctx);
+ }
+
+ return node;
+}
+
+template<bool Asc, bool Equals>
+TExprNode::TPtr ExpandSqlCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto lType = node->Head().GetTypeAnn();
+ const auto rType = node->Tail().GetTypeAnn();
+ if (const auto lKind = lType->GetKind(), rKind = rType->GetKind(); lKind == rKind) {
+ switch (rKind) {
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::EmptyList:
+ case ETypeAnnotationKind::EmptyDict:
+ return MakeBool<Equals>(node->Pos(), ctx);
+ case ETypeAnnotationKind::Null:
+ return MakeBoolNothing(node->Pos(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return SqlCompareTuples(*node, ctx);
+ case ETypeAnnotationKind::List:
+ return SqlCompareLists<Asc, Equals>(*node, ctx);
+ case ETypeAnnotationKind::Variant:
+ return SqlCompareVariants<false, Asc, false>(*node, ctx);
+ case ETypeAnnotationKind::Tagged:
+ return CompareTagged(*node, ctx);
+ case ETypeAnnotationKind::Optional:
+ return ReduceBothArgs<false>(*node, ctx);
+ default:
+ break;
+ }
+ } else if (ETypeAnnotationKind::List == lKind && ETypeAnnotationKind::EmptyList == rKind) {
+ return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), Asc != Equals ? MakeBool<!Asc>(node->Pos(), ctx) : CheckHasItems<Asc>(node->HeadPtr(), ctx), ctx);
+ } else if (ETypeAnnotationKind::EmptyList == lKind && ETypeAnnotationKind::List == rKind) {
+ return JustIf(ETypeAnnotationKind::Optional == node->GetTypeAnn()->GetKind(), Asc == Equals ? MakeBool<Asc>(node->Pos(), ctx) : CheckHasItems<!Asc>(node->TailPtr(), ctx), ctx);
+ } else if (ETypeAnnotationKind::Optional == lKind) {
+ return ReduceLeftArg<false, Equals, false>(*node, ctx);
+ } else if (ETypeAnnotationKind::Optional == rKind) {
+ return ReduceRightArg<false, Equals, false>(*node, ctx);
+ }
+
+ return node;
+}
+
+template <bool Equals>
+TExprNode::TPtr ExpandAggrEqual(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto type = node->Head().GetTypeAnn();
+ YQL_ENSURE(IsSameAnnotation(*type, *node->Tail().GetTypeAnn()), "Expected same type.");
+ switch (type->GetKind()) {
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::Null:
+ case ETypeAnnotationKind::EmptyList:
+ case ETypeAnnotationKind::EmptyDict:
+ return MakeBool<Equals>(node->Pos(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return AggrEqualTuples<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Struct:
+ return AggrEqualStructs<Equals>(*node, ctx);
+ case ETypeAnnotationKind::List:
+ return AggrEqualLists<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Dict:
+ return AggrEqualDicts<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Variant:
+ return AggrCompareVariants<true, !Equals>(*node, ctx);
+ case ETypeAnnotationKind::Tagged:
+ return CompareTagged(*node, ctx);
+ case ETypeAnnotationKind::Optional:
+ if (type->Cast<TOptionalExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Data)
+ return AggrEqualOpt<Equals>(*node, ctx);
+ [[fallthrough]];
+ default:
+ break;
+ }
+ return node;
+}
+
+template<bool Asc, bool Equals>
+TExprNode::TPtr ExpandAggrCompare(const TExprNode::TPtr& node, TExprContext& ctx) {
+ const auto type = node->Head().GetTypeAnn();
+ YQL_ENSURE(IsSameAnnotation(*type, *node->Tail().GetTypeAnn()), "Expected same type.");
+ switch (type->GetKind()) {
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::Null:
+ case ETypeAnnotationKind::EmptyList:
+ case ETypeAnnotationKind::EmptyDict:
+ return MakeBool<Equals>(node->Pos(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return AggrCompareTuples<Asc>(*node, ctx);
+ case ETypeAnnotationKind::List:
+ return AggrCompareLists<Equals>(*node, ctx);
+ case ETypeAnnotationKind::Variant:
+ return AggrCompareVariants<false, Asc>(*node, ctx);
+ case ETypeAnnotationKind::Tagged:
+ return CompareTagged(*node, ctx);
+ case ETypeAnnotationKind::Optional:
+ if (type->Cast<TOptionalExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Data)
+ return AggrCompareOpt<Asc, Equals>(*node, ctx);
+ [[fallthrough]];
+ default:
+ break;
+ }
+
+ return node;
+}
+
+ui64 ToDate(ui64 now) { return std::min<ui64>(NUdf::MAX_DATE - 1U, now / 86400000000ull); }
+ui64 ToDatetime(ui64 now) { return std::min<ui64>(NUdf::MAX_DATETIME - 1U, now / 1000000ull); }
+ui64 ToTimestamp(ui64 now) { return std::min<ui64>(NUdf::MAX_TIMESTAMP - 1ULL, now); }
+
+template <bool EnableNewOptimizers>
+struct TPeepHoleRules {
+ static constexpr std::initializer_list<TPeepHoleOptimizerMap::value_type> CommonStageRulesInit = {
+ {"EquiJoin", &ExpandEquiJoin},
+ {"SafeCast", &ExpandCast<false>},
+ {"StrictCast", &ExpandCast<true>},
+ {"AlterTo", &ExpandAlterTo},
{"SqlIn", &ExpandSqlIn},
- {"Lookup", &RewriteSearchByKeyForTypesMismatch<false>},
+ {"Lookup", &RewriteSearchByKeyForTypesMismatch<false>},
{"Contains", &RewriteSearchByKeyForTypesMismatch<true>},
- {"ListHas", &ExpandListHas},
- {"Map", &CleckClosureOnUpperLambdaOverList},
- {"OrderedMap", &CleckClosureOnUpperLambdaOverList},
- {"FlatMap", &CleckClosureOnUpperLambdaOverList},
- {"OrderedFlatMap", &CleckClosureOnUpperLambdaOverList},
- {"Filter", &CleckClosureOnUpperLambdaOverList},
- {"OrderedFilter", &CleckClosureOnUpperLambdaOverList},
- {"TakeWhile", &CleckClosureOnUpperLambdaOverList},
- {"SkipWhile", &CleckClosureOnUpperLambdaOverList},
- {"TakeWhileInclusive", &CleckClosureOnUpperLambdaOverList},
- {"SkipWhileInclusive", &CleckClosureOnUpperLambdaOverList},
- {"FoldMap", &CleckClosureOnUpperLambdaOverList<2U>},
- {"Fold1Map", &CleckClosureOnUpperLambdaOverList<1U, 2U>},
- {"Chain1Map", &CleckClosureOnUpperLambdaOverList<1U, 2U>},
- {"CalcOverWindow", &ExpandCalcOverWindow},
+ {"ListHas", &ExpandListHas},
+ {"Map", &CleckClosureOnUpperLambdaOverList},
+ {"OrderedMap", &CleckClosureOnUpperLambdaOverList},
+ {"FlatMap", &CleckClosureOnUpperLambdaOverList},
+ {"OrderedFlatMap", &CleckClosureOnUpperLambdaOverList},
+ {"Filter", &CleckClosureOnUpperLambdaOverList},
+ {"OrderedFilter", &CleckClosureOnUpperLambdaOverList},
+ {"TakeWhile", &CleckClosureOnUpperLambdaOverList},
+ {"SkipWhile", &CleckClosureOnUpperLambdaOverList},
+ {"TakeWhileInclusive", &CleckClosureOnUpperLambdaOverList},
+ {"SkipWhileInclusive", &CleckClosureOnUpperLambdaOverList},
+ {"FoldMap", &CleckClosureOnUpperLambdaOverList<2U>},
+ {"Fold1Map", &CleckClosureOnUpperLambdaOverList<1U, 2U>},
+ {"Chain1Map", &CleckClosureOnUpperLambdaOverList<1U, 2U>},
+ {"CalcOverWindow", &ExpandCalcOverWindow},
{"CalcOverSessionWindow", &ExpandCalcOverWindow},
{"CalcOverWindowGroup", &ExpandCalcOverWindow},
- {"PartitionsByKeys", &ExpandPartitionsByKeys},
- {"DictItems", &MapForOptionalContainer},
- {"DictKeys", &MapForOptionalContainer},
- {"DictPayloads", &MapForOptionalContainer},
- {"HasItems", &MapForOptionalContainer},
- {"Length", &MapForOptionalContainer},
- {"Size", &MapForOptionalContainer},
- {"ToIndexDict", &MapForOptionalContainer},
- {"Iterator", &WrapIteratorForOptionalList},
- {"IsKeySwitch", &ExpandIsKeySwitch},
- {"Mux", &ExpandMux},
- {"Demux", &ExpandDemux},
- {"OptionalReduce", &ExpandOptionalReduce},
- {"AggrMin", &ExpandAggrMinMax<true>},
- {"AggrMax", &ExpandAggrMinMax<false>},
+ {"PartitionsByKeys", &ExpandPartitionsByKeys},
+ {"DictItems", &MapForOptionalContainer},
+ {"DictKeys", &MapForOptionalContainer},
+ {"DictPayloads", &MapForOptionalContainer},
+ {"HasItems", &MapForOptionalContainer},
+ {"Length", &MapForOptionalContainer},
+ {"Size", &MapForOptionalContainer},
+ {"ToIndexDict", &MapForOptionalContainer},
+ {"Iterator", &WrapIteratorForOptionalList},
+ {"IsKeySwitch", &ExpandIsKeySwitch},
+ {"Mux", &ExpandMux},
+ {"Demux", &ExpandDemux},
+ {"OptionalReduce", &ExpandOptionalReduce},
+ {"AggrMin", &ExpandAggrMinMax<true>},
+ {"AggrMax", &ExpandAggrMinMax<false>},
{"Aggregate", &ExpandAggregateCompact},
- {"And", &OptimizeLogicalDups<true>},
- {"Or", &OptimizeLogicalDups<false>},
- {"CombineByKey", &ExpandCombineByKey},
- {"SkipNullMembers", &ExpandSkipNullFields<EnableNewOptimizers, false>},
- {"SkipNullElements", &ExpandSkipNullFields<EnableNewOptimizers, true>},
+ {"And", &OptimizeLogicalDups<true>},
+ {"Or", &OptimizeLogicalDups<false>},
+ {"CombineByKey", &ExpandCombineByKey},
+ {"SkipNullMembers", &ExpandSkipNullFields<EnableNewOptimizers, false>},
+ {"SkipNullElements", &ExpandSkipNullFields<EnableNewOptimizers, true>},
{"ConstraintsOf", &ExpandConstraintsOf},
- {"==", &ExpandSqlEqual<true, false>},
- {"!=", &ExpandSqlEqual<false, false>},
- {"IsNotDistinctFrom", &ExpandSqlEqual<true, true>},
- {"IsDistinctFrom", &ExpandSqlEqual<false, true>},
- {"<", &ExpandSqlCompare<true, false>},
- {">", &ExpandSqlCompare<false, false>},
- {"<=", &ExpandSqlCompare<true, true>},
- {">=", &ExpandSqlCompare<false, true>},
- {"AggrEquals", &ExpandAggrEqual<true>},
- {"AggrNotEquals", &ExpandAggrEqual<false>},
- {"AggrLess", &ExpandAggrCompare<true, false>},
- {"AggrGreater", &ExpandAggrCompare<false, false>},
- {"AggrLessOrEqual", &ExpandAggrCompare<true, true>},
- {"AggrGreaterOrEqual", &ExpandAggrCompare<false, true>},
+ {"==", &ExpandSqlEqual<true, false>},
+ {"!=", &ExpandSqlEqual<false, false>},
+ {"IsNotDistinctFrom", &ExpandSqlEqual<true, true>},
+ {"IsDistinctFrom", &ExpandSqlEqual<false, true>},
+ {"<", &ExpandSqlCompare<true, false>},
+ {">", &ExpandSqlCompare<false, false>},
+ {"<=", &ExpandSqlCompare<true, true>},
+ {">=", &ExpandSqlCompare<false, true>},
+ {"AggrEquals", &ExpandAggrEqual<true>},
+ {"AggrNotEquals", &ExpandAggrEqual<false>},
+ {"AggrLess", &ExpandAggrCompare<true, false>},
+ {"AggrGreater", &ExpandAggrCompare<false, false>},
+ {"AggrLessOrEqual", &ExpandAggrCompare<true, true>},
+ {"AggrGreaterOrEqual", &ExpandAggrCompare<false, true>},
{"RangeEmpty", &ExpandRangeEmpty},
{"AsRange", &ExpandAsRange},
{"RangeFor", &ExpandRangeFor},
{"PgCall", &ExpandPgCall},
- };
-
+ };
+
static constexpr std::initializer_list<TPeepHoleOptimizerMap::value_type> SimplifyStageRulesInit = {
- {"Map", &OptimizeMap<false, EnableNewOptimizers>},
- {"OrderedMap", &OptimizeMap<true, EnableNewOptimizers>},
- {"FlatMap", &ExpandFlatMap<false, EnableNewOptimizers>},
- {"OrderedFlatMap", &ExpandFlatMap<true, EnableNewOptimizers>},
+ {"Map", &OptimizeMap<false, EnableNewOptimizers>},
+ {"OrderedMap", &OptimizeMap<true, EnableNewOptimizers>},
+ {"FlatMap", &ExpandFlatMap<false, EnableNewOptimizers>},
+ {"OrderedFlatMap", &ExpandFlatMap<true, EnableNewOptimizers>},
{"ListIf", &ExpandContainerIf<false, true>},
{"OptionalIf", &ExpandContainerIf<false, false>},
{"FlatListIf", &ExpandContainerIf<true, true>},
@@ -5771,130 +5771,130 @@ struct TPeepHoleRules {
};
static constexpr std::initializer_list<TPeepHoleOptimizerMap::value_type> FinalStageRulesInit = {
- {"Take", &OptimizeTake<EnableNewOptimizers>},
- {"Skip", &OptimizeSkip},
- {"Likely", &LikelyExclude},
- {"GroupByKey", &PeepHoleConvertGroupBySingleKey},
- {"PartitionByKey", &PeepHolePlainKeyForPartitionByKey},
- {"ExtractMembers", &PeepHoleExpandExtractItems},
- {"DictFromKeys", &PeepHoleDictFromKeysToDict},
- {"AddMember", &ExpandAddMember},
- {"ReplaceMember", &ExpandReplaceMember},
- {"RemoveMember", &ExpandRemoveMember},
+ {"Take", &OptimizeTake<EnableNewOptimizers>},
+ {"Skip", &OptimizeSkip},
+ {"Likely", &LikelyExclude},
+ {"GroupByKey", &PeepHoleConvertGroupBySingleKey},
+ {"PartitionByKey", &PeepHolePlainKeyForPartitionByKey},
+ {"ExtractMembers", &PeepHoleExpandExtractItems},
+ {"DictFromKeys", &PeepHoleDictFromKeysToDict},
+ {"AddMember", &ExpandAddMember},
+ {"ReplaceMember", &ExpandReplaceMember},
+ {"RemoveMember", &ExpandRemoveMember},
{"RemovePrefixMembers", &ExpandRemovePrefixMembers},
{"AsSet", &ExpandAsSet},
- {"ForceRemoveMember", &ExpandRemoveMember},
- {"DivePrefixMembers", &ExpandDivePrefixMembers},
- {"FlattenMembers", &ExpandFlattenMembers},
- {"FlattenStructs", &ExpandFlattenStructs},
- {"FlattenByColumns", &ExpandFlattenByColumns},
+ {"ForceRemoveMember", &ExpandRemoveMember},
+ {"DivePrefixMembers", &ExpandDivePrefixMembers},
+ {"FlattenMembers", &ExpandFlattenMembers},
+ {"FlattenStructs", &ExpandFlattenStructs},
+ {"FlattenByColumns", &ExpandFlattenByColumns},
{"CastStruct", &ExpandCastStruct},
- {"Filter", &ExpandFilter},
- {"OrderedFilter", &ExpandFilter},
- {"TakeWhile", &ExpandFilter<false>},
- {"SkipWhile", &ExpandFilter<true>},
- {"LMap", &ExpandLMap},
- {"OrderedLMap", &ExpandLMap},
- {"ExpandMap", &OptimizeExpandMap},
- {"MultiMap", &OptimizeMultiMap<false>},
- {"OrderedMultiMap", &OptimizeMultiMap<true>},
- {"Nth", &OptimizeNth},
- {"Member", &OptimizeMember},
- {"Condense1", &OptimizeCondense1},
- {"CombineCore", &OptimizeCombineCore},
- {"Chopper", &OptimizeChopper},
- {"WideCombiner", &OptimizeWideCombiner},
- {"WideCondense1", &OptimizeWideCondense1},
- {"WideChopper", &OptimizeWideChopper},
- {"WideMap", &OptimizeWideMaps},
- {"NarrowMap", &OptimizeWideMaps},
- {"NarrowFlatMap", &OptimizeNarrowFlatMap},
- {"NarrowMultiMap", &OptimizeWideMaps},
- {"MapJoinCore", &OptimizeMapJoinCore},
+ {"Filter", &ExpandFilter},
+ {"OrderedFilter", &ExpandFilter},
+ {"TakeWhile", &ExpandFilter<false>},
+ {"SkipWhile", &ExpandFilter<true>},
+ {"LMap", &ExpandLMap},
+ {"OrderedLMap", &ExpandLMap},
+ {"ExpandMap", &OptimizeExpandMap},
+ {"MultiMap", &OptimizeMultiMap<false>},
+ {"OrderedMultiMap", &OptimizeMultiMap<true>},
+ {"Nth", &OptimizeNth},
+ {"Member", &OptimizeMember},
+ {"Condense1", &OptimizeCondense1},
+ {"CombineCore", &OptimizeCombineCore},
+ {"Chopper", &OptimizeChopper},
+ {"WideCombiner", &OptimizeWideCombiner},
+ {"WideCondense1", &OptimizeWideCondense1},
+ {"WideChopper", &OptimizeWideChopper},
+ {"WideMap", &OptimizeWideMaps},
+ {"NarrowMap", &OptimizeWideMaps},
+ {"NarrowFlatMap", &OptimizeNarrowFlatMap},
+ {"NarrowMultiMap", &OptimizeWideMaps},
+ {"MapJoinCore", &OptimizeMapJoinCore},
{"CommonJoinCore", &OptimizeCommonJoinCore},
- {"BuildTablePath", &DoBuildTablePath},
- {"Exists", &OptimizeExists},
- {"SqueezeToDict", &OptimizeSqueezeToDict}
- };
-
- static constexpr std::initializer_list<TNonDeterministicOptimizerMap::value_type> FinalStageNonDetRulesInit = {
- {"Random", &Random0Arg<double>},
- {"RandomNumber", &Random0Arg<ui64>},
- {"RandomUuid", &Random0Arg<TGUID>},
- {"Now", &Now0Arg<nullptr>},
- {"CurrentUtcDate", &Now0Arg<&ToDate>},
- {"CurrentUtcDatetime", &Now0Arg<&ToDatetime>},
- {"CurrentUtcTimestamp", &Now0Arg<&ToTimestamp>}
- };
-
- TPeepHoleRules()
- : CommonStageRules(CommonStageRulesInit)
- , FinalStageRules(FinalStageRulesInit)
+ {"BuildTablePath", &DoBuildTablePath},
+ {"Exists", &OptimizeExists},
+ {"SqueezeToDict", &OptimizeSqueezeToDict}
+ };
+
+ static constexpr std::initializer_list<TNonDeterministicOptimizerMap::value_type> FinalStageNonDetRulesInit = {
+ {"Random", &Random0Arg<double>},
+ {"RandomNumber", &Random0Arg<ui64>},
+ {"RandomUuid", &Random0Arg<TGUID>},
+ {"Now", &Now0Arg<nullptr>},
+ {"CurrentUtcDate", &Now0Arg<&ToDate>},
+ {"CurrentUtcDatetime", &Now0Arg<&ToDatetime>},
+ {"CurrentUtcTimestamp", &Now0Arg<&ToTimestamp>}
+ };
+
+ TPeepHoleRules()
+ : CommonStageRules(CommonStageRulesInit)
+ , FinalStageRules(FinalStageRulesInit)
, SimplifyStageRules(SimplifyStageRulesInit)
- , FinalStageNonDetRules(FinalStageNonDetRulesInit)
- {}
-
- static const TPeepHoleRules& Instance() {
- return *Singleton<TPeepHoleRules>();
- }
-
- const TPeepHoleOptimizerMap CommonStageRules;
- const TPeepHoleOptimizerMap FinalStageRules;
+ , FinalStageNonDetRules(FinalStageNonDetRulesInit)
+ {}
+
+ static const TPeepHoleRules& Instance() {
+ return *Singleton<TPeepHoleRules>();
+ }
+
+ const TPeepHoleOptimizerMap CommonStageRules;
+ const TPeepHoleOptimizerMap FinalStageRules;
const TPeepHoleOptimizerMap SimplifyStageRules;
- const TNonDeterministicOptimizerMap FinalStageNonDetRules;
-};
-
-template <bool EnableNewOptimizers>
-THolder<IGraphTransformer> CreatePeepHoleCommonStageTransformer(TTypeAnnotationContext& types,
+ const TNonDeterministicOptimizerMap FinalStageNonDetRules;
+};
+
+template <bool EnableNewOptimizers>
+THolder<IGraphTransformer> CreatePeepHoleCommonStageTransformer(TTypeAnnotationContext& types,
IGraphTransformer* typeAnnotator, const TPeepholeSettings& peepholeSettings)
{
- TTransformationPipeline pipeline(&types);
+ TTransformationPipeline pipeline(&types);
if (peepholeSettings.CommonConfig) {
peepholeSettings.CommonConfig->AfterCreate(&pipeline);
}
- AddStandardTransformers(pipeline, typeAnnotator);
+ AddStandardTransformers(pipeline, typeAnnotator);
if (peepholeSettings.CommonConfig) {
peepholeSettings.CommonConfig->AfterTypeAnnotation(&pipeline);
}
auto issueCode = TIssuesIds::CORE_EXEC;
- pipeline.AddCommonOptimization(issueCode);
- pipeline.Add(CreateFunctorTransformer(
- [&types](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- return PeepHoleCommonStage(input, output, ctx, types, TPeepHoleRules<EnableNewOptimizers>::Instance().CommonStageRules);
+ pipeline.AddCommonOptimization(issueCode);
+ pipeline.Add(CreateFunctorTransformer(
+ [&types](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ return PeepHoleCommonStage(input, output, ctx, types, TPeepHoleRules<EnableNewOptimizers>::Instance().CommonStageRules);
}
),
"PeepHoleCommon",
- issueCode);
+ issueCode);
if (peepholeSettings.CommonConfig) {
peepholeSettings.CommonConfig->AfterOptimize(&pipeline);
}
- return pipeline.BuildWithNoArgChecks(false);
+ return pipeline.BuildWithNoArgChecks(false);
}
-template <bool EnableNewOptimizers>
-THolder<IGraphTransformer> CreatePeepHoleFinalStageTransformer(TTypeAnnotationContext& types,
+template <bool EnableNewOptimizers>
+THolder<IGraphTransformer> CreatePeepHoleFinalStageTransformer(TTypeAnnotationContext& types,
IGraphTransformer* typeAnnotator,
bool* hasNonDeterministicFunctions,
const TPeepholeSettings& peepholeSettings)
{
- TTransformationPipeline pipeline(&types);
+ TTransformationPipeline pipeline(&types);
if (peepholeSettings.FinalConfig) {
peepholeSettings.FinalConfig->AfterCreate(&pipeline);
}
- AddStandardTransformers(pipeline, typeAnnotator);
+ AddStandardTransformers(pipeline, typeAnnotator);
if (peepholeSettings.FinalConfig) {
peepholeSettings.FinalConfig->AfterTypeAnnotation(&pipeline);
}
auto issueCode = TIssuesIds::CORE_EXEC;
- pipeline.Add(
+ pipeline.Add(
CreateFunctorTransformer(
[&types, hasNonDeterministicFunctions, withFinalRules = peepholeSettings.WithFinalStageRules,
withNonDeterministicRules = peepholeSettings.WithNonDeterministicRules](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
@@ -5911,13 +5911,13 @@ THolder<IGraphTransformer> CreatePeepHoleFinalStageTransformer(TTypeAnnotationCo
}
),
"PeepHoleFinal",
- issueCode);
+ issueCode);
if (peepholeSettings.FinalConfig) {
peepholeSettings.FinalConfig->AfterOptimize(&pipeline);
}
- return pipeline.BuildWithNoArgChecks(false);
+ return pipeline.BuildWithNoArgChecks(false);
}
}
@@ -5927,9 +5927,9 @@ IGraphTransformer::TStatus DoPeepHoleOptimizeNode(const TExprNode::TPtr& input,
{
output = input;
- for (bool isFinal = false;;) {
- const auto status = InstantTransform(isFinal ? finalTransformer : commonTransformer, output, ctx, input->IsLambda());
- if (status == IGraphTransformer::TStatus::Error || (status.HasRestart && input->IsLambda())) {
+ for (bool isFinal = false;;) {
+ const auto status = InstantTransform(isFinal ? finalTransformer : commonTransformer, output, ctx, input->IsLambda());
+ if (status == IGraphTransformer::TStatus::Error || (status.HasRestart && input->IsLambda())) {
return status;
}
if (status == IGraphTransformer::TStatus::Ok) {
@@ -5943,7 +5943,7 @@ IGraphTransformer::TStatus DoPeepHoleOptimizeNode(const TExprNode::TPtr& input,
return IGraphTransformer::TStatus::Ok;
}
-template <bool EnableNewOptimizers>
+template <bool EnableNewOptimizers>
IGraphTransformer::TStatus PeepHoleOptimizeNode(const TExprNode::TPtr& input, TExprNode::TPtr& output,
TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
bool& hasNonDeterministicFunctions, const TPeepholeSettings& peepholeSettings)
@@ -5955,22 +5955,22 @@ IGraphTransformer::TStatus PeepHoleOptimizeNode(const TExprNode::TPtr& input, TE
return DoPeepHoleOptimizeNode(input, output, ctx, *commonTransformer, *finalTransformer);
}
-THolder<IGraphTransformer> MakePeepholeOptimization(TTypeAnnotationContextPtr typeAnnotationContext, const IPipelineConfigurator* config) {
+THolder<IGraphTransformer> MakePeepholeOptimization(TTypeAnnotationContextPtr typeAnnotationContext, const IPipelineConfigurator* config) {
TPeepholeSettings peepholeSettings;
peepholeSettings.CommonConfig = peepholeSettings.FinalConfig = config;
auto commonTransformer = CreatePeepHoleCommonStageTransformer<true>(*typeAnnotationContext, nullptr, peepholeSettings);
auto finalTransformer = CreatePeepHoleFinalStageTransformer<true>(*typeAnnotationContext, nullptr, nullptr, peepholeSettings);
return CreateFunctorTransformer(
- [common = std::move(commonTransformer), final = std::move(finalTransformer)](TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
- return DoPeepHoleOptimizeNode(input, output, ctx, *common, *final);
+ [common = std::move(commonTransformer), final = std::move(finalTransformer)](TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
+ return DoPeepHoleOptimizeNode(input, output, ctx, *common, *final);
});
}
-template IGraphTransformer::TStatus PeepHoleOptimizeNode<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output,
- TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
+template IGraphTransformer::TStatus PeepHoleOptimizeNode<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output,
+ TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
bool& hasNonDeterministicFunctions, const TPeepholeSettings& peepholeSettings);
-
-template IGraphTransformer::TStatus PeepHoleOptimizeNode<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output,
- TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
+
+template IGraphTransformer::TStatus PeepHoleOptimizeNode<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output,
+ TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
bool& hasNonDeterministicFunctions, const TPeepholeSettings& peepholeSettings);
}
diff --git a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.h b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.h
index 059952adb8..a357c5b395 100644
--- a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.h
+++ b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.h
@@ -14,11 +14,11 @@ struct TPeepholeSettings {
bool WithNonDeterministicRules = true;
};
-template <bool EnableNewOptimizers>
+template <bool EnableNewOptimizers>
IGraphTransformer::TStatus PeepHoleOptimizeNode(const TExprNode::TPtr& input, TExprNode::TPtr& output,
TExprContext& ctx, TTypeAnnotationContext& types, IGraphTransformer* typeAnnotator,
bool& hasNonDeterministicFunctions, const TPeepholeSettings& peepholeSettings = {});
-THolder<IGraphTransformer> MakePeepholeOptimization(TTypeAnnotationContextPtr typeAnnotationContext, const IPipelineConfigurator* config = nullptr);
+THolder<IGraphTransformer> MakePeepholeOptimization(TTypeAnnotationContextPtr typeAnnotationContext, const IPipelineConfigurator* config = nullptr);
}
diff --git a/ydb/library/yql/core/services/yql_eval_expr.cpp b/ydb/library/yql/core/services/yql_eval_expr.cpp
index a424133e19..811f22a605 100644
--- a/ydb/library/yql/core/services/yql_eval_expr.cpp
+++ b/ydb/library/yql/core/services/yql_eval_expr.cpp
@@ -482,7 +482,7 @@ IGraphTransformer::TStatus EvaluateExpression(const TExprNode::TPtr& input, TExp
return IGraphTransformer::TStatus::Ok;
}), "CheckPure", EYqlIssueCode::TIssuesIds_EIssueCode_DEFAULT_ERROR, "Ensure expression is computable");
- pipeline.Add(MakePeepholeOptimization(&types), "PeepHole", EYqlIssueCode::TIssuesIds_EIssueCode_DEFAULT_ERROR, "Peephole optimizations");
+ pipeline.Add(MakePeepholeOptimization(&types), "PeepHole", EYqlIssueCode::TIssuesIds_EIssueCode_DEFAULT_ERROR, "Peephole optimizations");
auto fullTransformer = pipeline.Build();
@@ -835,7 +835,7 @@ IGraphTransformer::TStatus EvaluateExpression(const TExprNode::TPtr& input, TExp
return nullptr;
}
- keys.push_back(ctx.ReplaceNode(TExprNode::TPtr(eachKey), *list, std::move(name)));
+ keys.push_back(ctx.ReplaceNode(TExprNode::TPtr(eachKey), *list, std::move(name)));
}
}
@@ -895,7 +895,7 @@ IGraphTransformer::TStatus EvaluateExpression(const TExprNode::TPtr& input, TExp
externalWorldReplaces.emplace(x.first, ctx.NewWorld(x.first->Pos()));
}
- newArg = ctx.ReplaceNodes(std::move(newArg), externalWorldReplaces);
+ newArg = ctx.ReplaceNodes(std::move(newArg), externalWorldReplaces);
TExprNode::TPtr clonedArg;
{
TNodeOnNodeOwnedMap deepClones;
@@ -1067,7 +1067,7 @@ IGraphTransformer::TStatus EvaluateExpression(const TExprNode::TPtr& input, TExp
return true;
});
- result = ctx.ReplaceNodes(std::move(result), replaces);
+ result = ctx.ReplaceNodes(std::move(result), replaces);
ctx.Step.Repeat(TExprStep::ExpandApplyForLambdas);
hasPendingEvaluations = hasPendingEvaluations.Combine(IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true));
return result;
diff --git a/ydb/library/yql/core/services/yql_plan.cpp b/ydb/library/yql/core/services/yql_plan.cpp
index 8173643b30..4d7cfffaf5 100644
--- a/ydb/library/yql/core/services/yql_plan.cpp
+++ b/ydb/library/yql/core/services/yql_plan.cpp
@@ -100,8 +100,8 @@ struct TProviderInfo {
ui32 Id;
const TExprNode* Node;
IDataProvider* Provider;
- TNodeMap<ui32> Pin;
- std::vector<const TExprNode*> PinOrder;
+ TNodeMap<ui32> Pin;
+ std::vector<const TExprNode*> PinOrder;
TProviderInfo(ui32 id, const TExprNode* node, IDataProvider* provider)
: Id(id)
@@ -129,7 +129,7 @@ void WriteProviders(const TString& tag, const TProviderInfoMap& providers, NYson
writer.OnListItem();
writer.OnBeginMap();
writer.OnKeyedItem("Id");
- writer.OnUint64Scalar(p.second.Pin.find(pin)->second);
+ writer.OnUint64Scalar(p.second.Pin.find(pin)->second);
p.second.Provider->GetPlanFormatter().WritePinDetails(*pin, writer);
writer.OnEndMap();
}
@@ -189,7 +189,7 @@ public:
return;
}
- TNodeMap<TNodeInfo> nodes;
+ TNodeMap<TNodeInfo> nodes;
TExprNode::TListType order;
TProviderInfoMap providers;
@@ -204,7 +204,7 @@ public:
TVector<TBasicLink> basicLinks;
TMap<TString, ui32> opStats;
for (auto node : order) {
- auto& info = nodes.find(node.Get())->second;
+ auto& info = nodes.find(node.Get())->second;
if (!info.IsVisible) {
continue;
}
@@ -331,7 +331,7 @@ public:
}
void VisitCallable(const TExprNode::TPtr& node, TNodeMap<TNodeInfo>& nodes, TExprNode::TListType& order) {
- if (nodes.cend() != nodes.find(node.Get())) {
+ if (nodes.cend() != nodes.find(node.Get())) {
return;
}
@@ -340,25 +340,25 @@ public:
translatedId = ++NextId_;
}
- auto& info = nodes.emplace(node.Get(), TNodeInfo(translatedId, node.Get())).first->second;
+ auto& info = nodes.emplace(node.Get(), TNodeInfo(translatedId, node.Get())).first->second;
TExprNode::TListType& dependencies = info.Dependencies;
- if (node->Content() == CommitName) {
- dependencies.push_back(node->Child(0));
- auto dataSinkName = node->Child(1)->Child(0)->Content();
+ if (node->Content() == CommitName) {
+ dependencies.push_back(node->Child(0));
+ auto dataSinkName = node->Child(1)->Child(0)->Content();
auto datasink = Types_.DataSinkMap.FindPtr(dataSinkName);
YQL_ENSURE(datasink);
info.Provider = (*datasink).Get();
info.IsVisible = dataSinkName != ResultProviderName;
}
else if (node->ChildrenSize() >= 2 && node->Child(1)->IsCallable("DataSource")) {
- auto dataSourceName = node->Child(1)->Child(0)->Content();
+ auto dataSourceName = node->Child(1)->Child(0)->Content();
auto datasource = Types_.DataSourceMap.FindPtr(dataSourceName);
YQL_ENSURE(datasource);
info.Provider = (*datasource).Get();
info.IsVisible = (*datasource)->GetPlanFormatter().GetDependencies(*node, dependencies, true);
}
else if (node->ChildrenSize() >= 2 && node->Child(1)->IsCallable("DataSink")) {
- auto dataSinkName = node->Child(1)->Child(0)->Content();
+ auto dataSinkName = node->Child(1)->Child(0)->Content();
auto datasink = Types_.DataSinkMap.FindPtr(dataSinkName);
YQL_ENSURE(datasink);
info.Provider = (*datasink).Get();
@@ -379,16 +379,16 @@ public:
}
}
- for (const auto& child : dependencies) {
- VisitNode(child, nodes, order);
+ for (const auto& child : dependencies) {
+ VisitNode(child, nodes, order);
}
- order.push_back(node);
+ order.push_back(node);
}
- void VisitNode(const TExprNode::TPtr& node, TNodeMap<TNodeInfo>& nodes,
+ void VisitNode(const TExprNode::TPtr& node, TNodeMap<TNodeInfo>& nodes,
TExprNode::TListType& order) {
- switch (node->Type()) {
+ switch (node->Type()) {
case TExprNode::Atom:
case TExprNode::List:
case TExprNode::World:
@@ -404,16 +404,16 @@ public:
void GatherDependencies(const TExprNode& node,
const TNodeMap<TNodeInfo>& nodes, TSet<ui64>& dependsOn) {
- const auto info = nodes.find(&node);
- if (nodes.cend() == info)
+ const auto info = nodes.find(&node);
+ if (nodes.cend() == info)
return;
- if (info->second.IsVisible) {
- dependsOn.insert(info->second.NodeId);
+ if (info->second.IsVisible) {
+ dependsOn.insert(info->second.NodeId);
return;
}
- for (auto child : info->second.Dependencies) {
+ for (auto child : info->second.Dependencies) {
GatherDependencies(*child, nodes, dependsOn);
}
}
@@ -424,7 +424,7 @@ public:
THashMap<TPinKey, ui32, TPinKey::THash> allInputs;
THashMap<TPinKey, ui32, TPinKey::THash> allOutputs;
for (auto node : order) {
- auto& info = nodes.find(node.Get())->second;
+ auto& info = nodes.find(node.Get())->second;
if (!info.IsVisible) {
continue;
}
@@ -481,7 +481,7 @@ public:
}
for (auto node : order) {
- auto& info = nodes.find(node.Get())->second;
+ auto& info = nodes.find(node.Get())->second;
if (!info.IsVisible) {
continue;
}
diff --git a/ydb/library/yql/core/services/yql_transform_pipeline.cpp b/ydb/library/yql/core/services/yql_transform_pipeline.cpp
index 7e43259a7f..ae425f34c8 100644
--- a/ydb/library/yql/core/services/yql_transform_pipeline.cpp
+++ b/ydb/library/yql/core/services/yql_transform_pipeline.cpp
@@ -70,7 +70,7 @@ TTransformationPipeline& TTransformationPipeline::AddPreTypeAnnotation(EYqlIssue
Transformers_.push_back(TTransformStage(CreateFunctorTransformer(&ExpandApply), "ExpandApply",
issueCode));
Transformers_.push_back(TTransformStage(CreateFunctorTransformer(
- [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
return ValidateProviders(input, output, ctx, typeCtx);
}), "ValidateProviders", issueCode));
@@ -96,7 +96,7 @@ TTransformationPipeline& TTransformationPipeline::AddIOAnnotation(EYqlIssueCode
auto& typeCtx = *TypeAnnotationContext_;
Transformers_.push_back(TTransformStage(CreateFunctorTransformer(
- [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
return RewriteIO(input, output, typeCtx, ctx);
}), "RewriteIO", issueCode));
@@ -116,14 +116,14 @@ TTransformationPipeline& TTransformationPipeline::AddPostTypeAnnotation(bool for
CreateConstraintTransformer(*TypeAnnotationContext_, false, forSubGraph), "Constraints", issueCode));
Transformers_.push_back(TTransformStage(
CreateFunctorTransformer(
- [](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- return UpdateCompletness(input, output, ctx);
- }
- ),
- "UpdateCompletness",
- issueCode));
- Transformers_.push_back(TTransformStage(
- CreateFunctorTransformer(
+ [](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ return UpdateCompletness(input, output, ctx);
+ }
+ ),
+ "UpdateCompletness",
+ issueCode));
+ Transformers_.push_back(TTransformStage(
+ CreateFunctorTransformer(
[forSubGraph, coStore = TypeAnnotationContext_->ColumnOrderStorage](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
return EliminateCommonSubExpressions(input, output, ctx, forSubGraph, *coStore);
}
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 fa5ce8c6d0..5846e6cb10 100644
--- a/ydb/library/yql/core/type_ann/type_ann_core.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp
@@ -3,7 +3,7 @@
#include "type_ann_impl.h"
#include "type_ann_list.h"
#include "type_ann_columnorder.h"
-#include "type_ann_wide.h"
+#include "type_ann_wide.h"
#include "type_ann_types.h"
#include <ydb/library/yql/core/yql_atom_enums.h>
@@ -59,22 +59,22 @@ namespace NTypeAnnImpl {
if (atomNode.Content().size() != NKikimr::NUdf::GetDataTypeInfo(slot).FixedSize) {
isValid = false;
} else {
- const auto data = *reinterpret_cast<const T*>(atomNode.Content().data());
+ const auto data = *reinterpret_cast<const T*>(atomNode.Content().data());
isValid = NKikimr::NMiniKQL::IsValidValue(slot, NKikimr::NUdf::TUnboxedValuePod(data));
if (isValid) {
plainValue = ToString(data);
}
}
} else {
- isValid = NKikimr::NMiniKQL::IsValidStringValue(slot, atomNode.Content());
- if (!isValid) {
- if (slot == NKikimr::NUdf::EDataSlot::Bool) {
+ isValid = NKikimr::NMiniKQL::IsValidStringValue(slot, atomNode.Content());
+ if (!isValid) {
+ if (slot == NKikimr::NUdf::EDataSlot::Bool) {
isValid = (atomNode.Content() == TStringBuf("0")) || (atomNode.Content() == TStringBuf("1"));
- } else if (NKikimr::NUdf::GetDataTypeInfo(slot).Features &
- (NKikimr::NUdf::EDataTypeFeatures::DateType | NKikimr::NUdf::EDataTypeFeatures::TimeIntervalType)) {
- T data;
- isValid = TryFromString(atomNode.Content(), data)
- && NKikimr::NMiniKQL::IsValidValue(slot, NKikimr::NUdf::TUnboxedValuePod(data));
+ } else if (NKikimr::NUdf::GetDataTypeInfo(slot).Features &
+ (NKikimr::NUdf::EDataTypeFeatures::DateType | NKikimr::NUdf::EDataTypeFeatures::TimeIntervalType)) {
+ T data;
+ isValid = TryFromString(atomNode.Content(), data)
+ && NKikimr::NMiniKQL::IsValidValue(slot, NKikimr::NUdf::TUnboxedValuePod(data));
}
}
@@ -155,13 +155,13 @@ namespace NTypeAnnImpl {
return isValid;
}
- // TODO: Use ExpandType
+ // TODO: Use ExpandType
TExprNode::TPtr MakeNothingData(TExprContext& ctx, TPositionHandle pos, TStringBuf data) {
return ctx.Builder(pos)
.Callable("Nothing")
.Callable(0, "OptionalType")
.Callable(0, "DataType")
- .Atom(0, data, TNodeFlags::Default)
+ .Atom(0, data, TNodeFlags::Default)
.Seal()
.Seal()
.Seal()
@@ -234,7 +234,7 @@ namespace NTypeAnnImpl {
TVector<const TTypeAnnotationNode*> typeItems;
ui32 index = 0;
for (const auto& x : tupleType->GetItems()) {
- auto name = ctx.NewAtom(input->Pos(), ToString(index), TNodeFlags::Default);
+ auto name = ctx.NewAtom(input->Pos(), ToString(index), TNodeFlags::Default);
auto item = MakeRepr(ctx.NewCallable(input->Pos(), "Nth", { input, name }), x, ctx);
if (!item.first) {
return { nullptr, nullptr };
@@ -264,8 +264,8 @@ namespace NTypeAnnImpl {
case ETypeAnnotationKind::Dict: {
auto dictType = type->Cast<TDictExprType>();
auto arg = ctx.NewArgument(input->Pos(), "x");
- auto tuple0 = ctx.NewCallable(input->Pos(), "Nth", { arg, ctx.NewAtom(input->Pos(), "0", TNodeFlags::Default) });
- auto tuple1 = ctx.NewCallable(input->Pos(), "Nth", { arg, ctx.NewAtom(input->Pos(), "1", TNodeFlags::Default) });
+ auto tuple0 = ctx.NewCallable(input->Pos(), "Nth", { arg, ctx.NewAtom(input->Pos(), "0", TNodeFlags::Default) });
+ auto tuple1 = ctx.NewCallable(input->Pos(), "Nth", { arg, ctx.NewAtom(input->Pos(), "1", TNodeFlags::Default) });
auto inner = MakeRepr(tuple1, dictType->GetPayloadType(), ctx);
if (!inner.first) {
return { nullptr, nullptr };
@@ -284,19 +284,19 @@ namespace NTypeAnnImpl {
.Param("x")
.Callable("Nth")
.Arg(0, "x")
- .Atom(1, "0", TNodeFlags::Default)
+ .Atom(1, "0", TNodeFlags::Default)
.Seal()
.Seal()
.Lambda(2)
.Param("x")
.Callable("Nth")
.Arg(0, "x")
- .Atom(1, "1", TNodeFlags::Default)
+ .Atom(1, "1", TNodeFlags::Default)
.Seal()
.Seal()
.List(3)
- .Atom(0, "One", TNodeFlags::Default)
- .Atom(1, "Hashed", TNodeFlags::Default)
+ .Atom(0, "One", TNodeFlags::Default)
+ .Atom(1, "Hashed", TNodeFlags::Default)
.Seal()
.Seal()
.Build(), ctx.MakeType<TDictExprType>(dictType->GetKeyType(), inner.second) };
@@ -304,22 +304,22 @@ namespace NTypeAnnImpl {
case ETypeAnnotationKind::Resource: {
auto resType = type->Cast<TResourceExprType>();
- if (resType->GetTag() == "Yson2.Node") {
- return { ctx.Builder(input->Pos())
- .Callable("Apply")
- .Callable(0, "Udf")
- .Atom(0, "Yson2.Serialize", TNodeFlags::Default)
- .Seal()
- .Add(1, input)
- .Seal()
- .Build(), ctx.MakeType<TDataExprType>(EDataSlot::Yson) };
- }
-
+ if (resType->GetTag() == "Yson2.Node") {
+ return { ctx.Builder(input->Pos())
+ .Callable("Apply")
+ .Callable(0, "Udf")
+ .Atom(0, "Yson2.Serialize", TNodeFlags::Default)
+ .Seal()
+ .Add(1, input)
+ .Seal()
+ .Build(), ctx.MakeType<TDataExprType>(EDataSlot::Yson) };
+ }
+
if (resType->GetTag() == "Yson.Node") {
return { ctx.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, "Yson.Serialize", TNodeFlags::Default)
+ .Atom(0, "Yson.Serialize", TNodeFlags::Default)
.Seal()
.Add(1, input)
.Seal()
@@ -330,7 +330,7 @@ namespace NTypeAnnImpl {
return { ctx.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, "DateTime2.MakeTzTimestamp", TNodeFlags::Default)
+ .Atom(0, "DateTime2.MakeTzTimestamp", TNodeFlags::Default)
.Seal()
.Add(1, input)
.Seal()
@@ -341,7 +341,7 @@ namespace NTypeAnnImpl {
return { ctx.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, "Json2.Serialize", TNodeFlags::Default)
+ .Atom(0, "Json2.Serialize", TNodeFlags::Default)
.Seal()
.Add(1, input)
.Seal()
@@ -511,10 +511,10 @@ namespace NTypeAnnImpl {
return true;
}
- typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TContext& ctx)>
+ typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TContext& ctx)>
TAnnotationFunc;
- typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TExtContext& ctx)>
+ typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TExtContext& ctx)>
TExtendedAnnotationFunc;
struct TSyncFunctionsMap {
@@ -531,7 +531,7 @@ namespace NTypeAnnImpl {
}
};
- IGraphTransformer::TStatus DataSourceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DataSourceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
input->SetTypeAnn(ctx.Expr.MakeType<TUnitExprType>());
return IGraphTransformer::TStatus::Ok;
@@ -550,8 +550,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureDataType(input->Head().Pos(), *type, ctx.Expr)) {
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureDataType(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -559,163 +559,163 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus DataConstructorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (input->Content() == "Decimal") {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus DataConstructorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (input->Content() == "Decimal") {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
- if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
+
+ if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!NYql::NDecimal::IsValid(input->Head().Content())) {
+ if (!NYql::NDecimal::IsValid(input->Head().Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
<< input->Content() << ", value: " << TString{input->Head().Content()}.Quote()));
-
+
return IGraphTransformer::TStatus::Error;
}
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprParamsType>(EDataSlot::Decimal, input->Child(1)->Content(), input->Child(2)->Content()));
if (!input->GetTypeAnn()->Cast<TDataExprParamsType>()->Validate(input->Pos(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- return IGraphTransformer::TStatus::Ok;
- } else {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ return IGraphTransformer::TStatus::Ok;
+ } else {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
TMaybe<TString> textValue;
- if (input->Content() == "Bool") {
- if (!IsValidSmallData<bool>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Bool, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Uint8") {
- if (!IsValidSmallData<ui8>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint8, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Int8") {
- if (!IsValidSmallData<i8>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int8, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Int16") {
- if (!IsValidSmallData<i16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int16, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Uint16") {
- if (!IsValidSmallData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint16, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Int32") {
- if (!IsValidSmallData<i32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int32, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Uint32") {
- if (!IsValidSmallData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint32, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Int64") {
- if (!IsValidSmallData<i64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int64, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Uint64") {
- if (!IsValidSmallData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint64, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Float") {
- if (!IsValidSmallData<float>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Float, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Double") {
- if (!IsValidSmallData<double>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Double, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Yson") {
- if (!NDom::IsValidYson(input->Head().Content())) {
+ if (input->Content() == "Bool") {
+ if (!IsValidSmallData<bool>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Bool, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Uint8") {
+ if (!IsValidSmallData<ui8>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint8, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Int8") {
+ if (!IsValidSmallData<i8>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int8, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Int16") {
+ if (!IsValidSmallData<i16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int16, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Uint16") {
+ if (!IsValidSmallData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint16, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Int32") {
+ if (!IsValidSmallData<i32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int32, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Uint32") {
+ if (!IsValidSmallData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint32, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Int64") {
+ if (!IsValidSmallData<i64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Int64, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Uint64") {
+ if (!IsValidSmallData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Uint64, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Float") {
+ if (!IsValidSmallData<float>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Float, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Double") {
+ if (!IsValidSmallData<double>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Double, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Yson") {
+ if (!NDom::IsValidYson(input->Head().Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
- << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
-
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Json") {
- if (!NDom::IsValidJson(input->Head().Content())) {
+ << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Json") {
+ if (!NDom::IsValidJson(input->Head().Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
- << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
-
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Utf8") {
- if (!IsUtf8(input->Head().Content())) {
+ << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Utf8") {
+ if (!IsUtf8(input->Head().Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
- << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
-
- return IGraphTransformer::TStatus::Error;
- }
- }
- else if (input->Content() == "String") {
- // nothing to do
- }
- else if (input->Content() == "Date") {
- if (!IsValidSmallData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Date, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
- else if (input->Content() == "Datetime") {
- if (!IsValidSmallData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Datetime, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
- else if (input->Content() == "Timestamp") {
- if (!IsValidSmallData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Timestamp, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Interval") {
- if (!IsValidSmallData<i64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Interval, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "TzDate") {
- if (!IsValidTzData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Date, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "TzDatetime") {
- if (!IsValidTzData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Datetime, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "TzTimestamp") {
- if (!IsValidTzData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Timestamp, textValue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else if (input->Content() == "Uuid") {
- if (input->Head().Content().size() != 16) {
+ << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+ else if (input->Content() == "String") {
+ // nothing to do
+ }
+ else if (input->Content() == "Date") {
+ if (!IsValidSmallData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Date, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+ else if (input->Content() == "Datetime") {
+ if (!IsValidSmallData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Datetime, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+ else if (input->Content() == "Timestamp") {
+ if (!IsValidSmallData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Timestamp, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Interval") {
+ if (!IsValidSmallData<i64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Interval, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "TzDate") {
+ if (!IsValidTzData<ui16>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Date, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "TzDatetime") {
+ if (!IsValidTzData<ui32>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Datetime, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "TzTimestamp") {
+ if (!IsValidTzData<ui64>(input->Head(), input->Content(), ctx.Expr, NKikimr::NUdf::EDataSlot::Timestamp, textValue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (input->Content() == "Uuid") {
+ if (input->Head().Content().size() != 16) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
- << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
-
- return IGraphTransformer::TStatus::Error;
- }
+ << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
} else if (input->Content() == "JsonDocument") {
// check will be performed in JsonDocument callable
- } else if (input->Content() == "DyNumber") {
- if (!NKikimr::NMiniKQL::IsValidStringValue(EDataSlot::DyNumber, input->Head().Content())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
- << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
-
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- ythrow yexception() << "Unknown data type: " << input->Content();
+ } else if (input->Content() == "DyNumber") {
+ if (!NKikimr::NMiniKQL::IsValidStringValue(EDataSlot::DyNumber, input->Head().Content())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Bad atom format for type: "
+ << input->Content() << ", value: " << TString(input->Head().Content()).Quote()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ ythrow yexception() << "Unknown data type: " << input->Content();
}
if (textValue) {
@@ -729,20 +729,20 @@ namespace NTypeAnnImpl {
}
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(NKikimr::NUdf::GetDataSlot(input->Content())));
- return IGraphTransformer::TStatus::Ok;
+ return IGraphTransformer::TStatus::Ok;
}
}
- IGraphTransformer::TStatus KeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus KeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureTuple(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (child->ChildrenSize() != 1 && child->ChildrenSize() != 2) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected tuple of size 1 or 2, but got: " <<
- input->ChildrenSize()));
+ input->ChildrenSize()));
return IGraphTransformer::TStatus::Error;
}
@@ -767,17 +767,17 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus LeftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus LeftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTupleTypeSize(input->Head(), 2, ctx.Expr)) {
+ if (!EnsureTupleTypeSize(input->Head(), 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto worldType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[0];
+ auto worldType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[0];
if (worldType->GetKind() != ETypeAnnotationKind::World) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected world type as type of first tuple element, but got: "
<< *worldType));
@@ -788,24 +788,24 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus RightWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus RightWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTupleTypeSize(input->Head(), 2, ctx.Expr)) {
+ if (!EnsureTupleTypeSize(input->Head(), 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto worldType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[0];
+ auto worldType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[0];
if (worldType->GetKind() != ETypeAnnotationKind::World) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected world type as type of first tuple element, but got: "
<< *worldType));
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[1]);
+ input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems()[1]);
return IGraphTransformer::TStatus::Ok;
}
@@ -815,18 +815,18 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureWorldType(input->Head(), ctx.Expr)) {
+ if (!EnsureWorldType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
input->SetTypeAnn(ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
- input->Head().GetTypeAnn(),
- input->Tail().GetTypeAnn()
+ input->Head().GetTypeAnn(),
+ input->Tail().GetTypeAnn()
}));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DataSinkWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DataSinkWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
input->SetTypeAnn(ctx.Expr.MakeType<TUnitExprType>());
return IGraphTransformer::TStatus::Ok;
@@ -865,21 +865,21 @@ namespace NTypeAnnImpl {
return result;
}
- IGraphTransformer::TStatus MemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus MemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
const TStructExprType* structType;
bool isOptional;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -887,26 +887,26 @@ namespace NTypeAnnImpl {
isOptional = true;
}
else {
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
isOptional = false;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto memberName = input->Tail().Content();
+ auto memberName = input->Tail().Content();
auto pos = FindOrReportMissingMember(memberName, input->Pos(), *structType, ctx);
if (!pos) {
return IGraphTransformer::TStatus::Error;
}
input->SetTypeAnn(structType->GetItems()[*pos]->GetItemType());
- if (isOptional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Null) {
+ if (isOptional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Null) {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->GetTypeAnn()));
}
@@ -918,7 +918,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- auto arg = input->HeadPtr();
+ auto arg = input->HeadPtr();
if (IsNull(*arg)) {
output = arg;
@@ -961,18 +961,18 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
+ if (IsNull(input->Head())) {
if (columnOrType) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
TStringBuilder() << "Expected (optional) struct type, but got Null"));
return IGraphTransformer::TStatus::Error;
}
- output = input->HeadPtr();
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- auto rowNode = input->Child(0);
- const auto columnNameNode = input->Child(1);
+ auto rowNode = input->Child(0);
+ const auto columnNameNode = input->Child(1);
TExprNode::TPtr sourceNameNode;
if (input->ChildrenSize() > 2) {
sourceNameNode = input->ChildPtr(2);
@@ -1051,7 +1051,7 @@ namespace NTypeAnnImpl {
}
output = ctx.Expr.Builder(input->Pos())
.Callable("Member")
- .Add(0, std::move(rowNode))
+ .Add(0, std::move(rowNode))
.Atom(1, structType->GetItems()[*pos]->GetName())
.Seal().Build();
return IGraphTransformer::TStatus::Repeat;
@@ -1094,8 +1094,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TryMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus TryMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1123,17 +1123,17 @@ namespace NTypeAnnImpl {
isStructOptional = false;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto otherType = input->Child(2)->GetTypeAnn();
const bool isOptional = otherType->GetKind() == ETypeAnnotationKind::Optional;
- auto memberName = input->Child(1)->Content();
+ auto memberName = input->Child(1)->Content();
const TTypeAnnotationNode* foundFieldType = otherType;
bool fieldFound = false;
for (auto& field : structType->GetItems()) {
@@ -1168,10 +1168,10 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FlattenMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FlattenMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
TVector<const TItemExprType*> allItems;
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureTupleSize(*child, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1193,7 +1193,7 @@ namespace NTypeAnnImpl {
}
for (auto& field: type->Cast<TStructExprType>()->GetItems()) {
auto itemType = field->GetItemType();
- if (optional && itemType->GetKind() != ETypeAnnotationKind::Optional && itemType->GetKind() != ETypeAnnotationKind::Null) {
+ if (optional && itemType->GetKind() != ETypeAnnotationKind::Optional && itemType->GetKind() != ETypeAnnotationKind::Null) {
itemType = ctx.Expr.MakeType<TOptionalExprType>(itemType);
}
auto newField = ctx.Expr.MakeType<TItemExprType>(
@@ -1219,11 +1219,11 @@ namespace NTypeAnnImpl {
}
TVector<const TItemExprType*> allItems;
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
for (auto& x : structType->GetItems()) {
bool isOptional = false;
auto itemType = x->GetItemType();
@@ -1257,13 +1257,13 @@ namespace NTypeAnnImpl {
}
IGraphTransformer::TStatus NormalizeAtomListForDiveOrSelect(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- YQL_ENSURE(input->IsCallable({"DivePrefixMembers", "SelectMembers", "FilterMembers", "RemovePrefixMembers"}));
+ YQL_ENSURE(input->IsCallable({"DivePrefixMembers", "SelectMembers", "FilterMembers", "RemovePrefixMembers"}));
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto prefixes = input->Child(1);
+ auto prefixes = input->Child(1);
if (!EnsureTuple(*prefixes, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1284,7 +1284,7 @@ namespace NTypeAnnImpl {
output = ctx.Expr.Builder(input->Pos())
.Callable(input->Content())
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Add(1, ctx.Expr.NewList(prefixes->Pos(), std::move(list)))
.Seal()
.Build();
@@ -1295,13 +1295,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- template<bool ByPrefix>
+ template<bool ByPrefix>
IGraphTransformer::TStatus SelectMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto structObj = input->Child(0);
+ auto structObj = input->Child(0);
if (!EnsureStructOrOptionalStructType(*structObj, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1323,7 +1323,7 @@ namespace NTypeAnnImpl {
auto prefixes = input->Child(1);
for (const auto& prefixNode: prefixes->Children()) {
const auto& prefix = prefixNode->Content();
- if (ByPrefix ? fieldName.StartsWith(prefix) : fieldName == prefix) {
+ if (ByPrefix ? fieldName.StartsWith(prefix) : fieldName == prefix) {
allItems.push_back(field);
break;
}
@@ -1389,12 +1389,12 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FlattenByColumns(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FlattenByColumns(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto iter = input->Children().begin();
+ auto iter = input->Children().begin();
TString mode = "auto";
if ((*iter)->IsAtom()) {
mode = (*iter)->Content();
@@ -1416,7 +1416,7 @@ namespace NTypeAnnImpl {
}
TSet<TString> aliases;
TMap<TString, TString> flattenByColumns;
- for (++iter; iter != input->Children().end(); ++iter) {
+ for (++iter; iter != input->Children().end(); ++iter) {
const auto& child = *iter;
TString alias;
const auto& argType = child->Type();
@@ -1424,7 +1424,7 @@ namespace NTypeAnnImpl {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Expected atom or tuple, but got: " << argType));
return IGraphTransformer::TStatus::Error;
}
- TExprNode* columnNameNode = child.Get();
+ TExprNode* columnNameNode = child.Get();
if (argType == TExprNode::List) {
if (!EnsureTupleSize(*child, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1572,7 +1572,7 @@ namespace NTypeAnnImpl {
}
auto resultStruct = ctx.Expr.MakeType<TStructExprType>(allItems);
- if (!resultStruct->Validate(input->Pos(), ctx.Expr)) {
+ if (!resultStruct->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (allFieldOptional) {
@@ -1583,21 +1583,21 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus NthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus NthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
const TTupleExprType* tupleType;
bool isOptional;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1605,21 +1605,21 @@ namespace NTypeAnnImpl {
isOptional = true;
}
else {
- if (!EnsureTupleType(input->Head(), ctx.Expr)) {
+ if (!EnsureTupleType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- tupleType = input->Head().GetTypeAnn()->Cast<TTupleExprType>();
+ tupleType = input->Head().GetTypeAnn()->Cast<TTupleExprType>();
isOptional = false;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
ui32 index = 0;
- if (!TryFromString(input->Tail().Content(), index)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Tail().Content()));
+ if (!TryFromString(input->Tail().Content(), index)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Tail().Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -1629,39 +1629,39 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputableType(input->Head().Pos(), *tupleType, ctx.Expr)) {
+ if (!EnsureComputableType(input->Head().Pos(), *tupleType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
input->SetTypeAnn(tupleType->GetItems()[index]);
- if (isOptional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Null) {
+ if (isOptional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional && input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Null) {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->GetTypeAnn()));
}
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AddMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AddMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto memberName = input->Child(1)->Content();
+ auto memberName = input->Child(1)->Content();
auto newField = ctx.Expr.MakeType<TItemExprType>(memberName, input->Child(2)->GetTypeAnn());
- auto newItems = input->Head().GetTypeAnn()->Cast<TStructExprType>()->GetItems();
+ auto newItems = input->Head().GetTypeAnn()->Cast<TStructExprType>()->GetItems();
newItems.push_back(newField);
input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(newItems));
if (!input->GetTypeAnn()->Cast<TStructExprType>()->Validate(input->Pos(), ctx.Expr)) {
@@ -1672,22 +1672,22 @@ namespace NTypeAnnImpl {
}
template <bool Forced>
- IGraphTransformer::TStatus RemoveMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus RemoveMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
- auto memberName = input->Tail().Content();
+ auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ auto memberName = input->Tail().Content();
TVector<const TItemExprType*> newItems = structType->GetItems();
EraseIf(newItems, [&](const auto& item) { return item->GetName() == memberName; });
@@ -1853,32 +1853,32 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus ReplaceMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ReplaceMemberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto memberName = input->Child(1)->Content();
- auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ auto memberName = input->Child(1)->Content();
+ auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
auto pos = FindOrReportMissingMember(memberName, input->Pos(), *structType, ctx);
if (!pos) {
return IGraphTransformer::TStatus::Error;
}
- auto newItems = input->Head().GetTypeAnn()->Cast<TStructExprType>()->GetItems();
+ auto newItems = input->Head().GetTypeAnn()->Cast<TStructExprType>()->GetItems();
newItems[*pos] = ctx.Expr.MakeType<TItemExprType>(memberName, input->Child(2)->GetTypeAnn());
input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(newItems));
if (!input->GetTypeAnn()->Cast<TStructExprType>()->Validate(input->Pos(), ctx.Expr)) {
@@ -1889,7 +1889,7 @@ namespace NTypeAnnImpl {
}
template <bool Equality>
- IGraphTransformer::TStatus CompareWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CompareWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (input->Content() == "Equal") {
output = ctx.Expr.RenameNode(*input, "==");
return IGraphTransformer::TStatus::Repeat;
@@ -1920,38 +1920,38 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!(EnsurePersistable(input->Head(), ctx.Expr) && EnsurePersistable(input->Tail(), ctx.Expr))) {
+ if (!(EnsurePersistable(input->Head(), ctx.Expr) && EnsurePersistable(input->Tail(), ctx.Expr))) {
return IGraphTransformer::TStatus::Error;
}
- switch (CanCompare<Equality>(input->Head().GetTypeAnn(), input->Tail().GetTypeAnn())) {
- case ECompareOptions::Null:
- output = MakeBoolNothing(input->Pos(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ switch (CanCompare<Equality>(input->Head().GetTypeAnn(), input->Tail().GetTypeAnn())) {
+ case ECompareOptions::Null:
+ output = MakeBoolNothing(input->Pos(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
- case ECompareOptions::Uncomparable:
+ case ECompareOptions::Uncomparable:
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Uncompatible types in compare: " <<
- *input->Head().GetTypeAnn() << " '" << input->Content() << "' " << *input->Tail().GetTypeAnn()));
+ *input->Head().GetTypeAnn() << " '" << input->Content() << "' " << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
- case ECompareOptions::Comparable:
- input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
- break;
-
- case ECompareOptions::Optional:
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
- break;
+ case ECompareOptions::Comparable:
+ input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
+ break;
+
+ case ECompareOptions::Optional:
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
+ break;
}
-
- if (Equality) {
- input->SetUnorderedChildren();
- }
- return IGraphTransformer::TStatus::Ok;
+
+ if (Equality) {
+ input->SetUnorderedChildren();
+ }
+ return IGraphTransformer::TStatus::Ok;
}
IGraphTransformer::TStatus AbsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
@@ -1959,37 +1959,37 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (!(IsDataTypeNumeric(dataType->GetSlot()) || IsDataTypeDecimal(dataType->GetSlot()) || dataType->GetSlot() == EDataSlot::Interval)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected numeric, decimal or interval type, but got: "
- << *input->Head().GetTypeAnn()));
+ << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus MinMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus MinMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (1U == input->ChildrenSize()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (1U == input->ChildrenSize()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
for (ui32 i = 0; i < input->ChildrenSize(); ++i) {
if (IsNull(*input->Child(i))) {
output = input->ChildPtr(i);
@@ -1999,15 +1999,15 @@ namespace NTypeAnnImpl {
bool isOptional1;
const TDataExprType* dataType1;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isSomeOptional = isOptional1;
- for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
+ for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
bool isOptional2;
const TDataExprType* dataType2;
- if (!EnsureDataOrOptionalOfData(*input->Child(index), isOptional2, dataType2, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(*input->Child(index), isOptional2, dataType2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2016,7 +2016,7 @@ namespace NTypeAnnImpl {
const bool isRightNumeric = IsDataTypeNumeric(dataType2->GetSlot());
if (isLeftNumeric != isRightNumeric) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "mismatch of data types: "
- << *input->Head().GetTypeAnn() << " != " << *input->Child(index)->GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << " != " << *input->Child(index)->GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -2028,7 +2028,7 @@ namespace NTypeAnnImpl {
else {
if (!IsSameAnnotation(*dataType1, *dataType2)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "mismatch of data types: "
- << *input->Head().GetTypeAnn() << " != " << *input->Child(index)->GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << " != " << *input->Child(index)->GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
}
@@ -2038,35 +2038,35 @@ namespace NTypeAnnImpl {
if (isSomeOptional) {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->GetTypeAnn()));
}
- input->SetUnorderedChildren();
+ input->SetUnorderedChildren();
return IGraphTransformer::TStatus::Ok;
}
- template <bool Equal, bool Order>
+ template <bool Equal, bool Order>
IGraphTransformer::TStatus AggrCompareWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!(Order ? EnsureComparableType : EnsureEquatableType)(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr)) {
+ if (!(Order ? EnsureComparableType : EnsureEquatableType)(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
+ if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Type mismatch, left: "
- << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- if (IsInstantEqual(*input->Head().GetTypeAnn())) {
- output = MakeBool(input->Pos(), Equal, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsInstantEqual(*input->Head().GetTypeAnn())) {
+ output = MakeBool(input->Pos(), Equal, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
- if (!Order) {
- input->SetUnorderedChildren();
- }
+ if (!Order) {
+ input->SetUnorderedChildren();
+ }
return IGraphTransformer::TStatus::Ok;
}
@@ -2075,23 +2075,23 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComparableType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr)) {
+ if (!EnsureComparableType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
+ if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Type mismatch, left: "
- << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- if (IsInstantEqual(*input->Head().GetTypeAnn())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- input->SetUnorderedChildren();
+ if (IsInstantEqual(*input->Head().GetTypeAnn())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetUnorderedChildren();
return IGraphTransformer::TStatus::Ok;
}
@@ -2117,8 +2117,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AggrAddWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus AggrAddWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2134,36 +2134,36 @@ namespace NTypeAnnImpl {
bool isOptional1;
const TDataExprType* dataType1;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional2;
const TDataExprType* dataType2;
- if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataType2, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataType2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
+ if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Type mismatch, left: "
- << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- const bool isInterval = dataType1->GetSlot() == EDataSlot::Interval;
-
- if (!(IsDataTypeNumeric(dataType1->GetSlot()) || IsDataTypeDecimal(dataType1->GetSlot()) || isInterval)) {
+ const bool isInterval = dataType1->GetSlot() == EDataSlot::Interval;
+
+ if (!(IsDataTypeNumeric(dataType1->GetSlot()) || IsDataTypeDecimal(dataType1->GetSlot()) || isInterval)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected numeric or decimal data type, but got: "
- << *input->Head().GetTypeAnn()));
+ << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- auto resultType = input->Head().GetTypeAnn();
- if (isInterval && !isOptional1) {
- resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
- }
- input->SetTypeAnn(resultType);
+ auto resultType = input->Head().GetTypeAnn();
+ if (isInterval && !isOptional1) {
+ resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
+ }
+ input->SetTypeAnn(resultType);
return IGraphTransformer::TStatus::Ok;
}
@@ -2207,23 +2207,23 @@ namespace NTypeAnnImpl {
commonType = dataType[0];
haveOptional = true;
} else if (IsDataTypeDecimal(dataType[0]->GetSlot()) && IsDataTypeDecimal(dataType[1]->GetSlot())) {
- const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
- const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
-
- if (!(*dataTypeOne == *dataTypeTwo)) {
- ctx.Expr.AddError(TIssue(
+ const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
+ const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
+
+ if (!(*dataTypeOne == *dataTypeTwo)) {
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot add different decimals."
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- commonType = dataType[0];
+ TStringBuilder() << "Cannot add different decimals."
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ commonType = dataType[0];
} else {
ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot add type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ TStringBuilder() << "Cannot add type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
));
return IGraphTransformer::TStatus::Error;
@@ -2271,28 +2271,28 @@ namespace NTypeAnnImpl {
} else if ((IsDataTypeDate(dataType[0]->GetSlot()) || IsDataTypeTzDate(dataType[0]->GetSlot())) &&
(IsDataTypeDate(dataType[1]->GetSlot()) || IsDataTypeTzDate(dataType[1]->GetSlot()))) {
commonType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Interval);
- } else if (IsDataTypeDateOrTzDateOrInterval(dataType[0]->GetSlot()) &&
+ } else if (IsDataTypeDateOrTzDateOrInterval(dataType[0]->GetSlot()) &&
dataType[1]->GetSlot() == EDataSlot::Interval) {
commonType = dataType[0];
haveOptional = true;
} else if (IsDataTypeDecimal(dataType[0]->GetSlot()) && IsDataTypeDecimal(dataType[1]->GetSlot())) {
- const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
- const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
-
- if (!(*dataTypeOne == *dataTypeTwo)) {
- ctx.Expr.AddError(TIssue(
+ const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
+ const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
+
+ if (!(*dataTypeOne == *dataTypeTwo)) {
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot substract different decimals."
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- commonType = dataType[0];
+ TStringBuilder() << "Cannot substract different decimals."
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ commonType = dataType[0];
} else {
ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot substract type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ TStringBuilder() << "Cannot substract type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
));
return IGraphTransformer::TStatus::Error;
@@ -2340,15 +2340,15 @@ namespace NTypeAnnImpl {
commonType = dataType[0];
haveOptional = true;
} else if (IsDataTypeDecimal(dataType[0]->GetSlot()) || IsDataTypeDecimal(dataType[1]->GetSlot())) {
- output = ctx.Expr.RenameNode(*input, "DecimalMul");
+ output = ctx.Expr.RenameNode(*input, "DecimalMul");
if (!IsDataTypeDecimal(dataType[0]->GetSlot())) {
- output->ChildRef(0).Swap(output->ChildRef(1));
- }
- return IGraphTransformer::TStatus::Repeat;
+ output->ChildRef(0).Swap(output->ChildRef(1));
+ }
+ return IGraphTransformer::TStatus::Repeat;
} else {
ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot multiply type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ TStringBuilder() << "Cannot multiply type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
));
return IGraphTransformer::TStatus::Error;
@@ -2396,62 +2396,62 @@ namespace NTypeAnnImpl {
commonType = dataType[0];
haveOptional = true;
} else if (IsDataTypeDecimal(dataType[0]->GetSlot()) && (IsDataTypeDecimal(dataType[1]->GetSlot()) || IsDataTypeIntegral(dataType[1]->GetSlot()))) {
- output = ctx.Expr.RenameNode(*input, "DecimalDiv");
- return IGraphTransformer::TStatus::Repeat;
- } else {
- ctx.Expr.AddError(TIssue(
+ output = ctx.Expr.RenameNode(*input, "DecimalDiv");
+ return IGraphTransformer::TStatus::Repeat;
+ } else {
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot divide type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* resultType = commonType;
- if (haveOptional) {
- resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
- }
-
+ TStringBuilder() << "Cannot divide type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* resultType = commonType;
+ if (haveOptional) {
+ resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
+ }
+
input->SetTypeAnn(resultType);
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus ModWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TDataExprType* dataType[2];
- bool isOptional[2];
- bool haveOptional = false;
- const TDataExprType* commonType = nullptr;
- for (ui32 i = 0; i < 2; ++i) {
- if (IsNull(*input->Child(i))) {
- output = input->ChildPtr(i);
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional[i], dataType[i], ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- haveOptional |= isOptional[i];
- }
-
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus ModWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TDataExprType* dataType[2];
+ bool isOptional[2];
+ bool haveOptional = false;
+ const TDataExprType* commonType = nullptr;
+ for (ui32 i = 0; i < 2; ++i) {
+ if (IsNull(*input->Child(i))) {
+ output = input->ChildPtr(i);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional[i], dataType[i], ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ haveOptional |= isOptional[i];
+ }
+
if (IsDataTypeNumeric(dataType[0]->GetSlot()) && IsDataTypeNumeric(dataType[1]->GetSlot())) {
auto commonTypeSlot = GetNumericDataTypeByLevel(Max(GetNumericDataTypeLevel(dataType[0]->GetSlot()),
GetNumericDataTypeLevel(dataType[1]->GetSlot())));
commonType = ctx.Expr.MakeType<TDataExprType>(commonTypeSlot);
if (!IsDataTypeFloat(commonTypeSlot)) {
- haveOptional = true;
- }
+ haveOptional = true;
+ }
} else if (IsDataTypeDecimal(dataType[0]->GetSlot()) && (IsDataTypeDecimal(dataType[1]->GetSlot()) || IsDataTypeIntegral(dataType[1]->GetSlot()))) {
- output = ctx.Expr.RenameNode(*input, "DecimalMod");
- return IGraphTransformer::TStatus::Repeat;
+ output = ctx.Expr.RenameNode(*input, "DecimalMod");
+ return IGraphTransformer::TStatus::Repeat;
} else {
ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot mod type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ TStringBuilder() << "Cannot mod type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
));
return IGraphTransformer::TStatus::Error;
@@ -2466,143 +2466,143 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DecimalBinaryWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TDataExprType* dataType[2];
- bool isOptional[2];
- bool haveOptional = false;
- const TDataExprType* commonType = nullptr;
- for (ui32 i = 0; i < 2; ++i) {
- if (IsNull(*input->Child(i))) {
- output = input->ChildPtr(i);
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional[i], dataType[i], ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- haveOptional |= isOptional[i];
- }
-
+ IGraphTransformer::TStatus DecimalBinaryWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TDataExprType* dataType[2];
+ bool isOptional[2];
+ bool haveOptional = false;
+ const TDataExprType* commonType = nullptr;
+ for (ui32 i = 0; i < 2; ++i) {
+ if (IsNull(*input->Child(i))) {
+ output = input->ChildPtr(i);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional[i], dataType[i], ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ haveOptional |= isOptional[i];
+ }
+
if (IsDataTypeDecimal(dataType[0]->GetSlot())) {
if (IsDataTypeDecimal(dataType[1]->GetSlot())) {
- const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
- const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
-
- if (!(*dataTypeOne == *dataTypeTwo)) {
- ctx.Expr.AddError(TIssue(
+ const auto dataTypeOne = static_cast<const TDataExprParamsType*>(dataType[0]);
+ const auto dataTypeTwo = static_cast<const TDataExprParamsType*>(dataType[1]);
+
+ if (!(*dataTypeOne == *dataTypeTwo)) {
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot calculate with different decimals."
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
+ TStringBuilder() << "Cannot calculate with different decimals."
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
} else if (!IsDataTypeIntegral(dataType[1]->GetSlot())) {
- ctx.Expr.AddError(TIssue(
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot operate with decimal and " << *input->Tail().GetTypeAnn()
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- commonType = dataType[0];
- } else {
- ctx.Expr.AddError(TIssue(
+ TStringBuilder() << "Cannot operate with decimal and " << *input->Tail().GetTypeAnn()
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ commonType = dataType[0];
+ } else {
+ ctx.Expr.AddError(TIssue(
ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Cannot use type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
- ));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* resultType = commonType;
- if (haveOptional) {
- resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
- }
-
+ TStringBuilder() << "Cannot use type " << *input->Head().GetTypeAnn() << " and " << *input->Tail().GetTypeAnn()
+ ));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* resultType = commonType;
+ if (haveOptional) {
+ resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
+ }
+
input->SetTypeAnn(resultType);
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus CountBitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus CountBitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- bool isOptional;
- const TDataExprType* dataType;
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
+ bool isOptional;
+ const TDataExprType* dataType;
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
- if (!IsDataTypeIntegral(dataType->GetSlot())) {
+ if (!IsDataTypeIntegral(dataType->GetSlot())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected integral data type, but got: "
- << *input->Head().GetTypeAnn()));
-
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* resultType = dataType;
- if (isOptional) {
- resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
- }
-
+ << *input->Head().GetTypeAnn()));
+
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* resultType = dataType;
+ if (isOptional) {
+ resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
+ }
+
input->SetTypeAnn(resultType);
- return IGraphTransformer::TStatus::Ok;
- }
-
- template <bool IncOrDec>
- IGraphTransformer::TStatus IncDecWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- bool isOptional;
- const TDataExprType* dataType;
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ template <bool IncOrDec>
+ IGraphTransformer::TStatus IncDecWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool isOptional;
+ const TDataExprType* dataType;
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
const auto dataSlot = dataType->GetSlot();
- if (IsDataTypeDecimal(dataSlot)) {
- const auto params = static_cast<const TDataExprParamsType*>(dataType);
- if (const auto scale = FromString<ui8>(params->GetParamTwo())) {
- output = ctx.Expr.Builder(input->Pos())
- .Callable(IncOrDec ? "Add" : "Sub")
- .Add(0, input->Child(0))
- .Callable(1, "Decimal")
- .Atom(0, "1")
- .Atom(1, params->GetParamOne())
- .Atom(2, params->GetParamTwo())
- .Seal()
- .Seal()
- .Build();
- return IGraphTransformer::TStatus::Repeat;
- }
- } else if (!IsDataTypeNumeric(dataSlot)) {
+ if (IsDataTypeDecimal(dataSlot)) {
+ const auto params = static_cast<const TDataExprParamsType*>(dataType);
+ if (const auto scale = FromString<ui8>(params->GetParamTwo())) {
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable(IncOrDec ? "Add" : "Sub")
+ .Add(0, input->Child(0))
+ .Callable(1, "Decimal")
+ .Atom(0, "1")
+ .Atom(1, params->GetParamOne())
+ .Atom(2, params->GetParamTwo())
+ .Seal()
+ .Seal()
+ .Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else if (!IsDataTypeNumeric(dataSlot)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected numeric or decimal data type, but got: "
- << *input->Head().GetTypeAnn()));
+ << *input->Head().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
+ return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* resultType = dataType;
- if (isOptional) {
+ const TTypeAnnotationNode* resultType = dataType;
+ if (isOptional) {
resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
}
@@ -2617,24 +2617,24 @@ namespace NTypeAnnImpl {
bool isOptional;
const TDataExprType* dataType;
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto dataSlot = dataType->GetSlot();
if (!(IsDataTypeNumeric(dataSlot) || IsDataTypeDecimal(dataSlot) || dataSlot == EDataSlot::Interval)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected numeric, decimal or interval data type, but got: "
- << *input->Head().GetTypeAnn()));
+ << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -2687,76 +2687,76 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ShiftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus ShiftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto dataSlot = dataType->GetSlot();
- if (!IsDataTypeIntegral(dataSlot)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Unsupported type: " << *input->Head().GetTypeAnn()));
+ const auto dataSlot = dataType->GetSlot();
+ if (!IsDataTypeIntegral(dataSlot)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Unsupported type: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint8);
- const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint8);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Shift count must be Uint8"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Shift count must be Uint8"));
return IGraphTransformer::TStatus::Error;
- } else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ } else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
- if (IsDataTypeSigned(dataSlot)) {
- auto dataTypeName = TString("U") += NKikimr::NUdf::GetDataTypeInfo(dataSlot).Name;
- dataTypeName[1] = 'i';
- output = ctx.Expr.Builder(input->Pos())
- .Callable(input->Content())
- .Callable(0, "BitCast")
- .Add(0, input->HeadPtr())
- .Callable(1, "DataType")
- .Atom(0, dataTypeName, TNodeFlags::Default)
- .Seal()
- .Seal()
- .Add(1, input->TailPtr())
- .Seal().Build();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ if (IsDataTypeSigned(dataSlot)) {
+ auto dataTypeName = TString("U") += NKikimr::NUdf::GetDataTypeInfo(dataSlot).Name;
+ dataTypeName[1] = 'i';
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable(input->Content())
+ .Callable(0, "BitCast")
+ .Add(0, input->HeadPtr())
+ .Callable(1, "DataType")
+ .Atom(0, dataTypeName, TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Add(1, input->TailPtr())
+ .Seal().Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SyncWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus SyncWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureWorldType(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus ConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2769,25 +2769,25 @@ namespace NTypeAnnImpl {
bool isOptional1;
const TDataExprType* data1;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, data1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, data1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional2;
const TDataExprType* data2;
- if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, data2, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, data2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto dataType1 = data1->GetSlot();
auto dataType2 = data2->GetSlot();
if (dataType1 != EDataSlot::String && dataType1 != EDataSlot::Utf8) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
if (dataType2 != EDataSlot::String && dataType2 != EDataSlot::Utf8) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Tail().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -2803,39 +2803,39 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AggrConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
+ IGraphTransformer::TStatus AggrConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Tail().GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Type mismatch, left: "
- << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- bool isOptional;
- const TDataExprType* data;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, data, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (data->GetSlot() != EDataSlot::String && data->GetSlot() != EDataSlot::Utf8) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Head().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(input->Child(1)->GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus SubstringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head()) || IsNull(*input->Child(1)) && IsNull(*input->Child(2))) {
- output = input->HeadPtr();
+ << *input->Head().GetTypeAnn() << ", right:" << *input->Tail().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool isOptional;
+ const TDataExprType* data;
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, data, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (data->GetSlot() != EDataSlot::String && data->GetSlot() != EDataSlot::Utf8) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) String or Utf8, but got: " << *input->Head().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Child(1)->GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus SubstringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head()) || IsNull(*input->Child(1)) && IsNull(*input->Child(2))) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
@@ -2849,39 +2849,39 @@ namespace NTypeAnnImpl {
}
}
- auto originalType = input->Head().GetTypeAnn();
+ auto originalType = input->Head().GetTypeAnn();
auto type = originalType;
if (type->GetKind() == ETypeAnnotationKind::Optional) {
type = type->Cast<TOptionalExprType>()->GetItemType();
}
- if (!EnsureSpecificDataType(input->Head().Pos(), *type, EDataSlot::String, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head().Pos(), *type, EDataSlot::String, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* expectedTypeOne = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- const auto kindOne = input->Child(1U)->GetTypeAnn()->GetKind();
- if (kindOne == ETypeAnnotationKind::Optional || kindOne == ETypeAnnotationKind::Null) {
- expectedTypeOne = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeOne);
- }
- const auto convertStatus1 = TryConvertTo(input->ChildRef(1), *expectedTypeOne, ctx.Expr);
+ const TTypeAnnotationNode* expectedTypeOne = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
+ const auto kindOne = input->Child(1U)->GetTypeAnn()->GetKind();
+ if (kindOne == ETypeAnnotationKind::Optional || kindOne == ETypeAnnotationKind::Null) {
+ expectedTypeOne = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeOne);
+ }
+ const auto convertStatus1 = TryConvertTo(input->ChildRef(1), *expectedTypeOne, ctx.Expr);
if (convertStatus1.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* expectedTypeTwo = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- const auto kindTwo = input->Child(2U)->GetTypeAnn()->GetKind();
- if (kindTwo == ETypeAnnotationKind::Optional || kindTwo == ETypeAnnotationKind::Null) {
- expectedTypeTwo = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeTwo);
- }
- const auto convertStatus2 = TryConvertTo(input->ChildRef(2), *expectedTypeTwo, ctx.Expr);
+ const TTypeAnnotationNode* expectedTypeTwo = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
+ const auto kindTwo = input->Child(2U)->GetTypeAnn()->GetKind();
+ if (kindTwo == ETypeAnnotationKind::Optional || kindTwo == ETypeAnnotationKind::Null) {
+ expectedTypeTwo = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeTwo);
+ }
+ const auto convertStatus2 = TryConvertTo(input->ChildRef(2), *expectedTypeTwo, ctx.Expr);
if (convertStatus2.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
- const auto combinedStatus = convertStatus1.Combine(convertStatus2);
+ const auto combinedStatus = convertStatus1.Combine(convertStatus2);
if (combinedStatus.Level != IGraphTransformer::TStatus::Ok) {
return combinedStatus;
}
@@ -2890,103 +2890,103 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FindWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Type() == TExprNode::Lambda);
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected (optional) String, but got lambda"));
- return IGraphTransformer::TStatus::Error;
- }
-
- auto type = input->Head().GetTypeAnn();
- if (type->GetKind() == ETypeAnnotationKind::Optional) {
- type = type->Cast<TOptionalExprType>()->GetItemType();
- }
-
- if (!EnsureStringOrUtf8Type(input->Head().Pos(), *type, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (const auto convertStatus = TryConvertTo(input->ChildRef(1), *type, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
- return convertStatus;
- }
-
- const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- if (const auto kind = input->Child(2)->GetTypeAnn()->GetKind(); kind == ETypeAnnotationKind::Optional || kind == ETypeAnnotationKind::Null) {
- expectedType = ctx.Expr.MakeType<TOptionalExprType>(expectedType);
- }
-
- if (const auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
- return convertStatus;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32)));
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus WithWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head()) || IsNull(input->Tail())) {
- output = MakeBoolNothing(input->Pos(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool isOptional1, isOptional2;
- if (const TDataExprType *dataTypeOne, *dataTypeTwo;
- !(EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataTypeOne, ctx.Expr) && EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataTypeTwo, ctx.Expr)
- && EnsureStringOrUtf8Type(input->Head().Pos(), *dataTypeOne, ctx.Expr) && EnsureStringOrUtf8Type(input->Tail().Pos(), *dataTypeTwo, ctx.Expr))) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (isOptional1 || isOptional2)
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
- else
- input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
- return IGraphTransformer::TStatus::Ok;
- }
-
+ IGraphTransformer::TStatus FindWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Type() == TExprNode::Lambda);
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected (optional) String, but got lambda"));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto type = input->Head().GetTypeAnn();
+ if (type->GetKind() == ETypeAnnotationKind::Optional) {
+ type = type->Cast<TOptionalExprType>()->GetItemType();
+ }
+
+ if (!EnsureStringOrUtf8Type(input->Head().Pos(), *type, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(1), *type, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ return convertStatus;
+ }
+
+ const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
+ if (const auto kind = input->Child(2)->GetTypeAnn()->GetKind(); kind == ETypeAnnotationKind::Optional || kind == ETypeAnnotationKind::Null) {
+ expectedType = ctx.Expr.MakeType<TOptionalExprType>(expectedType);
+ }
+
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ return convertStatus;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32)));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus WithWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head()) || IsNull(input->Tail())) {
+ output = MakeBoolNothing(input->Pos(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool isOptional1, isOptional2;
+ if (const TDataExprType *dataTypeOne, *dataTypeTwo;
+ !(EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataTypeOne, ctx.Expr) && EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataTypeTwo, ctx.Expr)
+ && EnsureStringOrUtf8Type(input->Head().Pos(), *dataTypeOne, ctx.Expr) && EnsureStringOrUtf8Type(input->Tail().Pos(), *dataTypeTwo, ctx.Expr))) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (isOptional1 || isOptional2)
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
+ else
+ input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus ByteAtWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (!input->Head().GetTypeAnn()) {
+ if (!input->Head().GetTypeAnn()) {
YQL_ENSURE(input->Type() == TExprNode::Lambda);
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
<< "Expected (optional) String, but got lambda"));
return IGraphTransformer::TStatus::Error;
}
- auto originalType = input->Head().GetTypeAnn();
+ auto originalType = input->Head().GetTypeAnn();
auto type = originalType;
if (type->GetKind() == ETypeAnnotationKind::Optional) {
type = type->Cast<TOptionalExprType>()->GetItemType();
}
- if (!EnsureDataType(input->Head().Pos(), *type, ctx.Expr)) {
+ if (!EnsureDataType(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto dataType = type->Cast<TDataExprType>()->GetSlot();
if (dataType != EDataSlot::String && dataType != EDataSlot::Utf8) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
"Expected either String or Utf8, but got: " << *type));
return IGraphTransformer::TStatus::Error;
}
@@ -3006,54 +3006,54 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ListIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ListIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Tail(), ctx.Expr)) {
+ if (!EnsureComputable(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(input->Tail().GetTypeAnn()));
+ input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Ok;
}
template <bool IsStrict>
- IGraphTransformer::TStatus AsListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AsListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (input->ChildrenSize() == 0) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
}
- if constexpr (IsStrict) {
- std::set<const TTypeAnnotationNode*> set;
- input->ForEachChild([&](const TExprNode& item) { set.emplace(item.GetTypeAnn()); });
- if (1U != set.size()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
- "List items types isn't same: " << **set.cbegin() << " and " << **set.crbegin()));
- return IGraphTransformer::TStatus::Error;
- }
+ if constexpr (IsStrict) {
+ std::set<const TTypeAnnotationNode*> set;
+ input->ForEachChild([&](const TExprNode& item) { set.emplace(item.GetTypeAnn()); });
+ if (1U != set.size()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
+ "List items types isn't same: " << **set.cbegin() << " and " << **set.crbegin()));
+ return IGraphTransformer::TStatus::Error;
+ }
output = ctx.Expr.RenameNode(*input, "AsList");
return IGraphTransformer::TStatus::Repeat;
- } else if (const auto commonItemType = CommonTypeForChildren(*input, ctx.Expr)) {
- if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
- return status;
- } else
- return IGraphTransformer::TStatus::Error;
+ } else if (const auto commonItemType = CommonTypeForChildren(*input, ctx.Expr)) {
+ if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
+ return status;
+ } else
+ return IGraphTransformer::TStatus::Error;
input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3062,40 +3062,40 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- switch (const auto argType = input->Head().GetTypeAnn(); argType->GetKind()) {
- case ETypeAnnotationKind::List:
+ switch (const auto argType = input->Head().GetTypeAnn(); argType->GetKind()) {
+ case ETypeAnnotationKind::List:
case ETypeAnnotationKind::EmptyList:
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- case ETypeAnnotationKind::Tuple:
- if (argType->GetKind() == ETypeAnnotationKind::Tuple) {
- if (const auto size = argType->Cast<TTupleExprType>()->GetSize()) {
- TExprNodeList list;
- list.reserve(size);
- for (auto i = 0U; i < size; ++i) {
- list.emplace_back(
- input->Head().IsList() ? input->Head().ChildPtr(i) :
- ctx.Expr.NewCallable(input->Pos(), "Nth", { input->HeadPtr(), ctx.Expr.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default) })
- );
- }
- output = ctx.Expr.NewCallable(input->Pos(), "AsList", std::move(list));
- } else {
- output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
- }
- }
- return IGraphTransformer::TStatus::Repeat;
- case ETypeAnnotationKind::Optional:
- input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(argType->Cast<TOptionalExprType>()->GetItemType()));
- return IGraphTransformer::TStatus::Ok;
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
- TStringBuilder() << "Expecting list, optional or tuple argument, but got: " << *argType));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- IGraphTransformer::TStatus ToOptionalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ case ETypeAnnotationKind::Tuple:
+ if (argType->GetKind() == ETypeAnnotationKind::Tuple) {
+ if (const auto size = argType->Cast<TTupleExprType>()->GetSize()) {
+ TExprNodeList list;
+ list.reserve(size);
+ for (auto i = 0U; i < size; ++i) {
+ list.emplace_back(
+ input->Head().IsList() ? input->Head().ChildPtr(i) :
+ ctx.Expr.NewCallable(input->Pos(), "Nth", { input->HeadPtr(), ctx.Expr.NewAtom(input->Pos(), ToString(i), TNodeFlags::Default) })
+ );
+ }
+ output = ctx.Expr.NewCallable(input->Pos(), "AsList", std::move(list));
+ } else {
+ output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
+ }
+ }
+ return IGraphTransformer::TStatus::Repeat;
+ case ETypeAnnotationKind::Optional:
+ input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(argType->Cast<TOptionalExprType>()->GetItemType()));
+ return IGraphTransformer::TStatus::Ok;
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
+ TStringBuilder() << "Expecting list, optional or tuple argument, but got: " << *argType));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ IGraphTransformer::TStatus ToOptionalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3104,11 +3104,11 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(itemType));
return IGraphTransformer::TStatus::Ok;
}
@@ -3118,39 +3118,39 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus ToFlowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (ETypeAnnotationKind::Flow == input->Head().GetTypeAnn()->GetKind()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(itemType));
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus FromFlowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- input->SetTypeAnn(ctx.Expr.MakeType<TStreamExprType>(itemType));
- return IGraphTransformer::TStatus::Ok;
- }
-
+ IGraphTransformer::TStatus ToFlowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (ETypeAnnotationKind::Flow == input->Head().GetTypeAnn()->GetKind()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(itemType));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus FromFlowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ input->SetTypeAnn(ctx.Expr.MakeType<TStreamExprType>(itemType));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus BuildTablePathWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -3184,15 +3184,15 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TTaggedExprType>(input->Head().GetTypeAnn(), input->Tail().Content()));
+ input->SetTypeAnn(ctx.Expr.MakeType<TTaggedExprType>(input->Head().GetTypeAnn(), input->Tail().Content()));
if (!input->GetTypeAnn()->Cast<TTaggedExprType>()->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3205,18 +3205,18 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTaggedType(input->Head(), ctx.Expr)) {
+ if (!EnsureTaggedType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto tagType = input->Head().GetTypeAnn()->Cast<TTaggedExprType>();
- if (tagType->GetTag() != input->Tail().Content()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() <<
- "Expected tag: " << tagType->GetTag() << ", but got: " << input->Tail().Content()));
+ auto tagType = input->Head().GetTypeAnn()->Cast<TTaggedExprType>();
+ if (tagType->GetTag() != input->Tail().Content()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() <<
+ "Expected tag: " << tagType->GetTag() << ", but got: " << input->Tail().Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -3224,79 +3224,79 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus BoolOpt1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus BoolOpt1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = MakeBoolNothing(input->Head().Pos(), ctx.Expr);
+ if (IsNull(input->Head())) {
+ output = MakeBoolNothing(input->Head().Pos(), ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- template <bool Xor>
- IGraphTransformer::TStatus LogicalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ template <bool Xor>
+ IGraphTransformer::TStatus LogicalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- bool isOptionalResult = false;
- for (ui32 i = 0U; i < input->ChildrenSize() ; ++i) {
+ bool isOptionalResult = false;
+ for (ui32 i = 0U; i < input->ChildrenSize() ; ++i) {
if (IsNull(*input->Child(i))) {
- (Xor ? output : input->ChildRef(i)) = MakeBoolNothing(input->Child(i)->Pos(), ctx.Expr);
+ (Xor ? output : input->ChildRef(i)) = MakeBoolNothing(input->Child(i)->Pos(), ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
- bool isOptional;
- const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ bool isOptional;
+ const TDataExprType* dataType;
+ if (!EnsureDataOrOptionalOfData(*input->Child(i), isOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
- if (!EnsureSpecificDataType(input->Child(i)->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- isOptionalResult = isOptionalResult || isOptional;
+ if (!EnsureSpecificDataType(input->Child(i)->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ isOptionalResult = isOptionalResult || isOptional;
}
- if (1U == input->ChildrenSize()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
+ if (1U == input->ChildrenSize()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
}
- if (isOptionalResult) {
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
- } else {
- input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
+ if (isOptionalResult) {
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
+ } else {
+ input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
}
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus StructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus StructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (input->ChildrenSize() > 0) {
+ if (input->ChildrenSize() > 0) {
if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() != ETypeAnnotationKind::Struct) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
TStringBuilder() << "Expected struct type, but got: " << *type));
return IGraphTransformer::TStatus::Error;
}
@@ -3308,32 +3308,32 @@ namespace NTypeAnnImpl {
}
THashSet<TStringBuf> foundMembers;
- for (size_t i = 1; i < input->ChildrenSize(); ++i) {
- if (!EnsureTupleSize(*input->Child(i), 2, ctx.Expr)) {
+ for (size_t i = 1; i < input->ChildrenSize(); ++i) {
+ if (!EnsureTupleSize(*input->Child(i), 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto& nameNode = input->Child(i)->Head();
- if (!EnsureAtom(nameNode, ctx.Expr)) {
+ const auto& nameNode = input->Child(i)->Head();
+ if (!EnsureAtom(nameNode, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto& name = nameNode.Content();
+ const auto& name = nameNode.Content();
if (!foundMembers.insert(name).second) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Duplicated member: " << name));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Duplicated member: " << name));
return IGraphTransformer::TStatus::Error;
}
- const auto member = expectedMembers.FindPtr(name);
+ const auto member = expectedMembers.FindPtr(name);
if (!member) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Unknown member: " << name));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Unknown member: " << name));
return IGraphTransformer::TStatus::Error;
}
- const auto& valueNode = input->Child(i)->Tail();
- if (!IsSameAnnotation(*(*member)->GetItemType(), *valueNode.GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Mismatch type of member: " << name
- << ", expected type: " << *(*member)->GetItemType() << ", but got: " << *valueNode.GetTypeAnn()));
+ const auto& valueNode = input->Child(i)->Tail();
+ if (!IsSameAnnotation(*(*member)->GetItemType(), *valueNode.GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(nameNode.Pos()), TStringBuilder() << "Mismatch type of member: " << name
+ << ", expected type: " << *(*member)->GetItemType() << ", but got: " << *valueNode.GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
}
@@ -3358,55 +3358,55 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FlatListIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FlatListIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Tail(), ctx.Expr)) {
+ if (!EnsureListType(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Tail().GetTypeAnn());
+ input->SetTypeAnn(input->Tail().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FlatOptionalIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FlatOptionalIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureOptionalType(input->Tail(), ctx.Expr)) {
+ if (!EnsureOptionalType(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Tail().GetTypeAnn());
+ input->SetTypeAnn(input->Tail().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SizeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus SizeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = MakeNothingData(ctx.Expr, input->Head().Pos(), "Uint32");
+ if (IsNull(input->Head())) {
+ output = MakeNothingData(ctx.Expr, input->Head().Pos(), "Uint32");
return IGraphTransformer::TStatus::Repeat;
}
const TDataExprType* dataType;
bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3418,27 +3418,27 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FromStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FromStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TDataExprType* dataType;
bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto dataTypeName = input->Child(1)->Content();
+ auto dataTypeName = input->Child(1)->Content();
auto slot = NKikimr::NUdf::FindDataSlot(dataTypeName);
if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Unknown datatype: " << dataTypeName));
@@ -3446,10 +3446,10 @@ namespace NTypeAnnImpl {
}
const bool isDecimal = IsDataTypeDecimal(*slot);
- if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
const TDataExprType* dataTypeAnn;
if (isDecimal) {
auto ret = ctx.Expr.MakeType<TDataExprParamsType>(*slot, input->Child(2)->Content(), input->Child(3)->Content());
@@ -3466,27 +3466,27 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus StrictFromStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus StrictFromStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TDataExprType* dataType;
bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto dataTypeName = input->Child(1)->Content();
+ auto dataTypeName = input->Child(1)->Content();
auto slot = NKikimr::NUdf::FindDataSlot(dataTypeName);
if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Unknown datatype: " << dataTypeName));
@@ -3494,10 +3494,10 @@ namespace NTypeAnnImpl {
}
const bool isDecimal = IsDataTypeDecimal(*slot);
- if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
const TDataExprType* dataTypeAnn;
if (isDecimal) {
@@ -3508,8 +3508,8 @@ namespace NTypeAnnImpl {
input->SetTypeAnn(dataTypeAnn);
if (isDecimal && !input->GetTypeAnn()->Cast<TDataExprParamsType>()->Validate(input->Pos(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ return IGraphTransformer::TStatus::Error;
+ }
if (isOptional) {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->GetTypeAnn()));
}
@@ -3517,27 +3517,27 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FromBytesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FromBytesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::String, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto dataTypeName = input->Child(1)->Content();
+ auto dataTypeName = input->Child(1)->Content();
auto slot = NKikimr::NUdf::FindDataSlot(dataTypeName);
if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Unknown datatype: " << dataTypeName));
@@ -3545,17 +3545,17 @@ namespace NTypeAnnImpl {
}
const bool isDecimal = IsDataTypeDecimal(*slot);
- if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto dataTypeAnn = isDecimal ?
+ if (!EnsureArgsCount(*input, isDecimal ? 4 : 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto dataTypeAnn = isDecimal ?
ctx.Expr.MakeType<TDataExprParamsType>(*slot, input->Child(2)->Content(), input->Child(3)->Content()):
ctx.Expr.MakeType<TDataExprType>(*slot);
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(dataTypeAnn));
if (isDecimal && !input->GetTypeAnn()->Cast<TDataExprParamsType>()->Validate(input->Pos(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ return IGraphTransformer::TStatus::Error;
+ }
return IGraphTransformer::TStatus::Ok;
}
@@ -3568,7 +3568,7 @@ namespace NTypeAnnImpl {
else if (IsDataTypeFloat(sourceType) && IsDataTypeFloat(targetType)) {
canConvert = true;
}
- else if (sourceType == targetType && !IsDataTypeDecimal(sourceType)) {
+ else if (sourceType == targetType && !IsDataTypeDecimal(sourceType)) {
canConvert = true;
}
else if ((sourceType == EDataSlot::Yson || sourceType == EDataSlot::Utf8 || sourceType == EDataSlot::Json) && targetType == EDataSlot::String) {
@@ -3577,21 +3577,21 @@ namespace NTypeAnnImpl {
else if (sourceType == EDataSlot::Json && targetType == EDataSlot::Utf8) {
canConvert = true;
}
- else if (IsDataTypeDateOrTzDateOrInterval(sourceType) && IsDataTypeNumeric(targetType)) {
+ else if (IsDataTypeDateOrTzDateOrInterval(sourceType) && IsDataTypeNumeric(targetType)) {
canConvert = true;
}
return canConvert;
}
- IGraphTransformer::TStatus ConvertWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus ConvertWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TDataExprType* dataType;
bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3599,40 +3599,40 @@ namespace NTypeAnnImpl {
return status;
}
- EDataSlot targetSlot;
- if (input->Tail().Type() == TExprNode::Atom) {
- const auto targetTypeStr = input->Tail().Content();
- auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
- if (!slot) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = *slot;
- } else {
- const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
-
- if (!EnsureDataType(input->Tail().Pos(), *type, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = type->Cast<TDataExprType>()->GetSlot();
- }
-
- const auto sourceSlot = dataType->GetSlot();
-
- if (sourceSlot == targetSlot) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!CanConvert(sourceSlot, targetSlot)) {
+ EDataSlot targetSlot;
+ if (input->Tail().Type() == TExprNode::Atom) {
+ const auto targetTypeStr = input->Tail().Content();
+ auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
+ if (!slot) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = *slot;
+ } else {
+ const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+
+ if (!EnsureDataType(input->Tail().Pos(), *type, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = type->Cast<TDataExprType>()->GetSlot();
+ }
+
+ const auto sourceSlot = dataType->GetSlot();
+
+ if (sourceSlot == targetSlot) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!CanConvert(sourceSlot, targetSlot)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Cannot convert type " <<
- *input->Head().GetTypeAnn() << " into " << NKikimr::NUdf::GetDataTypeInfo(targetSlot).Name));
+ *input->Head().GetTypeAnn() << " into " << NKikimr::NUdf::GetDataTypeInfo(targetSlot).Name));
return IGraphTransformer::TStatus::Error;
}
- const auto dataTypeAnn = ctx.Expr.MakeType<TDataExprType>(targetSlot);
+ const auto dataTypeAnn = ctx.Expr.MakeType<TDataExprType>(targetSlot);
input->SetTypeAnn(dataTypeAnn);
if (isOptional) {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->GetTypeAnn()));
@@ -3641,63 +3641,63 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus BitCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TDataExprType* dataType;
- bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus BitCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TDataExprType* dataType;
+ bool isOptional;
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (auto status = EnsureTypeOrAtomRewrite(input->ChildRef(1), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- EDataSlot targetSlot;
- if (input->Tail().Type() == TExprNode::Atom) {
- const auto targetTypeStr = input->Tail().Content();
- auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
- if (!slot) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = *slot;
- } else {
- const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
-
- if (!EnsureDataType(input->Tail().Pos(), *type, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = type->Cast<TDataExprType>()->GetSlot();
- }
-
- const auto sourceSlot = dataType->GetSlot();
- if (!((EDataSlot::Bool == sourceSlot || IsDataTypeIntegral(sourceSlot) || IsDataTypeDateOrTzDateOrInterval(sourceSlot)) && IsDataTypeIntegral(targetSlot))) {
+ }
+
+ EDataSlot targetSlot;
+ if (input->Tail().Type() == TExprNode::Atom) {
+ const auto targetTypeStr = input->Tail().Content();
+ auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
+ if (!slot) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = *slot;
+ } else {
+ const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+
+ if (!EnsureDataType(input->Tail().Pos(), *type, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = type->Cast<TDataExprType>()->GetSlot();
+ }
+
+ const auto sourceSlot = dataType->GetSlot();
+ if (!((EDataSlot::Bool == sourceSlot || IsDataTypeIntegral(sourceSlot) || IsDataTypeDateOrTzDateOrInterval(sourceSlot)) && IsDataTypeIntegral(targetSlot))) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Cannot bit cast type " <<
- *input->Head().GetTypeAnn() << " into " << NKikimr::NUdf::GetDataTypeInfo(targetSlot).Name));
- return IGraphTransformer::TStatus::Error;
- }
-
- output = ctx.Expr.RenameNode(*input, "Convert");
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ *input->Head().GetTypeAnn() << " into " << NKikimr::NUdf::GetDataTypeInfo(targetSlot).Name));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ output = ctx.Expr.RenameNode(*input, "Convert");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
IGraphTransformer::TStatus AlterToWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto& source = input->Head();
+ const auto& source = input->Head();
auto& targetTypeNode = input->ChildRef(1);
auto& lambda = input->ChildRef(2);
- const auto& alterFailValue = input->Tail();
+ const auto& alterFailValue = input->Tail();
- if (!EnsureComputable(source, ctx.Expr)) {
+ if (!EnsureComputable(source, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3705,14 +3705,14 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureComputable(alterFailValue, ctx.Expr)) {
+ if (!EnsureComputable(alterFailValue, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto sourceType = source.GetTypeAnn();
+ const auto sourceType = source.GetTypeAnn();
const auto targetType = targetTypeNode->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- const auto status = ConvertToLambda(lambda, ctx.Expr, 1);
+ const auto status = ConvertToLambda(lambda, ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -3725,8 +3725,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- const auto alterSuccessType = lambda->GetTypeAnn();
- const auto alterFailType = alterFailValue.GetTypeAnn();
+ const auto alterSuccessType = lambda->GetTypeAnn();
+ const auto alterFailType = alterFailValue.GetTypeAnn();
if (!IsSameAnnotation(*alterSuccessType, *alterFailType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "mismatch of success/fail types, success type: "
<< *alterSuccessType << ", fail type: " << *alterFailType));
@@ -3734,13 +3734,13 @@ namespace NTypeAnnImpl {
}
if (IsSameAnnotation(*sourceType, *targetType)) {
- output = ctx.Expr.ReplaceNode(lambda->TailPtr(), lambda->Head().Head(), input->HeadPtr());
+ output = ctx.Expr.ReplaceNode(lambda->TailPtr(), lambda->Head().Head(), input->HeadPtr());
return IGraphTransformer::TStatus::Repeat;
}
- if (NKikimr::NUdf::ECastOptions::Impossible & CastResult<true>(sourceType, targetType)) {
+ if (NKikimr::NUdf::ECastOptions::Impossible & CastResult<true>(sourceType, targetType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Impossible alter " << *sourceType << " to " << *targetType));
+ TStringBuilder() << "Impossible alter " << *sourceType << " to " << *targetType));
return IGraphTransformer::TStatus::Error;
}
@@ -3748,14 +3748,14 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ToIntegralWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus ToIntegralWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TDataExprType* dataType;
bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3763,102 +3763,102 @@ namespace NTypeAnnImpl {
return status;
}
- EDataSlot targetSlot;
-
- if (input->Tail().Type() == TExprNode::Atom) {
- const auto targetTypeStr = input->Tail().Content();
- auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
- if (!slot) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = *slot;
-
- auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Deprecated ToIntegral signature, use Type instead of Atom.");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
- if (!ctx.Expr.AddWarning(issue)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- const TDataExprType* dataType;
-
- bool isOptional;
- if (!EnsureDataOrOptionalOfData(input->Tail().Pos(), type, isOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- targetSlot = dataType->GetSlot();
- }
-
- const auto sourceSlot = dataType->GetSlot();
-
- if (IsDataTypeIntegral(sourceSlot) && IsDataTypeIntegral(targetSlot)) {
- const auto& srcInfo = NKikimr::NUdf::GetDataTypeInfo(sourceSlot);
- const auto& dstInfo = NKikimr::NUdf::GetDataTypeInfo(targetSlot);
- if (srcInfo.FixedSize < dstInfo.FixedSize && (IsDataTypeUnsigned(sourceSlot) || IsDataTypeSigned(targetSlot)) ||
- srcInfo.FixedSize == dstInfo.FixedSize && IsDataTypeSigned(sourceSlot) == IsDataTypeSigned(targetSlot)) {
- output = ctx.Expr.RenameNode(*input, "BitCast");
- return IGraphTransformer::TStatus::Repeat;
- }
- } else if (!IsDataTypeFloat(sourceSlot) || !(IsDataTypeIntegral(targetSlot) || targetSlot == EDataSlot::Bool)) {
+ EDataSlot targetSlot;
+
+ if (input->Tail().Type() == TExprNode::Atom) {
+ const auto targetTypeStr = input->Tail().Content();
+ auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
+ if (!slot) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = *slot;
+
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Deprecated ToIntegral signature, use Type instead of Atom.");
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ const TDataExprType* dataType;
+
+ bool isOptional;
+ if (!EnsureDataOrOptionalOfData(input->Tail().Pos(), type, isOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetSlot = dataType->GetSlot();
+ }
+
+ const auto sourceSlot = dataType->GetSlot();
+
+ if (IsDataTypeIntegral(sourceSlot) && IsDataTypeIntegral(targetSlot)) {
+ const auto& srcInfo = NKikimr::NUdf::GetDataTypeInfo(sourceSlot);
+ const auto& dstInfo = NKikimr::NUdf::GetDataTypeInfo(targetSlot);
+ if (srcInfo.FixedSize < dstInfo.FixedSize && (IsDataTypeUnsigned(sourceSlot) || IsDataTypeSigned(targetSlot)) ||
+ srcInfo.FixedSize == dstInfo.FixedSize && IsDataTypeSigned(sourceSlot) == IsDataTypeSigned(targetSlot)) {
+ output = ctx.Expr.RenameNode(*input, "BitCast");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else if (!IsDataTypeFloat(sourceSlot) || !(IsDataTypeIntegral(targetSlot) || targetSlot == EDataSlot::Bool)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Cannot make an integral type " << NKikimr::NUdf::GetDataTypeInfo(targetSlot).Name
- << " from type " << *input->Head().GetTypeAnn()));
+ << " from type " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- const auto dataTypeAnn = ctx.Expr.MakeType<TDataExprType>(targetSlot);
+ const auto dataTypeAnn = ctx.Expr.MakeType<TDataExprType>(targetSlot);
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(dataTypeAnn));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus OldCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- bool isOptional;
- const TDataExprType* sourceDataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus OldCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool isOptional;
+ const TDataExprType* sourceDataType;
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (auto status = EnsureTypeOrAtomRewrite(input->ChildRef(1), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- EDataSlot targetType;
-
- if (input->Child(1)->Type() == TExprNode::Atom) {
- const auto targetTypeStr = input->Child(1)->Content();
- auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
- if (!slot) {
+ }
+
+ EDataSlot targetType;
+
+ if (input->Child(1)->Type() == TExprNode::Atom) {
+ const auto targetTypeStr = input->Child(1)->Content();
+ auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
+ if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
- return IGraphTransformer::TStatus::Error;
- }
-
- targetType = *slot;
- } else {
- const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- const TDataExprType* dataType;
-
- bool retIsOptional = false;
- if (!EnsureDataOrOptionalOfData(input->Tail().Pos(), type, retIsOptional, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- targetType = dataType->GetSlot();
- }
-
- const auto sourceType = sourceDataType->GetSlot();
- output = ctx.Expr.RenameNode(*input, IsDataTypeIntegral(sourceType) && IsDataTypeIntegral(targetType) ? "BitCast" : "SafeCast");
- return IGraphTransformer::TStatus::Repeat;
- }
-
- template <bool Strong>
- IGraphTransformer::TStatus CastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetType = *slot;
+ } else {
+ const auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ const TDataExprType* dataType;
+
+ bool retIsOptional = false;
+ if (!EnsureDataOrOptionalOfData(input->Tail().Pos(), type, retIsOptional, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetType = dataType->GetSlot();
+ }
+
+ const auto sourceType = sourceDataType->GetSlot();
+ output = ctx.Expr.RenameNode(*input, IsDataTypeIntegral(sourceType) && IsDataTypeIntegral(targetType) ? "BitCast" : "SafeCast");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ template <bool Strong>
+ IGraphTransformer::TStatus CastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3866,53 +3866,53 @@ namespace NTypeAnnImpl {
return status;
}
- const TTypeAnnotationNode* targetType = nullptr;
+ const TTypeAnnotationNode* targetType = nullptr;
- if (input->Child(1)->Type() == TExprNode::Atom) {
- const auto targetTypeStr = input->Child(1)->Content();
+ if (input->Child(1)->Type() == TExprNode::Atom) {
+ const auto targetTypeStr = input->Child(1)->Content();
auto slot = NKikimr::NUdf::FindDataSlot(targetTypeStr);
if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Unknown datatype: " << targetTypeStr));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsDataTypeDecimal(*slot)) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!(EnsureAtom(*input->Child(2), ctx.Expr) && EnsureAtom(*input->Child(3), ctx.Expr))) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto paramOne = input->Child(2)->Content();
- const auto paramTwo = input->Child(3)->Content();
- targetType = ctx.Expr.MakeType<TDataExprParamsType>(EDataSlot::Decimal, paramOne, paramTwo);
- } else {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- targetType = ctx.Expr.MakeType<TDataExprType>(*slot);
- }
- } else {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- targetType = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsDataTypeDecimal(*slot)) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!(EnsureAtom(*input->Child(2), ctx.Expr) && EnsureAtom(*input->Child(3), ctx.Expr))) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto paramOne = input->Child(2)->Content();
+ const auto paramTwo = input->Child(3)->Content();
+ targetType = ctx.Expr.MakeType<TDataExprParamsType>(EDataSlot::Decimal, paramOne, paramTwo);
+ } else {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ targetType = ctx.Expr.MakeType<TDataExprType>(*slot);
+ }
+ } else {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ targetType = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+
if (!EnsureComputableType(input->Tail().Pos(), *targetType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
if (!EnsureComputable(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto sourceType = input->Head().GetTypeAnn();
- const auto options = CastResult<Strong>(sourceType, targetType);
- if (!(options & NKikimr::NUdf::ECastOptions::Impossible)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto sourceType = input->Head().GetTypeAnn();
+ const auto options = CastResult<Strong>(sourceType, targetType);
+ if (!(options & NKikimr::NUdf::ECastOptions::Impossible)) {
auto type = targetType;
if (targetType->GetKind() != ETypeAnnotationKind::Optional && (options & NKikimr::NUdf::ECastOptions::MayFail)) {
if (!EnsurePersistableType(input->Tail().Pos(), *targetType, ctx.Expr)) {
@@ -3920,36 +3920,36 @@ namespace NTypeAnnImpl {
}
type = ctx.Expr.MakeType<TOptionalExprType>(targetType);
}
-
- if (ETypeAnnotationKind::Null == type->GetKind()) {
- output = ctx.Expr.NewCallable(input->Tail().Pos(), "Null", {});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (IsNull(input->Head())) {
- output = ctx.Expr.NewCallable(input->Head().Pos(), "Nothing", {ExpandType(input->Tail().Pos(), *type, ctx.Expr)});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(type);
- if (IsSameAnnotation(*sourceType, *input->GetTypeAnn())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const TDataExprType* sourceDataType = nullptr;
- const TDataExprType* targetDataType = nullptr;
- bool isOptional;
- if (IsDataOrOptionalOfData(sourceType, isOptional, sourceDataType) && IsDataOrOptionalOfData(targetType, isOptional, targetDataType)) {
- if (sourceDataType->GetSlot() == EDataSlot::Json && targetDataType->GetSlot() == EDataSlot::String) {
- auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Consider using ToBytes to get internal representation of Json type");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_CAST_YSON_JSON_BYTES, issue);
- if (!ctx.Expr.AddWarning(issue)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- if (sourceDataType->GetSlot() == EDataSlot::Yson && targetDataType->GetSlot() == EDataSlot::String) {
+
+ if (ETypeAnnotationKind::Null == type->GetKind()) {
+ output = ctx.Expr.NewCallable(input->Tail().Pos(), "Null", {});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (IsNull(input->Head())) {
+ output = ctx.Expr.NewCallable(input->Head().Pos(), "Nothing", {ExpandType(input->Tail().Pos(), *type, ctx.Expr)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(type);
+ if (IsSameAnnotation(*sourceType, *input->GetTypeAnn())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const TDataExprType* sourceDataType = nullptr;
+ const TDataExprType* targetDataType = nullptr;
+ bool isOptional;
+ if (IsDataOrOptionalOfData(sourceType, isOptional, sourceDataType) && IsDataOrOptionalOfData(targetType, isOptional, targetDataType)) {
+ if (sourceDataType->GetSlot() == EDataSlot::Json && targetDataType->GetSlot() == EDataSlot::String) {
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Consider using ToBytes to get internal representation of Json type");
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_CAST_YSON_JSON_BYTES, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ 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);
@@ -3977,13 +3977,13 @@ namespace NTypeAnnImpl {
}
}
- return IGraphTransformer::TStatus::Ok;
+ return IGraphTransformer::TStatus::Ok;
}
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Cannot cast type "
- << *sourceType << " into " << *targetType));
-
- return IGraphTransformer::TStatus::Error;
+ << *sourceType << " into " << *targetType));
+
+ return IGraphTransformer::TStatus::Error;
}
IGraphTransformer::TStatus WidenIntegralWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
@@ -3998,41 +3998,41 @@ namespace NTypeAnnImpl {
bool isOptional;
const TDataExprType* sourceDataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const bool isDecimal = IsDataTypeDecimal(sourceDataType->GetSlot());
- const bool isInterval = sourceDataType->GetSlot() == EDataSlot::Interval;
- if (!(isDecimal || IsDataTypeNumeric(sourceDataType->GetSlot()) || isInterval)) {
+ const bool isInterval = sourceDataType->GetSlot() == EDataSlot::Interval;
+ if (!(isDecimal || IsDataTypeNumeric(sourceDataType->GetSlot()) || isInterval)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected numeric type, but got " <<
- *input->Head().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (isDecimal) {
- const auto decimalType = sourceDataType->Cast<TDataExprParamsType>();
- output = ctx.Expr.Builder(input->Pos())
- .Callable("SafeCast")
- .Add(0, input->HeadPtr())
- .Callable(1, "DataType")
- .Atom(0, decimalType->GetName(), TNodeFlags::Default)
- .Atom(1, "35", TNodeFlags::Default)
- .Atom(2, decimalType->GetParamTwo(), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Build();
- } else if (isInterval) {
- output = isOptional ? input->HeadPtr() : ctx.Expr.Builder(input->Pos()).Callable("Just").Add(0, input->HeadPtr()).Seal().Build();
+ *input->Head().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (isDecimal) {
+ const auto decimalType = sourceDataType->Cast<TDataExprParamsType>();
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("SafeCast")
+ .Add(0, input->HeadPtr())
+ .Callable(1, "DataType")
+ .Atom(0, decimalType->GetName(), TNodeFlags::Default)
+ .Atom(1, "35", TNodeFlags::Default)
+ .Atom(2, decimalType->GetParamTwo(), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Build();
+ } else if (isInterval) {
+ output = isOptional ? input->HeadPtr() : ctx.Expr.Builder(input->Pos()).Callable("Just").Add(0, input->HeadPtr()).Seal().Build();
} else if (!IsDataTypeIntegral(sourceDataType->GetSlot())) {
- output = input->HeadPtr();
+ output = input->HeadPtr();
} else {
output = ctx.Expr.Builder(input->Pos())
- .Callable("SafeCast")
- .Add(0, input->HeadPtr())
- .Callable(1, "DataType")
- .Atom(0, IsDataTypeUnsigned(sourceDataType->GetSlot()) ? "Uint64" : "Int64", TNodeFlags::Default)
- .Seal()
+ .Callable("SafeCast")
+ .Add(0, input->HeadPtr())
+ .Callable(1, "DataType")
+ .Atom(0, IsDataTypeUnsigned(sourceDataType->GetSlot()) ? "Uint64" : "Int64", TNodeFlags::Default)
+ .Seal()
.Seal()
.Build();
}
@@ -4040,24 +4040,24 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus UnsafeTimestampCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ IGraphTransformer::TStatus UnsafeTimestampCastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!ctx.Types.DeprecatedSQL) {
+ if (!ctx.Types.DeprecatedSQL) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Unsafe timestamp cast restricted from SQL v1."));
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
bool isOptional;
const TDataExprType* sourceDataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceDataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Uint64, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Uint64, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4069,9 +4069,9 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DefaultWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DefaultWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4079,16 +4079,16 @@ namespace NTypeAnnImpl {
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head().Pos(), type, isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head().Pos(), type, isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto dataSlot = dataType->GetSlot();
if (dataSlot == EDataSlot::Yson || dataSlot == EDataSlot::Json) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "No default value supported for type: " << *type));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "No default value supported for type: " << *type));
return IGraphTransformer::TStatus::Error;
}
@@ -4096,13 +4096,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus PickleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus PickleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsurePersistable(input->Head(), ctx.Expr)) {
+ if (!EnsurePersistable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4110,9 +4110,9 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus UnpickleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus UnpickleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4120,8 +4120,8 @@ namespace NTypeAnnImpl {
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsurePersistableType(input->Head().Pos(), *type, ctx.Expr)) {
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsurePersistableType(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4133,17 +4133,17 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ExistsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ExistsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = MakeBool(input->Pos(), false, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (IsNull(input->Head())) {
+ output = MakeBool(input->Pos(), false, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4151,53 +4151,53 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CoalesceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus CoalesceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureComputable(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
if (input->ChildrenSize() == 1) {
- output = input->HeadPtr();
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
if (input->ChildrenSize() > 2) {
// split into pairs
- auto current = input->HeadPtr();
+ auto current = input->HeadPtr();
for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
- current = ctx.Expr.NewCallable(input->Pos(), input->Content(), { std::move(current), input->ChildPtr(i) });
+ current = ctx.Expr.NewCallable(input->Pos(), input->Content(), { std::move(current), input->ChildPtr(i) });
}
output = current;
return IGraphTransformer::TStatus::Repeat;
}
- if (IsNull(input->Head())) {
- output = input->TailPtr();
+ if (IsNull(input->Head())) {
+ output = input->TailPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (IsNull(input->Tail())) {
- output = input->HeadPtr();
+ if (IsNull(input->Tail())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- const auto leftType = input->Head().GetTypeAnn();
+ const auto leftType = input->Head().GetTypeAnn();
auto leftItemType = leftType;
if (leftType->GetKind() == ETypeAnnotationKind::Optional) {
leftItemType = leftType->Cast<TOptionalExprType>()->GetItemType();
- } else {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
+ } else {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
}
- const auto rightType = input->Tail().GetTypeAnn();
+ const auto rightType = input->Tail().GetTypeAnn();
auto rightItemType = rightType;
if (leftType->GetKind() != ETypeAnnotationKind::Optional &&
rightType->GetKind() == ETypeAnnotationKind::Optional) {
@@ -4221,7 +4221,7 @@ namespace NTypeAnnImpl {
leftType->GetKind() != ETypeAnnotationKind::Optional ||
TrySilentConvertTo(arg3, *leftType, *commonItemType, ctx.Expr) == IGraphTransformer::TStatus::Error;
bool changedArg2 = (convertedArg2 != arg2);
- bool changedArg1 = isNarrowing ? (convertedArg1 != arg1) : (!convertedArg1->IsCallable("Just") || convertedArg1->HeadPtr() != arg1);
+ bool changedArg1 = isNarrowing ? (convertedArg1 != arg1) : (!convertedArg1->IsCallable("Just") || convertedArg1->HeadPtr() != arg1);
auto retType = commonItemType;
if (changedArg1 || changedArg2) {
@@ -4230,12 +4230,12 @@ namespace NTypeAnnImpl {
if (leftType->GetKind() == ETypeAnnotationKind::Optional) {
input->ChildRef(0) = ctx.Expr.Builder(input->Pos())
.Callable(isNarrowing ? "Map" : "FlatMap")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Add(1, lambda1)
.Seal()
.Build();
} else {
- input->HeadRef() = ctx.Expr.ReplaceNode(lambda1->TailPtr(), lambda1->Head().Head(), input->HeadPtr());
+ input->HeadRef() = ctx.Expr.ReplaceNode(lambda1->TailPtr(), lambda1->Head().Head(), input->HeadPtr());
}
}
@@ -4340,86 +4340,86 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr) || !EnsureComputable(input->Tail(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr) || !EnsureComputable(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional1 = false;
const TDataExprType* dataType1 = nullptr;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const auto isDecimal = IsDataTypeDecimal(dataType1->GetSlot());
if (!(isDecimal || IsDataTypeFloat(dataType1->GetSlot()))) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected Float, Double or Decimal, but got: " << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected Float, Double or Decimal, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Tail())) {
- auto type = ExpandType(input->Tail().Pos(), *ctx.Expr.MakeType<TOptionalExprType>(dataType1), ctx.Expr);
- output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewCallable(input->Tail().Pos(), "Nothing", {std::move(type)}));
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Tail())) {
+ auto type = ExpandType(input->Tail().Pos(), *ctx.Expr.MakeType<TOptionalExprType>(dataType1), ctx.Expr);
+ output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewCallable(input->Tail().Pos(), "Nothing", {std::move(type)}));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
bool isOptional2 = false;
const TDataExprType* dataType2 = nullptr;
- if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataType2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (isDecimal) {
+ if (!EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataType2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (isDecimal) {
if (!IsDataTypeDecimal(dataType2->GetSlot())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
- << "Expected Decimal, but got: " << *input->Tail().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
+ << "Expected Decimal, but got: " << *input->Tail().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto paramsDataType1 = dataType1->Cast<TDataExprParamsType>();
+ const auto paramsDataType2 = dataType2->Cast<TDataExprParamsType>();
+
+ if (std::tie(paramsDataType1->GetParamOne(), paramsDataType1->GetParamTwo()) != std::tie(paramsDataType2->GetParamOne(), paramsDataType2->GetParamTwo())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
+ << "Expected Decimal parameters: (" << paramsDataType1->GetParamOne() << "," << paramsDataType1->GetParamTwo()
+ << ") but got: (" << paramsDataType2->GetParamOne() << "," << paramsDataType2->GetParamTwo() << ")!"));
return IGraphTransformer::TStatus::Error;
}
- const auto paramsDataType1 = dataType1->Cast<TDataExprParamsType>();
- const auto paramsDataType2 = dataType2->Cast<TDataExprParamsType>();
-
- if (std::tie(paramsDataType1->GetParamOne(), paramsDataType1->GetParamTwo()) != std::tie(paramsDataType2->GetParamOne(), paramsDataType2->GetParamTwo())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
- << "Expected Decimal parameters: (" << paramsDataType1->GetParamOne() << "," << paramsDataType1->GetParamTwo()
- << ") but got: (" << paramsDataType2->GetParamOne() << "," << paramsDataType2->GetParamTwo() << ")!"));
- return IGraphTransformer::TStatus::Error;
- }
-
const TDataExprType* retDataType = ctx.Expr.MakeType<TDataExprParamsType>(
paramsDataType1->GetSlot(), paramsDataType1->GetParamOne(), paramsDataType1->GetParamTwo());
-
- if (!retDataType->Cast<TDataExprParamsType>()->Validate(input->Pos(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+
+ if (!retDataType->Cast<TDataExprParamsType>()->Validate(input->Pos(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
input->SetTypeAnn((isOptional1 || isOptional2) ?
- (const TTypeAnnotationNode*)ctx.Expr.MakeType<TOptionalExprType>(retDataType) :
+ (const TTypeAnnotationNode*)ctx.Expr.MakeType<TOptionalExprType>(retDataType) :
(const TTypeAnnotationNode*)retDataType);
- } else {
+ } else {
if (!IsDataTypeFloat(dataType2->GetSlot())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
- << "Expected Float or Double, but got: " << *input->Tail().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder()
+ << "Expected Float or Double, but got: " << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- const TDataExprType* retDataType = ctx.Expr.MakeType<TDataExprType>(
+ const TDataExprType* retDataType = ctx.Expr.MakeType<TDataExprType>(
(dataType1->GetSlot() == EDataSlot::Double || dataType2->GetSlot() == EDataSlot::Double) ? EDataSlot::Double : EDataSlot::Float);
input->SetTypeAnn((isOptional1 || isOptional2) ?
- (const TTypeAnnotationNode*)ctx.Expr.MakeType<TOptionalExprType>(retDataType) :
+ (const TTypeAnnotationNode*)ctx.Expr.MakeType<TOptionalExprType>(retDataType) :
(const TTypeAnnotationNode*)retDataType);
}
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus UnwrapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus UnwrapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4435,33 +4435,33 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- if (input->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
- output = input->HeadPtr();
+ if (input->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
if (input->ChildrenSize() > 1) {
- if (!EnsureStringOrUtf8Type(input->Tail(), ctx.Expr)) {
+ if (!EnsureStringOrUtf8Type(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
- input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType());
+ input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType());
return IGraphTransformer::TStatus::Ok;
}
IGraphTransformer::TStatus PresortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().GetTypeAnn()->IsComparable()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected comparable type, but got: " << *input->Head().GetTypeAnn()));
+ if (!input->Head().GetTypeAnn()->IsComparable()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected comparable type, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -4481,7 +4481,7 @@ namespace NTypeAnnImpl {
}
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(DataSlot));
- input->SetUnorderedChildren();
+ input->SetUnorderedChildren();
return IGraphTransformer::TStatus::Ok;
}
@@ -4497,7 +4497,7 @@ namespace NTypeAnnImpl {
}
}
if (input->ChildrenSize() > 0) {
- if (!EnsureDependsOn(input->Head(), ctx.Expr)) {
+ if (!EnsureDependsOn(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4590,7 +4590,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
if (input->ChildrenSize() > 0) {
- if (!EnsureDependsOn(input->Head(), ctx.Expr)) {
+ if (!EnsureDependsOn(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4638,45 +4638,45 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
IGraphTransformer::TStatus IsKeySwitchWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureComputable(*input->ChildPtr(1), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1).Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(input->ChildRef(2), { input->Child(0)->GetTypeAnn() }, ctx.Expr) ||
- !UpdateLambdaAllArgumentsTypes(input->ChildRef(3), { input->Child(1)->GetTypeAnn() }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!input->Child(2)->GetTypeAnn() || !input->Tail().GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!IsSameAnnotation(*input->Child(2)->GetTypeAnn(), *input->Tail().GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder()
- << "Key extractors must return same type from row and state, but got: "
- << *input->Child(2)->GetTypeAnn() << " from row, and " << *input->Tail().GetTypeAnn() << " from state."));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureEquatableType(input->Pos(), *input->Tail().GetTypeAnn(), ctx.Expr)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Key extractor must return equatable value, but got: " << *input->Tail().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureComputable(*input->ChildPtr(1), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1).Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(input->ChildRef(2), { input->Child(0)->GetTypeAnn() }, ctx.Expr) ||
+ !UpdateLambdaAllArgumentsTypes(input->ChildRef(3), { input->Child(1)->GetTypeAnn() }, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!input->Child(2)->GetTypeAnn() || !input->Tail().GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!IsSameAnnotation(*input->Child(2)->GetTypeAnn(), *input->Tail().GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder()
+ << "Key extractors must return same type from row and state, but got: "
+ << *input->Child(2)->GetTypeAnn() << " from row, and " << *input->Tail().GetTypeAnn() << " from state."));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureEquatableType(input->Pos(), *input->Tail().GetTypeAnn(), ctx.Expr)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Key extractor must return equatable value, but got: " << *input->Tail().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
return IGraphTransformer::TStatus::Ok;
}
@@ -4686,57 +4686,57 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
TVector<TString> supportedSystems = { "yt", "kikimr", "rtmr" };
- if (auto p = FindPtr(supportedSystems, input->Tail().Content())) {
+ if (auto p = FindPtr(supportedSystems, input->Tail().Content())) {
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown system: "
- << input->Tail().Content() << ", supported: " << JoinSeq(",", supportedSystems)));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Unknown system: "
+ << input->Tail().Content() << ", supported: " << JoinSeq(",", supportedSystems)));
return IGraphTransformer::TStatus::Error;
}
- output = ctx.Expr.NewCallable(input->Pos(), to_title(TString(input->Tail().Content().substr(0, 2))) + "TableName",
- { input->HeadPtr() });
+ output = ctx.Expr.NewCallable(input->Pos(), to_title(TString(input->Tail().Content().substr(0, 2))) + "TableName",
+ { input->HeadPtr() });
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus OptionalIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus OptionalIfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Tail(), ctx.Expr)) {
+ if (!EnsureComputable(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->Tail().GetTypeAnn()));
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus JustWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus JustWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->Head().GetTypeAnn()));
+ input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus NothingWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus NothingWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4744,7 +4744,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() == ETypeAnnotationKind::Null) {
output = ctx.Expr.NewCallable(input->Pos(), "Null", {});
return IGraphTransformer::TStatus::Repeat;
@@ -4760,9 +4760,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus OptionalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus OptionalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4770,17 +4770,17 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() != ETypeAnnotationKind::Optional) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected optional type, but got: "
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected optional type, but got: "
<< *type));
return IGraphTransformer::TStatus::Error;
}
- if (!input->Tail().GetTypeAnn() || !IsSameAnnotation(*type->Cast<TOptionalExprType>()->GetItemType(),
- *input->Tail().GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Mismatch item type, expected: " <<
- *type->Cast<TOptionalExprType>()->GetItemType() << " but got: " << *input->Tail().GetTypeAnn()));
+ if (!input->Tail().GetTypeAnn() || !IsSameAnnotation(*type->Cast<TOptionalExprType>()->GetItemType(),
+ *input->Tail().GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), TStringBuilder() << "Mismatch item type, expected: " <<
+ *type->Cast<TOptionalExprType>()->GetItemType() << " but got: " << *input->Tail().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -4788,15 +4788,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ToStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ToStringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4808,13 +4808,13 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus VariantWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus VariantWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4842,7 +4842,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
} else {
auto tupleType = varType->GetUnderlyingType()->Cast<TTupleExprType>();
ui32 index = 0;
- if (!TryFromString(input->Child(1)->Content(), index)) {
+ if (!TryFromString(input->Child(1)->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -4856,7 +4856,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
itemType = tupleType->GetItems()[index];
}
- auto convertStatus = TryConvertTo(input->ChildRef(0), *itemType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(0), *itemType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
return IGraphTransformer::TStatus::Error;
} else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
@@ -4876,8 +4876,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Callable("Variant")
.Callable(0, "Void")
.Seal()
- .Add(1, input->HeadPtr())
- .Add(2, input->TailPtr())
+ .Add(1, input->HeadPtr())
+ .Add(2, input->TailPtr())
.Seal()
.Build();
@@ -4934,15 +4934,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus ToBytesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ToBytesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4954,9 +4954,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4964,9 +4964,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() != ETypeAnnotationKind::Dict) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected dict type, but got: "
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected dict type, but got: "
<< *type));
return IGraphTransformer::TStatus::Error;
}
@@ -4974,14 +4974,14 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto dictType = type->Cast<TDictExprType>();
auto keyType = dictType->GetKeyType();
auto payloadType = dictType->GetPayloadType();
- for (size_t i = 1; i < input->ChildrenSize(); ++i) {
- if (!EnsureTupleSize(*input->Child(i), 2, ctx.Expr)) {
+ for (size_t i = 1; i < input->ChildrenSize(); ++i) {
+ if (!EnsureTupleSize(*input->Child(i), 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!IsSameAnnotation(*input->Child(i)->Head().GetTypeAnn(), *keyType)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Head().Pos()), TStringBuilder()
- << "Mismatch type of key, expected: " << *keyType << ", but got: " << *input->Child(i)->Head().GetTypeAnn()));
+ if (!IsSameAnnotation(*input->Child(i)->Head().GetTypeAnn(), *keyType)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Head().Pos()), TStringBuilder()
+ << "Mismatch type of key, expected: " << *keyType << ", but got: " << *input->Child(i)->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -4996,7 +4996,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- template <bool ContainsOrLookup, bool InList = false>
+ template <bool ContainsOrLookup, bool InList = false>
IGraphTransformer::TStatus ContainsLookupWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -5008,12 +5008,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
- if (IsNull(input->Head())) {
- output = ContainsOrLookup ? MakeBool(input->Pos(), false, ctx.Expr) : input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
+ if (IsNull(input->Head())) {
+ output = ContainsOrLookup ? MakeBool(input->Pos(), false, ctx.Expr) : input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
}
- auto dictType = input->Head().GetTypeAnn();
+ auto dictType = input->Head().GetTypeAnn();
if (!dictType) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
TStringBuilder() << "Expected (optional) " << (InList ? "List" : "Dict") << " type, but got lambda"));
@@ -5024,18 +5024,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
dictType = dictType->Cast<TOptionalExprType>()->GetItemType();
}
- if constexpr (InList) {
+ if constexpr (InList) {
if (dictType->GetKind() == ETypeAnnotationKind::EmptyList) {
output = MakeBool(input->Pos(), false, ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head().Pos(), *dictType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else {
+ if (!EnsureListType(input->Head().Pos(), *dictType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
if (dictType->GetKind() == ETypeAnnotationKind::EmptyDict) {
- if constexpr (ContainsOrLookup) {
+ if constexpr (ContainsOrLookup) {
output = MakeBool(input->Pos(), false, ctx.Expr);
} else {
output = MakeNull(input->Pos(), ctx.Expr);
@@ -5045,30 +5045,30 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
- if (!EnsureDictType(input->Head().Pos(), *dictType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ if (!EnsureDictType(input->Head().Pos(), *dictType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ if (!EnsurePersistable(input->Tail(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
}
- if (!EnsurePersistable(input->Tail(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ const auto keyType = InList ? dictType->Cast<TListExprType>()->GetItemType() : dictType->Cast<TDictExprType>()->GetKeyType();
+ const auto payloadType = InList ? keyType : dictType->Cast<TDictExprType>()->GetPayloadType();
+ const auto lookupType = input->Tail().GetTypeAnn();
- const auto keyType = InList ? dictType->Cast<TListExprType>()->GetItemType() : dictType->Cast<TDictExprType>()->GetKeyType();
- const auto payloadType = InList ? keyType : dictType->Cast<TDictExprType>()->GetPayloadType();
- const auto lookupType = input->Tail().GetTypeAnn();
-
if (!EnsureEquatableType(input->Head().Pos(), *keyType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (NKikimr::NUdf::ECastOptions::Impossible & CastResult<true>(lookupType, keyType)) {
+ if (NKikimr::NUdf::ECastOptions::Impossible & CastResult<true>(lookupType, keyType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()),
- TStringBuilder() << "Can't lookup " << *lookupType << " in set of " << *keyType));
+ TStringBuilder() << "Can't lookup " << *lookupType << " in set of " << *keyType));
return IGraphTransformer::TStatus::Error;
}
- if constexpr (ContainsOrLookup) {
+ if constexpr (ContainsOrLookup) {
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
} else {
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(payloadType));
@@ -5118,7 +5118,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const auto lookupType = lookup->GetTypeAnn();
const bool isAnsi = HasSetting(*options, "ansi");
-
+
auto collectionType = collection->GetTypeAnn();
if (collectionType->GetKind() == ETypeAnnotationKind::Optional) {
collectionType = collectionType->Cast<TOptionalExprType>()->GetItemType();
@@ -5214,20 +5214,20 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
template <EDictItems Mode>
- IGraphTransformer::TStatus DictItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus DictItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
const TDictExprType* dictType;
bool isOptional;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
if (itemType->GetKind() == ETypeAnnotationKind::EmptyDict) {
dictType = nullptr;
} else {
@@ -5279,7 +5279,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AsStructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AsStructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (input->IsCallable("AsStructUnordered")) {
// obsolete callable
output = ctx.Expr.RenameNode(*input, "AsStruct");
@@ -5287,7 +5287,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
TVector<const TItemExprType*> items;
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureTupleSize(*child, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5311,12 +5311,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
auto structType = ctx.Expr.MakeType<TStructExprType>(items);
- if (!structType->Validate(input->Pos(), ctx.Expr)) {
+ if (!structType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto less = [](const TExprNode::TPtr& left, const TExprNode::TPtr& right) {
- return left->Head().Content() < right->Head().Content();
+ return left->Head().Content() < right->Head().Content();
};
if (!IsSorted(input->Children().begin(), input->Children().end(), less)) {
@@ -5331,13 +5331,13 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
template <bool IsStrict, bool IsSet>
- IGraphTransformer::TStatus AsDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AsDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (input->ChildrenSize() == 0) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyDict", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5345,7 +5345,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- auto commonType = input->Head().GetTypeAnn();
+ auto commonType = input->Head().GetTypeAnn();
bool needRetype = false;
for (size_t i = 1; i < input->ChildrenSize(); ++i) {
const auto child = input->Child(i);
@@ -5367,7 +5367,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto item1 = arg1;
auto item2 = arg2;
if (SilentInferCommonType(item1, *commonType, item2, *arg2->GetTypeAnn(), ctx.Expr, commonType)
- != IGraphTransformer::TStatus::Error) {
+ != IGraphTransformer::TStatus::Error) {
needRetype = needRetype || (item2 != arg2);
arg2 = item2;
if (item1 != arg1) {
@@ -5460,54 +5460,54 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
template <bool IsStrict>
- IGraphTransformer::TStatus IfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus IfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureSpecificDataType(input->Head(), EDataSlot::Bool, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto thenNode = input->Child(1);
- const auto elseNode = input->Child(2);
- const auto thenType = thenNode->GetTypeAnn();
- const auto elseType = elseNode->GetTypeAnn();
+ const auto thenNode = input->Child(1);
+ const auto elseNode = input->Child(2);
+ const auto thenType = thenNode->GetTypeAnn();
+ const auto elseType = elseNode->GetTypeAnn();
if (IsStrict) {
- if (IsSameAnnotation(*thenType, *elseType)) {
- output = ctx.Expr.RenameNode(*input, "If");
- return IGraphTransformer::TStatus::Repeat;
- } else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Different types of branches, then type: " <<
- *thenType << ", else type: " << *elseType));
- return IGraphTransformer::TStatus::Error;
+ if (IsSameAnnotation(*thenType, *elseType)) {
+ output = ctx.Expr.RenameNode(*input, "If");
+ return IGraphTransformer::TStatus::Repeat;
+ } else {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Different types of branches, then type: " <<
+ *thenType << ", else type: " << *elseType));
+ return IGraphTransformer::TStatus::Error;
}
}
- const TTypeAnnotationNode* commonType = nullptr;
- if (SilentInferCommonType(input->ChildRef(1), input->ChildRef(2), ctx.Expr, commonType) == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Uncompatible types of branches, then type: " <<
+ const TTypeAnnotationNode* commonType = nullptr;
+ if (SilentInferCommonType(input->ChildRef(1), input->ChildRef(2), ctx.Expr, commonType) == IGraphTransformer::TStatus::Error) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Uncompatible types of branches, then type: " <<
*thenType << ", else type: " << *elseType));
return IGraphTransformer::TStatus::Error;
}
- if (thenNode != input->Child(1) || elseNode != input->Child(2)) {
+ if (thenNode != input->Child(1) || elseNode != input->Child(2)) {
return IGraphTransformer::TStatus::Repeat;
}
- input->SetTypeAnn(commonType);
+ input->SetTypeAnn(commonType);
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus IfWorldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus IfWorldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5516,7 +5516,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureWorldType(input->Head(), ctx.Expr)) {
+ if (!EnsureWorldType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5524,22 +5524,22 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureWorldType(*input->Child(2), ctx.Expr)) {
+ if (!EnsureWorldType(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (input->ChildrenSize() == 3) {
auto children = input->ChildrenList();
- children.push_back(input->HeadPtr());
+ children.push_back(input->HeadPtr());
output = ctx.Expr.ChangeChildren(*input, std::move(children));
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureWorldType(*input->Child(3), ctx.Expr)) {
+ if (!EnsureWorldType(*input->Child(3), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -5552,7 +5552,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureWorldType(input->Head(), ctx.Expr)) {
+ if (!EnsureWorldType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5595,9 +5595,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const bool isNull = input->Child(1)->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Null;
if (isNull) {
if (input->ChildrenSize() == 3) {
- output = input->HeadPtr();
+ output = input->HeadPtr();
} else {
- output = ctx.Expr.ReplaceNode(lambda2->TailPtr(), lambda2->Head().Head(), input->HeadPtr());
+ output = ctx.Expr.ReplaceNode(lambda2->TailPtr(), lambda2->Head().Head(), input->HeadPtr());
}
return IGraphTransformer::TStatus::Repeat;
@@ -5627,44 +5627,44 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus IfPresentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus IfPresentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Tail(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto argsCount = input->ChildrenSize() - 2U;
- auto args = input->ChildrenList();
- args.resize(argsCount);
-
- TTypeAnnotationNode::TListType types;
- types.reserve(args.size());
- for (const auto& arg : args) {
- if (IsNull(*arg)) {
- output = input->TailPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureOptionalType(*arg, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- types.emplace_back(arg->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType());
+ if (!EnsureComputable(input->Tail(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
}
- auto& lambda = input->ChildRef(argsCount);
- if (const auto status = ConvertToLambda(lambda, ctx.Expr, argsCount); status.Level != IGraphTransformer::TStatus::Ok) {
+ const auto argsCount = input->ChildrenSize() - 2U;
+ auto args = input->ChildrenList();
+ args.resize(argsCount);
+
+ TTypeAnnotationNode::TListType types;
+ types.reserve(args.size());
+ for (const auto& arg : args) {
+ if (IsNull(*arg)) {
+ output = input->TailPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureOptionalType(*arg, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ types.emplace_back(arg->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType());
+ }
+
+ auto& lambda = input->ChildRef(argsCount);
+ if (const auto status = ConvertToLambda(lambda, ctx.Expr, argsCount); status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (!UpdateLambdaAllArgumentsTypes(lambda, types, ctx.Expr)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, types, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5672,8 +5672,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- const auto thenType = lambda->GetTypeAnn();
- const auto elseType = input->Tail().GetTypeAnn();
+ const auto thenType = lambda->GetTypeAnn();
+ const auto elseType = input->Tail().GetTypeAnn();
if (!IsSameAnnotation(*thenType, *elseType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "mismatch of then/else types, then type: "
<< *thenType << ", else type: " << *elseType));
@@ -5684,43 +5684,43 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus StaticMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus StaticMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (HasError(input->Head().GetTypeAnn(), ctx.Expr)) {
+ if (HasError(input->Head().GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Head().Type() == TExprNode::Lambda);
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either struct or tuple, but got lambda"));
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Head().Type() == TExprNode::Lambda);
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either struct or tuple, but got lambda"));
return IGraphTransformer::TStatus::Error;
}
- bool isStruct = input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct;
- bool isTuple = input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple;
+ bool isStruct = input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct;
+ bool isTuple = input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple;
if (!isStruct && !isTuple) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either struct or tuple, but got: "
- << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either struct or tuple, but got: "
+ << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
if (isTuple) {
- auto tupleType = input->Head().GetTypeAnn()->Cast<TTupleExprType>();
+ auto tupleType = input->Head().GetTypeAnn()->Cast<TTupleExprType>();
TExprNode::TListType children;
for (ui32 pos = 0; pos < tupleType->GetSize(); ++pos) {
- children.push_back(ctx.Expr.Builder(input->Pos())
- .Apply(input->Child(1))
+ children.push_back(ctx.Expr.Builder(input->Pos())
+ .Apply(input->Child(1))
.With(0)
.Callable("Nth")
- .Add(0, input->Child(0))
+ .Add(0, input->Child(0))
.Atom(1, ToString(pos))
.Seal()
.Done()
@@ -5728,18 +5728,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Build());
}
- output = ctx.Expr.NewList(input->Pos(), std::move(children));
+ output = ctx.Expr.NewList(input->Pos(), std::move(children));
} else {
- auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ auto structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
TExprNode::TListType children;
for (auto item : structType->GetItems()) {
- children.push_back(ctx.Expr.Builder(input->Pos())
+ children.push_back(ctx.Expr.Builder(input->Pos())
.List()
.Atom(0, item->GetName())
- .Apply(1, input->Child(1))
+ .Apply(1, input->Child(1))
.With(0)
.Callable("Member")
- .Add(0, input->Child(0))
+ .Add(0, input->Child(0))
.Atom(1, item->GetName())
.Seal()
.Done()
@@ -5748,7 +5748,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Build());
}
- output = ctx.Expr.NewCallable(input->Pos(), "AsStruct", std::move(children));
+ output = ctx.Expr.NewCallable(input->Pos(), "AsStruct", std::move(children));
}
return IGraphTransformer::TStatus::Repeat;
@@ -5878,7 +5878,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const TTypeAnnotationNode* resultType = nullptr;
if (isTuple) {
- auto outputTypes = value->GetTypeAnn()->Cast<TTupleExprType>()->GetItems();
+ auto outputTypes = value->GetTypeAnn()->Cast<TTupleExprType>()->GetItems();
for (auto& item : outputTypes) {
if (item->GetKind() == ETypeAnnotationKind::Optional) {
item = item->Cast<TOptionalExprType>()->GetItemType();
@@ -5886,21 +5886,21 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
resultType = ctx.Expr.MakeType<TTupleExprType>(std::move(outputTypes));
- } else if (isStruct) {
- auto outputTypes = value->GetTypeAnn()->Cast<TStructExprType>()->GetItems();
+ } else if (isStruct) {
+ auto outputTypes = value->GetTypeAnn()->Cast<TStructExprType>()->GetItems();
for (auto& item : outputTypes) {
if (item->GetItemType()->GetKind() == ETypeAnnotationKind::Optional) {
- item = ctx.Expr.MakeType<TItemExprType>(item->GetName(), item->GetItemType()->Cast<TOptionalExprType>()->GetItemType());
+ item = ctx.Expr.MakeType<TItemExprType>(item->GetName(), item->GetItemType()->Cast<TOptionalExprType>()->GetItemType());
}
}
resultType = ctx.Expr.MakeType<TStructExprType>(std::move(outputTypes));
}
- resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
- auto type = ExpandType(input->Pos(), *resultType, ctx.Expr);
- output = ctx.Expr.NewCallable(input->Pos(), "StrictCast", {std::move(value), std::move(type)});
- return IGraphTransformer::TStatus::Repeat;
+ resultType = ctx.Expr.MakeType<TOptionalExprType>(resultType);
+ auto type = ExpandType(input->Pos(), *resultType, ctx.Expr);
+ output = ctx.Expr.NewCallable(input->Pos(), "StrictCast", {std::move(value), std::move(type)});
+ return IGraphTransformer::TStatus::Repeat;
}
IGraphTransformer::TStatus HasNullWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
@@ -5909,7 +5909,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5917,18 +5917,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TypeOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().IsInspectable()) {
+ if (!input->Head().IsInspectable()) {
output = ctx.Expr.NewCallable(input->Pos(), "UnitType", {});
return IGraphTransformer::TStatus::Repeat;
}
- output = ExpandType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
IGraphTransformer::TStatus ConstraintsOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
@@ -5937,121 +5937,121 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Json));
+ input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Json));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus InstanceOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus InstanceOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus SourceOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus SourceOfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- const auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (ETypeAnnotationKind::Flow == type->GetKind()) {
- if (type->Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Null) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected flow of null, but got: " << *type));
- return IGraphTransformer::TStatus::Error;
- }
- } else if (ETypeAnnotationKind::Stream == type->GetKind()) {
- if (type->Cast<TStreamExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Null) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected stream of null, but got: " << *type));
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected flow or stream type, but got: " << *type));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(type);
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus MatchTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (input->ChildrenSize() % 2U) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(4)->Pos()), TStringBuilder() << "Expected even arguments."));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto& param = input->Head();
- auto argType = param.GetTypeAnn();
+ }
+
+ const auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (ETypeAnnotationKind::Flow == type->GetKind()) {
+ if (type->Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Null) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected flow of null, but got: " << *type));
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else if (ETypeAnnotationKind::Stream == type->GetKind()) {
+ if (type->Cast<TStreamExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Null) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected stream of null, but got: " << *type));
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected flow or stream type, but got: " << *type));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(type);
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus MatchTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (input->ChildrenSize() % 2U) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(4)->Pos()), TStringBuilder() << "Expected even arguments."));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto& param = input->Head();
+ auto argType = param.GetTypeAnn();
if (!argType) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(param.Pos()), TStringBuilder() << "Lambda is unexpected here"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(param.Pos()), TStringBuilder() << "Lambda is unexpected here"));
return IGraphTransformer::TStatus::Error;
}
auto argKind = argType->GetKind();
- if (argKind == ETypeAnnotationKind::Type) {
- argType = argType->Cast<TTypeExprType>()->GetType();
- argKind = argType->GetKind();
- }
-
- const auto argDataType = argKind == ETypeAnnotationKind::Data ? TMaybe<EDataSlot>(argType->Cast<TDataExprType>()->GetSlot()) : Nothing();
-
- auto index = input->ChildrenSize() - 1U;
- for (auto i = 1U; i < index; ++++i) {
- if (!EnsureAtom(*input->Child(i), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TString matchType(input->Child(i)->Content());
- const auto find = TSyncFunctionsMap::Instance().TypeKinds.FindPtr(matchType);
- const auto dataType = !find ? NKikimr::NUdf::FindDataSlot(matchType) : Nothing();
- if (!find && !dataType) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Pos()), TStringBuilder() << "Unknown type: " << matchType));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto kind = find ? *find : ETypeAnnotationKind::Data;
-
- if (argKind == kind && argDataType == dataType) {
- index = ++i;
- break;
- }
- }
-
- const auto selected = input->Child(index);
-
+ if (argKind == ETypeAnnotationKind::Type) {
+ argType = argType->Cast<TTypeExprType>()->GetType();
+ argKind = argType->GetKind();
+ }
+
+ const auto argDataType = argKind == ETypeAnnotationKind::Data ? TMaybe<EDataSlot>(argType->Cast<TDataExprType>()->GetSlot()) : Nothing();
+
+ auto index = input->ChildrenSize() - 1U;
+ for (auto i = 1U; i < index; ++++i) {
+ if (!EnsureAtom(*input->Child(i), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TString matchType(input->Child(i)->Content());
+ const auto find = TSyncFunctionsMap::Instance().TypeKinds.FindPtr(matchType);
+ const auto dataType = !find ? NKikimr::NUdf::FindDataSlot(matchType) : Nothing();
+ if (!find && !dataType) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Pos()), TStringBuilder() << "Unknown type: " << matchType));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto kind = find ? *find : ETypeAnnotationKind::Data;
+
+ if (argKind == kind && argDataType == dataType) {
+ index = ++i;
+ break;
+ }
+ }
+
+ const auto selected = input->Child(index);
+
if (!EnsureLambda(*selected, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
- const auto& args = selected->Head();
- auto body = selected->TailPtr();
- if (!EnsureMaxArgsCount(args, 1, ctx.Expr)) {
+
+ const auto& args = selected->Head();
+ auto body = selected->TailPtr();
+ if (!EnsureMaxArgsCount(args, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- output = args.ChildrenSize() ? ctx.Expr.ReplaceNode(std::move(body), args.Head(), input->HeadPtr()) : std::move(body);
- return IGraphTransformer::TStatus::Repeat;
+ output = args.ChildrenSize() ? ctx.Expr.ReplaceNode(std::move(body), args.Head(), input->HeadPtr()) : std::move(body);
+ return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus IfTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ IGraphTransformer::TStatus IfTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6059,23 +6059,23 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto param = input->HeadPtr();
+ auto param = input->HeadPtr();
const auto type = input->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
const ui32 idx = IsSameAnnotation(*param->GetTypeAnn(), *type) ? 2 : 3;
- const auto selected = input->Child(idx);
+ const auto selected = input->Child(idx);
if (!EnsureLambda(*selected, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
- const auto& args = selected->Head();
- auto body = selected->ChildPtr(1);
- if (!EnsureMaxArgsCount(args, 1, ctx.Expr)) {
+
+ const auto& args = selected->Head();
+ auto body = selected->ChildPtr(1);
+ if (!EnsureMaxArgsCount(args, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- output = args.ChildrenSize() ? ctx.Expr.ReplaceNode(std::move(body), args.Head(), std::move(param)) : std::move(body);
- return IGraphTransformer::TStatus::Repeat;
+ output = args.ChildrenSize() ? ctx.Expr.ReplaceNode(std::move(body), args.Head(), std::move(param)) : std::move(body);
+ return IGraphTransformer::TStatus::Repeat;
}
template <bool Strict>
@@ -6103,23 +6103,23 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
message += ")";
}
- if (HasError(input->Head().GetTypeAnn(), ctx.Expr)) {
+ if (HasError(input->Head().GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Head().Type() == TExprNode::Lambda);
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either type or computable value, but got lambda" << message));
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Head().Type() == TExprNode::Lambda);
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either type or computable value, but got lambda" << message));
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* valueType;
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
- valueType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- } else if (input->Head().GetTypeAnn()->IsComputable()) {
- valueType = input->Head().GetTypeAnn();
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Type) {
+ valueType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ } else if (input->Head().GetTypeAnn()->IsComputable()) {
+ valueType = input->Head().GetTypeAnn();
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either type or computable value, but got: " << *input->Head().GetTypeAnn() << message));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected either type or computable value, but got: " << *input->Head().GetTypeAnn() << message));
return IGraphTransformer::TStatus::Error;
}
@@ -6140,7 +6140,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
- output = input->HeadPtr();
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
@@ -6149,11 +6149,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto nodePtr = input->HeadPtr();
+ auto nodePtr = input->HeadPtr();
if (!nodePtr->IsPersistable()) {
auto issue = TIssue(ctx.Expr.GetPosition(nodePtr->Pos()), "Persistable required. Atom, key, world, datasink, datasource, callable, resource, stream and lambda are not persistable");
SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_NON_PERSISTABLE_ENTITY, issue);
@@ -6210,7 +6210,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
<< input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
- auto nodePtr = input->HeadPtr();
+ auto nodePtr = input->HeadPtr();
if (!EnsureTupleTypeSize(*nodePtr, tupleSize, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6221,16 +6221,16 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
IGraphTransformer::TStatus EnsureWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinMaxArgsCount(*input, 2, 3, ctx.Expr)) {
+ if (!EnsureMinMaxArgsCount(*input, 2, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TDataExprType* dataType;
- if (bool isOptional; !EnsureDataOrOptionalOfData(*input->Child(1), isOptional, dataType, ctx.Expr)) {
+ if (bool isOptional; !EnsureDataOrOptionalOfData(*input->Child(1), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6239,30 +6239,30 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
if (input->ChildrenSize() > 2) {
- if (!EnsureStringOrUtf8Type(input->Tail(), ctx.Expr)) {
+ if (!EnsureStringOrUtf8Type(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ToIndexDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ToIndexDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
const TListExprType* listType;
bool isOptional;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureListType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureListType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6270,11 +6270,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
isOptional = true;
}
else {
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
+ listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
isOptional = false;
}
@@ -6288,27 +6288,27 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ToDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ IGraphTransformer::TStatus ToDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
const TListExprType* listType;
bool isOptional;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
if (IsEmptyList(*itemType)) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyDict", {});
output = MakeConstMap(input->Pos(), input->HeadPtr(), output, ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6320,32 +6320,32 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
+ listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
isOptional = false;
}
const TTypeAnnotationNode* itemType = listType->Cast<TListExprType>()->GetItemType();
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1);
+ status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda1 = input->ChildRef(1);
- if (!UpdateLambdaAllArgumentsTypes(lambda1, {itemType}, ctx.Expr)) {
+ auto& lambda1 = input->ChildRef(1);
+ if (!UpdateLambdaAllArgumentsTypes(lambda1, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambda2 = input->ChildRef(2);
- if (!UpdateLambdaAllArgumentsTypes(lambda2, {itemType}, ctx.Expr)) {
+ auto& lambda2 = input->ChildRef(2);
+ if (!UpdateLambdaAllArgumentsTypes(lambda2, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6370,7 +6370,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
auto dictType = ctx.Expr.MakeType<TDictExprType>(keyType, payloadType);
- if (!dictType->Validate(input->Pos(), ctx.Expr)) {
+ if (!dictType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6396,39 +6396,39 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- template<bool Narrow>
+ template<bool Narrow>
IGraphTransformer::TStatus SqueezeToDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* itemType = nullptr;
- if constexpr (Narrow) {
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- } else {
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- auto& lambda1 = input->ChildRef(1);
- auto& lambda2 = input->ChildRef(2);
-
- const auto width = Narrow ? itemType->Cast<TMultiExprType>()->GetSize() : 1U;
- if (const auto status = ConvertToLambda(lambda1, ctx.Expr, width); status.Level != IGraphTransformer::TStatus::Ok) {
+ if constexpr (Narrow) {
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ } else {
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ auto& lambda1 = input->ChildRef(1);
+ auto& lambda2 = input->ChildRef(2);
+
+ const auto width = Narrow ? itemType->Cast<TMultiExprType>()->GetSize() : 1U;
+ if (const auto status = ConvertToLambda(lambda1, ctx.Expr, width); status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (const auto status = ConvertToLambda(lambda2, ctx.Expr, width); status.Level != IGraphTransformer::TStatus::Ok) {
+ if (const auto status = ConvertToLambda(lambda2, ctx.Expr, width); status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (const auto& items = Narrow ? itemType->Cast<TMultiExprType>()->GetItems() : TTypeAnnotationNode::TListType{itemType};
- !(UpdateLambdaAllArgumentsTypes(lambda1, items, ctx.Expr) && UpdateLambdaAllArgumentsTypes(lambda2, items, ctx.Expr))) {
+ if (const auto& items = Narrow ? itemType->Cast<TMultiExprType>()->GetItems() : TTypeAnnotationNode::TListType{itemType};
+ !(UpdateLambdaAllArgumentsTypes(lambda1, items, ctx.Expr) && UpdateLambdaAllArgumentsTypes(lambda2, items, ctx.Expr))) {
return IGraphTransformer::TStatus::Error;
}
@@ -6440,7 +6440,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TMaybe<bool> isHashed;
TMaybe<ui64> itemsCount;
bool isCompact;
- if (const auto error = ParseToDictSettings(*input, ctx.Expr, isMany, isHashed, itemsCount, isCompact)) {
+ if (const auto error = ParseToDictSettings(*input, ctx.Expr, isMany, isHashed, itemsCount, isCompact)) {
ctx.Expr.AddError(*error);
return IGraphTransformer::TStatus::Error;
}
@@ -6470,9 +6470,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus VoidWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus VoidWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6510,9 +6510,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ErrorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ErrorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6520,7 +6520,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() != ETypeAnnotationKind::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected error type, but got: " << *type));
return IGraphTransformer::TStatus::Error;
@@ -6530,38 +6530,38 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus OptionalReduceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus OptionalReduceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Child(1)->GetTypeAnn())) {
+ if (!IsSameAnnotation(*input->Head().GetTypeAnn(), *input->Child(1)->GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch types: "
- << *input->Head().GetTypeAnn() << " != " << *input->Child(1)->GetTypeAnn()));
+ << *input->Head().GetTypeAnn() << " != " << *input->Child(1)->GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* innerType = input->Head().GetTypeAnn();
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- innerType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ const TTypeAnnotationNode* innerType = input->Head().GetTypeAnn();
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ innerType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
}
- auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 2);
+ auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 2);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda = input->ChildRef(2);
- if (!UpdateLambdaAllArgumentsTypes(lambda, {innerType, innerType}, ctx.Expr)) {
+ auto& lambda = input->ChildRef(2);
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {innerType, innerType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6575,7 +6575,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -6606,9 +6606,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return true;
}
- IGraphTransformer::TStatus FilePathWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ IGraphTransformer::TStatus FilePathWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFileAlias(input->Head(), ctx)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFileAlias(input->Head(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
if (!EnsureNotInDiscoveryMode(*input, ctx)) {
@@ -6621,7 +6621,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
IGraphTransformer::TStatus FolderPathWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFolderAlias(input->Head(), ctx)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFolderAlias(input->Head(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
if (!EnsureNotInDiscoveryMode(*input, ctx)) {
@@ -6631,9 +6631,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FileContentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ IGraphTransformer::TStatus FileContentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFileAlias(input->Head(), ctx)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr) || !ValidateFileAlias(input->Head(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
if (!EnsureNotInDiscoveryMode(*input, ctx)) {
@@ -6643,74 +6643,74 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FilesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus FilesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TStructExprType>(TVector<const TItemExprType*>{
ctx.Expr.MakeType<TItemExprType>("Name", ctx.Expr.MakeType<TDataExprType>(EDataSlot::String)),
ctx.Expr.MakeType<TItemExprType>("IsFolder", ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)),
ctx.Expr.MakeType<TItemExprType>("Url", ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::String))),
ctx.Expr.MakeType<TItemExprType>("Path", ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::String)))
})));
-
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus AuthTokensWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus AuthTokensWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TStructExprType>(TVector<const TItemExprType*>{
ctx.Expr.MakeType<TItemExprType>("Name", ctx.Expr.MakeType<TDataExprType>(EDataSlot::String)),
ctx.Expr.MakeType<TItemExprType>("Category", ctx.Expr.MakeType<TDataExprType>(EDataSlot::String)),
ctx.Expr.MakeType<TItemExprType>("Subcategory", ctx.Expr.MakeType<TDataExprType>(EDataSlot::String))
})));
-
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus UdfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus UdfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureMaxArgsCount(*input, 7, ctx.Expr)) {
+ if (!EnsureMaxArgsCount(*input, 7, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
// (0) function name
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto name = input->Head().Content();
+ auto name = input->Head().Content();
TStringBuf moduleName, funcName;
if (!SplitUdfName(name, moduleName, funcName)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Invalid function name: " << name));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Invalid function name: " << name));
return IGraphTransformer::TStatus::Error;
}
// (1) run config value
- if (input->ChildrenSize() > 1) {
- if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
+ if (input->ChildrenSize() > 1) {
+ if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
// (2) user type
const TTypeAnnotationNode* userType = nullptr;
- if (input->ChildrenSize() > 2) {
- if (!input->Child(2)->IsCallable("Void")) {
+ if (input->ChildrenSize() > 2) {
+ if (!input->Child(2)->IsCallable("Void")) {
if (auto status = EnsureTypeRewrite(input->ChildRef(2), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -6724,23 +6724,23 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
// (3) type config
TStringBuf typeConfig = "";
- if (input->ChildrenSize() > 3) {
- if (!EnsureAtom(*input->Child(3), ctx.Expr)) {
+ if (input->ChildrenSize() > 3) {
+ if (!EnsureAtom(*input->Child(3), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- typeConfig = input->Child(3)->Content();
+ typeConfig = input->Child(3)->Content();
}
// (4) cached callable type
const TCallableExprType* cachedType = nullptr;
- if (input->ChildrenSize() > 4) {
+ if (input->ChildrenSize() > 4) {
if (auto status = EnsureTypeRewrite(input->ChildRef(4), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
}
auto type = input->Child(4)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureCallableType(input->Child(4)->Pos(), *type, ctx.Expr)) {
+ if (!EnsureCallableType(input->Child(4)->Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6749,7 +6749,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
// (5) cached run config type
const TTypeAnnotationNode* cachedRunConfigType = nullptr;
- if (input->ChildrenSize() > 5) {
+ if (input->ChildrenSize() > 5) {
if (auto status = EnsureTypeRewrite(input->ChildRef(5), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -6759,15 +6759,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
// (6) file alias
TStringBuf fileAlias = "";
- if (input->ChildrenSize() > 6) {
- if (!EnsureAtom(*input->Child(6), ctx.Expr)) {
+ if (input->ChildrenSize() > 6) {
+ if (!EnsureAtom(*input->Child(6), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- fileAlias = input->Child(6)->Content();
+ fileAlias = input->Child(6)->Content();
}
- if (input->ChildrenSize() != 7) {
+ if (input->ChildrenSize() != 7) {
YQL_PROFILE_SCOPE(DEBUG, "ResolveUdfs");
auto& cacheItem = ctx.Types.UdfTypeCache[std::make_tuple(TString(name), TString(typeConfig), userType)];
auto& cachedFuncType = std::get<0>(cacheItem);
@@ -6847,7 +6847,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TStringBuf fileAlias = foundAlias ? *foundAlias : "";
auto ret = ctx.Expr.Builder(input->Pos())
.Callable("Udf")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Add(1, runConfigValue)
.Add(2, ExpandType(input->Pos(), *cachedNormalizedUserType, ctx.Expr))
.Atom(3, typeConfig)
@@ -6861,7 +6861,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- auto status = TryConvertTo(input->ChildRef(1), *cachedRunConfigType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(1), *cachedRunConfigType, ctx.Expr);
if (status.Level != IGraphTransformer::TStatus::Ok) {
if (status.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Mismatch type of run config in UDF function "
@@ -6871,29 +6871,29 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- static const std::unordered_map<std::string_view, std::string_view> deprecated = {
- {"String.Reverse", "'Unicode::Reverse'"},
+ static const std::unordered_map<std::string_view, std::string_view> deprecated = {
+ {"String.Reverse", "'Unicode::Reverse'"},
{"String.ToLower", "'String::AsciiToLower' or 'Unicode::ToLower'"},
{"String.ToUpper", "'String::AsciiToUpper' or 'Unicode::ToUpper'"},
{"String.ToTitle", "'String::AsciiToTitle' or 'Unicode::ToTitle'"},
- {"String.Substring", "'SUBSTRING' builtin function"},
- {"String.Find", "'FIND' builtin function"},
- {"String.ReverseFind", "'RFIND' builtin function"},
- };
-
- if (const auto bad = deprecated.find(name); deprecated.cend() != bad) {
- auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Deprecated UDF function '" << moduleName << "::" << funcName << "', use " << bad->second << " instead.");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_UDF_FUNCTION, issue);
- if (!ctx.Expr.AddWarning(issue)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
+ {"String.Substring", "'SUBSTRING' builtin function"},
+ {"String.Find", "'FIND' builtin function"},
+ {"String.ReverseFind", "'RFIND' builtin function"},
+ };
+
+ if (const auto bad = deprecated.find(name); deprecated.cend() != bad) {
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Deprecated UDF function '" << moduleName << "::" << funcName << "', use " << bad->second << " instead.");
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_UDF_FUNCTION, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
input->SetTypeAnn(cachedType);
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ScriptUdfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ IGraphTransformer::TStatus ScriptUdfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -6903,12 +6903,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
// script type
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
// function name
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6920,12 +6920,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
const TTypeAnnotationNode* tn = input->Child(2)->GetTypeAnn();
const TTypeExprType* type = tn->Cast<TTypeExprType>();
- if (!EnsureCallableType(input->Child(2)->Pos(), *type->GetType(), ctx.Expr)) {
+ if (!EnsureCallableType(input->Child(2)->Pos(), *type->GetType(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
callableType = type->GetType()->Cast<TCallableExprType>();
- if (!EnsureComputableType(input->Child(2)->Pos(), *callableType, ctx.Expr)) {
+ if (!EnsureComputableType(input->Child(2)->Pos(), *callableType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
@@ -6935,7 +6935,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- auto moduleName = input->Head().Content();
+ auto moduleName = input->Head().Content();
auto scriptType = NKikimr::NMiniKQL::ScriptTypeFromStr(moduleName);
if (scriptType == NKikimr::NMiniKQL::EScriptType::Unknown) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Unknown script type: " << moduleName));
@@ -7020,27 +7020,27 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ApplyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ApplyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureCallableType(input->Head(), ctx.Expr)) {
+ if (!EnsureCallableType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
TIssueScopeGuard issueScope(ctx.Expr.IssueManager, [&]() {
- if (input->Head().IsCallable("Udf")) {
- return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Callable is produced by Udf: " << input->Head().Head().Content());
+ if (input->Head().IsCallable("Udf")) {
+ return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Callable is produced by Udf: " << input->Head().Head().Content());
} else {
- return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), "Callable is produced here");
+ return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), "Callable is produced here");
}
});
- auto type = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
+ auto type = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
auto autoMapFunction = type->GetReturnType()->GetKind() == ETypeAnnotationKind::Optional ? "FlatMap" : "Map";
- auto tmpArg = ctx.Expr.NewArgument(input->Pos(), "tmp");
+ auto tmpArg = ctx.Expr.NewArgument(input->Pos(), "tmp");
if (!EnsureCallableMaxArgsCount(input->Pos(), input->ChildrenSize() - 1, type->GetArgumentsSize(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7051,7 +7051,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto combinedStatus = IGraphTransformer::TStatus(IGraphTransformer::TStatus::Ok);
TVector<ui32> autoMapArgs;
- for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
+ for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
const auto& arg = type->GetArguments()[i - 1];
const bool isAutoMap = arg.Flags & NKikimr::NUdf::ICallablePayload::TArgumentFlags::AutoMap;
const auto srcType = input->Child(i)->GetTypeAnn();
@@ -7059,7 +7059,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- auto convertStatus = TrySilentConvertTo(input->ChildRef(i), *arg.Type, ctx.Expr);
+ auto convertStatus = TrySilentConvertTo(input->ChildRef(i), *arg.Type, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
if (isAutoMap && srcType && (srcType->GetKind() == ETypeAnnotationKind::Optional || srcType->GetKind() == ETypeAnnotationKind::Null)) {
if (srcType->GetKind() == ETypeAnnotationKind::Null) {
@@ -7073,7 +7073,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- auto tmp = tmpArg;
+ auto tmp = tmpArg;
convertStatus = TrySilentConvertTo(tmp, *srcType->Cast<TOptionalExprType>()->GetItemType(),
*arg.Type, ctx.Expr);
@@ -7136,37 +7136,37 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus NamedApplyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus NamedApplyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
if (!EnsureDependsOnTail(*input, ctx.Expr, 3)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureCallableType(input->Head(), ctx.Expr)) {
+ if (!EnsureCallableType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
TIssueScopeGuard issueScope(ctx.Expr.IssueManager, [&]() {
- if (input->Head().IsCallable("Udf")) {
- return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Callable is produced by Udf: " << input->Head().Head().Content());
+ if (input->Head().IsCallable("Udf")) {
+ return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Callable is produced by Udf: " << input->Head().Head().Content());
}
else {
- return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), "Callable is produced here");
+ return MakeIntrusive<TIssue>(ctx.Expr.GetPosition(input->Head().Pos()), "Callable is produced here");
}
});
- auto type = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
+ auto type = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
auto autoMapFunction = type->GetReturnType()->GetKind() == ETypeAnnotationKind::Optional ? "FlatMap" : "Map";
- auto tmpArg = ctx.Expr.NewArgument(input->Pos(), "tmp");
+ auto tmpArg = ctx.Expr.NewArgument(input->Pos(), "tmp");
// positional args
- if (!EnsureTupleType(*input->Child(1), ctx.Expr)) {
+ if (!EnsureTupleType(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto tupleType = input->Child(1)->GetTypeAnn()->Cast<TTupleExprType>();
auto tupleSize = tupleType->GetSize();
- if (!EnsureStructType(*input->Child(2), ctx.Expr)) {
+ if (!EnsureStructType(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7192,13 +7192,13 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TVector<ui32> tupleAutoMaps;
auto expectedTupleType = ctx.Expr.MakeType<TTupleExprType>(expectedTupleTypeItems);
- auto convertStatus = TrySilentConvertTo(input->ChildRef(1), *expectedTupleType, ctx.Expr);
+ auto convertStatus = TrySilentConvertTo(input->ChildRef(1), *expectedTupleType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
bool hasError = false;
for (ui32 i = 0; i < tupleType->GetSize(); ++i) {
auto srcType = tupleType->GetItems()[i];
auto dstType = expectedTupleType->GetItems()[i];
- auto tmp = tmpArg;
+ auto tmp = tmpArg;
auto convertStatus = TrySilentConvertTo(tmp, *srcType, *dstType, ctx.Expr);
if (convertStatus == IGraphTransformer::TStatus::Error) {
const bool isAutoMap = type->GetArguments()[i].Flags & NKikimr::NUdf::ICallablePayload::TArgumentFlags::AutoMap;
@@ -7267,18 +7267,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
auto expectedStructType = ctx.Expr.MakeType<TStructExprType>(expectedStructTypeItems);
- if (!expectedStructType->Validate(input->Child(2)->Pos(), ctx.Expr)) {
+ if (!expectedStructType->Validate(input->Child(2)->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- convertStatus = TrySilentConvertTo(input->ChildRef(2), *expectedStructType, ctx.Expr);
+ convertStatus = TrySilentConvertTo(input->ChildRef(2), *expectedStructType, ctx.Expr);
TVector<ui32> structAutoMaps;
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
bool hasError = false;
for (ui32 i = 0; i < structType->GetSize(); ++i) {
auto srcType = structType->GetItems()[i]->GetItemType();
auto dstType = expectedStructType->GetItems()[i]->GetItemType();
- auto tmp = tmpArg;
+ auto tmp = tmpArg;
auto convertStatus = TrySilentConvertTo(tmp, *srcType, *dstType, ctx.Expr);
if (convertStatus == IGraphTransformer::TStatus::Error) {
const bool isAutoMap = type->GetArguments()[i].Flags & NKikimr::NUdf::ICallablePayload::TArgumentFlags::AutoMap;
@@ -7512,9 +7512,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus CallableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CallableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7522,30 +7522,30 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureCallableType(input->Head().Pos(), *type, ctx.Expr)) {
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureCallableType(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto callableType = type->Cast<TCallableExprType>();
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, callableType->GetArgumentsSize());
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, callableType->GetArgumentsSize());
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- const auto lambda = input->Child(1);
+ const auto lambda = input->Child(1);
auto args = lambda->Child(0);
- if (const auto size = args->ChildrenSize()) {
- std::vector<const TTypeAnnotationNode*> argumentsAnnotations;
- argumentsAnnotations.reserve(size);
- for (const auto& arg : callableType->GetArguments()) {
- argumentsAnnotations.emplace_back(arg.Type);
- }
- if (!UpdateLambdaAllArgumentsTypes(input->ChildRef(1), argumentsAnnotations, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- if (!UpdateLambdaArgumentsType(*lambda, ctx.Expr)) {
+ if (const auto size = args->ChildrenSize()) {
+ std::vector<const TTypeAnnotationNode*> argumentsAnnotations;
+ argumentsAnnotations.reserve(size);
+ for (const auto& arg : callableType->GetArguments()) {
+ argumentsAnnotations.emplace_back(arg.Type);
+ }
+ if (!UpdateLambdaAllArgumentsTypes(input->ChildRef(1), argumentsAnnotations, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ if (!UpdateLambdaArgumentsType(*lambda, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
@@ -7564,16 +7564,16 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus NewMTRandWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus NewMTRandWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
@@ -7585,30 +7585,30 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus NextMTRandWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus NextMTRandWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureResourceType(input->Head(), ctx.Expr)) {
+ if (!EnsureResourceType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
TTypeAnnotationNode::TListType tupleItems(2);
tupleItems[0] = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- tupleItems[1] = input->Head().GetTypeAnn();
+ tupleItems[1] = input->Head().GetTypeAnn();
input->SetTypeAnn(ctx.Expr.MakeType<TTupleExprType>(tupleItems));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CastStructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CastStructWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7624,12 +7624,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
auto newStructType = type->Cast<TStructExprType>();
- auto oldStructType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ auto oldStructType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
for (auto item : newStructType->GetItems()) {
auto oldItem = oldStructType->FindItem(item->GetName());
if (!oldItem) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to find member with name: " <<
- item->GetName() << " in struct " << *input->Head().GetTypeAnn()));
+ item->GetName() << " in struct " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -7645,37 +7645,37 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus GuessWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus GuessWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TVariantExprType* variantType;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
variantType = itemType->Cast<TVariantExprType>();
}
else {
- if (!EnsureVariantType(input->Head(), ctx.Expr)) {
+ if (!EnsureVariantType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
+ variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (variantType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
auto tupleType = variantType->GetUnderlyingType()->Cast<TTupleExprType>();
ui32 index = 0;
- if (!TryFromString(input->Child(1)->Content(), index)) {
+ if (!TryFromString(input->Child(1)->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -7709,21 +7709,21 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional = false;
const TVariantExprType* variantType;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
isOptional = true;
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
variantType = itemType->Cast<TVariantExprType>();
}
else {
- if (!EnsureVariantType(input->Head(), ctx.Expr)) {
+ if (!EnsureVariantType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
+ variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
}
if (variantType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
@@ -7758,17 +7758,17 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus VisitWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus VisitWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureVariantType(input->Head(), ctx.Expr)) {
+ if (!EnsureVariantType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
+ auto variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
TVector<bool> usedFields;
ui32 usedCount = 0;
const TTupleExprType* tupleType = nullptr;
@@ -7785,9 +7785,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool needRepeat = false;
bool hasDefaultValue = false;
TVector<std::pair<ui32, size_t>> indexOrder;
- for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
+ for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
const TTypeAnnotationNode* currentType = nullptr;
- auto child = input->Child(index);
+ auto child = input->Child(index);
if (child->IsAtom()) {
const TTypeAnnotationNode* itemType;
ui32 itemIndex;
@@ -7834,18 +7834,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
++usedCount;
++index;
- if (index == input->ChildrenSize()) {
+ if (index == input->ChildrenSize()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), "Expected lambda after this argument"));
return IGraphTransformer::TStatus::Error;
}
- auto status = ConvertToLambda(input->ChildRef(index), ctx.Expr, 1);
+ auto status = ConvertToLambda(input->ChildRef(index), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda = input->ChildRef(index);
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ auto& lambda = input->ChildRef(index);
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7856,7 +7856,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
currentType = lambda->GetTypeAnn();
} else {
- if (index != input->ChildrenSize() - 1) {
+ if (index != input->ChildrenSize() - 1) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), "Default value should be in the end"));
return IGraphTransformer::TStatus::Error;
}
@@ -7921,21 +7921,21 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const TVariantExprType* variantType;
bool isOptional = false;
- if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ if (input->Head().GetTypeAnn() && input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
isOptional = true;
- auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ if (!EnsureVariantType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
variantType = itemType->Cast<TVariantExprType>();
}
else {
- if (!EnsureVariantType(input->Head(), ctx.Expr)) {
+ if (!EnsureVariantType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
+ variantType = input->Head().GetTypeAnn()->Cast<TVariantExprType>();
}
if (variantType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
@@ -7952,7 +7952,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SqlAccessWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus SqlAccessWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7965,7 +7965,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -7979,7 +7979,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isJson = false;
bool isYsonAutoConvert = false;
bool isYsonStrict = false;
- bool isYsonFast = false;
+ bool isYsonFast = false;
if (input->ChildrenSize() == 4) {
auto options = input->ChildPtr(3);
@@ -7989,10 +7989,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
isYsonAutoConvert = true;
} else if (optionName == "yson_strict") {
isYsonStrict = true;
- } else if (optionName == "yson_fast") {
- isYsonFast = true;
+ } else if (optionName == "yson_fast") {
+ isYsonFast = true;
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown SqlAccess option: " << optionName));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown SqlAccess option: " << optionName));
return IGraphTransformer::TStatus::Error;
}
}
@@ -8006,24 +8006,24 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
isJson = true;
}
- if (unpacked->GetKind() == ETypeAnnotationKind::Resource && unpacked->Cast<TResourceExprType>()->GetTag() == (isYsonFast ? "Yson2.Node" : "Yson.Node")) {
+ if (unpacked->GetKind() == ETypeAnnotationKind::Resource && unpacked->Cast<TResourceExprType>()->GetTag() == (isYsonFast ? "Yson2.Node" : "Yson.Node")) {
isYsonNode = true;
}
if (isYson || isJson || isYsonNode) {
auto key = input->ChildPtr(2);
- if (input->Head().Content() == "tuple" || input->Head().Content() == "struct") {
- key = ctx.Expr.NewCallable(input->Pos(), "String", { std::move(key) });
- } else if (input->Head().Content() == "dict") {
+ if (input->Head().Content() == "tuple" || input->Head().Content() == "struct") {
+ key = ctx.Expr.NewCallable(input->Pos(), "String", { std::move(key) });
+ } else if (input->Head().Content() == "dict") {
key = ctx.Expr.Builder(input->Pos())
- .Callable("SafeCast")
- .Add(0, std::move(key))
- .Callable(1, "DataType")
- .Atom(0, "String", TNodeFlags::Default)
- .Seal()
+ .Callable("SafeCast")
+ .Add(0, std::move(key))
+ .Callable(1, "DataType")
+ .Atom(0, "String", TNodeFlags::Default)
+ .Seal()
.Seal().Build();
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown access mode: " << input->Head().Content()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown access mode: " << input->Head().Content()));
return IGraphTransformer::TStatus::Error;
}
if (isYsonAutoConvert || isYsonStrict) {
@@ -8031,11 +8031,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Callable("AsStruct")
.List(0)
.Atom(0, "AutoConvert")
- .Add(1, MakeBool(input->Pos(), isYsonAutoConvert, ctx.Expr))
+ .Add(1, MakeBool(input->Pos(), isYsonAutoConvert, ctx.Expr))
.Seal()
.List(1)
.Atom(0, "Strict")
- .Add(1, MakeBool(input->Pos(), isYsonStrict, ctx.Expr))
+ .Add(1, MakeBool(input->Pos(), isYsonStrict, ctx.Expr))
.Seal()
.Seal()
.Build();
@@ -8043,21 +8043,21 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto ysonOptions = ctx.Expr.Builder(input->Pos())
.Callable("NamedApply")
.Callable(0, "Udf")
- .Atom(0, isYsonFast ? "Yson2.Options" : "Yson.Options", TNodeFlags::Default)
+ .Atom(0, isYsonFast ? "Yson2.Options" : "Yson.Options", TNodeFlags::Default)
.Seal()
.List(1).Seal()
- .Add(2, std::move(asStruct))
+ .Add(2, std::move(asStruct))
.Seal()
.Build();
output = ctx.Expr.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, isYsonFast ? "Yson2.Lookup" : "Yson.Lookup", TNodeFlags::Default)
+ .Atom(0, isYsonFast ? "Yson2.Lookup" : "Yson.Lookup", TNodeFlags::Default)
.Seal()
- .Add(1, input->ChildPtr(1))
- .Add(2, std::move(key))
- .Add(3, std::move(ysonOptions))
+ .Add(1, input->ChildPtr(1))
+ .Add(2, std::move(key))
+ .Add(3, std::move(ysonOptions))
.Seal()
.Build();
@@ -8065,50 +8065,50 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
output = ctx.Expr.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, isYsonFast ? "Yson2.Lookup" : "Yson.Lookup", TNodeFlags::Default)
+ .Atom(0, isYsonFast ? "Yson2.Lookup" : "Yson.Lookup", TNodeFlags::Default)
.Seal()
- .Add(1, input->ChildPtr(1))
- .Add(2, std::move(key))
+ .Add(1, input->ChildPtr(1))
+ .Add(2, std::move(key))
.Seal()
.Build();
}
return IGraphTransformer::TStatus::Repeat;
}
- if (input->Head().Content() == "tuple") {
+ if (input->Head().Content() == "tuple") {
if (unpacked->GetKind() == ETypeAnnotationKind::Tuple) {
- output = ctx.Expr.NewCallable(input->Pos(), "Nth", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Nth", { input->ChildPtr(1), input->ChildPtr(2) });
}
else if (unpacked->GetKind() == ETypeAnnotationKind::Variant) {
- output = ctx.Expr.NewCallable(input->Pos(), "Guess", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Guess", { input->ChildPtr(1), input->ChildPtr(2) });
} else {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), TStringBuilder()
<< "Expected (optional) tuple or variant based on it, but got: " << *input->Child(1)->GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
}
- else if (input->Head().Content() == "struct") {
+ else if (input->Head().Content() == "struct") {
if (unpacked->GetKind() == ETypeAnnotationKind::Struct) {
- output = ctx.Expr.NewCallable(input->Pos(), "Member", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Member", { input->ChildPtr(1), input->ChildPtr(2) });
}
else if (unpacked->GetKind() == ETypeAnnotationKind::Tuple) {
- output = ctx.Expr.NewCallable(input->Pos(), "Nth", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Nth", { input->ChildPtr(1), input->ChildPtr(2) });
}
else if (unpacked->GetKind() == ETypeAnnotationKind::Variant) {
- output = ctx.Expr.NewCallable(input->Pos(), "Guess", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Guess", { input->ChildPtr(1), input->ChildPtr(2) });
} else {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder()
<< "Expected (optional) struct/tuple or variant based on it, but got: " << *input->Child(1)->GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
}
- else if (input->Head().Content() == "dict") {
+ else if (input->Head().Content() == "dict") {
if (unpacked->GetKind() == ETypeAnnotationKind::Dict) {
- output = ctx.Expr.NewCallable(input->Pos(), "Lookup", { input->ChildPtr(1), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Lookup", { input->ChildPtr(1), input->ChildPtr(2) });
}
else if (unpacked->GetKind() == ETypeAnnotationKind::List) {
- output = ctx.Expr.NewCallable(input->Pos(), "Lookup", {
- ctx.Expr.NewCallable(input->Pos(), "ToIndexDict", { input->ChildPtr(1) }), input->ChildPtr(2) });
+ output = ctx.Expr.NewCallable(input->Pos(), "Lookup", {
+ ctx.Expr.NewCallable(input->Pos(), "ToIndexDict", { input->ChildPtr(1) }), input->ChildPtr(2) });
} else if (unpacked->GetKind() == ETypeAnnotationKind::EmptyList || unpacked->GetKind() == ETypeAnnotationKind::EmptyDict) {
output = ctx.Expr.NewCallable(input->Pos(), "Null", {});
} else {
@@ -8117,7 +8117,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown access mode: " << input->Head().Content()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Unknown access mode: " << input->Head().Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -8144,8 +8144,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TExprNode::TListType applyChildren = input->ChildrenList();
applyChildren.pop_back(); // Remove position of list argument
- if (input->Head().Type() != TExprNode::Lambda) {
- const TCallableExprType* callableType = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
+ if (input->Head().Type() != TExprNode::Lambda) {
+ const TCallableExprType* callableType = input->Head().GetTypeAnn()->Cast<TCallableExprType>();
if (applyChildren.size() < callableType->GetArgumentsSize() + 1 - callableType->GetOptionalArgumentsCount()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Invalid number of arguments "
@@ -8155,7 +8155,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const bool expectList = callableType->GetArguments()[listArg].Type->GetKind() == ETypeAnnotationKind::List;
if (expectList) {
- auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "The Udf used in PROCESS accepts List argument type, which prevents some optimizations."
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "The Udf used in PROCESS accepts List argument type, which prevents some optimizations."
" Consider to rewrite it using Stream argument type");
SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_NON_STREAM_BATCH_UDF, issue);
if (!ctx.Expr.AddWarning(issue)) {
@@ -8191,7 +8191,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Build();
}
else {
- auto lambda = input->HeadPtr();
+ auto lambda = input->HeadPtr();
const auto args = lambda->Child(0);
if (input->ChildrenSize() - 2 != args->ChildrenSize()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Different arguments count, lambda has "
@@ -8227,7 +8227,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
IGraphTransformer::TStatus SqlReduceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -8334,15 +8334,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ TExprNode::TPtr handler;
+
+ if (input->Child(2)->Type() != TExprNode::Lambda) {
+ const auto callableType = input->Child(2)->GetTypeAnn()->Cast<TCallableExprType>();
- TExprNode::TPtr handler;
-
- if (input->Child(2)->Type() != TExprNode::Lambda) {
- const auto callableType = input->Child(2)->GetTypeAnn()->Cast<TCallableExprType>();
-
if (callableType->GetArgumentsSize() != 2) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected callable with 2 arguments"));
return IGraphTransformer::TStatus::Error;
@@ -8350,7 +8350,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const bool expectList = callableType->GetArguments()[1].Type->GetKind() == ETypeAnnotationKind::List;
if (expectList) {
- auto issue = TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "The Udf used in REDUCE accepts List argument type, which prevents some optimizations."
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "The Udf used in REDUCE accepts List argument type, which prevents some optimizations."
" Consider to rewrite it using Stream argument type");
SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_NON_STREAM_BATCH_UDF, issue);
if (!ctx.Expr.AddWarning(issue)) {
@@ -8358,93 +8358,93 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
- handler = expectList ?
- ctx.Expr.Builder(input->Child(2)->Pos())
- .Lambda()
- .Param("key")
- .Param("stream")
- .Callable("ToStream")
- .Callable(0, "ToSequence")
- .Callable(0, "Apply")
- .Add(0, input->ChildPtr(2))
- .Arg(1, "key")
- .Callable(2, "ForwardList")
- .Callable(0, "Map")
- .Arg(0, "stream")
- .Add(1, input->TailPtr())
- .Seal()
- .Seal()
+ handler = expectList ?
+ ctx.Expr.Builder(input->Child(2)->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("stream")
+ .Callable("ToStream")
+ .Callable(0, "ToSequence")
+ .Callable(0, "Apply")
+ .Add(0, input->ChildPtr(2))
+ .Arg(1, "key")
+ .Callable(2, "ForwardList")
+ .Callable(0, "Map")
+ .Arg(0, "stream")
+ .Add(1, input->TailPtr())
+ .Seal()
+ .Seal()
.Seal()
.Seal()
.Seal()
- .Seal().Build():
- ctx.Expr.Builder(input->Child(2)->Pos())
- .Lambda()
- .Param("key")
- .Param("stream")
- .Callable("ToStream")
- .Callable(0, "ToSequence")
- .Callable(0, "Apply")
- .Add(0, input->ChildPtr(2))
- .Arg(1, "key")
- .Callable(2, "Map")
- .Arg(0, "stream")
- .Add(1, input->TailPtr())
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
- } else {
- if (const auto& lambda = *input->Child(2); lambda.Head().ChildrenSize() != 2) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda.Pos()), TStringBuilder() << "Expected lambda with 2 arguments"));
- return IGraphTransformer::TStatus::Error;
- }
-
- handler = ctx.Expr.Builder(input->Child(2)->Pos())
- .Lambda()
- .Param("key")
- .Param("stream")
- .Callable("ToStream")
- .Callable(0, "ToSequence")
- .Apply(0, *input->Child(2))
- .With(0, "key")
+ .Seal().Build():
+ ctx.Expr.Builder(input->Child(2)->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("stream")
+ .Callable("ToStream")
+ .Callable(0, "ToSequence")
+ .Callable(0, "Apply")
+ .Add(0, input->ChildPtr(2))
+ .Arg(1, "key")
+ .Callable(2, "Map")
+ .Arg(0, "stream")
+ .Add(1, input->TailPtr())
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ } else {
+ if (const auto& lambda = *input->Child(2); lambda.Head().ChildrenSize() != 2) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda.Pos()), TStringBuilder() << "Expected lambda with 2 arguments"));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ handler = ctx.Expr.Builder(input->Child(2)->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("stream")
+ .Callable("ToStream")
+ .Callable(0, "ToSequence")
+ .Apply(0, *input->Child(2))
+ .With(0, "key")
.With(1)
.Callable("Map")
- .Arg(0, "stream")
- .Add(1, input->TailPtr())
+ .Arg(0, "stream")
+ .Add(1, input->TailPtr())
.Seal()
.Done()
.Seal()
.Seal()
.Seal()
- .Seal().Build();
- }
-
- output = ctx.Expr.Builder(input->Pos())
- .Callable("ForwardList")
- .Callable(0, "Chopper")
- .Callable(0, "ToStream")
- .Add(0, input->HeadPtr())
- .Seal()
- .Add(1, input->ChildPtr(1))
- .Lambda(2)
- .Param("key")
- .Param("item")
- .Callable("IsKeySwitch")
- .Arg(0, "key")
- .Arg(1, "item")
- .Lambda(2)
- .Param("k")
- .Arg("k")
- .Seal()
- .Add(3, input->ChildPtr(1))
- .Seal()
- .Seal()
- .Add(3, std::move(handler))
- .Seal()
- .Seal().Build();
-
+ .Seal().Build();
+ }
+
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("ForwardList")
+ .Callable(0, "Chopper")
+ .Callable(0, "ToStream")
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Add(1, input->ChildPtr(1))
+ .Lambda(2)
+ .Param("key")
+ .Param("item")
+ .Callable("IsKeySwitch")
+ .Arg(0, "key")
+ .Arg(1, "item")
+ .Lambda(2)
+ .Param("k")
+ .Arg("k")
+ .Seal()
+ .Add(3, input->ChildPtr(1))
+ .Seal()
+ .Seal()
+ .Add(3, std::move(handler))
+ .Seal()
+ .Seal().Build();
+
return IGraphTransformer::TStatus::Repeat;
}
@@ -8574,15 +8574,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct) {
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Struct) {
output = ctx.Expr.Builder(input->Pos())
.Apply(input->ChildPtr(1))
- .With(0, input->HeadPtr())
+ .With(0, input->HeadPtr())
.Seal()
.Build();
}
- else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Variant) {
- auto underlyingType = input->Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
+ else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Variant) {
+ auto underlyingType = input->Head().GetTypeAnn()->Cast<TVariantExprType>()->GetUnderlyingType();
if (underlyingType->GetKind() == ETypeAnnotationKind::Tuple) {
auto tupleTypeItems = underlyingType->Cast<TTupleExprType>()->GetItems();
if (std::adjacent_find(tupleTypeItems.cbegin(), tupleTypeItems.cend(), std::not_equal_to<const TTypeAnnotationNode*>()) == tupleTypeItems.cend()) {
@@ -8591,7 +8591,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Apply(input->ChildPtr(1))
.With(0)
.Callable("VariantItem")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Seal()
.Done()
.Seal()
@@ -8600,7 +8600,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
else { // Non equal types
output = ctx.Expr.Builder(input->Pos())
.Callable("Visit")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Do([&input, &tupleTypeItems](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
for (size_t i = 0; i < tupleTypeItems.size(); ++i) {
parent
@@ -8629,7 +8629,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Apply(input->ChildPtr(1))
.With(0)
.Callable("VariantItem")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Seal()
.Done()
.Seal()
@@ -8638,7 +8638,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
else { // Non equal types
output = ctx.Expr.Builder(input->Pos())
.Callable("Visit")
- .Add(0, input->HeadPtr())
+ .Add(0, input->HeadPtr())
.Do([&input, &structTypeItems](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
for (size_t i = 0; i < structTypeItems.size(); ++i) {
parent
@@ -8659,7 +8659,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected Struct or Variant type, but got: " << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected Struct or Variant type, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -10807,44 +10807,44 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
+ auto listType = input->Head().GetTypeAnn()->Cast<TListExprType>();
if (listType->GetItemType()->GetKind() == ETypeAnnotationKind::Variant) {
output = ctx.Expr.RenameNode(*input, "Demux");
} else {
- output = input->HeadPtr();
+ output = input->HeadPtr();
}
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus AggrCountInitWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus AggrCountInitWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = ctx.Expr.NewCallable(input->Pos(), "Uint64", {ctx.Expr.NewAtom(input->Pos(), "0", TNodeFlags::Default)});
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Head())) {
+ output = ctx.Expr.NewCallable(input->Pos(), "Uint64", {ctx.Expr.NewAtom(input->Pos(), "0", TNodeFlags::Default)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AggrCountUpdateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus AggrCountUpdateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -10852,12 +10852,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->TailPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(input->Tail().GetTypeAnn());
+ if (IsNull(input->Head())) {
+ output = input->TailPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(input->Tail().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -11057,11 +11057,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -11105,7 +11105,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11149,10 +11149,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head(), ctx.Expr)) {
+ if (!EnsureStructType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TStructExprType* structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
+ const TStructExprType* structType = input->Head().GetTypeAnn()->Cast<TStructExprType>();
auto targetSlot = ExtractDataType(*input->Child(1), ctx.Expr);
if (!targetSlot) {
@@ -11181,7 +11181,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
const auto sourceName = input->Child(2)->ChildrenSize() == 2 ? input->Child(2)->Child(1)->Content() : "";
- const auto memberName = input->Child(2)->Head().Content();
+ const auto memberName = input->Child(2)->Head().Content();
const auto fullMemberName = sourceName ? DotJoin(sourceName, memberName) : TString(memberName);
const auto otherField = sourceName ? DotJoin(sourceName, "_other") : "_other";
const auto restField = sourceName ? DotJoin(sourceName, "_rest") : "_rest";
@@ -11234,7 +11234,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto parsedDict = ctx.Expr.Builder(input->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, "Yson2.ConvertToDict")
+ .Atom(0, "Yson2.ConvertToDict")
.Seal()
.Add(1, member)
.Seal()
@@ -11255,7 +11255,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
.Seal()
.Callable(1, "Apply")
.Callable(0, "Udf")
- .Atom(0, "Yson2.Serialize")
+ .Atom(0, "Yson2.Serialize")
.Seal()
.Callable(1, "Nth")
.Arg(0, "pair")
@@ -11428,7 +11428,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional;
const TDataExprType* sourceType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, sourceType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11501,15 +11501,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Head(), ctx.Expr)) {
+ if (!EnsureAtom(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto tokenName = input->Head().Content();
+ auto tokenName = input->Head().Content();
auto separator = tokenName.find(":");
if (separator == TString::npos || separator == tokenName.size()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "malformed secure param: " << tokenName));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "malformed secure param: " << tokenName));
return IGraphTransformer::TStatus::Error;
}
@@ -11517,15 +11517,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
if (p0 == "api") {
const auto p1 = tokenName.substr(separator + 1);
if (p1 != "oauth" && p1 != "cookie") {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token: " << p1 << ", prefix: " << p0));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token: " << p1 << ", prefix: " << p0));
return IGraphTransformer::TStatus::Error;
}
if (p1 == "oauth" && ctx.Types.UserCredentials.OauthToken.empty()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty Oauth token string"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty Oauth token string"));
return IGraphTransformer::TStatus::Error;
}
if (p1 == "cookie" && ctx.Types.UserCredentials.BlackboxSessionIdCookie.empty()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty session cookie"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty session cookie"));
return IGraphTransformer::TStatus::Error;
}
} else if (p0 == "token" || p0 == "cluster") {
@@ -11559,15 +11559,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
if (cred == nullptr) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token id: " << p1 << ", prefix: " << p0));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token id: " << p1 << ", prefix: " << p0));
return IGraphTransformer::TStatus::Error;
}
if (cred->Content.empty()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty credential content for id: " << p1));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "got empty credential content for id: " << p1));
return IGraphTransformer::TStatus::Error;
}
} else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token prefix: " << p0));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "unknown token prefix: " << p0));
return IGraphTransformer::TStatus::Error;
}
@@ -11581,14 +11581,14 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* inputType = input->Head().GetTypeAnn();
+ const TTypeAnnotationNode* inputType = input->Head().GetTypeAnn();
const TTypeAnnotationNode* resultType = nullptr;
if (inputType->GetKind() == ETypeAnnotationKind::Tuple) {
const TTupleExprType* tupleType = inputType->Cast<TTupleExprType>();
TTypeAnnotationNode::TListType itemTypes;
TExprNode::TListType updatedChildren;
for (size_t i = 0; i < tupleType->GetSize(); ++i) {
- if (!EnsureListType(input->Head().Pos(), *tupleType->GetItems()[i], ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *tupleType->GetItems()[i], ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto itemType = tupleType->GetItems()[i]->Cast<TListExprType>()->GetItemType();
@@ -11633,7 +11633,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TVector<const TItemExprType*> itemTypes;
TExprNode::TListType updatedChildren;
for (size_t i = 0; i < structType->GetSize(); ++i) {
- if (!EnsureListType(input->Head().Pos(), *structType->GetItems()[i]->GetItemType(), ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *structType->GetItems()[i]->GetItemType(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto itemType = structType->GetItems()[i]->GetItemType()->Cast<TListExprType>()->GetItemType();
@@ -11683,7 +11683,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
resultType = ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TVariantExprType>(ctx.Expr.MakeType<TStructExprType>(itemTypes)));
}
else {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected Tuple or Struct type, but got: " << *inputType));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected Tuple or Struct type, but got: " << *inputType));
return IGraphTransformer::TStatus::Error;
}
@@ -11697,12 +11697,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto listItemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!EnsureVariantType(input->Head().Pos(), *listItemType, ctx.Expr)) {
+ auto listItemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ if (!EnsureVariantType(input->Head().Pos(), *listItemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11741,7 +11741,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11753,7 +11753,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const TTypeAnnotationNode* expectedType = isOptional ? optUi16Type : ui16Type;
auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
@@ -11761,7 +11761,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return convertStatus;
}
- output = input->HeadPtr();
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
@@ -11777,7 +11777,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional;
const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional, dataType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11788,7 +11788,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
@@ -11808,12 +11808,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional1;
const TDataExprType* dataType1;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (!IsDataTypeDate(dataType1->GetSlot())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) date type, but got: " << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected (optional) date type, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -11849,13 +11849,13 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
bool isOptional1;
const TDataExprType* dataType1;
- if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
+ if (!EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataType1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
if (!IsDataTypeTzDate(dataType1->GetSlot())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
- TStringBuilder() << "Expected (optional) date with timezone type, but got: " << *input->Head().GetTypeAnn()));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
+ TStringBuilder() << "Expected (optional) date with timezone type, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -12721,8 +12721,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["OrderedFilter"] = &FilterWrapper;
Functions["TakeWhile"] = &FilterWrapper;
Functions["SkipWhile"] = &FilterWrapper;
- Functions["TakeWhileInclusive"] = &InclusiveFilterWrapper<false>;
- Functions["SkipWhileInclusive"] = &InclusiveFilterWrapper<true>;
+ Functions["TakeWhileInclusive"] = &InclusiveFilterWrapper<false>;
+ Functions["SkipWhileInclusive"] = &InclusiveFilterWrapper<true>;
Functions["Member"] = &MemberWrapper;
Functions["SingleMember"] = &SingleMemberWrapper;
Functions["SqlColumn"] = &SqlColumnWrapper;
@@ -12732,8 +12732,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["SqlColumnFromType"] = &SqlColumnFromTypeWrapper;
Functions["Nth"] = &NthWrapper;
Functions["FlattenMembers"] = &FlattenMembersWrapper;
- Functions["SelectMembers"] = &SelectMembersWrapper<true>;
- Functions["FilterMembers"] = &SelectMembersWrapper<false>;
+ Functions["SelectMembers"] = &SelectMembersWrapper<true>;
+ Functions["FilterMembers"] = &SelectMembersWrapper<false>;
Functions["DivePrefixMembers"] = &DivePrefixMembersWrapper;
Functions["FlattenByColumns"] = &FlattenByColumns;
Functions["ExtractMembers"] = &ExtractMembersWrapper;
@@ -12750,10 +12750,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["Equal"] = &CompareWrapper<true>;
Functions["!="] = &CompareWrapper<true>;
Functions["NotEqual"] = &CompareWrapper<true>;
- Functions["Inc"] = &IncDecWrapper<true>;
- Functions["Dec"] = &IncDecWrapper<false>;
+ Functions["Inc"] = &IncDecWrapper<true>;
+ Functions["Dec"] = &IncDecWrapper<false>;
Functions["BitNot"] = &BitOpsWrapper<1>;
- Functions["CountBits"] = &CountBitsWrapper;
+ Functions["CountBits"] = &CountBitsWrapper;
Functions["Plus"] = &PlusMinusWrapper;
Functions["Minus"] = &PlusMinusWrapper;
Functions["+"] = &AddWrapper;
@@ -12765,19 +12765,19 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["Mul"] = &MulWrapper;
Functions["/"] = &DivWrapper;
Functions["Div"] = &DivWrapper;
- Functions["%"] = &ModWrapper;
- Functions["Mod"] = &ModWrapper;
+ Functions["%"] = &ModWrapper;
+ Functions["Mod"] = &ModWrapper;
Functions["BitAnd"] = &BitOpsWrapper<2>;
Functions["BitOr"] = &BitOpsWrapper<2>;
Functions["BitXor"] = &BitOpsWrapper<2>;
Functions["Min"] = &MinMaxWrapper;
Functions["Max"] = &MinMaxWrapper;
- Functions["AggrEquals"] = &AggrCompareWrapper<true, false>;
- Functions["AggrNotEquals"] = &AggrCompareWrapper<false, false>;
- Functions["AggrLess"] = &AggrCompareWrapper<false, true>;
- Functions["AggrLessOrEqual"] = &AggrCompareWrapper<true, true>;
- Functions["AggrGreater"] = &AggrCompareWrapper<false, true>;
- Functions["AggrGreaterOrEqual"] = &AggrCompareWrapper<true, true>;
+ Functions["AggrEquals"] = &AggrCompareWrapper<true, false>;
+ Functions["AggrNotEquals"] = &AggrCompareWrapper<false, false>;
+ Functions["AggrLess"] = &AggrCompareWrapper<false, true>;
+ Functions["AggrLessOrEqual"] = &AggrCompareWrapper<true, true>;
+ Functions["AggrGreater"] = &AggrCompareWrapper<false, true>;
+ Functions["AggrGreaterOrEqual"] = &AggrCompareWrapper<true, true>;
Functions["AggrMin"] = &AggrMinMaxWrapper;
Functions["AggrMax"] = &AggrMinMaxWrapper;
Functions["IsNotDistinctFrom"] = &DistinctFromWrapper;
@@ -12789,12 +12789,12 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["RotRight"] = &ShiftWrapper;
Functions[SyncName] = &SyncWrapper;
Functions["Concat"] = &ConcatWrapper;
- Functions["AggrConcat"] = &AggrConcatWrapper;
+ Functions["AggrConcat"] = &AggrConcatWrapper;
Functions["Substring"] = &SubstringWrapper;
- Functions["Find"] = &FindWrapper;
- Functions["RFind"] = &FindWrapper;
- Functions["StartsWith"] = &WithWrapper;
- Functions["EndsWith"] = &WithWrapper;
+ Functions["Find"] = &FindWrapper;
+ Functions["RFind"] = &FindWrapper;
+ Functions["StartsWith"] = &WithWrapper;
+ Functions["EndsWith"] = &WithWrapper;
Functions["ByteAt"] = &ByteAtWrapper;
Functions["ListIf"] = &ListIfWrapper;
Functions["AsList"] = &AsListWrapper<false>;
@@ -12803,19 +12803,19 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["ToOptional"] = &ToOptionalWrapper;
Functions["Iterable"] = &IterableWrapper;
Functions["Head"] = &HeadWrapper;
- Functions["Last"] = &ToOptionalWrapper;
+ Functions["Last"] = &ToOptionalWrapper;
Functions["AsTagged"] = &AsTaggedWrapper;
Functions["Untag"] = &UntagWrapper;
- Functions["And"] = &LogicalWrapper<false>;
- Functions["Or"] = &LogicalWrapper<false>;
- Functions["Xor"] = &LogicalWrapper<true>;
+ Functions["And"] = &LogicalWrapper<false>;
+ Functions["Or"] = &LogicalWrapper<false>;
+ Functions["Xor"] = &LogicalWrapper<true>;
Functions["Not"] = &BoolOpt1Wrapper;
Functions["Likely"] = &BoolOpt1Wrapper;
Functions["Map"] = &MapWrapper;
Functions["OrderedMap"] = &MapWrapper;
Functions["FoldMap"] = &FoldMapWrapper;
Functions["Fold1Map"] = &Fold1MapWrapper;
- Functions["Chain1Map"] = &Chain1MapWrapper;
+ Functions["Chain1Map"] = &Chain1MapWrapper;
Functions["LMap"] = &LMapWrapper;
Functions["OrderedLMap"] = &LMapWrapper;
Functions["Struct"] = &StructWrapper;
@@ -12828,8 +12828,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["FlatMap"] = &FlatMapWrapper<false>;
Functions["OrderedFlatMap"] = &FlatMapWrapper<false>;
Functions["OrderedFlatMapWarn"] = &FlatMapWrapper<true>;
- Functions["MultiMap"] = &MultiMapWrapper<false>;
- Functions["OrderedMultiMap"] = &MultiMapWrapper<true>;
+ Functions["MultiMap"] = &MultiMapWrapper<false>;
+ Functions["OrderedMultiMap"] = &MultiMapWrapper<true>;
Functions["FlatMapToEquiJoin"] = &FlatMapWrapper<false>;
Functions["OrderedFlatMapToEquiJoin"] = &FlatMapWrapper<false>;
Functions["FlatListIf"] = &FlatListIfWrapper;
@@ -12842,11 +12842,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["ToStream"] = &ToStreamWrapper;
Functions["ToSequence"] = &ToSequenceWrapper;
Functions["Collect"] = &CollectWrapper;
- Functions["LazyList"] = &LazyListWrapper;
+ Functions["LazyList"] = &LazyListWrapper;
Functions["ListFromRange"] = &ListFromRangeWrapper;
Functions["Replicate"] = &ReplicateWrapper;
Functions["Switch"] = &SwitchWrapper;
- Functions["Chopper"] = &ChopperWrapper;
+ Functions["Chopper"] = &ChopperWrapper;
Functions["HasItems"] = &HasItemsWrapper;
Functions["Append"] = &AppendWrapper;
Functions["Insert"] = &AppendWrapper;
@@ -12858,18 +12858,18 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["OrderedExtract"] = &ExtractWrapper;
Functions["UnionAll"] = &UnionAllWrapper;
Functions["UnionMerge"] = &UnionAllWrapper;
- Functions["ListExtend"] = &ListExtendWrapper<false>;
- Functions["ListExtendStrict"] = &ListExtendWrapper<true>;
+ Functions["ListExtend"] = &ListExtendWrapper<false>;
+ Functions["ListExtendStrict"] = &ListExtendWrapper<true>;
Functions["ListUnionAll"] = &ListUnionAllWrapper;
- Functions["ListZip"] = &ListZipWrapper;
- Functions["ListZipAll"] = &ListZipAllWrapper;
+ Functions["ListZip"] = &ListZipWrapper;
+ Functions["ListZipAll"] = &ListZipAllWrapper;
Functions["Sort"] = &SortWrapper;
Functions["AssumeSorted"] = &SortWrapper;
Functions["AssumeUnique"] = &AssumeUniqueWrapper;
Functions["AssumeAllMembersNullableAtOnce"] = &AssumeAllMembersNullableAtOnceWrapper;
- Functions["Top"] = &TopWrapper;
- Functions["TopSort"] = &TopWrapper;
- Functions["KeepTop"] = &KeepTopWrapper;
+ Functions["Top"] = &TopWrapper;
+ Functions["TopSort"] = &TopWrapper;
+ Functions["KeepTop"] = &KeepTopWrapper;
Functions["Unordered"] = &UnorderedWrapper;
Functions["UnorderedSubquery"] = &UnorderedWrapper;
Functions["SortTraits"] = &SortTraitsWrapper;
@@ -12880,10 +12880,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["Convert"] = &ConvertWrapper;
Functions["AlterTo"] = &AlterToWrapper;
Functions["ToIntegral"] = &ToIntegralWrapper;
- Functions["Cast"] = &OldCastWrapper;
- Functions["SafeCast"] = &CastWrapper<false>;
- Functions["StrictCast"] = &CastWrapper<true>;
- Functions["BitCast"] = &BitCastWrapper;
+ Functions["Cast"] = &OldCastWrapper;
+ Functions["SafeCast"] = &CastWrapper<false>;
+ Functions["StrictCast"] = &CastWrapper<true>;
+ Functions["BitCast"] = &BitCastWrapper;
Functions["WidenIntegral"] = &WidenIntegralWrapper;
Functions["Default"] = &DefaultWrapper;
Functions["Pickle"] = &PickleWrapper;
@@ -12902,15 +12902,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["ToBytes"] = &ToBytesWrapper;
Functions["GroupByKey"] = &GroupByKeyWrapper;
Functions["PartitionByKey"] = &PartitionByKeyWrapper;
- Functions["PartitionsByKeys"] = &PartitionsByKeysWrapper;
+ Functions["PartitionsByKeys"] = &PartitionsByKeysWrapper;
Functions["Reverse"] = &ReverseWrapper;
Functions["Skip"] = &TakeWrapper;
Functions["Take"] = &TakeWrapper;
Functions["Limit"] = &TakeWrapper;
Functions["Fold"] = &FoldWrapper;
Functions["Fold1"] = &Fold1Wrapper;
- Functions["Condense"] = &CondenseWrapper;
- Functions["Condense1"] = &Condense1Wrapper;
+ Functions["Condense"] = &CondenseWrapper;
+ Functions["Condense1"] = &Condense1Wrapper;
Functions["Squeeze"] = &SqueezeWrapper;
Functions["Squeeze1"] = &Squeeze1Wrapper;
Functions["Discard"] = &DiscardWrapper;
@@ -12923,13 +12923,13 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["DataType"] = &TypeWrapper<ETypeAnnotationKind::Data>;
Functions["ListType"] = &TypeWrapper<ETypeAnnotationKind::List>;
Functions["TupleType"] = &TypeWrapper<ETypeAnnotationKind::Tuple>;
- Functions["MultiType"] = &TypeWrapper<ETypeAnnotationKind::Multi>;
+ Functions["MultiType"] = &TypeWrapper<ETypeAnnotationKind::Multi>;
Functions["StructType"] = &TypeWrapper<ETypeAnnotationKind::Struct>;
Functions["OptionalType"] = &TypeWrapper<ETypeAnnotationKind::Optional>;
Functions["TaggedType"] = &TypeWrapper<ETypeAnnotationKind::Tagged>;
Functions["VariantType"] = &TypeWrapper<ETypeAnnotationKind::Variant>;
Functions["StreamType"] = &TypeWrapper<ETypeAnnotationKind::Stream>;
- Functions["FlowType"] = &TypeWrapper<ETypeAnnotationKind::Flow>;
+ Functions["FlowType"] = &TypeWrapper<ETypeAnnotationKind::Flow>;
Functions["Nothing"] = &NothingWrapper;
Functions["List"] = &ListWrapper;
Functions["DictType"] = &TypeWrapper<ETypeAnnotationKind::Dict>;
@@ -12940,7 +12940,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["AsEnum"] = &AsEnumWrapper;
Functions["Contains"] = &ContainsLookupWrapper<true>;
Functions["SqlIn"] = &SqlInWrapper;
- Functions["Lookup"] = &ContainsLookupWrapper<false>;
+ Functions["Lookup"] = &ContainsLookupWrapper<false>;
Functions["DictItems"] = &DictItemsWrapper<EDictItems::Both>;
Functions["DictKeys"] = &DictItemsWrapper<EDictItems::Keys>;
Functions["DictPayloads"] = &DictItemsWrapper<EDictItems::Payloads>;
@@ -12962,8 +12962,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["HasNull"] = &HasNullWrapper;
Functions["TypeOf"] = &TypeOfWrapper;
Functions["ConstraintsOf"] = &ConstraintsOfWrapper;
- Functions["InstanceOf"] = &InstanceOfWrapper;
- Functions["SourceOf"] = &SourceOfWrapper;
+ Functions["InstanceOf"] = &InstanceOfWrapper;
+ Functions["SourceOf"] = &SourceOfWrapper;
Functions["MatchType"] = &MatchTypeWrapper;
Functions["IfType"] = &IfTypeWrapper;
Functions["EnsureType"] = &TypeAssertWrapper<true>;
@@ -12975,9 +12975,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["TryMember"] = &TryMemberWrapper;
Functions["ToIndexDict"] = &ToIndexDictWrapper;
Functions["ToDict"] = &ToDictWrapper;
- Functions["SqueezeToDict"] = &SqueezeToDictWrapper<false>;
- Functions["NarrowSqueezeToDict"] = &SqueezeToDictWrapper<true>;
- Functions["SqueezeToList"] = &SqueezeToListWrapper;
+ Functions["SqueezeToDict"] = &SqueezeToDictWrapper<false>;
+ Functions["NarrowSqueezeToDict"] = &SqueezeToDictWrapper<true>;
+ Functions["SqueezeToList"] = &SqueezeToListWrapper;
Functions["Void"] = &VoidWrapper;
Functions["Null"] = &NullWrapper;
Functions["EmptyList"] = &EmptyListWrapper;
@@ -13038,10 +13038,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["Descending"] = &PresortWrapper;
Functions["IsKeySwitch"] = &IsKeySwitchWrapper;
Functions["TableName"] = &TableNameWrapper;
- Functions["FilterNullMembers"] = &FilterNullMembersWrapper;
- Functions["SkipNullMembers"] = &SkipNullMembersWrapper;
- Functions["FilterNullElements"] = &FilterNullElementsWrapper;
- Functions["SkipNullElements"] = &SkipNullElementsWrapper;
+ Functions["FilterNullMembers"] = &FilterNullMembersWrapper;
+ Functions["SkipNullMembers"] = &SkipNullMembersWrapper;
+ Functions["FilterNullElements"] = &FilterNullElementsWrapper;
+ Functions["SkipNullElements"] = &SkipNullElementsWrapper;
Functions["AddMemberType"] = &TypeArgWrapper<ETypeArgument::AddMember>;
Functions["RemoveMemberType"] = &TypeArgWrapper<ETypeArgument::RemoveMember>;
Functions["ForceRemoveMemberType"] = &TypeArgWrapper<ETypeArgument::ForceRemoveMember>;
@@ -13137,57 +13137,57 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["EvaluateType"] = &RestartEvaluationWrapper;
Functions["EvaluateCode"] = &RestartEvaluationWrapper;
Functions["EvaluateExprIfPure"] = &EvaluateExprIfPureWrapper;
- Functions["ToFlow"] = &ToFlowWrapper;
- Functions["FromFlow"] = &FromFlowWrapper;
+ Functions["ToFlow"] = &ToFlowWrapper;
+ Functions["FromFlow"] = &FromFlowWrapper;
Functions["BuildTablePath"] = &BuildTablePathWrapper;
Functions["WithOptionalArgs"] = &WithOptionalArgsWrapper;
- Functions["DecimalDiv"] = &DecimalBinaryWrapper;
- Functions["DecimalMod"] = &DecimalBinaryWrapper;
- Functions["DecimalMul"] = &DecimalBinaryWrapper;
-
+ Functions["DecimalDiv"] = &DecimalBinaryWrapper;
+ Functions["DecimalMod"] = &DecimalBinaryWrapper;
+ Functions["DecimalMul"] = &DecimalBinaryWrapper;
+
Functions["ListFilter"] = &ListFilterWrapper;
Functions["ListMap"] = &ListMapWrapper;
Functions["ListFlatMap"] = &ListFlatMapWrapper;
Functions["ListSkipWhile"] = &ListSkipWhileWrapper;
Functions["ListTakeWhile"] = &ListTakeWhileWrapper;
- Functions["ListSkipWhileInclusive"] = &ListSkipWhileInclusiveWrapper;
- Functions["ListTakeWhileInclusive"] = &ListTakeWhileInclusiveWrapper;
- Functions["ListSkip"] = &ListSkipWrapper;
- Functions["ListTake"] = &ListTakeWrapper;
- Functions["ListHead"] = &ListHeadWrapper;
- Functions["ListLast"] = &ListLastWrapper;
- Functions["ListEnumerate"] = &ListEnumerateWrapper;
- Functions["ListReverse"] = &ListReverseWrapper;
- Functions["ListSort"] = &ListSortWrapper;
- Functions["ListExtract"] = &ListExtractWrapper;
- Functions["ListCollect"] = &ListCollectWrapper;
- Functions["ListMin"] = &ListMinWrapper;
- Functions["ListMax"] = &ListMaxWrapper;
- Functions["ListSum"] = &ListSumWrapper;
- Functions["ListConcat"] = &ListConcatWrapper;
- Functions["ListHas"] = &ContainsLookupWrapper<true, true>;
- Functions["ListAvg"] = &ListAvgWrapper;
- Functions["ListAll"] = &ListAllAnyWrapper<true>;
- Functions["ListAny"] = &ListAllAnyWrapper<false>;
+ Functions["ListSkipWhileInclusive"] = &ListSkipWhileInclusiveWrapper;
+ Functions["ListTakeWhileInclusive"] = &ListTakeWhileInclusiveWrapper;
+ Functions["ListSkip"] = &ListSkipWrapper;
+ Functions["ListTake"] = &ListTakeWrapper;
+ Functions["ListHead"] = &ListHeadWrapper;
+ Functions["ListLast"] = &ListLastWrapper;
+ Functions["ListEnumerate"] = &ListEnumerateWrapper;
+ Functions["ListReverse"] = &ListReverseWrapper;
+ Functions["ListSort"] = &ListSortWrapper;
+ Functions["ListExtract"] = &ListExtractWrapper;
+ Functions["ListCollect"] = &ListCollectWrapper;
+ Functions["ListMin"] = &ListMinWrapper;
+ Functions["ListMax"] = &ListMaxWrapper;
+ Functions["ListSum"] = &ListSumWrapper;
+ Functions["ListConcat"] = &ListConcatWrapper;
+ Functions["ListHas"] = &ContainsLookupWrapper<true, true>;
+ Functions["ListAvg"] = &ListAvgWrapper;
+ Functions["ListAll"] = &ListAllAnyWrapper<true>;
+ Functions["ListAny"] = &ListAllAnyWrapper<false>;
Functions["ListNotNull"] = &ListNotNullWrapper;
Functions["ListFlatten"] = &ListFlattenWrapper;
- Functions["ExpandMap"] = &ExpandMapWrapper;
- Functions["WideMap"] = &WideMapWrapper;
- Functions["WideFilter"] = &WideFilterWrapper;
- Functions["WideTakeWhile"] = &WideWhileWrapper;
- Functions["WideSkipWhile"] = &WideWhileWrapper;
- Functions["WideTakeWhileInclusive"] = &WideWhileWrapper;
- Functions["WideSkipWhileInclusive"] = &WideWhileWrapper;
- Functions["WideCondense1"] = &WideCondense1Wrapper;
- Functions["WideCombiner"] = &WideCombinerWrapper;
- Functions["WideChopper"] = &WideChopperWrapper;
- Functions["WideChain1Map"] = &WideChain1MapWrapper;
- Functions["NarrowMap"] = &NarrowMapWrapper;
- Functions["NarrowFlatMap"] = &NarrowFlatMapWrapper;
- Functions["NarrowMultiMap"] = &NarrowMultiMapWrapper;
-
+ Functions["ExpandMap"] = &ExpandMapWrapper;
+ Functions["WideMap"] = &WideMapWrapper;
+ Functions["WideFilter"] = &WideFilterWrapper;
+ Functions["WideTakeWhile"] = &WideWhileWrapper;
+ Functions["WideSkipWhile"] = &WideWhileWrapper;
+ Functions["WideTakeWhileInclusive"] = &WideWhileWrapper;
+ Functions["WideSkipWhileInclusive"] = &WideWhileWrapper;
+ Functions["WideCondense1"] = &WideCondense1Wrapper;
+ Functions["WideCombiner"] = &WideCombinerWrapper;
+ Functions["WideChopper"] = &WideChopperWrapper;
+ Functions["WideChain1Map"] = &WideChain1MapWrapper;
+ Functions["NarrowMap"] = &NarrowMapWrapper;
+ Functions["NarrowFlatMap"] = &NarrowFlatMapWrapper;
+ Functions["NarrowMultiMap"] = &NarrowMultiMapWrapper;
+
Functions["AsRange"] = &AsRangeWrapper;
Functions["RangeCreate"] = &RangeCreateWrapper;
Functions["RangeEmpty"] = &RangeEmptyWrapper;
@@ -13224,8 +13224,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
ExtFunctions["FilePath"] = &FilePathWrapper;
ExtFunctions["FileContent"] = &FileContentWrapper;
ExtFunctions["FolderPath"] = &FolderPathWrapper;
- ExtFunctions["Files"] = &FilesWrapper;
- ExtFunctions["AuthTokens"] = &AuthTokensWrapper;
+ ExtFunctions["Files"] = &FilesWrapper;
+ ExtFunctions["AuthTokens"] = &AuthTokensWrapper;
ExtFunctions["Udf"] = &UdfWrapper;
ExtFunctions["ScriptUdf"] = &ScriptUdfWrapper;
ExtFunctions["ParseType"] = &ParseTypeWrapper;
@@ -13233,7 +13233,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
ExtFunctions["CurrentOperationSharedId"] = &CurrentOperationSharedIdWrapper;
ExtFunctions["CurrentAuthenticatedUser"] = &CurrentAuthenticatedUserWrapper;
ExtFunctions["SecureParam"] = &SecureParamWrapper;
- ExtFunctions["UnsafeTimestampCast"] = &UnsafeTimestampCastWrapper;
+ ExtFunctions["UnsafeTimestampCast"] = &UnsafeTimestampCastWrapper;
ExtFunctions["JsonValue"] = &JsonValueWrapper;
ExtFunctions["JsonExists"] = &JsonExistsWrapper;
ExtFunctions["JsonQuery"] = &JsonQueryWrapper;
@@ -13291,15 +13291,15 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
{}
IGraphTransformer::TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
if (ctx.Step.IsDone(TExprStep::Intents)) {
return TStatus::Ok;
}
TOptimizeExprSettings settings(nullptr);
- auto ret = OptimizeExpr(input, output, [this](const TExprNode::TPtr& input, TExprContext& ctx) {
+ auto ret = OptimizeExpr(input, output, [this](const TExprNode::TPtr& input, TExprContext& ctx) {
TStatus status = TStatus::Ok;
- auto output = input;
+ auto output = input;
bool foundFunc = false;
@@ -13337,7 +13337,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
private:
IGraphTransformer::TStatus DetermineIntents(IDataProvider& dataProvider,
- const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
return dataProvider.GetIntentDeterminationTransformer().Transform(input, output, ctx);
}
@@ -13377,10 +13377,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return status;
}
- TMaybe<IGraphTransformer::TStatus> ProcessList(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&) {
- return {};
- }
-
+ TMaybe<IGraphTransformer::TStatus> ProcessList(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&) {
+ return {};
+ }
+
IGraphTransformer::TStatus ProcessUnknown(const TExprNode::TPtr& input, TExprContext& ctx) {
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder()
<< "(Core type annotation) Unsupported function: " << input->Content()));
@@ -13415,7 +13415,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
IGraphTransformer::TStatus ValidateProviderConfigureResult(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!input->GetTypeAnn() || input->GetTypeAnn()->GetKind() != input->Head().GetTypeAnn()->GetKind()) {
+ if (!input->GetTypeAnn() || input->GetTypeAnn()->GetKind() != input->Head().GetTypeAnn()->GetKind()) {
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), "Bad provider configure result"));
return TStatus::Error;
}
@@ -13442,17 +13442,17 @@ const THashSet<TString>& GetBuiltinFunctions() {
IGraphTransformer::TStatus ValidateDataSource(const TExprNode::TPtr& input, TExprContext& ctx, const TTypeAnnotationContext& types,
TSet<std::pair<TString, TString>>& clusters) {
- if (!EnsureMinArgsCount(*input, 1, ctx)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Head(), ctx)) {
+ if (!EnsureAtom(input->Head(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto datasource = types.DataSourceMap.FindPtr(input->Head().Content());
+ auto datasource = types.DataSourceMap.FindPtr(input->Head().Content());
if (!datasource) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported datasource: " << input->Head().Content()));
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported datasource: " << input->Head().Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -13462,7 +13462,7 @@ IGraphTransformer::TStatus ValidateDataSource(const TExprNode::TPtr& input, TExp
}
if (cluster) {
- clusters.insert(std::make_pair(TString(input->Head().Content()), *cluster));
+ clusters.insert(std::make_pair(TString(input->Head().Content()), *cluster));
}
return IGraphTransformer::TStatus::Ok;
@@ -13470,17 +13470,17 @@ IGraphTransformer::TStatus ValidateDataSource(const TExprNode::TPtr& input, TExp
IGraphTransformer::TStatus ValidateDataSink(const TExprNode::TPtr& input, TExprContext& ctx, const TTypeAnnotationContext& types,
TSet<std::pair<TString, TString>>& clusters) {
- if (!EnsureMinArgsCount(*input, 1, ctx)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(input->Head(), ctx)) {
+ if (!EnsureAtom(input->Head(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto datasink = types.DataSinkMap.FindPtr(input->Head().Content());
+ auto datasink = types.DataSinkMap.FindPtr(input->Head().Content());
if (!datasink) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported datasink: " << input->Head().Content()));
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported datasink: " << input->Head().Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -13490,7 +13490,7 @@ IGraphTransformer::TStatus ValidateDataSink(const TExprNode::TPtr& input, TExprC
}
if (cluster) {
- clusters.insert(std::make_pair(TString(input->Head().Content()), *cluster));
+ clusters.insert(std::make_pair(TString(input->Head().Content()), *cluster));
}
return IGraphTransformer::TStatus::Ok;
@@ -13506,18 +13506,18 @@ IGraphTransformer::TStatus ValidateProviders(const TExprNode::TPtr& input, TExpr
TOptimizeExprSettings settings(nullptr);
settings.VisitChanges = true;
auto status = OptimizeExpr(output, output, [&](const TExprNode::TPtr& input, TExprContext& ctx) -> TExprNode::TPtr {
- if (input->Content() == "DataSource") {
+ if (input->Content() == "DataSource") {
if (ValidateDataSource(input, ctx, types, clusters).Level == IGraphTransformer::TStatus::Error) {
return nullptr;
}
}
- else if (input->Content() == "DataSink") {
+ else if (input->Content() == "DataSink") {
if (ValidateDataSink(input, ctx, types, clusters).Level == IGraphTransformer::TStatus::Error) {
return nullptr;
}
}
- return input;
+ return input;
}, ctx, settings);
if (status != IGraphTransformer::TStatus::Ok) {
diff --git a/ydb/library/yql/core/type_ann/type_ann_core.h b/ydb/library/yql/core/type_ann/type_ann_core.h
index 147dc235d7..8396222009 100644
--- a/ydb/library/yql/core/type_ann/type_ann_core.h
+++ b/ydb/library/yql/core/type_ann/type_ann_core.h
@@ -7,8 +7,8 @@
namespace NYql {
-IGraphTransformer::TStatus ValidateDataSource(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types);
-IGraphTransformer::TStatus ValidateDataSink(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types);
+IGraphTransformer::TStatus ValidateDataSource(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types);
+IGraphTransformer::TStatus ValidateDataSink(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types);
IGraphTransformer::TStatus ValidateProviders(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, const TTypeAnnotationContext& types);
TAutoPtr<IGraphTransformer> CreateIntentDeterminationTransformer(const TTypeAnnotationContext& types);
diff --git a/ydb/library/yql/core/type_ann/type_ann_expr.cpp b/ydb/library/yql/core/type_ann/type_ann_expr.cpp
index 72d944ead0..f67d3b4120 100644
--- a/ydb/library/yql/core/type_ann/type_ann_expr.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_expr.cpp
@@ -42,7 +42,7 @@ public:
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
YQL_PROFILE_SCOPE(DEBUG, "TypeAnnotationTransformer::DoTransform");
- output = input;
+ output = input;
auto status = TransformNode(input, output, ctx);
UpdateStatusIfChanged(status, input, output);
if (status.Level != TStatus::Ok) {
@@ -50,7 +50,7 @@ public:
}
if (status.Level != TStatus::Error && HasRenames) {
- output = ctx.ReplaceNodes(std::move(output), Processed);
+ output = ctx.ReplaceNodes(std::move(output), Processed);
}
Processed.clear();
@@ -67,7 +67,7 @@ public:
YQL_PROFILE_SCOPE(DEBUG, "TypeAnnotationTransformer::DoGetAsyncFuture");
Y_UNUSED(input);
TVector<NThreading::TFuture<void>> futures;
- for (const auto& callable : CallableInputs) {
+ for (const auto& callable : CallableInputs) {
futures.push_back(CallableTransformer->GetAsyncFuture(*callable));
}
@@ -76,13 +76,13 @@ public:
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
YQL_PROFILE_SCOPE(DEBUG, "TypeAnnotationTransformer::DoApplyAsyncChanges");
- output = input;
+ output = input;
TStatus combinedStatus = TStatus::Ok;
- for (const auto& callable : CallableInputs) {
+ for (const auto& callable : CallableInputs) {
callable->SetState(TExprNode::EState::TypePending);
- TExprNode::TPtr callableOutput;
- auto status = CallableTransformer->ApplyAsyncChanges(callable, callableOutput, ctx);
- Y_VERIFY(callableOutput);
+ TExprNode::TPtr callableOutput;
+ auto status = CallableTransformer->ApplyAsyncChanges(callable, callableOutput, ctx);
+ Y_VERIFY(callableOutput);
YQL_ENSURE(status != TStatus::Async);
YQL_ENSURE(callableOutput == callable);
combinedStatus = combinedStatus.Combine(status);
@@ -140,9 +140,9 @@ private:
return IGraphTransformer::TStatus::Async;
case TExprNode::EState::TypePending:
if (start->Type() == TExprNode::Lambda) {
- if (!start->Head().GetTypeAnn()) {
+ if (!start->Head().GetTypeAnn()) {
return TStatus::Ok;
- } else if (start->Head().ChildrenSize() == 0) {
+ } else if (start->Head().ChildrenSize() == 0) {
break;
}
}
@@ -308,15 +308,15 @@ private:
case TExprNode::Lambda:
{
- YQL_ENSURE(input->ChildrenSize() > 0U);
- const auto& args = input->Head();
- for (ui32 i = 0; i < args.ChildrenSize(); ++i) {
- args.Child(i)->SetArgIndex(i);
+ YQL_ENSURE(input->ChildrenSize() > 0U);
+ const auto& args = input->Head();
+ for (ui32 i = 0; i < args.ChildrenSize(); ++i) {
+ args.Child(i)->SetArgIndex(i);
}
TExprNode::TPtr out;
- auto argStatus = TransformNode(input->HeadPtr(), out, ctx);
- UpdateStatusIfChanged(argStatus, input->HeadPtr(), out);
+ auto argStatus = TransformNode(input->HeadPtr(), out, ctx);
+ UpdateStatusIfChanged(argStatus, input->HeadPtr(), out);
if (argStatus.Level == TStatus::Error) {
input->SetState(TExprNode::EState::Error);
return argStatus;
@@ -325,44 +325,44 @@ private:
if (argStatus.Level == TStatus::Repeat)
return TStatus::Ok;
- TStatus combinedStatus = TStatus::Ok;
- TExprNode::TListType newChildren;
- newChildren.reserve(input->ChildrenSize());
- newChildren.emplace_back(input->HeadPtr());
- bool updatedChildren = false;
- for (ui32 i = 1U; i < input->ChildrenSize(); ++i) {
- const auto child = input->ChildPtr(i);
- TExprNode::TPtr newChild;
- auto childStatus = TransformNode(child, newChild, ctx);
- UpdateStatusIfChanged(childStatus, child, newChild);
- updatedChildren = updatedChildren || (newChild != child);
- combinedStatus = combinedStatus.Combine(childStatus);
- newChildren.emplace_back(std::move(newChild));
- }
-
+ TStatus combinedStatus = TStatus::Ok;
+ TExprNode::TListType newChildren;
+ newChildren.reserve(input->ChildrenSize());
+ newChildren.emplace_back(input->HeadPtr());
+ bool updatedChildren = false;
+ for (ui32 i = 1U; i < input->ChildrenSize(); ++i) {
+ const auto child = input->ChildPtr(i);
+ TExprNode::TPtr newChild;
+ auto childStatus = TransformNode(child, newChild, ctx);
+ UpdateStatusIfChanged(childStatus, child, newChild);
+ updatedChildren = updatedChildren || (newChild != child);
+ combinedStatus = combinedStatus.Combine(childStatus);
+ newChildren.emplace_back(std::move(newChild));
+ }
+
if (combinedStatus != TStatus::Ok) {
if (combinedStatus.Level == TStatus::Error) {
input->SetState(TExprNode::EState::Error);
}
- else if (updatedChildren) {
- input->ChangeChildrenInplace(std::move(newChildren));
+ else if (updatedChildren) {
+ input->ChangeChildrenInplace(std::move(newChildren));
}
retStatus = combinedStatus;
break;
}
- if (newChildren.size() != 2U) {
- TTypeAnnotationNode::TListType rootTypes;
- rootTypes.reserve(newChildren.size() - 1U);
- for (ui32 i = 1U; i < newChildren.size(); ++i) {
- rootTypes.emplace_back(newChildren[i]->GetTypeAnn());
- }
- input->SetTypeAnn(ctx.MakeType<TMultiExprType>(rootTypes));
- } else {
- input->SetTypeAnn(input->Tail().GetTypeAnn());
- }
-
+ if (newChildren.size() != 2U) {
+ TTypeAnnotationNode::TListType rootTypes;
+ rootTypes.reserve(newChildren.size() - 1U);
+ for (ui32 i = 1U; i < newChildren.size(); ++i) {
+ rootTypes.emplace_back(newChildren[i]->GetTypeAnn());
+ }
+ input->SetTypeAnn(ctx.MakeType<TMultiExprType>(rootTypes));
+ } else {
+ input->SetTypeAnn(input->Tail().GetTypeAnn());
+ }
+
if (input->GetTypeAnn()) {
CheckExpected(*input, ctx);
}
@@ -480,15 +480,15 @@ private:
auto childStatus = TransformNode(child, tmp, ctx);
UpdateStatusIfChanged(childStatus, child, tmp);
YQL_ENSURE(tmp == child);
- combinedStatus = combinedStatus.Combine(childStatus);
- }
+ combinedStatus = combinedStatus.Combine(childStatus);
+ }
- if (combinedStatus != TStatus::Ok) {
- if (combinedStatus.Level == TStatus::Error) {
+ if (combinedStatus != TStatus::Ok) {
+ if (combinedStatus.Level == TStatus::Error) {
input->SetState(TExprNode::EState::Error);
- }
-
- return combinedStatus;
+ }
+
+ return combinedStatus;
}
input->SetTypeAnn(ctx.MakeType<TUnitExprType>());
@@ -497,8 +497,8 @@ private:
default:
YQL_ENSURE(false, "Unknown type");
- }
-
+ }
+
if (retStatus.Level != TStatus::Repeat || retStatus.HasRestart) {
return retStatus;
}
@@ -554,8 +554,8 @@ private:
} // namespace
-IGraphTransformer::TStatus CheckWholeProgramType(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- output = input;
+IGraphTransformer::TStatus CheckWholeProgramType(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ output = input;
if (input->Type() == TExprNode::Lambda || input->GetTypeAnn()->GetKind() != ETypeAnnotationKind::World) {
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), "Return must be world"));
input->SetState(TExprNode::EState::Error);
@@ -636,7 +636,7 @@ TAutoPtr<IGraphTransformer> CreateFullTypeAnnotationTransformer(
}
bool SyncAnnotateTypes(
- TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
+ TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext)
{
auto fullTransformer = CreateFullTypeAnnotationTransformer(wholeProgram, typeAnnotationContext);
@@ -644,14 +644,14 @@ bool SyncAnnotateTypes(
}
bool InstantAnnotateTypes(
- TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
+ TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext)
{
auto fullTransformer = CreateFullTypeAnnotationTransformer(wholeProgram, typeAnnotationContext);
return InstantTransform(*fullTransformer, root, ctx) == IGraphTransformer::TStatus::Ok;
}
-TExprNode::TPtr ParseAndAnnotate(
+TExprNode::TPtr ParseAndAnnotate(
const TStringBuf& str,
TExprContext& exprCtx, bool instant, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext)
@@ -662,7 +662,7 @@ TExprNode::TPtr ParseAndAnnotate(
return nullptr;
}
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
if (!CompileExpr(*astRes.Root, exprRoot, exprCtx, nullptr)) {
return nullptr;
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_expr.h b/ydb/library/yql/core/type_ann/type_ann_expr.h
index 3ec7808326..914e71cede 100644
--- a/ydb/library/yql/core/type_ann/type_ann_expr.h
+++ b/ydb/library/yql/core/type_ann/type_ann_expr.h
@@ -14,14 +14,14 @@ TAutoPtr<IGraphTransformer> CreateTypeAnnotationTransformer(
TAutoPtr<IGraphTransformer> CreateFullTypeAnnotationTransformer(bool instant, bool wholeProgram, TTypeAnnotationContext& types);
bool SyncAnnotateTypes(
- TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
+ TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext);
bool InstantAnnotateTypes(
- TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
+ TExprNode::TPtr& root, TExprContext& ctx, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext);
-TExprNode::TPtr ParseAndAnnotate(
+TExprNode::TPtr ParseAndAnnotate(
const TStringBuf& str,
TExprContext& exprCtx, bool instant, bool wholeProgram,
TTypeAnnotationContext& typeAnnotationContext);
diff --git a/ydb/library/yql/core/type_ann/type_ann_impl.h b/ydb/library/yql/core/type_ann/type_ann_impl.h
index a8391830f4..3d940ebd73 100644
--- a/ydb/library/yql/core/type_ann/type_ann_impl.h
+++ b/ydb/library/yql/core/type_ann/type_ann_impl.h
@@ -25,11 +25,11 @@ namespace NTypeAnnImpl {
};
// Implemented in type_ann_join.cpp
- IGraphTransformer::TStatus JoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus JoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus JoinDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus MapJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus CommonJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus EquiJoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus MapJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus CommonJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus EquiJoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CombineCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus GroupingCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
diff --git a/ydb/library/yql/core/type_ann/type_ann_join.cpp b/ydb/library/yql/core/type_ann/type_ann_join.cpp
index 3b63309dd2..18516a8ab8 100644
--- a/ydb/library/yql/core/type_ann/type_ann_join.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_join.cpp
@@ -8,31 +8,31 @@ namespace NTypeAnnImpl {
using namespace NNodes;
- IGraphTransformer::TStatus JoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus JoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(*input->Child(1), ctx.Expr)) {
+ if (!EnsureListType(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1);
- status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
+ auto status = ConvertToLambda(input->ChildRef(2), ctx.Expr, 1);
+ status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (!EnsureAtom(*input->Child(4), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(4), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto joinKind = input->Child(4)->Content();
+ auto joinKind = input->Child(4)->Content();
if (joinKind != "Inner" && joinKind != "Left" && joinKind != "Right" && joinKind != "Full") {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(4)->Pos()), TStringBuilder() << "Unknown join kind: " << joinKind
<< ", supported: Inner, Right, Left, Full"));
@@ -75,13 +75,13 @@ namespace NTypeAnnImpl {
}
}
- auto& lambda1 = input->ChildRef(2);
- if (!UpdateLambdaAllArgumentsTypes(lambda1, {leftItemType}, ctx.Expr)) {
+ auto& lambda1 = input->ChildRef(2);
+ if (!UpdateLambdaAllArgumentsTypes(lambda1, {leftItemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambda2 = input->ChildRef(3);
- if (!UpdateLambdaAllArgumentsTypes(lambda2, {rightItemType}, ctx.Expr)) {
+ auto& lambda2 = input->ChildRef(3);
+ if (!UpdateLambdaAllArgumentsTypes(lambda2, {rightItemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -130,115 +130,115 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus JoinDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinMaxArgsCount(*input, 3U, 4U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto& left = input->Head();
- const auto& right = *input->Child(1U);
- const auto& kind = *input->Child(2U);
-
- if (!EnsureDictType(left, ctx.Expr) || !EnsureDictType(right, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureAtom(kind, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- bool leftUnique = false, rightUnique = false;
- if (input->ChildrenSize() > 3U) {
- if (!EnsureTupleOfAtoms(input->Tail(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- bool hasUnknown = false;
- input->Tail().ForEachChild([&](const TExprNode& flag) {
- if (const auto& content = flag.Content(); content == "LeftUnique")
- leftUnique = true;
- else if (content == "RightUnique")
- rightUnique = true;
- else {
- hasUnknown = true;
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(flag.Pos()), TStringBuilder() << "Unknown flag " << content));
- }
- });
- if (hasUnknown)
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto keyType = left.GetTypeAnn()->Cast<TDictExprType>()->GetKeyType();
- if (const auto rightKeyType = right.GetTypeAnn()->Cast<TDictExprType>()->GetKeyType(); !IsSameAnnotation(*keyType, *rightKeyType)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch dict key types: " << *keyType << " and " << *rightKeyType));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureDryType(input->Pos(), *keyType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto leftPayloadType = left.GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
- const auto rightPayloadType = right.GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
- const TTypeAnnotationNode* outputItemType = nullptr;
- if (const auto joinKind = kind.Content(); joinKind == "LeftOnly" || joinKind == "LeftSemi") {
- if (!leftUnique && leftPayloadType->GetKind() != ETypeAnnotationKind::List) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected multi dict on left side but got " << *left.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- if (rightPayloadType->GetKind() != ETypeAnnotationKind::Void) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected set on right side but got " << *right.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- outputItemType = leftUnique ? leftPayloadType : leftPayloadType->Cast<TListExprType>()->GetItemType();
- } else if (joinKind == "RightOnly" || joinKind == "RightSemi") {
- if (leftPayloadType->GetKind() != ETypeAnnotationKind::Void) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected set on left side but got " << *left.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- if (!rightUnique && rightPayloadType->GetKind() != ETypeAnnotationKind::List) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected multi dict on right side but got " << *right.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- outputItemType = rightUnique ? rightPayloadType : rightPayloadType->Cast<TListExprType>()->GetItemType();
- } else if (joinKind == "Inner" || joinKind == "Left" || joinKind == "Right" || joinKind == "Full" || joinKind == "Exclusion") {
- if (!leftUnique && leftPayloadType->GetKind() != ETypeAnnotationKind::List) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected multi dict on left side but got " << *left.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- if (!rightUnique && rightPayloadType->GetKind() != ETypeAnnotationKind::List) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected multi dict on right side but got " << *right.GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- TTypeAnnotationNode::TListType tupleItems = {
- leftUnique ? leftPayloadType : leftPayloadType->Cast<TListExprType>()->GetItemType(),
- rightUnique ? rightPayloadType : rightPayloadType->Cast<TListExprType>()->GetItemType()
- };
-
- if (joinKind == "Right" || joinKind == "Full" || joinKind == "Exclusion") {
- tupleItems.front() = ctx.Expr.MakeType<TOptionalExprType>(tupleItems.front());
- }
- if (joinKind == "Left" || joinKind == "Full" || joinKind == "Exclusion") {
- tupleItems.back() = ctx.Expr.MakeType<TOptionalExprType>(tupleItems.back());
- }
-
- outputItemType = ctx.Expr.MakeType<TTupleExprType>(tupleItems);
- } else {
- ctx.Expr.AddError(
- TIssue(ctx.Expr.GetPosition(kind.Pos()), TStringBuilder() << "Unsupported join kind: " << joinKind)
- );
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(outputItemType));
+ if (!EnsureMinMaxArgsCount(*input, 3U, 4U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto& left = input->Head();
+ const auto& right = *input->Child(1U);
+ const auto& kind = *input->Child(2U);
+
+ if (!EnsureDictType(left, ctx.Expr) || !EnsureDictType(right, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureAtom(kind, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool leftUnique = false, rightUnique = false;
+ if (input->ChildrenSize() > 3U) {
+ if (!EnsureTupleOfAtoms(input->Tail(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool hasUnknown = false;
+ input->Tail().ForEachChild([&](const TExprNode& flag) {
+ if (const auto& content = flag.Content(); content == "LeftUnique")
+ leftUnique = true;
+ else if (content == "RightUnique")
+ rightUnique = true;
+ else {
+ hasUnknown = true;
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(flag.Pos()), TStringBuilder() << "Unknown flag " << content));
+ }
+ });
+ if (hasUnknown)
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto keyType = left.GetTypeAnn()->Cast<TDictExprType>()->GetKeyType();
+ if (const auto rightKeyType = right.GetTypeAnn()->Cast<TDictExprType>()->GetKeyType(); !IsSameAnnotation(*keyType, *rightKeyType)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch dict key types: " << *keyType << " and " << *rightKeyType));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureDryType(input->Pos(), *keyType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto leftPayloadType = left.GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
+ const auto rightPayloadType = right.GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
+ const TTypeAnnotationNode* outputItemType = nullptr;
+ if (const auto joinKind = kind.Content(); joinKind == "LeftOnly" || joinKind == "LeftSemi") {
+ if (!leftUnique && leftPayloadType->GetKind() != ETypeAnnotationKind::List) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected multi dict on left side but got " << *left.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (rightPayloadType->GetKind() != ETypeAnnotationKind::Void) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected set on right side but got " << *right.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ outputItemType = leftUnique ? leftPayloadType : leftPayloadType->Cast<TListExprType>()->GetItemType();
+ } else if (joinKind == "RightOnly" || joinKind == "RightSemi") {
+ if (leftPayloadType->GetKind() != ETypeAnnotationKind::Void) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected set on left side but got " << *left.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!rightUnique && rightPayloadType->GetKind() != ETypeAnnotationKind::List) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected multi dict on right side but got " << *right.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ outputItemType = rightUnique ? rightPayloadType : rightPayloadType->Cast<TListExprType>()->GetItemType();
+ } else if (joinKind == "Inner" || joinKind == "Left" || joinKind == "Right" || joinKind == "Full" || joinKind == "Exclusion") {
+ if (!leftUnique && leftPayloadType->GetKind() != ETypeAnnotationKind::List) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(left.Pos()), TStringBuilder() << "Expected multi dict on left side but got " << *left.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!rightUnique && rightPayloadType->GetKind() != ETypeAnnotationKind::List) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(right.Pos()), TStringBuilder() << "Expected multi dict on right side but got " << *right.GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ TTypeAnnotationNode::TListType tupleItems = {
+ leftUnique ? leftPayloadType : leftPayloadType->Cast<TListExprType>()->GetItemType(),
+ rightUnique ? rightPayloadType : rightPayloadType->Cast<TListExprType>()->GetItemType()
+ };
+
+ if (joinKind == "Right" || joinKind == "Full" || joinKind == "Exclusion") {
+ tupleItems.front() = ctx.Expr.MakeType<TOptionalExprType>(tupleItems.front());
+ }
+ if (joinKind == "Left" || joinKind == "Full" || joinKind == "Exclusion") {
+ tupleItems.back() = ctx.Expr.MakeType<TOptionalExprType>(tupleItems.back());
+ }
+
+ outputItemType = ctx.Expr.MakeType<TTupleExprType>(tupleItems);
+ } else {
+ ctx.Expr.AddError(
+ TIssue(ctx.Expr.GetPosition(kind.Pos()), TStringBuilder() << "Unsupported join kind: " << joinKind)
+ );
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(outputItemType));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus EquiJoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) {
+ IGraphTransformer::TStatus EquiJoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const size_t numLists = input->ChildrenSize() - 2;
+ const size_t numLists = input->ChildrenSize() - 2;
auto optionsNode = input->Child(input->ChildrenSize() - 1);
TJoinOptions options;
@@ -250,12 +250,12 @@ namespace NTypeAnnImpl {
TJoinLabels labels;
TExprNode::TListType updatedChildren;
for (ui32 idx = 0; idx < numLists; ++idx) {
- auto& listPair = *input->Child(idx);
+ auto& listPair = *input->Child(idx);
if (!EnsureTupleSize(listPair, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto& list = listPair.Head();
+ const auto& list = listPair.Head();
if (!EnsureListType(list, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -300,7 +300,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Repeat;
}
- auto joins = input->Child(input->ChildrenSize() - 2);
+ auto joins = input->Child(input->ChildrenSize() - 2);
const TStructExprType* resultType = nullptr;
status = EquiJoinAnnotation(input->Pos(), resultType, labels, *joins, options, ctx.Expr);
if (status != IGraphTransformer::TStatus::Ok) {
@@ -311,93 +311,93 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- const TTypeAnnotationNode* GetFieldType(const TTupleExprType& tupleType, const ui32 position) {
- return tupleType.GetItems()[position];
- }
-
- const TTypeAnnotationNode* GetFieldType(const TMultiExprType& multiType, const ui32 position) {
- return multiType.GetItems()[position];
- }
-
- const TTypeAnnotationNode* GetFieldType(const TStructExprType& structType, const ui32 position) {
- return structType.GetItems()[position]->GetItemType();
- }
-
- template<class TLeftType>
- IGraphTransformer::TStatus MapJoinCoreWrapperT(const TExprNode::TPtr& input, const TLeftType& leftItemType, TContext& ctx) {
- constexpr bool ByStruct = std::is_same<TLeftType, TStructExprType>::value;
+ const TTypeAnnotationNode* GetFieldType(const TTupleExprType& tupleType, const ui32 position) {
+ return tupleType.GetItems()[position];
+ }
+
+ const TTypeAnnotationNode* GetFieldType(const TMultiExprType& multiType, const ui32 position) {
+ return multiType.GetItems()[position];
+ }
+
+ const TTypeAnnotationNode* GetFieldType(const TStructExprType& structType, const ui32 position) {
+ return structType.GetItems()[position]->GetItemType();
+ }
+
+ template<class TLeftType>
+ IGraphTransformer::TStatus MapJoinCoreWrapperT(const TExprNode::TPtr& input, const TLeftType& leftItemType, TContext& ctx) {
+ constexpr bool ByStruct = std::is_same<TLeftType, TStructExprType>::value;
const auto dictType = input->Child(1)->GetTypeAnn()->Cast<TDictExprType>();
- const auto dictPayloadType = dictType->GetPayloadType();
+ const auto dictPayloadType = dictType->GetPayloadType();
- if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto joinKind = input->Child(2)->Content();
+ const auto joinKind = input->Child(2)->Content();
if (joinKind != "Inner" && joinKind != "Left" && joinKind != "LeftSemi" && joinKind != "LeftOnly") {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), TStringBuilder() << "Unknown join kind: " << joinKind
<< ", supported: Inner, Left, LeftSemi, LeftOnly"));
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTupleOfAtoms(*input->Child(3), ctx.Expr)) {
+ if (!EnsureTupleOfAtoms(*input->Child(3), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
for (const auto& child : input->Child(3)->Children()) {
- if (!GetFieldPosition(leftItemType, child->Content())) {
+ if (!GetFieldPosition(leftItemType, child->Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown key column: " << child->Content()));
return IGraphTransformer::TStatus::Error;
}
}
- const TStructExprType* rightStructType = nullptr;
- const TTupleExprType* rightTupleType = nullptr;
- if (joinKind != "LeftSemi" && joinKind != "LeftOnly") {
- auto singleItemType = dictPayloadType;
- if (dictPayloadType->GetKind() == ETypeAnnotationKind::List) {
- singleItemType = dictPayloadType->Cast<TListExprType>()->GetItemType();
- }
+ const TStructExprType* rightStructType = nullptr;
+ const TTupleExprType* rightTupleType = nullptr;
+ if (joinKind != "LeftSemi" && joinKind != "LeftOnly") {
+ auto singleItemType = dictPayloadType;
+ if (dictPayloadType->GetKind() == ETypeAnnotationKind::List) {
+ singleItemType = dictPayloadType->Cast<TListExprType>()->GetItemType();
+ }
- switch (singleItemType->GetKind()) {
- case ETypeAnnotationKind::Struct:
- rightStructType = singleItemType->Cast<TStructExprType>();
- break;
- case ETypeAnnotationKind::Tuple:
- rightTupleType = singleItemType->Cast<TTupleExprType>();
- break;
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()),
- TStringBuilder() << "Expected tuple or struct payload type, but got: " << *singleItemType));
+ switch (singleItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct:
+ rightStructType = singleItemType->Cast<TStructExprType>();
+ break;
+ case ETypeAnnotationKind::Tuple:
+ rightTupleType = singleItemType->Cast<TTupleExprType>();
+ break;
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()),
+ TStringBuilder() << "Expected tuple or struct payload type, but got: " << *singleItemType));
return IGraphTransformer::TStatus::Error;
}
}
- const auto& leftRenames = *input->Child(4);
- const auto& rightRenames = *input->Child(5);
- if (!EnsureTupleOfAtoms(leftRenames, ctx.Expr)) {
+ const auto& leftRenames = *input->Child(4);
+ const auto& rightRenames = *input->Child(5);
+ if (!EnsureTupleOfAtoms(leftRenames, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (leftRenames.ChildrenSize() % 2 != 0) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(leftRenames.Pos()), TStringBuilder() << "Expected even count of atoms"));
+ if (leftRenames.ChildrenSize() % 2 != 0) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(leftRenames.Pos()), TStringBuilder() << "Expected even count of atoms"));
return IGraphTransformer::TStatus::Error;
}
- const auto outputSize = (leftRenames.ChildrenSize() + rightRenames.ChildrenSize()) >> 1U;
- std::conditional_t<ByStruct, TVector<const TItemExprType*>, TVector<const TTypeAnnotationNode*>> resultItems;
- if constexpr (ByStruct)
- resultItems.reserve(outputSize);
- else
- resultItems.resize(outputSize);
-
- THashSet<TStringBuf> outputColumns;
- outputColumns.reserve(outputSize);
- for (ui32 i = 0; i < leftRenames.ChildrenSize(); i += 2) {
- const auto oldName = leftRenames.Child(i);
- const auto newName = leftRenames.Child(i + 1);
+ const auto outputSize = (leftRenames.ChildrenSize() + rightRenames.ChildrenSize()) >> 1U;
+ std::conditional_t<ByStruct, TVector<const TItemExprType*>, TVector<const TTypeAnnotationNode*>> resultItems;
+ if constexpr (ByStruct)
+ resultItems.reserve(outputSize);
+ else
+ resultItems.resize(outputSize);
- const auto oldPos = GetFieldPosition(leftItemType, oldName->Content());
+ THashSet<TStringBuf> outputColumns;
+ outputColumns.reserve(outputSize);
+ for (ui32 i = 0; i < leftRenames.ChildrenSize(); i += 2) {
+ const auto oldName = leftRenames.Child(i);
+ const auto newName = leftRenames.Child(i + 1);
+
+ const auto oldPos = GetFieldPosition(leftItemType, oldName->Content());
if (!oldPos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(oldName->Pos()), TStringBuilder() << "Unknown column: " << oldName->Content()));
return IGraphTransformer::TStatus::Error;
@@ -408,40 +408,40 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!outputColumns.emplace(newName->Content()).second) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Duplicate output field: " << newName->Content()));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto columnType = GetFieldType(leftItemType, *oldPos);
-
- if constexpr (ByStruct)
- resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(newName->Content(), columnType));
- else {
- if (ui32 index; !TryFromString(newName->Content(), index) || index >= resultItems.size()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Invalid output field index: " << newName->Content()));
- return IGraphTransformer::TStatus::Error;
- } else {
- resultItems[index] = columnType;
- }
- }
+ if (!outputColumns.emplace(newName->Content()).second) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Duplicate output field: " << newName->Content()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto columnType = GetFieldType(leftItemType, *oldPos);
+
+ if constexpr (ByStruct)
+ resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(newName->Content(), columnType));
+ else {
+ if (ui32 index; !TryFromString(newName->Content(), index) || index >= resultItems.size()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Invalid output field index: " << newName->Content()));
+ return IGraphTransformer::TStatus::Error;
+ } else {
+ resultItems[index] = columnType;
+ }
+ }
}
- if (rightStructType || rightTupleType) {
- if (!EnsureTupleOfAtoms(rightRenames, ctx.Expr)) {
+ if (rightStructType || rightTupleType) {
+ if (!EnsureTupleOfAtoms(rightRenames, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (rightRenames.ChildrenSize() % 2 != 0) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(rightRenames.Pos()), TStringBuilder() << "Expected even count of atoms"));
+ if (rightRenames.ChildrenSize() % 2 != 0) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(rightRenames.Pos()), TStringBuilder() << "Expected even count of atoms"));
return IGraphTransformer::TStatus::Error;
}
- for (ui32 i = 0; i < rightRenames.ChildrenSize(); i += 2) {
- const auto oldName = rightRenames.Child(i);
- const auto newName = rightRenames.Child(i + 1);
+ for (ui32 i = 0; i < rightRenames.ChildrenSize(); i += 2) {
+ const auto oldName = rightRenames.Child(i);
+ const auto newName = rightRenames.Child(i + 1);
- const auto oldPos = rightStructType ? GetFieldPosition(*rightStructType, oldName->Content()) : GetFieldPosition(*rightTupleType, oldName->Content());
+ const auto oldPos = rightStructType ? GetFieldPosition(*rightStructType, oldName->Content()) : GetFieldPosition(*rightTupleType, oldName->Content());
if (!oldPos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(oldName->Pos()), TStringBuilder() << "Unknown column: " << oldName->Content()));
return IGraphTransformer::TStatus::Error;
@@ -452,81 +452,81 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!outputColumns.emplace(newName->Content()).second) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Duplicate output field: " << newName->Content()));
- return IGraphTransformer::TStatus::Error;
- }
-
- auto columnType = rightStructType ? GetFieldType(*rightStructType, *oldPos) : GetFieldType(*rightTupleType, *oldPos);
+ if (!outputColumns.emplace(newName->Content()).second) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Duplicate output field: " << newName->Content()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto columnType = rightStructType ? GetFieldType(*rightStructType, *oldPos) : GetFieldType(*rightTupleType, *oldPos);
if (joinKind == "Left" && !columnType->IsOptionalOrNull()) {
columnType = ctx.Expr.MakeType<TOptionalExprType>(columnType);
}
- if constexpr (ByStruct)
- resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(newName->Content(), columnType));
- else {
- if (ui32 index; !TryFromString(newName->Content(), index) || index >= resultItems.size()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Invalid output field index: " << newName->Content()));
- return IGraphTransformer::TStatus::Error;
- } else {
- resultItems[index] = columnType;
- }
- }
+ if constexpr (ByStruct)
+ resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(newName->Content(), columnType));
+ else {
+ if (ui32 index; !TryFromString(newName->Content(), index) || index >= resultItems.size()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(newName->Pos()), TStringBuilder() << "Invalid output field index: " << newName->Content()));
+ return IGraphTransformer::TStatus::Error;
+ } else {
+ resultItems[index] = columnType;
+ }
+ }
}
- } else if (!EnsureTupleSize(rightRenames, 0, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
+ } else if (!EnsureTupleSize(rightRenames, 0, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
}
- const auto resultItemType = ctx.Expr.MakeType<TLeftType>(resultItems);
- if (!resultItemType->Validate(input->Pos(), ctx.Expr)) {
+ const auto resultItemType = ctx.Expr.MakeType<TLeftType>(resultItems);
+ if (!resultItemType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus MapJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (input->ChildrenSize() == 7U) {
- // Drop unused argument: right key.
- auto children = input->ChildrenList();
- auto it = children.cbegin();
- std::advance(it, 4U);
- children.erase(it);
- output = ctx.Expr.ChangeChildren(*input, std::move(children));
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureArgsCount(*input, 6, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* leftItemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &leftItemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureDictType(*input->Child(1), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- switch (leftItemType->GetKind()) {
- case ETypeAnnotationKind::Struct:
- return MapJoinCoreWrapperT(input, *leftItemType->Cast<TStructExprType>(), ctx);
- case ETypeAnnotationKind::Tuple:
- return MapJoinCoreWrapperT(input, *leftItemType->Cast<TTupleExprType>(), ctx);
- case ETypeAnnotationKind::Multi:
- return MapJoinCoreWrapperT(input, *leftItemType->Cast<TMultiExprType>(), ctx);
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected tuple or struct or multi item type, but got: " << *leftItemType));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- template<class TInputType>
- IGraphTransformer::TStatus CommonJoinCoreWrapperT(const TExprNode::TPtr& input, const TInputType& inputItemType, TContext& ctx) {
- constexpr bool ByStruct = std::is_same<TInputType, TStructExprType>::value;
-
- const auto joinKind = input->Child(1)->Content();
+ IGraphTransformer::TStatus MapJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (input->ChildrenSize() == 7U) {
+ // Drop unused argument: right key.
+ auto children = input->ChildrenList();
+ auto it = children.cbegin();
+ std::advance(it, 4U);
+ children.erase(it);
+ output = ctx.Expr.ChangeChildren(*input, std::move(children));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureArgsCount(*input, 6, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* leftItemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &leftItemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureDictType(*input->Child(1), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ switch (leftItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct:
+ return MapJoinCoreWrapperT(input, *leftItemType->Cast<TStructExprType>(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return MapJoinCoreWrapperT(input, *leftItemType->Cast<TTupleExprType>(), ctx);
+ case ETypeAnnotationKind::Multi:
+ return MapJoinCoreWrapperT(input, *leftItemType->Cast<TMultiExprType>(), ctx);
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected tuple or struct or multi item type, but got: " << *leftItemType));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ template<class TInputType>
+ IGraphTransformer::TStatus CommonJoinCoreWrapperT(const TExprNode::TPtr& input, const TInputType& inputItemType, TContext& ctx) {
+ constexpr bool ByStruct = std::is_same<TInputType, TStructExprType>::value;
+
+ const auto joinKind = input->Child(1)->Content();
if (joinKind != "Inner" && joinKind != "Left" && joinKind != "Right" && joinKind != "Full"
&& joinKind != "LeftOnly" && joinKind != "RightOnly" && joinKind != "Exclusion"
&& joinKind != "LeftSemi" && joinKind != "RightSemi" && joinKind != "Cross") {
@@ -535,26 +535,26 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- const auto tableIndexFieldName = input->Tail().Content();
- const auto tableIndexPos = GetFieldPosition(inputItemType, tableIndexFieldName);
+ const auto tableIndexFieldName = input->Tail().Content();
+ const auto tableIndexPos = GetFieldPosition(inputItemType, tableIndexFieldName);
if (!tableIndexPos) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Missing required field: " << tableIndexFieldName));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Missing required field: " << tableIndexFieldName));
return IGraphTransformer::TStatus::Error;
}
- if (const auto tableIndexType = GetFieldType(inputItemType, *tableIndexPos); !EnsureSpecificDataType(input->Head().Pos(), *tableIndexType, EDataSlot::Uint32, ctx.Expr)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected type Uint32 for field " << tableIndexFieldName << ", but got: "
- << *tableIndexType));
+ if (const auto tableIndexType = GetFieldType(inputItemType, *tableIndexPos); !EnsureSpecificDataType(input->Head().Pos(), *tableIndexType, EDataSlot::Uint32, ctx.Expr)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected type Uint32 for field " << tableIndexFieldName << ", but got: "
+ << *tableIndexType));
return IGraphTransformer::TStatus::Error;
}
- THashSet<TStringBuf> leftColumns, rightColumns, fullColumns, requiredColumns, keyColumns;
+ THashSet<TStringBuf> leftColumns, rightColumns, fullColumns, requiredColumns, keyColumns;
if (joinKind == "RightOnly" || joinKind == "RightSemi") {
- if (!EnsureTupleSize(*input->Child(2), 0, ctx.Expr)) {
+ if (!EnsureTupleSize(*input->Child(2), 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- } else {
- if (!EnsureTuple(*input->Child(2), ctx.Expr)) {
+ } else {
+ if (!EnsureTuple(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -563,7 +563,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- const auto pos = GetFieldPosition(inputItemType, child->Content());
+ const auto pos = GetFieldPosition(inputItemType, child->Content());
if (!pos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown column: " << child->Content()));
return IGraphTransformer::TStatus::Error;
@@ -574,7 +574,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto inputColumnType = GetFieldType(inputItemType, *pos); !inputColumnType->IsOptionalOrNull()) {
+ if (const auto inputColumnType = GetFieldType(inputItemType, *pos); !inputColumnType->IsOptionalOrNull()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Expected optional or null type for column: " << child->Content() << ", but got: " << *inputColumnType));
return IGraphTransformer::TStatus::Error;
}
@@ -582,11 +582,11 @@ namespace NTypeAnnImpl {
}
if (joinKind == "LeftOnly" || joinKind == "LeftSemi") {
- if (!EnsureTupleSize(*input->Child(3), 0, ctx.Expr)) {
+ if (!EnsureTupleSize(*input->Child(3), 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- } else {
- if (!EnsureTuple(*input->Child(3), ctx.Expr)) {
+ } else {
+ if (!EnsureTuple(*input->Child(3), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -595,7 +595,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- const auto pos = GetFieldPosition(inputItemType, child->Content());
+ const auto pos = GetFieldPosition(inputItemType, child->Content());
if (!pos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown column: " << child->Content()));
return IGraphTransformer::TStatus::Error;
@@ -606,14 +606,14 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto inputColumnType = GetFieldType(inputItemType, *pos); !inputColumnType->IsOptionalOrNull()) {
+ if (const auto inputColumnType = GetFieldType(inputItemType, *pos); !inputColumnType->IsOptionalOrNull()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Expected optional or null type for column: " << child->Content() << ", but got: " << *inputColumnType));
return IGraphTransformer::TStatus::Error;
}
}
}
- if (!EnsureTuple(*input->Child(4), ctx.Expr)) {
+ if (!EnsureTuple(*input->Child(4), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -632,7 +632,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (leftColumns.contains(child->Content())) {
+ if (leftColumns.contains(child->Content())) {
if (IsLeftJoinSideOptional(joinKind)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Required column " << child->Content() << " cannot be at the left side for the join kind: " << joinKind));
return IGraphTransformer::TStatus::Error;
@@ -645,7 +645,7 @@ namespace NTypeAnnImpl {
}
}
- if (!EnsureTuple(*input->Child(5), ctx.Expr)) {
+ if (!EnsureTuple(*input->Child(5), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -654,7 +654,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto pos = GetFieldPosition(inputItemType, child->Content()); !pos) {
+ if (const auto pos = GetFieldPosition(inputItemType, child->Content()); !pos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown column: " << child->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -670,16 +670,16 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(child->Head(), ctx.Expr)) {
+ if (!EnsureAtom(child->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (const auto optionName = child->Head().Content(); !seenOptions.insert(optionName).second) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Head().Pos()), TStringBuilder() <<
+ if (const auto optionName = child->Head().Content(); !seenOptions.insert(optionName).second) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Head().Pos()), TStringBuilder() <<
"Duplicate option: " << optionName));
return IGraphTransformer::TStatus::Error;
}
- else if (optionName == "sorted") {
+ else if (optionName == "sorted") {
if (!EnsureTupleSize(*child, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -688,7 +688,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto side = child->Child(1)->Content(); side != "left" && side != "right") {
+ if (const auto side = child->Child(1)->Content(); side != "left" && side != "right") {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Child(1)->Pos()), TStringBuilder() <<
"Unknown sorted side, expected left or right, but got: " << side));
return IGraphTransformer::TStatus::Error;
@@ -703,7 +703,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (ui64 memLimit = 0ULL; !TryFromString(child->Child(1)->Content(), memLimit)) {
+ if (ui64 memLimit = 0ULL; !TryFromString(child->Child(1)->Content(), memLimit)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Child(1)->Pos()), TStringBuilder() <<
"Bad memLimit value: " << child->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
@@ -744,73 +744,73 @@ namespace NTypeAnnImpl {
}
}
- std::conditional_t<ByStruct, TVector<const TItemExprType*>, TVector<const TTypeAnnotationNode*>> resultItems;
- resultItems.reserve(fullColumns.size());
-
+ std::conditional_t<ByStruct, TVector<const TItemExprType*>, TVector<const TTypeAnnotationNode*>> resultItems;
+ resultItems.reserve(fullColumns.size());
+
for (const auto& child : input->Child(2)->Children()) {
- const auto pos = GetFieldPosition(inputItemType, child->Content());
- auto inputColumnType = GetFieldType(inputItemType, *pos);
+ const auto pos = GetFieldPosition(inputItemType, child->Content());
+ auto inputColumnType = GetFieldType(inputItemType, *pos);
if (requiredColumns.contains(child->Content())) {
- inputColumnType = inputColumnType->template Cast<TOptionalExprType>()->GetItemType();
+ inputColumnType = inputColumnType->template Cast<TOptionalExprType>()->GetItemType();
}
- if constexpr (ByStruct)
- resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(child->Content(), inputColumnType));
- else
- resultItems.emplace_back(inputColumnType);
+ if constexpr (ByStruct)
+ resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(child->Content(), inputColumnType));
+ else
+ resultItems.emplace_back(inputColumnType);
}
for (const auto& child : input->Child(3)->Children()) {
- const auto pos = GetFieldPosition(inputItemType, child->Content());
- auto inputColumnType = GetFieldType(inputItemType, *pos);
+ const auto pos = GetFieldPosition(inputItemType, child->Content());
+ auto inputColumnType = GetFieldType(inputItemType, *pos);
if (requiredColumns.contains(child->Content())) {
- inputColumnType = inputColumnType->template Cast<TOptionalExprType>()->GetItemType();
+ inputColumnType = inputColumnType->template Cast<TOptionalExprType>()->GetItemType();
}
- if constexpr (ByStruct)
- resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(child->Content(), inputColumnType));
- else
- resultItems.emplace_back(inputColumnType);
+ if constexpr (ByStruct)
+ resultItems.emplace_back(ctx.Expr.MakeType<TItemExprType>(child->Content(), inputColumnType));
+ else
+ resultItems.emplace_back(inputColumnType);
}
- const auto resultItemType = ctx.Expr.MakeType<TInputType>(resultItems);
- if (!resultItemType->Validate(input->Pos(), ctx.Expr)) {
+ const auto resultItemType = ctx.Expr.MakeType<TInputType>(resultItems);
+ if (!resultItemType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CommonJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 8U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* inputItemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &inputItemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- switch (inputItemType->GetKind()) {
- case ETypeAnnotationKind::Struct:
- return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TStructExprType>(), ctx);
- case ETypeAnnotationKind::Tuple:
- return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TTupleExprType>(), ctx);
- case ETypeAnnotationKind::Multi:
- return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TMultiExprType>(), ctx);
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected tuple or struct or multi item type, but got: " << *inputItemType));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
+ IGraphTransformer::TStatus CommonJoinCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 8U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* inputItemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &inputItemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ switch (inputItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct:
+ return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TStructExprType>(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TTupleExprType>(), ctx);
+ case ETypeAnnotationKind::Multi:
+ return CommonJoinCoreWrapperT(input, *inputItemType->Cast<TMultiExprType>(), ctx);
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "Expected tuple or struct or multi item type, but got: " << *inputItemType));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
} // namespace NTypeAnnImpl
} // namespace NYql
diff --git a/ydb/library/yql/core/type_ann/type_ann_list.cpp b/ydb/library/yql/core/type_ann/type_ann_list.cpp
index 2a8590a968..b145cde389 100644
--- a/ydb/library/yql/core/type_ann/type_ann_list.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_list.cpp
@@ -119,9 +119,9 @@ namespace {
TNodeOnNodeOwnedMap factoryReplaces;
factoryReplaces[traitsFactory->Head().Child(0)] = listType ? ExpandType(node.Pos(), *listType->GetItemType(), ctx) : node.HeadPtr();
- factoryReplaces[traitsFactory->Head().Child(1)] = extractor;
+ factoryReplaces[traitsFactory->Head().Child(1)] = extractor;
- auto traits = ctx.ReplaceNodes(traitsFactory->ChildPtr(1), factoryReplaces);
+ auto traits = ctx.ReplaceNodes(traitsFactory->ChildPtr(1), factoryReplaces);
ctx.Step.Repeat(TExprStep::ExpandApplyForLambdas);
auto status = ExpandApply(traits, traits, ctx);
if (status == IGraphTransformer::TStatus::Error) {
@@ -133,8 +133,8 @@ namespace {
auto initLambda = traits->Child(1);
TNodeOnNodeOwnedMap replaces;
replaces[initLambda->Head().Child(0)] = listType ? listItemArg : initArg1;
- if (initLambda->Head().ChildrenSize() == 2) {
- replaces[initLambda->Head().Child(1)] = initArg2;
+ if (initLambda->Head().ChildrenSize() == 2) {
+ replaces[initLambda->Head().Child(1)] = initArg2;
}
auto replaced = ctx.ReplaceNodes(initLambda->TailPtr(), replaces);
@@ -160,8 +160,8 @@ namespace {
replaces[updateLambda->Head().Child(1)] = structType ?
ctx.NewCallable(node.Pos(), "Member", { updateArg2, memberAtom }) :
ctx.NewCallable(node.Pos(), "Nth", { listType ? listItemArg : updateArg2, listType ? atom1 : nthAtom });
- if (updateLambda->Head().ChildrenSize() == 3) {
- replaces[updateLambda->Head().Child(2)] = updateArg3;
+ if (updateLambda->Head().ChildrenSize() == 3) {
+ replaces[updateLambda->Head().Child(2)] = updateArg3;
}
auto replaced = ctx.ReplaceNodes(updateLambda->TailPtr(), replaces);
@@ -587,7 +587,7 @@ namespace {
const TTypeAnnotationNode& finishType, TStringBuf finishName, TExprNode::TPtr& output, TContext& ctx)
{
auto defaultValue = input->Child(defaultValueIndex);
- if (!defaultValue->IsCallable({"Null", "EmptyList"})) {
+ if (!defaultValue->IsCallable({"Null", "EmptyList"})) {
if (defaultValue->IsLambda()) {
if (!EnsureMinArgsCount(defaultValue->Head(), 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -612,8 +612,8 @@ namespace {
}
auto finishItemType = RemoveOptionalType(&finishType);
- if (finishItemType->GetKind() != ETypeAnnotationKind::Null && finishItemType->GetKind() != ETypeAnnotationKind::EmptyList
- && !IsSameAnnotation(*finishItemType, *defaultValue->GetTypeAnn())) {
+ if (finishItemType->GetKind() != ETypeAnnotationKind::Null && finishItemType->GetKind() != ETypeAnnotationKind::EmptyList
+ && !IsSameAnnotation(*finishItemType, *defaultValue->GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(defaultValue->Pos()),
TStringBuilder() << "Mismatch of default value type and " << finishName
<< " type: " << *defaultValue->GetTypeAnn() << " != " << finishType));
@@ -625,43 +625,43 @@ namespace {
}
} // namespace
- IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
+ IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (input->ChildrenSize() > 2U) {
- const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
- if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()),
- TStringBuilder() << "Mismatch 'limit' type. Expected Uint64, got: " << *input->Tail().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ if (input->ChildrenSize() > 2U) {
+ const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()),
+ TStringBuilder() << "Mismatch 'limit' type. Expected Uint64, got: " << *input->Tail().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambda = input->ChildRef(1);
- const auto status = ConvertToLambda(lambda, ctx.Expr, 1);
+ auto& lambda = input->ChildRef(1);
+ const auto status = ConvertToLambda(lambda, ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -673,96 +673,96 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- template<bool InverseCondition>
- IGraphTransformer::TStatus InclusiveFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ template<bool InverseCondition>
+ IGraphTransformer::TStatus InclusiveFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- output = InverseCondition ?
- ctx.Expr.Builder(input->Pos())
- .Callable("Nothing")
- .Add(0, ExpandType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr))
- .Seal().Build():
- input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto& lambda = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- template
- IGraphTransformer::TStatus InclusiveFilterWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- template
- IGraphTransformer::TStatus InclusiveFilterWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- IGraphTransformer::TStatus MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ output = InverseCondition ?
+ ctx.Expr.Builder(input->Pos())
+ .Callable("Nothing")
+ .Add(0, ExpandType(input->Pos(), *input->Head().GetTypeAnn(), ctx.Expr))
+ .Seal().Build():
+ input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto& lambda = input->TailRef();
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ template
+ IGraphTransformer::TStatus InclusiveFilterWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ template
+ IGraphTransformer::TStatus InclusiveFilterWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ IGraphTransformer::TStatus MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
+ const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ auto& lambda = input->TailRef();
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -770,16 +770,16 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (&lambda->Head().Head() == &lambda->Tail()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (&lambda->Head().Head() == &lambda->Tail()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (!EnsureComputableType(lambda->Pos(), *lambda->GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *lambda->GetTypeAnn(), ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *lambda->GetTypeAnn(), ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
@@ -789,18 +789,18 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
+ const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda = input->TailRef();
+ auto& lambda = input->TailRef();
const TTypeAnnotationNode* itemType =
- input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
auto handlerStreamType = ctx.Expr.MakeType<TStreamExprType>(itemType);
if (!UpdateLambdaAllArgumentsTypes(lambda, { handlerStreamType }, ctx.Expr)) {
@@ -833,7 +833,7 @@ namespace {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
@@ -842,11 +842,11 @@ namespace {
auto& initState = *input->ChildRef(1);
auto& lambda = input->ChildRef(2);
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
-
+
if (!EnsureComputable(initState, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -885,7 +885,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updatedListType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updatedListType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
@@ -893,7 +893,7 @@ namespace {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
-
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
@@ -902,11 +902,11 @@ namespace {
auto& initLambda = input->ChildRef(1);
auto& updateLambda = input->ChildRef(2);
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
-
+
auto status = ConvertToLambda(initLambda, ctx.Expr, 1);
status = status.Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
if (status.Level != IGraphTransformer::TStatus::Ok) {
@@ -952,65 +952,65 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updatedListType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updatedListType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus Chain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsEmptyList(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto& initLambda = input->ChildRef(1);
- auto& updateLambda = input->ChildRef(2);
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto status = ConvertToLambda(initLambda, ctx.Expr, 1);
+ IGraphTransformer::TStatus Chain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsEmptyList(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto& initLambda = input->ChildRef(1);
+ auto& updateLambda = input->ChildRef(2);
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto status = ConvertToLambda(initLambda, ctx.Expr, 1);
status = status.Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(initLambda, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto lambdaType = initLambda->GetTypeAnn();
- if (!lambdaType) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(updateLambda, {itemType, lambdaType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto updateLambdaType = updateLambda->GetTypeAnn();
- if (!updateLambdaType) {
- return IGraphTransformer::TStatus::Repeat;
- }
- if (!IsSameAnnotation(*lambdaType, *updateLambdaType)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(updateLambda->Pos()), TStringBuilder() <<
- "Mismatch of update and init lambda types: " <<
- *updateLambdaType << " != " << *lambdaType));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updateLambdaType, ctx.Expr));
- return IGraphTransformer::TStatus::Ok;
- }
-
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(initLambda, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto lambdaType = initLambda->GetTypeAnn();
+ if (!lambdaType) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(updateLambda, {itemType, lambdaType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto updateLambdaType = updateLambda->GetTypeAnn();
+ if (!updateLambdaType) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ if (!IsSameAnnotation(*lambdaType, *updateLambdaType)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(updateLambda->Pos()), TStringBuilder() <<
+ "Mismatch of update and init lambda types: " <<
+ *updateLambdaType << " != " << *lambdaType));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *updateLambdaType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
template <bool Warn>
- IGraphTransformer::TStatus FlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus FlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1019,19 +1019,19 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
+ const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambda = input->TailRef();
+ auto& lambda = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1039,30 +1039,30 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- const auto retKind = lambda->GetTypeAnn()->GetKind();
- // input F L S O
- // lambda L F L S L
- // lambda S F L S S
- // lambda O F L S O
- // lambda F F F - F
+ const auto retKind = lambda->GetTypeAnn()->GetKind();
+ // input F L S O
+ // lambda L F L S L
+ // lambda S F L S S
+ // lambda O F L S O
+ // lambda F F F - F
bool warn = false;
auto resultKind = input->Head().GetTypeAnn()->GetKind();
const TTypeAnnotationNode* lambdaItemType = nullptr;
- switch (retKind) {
- case ETypeAnnotationKind::List:
- lambdaItemType = lambda->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- break;
- case ETypeAnnotationKind::Stream:
- lambdaItemType = lambda->GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
- break;
- case ETypeAnnotationKind::Optional:
+ switch (retKind) {
+ case ETypeAnnotationKind::List:
+ lambdaItemType = lambda->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ break;
+ case ETypeAnnotationKind::Stream:
+ lambdaItemType = lambda->GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
+ break;
+ case ETypeAnnotationKind::Optional:
if (input->Content().EndsWith("Warn")) {
warn = true;
}
- lambdaItemType = lambda->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
- break;
+ lambdaItemType = lambda->GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ break;
case ETypeAnnotationKind::Null: {
if (input->Content().EndsWith("Warn")) {
warn = true;
@@ -1080,21 +1080,21 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- case ETypeAnnotationKind::Flow:
- if (ETypeAnnotationKind::Stream != input->Head().GetTypeAnn()->GetKind()) {
- lambdaItemType = lambda->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- resultKind = ETypeAnnotationKind::Flow;
- break;
- }
+ case ETypeAnnotationKind::Flow:
+ if (ETypeAnnotationKind::Stream != input->Head().GetTypeAnn()->GetKind()) {
+ lambdaItemType = lambda->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ resultKind = ETypeAnnotationKind::Flow;
+ break;
+ }
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder()
- << "Expected list, stream or optional as FlatMap lambda return type, but got: " << *lambda->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder()
+ << "Expected list, stream or optional as FlatMap lambda return type, but got: " << *lambda->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
}
- if (ETypeAnnotationKind::Optional == resultKind) {
- resultKind = retKind;
+ if (ETypeAnnotationKind::Optional == resultKind) {
+ resultKind = retKind;
}
if (warn) {
@@ -1113,7 +1113,7 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- input->SetTypeAnn(MakeSequenceType(resultKind, *lambdaItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(resultKind, *lambdaItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
@@ -1124,87 +1124,87 @@ namespace {
IGraphTransformer::TStatus FlatMapWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- template<bool Ordered>
- IGraphTransformer::TStatus MultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsEmptyList(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false, true, false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (input->Tail().ChildrenSize() < 3U) {
- output = ctx.Expr.RenameNode(*input, Ordered ? "OrderedMap" : "Map");
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto& lambda = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto lambdaItemType = lambda->Tail().GetTypeAnn();
- for (ui32 i = 1U; i < lambda->ChildrenSize() - 1U; ++i) {
- if (!IsSameAnnotation(*lambdaItemType, *lambda->Child(i)->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder()
- << input->Content() << " lambda returns types is not same."));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- const auto resultKind = input->Head().GetTypeAnn()->GetKind();
- input->SetTypeAnn(MakeSequenceType(resultKind, *lambdaItemType, ctx.Expr));
- return IGraphTransformer::TStatus::Ok;
- }
-
- 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>
+ template<bool Ordered>
+ IGraphTransformer::TStatus MultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsEmptyList(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false, true, false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 1);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (input->Tail().ChildrenSize() < 3U) {
+ output = ctx.Expr.RenameNode(*input, Ordered ? "OrderedMap" : "Map");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto& lambda = input->TailRef();
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto lambdaItemType = lambda->Tail().GetTypeAnn();
+ for (ui32 i = 1U; i < lambda->ChildrenSize() - 1U; ++i) {
+ if (!IsSameAnnotation(*lambdaItemType, *lambda->Child(i)->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder()
+ << input->Content() << " lambda returns types is not same."));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ const auto resultKind = input->Head().GetTypeAnn()->GetKind();
+ input->SetTypeAnn(MakeSequenceType(resultKind, *lambdaItemType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ 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) {
- if (MinArgsCount == MaxArgsCount) {
- if (!EnsureArgsCount(*input, MinArgsCount, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- if (!(EnsureMinArgsCount(*input, MinArgsCount, ctx.Expr) && EnsureMaxArgsCount(*input, MaxArgsCount, ctx.Expr))) {
- return IGraphTransformer::TStatus::Error;
- }
+ if (MinArgsCount == MaxArgsCount) {
+ if (!EnsureArgsCount(*input, MinArgsCount, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ if (!(EnsureMinArgsCount(*input, MinArgsCount, ctx.Expr) && EnsureMaxArgsCount(*input, MaxArgsCount, ctx.Expr))) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
bool isOptional = false;
- auto type = input->Head().GetTypeAnn();
+ auto type = input->Head().GetTypeAnn();
if (type->GetKind() == ETypeAnnotationKind::Optional) {
type = type->Cast<TOptionalExprType>()->GetItemType();
isOptional = true;
@@ -1217,16 +1217,16 @@ namespace {
}
if (isOptional) {
- output = AddChildren(ctx.Expr.Builder(input->Pos())
- .Callable(UseFlatMap ? "FlatMap" : "Map")
- .Add(0, input->HeadPtr())
+ output = AddChildren(ctx.Expr.Builder(input->Pos())
+ .Callable(UseFlatMap ? "FlatMap" : "Map")
+ .Add(0, input->HeadPtr())
.Lambda(1)
.Param("x")
.Callable(name)
- .Arg(0, "x"), 1U, input)
+ .Arg(0, "x"), 1U, input)
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
} else {
output = ctx.Expr.RenameNode(*input, name);
}
@@ -1246,14 +1246,14 @@ namespace {
return OptListWrapperImpl(input, output, ctx, "OrderedFlatMapWarn");
}
- IGraphTransformer::TStatus ListSkipWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl(input, output, ctx, "SkipWhileInclusive");
- }
-
- IGraphTransformer::TStatus ListTakeWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl(input, output, ctx, "TakeWhileInclusive");
- }
-
+ IGraphTransformer::TStatus ListSkipWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl(input, output, ctx, "SkipWhileInclusive");
+ }
+
+ IGraphTransformer::TStatus ListTakeWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl(input, output, ctx, "TakeWhileInclusive");
+ }
+
IGraphTransformer::TStatus ListSkipWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return OptListWrapperImpl(input, output, ctx, "SkipWhile");
}
@@ -1262,61 +1262,61 @@ namespace {
return OptListWrapperImpl(input, output, ctx, "TakeWhile");
}
- IGraphTransformer::TStatus ListSkipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl(input, output, ctx, "Skip");
- }
-
- IGraphTransformer::TStatus ListHeadWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<1U, 1U, true>(input, output, ctx, "Head");
- }
-
- IGraphTransformer::TStatus ListLastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<1U, 1U, true>(input, output, ctx, "Last");
- }
-
- IGraphTransformer::TStatus ListTakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl(input, output, ctx, "Take");
- }
-
- IGraphTransformer::TStatus ListEnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<1U, 3U>(input, output, ctx, "Enumerate");
- }
-
- IGraphTransformer::TStatus ListReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<1U>(input, output, ctx, "Reverse");
- }
-
- IGraphTransformer::TStatus ListSortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<3U>(input, output, ctx, "Sort");
- }
-
- IGraphTransformer::TStatus ListExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<2U>(input, output, ctx, "OrderedExtract");
- }
-
- IGraphTransformer::TStatus ListCollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListWrapperImpl<1U>(input, output, ctx, "Collect");
- }
-
- IGraphTransformer::TStatus OptListFold1WrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, TExprNode::TPtr&& updateLambda) {
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ IGraphTransformer::TStatus ListSkipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl(input, output, ctx, "Skip");
+ }
+
+ IGraphTransformer::TStatus ListHeadWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<1U, 1U, true>(input, output, ctx, "Head");
+ }
+
+ IGraphTransformer::TStatus ListLastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<1U, 1U, true>(input, output, ctx, "Last");
+ }
+
+ IGraphTransformer::TStatus ListTakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl(input, output, ctx, "Take");
+ }
+
+ IGraphTransformer::TStatus ListEnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<1U, 3U>(input, output, ctx, "Enumerate");
+ }
+
+ IGraphTransformer::TStatus ListReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<1U>(input, output, ctx, "Reverse");
+ }
+
+ IGraphTransformer::TStatus ListSortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<3U>(input, output, ctx, "Sort");
+ }
+
+ IGraphTransformer::TStatus ListExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<2U>(input, output, ctx, "OrderedExtract");
+ }
+
+ IGraphTransformer::TStatus ListCollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListWrapperImpl<1U>(input, output, ctx, "Collect");
+ }
+
+ IGraphTransformer::TStatus OptListFold1WrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, TExprNode::TPtr&& updateLambda) {
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (input->Head().GetTypeAnn() && IsEmptyList(*RemoveOptionalType(input->Head().GetTypeAnn()))) {
output = ctx.Expr.NewCallable(input->Pos(), "Null", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto type = input->Head().GetTypeAnn();
+ if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto type = input->Head().GetTypeAnn();
TExprNode::TPtr fold1Input = input->HeadPtr();
- if (type->GetKind() == ETypeAnnotationKind::Optional) {
- type = type->Cast<TOptionalExprType>()->GetItemType();
+ if (type->GetKind() == ETypeAnnotationKind::Optional) {
+ type = type->Cast<TOptionalExprType>()->GetItemType();
fold1Input = ctx.Expr.Builder(input->Head().Pos())
.Callable("Coalesce")
.Add(0, input->HeadPtr())
@@ -1325,20 +1325,20 @@ namespace {
.Seal()
.Seal()
.Build();
- }
-
+ }
+
output = ctx.Expr.Builder(input->Pos())
- .Callable("Fold1")
+ .Callable("Fold1")
.Add(0, fold1Input)
.Lambda(1)
.Param("item")
.Arg("item")
.Seal()
- .Add(2, std::move(updateLambda))
+ .Add(2, std::move(updateLambda))
.Seal()
.Build();
- const auto itemType = type->Cast<TListExprType>()->GetItemType();
+ const auto itemType = type->Cast<TListExprType>()->GetItemType();
if (itemType->GetKind() == ETypeAnnotationKind::Optional) {
// remove extra optional level created by Fold1
output = ctx.Expr.Builder(input->Pos())
@@ -1350,181 +1350,181 @@ namespace {
.Seal()
.Seal()
.Build();
- }
-
- return IGraphTransformer::TStatus::Repeat;
- }
-
- IGraphTransformer::TStatus OptListFold1WrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, TStringBuf name) {
- if (!EnsureArgsCount(*input, 1U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto lambda = ctx.Expr.Builder(input->Pos())
- .Lambda()
- .Param("item")
- .Param("state")
- .Callable(name)
- .Arg(0, "state")
- .Arg(1, "item")
- .Seal()
- .Seal().Build();
-
- return OptListFold1WrapperImpl(input, output, ctx, std::move(lambda));
- }
-
- IGraphTransformer::TStatus ListMinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListFold1WrapperImpl(input, output, ctx, "AggrMin");
- }
-
- IGraphTransformer::TStatus ListMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListFold1WrapperImpl(input, output, ctx, "AggrMax");
- }
-
- IGraphTransformer::TStatus ListSumWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- return OptListFold1WrapperImpl(input, output, ctx, "AggrAdd");
- }
-
- IGraphTransformer::TStatus ListConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMaxArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (2U > input->ChildrenSize()) {
- return OptListFold1WrapperImpl(input, output, ctx, "AggrConcat");
- }
-
- if (IsNull(input->Tail())) {
- output = ctx.Expr.ChangeChildren(*input, {input->HeadPtr()});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool isOptional;
- if (const TDataExprType* data; !EnsureDataOrOptionalOfData(input->Tail(), isOptional, data, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (isOptional) {
- output = ctx.Expr.Builder(input->Pos())
- .Callable("IfPresent")
- .Add(0, input->TailPtr())
- .Lambda(1)
- .Param("separator")
- .Callable(input->Content())
- .Add(0, input->HeadPtr())
- .Arg(1, "separator")
- .Seal()
- .Seal()
- .Callable(2, input->Content())
- .Add(0, input->HeadPtr())
- .Seal()
- .Seal().Build();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto lambda = ctx.Expr.Builder(input->Pos())
- .Lambda()
- .Param("item")
- .Param("state")
- .Callable("AggrConcat")
- .Callable(0, "Concat")
- .Arg(0, "state")
- .Add(1, input->TailPtr())
- .Seal()
- .Arg(1, "item")
- .Seal()
- .Seal().Build();
- return OptListFold1WrapperImpl(input, output, ctx, std::move(lambda));
- }
-
- IGraphTransformer::TStatus ListAvgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (input->Head().GetTypeAnn() && IsEmptyList(*RemoveOptionalType(input->Head().GetTypeAnn()))) {
+ }
+
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ IGraphTransformer::TStatus OptListFold1WrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, TStringBuf name) {
+ if (!EnsureArgsCount(*input, 1U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto lambda = ctx.Expr.Builder(input->Pos())
+ .Lambda()
+ .Param("item")
+ .Param("state")
+ .Callable(name)
+ .Arg(0, "state")
+ .Arg(1, "item")
+ .Seal()
+ .Seal().Build();
+
+ return OptListFold1WrapperImpl(input, output, ctx, std::move(lambda));
+ }
+
+ IGraphTransformer::TStatus ListMinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListFold1WrapperImpl(input, output, ctx, "AggrMin");
+ }
+
+ IGraphTransformer::TStatus ListMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListFold1WrapperImpl(input, output, ctx, "AggrMax");
+ }
+
+ IGraphTransformer::TStatus ListSumWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return OptListFold1WrapperImpl(input, output, ctx, "AggrAdd");
+ }
+
+ IGraphTransformer::TStatus ListConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMaxArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (2U > input->ChildrenSize()) {
+ return OptListFold1WrapperImpl(input, output, ctx, "AggrConcat");
+ }
+
+ if (IsNull(input->Tail())) {
+ output = ctx.Expr.ChangeChildren(*input, {input->HeadPtr()});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool isOptional;
+ if (const TDataExprType* data; !EnsureDataOrOptionalOfData(input->Tail(), isOptional, data, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (isOptional) {
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("IfPresent")
+ .Add(0, input->TailPtr())
+ .Lambda(1)
+ .Param("separator")
+ .Callable(input->Content())
+ .Add(0, input->HeadPtr())
+ .Arg(1, "separator")
+ .Seal()
+ .Seal()
+ .Callable(2, input->Content())
+ .Add(0, input->HeadPtr())
+ .Seal()
+ .Seal().Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto lambda = ctx.Expr.Builder(input->Pos())
+ .Lambda()
+ .Param("item")
+ .Param("state")
+ .Callable("AggrConcat")
+ .Callable(0, "Concat")
+ .Arg(0, "state")
+ .Add(1, input->TailPtr())
+ .Seal()
+ .Arg(1, "item")
+ .Seal()
+ .Seal().Build();
+ return OptListFold1WrapperImpl(input, output, ctx, std::move(lambda));
+ }
+
+ IGraphTransformer::TStatus ListAvgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (input->Head().GetTypeAnn() && IsEmptyList(*RemoveOptionalType(input->Head().GetTypeAnn()))) {
output = ctx.Expr.NewCallable(input->Pos(), "Null", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- output = ctx.Expr.Builder(input->Pos())
- .Callable("FlatMap")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("list")
- .Callable(input->Content())
- .Arg(0, "list")
- .Seal()
- .Seal()
- .Seal().Build();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto itemType = RemoveOptionalType(input->Head().GetTypeAnn())->Cast<TListExprType>()->GetItemType();
-
- bool isOptionalItem;
- const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head().Pos(), itemType, isOptionalItem, dataType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto targetSlot = EDataSlot::Float == dataType->GetSlot() || GetDataTypeInfo(dataType->GetSlot()).FixedSize < 4U ?
- EDataSlot::Float : EDataSlot::Double;
-
- if (dataType->GetSlot() != targetSlot || isOptionalItem) {
- auto cast = ctx.Expr.Builder(input->Head().Pos())
- .Callable("SafeCast")
- .Add(0, input->HeadPtr())
- .Callable(1, "ListType")
- .Callable(0, "DataType")
- .Atom(0, GetDataTypeInfo(targetSlot).Name, TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal().Build();
- output = ctx.Expr.ChangeChild(*input, 0U, std::move(cast));
- } else {
- const auto list = ctx.Expr.Builder(input->Pos())
- .Callable("ListCollect")
- .Add(0, input->HeadPtr())
- .Seal().Build();
-
- output = ctx.Expr.Builder(input->Pos())
- .Callable("Div")
- .Callable(0, "ListSum")
- .Add(0, list)
- .Seal()
- .Callable(1, "Length")
- .Add(0, list)
- .Seal()
- .Seal().Build();
- }
-
- return IGraphTransformer::TStatus::Repeat;
- }
-
- template <bool AllOrAny>
- IGraphTransformer::TStatus ListAllAnyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto stub = MakeBool<AllOrAny>(input->Pos(), ctx.Expr);
- if (IsNull(input->Head())) {
- output = std::move(stub);
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto listType = input->Head().GetTypeAnn();
+ if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("FlatMap")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("list")
+ .Callable(input->Content())
+ .Arg(0, "list")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto itemType = RemoveOptionalType(input->Head().GetTypeAnn())->Cast<TListExprType>()->GetItemType();
+
+ bool isOptionalItem;
+ const TDataExprType* dataType;
+ if (!EnsureDataOrOptionalOfData(input->Head().Pos(), itemType, isOptionalItem, dataType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto targetSlot = EDataSlot::Float == dataType->GetSlot() || GetDataTypeInfo(dataType->GetSlot()).FixedSize < 4U ?
+ EDataSlot::Float : EDataSlot::Double;
+
+ if (dataType->GetSlot() != targetSlot || isOptionalItem) {
+ auto cast = ctx.Expr.Builder(input->Head().Pos())
+ .Callable("SafeCast")
+ .Add(0, input->HeadPtr())
+ .Callable(1, "ListType")
+ .Callable(0, "DataType")
+ .Atom(0, GetDataTypeInfo(targetSlot).Name, TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ output = ctx.Expr.ChangeChild(*input, 0U, std::move(cast));
+ } else {
+ const auto list = ctx.Expr.Builder(input->Pos())
+ .Callable("ListCollect")
+ .Add(0, input->HeadPtr())
+ .Seal().Build();
+
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("Div")
+ .Callable(0, "ListSum")
+ .Add(0, list)
+ .Seal()
+ .Callable(1, "Length")
+ .Add(0, list)
+ .Seal()
+ .Seal().Build();
+ }
+
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ template <bool AllOrAny>
+ IGraphTransformer::TStatus ListAllAnyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto stub = MakeBool<AllOrAny>(input->Pos(), ctx.Expr);
+ if (IsNull(input->Head())) {
+ output = std::move(stub);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto listType = input->Head().GetTypeAnn();
if (HasError(listType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1535,111 +1535,111 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (listType->GetKind() == ETypeAnnotationKind::Optional) {
- listType = listType->Cast<TOptionalExprType>()->GetItemType();
- }
-
+ if (listType->GetKind() == ETypeAnnotationKind::Optional) {
+ listType = listType->Cast<TOptionalExprType>()->GetItemType();
+ }
+
if (IsEmptyList(*listType)) {
output = stub;
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head().Pos(), *listType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto itemType = listType->Cast<TListExprType>()->GetItemType();
-
- bool isOptionalItem;
- const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(input->Head().Pos(), itemType, isOptionalItem, dataType, ctx.Expr) || !EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *listType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto itemType = listType->Cast<TListExprType>()->GetItemType();
+
+ bool isOptionalItem;
+ const TDataExprType* dataType;
+ if (!EnsureDataOrOptionalOfData(input->Head().Pos(), itemType, isOptionalItem, dataType, ctx.Expr) || !EnsureSpecificDataType(input->Head().Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() << "List of " << *itemType << " instead of boolean."));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto coalesce = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- return isOptionalItem ?
- parent
- .Callable("Coalesce")
- .Arg(0, "item")
- .Callable(1, "Bool")
- .Atom(0, "false", TNodeFlags::Default)
- .Seal()
- .Seal():
- parent.Arg("item");
- };
-
- const auto filter = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- return AllOrAny ? coalesce(parent):
- isOptionalItem ?
- parent
- .Callable("Not")
- .Callable(0, "Coalesce")
- .Arg(0, "item")
- .Callable(1, "Bool")
- .Atom(0, "false", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal():
- parent.Callable("Not").Arg(0, "item").Seal();
- };
-
- output = ctx.Expr.Builder(input->Pos())
- .Callable("IfPresent")
- .Callable(0, "ListLast")
- .Callable(0, "ListTakeWhileInclusive")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Do(filter)
- .Seal()
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("item")
- .Do(coalesce)
- .Seal()
- .Add(2, std::move(stub))
- .Seal().Build();
-
- return IGraphTransformer::TStatus::Repeat;
- }
-
- template
- IGraphTransformer::TStatus ListAllAnyWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- template
- IGraphTransformer::TStatus ListAllAnyWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- IGraphTransformer::TStatus PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto coalesce = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ return isOptionalItem ?
+ parent
+ .Callable("Coalesce")
+ .Arg(0, "item")
+ .Callable(1, "Bool")
+ .Atom(0, "false", TNodeFlags::Default)
+ .Seal()
+ .Seal():
+ parent.Arg("item");
+ };
+
+ const auto filter = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ return AllOrAny ? coalesce(parent):
+ isOptionalItem ?
+ parent
+ .Callable("Not")
+ .Callable(0, "Coalesce")
+ .Arg(0, "item")
+ .Callable(1, "Bool")
+ .Atom(0, "false", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal():
+ parent.Callable("Not").Arg(0, "item").Seal();
+ };
+
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("IfPresent")
+ .Callable(0, "ListLast")
+ .Callable(0, "ListTakeWhileInclusive")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Do(filter)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("item")
+ .Do(coalesce)
+ .Seal()
+ .Add(2, std::move(stub))
+ .Seal().Build();
+
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ template
+ IGraphTransformer::TStatus ListAllAnyWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ template
+ IGraphTransformer::TStatus ListAllAnyWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ IGraphTransformer::TStatus PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!EnsureListOrEmptyType(input->Tail(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (input->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::EmptyList) {
output = ctx.Expr.NewCallable(input->Pos(), "AsList", { input->HeadPtr() });
return IGraphTransformer::TStatus::Repeat;
}
- auto expectedType = input->Tail().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- auto convertStatus = TryConvertTo(input->HeadRef(), *expectedType, ctx.Expr);
- if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch type of item being prepended and list"));
- return IGraphTransformer::TStatus::Error;
- } else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
- return convertStatus;
- }
-
- input->SetTypeAnn(input->Tail().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ auto expectedType = input->Tail().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ auto convertStatus = TryConvertTo(input->HeadRef(), *expectedType, ctx.Expr);
+ if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch type of item being prepended and list"));
+ return IGraphTransformer::TStatus::Error;
+ } else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ return convertStatus;
+ }
+
+ input->SetTypeAnn(input->Tail().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1652,37 +1652,37 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- auto expectedType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ auto expectedType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Mismatch type of item being appended and list"));
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Mismatch type of item being appended and list"));
return IGraphTransformer::TStatus::Error;
} else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus LengthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus LengthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = MakeNothingData(ctx.Expr, input->Head().Pos(), "Uint64");
+ if (IsNull(input->Head())) {
+ output = MakeNothingData(ctx.Expr, input->Head().Pos(), "Uint64");
return IGraphTransformer::TStatus::Repeat;
}
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Type() == TExprNode::Lambda);
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Type() == TExprNode::Lambda);
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
<< "Expected (optional) list or dict type, but got lambda"));
return IGraphTransformer::TStatus::Error;
}
- auto originalType = input->Head().GetTypeAnn();
+ auto originalType = input->Head().GetTypeAnn();
auto type = originalType;
bool isOptional = false;
if (type->GetKind() == ETypeAnnotationKind::Optional) {
@@ -1718,26 +1718,26 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus IteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus IteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Type() == TExprNode::Lambda);
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Type() == TExprNode::Lambda);
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
<< "Expected (optional) list, but got lambda"));
return IGraphTransformer::TStatus::Error;
}
- for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
+ for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
if (!EnsureDependsOn(*input->Child(i), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
- auto originalType = input->Head().GetTypeAnn();
+ auto originalType = input->Head().GetTypeAnn();
auto type = originalType;
if (type->GetKind() == ETypeAnnotationKind::Optional) {
type = type->Cast<TOptionalExprType>()->GetItemType();
@@ -1754,9 +1754,9 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus EmptyIteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus EmptyIteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1764,8 +1764,8 @@ namespace {
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureNewSeqType<false, false>(input->Head().Pos(), *type, ctx.Expr)) {
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureNewSeqType<false, false>(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1779,8 +1779,8 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1793,26 +1793,26 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
- output = input->HeadPtr();
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
output = ctx.Expr.RenameNode(*input, "Iterator");
return IGraphTransformer::TStatus::Repeat;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
- output = ctx.Expr.RenameNode(*input, "FromFlow");
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
+ output = ctx.Expr.RenameNode(*input, "FromFlow");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
if (!EnsureDependsOn(*input->Child(i), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1828,15 +1828,15 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- switch (input->Head().GetTypeAnn()->GetKind()) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ switch (input->Head().GetTypeAnn()->GetKind()) {
case ETypeAnnotationKind::Stream:
case ETypeAnnotationKind::List:
case ETypeAnnotationKind::Optional:
- output = input->HeadPtr();
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
default:
output = ctx.Expr.RenameNode(*input, "Just");
@@ -1844,35 +1844,35 @@ namespace {
}
}
- IGraphTransformer::TStatus LazyListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ IGraphTransformer::TStatus LazyListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
+ if (!EnsureListOrOptionalListType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus CollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1882,15 +1882,15 @@ namespace {
}
const TTypeAnnotationNode* itemType = nullptr;
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
- itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- } else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
- itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- } else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
- itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow) {
+ itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ } else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
+ itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ } else if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
+ itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
} else {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
- << "Expected list or stream type, but got: " << *input->Head().GetTypeAnn()));
+ << "Expected list or stream type, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -1899,75 +1899,75 @@ namespace {
}
IGraphTransformer::TStatus ListFromRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
+ if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!(EnsureDataType(input->Head(), ctx.Expr) && EnsureDataType(*input->Child(1U), ctx.Expr))) {
+ if (!(EnsureDataType(input->Head(), ctx.Expr) && EnsureDataType(*input->Child(1U), ctx.Expr))) {
return IGraphTransformer::TStatus::Error;
}
-
- const auto stepType = input->ChildrenSize() == 2U ? nullptr : input->Tail().GetTypeAnn();
- if (stepType && !EnsureDataType(input->Tail().Pos(), *stepType, ctx.Expr)) {
+
+ const auto stepType = input->ChildrenSize() == 2U ? nullptr : input->Tail().GetTypeAnn();
+ if (stepType && !EnsureDataType(input->Tail().Pos(), *stepType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* commonType = nullptr;
- if (stepType && IsDataTypeFloat(stepType->Cast<TDataExprType>()->GetSlot())) {
- commonType = stepType;
- if (const auto status = TrySilentConvertTo(input->ChildRef(0U), *stepType, ctx.Expr); IGraphTransformer::TStatus::Ok != status) {
- if (IGraphTransformer::TStatus::Error == status) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0U)->Pos()), TStringBuilder() << "Impossible silent convert bound of type " <<
- *input->Child(0U)->GetTypeAnn() << " into " << *stepType));
+ const TTypeAnnotationNode* commonType = nullptr;
+ if (stepType && IsDataTypeFloat(stepType->Cast<TDataExprType>()->GetSlot())) {
+ commonType = stepType;
+ if (const auto status = TrySilentConvertTo(input->ChildRef(0U), *stepType, ctx.Expr); IGraphTransformer::TStatus::Ok != status) {
+ if (IGraphTransformer::TStatus::Error == status) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0U)->Pos()), TStringBuilder() << "Impossible silent convert bound of type " <<
+ *input->Child(0U)->GetTypeAnn() << " into " << *stepType));
}
- return status;
+ return status;
}
- if (const auto status = TrySilentConvertTo(input->ChildRef(1U), *stepType, ctx.Expr); IGraphTransformer::TStatus::Ok != status) {
- if (IGraphTransformer::TStatus::Error == status) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()), TStringBuilder() << "Impossible silent convert bound of type " <<
- *input->Child(1U)->GetTypeAnn() << " into " << *stepType));
+ if (const auto status = TrySilentConvertTo(input->ChildRef(1U), *stepType, ctx.Expr); IGraphTransformer::TStatus::Ok != status) {
+ if (IGraphTransformer::TStatus::Error == status) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()), TStringBuilder() << "Impossible silent convert bound of type " <<
+ *input->Child(1U)->GetTypeAnn() << " into " << *stepType));
}
- return status;
- }
- } else if (const auto status = SilentInferCommonType(input->ChildRef(0U), input->ChildRef(1U), ctx.Expr, commonType); IGraphTransformer::TStatus::Ok != status) {
- if (IGraphTransformer::TStatus::Error == status) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Uncompatible types of bounds " <<
- *input->Child(0U)->GetTypeAnn() << " and " << *input->Child(1U)->GetTypeAnn()));
- }
- return status;
- }
-
- const auto slot = commonType->Cast<TDataExprType>()->GetSlot();
- if (!(IsDataTypeDateOrTzDateOrInterval(slot) || IsDataTypeNumeric(slot))) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected type of bounds is numeric or datetime, but got " << *commonType));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (const auto stepSlot = IsDataTypeDateOrTzDateOrInterval(slot) ? EDataSlot::Interval : MakeSigned(slot); stepType) {
- if (const auto requredStepType = slot == stepSlot ? commonType : ctx.Expr.MakeType<TDataExprType>(stepSlot); !IsSameAnnotation(*stepType, *requredStepType)) {
- if (const auto status = TrySilentConvertTo(input->ChildRef(2U), *requredStepType, ctx.Expr); IGraphTransformer::TStatus::Repeat == status)
- return status;
- else if (IGraphTransformer::TStatus::Error == status && !EnsureSpecificDataType(input->Tail().Pos(), *stepType, stepSlot, ctx.Expr))
- return status;
- }
- } else {
- TExprNode::TPtr value;
- switch (slot) {
+ return status;
+ }
+ } else if (const auto status = SilentInferCommonType(input->ChildRef(0U), input->ChildRef(1U), ctx.Expr, commonType); IGraphTransformer::TStatus::Ok != status) {
+ if (IGraphTransformer::TStatus::Error == status) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Uncompatible types of bounds " <<
+ *input->Child(0U)->GetTypeAnn() << " and " << *input->Child(1U)->GetTypeAnn()));
+ }
+ return status;
+ }
+
+ const auto slot = commonType->Cast<TDataExprType>()->GetSlot();
+ if (!(IsDataTypeDateOrTzDateOrInterval(slot) || IsDataTypeNumeric(slot))) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Expected type of bounds is numeric or datetime, but got " << *commonType));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (const auto stepSlot = IsDataTypeDateOrTzDateOrInterval(slot) ? EDataSlot::Interval : MakeSigned(slot); stepType) {
+ if (const auto requredStepType = slot == stepSlot ? commonType : ctx.Expr.MakeType<TDataExprType>(stepSlot); !IsSameAnnotation(*stepType, *requredStepType)) {
+ if (const auto status = TrySilentConvertTo(input->ChildRef(2U), *requredStepType, ctx.Expr); IGraphTransformer::TStatus::Repeat == status)
+ return status;
+ else if (IGraphTransformer::TStatus::Error == status && !EnsureSpecificDataType(input->Tail().Pos(), *stepType, stepSlot, ctx.Expr))
+ return status;
+ }
+ } else {
+ TExprNode::TPtr value;
+ switch (slot) {
case EDataSlot::Date:
case EDataSlot::TzDate:
- value = ctx.Expr.NewAtom(input->Pos(), "86400000000", TNodeFlags::Default);
+ value = ctx.Expr.NewAtom(input->Pos(), "86400000000", TNodeFlags::Default);
break;
case EDataSlot::Datetime:
case EDataSlot::TzDatetime:
- value = ctx.Expr.NewAtom(input->Pos(), "1000000", TNodeFlags::Default);
+ value = ctx.Expr.NewAtom(input->Pos(), "1000000", TNodeFlags::Default);
break;
default:
- value = ctx.Expr.NewAtom(input->Pos(), "1", TNodeFlags::Default);
+ value = ctx.Expr.NewAtom(input->Pos(), "1", TNodeFlags::Default);
break;
}
- auto newChildren = input->ChildrenList();
- newChildren.emplace_back(ctx.Expr.NewCallable(input->Pos(), NKikimr::NUdf::GetDataTypeInfo(stepSlot).Name, {std::move(value)}));
+ auto newChildren = input->ChildrenList();
+ newChildren.emplace_back(ctx.Expr.NewCallable(input->Pos(), NKikimr::NUdf::GetDataTypeInfo(stepSlot).Name, {std::move(value)}));
output = ctx.Expr.ChangeChildren(*input, std::move(newChildren));
return IGraphTransformer::TStatus::Repeat;
}
@@ -1982,12 +1982,12 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -1997,7 +1997,7 @@ namespace {
return convertStatus;
}
- input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(input->Head().GetTypeAnn()));
+ input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Ok;
}
@@ -2007,12 +2007,12 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* inputItemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &inputItemType)) {
+ const TTypeAnnotationNode* inputItemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &inputItemType)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsurePersistableType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
+ if (!EnsurePersistableType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2030,7 +2030,7 @@ namespace {
ui32 inputStreamsCount = 1;
if (inputItemType->GetKind() == ETypeAnnotationKind::Variant) {
auto underlyingType = inputItemType->Cast<TVariantExprType>()->GetUnderlyingType();
- if (!EnsureTupleType(input->Head().Pos(), *underlyingType, ctx.Expr)) {
+ if (!EnsureTupleType(input->Head().Pos(), *underlyingType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2049,28 +2049,28 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- TVector<const TTypeAnnotationNode*> lambdaInputItemTypes;
- std::unordered_set<ui32> indxs;
- for (const auto& child : input->Child(i)->Children()) {
+ TVector<const TTypeAnnotationNode*> lambdaInputItemTypes;
+ std::unordered_set<ui32> indxs;
+ for (const auto& child : input->Child(i)->Children()) {
if (!EnsureAtom(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
ui32 index = 0;
if (!TryFromString(child->Content(), index)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
<< "Failed to convert to integer: " << child->Content()));
return IGraphTransformer::TStatus::Error;
}
- if (!indxs.emplace(index).second) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
- << "Duplicate stream index: " << index));
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!indxs.emplace(index).second) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
+ << "Duplicate stream index: " << index));
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (index >= inputStreamsCount) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
<< "Wrong stream index: "
<< index << ", count: " << inputStreamsCount));
return IGraphTransformer::TStatus::Error;
@@ -2079,7 +2079,7 @@ namespace {
lambdaInputItemTypes.push_back(inputStreams ? inputStreams->GetItems()[index] : inputItemType);
}
- if (lambdaInputItemTypes.empty()) {
+ if (lambdaInputItemTypes.empty()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Pos()), "At least one stream index must be specified"));
}
@@ -2093,13 +2093,13 @@ namespace {
return status;
}
- const auto lambdaInputItemType = 1U == lambdaInputItemTypes.size() ?
- lambdaInputItemTypes.front(): ctx.Expr.MakeType<TVariantExprType>(ctx.Expr.MakeType<TTupleExprType>(lambdaInputItemTypes));
+ const auto lambdaInputItemType = 1U == lambdaInputItemTypes.size() ?
+ lambdaInputItemTypes.front(): ctx.Expr.MakeType<TVariantExprType>(ctx.Expr.MakeType<TTupleExprType>(lambdaInputItemTypes));
+
+ const auto lambdaInputType = MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *lambdaInputItemType, ctx.Expr);
- const auto lambdaInputType = MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *lambdaInputItemType, ctx.Expr);
-
auto& lambda = input->ChildRef(i + 1);
- if (!UpdateLambdaAllArgumentsTypes(lambda, { lambdaInputType }, ctx.Expr)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, { lambdaInputType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2107,7 +2107,7 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* lambdaItemType = nullptr;
+ const TTypeAnnotationNode* lambdaItemType = nullptr;
if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream) {
if (!EnsureStreamType(lambda->Pos(), *lambda->GetTypeAnn(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -2130,38 +2130,38 @@ namespace {
continue;
}
- const auto underlyingType = lambdaItemType->Cast<TVariantExprType>()->GetUnderlyingType();
+ const auto underlyingType = lambdaItemType->Cast<TVariantExprType>()->GetUnderlyingType();
if (!EnsureTupleType(lambda->Pos(), *underlyingType, ctx.Expr)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), "Lambda output variant must be tuple based"));
return IGraphTransformer::TStatus::Error;
}
- const auto lambdaTupleType = underlyingType->Cast<TTupleExprType>();
+ const auto lambdaTupleType = underlyingType->Cast<TTupleExprType>();
for (auto& x : lambdaTupleType->GetItems()) {
outputStreamItems.push_back(x);
}
}
- const auto resultItemType = 1U == outputStreamItems.size() ?
- outputStreamItems.front() : ctx.Expr.MakeType<TVariantExprType>(ctx.Expr.MakeType<TTupleExprType>(outputStreamItems));
+ const auto resultItemType = 1U == outputStreamItems.size() ?
+ outputStreamItems.front() : ctx.Expr.MakeType<TVariantExprType>(ctx.Expr.MakeType<TTupleExprType>(outputStreamItems));
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resultItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus HasItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus HasItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!input->Head().GetTypeAnn()) {
- YQL_ENSURE(input->Type() == TExprNode::Lambda);
+ if (!input->Head().GetTypeAnn()) {
+ YQL_ENSURE(input->Type() == TExprNode::Lambda);
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
<< "Expected (optional) (empty) list or dict type, but got lambda"));
return IGraphTransformer::TStatus::Error;
}
- auto originalType = input->Head().GetTypeAnn();
+ auto originalType = input->Head().GetTypeAnn();
auto type = originalType;
bool isOptional = false;
if (type->GetKind() == ETypeAnnotationKind::Optional) {
@@ -2193,7 +2193,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!input->ChildrenSize()) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
@@ -2207,17 +2207,17 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- auto listType = input->Head().GetTypeAnn();
- for (ui32 i = 0; i < input->ChildrenSize(); ++i) {
- if (!EnsureNewSeqType<false>(*input->Child(i), ctx.Expr)) {
+ auto listType = input->Head().GetTypeAnn();
+ for (ui32 i = 0; i < input->ChildrenSize(); ++i) {
+ if (!EnsureNewSeqType<false>(*input->Child(i), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (i && !IsSameAnnotation(*listType, *input->Child(i)->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder()
- << "Mismatch type of sequences being extended: "
- << GetTypeDiff(*listType, *input->Child(i)->GetTypeAnn())));
- return IGraphTransformer::TStatus::Error;
+ if (i && !IsSameAnnotation(*listType, *input->Child(i)->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder()
+ << "Mismatch type of sequences being extended: "
+ << GetTypeDiff(*listType, *input->Child(i)->GetTypeAnn())));
+ return IGraphTransformer::TStatus::Error;
}
}
@@ -2225,7 +2225,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus UnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus UnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!input->ChildrenSize()) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
@@ -2242,7 +2242,7 @@ namespace {
auto tmpArg1 = ctx.Expr.NewArgument(input->Pos(), "tmp1");
auto tmpArg2 = ctx.Expr.NewArgument(input->Pos(), "tmp2");
THashMap<TStringBuf, std::pair<const TTypeAnnotationNode*, ui32>> members;
- ui32 inputsCount = input->ChildrenSize();
+ ui32 inputsCount = input->ChildrenSize();
auto checkStructType = [&members, &ctx, tmpArg1, tmpArg2, inputsCount, pos = input->Pos()](TExprNode& input) -> const TStructExprType* {
if (!EnsureListType(input, ctx.Expr)) {
return nullptr;
@@ -2289,7 +2289,7 @@ namespace {
};
TVector<const TStructExprType*> structTypes;
- for (auto child : input->Children()) {
+ for (auto child : input->Children()) {
auto structType = checkStructType(*child);
if (!structType) {
return IGraphTransformer::TStatus::Error;
@@ -2326,7 +2326,7 @@ namespace {
}
auto structType = ctx.Expr.MakeType<TStructExprType>(resultItems);
- if (!structType->Validate(input->Pos(), ctx.Expr)) {
+ if (!structType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2402,7 +2402,7 @@ namespace {
auto arg2 = ctx.Expr.NewArgument(child ->Pos(), "arg2");
const TTypeAnnotationNode* commonType = nullptr;
auto status = SilentInferCommonType(arg1, *resultTypes[i], arg2, *childTypes[i], ctx.Expr, commonType);
- if (status == IGraphTransformer::TStatus::Error) {
+ if (status == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
<< "Can not infer common type for result column " << resultColumnOrder[i]
<< ": no common type for " << *resultTypes[i] << " and column " << (*childColumnOrder)[i]
@@ -2472,12 +2472,12 @@ namespace {
// pack all nodes to tuple
output = ctx.Expr.Builder(input->Pos())
.Callable("Map")
- .Callable(0, "FilterNullElements")
- .Callable(0, "Just")
- .List(0)
- .Add(input->ChildrenList())
- .Seal()
- .Seal()
+ .Callable(0, "FilterNullElements")
+ .Callable(0, "Just")
+ .List(0)
+ .Add(input->ChildrenList())
+ .Seal()
+ .Seal()
.Seal()
.Lambda(1)
.Param("item")
@@ -2486,7 +2486,7 @@ namespace {
for (ui32 i = 0; i < input->ChildrenSize(); ++i) {
builder.Callable(i, "Nth")
.Arg(0, "item")
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Seal();
}
@@ -2501,15 +2501,15 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- template<bool IsStrict>
+ template<bool IsStrict>
IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!input->ChildrenSize()) {
- output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool hasEmptyList = false;
- for (const auto& child : input->Children()) {
+ if (!input->ChildrenSize()) {
+ output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool hasEmptyList = false;
+ for (const auto& child : input->Children()) {
if (!child->GetTypeAnn()) {
YQL_ENSURE(child->Type() == TExprNode::Lambda);
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
@@ -2521,43 +2521,43 @@ namespace {
output = child;
return IGraphTransformer::TStatus::Repeat;
}
- hasEmptyList = hasEmptyList || ETypeAnnotationKind::EmptyList == child->GetTypeAnn()->GetKind();
+ hasEmptyList = hasEmptyList || ETypeAnnotationKind::EmptyList == child->GetTypeAnn()->GetKind();
}
- if (hasEmptyList) {
- auto children = input->ChildrenList();
- children.erase(std::remove_if(children.begin(), children.end(),
- [](const TExprNode::TPtr& child) { return ETypeAnnotationKind::EmptyList == child->GetTypeAnn()->GetKind(); }), children.end());
- output = ctx.Expr.ChangeChildren(*input, std::move(children));
- return IGraphTransformer::TStatus::Repeat;
- }
+ if (hasEmptyList) {
+ auto children = input->ChildrenList();
+ children.erase(std::remove_if(children.begin(), children.end(),
+ [](const TExprNode::TPtr& child) { return ETypeAnnotationKind::EmptyList == child->GetTypeAnn()->GetKind(); }), children.end());
+ output = ctx.Expr.ChangeChildren(*input, std::move(children));
+ return IGraphTransformer::TStatus::Repeat;
+ }
- if constexpr (!IsStrict) {
- if (const auto commonType = CommonTypeForChildren(*input, ctx.Expr)) {
- if (const auto status = ConvertChildrenToType(input, commonType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
+ if constexpr (!IsStrict) {
+ if (const auto commonType = CommonTypeForChildren(*input, ctx.Expr)) {
+ if (const auto status = ConvertChildrenToType(input, commonType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
return status;
- } else
- return IGraphTransformer::TStatus::Error;
+ } else
+ return IGraphTransformer::TStatus::Error;
}
- return ListAutomapArgs(input, output, ctx, "OrderedExtend");
+ return ListAutomapArgs(input, output, ctx, "OrderedExtend");
}
- template IGraphTransformer::TStatus ListExtendWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- template IGraphTransformer::TStatus ListExtendWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
+ template IGraphTransformer::TStatus ListExtendWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ template IGraphTransformer::TStatus ListExtendWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
IGraphTransformer::TStatus ListUnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return ListAutomapArgs(input, output, ctx, "UnionAll");
}
- IGraphTransformer::TStatus ListZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ListZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return ListAutomapArgs(input, output, ctx, "Zip");
- }
-
- IGraphTransformer::TStatus ListZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ }
+
+ IGraphTransformer::TStatus ListZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return ListAutomapArgs(input, output, ctx, "ZipAll");
- }
-
+ }
+
bool ValidateSortDirections(TExprNode& direction, TExprContext& ctx, bool& isTuple) {
bool isOkAscending = false;
@@ -2598,7 +2598,7 @@ namespace {
return status;
}
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2632,8 +2632,8 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus SortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2642,94 +2642,94 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- auto status = ValidateSortTraits(itemType, input->Child(1), input->TailRef(), ctx.Expr);
+ auto status = ValidateSortTraits(itemType, input->Child(1), input->TailRef(), ctx.Expr);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
IGraphTransformer::TStatus TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- const auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
- if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
+ const auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto status = ValidateSortTraits(itemType, input->Child(2), input->TailRef(), ctx.Expr);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (IsEmptyList(*input->Child(1))) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureListType(input->Child(1)->Pos(), *input->Child(1)->GetTypeAnn(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- if (const auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr); convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = input->Child(1)->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!IsSameAnnotation(*itemType, *input->Child(2)->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), TStringBuilder() << "Mismatch list items and new item types, "
- << *itemType << " != " << *input->Child(2)->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto status = ValidateSortTraits(itemType, input->Child(3), input->TailRef(), ctx.Expr);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- input->SetTypeAnn(input->Child(1)->GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto status = ValidateSortTraits(itemType, input->Child(2), input->TailRef(), ctx.Expr);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsEmptyList(*input->Child(1))) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureListType(input->Child(1)->Pos(), *input->Child(1)->GetTypeAnn(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr); convertStatus.Level == IGraphTransformer::TStatus::Error) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = input->Child(1)->GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ if (!IsSameAnnotation(*itemType, *input->Child(2)->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), TStringBuilder() << "Mismatch list items and new item types, "
+ << *itemType << " != " << *input->Child(2)->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto status = ValidateSortTraits(itemType, input->Child(3), input->TailRef(), ctx.Expr);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ input->SetTypeAnn(input->Child(1)->GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus UnorderedWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
- output = input->HeadPtr();
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ output = input->HeadPtr();
return IGraphTransformer::TStatus::Repeat;
}
@@ -2738,11 +2738,11 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr)) {
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
@@ -2754,7 +2754,7 @@ namespace {
return status;
}
- const auto& listTypeNode = input->Head();
+ const auto& listTypeNode = input->Head();
auto& listType = *listTypeNode.GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (listType.GetKind() == ETypeAnnotationKind::EmptyList) {
output = ctx.Expr.NewCallable(input->Pos(), "Void", {});
@@ -2952,25 +2952,25 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus GroupByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus GroupByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
- status = status.Combine(ConvertToLambda(input->TailRef(), ctx.Expr, 2));
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ status = status.Combine(ConvertToLambda(input->TailRef(), ctx.Expr, 2));
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambdaKeySelector = input->ChildRef(1);
- auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
+ auto& lambdaKeySelector = input->ChildRef(1);
+ auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2988,8 +2988,8 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaListHandler = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(lambdaListHandler, {lambdaKeySelector->GetTypeAnn(), input->Head().GetTypeAnn()}, ctx.Expr)) {
+ auto& lambdaListHandler = input->TailRef();
+ if (!UpdateLambdaAllArgumentsTypes(lambdaListHandler, {lambdaKeySelector->GetTypeAnn(), input->Head().GetTypeAnn()}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3020,27 +3020,27 @@ namespace {
IGraphTransformer::TStatus PartitionByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (input->Child(2)->IsCallable("Void") != input->Child(3)->IsCallable("Void")) {
+ if (input->Child(2)->IsCallable("Void") != input->Child(3)->IsCallable("Void")) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(3)->Pos()), TStringBuilder() <<
"Direction and sort key extractor should be specified at the same time"));
return IGraphTransformer::TStatus::Error;
}
- bool hasSort = !input->Child(2)->IsCallable("Void");
+ bool hasSort = !input->Child(2)->IsCallable("Void");
if (hasSort) {
auto status = ValidateSortTraits(itemType, input->Child(2), input->ChildRef(3), ctx.Expr);
if (status.Level != IGraphTransformer::TStatus::Ok) {
@@ -3048,13 +3048,13 @@ namespace {
}
}
- status = ConvertToLambda(input->ChildRef(4), ctx.Expr, 1);
+ status = ConvertToLambda(input->ChildRef(4), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambdaKeySelector = input->ChildRef(1);
- if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
+ auto& lambdaKeySelector = input->ChildRef(1);
+ if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3068,15 +3068,15 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaListHandler = input->ChildRef(4);
+ auto& lambdaListHandler = input->ChildRef(4);
TTypeAnnotationNode::TListType tupleItems = {
lambdaKeySelector->GetTypeAnn(),
ctx.Expr.MakeType<TStreamExprType>(itemType)
};
- const auto groupType = ctx.Expr.MakeType<TTupleExprType>(tupleItems);
- const auto listOfGroupsType = ctx.Expr.MakeType<TStreamExprType>(groupType);
- if (!UpdateLambdaAllArgumentsTypes(lambdaListHandler, {listOfGroupsType}, ctx.Expr)) {
+ const auto groupType = ctx.Expr.MakeType<TTupleExprType>(tupleItems);
+ const auto listOfGroupsType = ctx.Expr.MakeType<TStreamExprType>(groupType);
+ if (!UpdateLambdaAllArgumentsTypes(lambdaListHandler, {listOfGroupsType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3088,7 +3088,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- const auto retKind = lambdaListHandler->GetTypeAnn()->GetKind();
+ const auto retKind = lambdaListHandler->GetTypeAnn()->GetKind();
if (retKind != ETypeAnnotationKind::List && retKind != ETypeAnnotationKind::Optional &&
retKind != ETypeAnnotationKind::Stream)
{
@@ -3098,79 +3098,79 @@ namespace {
}
- const auto retItemType = GetSeqItemType(lambdaListHandler->GetTypeAnn());
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *retItemType, ctx.Expr));
+ const auto retItemType = GetSeqItemType(lambdaListHandler->GetTypeAnn());
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *retItemType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus PartitionsByKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto& lambdaKeySelector = input->ChildRef(1);
+ const auto status1 = ConvertToLambda(lambdaKeySelector, ctx.Expr, 1);
+ if (status1.Level != IGraphTransformer::TStatus::Ok) {
+ return status1;
+ }
+
+ auto& lambdaFinalHandler = input->TailRef();
+ const auto status = ConvertToLambda(lambdaFinalHandler, ctx.Expr, 1);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (input->Child(2)->IsCallable("Void") != input->Child(3)->IsCallable("Void")) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(3)->Pos()), TStringBuilder() <<
+ "Direction and sort key extractor should be specified at the same time"));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!input->Child(2)->IsCallable("Void")) {
+ const auto status = ValidateSortTraits(itemType, input->Child(2), input->ChildRef(3), ctx.Expr);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambdaKeySelector->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!lambdaKeySelector->GetTypeAnn()->IsHashable() || !lambdaKeySelector->GetTypeAnn()->IsEquatable()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambdaKeySelector->Pos()), TStringBuilder()
+ << "Expected hashable and equatable type for key, but got: " << *lambdaKeySelector->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambdaFinalHandler, { input->Head().GetTypeAnn() }, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambdaFinalHandler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureNewSeqType<false>(input->Tail().Pos(), *lambdaFinalHandler->GetTypeAnn(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(lambdaFinalHandler->GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus PartitionsByKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto& lambdaKeySelector = input->ChildRef(1);
- const auto status1 = ConvertToLambda(lambdaKeySelector, ctx.Expr, 1);
- if (status1.Level != IGraphTransformer::TStatus::Ok) {
- return status1;
- }
-
- auto& lambdaFinalHandler = input->TailRef();
- const auto status = ConvertToLambda(lambdaFinalHandler, ctx.Expr, 1);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (input->Child(2)->IsCallable("Void") != input->Child(3)->IsCallable("Void")) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(3)->Pos()), TStringBuilder() <<
- "Direction and sort key extractor should be specified at the same time"));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!input->Child(2)->IsCallable("Void")) {
- const auto status = ValidateSortTraits(itemType, input->Child(2), input->ChildRef(3), ctx.Expr);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambdaKeySelector->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!lambdaKeySelector->GetTypeAnn()->IsHashable() || !lambdaKeySelector->GetTypeAnn()->IsEquatable()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambdaKeySelector->Pos()), TStringBuilder()
- << "Expected hashable and equatable type for key, but got: " << *lambdaKeySelector->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambdaFinalHandler, { input->Head().GetTypeAnn() }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambdaFinalHandler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureNewSeqType<false>(input->Tail().Pos(), *lambdaFinalHandler->GetTypeAnn(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(lambdaFinalHandler->GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus ReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3179,16 +3179,16 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3197,12 +3197,12 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr)) {
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3212,57 +3212,57 @@ namespace {
return convertStatus;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FoldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus FoldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->ChildPtr(1);
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Head())) {
+ output = input->ChildPtr(1);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = input->ChildPtr(1);
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
+ if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
+ if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 2);
+ const auto status = ConvertToLambda(input->TailRef(), ctx.Expr, 2);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- output = ctx.Expr.Builder(input->Pos())
- .Callable("IfPresent")
- .Add(0, input->HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(input->TailPtr())
- .With(0, "item")
- .With(1, input->ChildPtr(1))
- .Seal()
- .Seal()
- .Add(2, input->ChildPtr(1))
- .Seal().Build();
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto& lambda = input->TailRef();
- const auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
-
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ output = ctx.Expr.Builder(input->Pos())
+ .Callable("IfPresent")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(input->TailPtr())
+ .With(0, "item")
+ .With(1, input->ChildPtr(1))
+ .Seal()
+ .Seal()
+ .Add(2, input->ChildPtr(1))
+ .Seal().Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto& lambda = input->TailRef();
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+
if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType, input->Child(1)->GetTypeAnn()}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3281,44 +3281,44 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus Fold1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus Fold1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (IsNull(input->Head())) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
if (IsEmptyList(input->Head())) {
output = ctx.Expr.NewCallable(input->Pos(), "Null", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
+ if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto status1 = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
- if (status1.Level != IGraphTransformer::TStatus::Ok) {
- return status1;
+ const auto status1 = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ if (status1.Level != IGraphTransformer::TStatus::Ok) {
+ return status1;
+ }
+
+ if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ output = ctx.Expr.NewCallable(input->Pos(), "Map", {input->HeadPtr(), input->ChildPtr(1)});
+ return IGraphTransformer::TStatus::Repeat;
}
- if (input->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
- output = ctx.Expr.NewCallable(input->Pos(), "Map", {input->HeadPtr(), input->ChildPtr(1)});
- return IGraphTransformer::TStatus::Repeat;
+ const auto status2 = ConvertToLambda(input->TailRef(), ctx.Expr, 2);
+ if (status2.Level != IGraphTransformer::TStatus::Ok) {
+ return status2;
}
- const auto status2 = ConvertToLambda(input->TailRef(), ctx.Expr, 2);
- if (status2.Level != IGraphTransformer::TStatus::Ok) {
- return status2;
- }
-
- auto& initLambda = input->ChildRef(1);
- const auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
-
- if (!UpdateLambdaAllArgumentsTypes(initLambda, {itemType}, ctx.Expr)) {
+ auto& initLambda = input->ChildRef(1);
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+
+ if (!UpdateLambdaAllArgumentsTypes(initLambda, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3326,9 +3326,9 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- const auto stateType = initLambda->GetTypeAnn();
- auto& updateLambda = input->TailRef();
- if (!UpdateLambdaAllArgumentsTypes(updateLambda, {itemType, stateType}, ctx.Expr)) {
+ const auto stateType = initLambda->GetTypeAnn();
+ auto& updateLambda = input->TailRef();
+ if (!UpdateLambdaAllArgumentsTypes(updateLambda, {itemType, stateType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3342,125 +3342,125 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- const auto optAnn = ctx.Expr.MakeType<TOptionalExprType>(stateType);
+ const auto optAnn = ctx.Expr.MakeType<TOptionalExprType>(stateType);
input->SetTypeAnn(optAnn);
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CondenseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus CondenseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureComputable(*input->Child(1), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
const auto stateType = input->Child(1)->GetTypeAnn();
-
- auto& switchLambda = input->ChildRef(2);
- auto& updateLambda = input->ChildRef(3);
-
- const auto status = ConvertToLambda(switchLambda, ctx.Expr, 2).Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(switchLambda, { itemType, stateType }, ctx.Expr) ||
- !UpdateLambdaAllArgumentsTypes(updateLambda, { itemType, stateType }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+
+ auto& switchLambda = input->ChildRef(2);
+ auto& updateLambda = input->ChildRef(3);
+
+ const auto status = ConvertToLambda(switchLambda, ctx.Expr, 2).Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(switchLambda, { itemType, stateType }, ctx.Expr) ||
+ !UpdateLambdaAllArgumentsTypes(updateLambda, { itemType, stateType }, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!switchLambda->GetTypeAnn() || !updateLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool isOptional;
- const TDataExprType* dataType;
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool isOptional;
+ const TDataExprType* dataType;
if (!EnsureDataOrOptionalOfData(switchLambda->Pos(), switchLambda->GetTypeAnn(), isOptional, dataType, ctx.Expr) || !EnsureSpecificDataType(switchLambda->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(switchLambda->Pos()), TStringBuilder() << "Switch lambda returns " << *switchLambda->GetTypeAnn() << " instead of boolean."));
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!IsSameAnnotation(*updateLambda->GetTypeAnn(), *stateType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(updateLambda->Pos()), TStringBuilder() << "Mismatch of lambda return type and state type, "
<< *updateLambda->GetTypeAnn() << " != " << *stateType));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *stateType, ctx.Expr));
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus Condense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto& initLambda = input->ChildRef(1);
- auto& switchLambda = input->ChildRef(2);
- auto& updateLambda = input->ChildRef(3);
-
- const auto status = ConvertToLambda(initLambda, ctx.Expr, 1)
- .Combine(ConvertToLambda(switchLambda, ctx.Expr, 2))
- .Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(initLambda, { itemType }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *stateType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus Condense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto& initLambda = input->ChildRef(1);
+ auto& switchLambda = input->ChildRef(2);
+ auto& updateLambda = input->ChildRef(3);
+
+ const auto status = ConvertToLambda(initLambda, ctx.Expr, 1)
+ .Combine(ConvertToLambda(switchLambda, ctx.Expr, 2))
+ .Combine(ConvertToLambda(updateLambda, ctx.Expr, 2));
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(initLambda, { itemType }, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!initLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
const auto stateType = initLambda->GetTypeAnn();
-
- if (!UpdateLambdaAllArgumentsTypes(switchLambda, { itemType, stateType }, ctx.Expr) ||
- !UpdateLambdaAllArgumentsTypes(updateLambda, { itemType, stateType }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+
+ if (!UpdateLambdaAllArgumentsTypes(switchLambda, { itemType, stateType }, ctx.Expr) ||
+ !UpdateLambdaAllArgumentsTypes(updateLambda, { itemType, stateType }, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!switchLambda->GetTypeAnn() || !updateLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool isOptional;
- const TDataExprType* dataType;
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool isOptional;
+ const TDataExprType* dataType;
if (!EnsureDataOrOptionalOfData(switchLambda->Pos(), switchLambda->GetTypeAnn(), isOptional, dataType, ctx.Expr) || !EnsureSpecificDataType(switchLambda->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(switchLambda->Pos()), TStringBuilder() << "Switch lambda returns " << *switchLambda->GetTypeAnn() << " instead of boolean."));
- return IGraphTransformer::TStatus::Error;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (!IsSameAnnotation(*updateLambda->GetTypeAnn(), *stateType)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(updateLambda->Pos()), TStringBuilder() << "Mismatch of lambda return type and state type, "
<< *updateLambda->GetTypeAnn() << "!= " << *stateType));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *stateType, ctx.Expr));
- return IGraphTransformer::TStatus::Ok;
- }
-
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *stateType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus SqueezeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStreamType(input->Head(), ctx.Expr)) {
+ if (!EnsureStreamType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3476,7 +3476,7 @@ namespace {
}
auto stateType = input->Child(1)->GetTypeAnn();
- auto itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
+ auto itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
if (!UpdateLambdaAllArgumentsTypes(lambda, { itemType, stateType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3533,11 +3533,11 @@ namespace {
}
auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Deprecated Squeeze, use Condense instead.");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
- if (!ctx.Expr.AddWarning(issue)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
input->SetTypeAnn(ctx.Expr.MakeType<TStreamExprType>(stateType));
return IGraphTransformer::TStatus::Ok;
}
@@ -3548,7 +3548,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStreamType(input->Head(), ctx.Expr)) {
+ if (!EnsureStreamType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3561,7 +3561,7 @@ namespace {
return status;
}
- auto itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
+ auto itemType = input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType();
if (!UpdateLambdaAllArgumentsTypes(initLambda, { itemType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3628,11 +3628,11 @@ namespace {
}
auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Deprecated Squeeze1, use Condense1 instead.");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
- if (!ctx.Expr.AddWarning(issue)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_YQL_DEPRECATED_FUNCTION_OR_SIGNATURE, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
auto optAnn = ctx.Expr.MakeType<TStreamExprType>(stateType);
input->SetTypeAnn(optAnn);
return IGraphTransformer::TStatus::Ok;
@@ -3644,58 +3644,58 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr)) {
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(input->Head().GetTypeAnn());
+ input->SetTypeAnn(input->Head().GetTypeAnn());
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!input->ChildrenSize()) {
- output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType())), ctx.Expr)});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- for (auto& child : input->Children()) {
+ IGraphTransformer::TStatus ZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!input->ChildrenSize()) {
+ output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType())), ctx.Expr)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ for (auto& child : input->Children()) {
if (!EnsureListOrEmptyType(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
TTypeAnnotationNode::TListType tupleItems;
- bool hasEmpty = false;
- for (auto& child : input->Children()) {
- hasEmpty = hasEmpty || child->GetTypeAnn()->GetKind() != ETypeAnnotationKind::List;
+ bool hasEmpty = false;
+ for (auto& child : input->Children()) {
+ hasEmpty = hasEmpty || child->GetTypeAnn()->GetKind() != ETypeAnnotationKind::List;
auto itemType = child->GetTypeAnn()->GetKind() == ETypeAnnotationKind::List ?
child->GetTypeAnn()->Cast<TListExprType>()->GetItemType() :
ctx.Expr.MakeType<TVoidExprType>();
tupleItems.push_back(itemType);
}
- const auto returnType = ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(tupleItems));
- if (hasEmpty) {
- output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *returnType, ctx.Expr)});
- return IGraphTransformer::TStatus::Repeat;
- }
- input->SetTypeAnn(returnType);
+ const auto returnType = ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(tupleItems));
+ if (hasEmpty) {
+ output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *returnType, ctx.Expr)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ input->SetTypeAnn(returnType);
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!input->ChildrenSize()) {
- output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType())), ctx.Expr)});
- return IGraphTransformer::TStatus::Repeat;
- }
-
- for (auto& child : input->Children()) {
+ IGraphTransformer::TStatus ZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!input->ChildrenSize()) {
+ output = ctx.Expr.NewCallable(input->Pos(), "List", {ExpandType(input->Pos(), *ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType())), ctx.Expr)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ for (auto& child : input->Children()) {
if (!EnsureListOrEmptyType(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
TTypeAnnotationNode::TListType tupleItems;
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
auto itemType = child->GetTypeAnn()->GetKind() == ETypeAnnotationKind::List ?
child->GetTypeAnn()->Cast<TListExprType>()->GetItemType() :
ctx.Expr.MakeType<TVoidExprType>();
@@ -3709,12 +3709,12 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureMaxArgsCount(*input, 3, ctx.Expr)) {
+ if (!EnsureMaxArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3723,13 +3723,13 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- if (input->ChildrenSize() > 1) {
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ if (input->ChildrenSize() > 1) {
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3740,8 +3740,8 @@ namespace {
}
}
- if (input->ChildrenSize() > 2) {
- auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr);
+ if (input->ChildrenSize() > 2) {
+ auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3754,14 +3754,14 @@ namespace {
TTypeAnnotationNode::TListType tupleItems(2);
tupleItems[0] = expectedType;
- tupleItems[1] = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ tupleItems[1] = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
auto retTuple = ctx.Expr.MakeType<TTupleExprType>(tupleItems);
input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(retTuple));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus ListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3769,19 +3769,19 @@ namespace {
return status;
}
- auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto type = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (type->GetKind() == ETypeAnnotationKind::EmptyList) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head().Pos(), *type, ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto listType = type->Cast<TListExprType>();
auto itemType = listType->GetItemType();
- for (size_t i = 1; i < input->ChildrenSize(); ++i) {
+ for (size_t i = 1; i < input->ChildrenSize(); ++i) {
if (!IsSameAnnotation(*itemType, *input->Child(i)->GetTypeAnn())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(i)->Pos()), TStringBuilder() << "Mismatch type of list item, "
<< *itemType << " != " << *input->Child(i)->GetTypeAnn()));
@@ -3793,9 +3793,9 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CombineByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CombineByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 6, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 6, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3805,17 +3805,17 @@ namespace {
}
auto inputTypeKind = input->Head().GetTypeAnn()->GetKind();
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
- status = status.Combine(ConvertToLambda(input->ChildRef(2), ctx.Expr, 1));
- status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 2));
- status = status.Combine(ConvertToLambda(input->ChildRef(4), ctx.Expr, 3));
- status = status.Combine(ConvertToLambda(input->ChildRef(5), ctx.Expr, 2));
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
+ status = status.Combine(ConvertToLambda(input->ChildRef(2), ctx.Expr, 1));
+ status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 2));
+ status = status.Combine(ConvertToLambda(input->ChildRef(4), ctx.Expr, 3));
+ status = status.Combine(ConvertToLambda(input->ChildRef(5), ctx.Expr, 2));
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto& lambdaPreMap = input->ChildRef(1);
- if (!UpdateLambdaAllArgumentsTypes(lambdaPreMap, {rawItemType}, ctx.Expr)) {
+ auto& lambdaPreMap = input->ChildRef(1);
+ if (!UpdateLambdaAllArgumentsTypes(lambdaPreMap, {rawItemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3828,8 +3828,8 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaKeySelector = input->ChildRef(2);
- if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
+ auto& lambdaKeySelector = input->ChildRef(2);
+ if (!UpdateLambdaAllArgumentsTypes(lambdaKeySelector, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3847,7 +3847,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaInitHandler = input->ChildRef(3);
+ auto& lambdaInitHandler = input->ChildRef(3);
if (!UpdateLambdaAllArgumentsTypes(lambdaInitHandler, {lambdaKeySelector->GetTypeAnn(), itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3861,7 +3861,7 @@ namespace {
}
auto stateType = lambdaInitHandler->GetTypeAnn();
- auto& lambdaUpdateHandler = input->ChildRef(4);
+ auto& lambdaUpdateHandler = input->ChildRef(4);
if (!UpdateLambdaAllArgumentsTypes(lambdaUpdateHandler, {lambdaKeySelector->GetTypeAnn(), itemType, stateType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3877,7 +3877,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaFinishHandler = input->ChildRef(5);
+ auto& lambdaFinishHandler = input->ChildRef(5);
if (!UpdateLambdaAllArgumentsTypes(lambdaFinishHandler, {lambdaKeySelector->GetTypeAnn(), stateType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3899,8 +3899,8 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus ExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3909,29 +3909,29 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
+ if (!EnsureListOrOptionalType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto firstArgKind = input->Head().GetTypeAnn()->GetKind();
- if (!EnsureAtom(input->Tail(), ctx.Expr)) {
+ auto firstArgKind = input->Head().GetTypeAnn()->GetKind();
+ if (!EnsureAtom(input->Tail(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const TTypeAnnotationNode* itemType = nullptr;
if (firstArgKind == ETypeAnnotationKind::List) {
- itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ itemType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
} else {
- itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
+ itemType = input->Head().GetTypeAnn()->Cast<TOptionalExprType>()->GetItemType();
}
const TTypeAnnotationNode* extractedType = nullptr;
if (itemType->GetKind() == ETypeAnnotationKind::Struct) {
auto structType = itemType->Cast<TStructExprType>();
- auto pos = structType->FindItem(input->Tail().Content());
+ auto pos = structType->FindItem(input->Tail().Content());
if (!pos) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
- "Member with name " << input->Tail().Content() << " is not found in " << *input->Head().GetTypeAnn()));
+ "Member with name " << input->Tail().Content() << " is not found in " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -3939,7 +3939,7 @@ namespace {
}
else if (itemType->GetKind() == ETypeAnnotationKind::Tuple) {
ui32 index = 0;
- if (!TryFromString(input->Tail().Content(), index)) {
+ if (!TryFromString(input->Tail().Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -3947,7 +3947,7 @@ namespace {
auto tupleType = itemType->Cast<TTupleExprType>();
if (index >= tupleType->GetSize()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Index out of range. Index: " <<
- index << ", size: " << tupleType->GetSize() << ", type: " << *input->Head().GetTypeAnn()));
+ index << ", size: " << tupleType->GetSize() << ", type: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -3955,7 +3955,7 @@ namespace {
}
else {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder() <<
- "Expected either list of struct or list tuples, but got: " << *input->Head().GetTypeAnn()));
+ "Expected either list of struct or list tuples, but got: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -3978,18 +3978,18 @@ namespace {
return status;
}
- const TTypeAnnotationNode* inputItemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &inputItemType)) {
- return IGraphTransformer::TStatus::Error;
+ const TTypeAnnotationNode* inputItemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &inputItemType)) {
+ return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
+ if (!EnsureStructType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto structType = inputItemType->Cast<TStructExprType>();
+ const auto structType = inputItemType->Cast<TStructExprType>();
TVector<const TItemExprType*> resItems;
- for (auto& x : input->Tail().Children()) {
+ for (auto& x : input->Tail().Children()) {
YQL_ENSURE(x->IsAtom());
auto pos = FindOrReportMissingMember(x->Content(), input->Head().Pos(), *structType, ctx);
if (!pos) {
@@ -3999,12 +3999,12 @@ namespace {
resItems.push_back(structType->GetItems()[*pos]);
}
- const auto resItemType = ctx.Expr.MakeType<TStructExprType>(resItems);
+ const auto resItemType = ctx.Expr.MakeType<TStructExprType>(resItems);
if (!resItemType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *resItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
@@ -4121,7 +4121,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AggregationTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AggregationTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 8, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -4137,32 +4137,32 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1, 2);
- status = status.Combine(ConvertToLambda(input->ChildRef(2), ctx.Expr, 2, 3));
- status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
- status = status.Combine(ConvertToLambda(input->ChildRef(4), ctx.Expr, 1));
- status = status.Combine(ConvertToLambda(input->ChildRef(5), ctx.Expr, 2));
- status = status.Combine(ConvertToLambda(input->ChildRef(6), ctx.Expr, 1));
+ auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1, 2);
+ status = status.Combine(ConvertToLambda(input->ChildRef(2), ctx.Expr, 2, 3));
+ status = status.Combine(ConvertToLambda(input->ChildRef(3), ctx.Expr, 1));
+ status = status.Combine(ConvertToLambda(input->ChildRef(4), ctx.Expr, 1));
+ status = status.Combine(ConvertToLambda(input->ChildRef(5), ctx.Expr, 2));
+ status = status.Combine(ConvertToLambda(input->ChildRef(6), ctx.Expr, 1));
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
- if (!EnsureComputableType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureComputableType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaInit = input->ChildRef(1);
+ auto& lambdaInit = input->ChildRef(1);
auto ui32Type = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- if (lambdaInit->Head().ChildrenSize() == 1U) {
+ if (lambdaInit->Head().ChildrenSize() == 1U) {
if (!UpdateLambdaAllArgumentsTypes(lambdaInit, { itemType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
else {
if (!UpdateLambdaAllArgumentsTypes(lambdaInit, { itemType, ui32Type }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ return IGraphTransformer::TStatus::Error;
+ }
}
if (!lambdaInit->GetTypeAnn()) {
@@ -4174,16 +4174,16 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaUpdate = input->ChildRef(2);
- if (lambdaUpdate->Head().ChildrenSize() == 2U) {
+ auto& lambdaUpdate = input->ChildRef(2);
+ if (lambdaUpdate->Head().ChildrenSize() == 2U) {
if (!UpdateLambdaAllArgumentsTypes(lambdaUpdate, { itemType, combineStateType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
}
else {
if (!UpdateLambdaAllArgumentsTypes(lambdaUpdate, { itemType, combineStateType, ui32Type }, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ return IGraphTransformer::TStatus::Error;
+ }
}
if (!lambdaUpdate->GetTypeAnn()) {
@@ -4196,7 +4196,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaSave = input->ChildRef(3);
+ auto& lambdaSave = input->ChildRef(3);
if (!UpdateLambdaAllArgumentsTypes(lambdaSave, { combineStateType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4210,7 +4210,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaLoad = input->ChildRef(4);
+ auto& lambdaLoad = input->ChildRef(4);
if (!UpdateLambdaAllArgumentsTypes(lambdaLoad, { savedType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4219,14 +4219,14 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!IsSameAnnotation(*lambdaUpdate->GetTypeAnn(), *lambdaLoad->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambdaUpdate->Pos()), TStringBuilder() << "Mismatch state type after load, expected: "
- << *lambdaUpdate->GetTypeAnn() << ", but got: " << *lambdaLoad->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!IsSameAnnotation(*lambdaUpdate->GetTypeAnn(), *lambdaLoad->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambdaUpdate->Pos()), TStringBuilder() << "Mismatch state type after load, expected: "
+ << *lambdaUpdate->GetTypeAnn() << ", but got: " << *lambdaLoad->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
auto reduceStateType = lambdaLoad->GetTypeAnn();
- auto& lambdaMerge = input->ChildRef(5);
+ auto& lambdaMerge = input->ChildRef(5);
if (!UpdateLambdaAllArgumentsTypes(lambdaMerge, { reduceStateType, reduceStateType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4241,7 +4241,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto& lambdaFinish = input->ChildRef(6);
+ auto& lambdaFinish = input->ChildRef(6);
if (!UpdateLambdaAllArgumentsTypes(lambdaFinish, { reduceStateType }, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4273,7 +4273,7 @@ namespace {
return status;
}
- auto rowType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto rowType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
auto status = ConvertToLambda(input->ChildRef(1), ctx.Expr, 1);
if (status.Level != IGraphTransformer::TStatus::Ok) {
@@ -4306,7 +4306,7 @@ namespace {
return output ? IGraphTransformer::TStatus::Repeat : IGraphTransformer::TStatus::Error;
}
- IGraphTransformer::TStatus AggregateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AggregateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4320,15 +4320,15 @@ namespace {
}
bool isStream;
- if (!EnsureSeqType(input->Head(), ctx.Expr, &isStream)) {
+ if (!EnsureSeqType(input->Head(), ctx.Expr, &isStream)) {
return IGraphTransformer::TStatus::Error;
}
auto inputItemType = isStream
- ? input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType()
- : input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ ? input->Head().GetTypeAnn()->Cast<TStreamExprType>()->GetItemType()
+ : input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!EnsureStructType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
+ if (!EnsureStructType(input->Head().Pos(), *inputItemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4484,18 +4484,18 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (!child->Head().IsAtom() && !child->Head().IsList()) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Head().Pos()), TStringBuilder()
- << "Expected atom or tuple, but got: " << child->Head().Type()));
+ if (!child->Head().IsAtom() && !child->Head().IsList()) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Head().Pos()), TStringBuilder()
+ << "Expected atom or tuple, but got: " << child->Head().Type()));
return IGraphTransformer::TStatus::Error;
}
- if (child->Head().IsList()) {
- if (!EnsureTupleMinSize(child->Head(), 1, ctx.Expr)) {
+ if (child->Head().IsList()) {
+ if (!EnsureTupleMinSize(child->Head(), 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- for (auto& outField : child->Head().Children()) {
+ for (auto& outField : child->Head().Children()) {
if (!EnsureAtom(*outField, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4516,7 +4516,7 @@ namespace {
auto item = inputStructType->FindItem(child->Child(2)->Content());
if (!item) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown key column: " <<
- child->Child(2)->Content() << ", type: " << *input->Head().GetTypeAnn()));
+ child->Child(2)->Content() << ", type: " << *input->Head().GetTypeAnn()));
return IGraphTransformer::TStatus::Error;
}
@@ -4530,22 +4530,22 @@ namespace {
auto finishType = child->Child(1)->Child(6)->GetTypeAnn();
bool isOptional = finishType->GetKind() == ETypeAnnotationKind::Optional;
- if (child->Head().IsList()) {
- if (isOptional) {
- finishType = finishType->Cast<TOptionalExprType>()->GetItemType();
- }
-
- const auto tupleType = finishType->Cast<TTupleExprType>();
- if (tupleType->GetSize() != child->Head().ChildrenSize()) {
+ if (child->Head().IsList()) {
+ if (isOptional) {
+ finishType = finishType->Cast<TOptionalExprType>()->GetItemType();
+ }
+
+ const auto tupleType = finishType->Cast<TTupleExprType>();
+ if (tupleType->GetSize() != child->Head().ChildrenSize()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Child(1)->Child(6)->Pos()),
- TStringBuilder() << "Expected tuple type of size: " << child->Head().ChildrenSize() << ", but got: " << tupleType->GetSize()));
+ TStringBuilder() << "Expected tuple type of size: " << child->Head().ChildrenSize() << ", but got: " << tupleType->GetSize()));
return IGraphTransformer::TStatus::Error;
}
for (ui32 index = 0; index < tupleType->GetSize(); ++index) {
- const auto item = tupleType->GetItems()[index];
+ const auto item = tupleType->GetItems()[index];
rowColumns.push_back(ctx.Expr.MakeType<TItemExprType>(
- child->Head().Child(index)->Content(),
+ child->Head().Child(index)->Content(),
(isOptional || (input->Child(1)->ChildrenSize() == 0 && !isHopping)) &&
item->GetKind() != ETypeAnnotationKind::Optional ? ctx.Expr.MakeType<TOptionalExprType>(item) : item));
}
@@ -4562,7 +4562,7 @@ namespace {
finishType = defVal->GetTypeAnn();
}
- rowColumns.push_back(ctx.Expr.MakeType<TItemExprType>(child->Head().Content(), finishType));
+ rowColumns.push_back(ctx.Expr.MakeType<TItemExprType>(child->Head().Content(), finishType));
}
}
@@ -4615,72 +4615,72 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FilterNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus FilterNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const auto originalStructType = itemType->Cast<TStructExprType>();
+ const auto originalStructType = itemType->Cast<TStructExprType>();
- std::unordered_map<std::string_view, const TTypeAnnotationNode*> columnTypes;
- columnTypes.reserve(originalStructType->GetSize());
- for (const auto& x : originalStructType->GetItems()) {
- columnTypes.emplace(x->GetName(), x->GetItemType());
+ std::unordered_map<std::string_view, const TTypeAnnotationNode*> columnTypes;
+ columnTypes.reserve(originalStructType->GetSize());
+ for (const auto& x : originalStructType->GetItems()) {
+ columnTypes.emplace(x->GetName(), x->GetItemType());
}
- if (input->ChildrenSize() < 2U) {
- bool hasOptional = false;
- for (auto& column : columnTypes) {
- if (column.second->GetKind() == ETypeAnnotationKind::Optional) {
- hasOptional = true;
- column.second = column.second->Cast<TOptionalExprType>()->GetItemType();
- }
+ if (input->ChildrenSize() < 2U) {
+ bool hasOptional = false;
+ for (auto& column : columnTypes) {
+ if (column.second->GetKind() == ETypeAnnotationKind::Optional) {
+ hasOptional = true;
+ column.second = column.second->Cast<TOptionalExprType>()->GetItemType();
+ }
}
-
- if (!hasOptional) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
- } else {
+
+ if (!hasOptional) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else {
const auto status = NormalizeTupleOfAtoms(input, 1, output, ctx.Expr);
- if (status != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- TExprNode::TListType reducedMembers;
- const auto& members = input->Tail();
- reducedMembers.reserve(members.ChildrenSize());
- for (const auto& child : members.Children()) {
- const auto& name = child->Content();
- const auto it = columnTypes.find(name);
- if (columnTypes.cend() == it) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(members.Pos()), TStringBuilder() << "Unknown column: " << name));
- return IGraphTransformer::TStatus::Error;
- }
-
- auto& columnType = it->second;
- if (columnType->GetKind() == ETypeAnnotationKind::Optional) {
- reducedMembers.emplace_back(child);
- columnType = columnType->Cast<TOptionalExprType>()->GetItemType();
- }
- }
-
- if (reducedMembers.empty()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- } else if (reducedMembers.size() != members.ChildrenSize()) {
- output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(members.Pos(), std::move(reducedMembers)));
- return IGraphTransformer::TStatus::Repeat;
- }
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ TExprNode::TListType reducedMembers;
+ const auto& members = input->Tail();
+ reducedMembers.reserve(members.ChildrenSize());
+ for (const auto& child : members.Children()) {
+ const auto& name = child->Content();
+ const auto it = columnTypes.find(name);
+ if (columnTypes.cend() == it) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(members.Pos()), TStringBuilder() << "Unknown column: " << name));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto& columnType = it->second;
+ if (columnType->GetKind() == ETypeAnnotationKind::Optional) {
+ reducedMembers.emplace_back(child);
+ columnType = columnType->Cast<TOptionalExprType>()->GetItemType();
+ }
+ }
+
+ if (reducedMembers.empty()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ } else if (reducedMembers.size() != members.ChildrenSize()) {
+ output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(members.Pos(), std::move(reducedMembers)));
+ return IGraphTransformer::TStatus::Repeat;
+ }
}
TVector<const TItemExprType*> items;
@@ -4688,225 +4688,225 @@ namespace {
items.push_back(ctx.Expr.MakeType<TItemExprType>(pair.first, pair.second));
}
- const auto newStructType = ctx.Expr.MakeType<TStructExprType>(items);
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *newStructType, ctx.Expr));
+ const auto newStructType = ctx.Expr.MakeType<TStructExprType>(items);
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *newStructType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SkipNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto originalStructType = itemType->Cast<TStructExprType>();
-
- std::unordered_map<std::string_view, const TTypeAnnotationNode*> columnTypes;
- columnTypes.reserve(originalStructType->GetSize());
- for (const auto& x : originalStructType->GetItems()) {
- columnTypes.emplace(x->GetName(), x->GetItemType());
- }
-
- if (input->ChildrenSize() < 2U) {
- bool hasOptional = false;
- for (const auto& column : columnTypes) {
- if (column.second->GetKind() == ETypeAnnotationKind::Optional) {
- hasOptional = true;
- break;
- }
- }
-
- if (!hasOptional) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
- } else {
+ IGraphTransformer::TStatus SkipNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureStructType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto originalStructType = itemType->Cast<TStructExprType>();
+
+ std::unordered_map<std::string_view, const TTypeAnnotationNode*> columnTypes;
+ columnTypes.reserve(originalStructType->GetSize());
+ for (const auto& x : originalStructType->GetItems()) {
+ columnTypes.emplace(x->GetName(), x->GetItemType());
+ }
+
+ if (input->ChildrenSize() < 2U) {
+ bool hasOptional = false;
+ for (const auto& column : columnTypes) {
+ if (column.second->GetKind() == ETypeAnnotationKind::Optional) {
+ hasOptional = true;
+ break;
+ }
+ }
+
+ if (!hasOptional) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else {
const auto status = NormalizeTupleOfAtoms(input, 1, output, ctx.Expr);
- if (status != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- TExprNode::TListType reducedMembers;
- const auto members = input->Child(1);
- reducedMembers.reserve(members->ChildrenSize());
- for (const auto& child : members->Children()) {
- const auto& name = child->Content();
-
- const auto it = columnTypes.find(name);
- if (columnTypes.cend() == it) {
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ TExprNode::TListType reducedMembers;
+ const auto members = input->Child(1);
+ reducedMembers.reserve(members->ChildrenSize());
+ for (const auto& child : members->Children()) {
+ const auto& name = child->Content();
+
+ const auto it = columnTypes.find(name);
+ if (columnTypes.cend() == it) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(members->Pos()), TStringBuilder() << "Unknown column: " << name));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (it->second->GetKind() == ETypeAnnotationKind::Optional) {
- reducedMembers.emplace_back(child);
- }
- }
-
- if (reducedMembers.empty()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- } else if (reducedMembers.size() != members->ChildrenSize()) {
- output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(members->Pos(), std::move(reducedMembers)));
- return IGraphTransformer::TStatus::Repeat;
- }
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus FilterNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto originalTupleType = itemType->Cast<TTupleExprType>();
- auto columnTypes = originalTupleType->GetItems();
-
- if (input->ChildrenSize() < 2U) {
- bool hasOptional = false;
- for (auto& column : columnTypes) {
- if (column->GetKind() == ETypeAnnotationKind::Optional) {
- hasOptional = true;
- column = column->Cast<TOptionalExprType>()->GetItemType();
- }
- }
-
- if (!hasOptional) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
- } else {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (it->second->GetKind() == ETypeAnnotationKind::Optional) {
+ reducedMembers.emplace_back(child);
+ }
+ }
+
+ if (reducedMembers.empty()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ } else if (reducedMembers.size() != members->ChildrenSize()) {
+ output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(members->Pos(), std::move(reducedMembers)));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus FilterNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto originalTupleType = itemType->Cast<TTupleExprType>();
+ auto columnTypes = originalTupleType->GetItems();
+
+ if (input->ChildrenSize() < 2U) {
+ bool hasOptional = false;
+ for (auto& column : columnTypes) {
+ if (column->GetKind() == ETypeAnnotationKind::Optional) {
+ hasOptional = true;
+ column = column->Cast<TOptionalExprType>()->GetItemType();
+ }
+ }
+
+ if (!hasOptional) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else {
const auto status = NormalizeTupleOfAtoms(input, 1, output, ctx.Expr);
- if (status != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- TExprNode::TListType reducedElements;
- const auto elements = input->Child(1);
- reducedElements.reserve(elements->ChildrenSize());
- for (const auto& child : elements->Children()) {
- ui32 index = 0U;
- if (!TryFromString(child->Content(), index)) {
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ TExprNode::TListType reducedElements;
+ const auto elements = input->Child(1);
+ reducedElements.reserve(elements->ChildrenSize());
+ for (const auto& child : elements->Children()) {
+ ui32 index = 0U;
+ if (!TryFromString(child->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Failed to convert to integer: " << child->Content()));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (index >= columnTypes.size()) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (index >= columnTypes.size()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Index out of range. Index: " <<
- index << ", size: " << columnTypes.size()));
- return IGraphTransformer::TStatus::Error;
- }
-
- auto& columnType = columnTypes[index];
- if (columnType->GetKind() == ETypeAnnotationKind::Optional) {
- reducedElements.emplace_back(child);
- columnType = columnType->Cast<TOptionalExprType>()->GetItemType();
- }
- }
-
- if (reducedElements.empty()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- } else if (reducedElements.size() != elements->ChildrenSize()) {
- output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(elements->Pos(), std::move(reducedElements)));
- return IGraphTransformer::TStatus::Repeat;
- }
- }
-
- const auto newTupleType = ctx.Expr.MakeType<TTupleExprType>(columnTypes);
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *newTupleType, ctx.Expr));
- return IGraphTransformer::TStatus::Ok;
- }
-
- IGraphTransformer::TStatus SkipNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto originalTupleType = itemType->Cast<TTupleExprType>();
- const auto& columnTypes = originalTupleType->GetItems();
-
- if (input->ChildrenSize() < 2U) {
- bool hasOptional = false;
- for (const auto& column : columnTypes) {
- if (column->GetKind() == ETypeAnnotationKind::Optional) {
- hasOptional = true;
- break;
- }
- }
-
- if (!hasOptional) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
- } else {
+ index << ", size: " << columnTypes.size()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto& columnType = columnTypes[index];
+ if (columnType->GetKind() == ETypeAnnotationKind::Optional) {
+ reducedElements.emplace_back(child);
+ columnType = columnType->Cast<TOptionalExprType>()->GetItemType();
+ }
+ }
+
+ if (reducedElements.empty()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ } else if (reducedElements.size() != elements->ChildrenSize()) {
+ output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(elements->Pos(), std::move(reducedElements)));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ }
+
+ const auto newTupleType = ctx.Expr.MakeType<TTupleExprType>(columnTypes);
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *newTupleType, ctx.Expr));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ IGraphTransformer::TStatus SkipNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 2, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<true>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureTupleType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto originalTupleType = itemType->Cast<TTupleExprType>();
+ const auto& columnTypes = originalTupleType->GetItems();
+
+ if (input->ChildrenSize() < 2U) {
+ bool hasOptional = false;
+ for (const auto& column : columnTypes) {
+ if (column->GetKind() == ETypeAnnotationKind::Optional) {
+ hasOptional = true;
+ break;
+ }
+ }
+
+ if (!hasOptional) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ } else {
const auto status = NormalizeTupleOfAtoms(input, 1, output, ctx.Expr);
- if (status != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- TExprNode::TListType reducedElements;
- const auto elements = input->Child(1);
- reducedElements.reserve(elements->ChildrenSize());
- for (const auto& child : elements->Children()) {
- ui32 index = 0U;
- if (!TryFromString(child->Content(), index)) {
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ TExprNode::TListType reducedElements;
+ const auto elements = input->Child(1);
+ reducedElements.reserve(elements->ChildrenSize());
+ for (const auto& child : elements->Children()) {
+ ui32 index = 0U;
+ if (!TryFromString(child->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Failed to convert to integer: " << child->Content()));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (index >= columnTypes.size()) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (index >= columnTypes.size()) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Index out of range. Index: " <<
- index << ", size: " << columnTypes.size()));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (columnTypes[index]->GetKind() == ETypeAnnotationKind::Optional) {
- reducedElements.emplace_back(child);
- }
- }
-
- if (reducedElements.empty()) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- } else if (reducedElements.size() != elements->ChildrenSize()) {
- output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(elements->Pos(), std::move(reducedElements)));
- return IGraphTransformer::TStatus::Repeat;
- }
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
-
+ index << ", size: " << columnTypes.size()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (columnTypes[index]->GetKind() == ETypeAnnotationKind::Optional) {
+ reducedElements.emplace_back(child);
+ }
+ }
+
+ if (reducedElements.empty()) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ } else if (reducedElements.size() != elements->ChildrenSize()) {
+ output = ctx.Expr.ChangeChild(*input, 1, ctx.Expr.NewList(elements->Pos(), std::move(reducedElements)));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
+
IGraphTransformer::TStatus WinOnRowsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -5002,7 +5002,7 @@ namespace {
}
auto ui32Type = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- if (lambdaInit->Head().ChildrenSize() == 1U) {
+ if (lambdaInit->Head().ChildrenSize() == 1U) {
if (!UpdateLambdaAllArgumentsTypes(lambdaInit, {itemType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5021,7 +5021,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (lambdaUpdate->Head().ChildrenSize() == 2U) {
+ if (lambdaUpdate->Head().ChildrenSize() == 2U) {
if (!UpdateLambdaAllArgumentsTypes(lambdaUpdate, {itemType, stateType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5041,7 +5041,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- if (lambdaShift->Head().ChildrenSize() == 2U) {
+ if (lambdaShift->Head().ChildrenSize() == 2U) {
if (!UpdateLambdaAllArgumentsTypes(lambdaShift, {itemType, stateType}, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5126,12 +5126,12 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head(), ctx.Expr)) {
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto inputListType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- if (!EnsureStructType(input->Head().Pos(), *inputListType, ctx.Expr)) {
+ auto inputListType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
+ if (!EnsureStructType(input->Head().Pos(), *inputListType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5250,17 +5250,17 @@ namespace {
if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
}
- auto rowListType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ auto rowListType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
if (rowListType->GetKind() == ETypeAnnotationKind::EmptyList) {
output = ctx.Expr.NewCallable(input->Pos(), "Void", {});
return IGraphTransformer::TStatus::Repeat;
}
- if (!EnsureListType(input->Head().Pos(), *rowListType, ctx.Expr)) {
+ if (!EnsureListType(input->Head().Pos(), *rowListType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto rowType = rowListType->Cast<TListExprType>()->GetItemType();
- if (!EnsureStructType(input->Head().Pos(), *rowType, ctx.Expr)) {
+ if (!EnsureStructType(input->Head().Pos(), *rowType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5406,8 +5406,8 @@ namespace {
return status;
}
- auto itemType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureComputableType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ auto itemType = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureComputableType(input->Head().Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -5798,26 +5798,26 @@ namespace {
IGraphTransformer::TStatus CombineCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinMaxArgsCount(*input, 5U, 6U, ctx.Expr)) {
+ if (!EnsureMinMaxArgsCount(*input, 5U, 6U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
return IGraphTransformer::TStatus::Error;
}
- if (TCoCombineCore::idx_MemLimit < input->ChildrenSize()) {
- if (!EnsureAtom(*input->Child(TCoCombineCore::idx_MemLimit), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ if (TCoCombineCore::idx_MemLimit < input->ChildrenSize()) {
+ if (!EnsureAtom(*input->Child(TCoCombineCore::idx_MemLimit), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
- ui64 memLimit = 0ULL;
- if (!TryFromString(input->Child(TCoCombineCore::idx_MemLimit)->Content(), memLimit)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(TCoCombineCore::idx_MemLimit)->Pos()), TStringBuilder() <<
- "Bad memLimit value: " << input->Child(TCoCombineCore::idx_MemLimit)->Content()));
- return IGraphTransformer::TStatus::Error;
- }
+ ui64 memLimit = 0ULL;
+ if (!TryFromString(input->Child(TCoCombineCore::idx_MemLimit)->Content(), memLimit)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(TCoCombineCore::idx_MemLimit)->Pos()), TStringBuilder() <<
+ "Bad memLimit value: " << input->Child(TCoCombineCore::idx_MemLimit)->Content()));
+ return IGraphTransformer::TStatus::Error;
+ }
}
TExprNode::TPtr& keyExtractor = input->ChildRef(TCoCombineCore::idx_KeyExtractor);
@@ -5897,27 +5897,27 @@ namespace {
retItemType = finishType->Cast<TStreamExprType>()->GetItemType();
}
- input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *retItemType, ctx.Expr));
+ input->SetTypeAnn(MakeSequenceType(input->Head().GetTypeAnn()->GetKind(), *retItemType, ctx.Expr));
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus GroupingCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ IGraphTransformer::TStatus GroupingCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
if (!EnsureMinMaxArgsCount(*input, 3, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureStreamType(*input->Child(TCoGroupingCore::idx_Input), ctx.Expr)) {
+ if (!EnsureStreamType(*input->Child(TCoGroupingCore::idx_Input), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
const bool hasHandler = 4 == input->ChildrenSize();
- const auto streamType = input->Child(TCoGroupingCore::idx_Input)->GetTypeAnn();
+ const auto streamType = input->Child(TCoGroupingCore::idx_Input)->GetTypeAnn();
auto itemType = streamType->Cast<TStreamExprType>()->GetItemType();
- auto& groupSwitch = input->ChildRef(TCoGroupingCore::idx_GroupSwitch);
- auto& keyExtractor = input->ChildRef(TCoGroupingCore::idx_KeyExtractor);
-
+ auto& groupSwitch = input->ChildRef(TCoGroupingCore::idx_GroupSwitch);
+ auto& keyExtractor = input->ChildRef(TCoGroupingCore::idx_KeyExtractor);
+
auto status = ConvertToLambda(groupSwitch, ctx.Expr, 2);
status = status.Combine(ConvertToLambda(keyExtractor, ctx.Expr, 1));
if (hasHandler) {
@@ -5977,96 +5977,96 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const TTypeAnnotationNode* itemType = nullptr;
- if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto& keyExtractor = input->ChildRef(1U);
- auto& groupSwitch = input->ChildRef(2U);
- auto& handler = input->TailRef();
-
- auto status = ConvertToLambda(keyExtractor, ctx.Expr, 1);
- status = status.Combine(ConvertToLambda(groupSwitch, ctx.Expr, 2));
- status = status.Combine(ConvertToLambda(handler, ctx.Expr, 2));
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- // keyExtractor
- if (!UpdateLambdaAllArgumentsTypes(keyExtractor, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- if (!keyExtractor->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- // groupSwitch
- const auto keyType = keyExtractor->GetTypeAnn();
- if (!UpdateLambdaAllArgumentsTypes(groupSwitch, {keyType, itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- if (!groupSwitch->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
- if (!EnsureSpecificDataType(*groupSwitch, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(handler, {keyType, input->Head().GetTypeAnn()}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- if (!handler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (handler->GetTypeAnn()->GetKind() != input->Head().GetTypeAnn()->GetKind()) {
- switch (input->Head().GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Stream: {
- auto lambda = ctx.Expr.Builder(input->Tail().Pos())
- .Lambda()
- .Param("key")
- .Param("stream")
- .Callable("FromFlow")
- .Apply(0, input->Tail())
- .With(0, "key")
- .With(1, "stream")
- .Seal()
- .Seal()
- .Seal().Build();
- output = ctx.Expr.ChangeChild(*input, 3U, std::move(lambda));
- return IGraphTransformer::TStatus::Repeat;
- }
- case ETypeAnnotationKind::Flow: {
- auto lambda = ctx.Expr.Builder(input->Tail().Pos())
- .Lambda()
- .Param("key")
- .Param("flow")
- .Callable("ToFlow")
- .Apply(0, input->Tail())
- .With(0, "key")
- .With(1, "flow")
- .Seal()
- .Seal()
- .Seal().Build();
- output = ctx.Expr.ChangeChild(*input, 3U, std::move(lambda));
- return IGraphTransformer::TStatus::Repeat;
- }
- default:
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(keyExtractor->Pos()), TStringBuilder()
- << "Wrong handler kind of output sequence " << *handler->GetTypeAnn() << ", must be " << input->Head().GetTypeAnn()->GetKind()));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- input->SetTypeAnn(handler->GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
- }
+ IGraphTransformer::TStatus ChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const TTypeAnnotationNode* itemType = nullptr;
+ if (!EnsureNewSeqType<false, false>(input->Head(), ctx.Expr, &itemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto& keyExtractor = input->ChildRef(1U);
+ auto& groupSwitch = input->ChildRef(2U);
+ auto& handler = input->TailRef();
+
+ auto status = ConvertToLambda(keyExtractor, ctx.Expr, 1);
+ status = status.Combine(ConvertToLambda(groupSwitch, ctx.Expr, 2));
+ status = status.Combine(ConvertToLambda(handler, ctx.Expr, 2));
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ // keyExtractor
+ if (!UpdateLambdaAllArgumentsTypes(keyExtractor, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!keyExtractor->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ // groupSwitch
+ const auto keyType = keyExtractor->GetTypeAnn();
+ if (!UpdateLambdaAllArgumentsTypes(groupSwitch, {keyType, itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!groupSwitch->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ if (!EnsureSpecificDataType(*groupSwitch, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(handler, {keyType, input->Head().GetTypeAnn()}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!handler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (handler->GetTypeAnn()->GetKind() != input->Head().GetTypeAnn()->GetKind()) {
+ switch (input->Head().GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Stream: {
+ auto lambda = ctx.Expr.Builder(input->Tail().Pos())
+ .Lambda()
+ .Param("key")
+ .Param("stream")
+ .Callable("FromFlow")
+ .Apply(0, input->Tail())
+ .With(0, "key")
+ .With(1, "stream")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ output = ctx.Expr.ChangeChild(*input, 3U, std::move(lambda));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ case ETypeAnnotationKind::Flow: {
+ auto lambda = ctx.Expr.Builder(input->Tail().Pos())
+ .Lambda()
+ .Param("key")
+ .Param("flow")
+ .Callable("ToFlow")
+ .Apply(0, input->Tail())
+ .With(0, "key")
+ .With(1, "flow")
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ output = ctx.Expr.ChangeChild(*input, 3U, std::move(lambda));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ default:
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(keyExtractor->Pos()), TStringBuilder()
+ << "Wrong handler kind of output sequence " << *handler->GetTypeAnn() << ", must be " << input->Head().GetTypeAnn()->GetKind()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ input->SetTypeAnn(handler->GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+ }
IGraphTransformer::TStatus IterableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
@@ -6268,29 +6268,29 @@ namespace {
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus SqueezeToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1U, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (input->ChildrenSize() > 1U) {
- if (!EnsureSpecificDataType(input->Tail(), EDataSlot::Uint64, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- } else {
- auto children = input->ChildrenList();
- children.emplace_back(ctx.Expr.NewCallable(input->Pos(), "Uint64", {ctx.Expr.NewAtom(input->Pos(), "0", TNodeFlags::Default)}));
- output = ctx.Expr.ChangeChildren(*input, std::move(children));
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(ctx.Expr.MakeType<TListExprType>(itemType)));
- return IGraphTransformer::TStatus::Ok;
- }
+ IGraphTransformer::TStatus SqueezeToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1U, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > 1U) {
+ if (!EnsureSpecificDataType(input->Tail(), EDataSlot::Uint64, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ auto children = input->ChildrenList();
+ children.emplace_back(ctx.Expr.NewCallable(input->Pos(), "Uint64", {ctx.Expr.NewAtom(input->Pos(), "0", TNodeFlags::Default)}));
+ output = ctx.Expr.ChangeChildren(*input, std::move(children));
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(ctx.Expr.MakeType<TListExprType>(itemType)));
+ return IGraphTransformer::TStatus::Ok;
+ }
} // namespace NTypeAnnImpl
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_list.h b/ydb/library/yql/core/type_ann/type_ann_list.h
index fc64b60a4c..608b813fe8 100644
--- a/ydb/library/yql/core/type_ann/type_ann_list.h
+++ b/ydb/library/yql/core/type_ann/type_ann_list.h
@@ -10,92 +10,92 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus InferPositionalUnionType(TPositionHandle pos, const TExprNode::TListType& children,
TColumnOrder& resultColumnOrder, const TStructExprType*& resultStructType, TExtContext& ctx);
- IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- template <bool InverseCondition>
- IGraphTransformer::TStatus InclusiveFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ template <bool InverseCondition>
+ IGraphTransformer::TStatus InclusiveFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus LMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
template <bool Warn>
- IGraphTransformer::TStatus FlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- template <bool Ordered>
- IGraphTransformer::TStatus MultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ template <bool Ordered>
+ IGraphTransformer::TStatus MultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListFlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListSkipWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListTakeWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListSkipWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListTakeWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListSkipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListTakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListHeadWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListLastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListEnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListSortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListCollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListSkipWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListTakeWhileInclusiveWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListSkipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListTakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListHeadWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListLastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListEnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListSortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListCollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus FoldMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus Fold1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus Chain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus LengthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus IteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus EmptyIteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus Chain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus LengthWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus IteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus EmptyIteratorWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ForwardListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ToStreamWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ToSequenceWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus LazyListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus LazyListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CollectWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListFromRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ReplicateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SwitchWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus HasItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus UnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus HasItemsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus UnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus UnionAllPositionalWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
- template <bool IsStrict>
+ template <bool IsStrict>
IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListUnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus SortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus SortWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus UnorderedWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SortTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SessionWindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus GroupByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus GroupByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus PartitionByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus PartitionsByKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus FoldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus Fold1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus CondenseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus Condense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus PartitionsByKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ReverseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FoldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus Fold1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus CondenseWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus Condense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SqueezeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus Squeeze1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus DiscardWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus CombineByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ZipWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ZipAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus CombineByKeyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ExtractWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ExtractMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus AssumeUniqueWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus AssumeColumnOrderWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
- IGraphTransformer::TStatus AggregationTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus AggregationTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus MultiAggregateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus AggregateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus AggregateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SqlAggregateAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus FilterNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus SkipNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus FilterNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus SkipNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FilterNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus SkipNullMembersWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FilterNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus SkipNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinOnRowsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinOnRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
@@ -107,16 +107,16 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus HoppingCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus MultiHoppingCoreWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus HoppingTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListMinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListSumWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ListAvgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- template <bool AllOrAny>
- IGraphTransformer::TStatus ListAllAnyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListMinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListSumWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListConcatWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListAvgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ template <bool AllOrAny>
+ IGraphTransformer::TStatus ListAllAnyWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListNotNullWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListFlattenWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus IterableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus SqueezeToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus SqueezeToListWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
} // namespace NTypeAnnImpl
} // namespace NYql
diff --git a/ydb/library/yql/core/type_ann/type_ann_types.cpp b/ydb/library/yql/core/type_ann/type_ann_types.cpp
index 1a0f3fd117..c27c0c433f 100644
--- a/ydb/library/yql/core/type_ann/type_ann_types.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_types.cpp
@@ -84,36 +84,36 @@ namespace NTypeAnnImpl {
template <>
IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Generic>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto genType = ctx.Expr.MakeType<TGenericExprType>();
+ auto genType = ctx.Expr.MakeType<TGenericExprType>();
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(genType));
return IGraphTransformer::TStatus::Ok;
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto tag = input->Child(0)->Content();
+ auto tag = input->Child(0)->Content();
auto resType = ctx.Expr.MakeType<TResourceExprType>(tag);
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(resType));
return IGraphTransformer::TStatus::Ok;
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -121,16 +121,16 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto underlyingType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(0)->Pos(), *underlyingType, ctx.Expr)) {
+ if (!EnsureInspectableType(input->Child(0)->Pos(), *underlyingType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto tag = input->Child(1)->Content();
+ auto tag = input->Child(1)->Content();
auto taggedType = ctx.Expr.MakeType<TTaggedExprType>(underlyingType, tag);
if (!taggedType->Validate(input->Pos(), ctx.Expr)) {
@@ -141,21 +141,21 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Error>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Error>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(2), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -164,13 +164,13 @@ namespace NTypeAnnImpl {
}
ui32 row = 0;
- if (!TryFromString(input->Child(0)->Content(), row)) {
+ if (!TryFromString(input->Child(0)->Content(), row)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(0)->Content()));
return IGraphTransformer::TStatus::Error;
}
ui32 column = 0;
- if (!TryFromString(input->Child(1)->Content(), column)) {
+ if (!TryFromString(input->Child(1)->Content(), column)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -183,36 +183,36 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto name = input->Child(0)->Content();
+ auto name = input->Child(0)->Content();
auto slot = NKikimr::NUdf::FindDataSlot(name);
if (!slot) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Unknown data type: " << name));
return IGraphTransformer::TStatus::Error;
} else if (*slot == EDataSlot::Decimal) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
auto dataType = ctx.Expr.MakeType<TDataExprParamsType>(*slot , input->Child(1)->Content(), input->Child(2)->Content());
if (!dataType->Validate(input->Pos(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
+ return IGraphTransformer::TStatus::Error;
+ }
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(dataType));
- } else {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ } else {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
auto dataType = ctx.Expr.MakeType<TDataExprType>(*slot);
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(dataType));
}
@@ -220,9 +220,9 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -231,7 +231,7 @@ namespace NTypeAnnImpl {
}
auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -241,9 +241,9 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -252,7 +252,7 @@ namespace NTypeAnnImpl {
}
auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -262,30 +262,30 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Flow>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Flow>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
if (auto status = EnsureTypeRewrite(input->HeadRef(), ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- auto listType = ctx.Expr.MakeType<TFlowExprType>(itemType);
- input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(listType));
- return IGraphTransformer::TStatus::Ok;
- }
-
- template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ }
+
+ auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ auto listType = ctx.Expr.MakeType<TFlowExprType>(itemType);
+ input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(listType));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ template <>
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -294,7 +294,7 @@ namespace NTypeAnnImpl {
}
auto itemType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
+ if (!EnsureInspectableType(input->Child(0)->Pos(), *itemType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -304,7 +304,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
TTypeAnnotationNode::TListType items;
for (size_t i = 0; i < input->ChildrenSize(); ++i) {
@@ -326,30 +326,30 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Multi>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- Y_UNUSED(output);
- TTypeAnnotationNode::TListType items;
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Multi>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ Y_UNUSED(output);
+ TTypeAnnotationNode::TListType items;
for (size_t i = 0; i < input->ChildrenSize(); ++i) {
auto& child = input->ChildRef(i);
if (auto status = EnsureTypeRewrite(child, ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
return status;
- }
-
- auto elemType = child->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(child->Pos(), *elemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- items.push_back(elemType);
- }
-
- auto multiType = ctx.Expr.MakeType<TMultiExprType>(items);
- input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(multiType));
- return IGraphTransformer::TStatus::Ok;
- }
-
- template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ }
+
+ auto elemType = child->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureInspectableType(child->Pos(), *elemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ items.push_back(elemType);
+ }
+
+ auto multiType = ctx.Expr.MakeType<TMultiExprType>(items);
+ input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(multiType));
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ template <>
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
TVector<const TItemExprType*> items;
for (size_t i = 0; i < input->ChildrenSize(); ++i) {
@@ -380,7 +380,7 @@ namespace NTypeAnnImpl {
}
auto structType = ctx.Expr.MakeType<TStructExprType>(items);
- if (!structType->Validate(input->Pos(), ctx.Expr)) {
+ if (!structType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -400,9 +400,9 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -416,12 +416,12 @@ namespace NTypeAnnImpl {
auto keyType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
auto payloadType = input->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureInspectableType(input->Child(1)->Pos(), *payloadType, ctx.Expr)) {
+ if (!EnsureInspectableType(input->Child(1)->Pos(), *payloadType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto dictType = ctx.Expr.MakeType<TDictExprType>(keyType, payloadType);
- if (!dictType->Validate(input->Pos(), ctx.Expr)) {
+ if (!dictType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -430,13 +430,13 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto voidType = ctx.Expr.MakeType<TVoidExprType>();
+ auto voidType = ctx.Expr.MakeType<TVoidExprType>();
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(voidType));
return IGraphTransformer::TStatus::Ok;
}
@@ -454,13 +454,13 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Unit>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Unit>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- auto unitType = ctx.Expr.MakeType<TUnitExprType>();
+ auto unitType = ctx.Expr.MakeType<TUnitExprType>();
input->SetTypeAnn(ctx.Expr.MakeType<TTypeExprType>(unitType));
return IGraphTransformer::TStatus::Ok;
}
@@ -490,8 +490,8 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::OptionalItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::OptionalItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -517,13 +517,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TOptionalExprType>()->GetItemType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *type->Cast<TOptionalExprType>()->GetItemType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ListItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ListItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -549,13 +549,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TListExprType>()->GetItemType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *type->Cast<TListExprType>()->GetItemType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StreamItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StreamItem>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -576,13 +576,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TStreamExprType>()->GetItemType(), ctx.Expr);
+ output = ExpandType(input->Pos(), *type->Cast<TStreamExprType>()->GetItemType(), ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::TupleElement>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::TupleElement>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -590,7 +590,7 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -602,7 +602,7 @@ namespace NTypeAnnImpl {
}
ui32 index = 0;
- if (!TryFromString(input->Child(1)->Content(), index)) {
+ if (!TryFromString(input->Child(1)->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -615,13 +615,13 @@ namespace NTypeAnnImpl {
}
- output = ExpandType(input->Pos(), *tupleType->GetItems()[index], ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *tupleType->GetItems()[index], ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StructMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::StructMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -629,7 +629,7 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -643,7 +643,7 @@ namespace NTypeAnnImpl {
auto structType = type->Cast<TStructExprType>();
const TItemExprType* foundMember = nullptr;
for (auto item : structType->GetItems()) {
- if (item->GetName() == input->Child(1)->Content()) {
+ if (item->GetName() == input->Child(1)->Content()) {
foundMember = item;
break;
}
@@ -651,17 +651,17 @@ namespace NTypeAnnImpl {
if (!foundMember) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() << "Incorrect member name: "
- << input->Child(1)->Content()));
+ << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *foundMember->GetItemType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *foundMember->GetItemType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictKey>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictKey>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -681,13 +681,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TDictExprType>()->GetKeyType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *type->Cast<TDictExprType>()->GetKeyType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictPayload>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::DictPayload>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -707,51 +707,51 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TDictExprType>()->GetPayloadType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *type->Cast<TDictExprType>()->GetPayloadType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
+ if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTupleMinSize(*input->Child(0), 0, ctx.Expr)) {
+ if (!EnsureTupleMinSize(*input->Child(0), 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureTupleMaxSize(*input->Child(0), 2, ctx.Expr)) {
+ if (!EnsureTupleMaxSize(*input->Child(0), 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
ui32 optionalArgsCount = 0;
- if (input->Child(0)->ChildrenSize() > 0) {
- if (!EnsureAtom(*input->Child(0)->Child(0), ctx.Expr)) {
+ if (input->Child(0)->ChildrenSize() > 0) {
+ if (!EnsureAtom(*input->Child(0)->Child(0), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!TryFromString(input->Child(0)->Child(0)->Content(), optionalArgsCount)) {
+ if (!TryFromString(input->Child(0)->Child(0)->Content(), optionalArgsCount)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: "
- << input->Child(0)->Child(0)->Content()));
+ << input->Child(0)->Child(0)->Content()));
return IGraphTransformer::TStatus::Error;
}
}
TString payload;
- if (input->Child(0)->ChildrenSize() > 1) {
- if (!EnsureAtom(*input->Child(0)->Child(1), ctx.Expr)) {
+ if (input->Child(0)->ChildrenSize() > 1) {
+ if (!EnsureAtom(*input->Child(0)->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- payload = input->Child(0)->Child(1)->Content();
+ payload = input->Child(0)->Child(1)->Content();
}
const TTypeAnnotationNode* resultType = nullptr;
TVector<TCallableExprType::TArgumentInfo> arguments;
- for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
- auto child = input->Child(index);
+ for (ui32 index = 1; index < input->ChildrenSize(); ++index) {
+ auto child = input->Child(index);
if (!EnsureTupleMinSize(*child, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -804,7 +804,7 @@ namespace NTypeAnnImpl {
}
auto callableType = ctx.Expr.MakeType<TCallableExprType>(resultType, arguments, optionalArgsCount, payload);
- if (!callableType->Validate(input->Pos(), ctx.Expr)) {
+ if (!callableType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -813,8 +813,8 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableResult>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableResult>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -829,13 +829,13 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TCallableExprType>()->GetReturnType(), ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *type->Cast<TCallableExprType>()->GetReturnType(), ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableArgument>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::CallableArgument>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -843,7 +843,7 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -855,7 +855,7 @@ namespace NTypeAnnImpl {
}
ui32 index = 0;
- if (!TryFromString(input->Child(1)->Content(), index)) {
+ if (!TryFromString(input->Child(1)->Content(), index)) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Failed to convert to integer: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
@@ -867,17 +867,17 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *callableType->GetArguments()[index].Type, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *callableType->GetArguments()[index].Type, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus ParseTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ IGraphTransformer::TStatus ParseTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -893,7 +893,7 @@ namespace NTypeAnnImpl {
auto astRoot = TAstNode::NewList(inputPos, pool,
TAstNode::NewList(inputPos, pool,
TAstNode::NewLiteralAtom(inputPos, TStringBuf("return"), pool), parsedType));
- TExprNode::TPtr exprRoot;
+ TExprNode::TPtr exprRoot;
if (!CompileExpr(*astRoot, exprRoot, ctx.Expr, nullptr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -909,9 +909,9 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -969,8 +969,8 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::AddMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::AddMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -978,7 +978,7 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -987,30 +987,30 @@ namespace NTypeAnnImpl {
}
auto type = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureStructType(input->Child(0)->Pos(), *type, ctx.Expr)) {
+ if (!EnsureStructType(input->Child(0)->Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto structType = type->Cast<TStructExprType>();
TVector<const TItemExprType*> items = structType->GetItems();
- auto newItem = ctx.Expr.MakeType<TItemExprType>(input->Child(1)->Content(),
+ auto newItem = ctx.Expr.MakeType<TItemExprType>(input->Child(1)->Content(),
input->Child(2)->GetTypeAnn()->Cast<TTypeExprType>()->GetType());
- if (!newItem->Validate(input->Pos(), ctx.Expr)) {
+ if (!newItem->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
items.push_back(newItem);
auto newStructType = ctx.Expr.MakeType<TStructExprType>(items);
- if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
+ if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus RemoveMemberImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, bool force) {
- if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
+ IGraphTransformer::TStatus RemoveMemberImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx, bool force) {
+ if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1018,7 +1018,7 @@ namespace NTypeAnnImpl {
return status;
}
- if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
+ if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1028,7 +1028,7 @@ namespace NTypeAnnImpl {
}
auto type = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureStructType(input->Child(0)->Pos(), *type, ctx.Expr)) {
+ if (!EnsureStructType(input->Child(0)->Pos(), *type, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1037,7 +1037,7 @@ namespace NTypeAnnImpl {
items.reserve(Max<ui64>(structType->GetSize(), 1) - 1);
bool found = false;
for (auto& item : structType->GetItems()) {
- if (item->GetName() == input->Child(1)->Content()) {
+ if (item->GetName() == input->Child(1)->Content()) {
found = true;
continue;
}
@@ -1047,33 +1047,33 @@ namespace NTypeAnnImpl {
if (!found && !force) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() <<
- "Unknown member name: " << input->Child(1)->Content()));
+ "Unknown member name: " << input->Child(1)->Content()));
return IGraphTransformer::TStatus::Error;
}
auto newStructType = ctx.Expr.MakeType<TStructExprType>(items);
- if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
+ if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::RemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::RemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return RemoveMemberImpl(input, output, ctx, false);
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ForceRemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::ForceRemoveMember>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return RemoveMemberImpl(input, output, ctx, true);
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::FlattenMembers>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::FlattenMembers>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
TVector<const TItemExprType*> allItems;
- for (auto& child : input->Children()) {
+ for (auto& child : input->Children()) {
if (!EnsureTupleSize(*child, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1115,18 +1115,18 @@ namespace NTypeAnnImpl {
}
auto newStructType = ctx.Expr.MakeType<TStructExprType>(allItems);
- if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
+ if (!newStructType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
- return IGraphTransformer::TStatus::Repeat;
+ output = ExpandType(input->Pos(), *newStructType, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
}
template <>
- IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TypeWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1135,12 +1135,12 @@ namespace NTypeAnnImpl {
}
auto underlyingType = input->Child(0)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureComputableType(input->Child(0)->Pos(), *underlyingType, ctx.Expr)) {
+ if (!EnsureComputableType(input->Child(0)->Pos(), *underlyingType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto varType = ctx.Expr.MakeType<TVariantExprType>(underlyingType);
- if (!varType->Validate(input->Pos(), ctx.Expr)) {
+ if (!varType->Validate(input->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1149,8 +1149,8 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::VariantUnderlying>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ IGraphTransformer::TStatus TypeArgWrapper<ETypeArgument::VariantUnderlying>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1171,7 +1171,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- output = ExpandType(input->Pos(), *type->Cast<TVariantExprType>()->GetUnderlyingType(), ctx.Expr);
+ output = ExpandType(input->Pos(), *type->Cast<TVariantExprType>()->GetUnderlyingType(), ctx.Expr);
return IGraphTransformer::TStatus::Repeat;
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_types.h b/ydb/library/yql/core/type_ann/type_ann_types.h
index a06c8de437..8c79ed458d 100644
--- a/ydb/library/yql/core/type_ann/type_ann_types.h
+++ b/ydb/library/yql/core/type_ann/type_ann_types.h
@@ -8,7 +8,7 @@
namespace NYql {
namespace NTypeAnnImpl {
template <ETypeAnnotationKind>
- IGraphTransformer::TStatus TypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus TypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
#define TYPE_ANN_TYPE_ARGUMENT_MAP(xx) \
xx(Unknown, 0) \
@@ -32,9 +32,9 @@ namespace NTypeAnnImpl {
};
template <ETypeArgument>
- IGraphTransformer::TStatus TypeArgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus ParseTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
- IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus TypeArgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ParseTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+ IGraphTransformer::TStatus FormatTypeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus TypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus SerializeTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ParseTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
diff --git a/ydb/library/yql/core/type_ann/type_ann_wide.cpp b/ydb/library/yql/core/type_ann/type_ann_wide.cpp
index 3b305c2025..5b23722ca4 100644
--- a/ydb/library/yql/core/type_ann/type_ann_wide.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_wide.cpp
@@ -1,629 +1,629 @@
-#include "type_ann_wide.h"
-
+#include "type_ann_wide.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/core/yql_expr_type_annotation.h>
-
-namespace NYql {
-namespace NTypeAnnImpl {
-
-namespace {
-
-const TMultiExprType* GetWideLambdaOutputType(const TExprNode& lambda, TExprContext& ctx) {
- TTypeAnnotationNode::TListType types;
- types.reserve(lambda.ChildrenSize() - 1U);
- for (ui32 i = 1U; i < lambda.ChildrenSize(); ++i) {
- types.emplace_back(lambda.Child(i)->GetTypeAnn());
- }
- return ctx.MakeType<TMultiExprType>(types);
-}
-
-}
-
-IGraphTransformer::TStatus ExpandMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
-
- auto& lambda = input->TailRef();
-
- const auto status = ConvertToLambda(lambda, ctx.Expr, 1U);
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*lambda, ctx.Expr)));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->TailRef();
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (const auto width = lambda->Head().ChildrenSize(); lambda->ChildrenSize() == width + 1U) {
- bool pass = true;
- for (auto i = 0U; pass && i < width; ++i)
- pass = lambda->Head().Child(i) == lambda->Child(i + 1U);
-
- if (pass) {
- output = input->HeadPtr();
- return IGraphTransformer::TStatus::Repeat;
- }
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*lambda, ctx.Expr)));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideChain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 3U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& initLambda = input->ChildRef(1U);
-
- if (const auto status = ConvertToLambda(initLambda, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(initLambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!initLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- auto argTypes = multiType->GetItems();
-
- const auto initType = GetWideLambdaOutputType(*initLambda, ctx.Expr);
- const auto& stateTypes = initType->GetItems();
- argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
-
- auto& updateLambda = input->TailRef();
- if (const auto status = ConvertToLambda(updateLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(updateLambda, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!updateLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (const auto outputType = GetWideLambdaOutputType(*updateLambda, ctx.Expr); !IsSameAnnotation(*initType, *outputType)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch init and update handlers output types: "
- << *static_cast<const TTypeAnnotationNode*>(initType) << " and " << *static_cast<const TTypeAnnotationNode*>(outputType)));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(initType));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (input->ChildrenSize() > 2U) {
- const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
- if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()),
- TStringBuilder() << "Mismatch 'limit' type. Expected Uint64, got: " << *input->Tail().GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->ChildRef(1U);
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->TailRef();
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(input->Head().GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideCondense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& initLambda = input->ChildRef(1U);
- auto& switchLambda = input->ChildRef(2U);
- auto& updateLambda = input->ChildRef(3U);
-
- if (const auto status = ConvertToLambda(initLambda, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(initLambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!initLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto initType = GetWideLambdaOutputType(*initLambda, ctx.Expr);
- const auto& stateTypes = initType->GetItems();
- for (ui32 i = 1U; i < initLambda->ChildrenSize(); ++i) {
- if (!EnsureComputableType(initLambda->Child(i)->Pos(), *stateTypes.back(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- auto argTypes = multiType->GetItems();
- argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
-
- if (const auto status = ConvertToLambda(switchLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(switchLambda, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!switchLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- bool isOptional;
- const TDataExprType* dataType;
- if (!EnsureDataOrOptionalOfData(switchLambda->Pos(), switchLambda->GetTypeAnn(), isOptional, dataType, ctx.Expr) || !EnsureSpecificDataType(switchLambda->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(switchLambda->Pos()), TStringBuilder() << "Switch lambda returns " << *switchLambda->GetTypeAnn() << " instead of boolean."));
- return IGraphTransformer::TStatus::Error;
- }
-
- if (const auto status = ConvertToLambda(updateLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(updateLambda, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!updateLambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (const auto outputType = GetWideLambdaOutputType(*updateLambda, ctx.Expr); !IsSameAnnotation(*initType, *outputType)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch init and update handlers output types: "
- << *static_cast<const TTypeAnnotationNode*>(initType) << " and " << *static_cast<const TTypeAnnotationNode*>(outputType)));
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(initType));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideCombinerWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 6U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- if (!EnsureAtom(*input->Child(1U), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (const auto& limit = input->Child(1U)->Content(); !limit.empty()) {
- ui64 memLimit = 0ULL;
- if (!TryFromString(limit, memLimit)) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()), TStringBuilder() <<
- "Bad memLimit value: " << limit));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- auto& keyExtractor = input->ChildRef(2U);
- auto& initHandler = input->ChildRef(3U);
- auto& updateHandler = input->ChildRef(4U);
- auto& finishHandler = input->ChildRef(5U);
-
- if (const auto status = ConvertToLambda(keyExtractor, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(keyExtractor, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!keyExtractor->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- TTypeAnnotationNode::TListType keyTypes;
- keyTypes.reserve(keyExtractor->ChildrenSize() - 1U);
- for (ui32 i = 1U; i < keyExtractor->ChildrenSize(); ++i) {
- const auto child = keyExtractor->Child(i);
- keyTypes.emplace_back(child->GetTypeAnn());
- if (!EnsureHashableKey(child->Pos(), keyTypes.back(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- if (!EnsureEquatableKey(child->Pos(), keyTypes.back(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- auto argTypes = multiType->GetItems();
- argTypes.insert(argTypes.cbegin(), keyTypes.cbegin(), keyTypes.cend());
-
- if (const auto status = ConvertToLambda(initHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(initHandler, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!initHandler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- TTypeAnnotationNode::TListType stateTypes;
- stateTypes.reserve(initHandler->ChildrenSize() - 1U);
- for (ui32 i = 1U; i < initHandler->ChildrenSize(); ++i) {
- const auto child = initHandler->Child(i);
- stateTypes.emplace_back(child->GetTypeAnn());
- if (!EnsureComputableType(child->Pos(), *stateTypes.back(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
-
- if (const auto status = ConvertToLambda(updateHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(updateHandler, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!updateHandler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- for (auto i = updateHandler->ChildrenSize() - 1U; i;) {
- const auto child = updateHandler->Child(i);
- if (!IsSameAnnotation(*stateTypes[--i], *child->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "State type changed in update from "
- << *stateTypes[i] << " on " << *child->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- argTypes.erase(argTypes.cbegin() + keyTypes.size(), argTypes.cbegin() + keyTypes.size() + multiType->GetSize());
-
- if (const auto status = ConvertToLambda(finishHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(finishHandler, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!finishHandler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*finishHandler, ctx.Expr)));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus WideChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
-
- if (!EnsureMultiType(input->Head().Pos(), *itemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = itemType->Cast<TMultiExprType>();
-
- auto& keyExtractor = input->ChildRef(1U);
- auto& groupSwitch = input->ChildRef(2U);
- auto& handler = input->TailRef();
-
- if (const auto status = ConvertToLambda(keyExtractor, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(keyExtractor, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!keyExtractor->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- TTypeAnnotationNode::TListType keyTypes;
- keyTypes.reserve(keyExtractor->ChildrenSize() - 1U);
- for (ui32 i = 1U; i < keyExtractor->ChildrenSize(); ++i) {
- keyTypes.emplace_back(keyExtractor->Child(i)->GetTypeAnn());
- if (!EnsureComputableType(keyExtractor->Child(i)->Pos(), *keyTypes.back(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- auto argTypes = multiType->GetItems();
- argTypes.insert(argTypes.cbegin(), keyTypes.cbegin(), keyTypes.cend());
-
- if (const auto status = ConvertToLambda(groupSwitch, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(groupSwitch, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!groupSwitch->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureSpecificDataType(*groupSwitch, EDataSlot::Bool, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- argTypes.resize(keyTypes.size());
- argTypes.emplace_back(input->Head().GetTypeAnn());
-
- if (const auto status = ConvertToLambda(handler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(handler, argTypes, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!handler->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!EnsureFlowType(*handler, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureMultiType(handler->Pos(), *handler->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(handler->GetTypeAnn());
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus NarrowMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->TailRef();
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto outputItemType = lambda->GetTypeAnn();
- if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus NarrowMultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->TailRef();
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (lambda->ChildrenSize() < 3U) {
- output = ctx.Expr.RenameNode(*input, "NarrowMap");
- return IGraphTransformer::TStatus::Repeat;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const auto outputItemType = lambda->Tail().GetTypeAnn();
- if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- for (ui32 i = lambda->ChildrenSize() - 2U; i > 0U; --i) {
- if (!IsSameAnnotation(*outputItemType, *lambda->Child(i)->GetTypeAnn())) {
- ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder() << "Mismatch of multi map lambda return types: "
- << *outputItemType << " and " << *lambda->Child(i)->GetTypeAnn()));
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
- return IGraphTransformer::TStatus::Ok;
-}
-
-IGraphTransformer::TStatus NarrowFlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
- if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
-
- auto& lambda = input->TailRef();
- const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
- if (status.Level != IGraphTransformer::TStatus::Ok) {
- return status;
- }
-
- if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!lambda->GetTypeAnn()) {
- return IGraphTransformer::TStatus::Repeat;
- }
-
- const TTypeAnnotationNode* outputItemType = nullptr;
- if (!EnsureNewSeqType<true>(*lambda, ctx.Expr, &outputItemType)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
- return IGraphTransformer::TStatus::Ok;
-}
-
-} // namespace NTypeAnnImpl
-}
+
+namespace NYql {
+namespace NTypeAnnImpl {
+
+namespace {
+
+const TMultiExprType* GetWideLambdaOutputType(const TExprNode& lambda, TExprContext& ctx) {
+ TTypeAnnotationNode::TListType types;
+ types.reserve(lambda.ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < lambda.ChildrenSize(); ++i) {
+ types.emplace_back(lambda.Child(i)->GetTypeAnn());
+ }
+ return ctx.MakeType<TMultiExprType>(types);
+}
+
+}
+
+IGraphTransformer::TStatus ExpandMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+
+ auto& lambda = input->TailRef();
+
+ const auto status = ConvertToLambda(lambda, ctx.Expr, 1U);
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, {itemType}, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*lambda, ctx.Expr)));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->TailRef();
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (const auto width = lambda->Head().ChildrenSize(); lambda->ChildrenSize() == width + 1U) {
+ bool pass = true;
+ for (auto i = 0U; pass && i < width; ++i)
+ pass = lambda->Head().Child(i) == lambda->Child(i + 1U);
+
+ if (pass) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*lambda, ctx.Expr)));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideChain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 3U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& initLambda = input->ChildRef(1U);
+
+ if (const auto status = ConvertToLambda(initLambda, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(initLambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!initLambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto argTypes = multiType->GetItems();
+
+ const auto initType = GetWideLambdaOutputType(*initLambda, ctx.Expr);
+ const auto& stateTypes = initType->GetItems();
+ argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
+
+ auto& updateLambda = input->TailRef();
+ if (const auto status = ConvertToLambda(updateLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(updateLambda, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!updateLambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (const auto outputType = GetWideLambdaOutputType(*updateLambda, ctx.Expr); !IsSameAnnotation(*initType, *outputType)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch init and update handlers output types: "
+ << *static_cast<const TTypeAnnotationNode*>(initType) << " and " << *static_cast<const TTypeAnnotationNode*>(outputType)));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(initType));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > 2U) {
+ const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()),
+ TStringBuilder() << "Mismatch 'limit' type. Expected Uint64, got: " << *input->Tail().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->ChildRef(1U);
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->TailRef();
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureSpecificDataType(*lambda, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideCondense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& initLambda = input->ChildRef(1U);
+ auto& switchLambda = input->ChildRef(2U);
+ auto& updateLambda = input->ChildRef(3U);
+
+ if (const auto status = ConvertToLambda(initLambda, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(initLambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!initLambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto initType = GetWideLambdaOutputType(*initLambda, ctx.Expr);
+ const auto& stateTypes = initType->GetItems();
+ for (ui32 i = 1U; i < initLambda->ChildrenSize(); ++i) {
+ if (!EnsureComputableType(initLambda->Child(i)->Pos(), *stateTypes.back(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ auto argTypes = multiType->GetItems();
+ argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
+
+ if (const auto status = ConvertToLambda(switchLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(switchLambda, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!switchLambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ bool isOptional;
+ const TDataExprType* dataType;
+ if (!EnsureDataOrOptionalOfData(switchLambda->Pos(), switchLambda->GetTypeAnn(), isOptional, dataType, ctx.Expr) || !EnsureSpecificDataType(switchLambda->Pos(), *dataType, EDataSlot::Bool, ctx.Expr)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(switchLambda->Pos()), TStringBuilder() << "Switch lambda returns " << *switchLambda->GetTypeAnn() << " instead of boolean."));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (const auto status = ConvertToLambda(updateLambda, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(updateLambda, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!updateLambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (const auto outputType = GetWideLambdaOutputType(*updateLambda, ctx.Expr); !IsSameAnnotation(*initType, *outputType)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()), TStringBuilder() << "Mismatch init and update handlers output types: "
+ << *static_cast<const TTypeAnnotationNode*>(initType) << " and " << *static_cast<const TTypeAnnotationNode*>(outputType)));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(initType));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideCombinerWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 6U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ if (!EnsureAtom(*input->Child(1U), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (const auto& limit = input->Child(1U)->Content(); !limit.empty()) {
+ ui64 memLimit = 0ULL;
+ if (!TryFromString(limit, memLimit)) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1U)->Pos()), TStringBuilder() <<
+ "Bad memLimit value: " << limit));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ auto& keyExtractor = input->ChildRef(2U);
+ auto& initHandler = input->ChildRef(3U);
+ auto& updateHandler = input->ChildRef(4U);
+ auto& finishHandler = input->ChildRef(5U);
+
+ if (const auto status = ConvertToLambda(keyExtractor, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(keyExtractor, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!keyExtractor->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ TTypeAnnotationNode::TListType keyTypes;
+ keyTypes.reserve(keyExtractor->ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < keyExtractor->ChildrenSize(); ++i) {
+ const auto child = keyExtractor->Child(i);
+ keyTypes.emplace_back(child->GetTypeAnn());
+ if (!EnsureHashableKey(child->Pos(), keyTypes.back(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ if (!EnsureEquatableKey(child->Pos(), keyTypes.back(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ auto argTypes = multiType->GetItems();
+ argTypes.insert(argTypes.cbegin(), keyTypes.cbegin(), keyTypes.cend());
+
+ if (const auto status = ConvertToLambda(initHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(initHandler, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!initHandler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ TTypeAnnotationNode::TListType stateTypes;
+ stateTypes.reserve(initHandler->ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < initHandler->ChildrenSize(); ++i) {
+ const auto child = initHandler->Child(i);
+ stateTypes.emplace_back(child->GetTypeAnn());
+ if (!EnsureComputableType(child->Pos(), *stateTypes.back(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ argTypes.insert(argTypes.cend(), stateTypes.cbegin(), stateTypes.cend());
+
+ if (const auto status = ConvertToLambda(updateHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(updateHandler, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!updateHandler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ for (auto i = updateHandler->ChildrenSize() - 1U; i;) {
+ const auto child = updateHandler->Child(i);
+ if (!IsSameAnnotation(*stateTypes[--i], *child->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "State type changed in update from "
+ << *stateTypes[i] << " on " << *child->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ argTypes.erase(argTypes.cbegin() + keyTypes.size(), argTypes.cbegin() + keyTypes.size() + multiType->GetSize());
+
+ if (const auto status = ConvertToLambda(finishHandler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(finishHandler, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!finishHandler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(GetWideLambdaOutputType(*finishHandler, ctx.Expr)));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus WideChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 4U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto itemType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+
+ if (!EnsureMultiType(input->Head().Pos(), *itemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = itemType->Cast<TMultiExprType>();
+
+ auto& keyExtractor = input->ChildRef(1U);
+ auto& groupSwitch = input->ChildRef(2U);
+ auto& handler = input->TailRef();
+
+ if (const auto status = ConvertToLambda(keyExtractor, ctx.Expr, multiType->GetSize()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(keyExtractor, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!keyExtractor->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ TTypeAnnotationNode::TListType keyTypes;
+ keyTypes.reserve(keyExtractor->ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < keyExtractor->ChildrenSize(); ++i) {
+ keyTypes.emplace_back(keyExtractor->Child(i)->GetTypeAnn());
+ if (!EnsureComputableType(keyExtractor->Child(i)->Pos(), *keyTypes.back(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ auto argTypes = multiType->GetItems();
+ argTypes.insert(argTypes.cbegin(), keyTypes.cbegin(), keyTypes.cend());
+
+ if (const auto status = ConvertToLambda(groupSwitch, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(groupSwitch, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!groupSwitch->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureSpecificDataType(*groupSwitch, EDataSlot::Bool, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ argTypes.resize(keyTypes.size());
+ argTypes.emplace_back(input->Head().GetTypeAnn());
+
+ if (const auto status = ConvertToLambda(handler, ctx.Expr, argTypes.size()); status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(handler, argTypes, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!handler->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureFlowType(*handler, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureMultiType(handler->Pos(), *handler->GetTypeAnn()->Cast<TFlowExprType>()->GetItemType(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(handler->GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus NarrowMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->TailRef();
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto outputItemType = lambda->GetTypeAnn();
+ if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus NarrowMultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->TailRef();
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (lambda->ChildrenSize() < 3U) {
+ output = ctx.Expr.RenameNode(*input, "NarrowMap");
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const auto outputItemType = lambda->Tail().GetTypeAnn();
+ if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ for (ui32 i = lambda->ChildrenSize() - 2U; i > 0U; --i) {
+ if (!IsSameAnnotation(*outputItemType, *lambda->Child(i)->GetTypeAnn())) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), TStringBuilder() << "Mismatch of multi map lambda return types: "
+ << *outputItemType << " and " << *lambda->Child(i)->GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+IGraphTransformer::TStatus NarrowFlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureWideFlowType(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto multiType = input->Head().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>();
+
+ auto& lambda = input->TailRef();
+ const auto status = ConvertToLambda(lambda, ctx.Expr, multiType->GetSize());
+ if (status.Level != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if (!UpdateLambdaAllArgumentsTypes(lambda, multiType->GetItems(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!lambda->GetTypeAnn()) {
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ const TTypeAnnotationNode* outputItemType = nullptr;
+ if (!EnsureNewSeqType<true>(*lambda, ctx.Expr, &outputItemType)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureComputableType(lambda->Pos(), *outputItemType, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(outputItemType));
+ return IGraphTransformer::TStatus::Ok;
+}
+
+} // namespace NTypeAnnImpl
+}
diff --git a/ydb/library/yql/core/type_ann/type_ann_wide.h b/ydb/library/yql/core/type_ann/type_ann_wide.h
index 14533f721f..71ffe0af19 100644
--- a/ydb/library/yql/core/type_ann/type_ann_wide.h
+++ b/ydb/library/yql/core/type_ann/type_ann_wide.h
@@ -1,24 +1,24 @@
-#pragma once
-
-#include "type_ann_impl.h"
-
+#pragma once
+
+#include "type_ann_impl.h"
+
#include <ydb/library/yql/ast/yql_expr.h>
#include <ydb/library/yql/ast/yql_expr_types.h>
-
-namespace NYql {
-namespace NTypeAnnImpl {
- IGraphTransformer::TStatus ExpandMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- IGraphTransformer::TStatus WideMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideCombinerWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideCondense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideChain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-
- IGraphTransformer::TStatus NarrowMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus NarrowFlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus NarrowMultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
-} // namespace NTypeAnnImpl
-} // namespace NYql
+
+namespace NYql {
+namespace NTypeAnnImpl {
+ IGraphTransformer::TStatus ExpandMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ IGraphTransformer::TStatus WideMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideWhileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideCombinerWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideCondense1Wrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideChopperWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideChain1MapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+
+ IGraphTransformer::TStatus NarrowMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus NarrowFlatMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus NarrowMultiMapWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+} // namespace NTypeAnnImpl
+} // namespace NYql
diff --git a/ydb/library/yql/core/type_ann/ya.make b/ydb/library/yql/core/type_ann/ya.make
index 292b3a0ce4..be843b5abc 100644
--- a/ydb/library/yql/core/type_ann/ya.make
+++ b/ydb/library/yql/core/type_ann/ya.make
@@ -18,8 +18,8 @@ SRCS(
type_ann_list.h
type_ann_types.cpp
type_ann_types.h
- type_ann_wide.cpp
- type_ann_wide.h
+ type_ann_wide.cpp
+ type_ann_wide.h
)
PEERDIR(
diff --git a/ydb/library/yql/core/ya.make b/ydb/library/yql/core/ya.make
index f4c9e06977..29169996f5 100644
--- a/ydb/library/yql/core/ya.make
+++ b/ydb/library/yql/core/ya.make
@@ -31,8 +31,8 @@ SRCS(
yql_holding_file_storage.h
yql_join.cpp
yql_join.h
- yql_library_compiler.cpp
- yql_opt_aggregate.cpp
+ yql_library_compiler.cpp
+ yql_opt_aggregate.cpp
yql_opt_proposed_by_data.cpp
yql_opt_proposed_by_data.h
yql_opt_range.cpp
diff --git a/ydb/library/yql/core/yql_callable_transform.h b/ydb/library/yql/core/yql_callable_transform.h
index 4d8d7d855a..d508152029 100644
--- a/ydb/library/yql/core/yql_callable_transform.h
+++ b/ydb/library/yql/core/yql_callable_transform.h
@@ -30,12 +30,12 @@ public:
IGraphTransformer::TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
output = input;
- if (input->IsList()) {
- if (const auto maybeStatus = static_cast<TDerived*>(this)->ProcessList(input, output, ctx)) {
- return *maybeStatus;
- }
- }
-
+ if (input->IsList()) {
+ if (const auto maybeStatus = static_cast<TDerived*>(this)->ProcessList(input, output, ctx)) {
+ return *maybeStatus;
+ }
+ }
+
auto name = input->Content();
TIssueScopeGuard issueScope(ctx.IssueManager, [&]() {
return MakeIntrusive<TIssue>(ctx.GetPosition(input->Pos()), TStringBuilder() << "At function: " << name);
diff --git a/ydb/library/yql/core/yql_data_provider.h b/ydb/library/yql/core/yql_data_provider.h
index a156f11019..3ffbdc041d 100644
--- a/ydb/library/yql/core/yql_data_provider.h
+++ b/ydb/library/yql/core/yql_data_provider.h
@@ -123,12 +123,12 @@ public:
virtual void FillModifyCallables(THashSet<TStringBuf>& callables) = 0;
//-- optimizations
- virtual TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) = 0;
+ virtual TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) = 0;
virtual IGraphTransformer& GetRecaptureOptProposalTransformer() = 0;
virtual IGraphTransformer& GetLogicalOptProposalTransformer() = 0;
virtual IGraphTransformer& GetPhysicalOptProposalTransformer() = 0;
virtual IGraphTransformer& GetPhysicalFinalizingTransformer() = 0;
- virtual void PostRewriteIO() = 0;
+ virtual void PostRewriteIO() = 0;
virtual void Reset() = 0;
//-- metadata loading
@@ -138,13 +138,13 @@ public:
virtual bool IsPersistent(const TExprNode& node) = 0;
// Right! or worlds are written to syncList
- virtual bool CanBuildResult(const TExprNode& node, TSyncMap& syncList) = 0;
- virtual bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) = 0;
+ virtual bool CanBuildResult(const TExprNode& node, TSyncMap& syncList) = 0;
+ virtual bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) = 0;
virtual bool GetExecWorld(const TExprNode& node, TExprNode::TPtr& root) = 0;
virtual bool CanEvaluate(const TExprNode& node) = 0;
virtual void UndoEvaluationChanges() = 0;
- virtual TExprNode::TPtr CleanupWorld(const TExprNode::TPtr& node, TExprContext& ctx) = 0;
- virtual TExprNode::TPtr OptimizePull(const TExprNode::TPtr& source, const TFillSettings& fillSettings, TExprContext& ctx,
+ virtual TExprNode::TPtr CleanupWorld(const TExprNode::TPtr& node, TExprContext& ctx) = 0;
+ virtual TExprNode::TPtr OptimizePull(const TExprNode::TPtr& source, const TFillSettings& fillSettings, TExprContext& ctx,
IOptimizationContext& optCtx) = 0;
//-- execution
diff --git a/ydb/library/yql/core/yql_execution.cpp b/ydb/library/yql/core/yql_execution.cpp
index 0389b64c27..eb138b1b4f 100644
--- a/ydb/library/yql/core/yql_execution.cpp
+++ b/ydb/library/yql/core/yql_execution.cpp
@@ -23,7 +23,7 @@ public:
struct TItem : public TIntrusiveListItem<TItem> {
TExprNode* Node = nullptr;
- IDataProvider* DataProvider = nullptr;
+ IDataProvider* DataProvider = nullptr;
};
using TQueueType = TIntrusiveListWithAutoDelete<TState::TItem, TDelete>;
@@ -46,18 +46,18 @@ public:
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
if (FinalizingTransformer) {
- YQL_CLOG(INFO, CoreExecution) << "FinalizingTransformer, root #" << input->UniqueId();
+ YQL_CLOG(INFO, CoreExecution) << "FinalizingTransformer, root #" << input->UniqueId();
auto status = FinalizingTransformer->Transform(input, output, ctx);
YQL_CLOG(INFO, CoreExecution) << "FinalizingTransformer done, output #" << output->UniqueId() << ", status: " << status;
return status;
}
- YQL_CLOG(INFO, CoreExecution) << "Begin, root #" << input->UniqueId();
- output = input;
+ YQL_CLOG(INFO, CoreExecution) << "Begin, root #" << input->UniqueId();
+ output = input;
if (RewriteSanityCheck) {
- VisitExpr(input, [&](const TExprNode::TPtr& localInput) {
- if (NewNodes.cend() != NewNodes.find(localInput.Get())) {
- Cerr << "found old node: #" << localInput->UniqueId() << "\n" << input->Dump();
+ VisitExpr(input, [&](const TExprNode::TPtr& localInput) {
+ if (NewNodes.cend() != NewNodes.find(localInput.Get())) {
+ Cerr << "found old node: #" << localInput->UniqueId() << "\n" << input->Dump();
YQL_ENSURE(false);
}
return true;
@@ -100,7 +100,7 @@ public:
return FinalizingTransformer->ApplyAsyncChanges(input, output, ctx);
}
- output = input;
+ output = input;
TStatus combinedStatus = TStatus::Ok;
@@ -125,9 +125,9 @@ public:
}
YQL_CLOG(INFO, CoreExecution) << "Completed async execution for node #" << item.Node->UniqueId();
- TExprNode::TPtr callableOutput;
- auto status = item.DataProvider->GetCallableExecutionTransformer().ApplyAsyncChanges(item.Node, callableOutput, ctx);
- Y_VERIFY(callableOutput);
+ TExprNode::TPtr callableOutput;
+ auto status = item.DataProvider->GetCallableExecutionTransformer().ApplyAsyncChanges(item.Node, callableOutput, ctx);
+ Y_VERIFY(callableOutput);
YQL_ENSURE(status != TStatus::Async);
combinedStatus = combinedStatus.Combine(status);
if (status.Level == TStatus::Error) {
@@ -212,12 +212,12 @@ public:
ProvidersCache.clear();
}
- TStatus ExecuteNode(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
- output = node;
+ TStatus ExecuteNode(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
+ output = node;
bool changed = false;
- const auto knownNode = NewNodes.find(node.Get());
- if (NewNodes.cend() != knownNode) {
- output = knownNode->second;
+ const auto knownNode = NewNodes.find(node.Get());
+ if (NewNodes.cend() != knownNode) {
+ output = knownNode->second;
changed = true;
}
@@ -232,7 +232,7 @@ public:
case TExprNode::EState::ExecutionInProgress:
return TStatus::Async;
case TExprNode::EState::ExecutionPending:
- return ExecuteChildren(output, output, ctx, depth + 1);
+ return ExecuteChildren(output, output, ctx, depth + 1);
case TExprNode::EState::ConstrComplete:
case TExprNode::EState::ExecutionRequired:
break;
@@ -271,7 +271,7 @@ public:
} else if (status.Level == TStatus::Repeat) {
if (!status.HasRestart) {
output->SetState(TExprNode::EState::ExecutionPending);
- status = ExecuteChildren(output, output, ctx, depth + 1);
+ status = ExecuteChildren(output, output, ctx, depth + 1);
if (TExprNode::EState::ExecutionPending == output->GetState()) {
FreshPendingNodes.push_back(output.Get());
}
@@ -280,8 +280,8 @@ public:
}
}
if (output != prevOutput) {
- YQL_CLOG(INFO, CoreExecution) << "Rewrite node #" << node->UniqueId() << " to #" << output->UniqueId();
- NewNodes[node.Get()] = output;
+ YQL_CLOG(INFO, CoreExecution) << "Rewrite node #" << node->UniqueId() << " to #" << output->UniqueId();
+ NewNodes[node.Get()] = output;
}
return TStatus(TStatus::Repeat, output != prevOutput);
} else if (status.Level == TStatus::Async) {
@@ -300,14 +300,14 @@ public:
}
}
- TStatus ExecuteChildren(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
+ TStatus ExecuteChildren(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
TStatus combinedStatus = TStatus::Ok;
TExprNode::TListType newChildren;
bool newNode = false;
- for (auto& child : node->Children()) {
- auto newChild = child;
+ for (auto& child : node->Children()) {
+ auto newChild = child;
if (child->GetState() == TExprNode::EState::ExecutionRequired) {
- auto childStatus = ExecuteNode(child, newChild, ctx, depth);
+ auto childStatus = ExecuteNode(child, newChild, ctx, depth);
if (childStatus.Level == TStatus::Error)
return childStatus;
@@ -324,7 +324,7 @@ public:
}
if (combinedStatus.Level == TStatus::Ok) {
- Y_VERIFY_DEBUG(!newNode);
+ Y_VERIFY_DEBUG(!newNode);
node->SetState(TExprNode::EState::ConstrComplete);
return ExecuteNode(node, output, ctx, depth - 1);
} else {
@@ -332,7 +332,7 @@ public:
node->SetState(TExprNode::EState::Error);
}
if (newNode) {
- output = ctx.ChangeChildren(*node, std::move(newChildren));
+ output = ctx.ChangeChildren(*node, std::move(newChildren));
}
return combinedStatus;
@@ -372,10 +372,10 @@ public:
return dataProvider;
}
- TStatus ExecuteCallable(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
+ TStatus ExecuteCallable(const TExprNode::TPtr& node, TExprNode::TPtr& output, TExprContext& ctx, ui32 depth) {
YQL_CLOG(TRACE, CoreExecution) << '{' << depth << "}, callable #"
- << node->UniqueId() << " <" << node->Content() << '>';
- if (node->Content() == CommitName) {
+ << node->UniqueId() << " <" << node->Content() << '>';
+ if (node->Content() == CommitName) {
auto requireStatus = RequireChild(*node, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
@@ -384,12 +384,12 @@ public:
auto category = node->Child(1)->Child(0)->Content();
auto datasink = Types.DataSinkMap.FindPtr(category);
YQL_ENSURE(datasink);
- output = node;
+ output = node;
auto status = (*datasink)->GetCallableExecutionTransformer().Transform(node, output, ctx);
if (status.Level == TStatus::Async) {
- Y_VERIFY_DEBUG(output == node);
+ Y_VERIFY_DEBUG(output == node);
StartNode(category, *node);
- AddCallable(node, (*datasink).Get(), ctx);
+ AddCallable(node, (*datasink).Get(), ctx);
} else {
if (output->GetState() == TExprNode::EState::ExecutionComplete ||
output->GetState() == TExprNode::EState::Error)
@@ -402,27 +402,27 @@ public:
return status;
}
- if (node->Content() == SyncName) {
+ if (node->Content() == SyncName) {
return ExecuteList(node, ctx);
}
- if (node->Content() == LeftName) {
+ if (node->Content() == LeftName) {
auto requireStatus = RequireChild(*node, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
}
- node->SetResult(ctx.NewWorld(node->Pos()));
+ node->SetResult(ctx.NewWorld(node->Pos()));
return TStatus::Ok;
}
- if (node->Content() == RightName) {
+ if (node->Content() == RightName) {
auto requireStatus = RequireChild(*node, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
}
- node->SetResult(ctx.NewWorld(node->Pos()));
+ node->SetResult(ctx.NewWorld(node->Pos()));
return TStatus::Ok;
}
@@ -432,12 +432,12 @@ public:
return TStatus::Error;
}
- output = node;
+ output = node;
TStatus status = dataProvider->GetCallableExecutionTransformer().Transform(node, output, ctx);
if (status.Level == TStatus::Async) {
- Y_VERIFY_DEBUG(output == node);
+ Y_VERIFY_DEBUG(output == node);
StartNode(dataProvider->GetName(), *node);
- AddCallable(node, dataProvider, ctx);
+ AddCallable(node, dataProvider, ctx);
} else {
if (output->GetState() == TExprNode::EState::ExecutionComplete ||
output->GetState() == TExprNode::EState::Error)
@@ -450,7 +450,7 @@ public:
return status;
}
- void AddCallable(const TExprNode::TPtr& node, IDataProvider* dataProvider, TExprContext& ctx) {
+ void AddCallable(const TExprNode::TPtr& node, IDataProvider* dataProvider, TExprContext& ctx) {
Y_UNUSED(ctx);
YQL_CLOG(INFO, CoreExecution) << "Register async execution for node #" << node->UniqueId();
auto future = dataProvider->GetCallableExecutionTransformer().GetAsyncFuture(*node);
@@ -460,10 +460,10 @@ public:
void SubscribeAsyncFuture(const TExprNode::TPtr& node, IDataProvider* dataProvider, const NThreading::TFuture<void>& future)
{
auto state = State;
- future.Subscribe([state, node=node.Get(), dataProvider](const NThreading::TFuture<void>& future) {
+ future.Subscribe([state, node=node.Get(), dataProvider](const NThreading::TFuture<void>& future) {
YQL_ENSURE(!future.HasException());
TAutoPtr<TState::TItem> item(new TState::TItem);
- item->Node = node;
+ item->Node = node;
item->DataProvider = dataProvider;
NThreading::TPromise<void> promiseToSet;
@@ -629,7 +629,7 @@ private:
TOperationProgressWriter Writer;
const bool WithFinalize;
TStatePtr State;
- TNodeOnNodeOwnedMap NewNodes;
+ TNodeOnNodeOwnedMap NewNodes;
TAutoPtr<IGraphTransformer> FinalizingTransformer;
THashMap<ui32, TOperationProgress> Progresses;
@@ -645,7 +645,7 @@ private:
TExprNode::TListType FreshPendingNodes;
};
-IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types, TNodeSet& visited);
+IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types, TNodeSet& visited);
IGraphTransformer::TStatus ValidateList(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types, TNodeSet& visited) {
IGraphTransformer::TStatus combinedStatus = IGraphTransformer::TStatus::Ok;
@@ -656,29 +656,29 @@ IGraphTransformer::TStatus ValidateList(const TExprNode::TPtr& node, TExprContex
return combinedStatus;
}
-IGraphTransformer::TStatus ValidateCallable(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types, TNodeSet& visited) {
+IGraphTransformer::TStatus ValidateCallable(const TExprNode::TPtr& node, TExprContext& ctx, const TTypeAnnotationContext& types, TNodeSet& visited) {
using TStatus = IGraphTransformer::TStatus;
- if (node->Content() == CommitName) {
+ if (node->Content() == CommitName) {
auto datasink = types.DataSinkMap.FindPtr(node->Child(1)->Child(0)->Content());
if (!datasink) {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Unknown datasink: " << node->Child(1)->Child(0)->Content()));
return TStatus::Error;
}
- return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
+ return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
}
- if (node->Content() == SyncName) {
+ if (node->Content() == SyncName) {
return ValidateList(node, ctx, types, visited);
}
- if (node->Content() == LeftName) {
- return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
+ if (node->Content() == LeftName) {
+ return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
}
- if (node->Content() == RightName) {
- return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
+ if (node->Content() == RightName) {
+ return ValidateExecution(node->ChildPtr(0), ctx, types, visited);
}
IDataProvider* dataProvider = nullptr;
@@ -704,23 +704,23 @@ IGraphTransformer::TStatus ValidateCallable(const TExprNode::TPtr& node, TExprCo
return TStatus::Error;
}
- if (node->ChildrenSize() < 2) {
+ if (node->ChildrenSize() < 2) {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Executable callable should have at least 2 children"));
return TStatus::Error;
}
TExprNode::TListType childrenToCheck;
- dataProvider->GetRequiredChildren(*node, childrenToCheck);
+ dataProvider->GetRequiredChildren(*node, childrenToCheck);
IGraphTransformer::TStatus combinedStatus = IGraphTransformer::TStatus::Ok;
for (ui32 i = 0; i < childrenToCheck.size(); ++i) {
- combinedStatus = combinedStatus.Combine(ValidateExecution(childrenToCheck[i], ctx, types, visited));
+ combinedStatus = combinedStatus.Combine(ValidateExecution(childrenToCheck[i], ctx, types, visited));
}
return combinedStatus;
}
-IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprContext& ctx,
- const TTypeAnnotationContext& types, TNodeSet& visited) {
+IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprContext& ctx,
+ const TTypeAnnotationContext& types, TNodeSet& visited) {
using TStatus = IGraphTransformer::TStatus;
if (node->GetState() == TExprNode::EState::ExecutionComplete) {
return TStatus::Ok;
@@ -732,7 +732,7 @@ IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprC
}
TStatus status = TStatus::Ok;
- switch (node->Type()) {
+ switch (node->Type()) {
case TExprNode::Atom:
case TExprNode::Argument:
case TExprNode::Arguments:
@@ -744,13 +744,13 @@ IGraphTransformer::TStatus ValidateExecution(const TExprNode::TPtr& node, TExprC
return ValidateList(node, ctx, types, visited);
case TExprNode::Callable:
- if (visited.cend() != visited.find(node.Get())) {
+ if (visited.cend() != visited.find(node.Get())) {
return TStatus::Ok;
}
status = ValidateCallable(node, ctx, types, visited);
if (status.Level == TStatus::Ok) {
- visited.insert(node.Get());
+ visited.insert(node.Get());
}
break;
@@ -777,7 +777,7 @@ TAutoPtr<IGraphTransformer> CreateExecutionTransformer(
TAutoPtr<IGraphTransformer> CreateCheckExecutionTransformer(const TTypeAnnotationContext& types, bool checkWorld) {
return CreateFunctorTransformer([&types, checkWorld](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx)
-> IGraphTransformer::TStatus {
- output = input;
+ output = input;
if (checkWorld) {
TNodeSet visited;
auto status = ValidateExecution(input, ctx, types, visited);
@@ -792,7 +792,7 @@ TAutoPtr<IGraphTransformer> CreateCheckExecutionTransformer(const TTypeAnnotatio
bool hasErrors = false;
THashSet<TIssue> added;
auto funcCheckExecution = [&](const THashSet<TStringBuf>& notAllowList, bool collectCalcOverWindow, const TExprNode::TPtr& node) {
- if (node->IsCallable("ErrorType")) {
+ if (node->IsCallable("ErrorType")) {
hasErrors = true;
const auto err = node->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TErrorExprType>()->GetError();
if (added.insert(err).second) {
@@ -814,13 +814,13 @@ TAutoPtr<IGraphTransformer> CreateCheckExecutionTransformer(const TTypeAnnotatio
overWinNodes.emplace(node.Get());
return false;
} else if (node->IsCallable(notAllowList)) {
- hasErrors = true;
+ hasErrors = true;
const auto err = TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Can't execute " << node->Content());
- if (added.insert(err).second) {
- ctx.AddError(err);
- }
- } else if (node->Type() != TExprNode::Lambda &&
- (node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream || node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow)) {
+ if (added.insert(err).second) {
+ ctx.AddError(err);
+ }
+ } else if (node->Type() != TExprNode::Lambda &&
+ (node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream || node->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow)) {
auto parentsIt = parentsMap.find(node.Get());
if (parentsIt != parentsMap.end()) {
ui32 usageCount = 0;
@@ -846,7 +846,7 @@ TAutoPtr<IGraphTransformer> CreateCheckExecutionTransformer(const TTypeAnnotatio
}
}
- return true;
+ return true;
};
static const THashSet<TStringBuf> noExecutionList = {"InstanceOf", "Lag", "Lead", "Rank", "DenseRank", "RowNumber"};
static const THashSet<TStringBuf> noExecutionListForCalcOverWindow = {"InstanceOf"};
@@ -865,9 +865,9 @@ TAutoPtr<IGraphTransformer> CreateCheckExecutionTransformer(const TTypeAnnotatio
});
};
-IGraphTransformer::TStatus RequireChild(const TExprNode& node, ui32 index) {
+IGraphTransformer::TStatus RequireChild(const TExprNode& node, ui32 index) {
switch (node.Child(index)->GetState()) {
- case TExprNode::EState::Error:
+ case TExprNode::EState::Error:
case TExprNode::EState::ExecutionComplete:
return IGraphTransformer::TStatus::Ok;
case TExprNode::EState::ExecutionInProgress:
diff --git a/ydb/library/yql/core/yql_execution.h b/ydb/library/yql/core/yql_execution.h
index 74f602cd02..cb38d913fa 100644
--- a/ydb/library/yql/core/yql_execution.h
+++ b/ydb/library/yql/core/yql_execution.h
@@ -28,21 +28,21 @@ namespace NYql {
TString RemoteId;
struct TCounters {
- ui64 Completed = 0ULL;
- ui64 Running = 0ULL;
- ui64 Total = 0ULL;
- ui64 Aborted = 0ULL;
- ui64 Failed = 0ULL;
- ui64 Lost = 0ULL;
- ui64 Pending = 0ULL;
+ ui64 Completed = 0ULL;
+ ui64 Running = 0ULL;
+ ui64 Total = 0ULL;
+ ui64 Aborted = 0ULL;
+ ui64 Failed = 0ULL;
+ ui64 Lost = 0ULL;
+ ui64 Pending = 0ULL;
bool operator==(const TCounters& rhs) const noexcept {
return Completed == rhs.Completed &&
Running == rhs.Running &&
- Total == rhs.Total &&
- Aborted == rhs.Aborted &&
- Failed == rhs.Failed &&
- Lost == rhs.Lost &&
- Pending == rhs.Pending;
+ Total == rhs.Total &&
+ Aborted == rhs.Aborted &&
+ Failed == rhs.Failed &&
+ Lost == rhs.Lost &&
+ Pending == rhs.Pending;
}
bool operator!=(const TCounters& rhs) const noexcept {
diff --git a/ydb/library/yql/core/yql_expr_constraint.cpp b/ydb/library/yql/core/yql_expr_constraint.cpp
index 5e4756f29c..78c8f68776 100644
--- a/ydb/library/yql/core/yql_expr_constraint.cpp
+++ b/ydb/library/yql/core/yql_expr_constraint.cpp
@@ -93,22 +93,22 @@ public:
Functions["SkipWhile"] = &TCallableConstraintTransformer::FilterWrap<true>;
Functions["TakeWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
Functions["SkipWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
- Functions["WideTakeWhile"] = &TCallableConstraintTransformer::FilterWrap<true>;
- Functions["WideSkipWhile"] = &TCallableConstraintTransformer::FilterWrap<true>;
- Functions["WideTakeWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
- Functions["WideSkipWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
+ Functions["WideTakeWhile"] = &TCallableConstraintTransformer::FilterWrap<true>;
+ Functions["WideSkipWhile"] = &TCallableConstraintTransformer::FilterWrap<true>;
+ Functions["WideTakeWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
+ Functions["WideSkipWhileInclusive"] = &TCallableConstraintTransformer::FilterWrap<true>;
Functions["Iterator"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["ForwardList"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["LazyList"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
- Functions["ToFlow"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
- Functions["FromFlow"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
+ Functions["ToFlow"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
+ Functions["FromFlow"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["ToStream"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["ToSequence"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["Collect"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["FilterNullMembers"] = &TCallableConstraintTransformer::FromFirst<TSortedConstraintNode, TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode>;
Functions["SkipNullMembers"] = &TCallableConstraintTransformer::FromFirst<TSortedConstraintNode, TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode>;
- Functions["FilterNullElements"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TVarIndexConstraintNode>;
- Functions["SkipNullElements"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TVarIndexConstraintNode>;
+ Functions["FilterNullElements"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TVarIndexConstraintNode>;
+ Functions["SkipNullElements"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TVarIndexConstraintNode>;
Functions["Right!"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
Functions["Cons!"] = &TCallableConstraintTransformer::CopyAllFrom<1>;
Functions["ExtractMembers"] = &TCallableConstraintTransformer::ExtractMembersWrap;
@@ -116,25 +116,25 @@ public:
Functions["RemovePrefixMembers"] = &TCallableConstraintTransformer::RemovePrefixMembersWrap;
Functions["SelectMembers"] = &TCallableConstraintTransformer::SelectMembersWrap;
Functions["CastStruct"] = &TCallableConstraintTransformer::SelectMembersWrap;
- Functions["SafeCast"] = &TCallableConstraintTransformer::SelectMembersWrap<true>;
- Functions["StrictCast"] = &TCallableConstraintTransformer::SelectMembersWrap<true>;
+ Functions["SafeCast"] = &TCallableConstraintTransformer::SelectMembersWrap<true>;
+ Functions["StrictCast"] = &TCallableConstraintTransformer::SelectMembersWrap<true>;
Functions["DivePrefixMembers"] = &TCallableConstraintTransformer::DivePrefixMembersWrap;
Functions["OrderedFilter"] = &TCallableConstraintTransformer::FilterWrap<true>;
Functions["Filter"] = &TCallableConstraintTransformer::FilterWrap<false>;
- Functions["WideFilter"] = &TCallableConstraintTransformer::FilterWrap<true>;
- Functions["OrderedMap"] = &TCallableConstraintTransformer::MapWrap<true, false>;
- Functions["Map"] = &TCallableConstraintTransformer::MapWrap<false, false>;
- Functions["OrderedFlatMap"] = &TCallableConstraintTransformer::MapWrap<true, true>;
- Functions["FlatMap"] = &TCallableConstraintTransformer::MapWrap<false, true>;
- Functions["OrderedMultiMap"] = &TCallableConstraintTransformer::MapWrap<true, false>;
- Functions["MultiMap"] = &TCallableConstraintTransformer::MapWrap<false, false>;
- Functions["ExpandMap"] = &TCallableConstraintTransformer::MapWrap<true, false, false, true>;
- Functions["WideMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, true>;
- Functions["NarrowMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, false>;
- Functions["NarrowFlatMap"] = &TCallableConstraintTransformer::MapWrap<true, true, true, false>;
- Functions["NarrowMultiMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, false>;
- Functions["OrderedFlatMapToEquiJoin"] = &TCallableConstraintTransformer::MapWrap<true, true>;
- Functions["FlatMapToEquiJoin"] = &TCallableConstraintTransformer::MapWrap<false, true>;
+ Functions["WideFilter"] = &TCallableConstraintTransformer::FilterWrap<true>;
+ Functions["OrderedMap"] = &TCallableConstraintTransformer::MapWrap<true, false>;
+ Functions["Map"] = &TCallableConstraintTransformer::MapWrap<false, false>;
+ Functions["OrderedFlatMap"] = &TCallableConstraintTransformer::MapWrap<true, true>;
+ Functions["FlatMap"] = &TCallableConstraintTransformer::MapWrap<false, true>;
+ Functions["OrderedMultiMap"] = &TCallableConstraintTransformer::MapWrap<true, false>;
+ Functions["MultiMap"] = &TCallableConstraintTransformer::MapWrap<false, false>;
+ Functions["ExpandMap"] = &TCallableConstraintTransformer::MapWrap<true, false, false, true>;
+ Functions["WideMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, true>;
+ Functions["NarrowMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, false>;
+ Functions["NarrowFlatMap"] = &TCallableConstraintTransformer::MapWrap<true, true, true, false>;
+ Functions["NarrowMultiMap"] = &TCallableConstraintTransformer::MapWrap<true, false, true, false>;
+ Functions["OrderedFlatMapToEquiJoin"] = &TCallableConstraintTransformer::MapWrap<true, true>;
+ Functions["FlatMapToEquiJoin"] = &TCallableConstraintTransformer::MapWrap<false, true>;
Functions["OrderedLMap"] = &TCallableConstraintTransformer::LMapWrap<true>;
Functions["LMap"] = &TCallableConstraintTransformer::LMapWrap<false>;
Functions["Extract"] = &TCallableConstraintTransformer::FromFirst<TEmptyConstraintNode>;
@@ -152,7 +152,7 @@ public:
Functions["Just"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
Functions["Unwrap"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode, TEmptyConstraintNode>;
Functions["ToList"] = &TCallableConstraintTransformer::CopyAllFrom<0>;
- Functions["ToOptional"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
+ Functions["ToOptional"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
Functions["Head"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
Functions["Last"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
Functions["Reverse"] = &TCallableConstraintTransformer::FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
@@ -168,17 +168,17 @@ public:
Functions["FlatOptionalIf"] = &TCallableConstraintTransformer::CopyAllFrom<1>;
Functions["EmptyIterator"] = &TCallableConstraintTransformer::FromEmpty;
Functions["List"] = &TCallableConstraintTransformer::ListWrap;
- Functions["Dict"] = &TCallableConstraintTransformer::DictWrap;
+ Functions["Dict"] = &TCallableConstraintTransformer::DictWrap;
Functions["EmptyList"] = &TCallableConstraintTransformer::FromEmpty;
Functions["EmptyDict"] = &TCallableConstraintTransformer::FromEmpty;
Functions["DictItems"] = &TCallableConstraintTransformer::FromFirst<TEmptyConstraintNode>;
Functions["DictKeys"] = &TCallableConstraintTransformer::FromFirst<TEmptyConstraintNode>;
Functions["DictPayloads"] = &TCallableConstraintTransformer::FromFirst<TEmptyConstraintNode>;
Functions["DictFromKeys"] = &TCallableConstraintTransformer::DictFromKeysWrap;
- Functions["If"] = &TCallableConstraintTransformer::IfWrap;
+ Functions["If"] = &TCallableConstraintTransformer::IfWrap;
Functions["Nothing"] = &TCallableConstraintTransformer::FromEmpty;
Functions["IfPresent"] = &TCallableConstraintTransformer::IfPresentWrap;
- Functions["Coalesce"] = &TCallableConstraintTransformer::CommonFromChildren<0, TSortedConstraintNode, TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
+ Functions["Coalesce"] = &TCallableConstraintTransformer::CommonFromChildren<0, TSortedConstraintNode, TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>;
Functions["CombineByKey"] = &TCallableConstraintTransformer::FromFinalLambda<TCoCombineByKey::idx_FinishHandlerLambda>;
Functions["CombineCore"] = &TCallableConstraintTransformer::FromFinalLambda<TCoCombineCore::idx_FinishHandler>;
Functions["PartitionByKey"] = &TCallableConstraintTransformer::PartitionByKeyWrap;
@@ -197,18 +197,18 @@ public:
Functions["ToDict"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
Functions["FoldMap"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough
Functions["Fold1Map"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough
- Functions["Chain1Map"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough, sorted, unique
- Functions["WideChain1Map"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough, sorted, unique
+ Functions["Chain1Map"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough, sorted, unique
+ Functions["WideChain1Map"] = &TCallableConstraintTransformer::InheriteEmptyFromInput; // TODO: passthrough, sorted, unique
Functions["IsKeySwitch"] = &TCallableConstraintTransformer::IsKeySwitchWrap;
Functions["Condense"] = &TCallableConstraintTransformer::CondenseWrap;
Functions["Condense1"] = &TCallableConstraintTransformer::CondenseWrap;
Functions["Squeeze"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
Functions["Squeeze1"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
Functions["GroupingCore"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
- Functions["Chopper"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
- Functions["WideChopper"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
- Functions["WideCombiner"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
- Functions["WideCondense1"] = &TCallableConstraintTransformer::WideCondense1Wrap;
+ Functions["Chopper"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
+ Functions["WideChopper"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
+ Functions["WideCombiner"] = &TCallableConstraintTransformer::InheriteEmptyFromInput;
+ Functions["WideCondense1"] = &TCallableConstraintTransformer::WideCondense1Wrap;
Functions["Aggregate"] = &TCallableConstraintTransformer::AggregateWrap;
Functions["Fold"] = &TCallableConstraintTransformer::FoldWrap;
Functions["Fold1"] = &TCallableConstraintTransformer::FoldWrap;
@@ -221,12 +221,12 @@ public:
return Nothing();
}
- TMaybe<IGraphTransformer::TStatus> ProcessList(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- if (!input->ChildrenSize() || ETypeAnnotationKind::Tuple != input->GetTypeAnn()->GetKind())
- return TStatus::Ok;
- return AsTupleWrap(input, output, ctx);
- }
-
+ TMaybe<IGraphTransformer::TStatus> ProcessList(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ if (!input->ChildrenSize() || ETypeAnnotationKind::Tuple != input->GetTypeAnn()->GetKind())
+ return TStatus::Ok;
+ return AsTupleWrap(input, output, ctx);
+ }
+
TStatus ProcessUnknown(const TExprNode::TPtr& input, TExprContext&) {
return UpdateAllChildLambdasConstraints(*input);
}
@@ -378,7 +378,7 @@ private:
return FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode>(input, output, ctx);
}
- template <bool CheckMembersType = false>
+ template <bool CheckMembersType = false>
TStatus SelectMembersWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
const TTypeAnnotationNode* outItemType = input->GetTypeAnn();
while (outItemType->GetKind() == ETypeAnnotationKind::Optional) {
@@ -395,9 +395,9 @@ private:
if (item.first < outSize) {
filteredItems.push_back(item);
}
- }
+ }
multi = filteredItems.empty() ? nullptr : ctx.MakeConstraint<TMultiConstraintNode>(std::move(filteredItems));
- }
+ }
if (multi) {
input->AddConstraint(multi);
}
@@ -409,9 +409,9 @@ private:
if (item.first < outSize) {
filteredItems.push_back(item);
}
- }
+ }
varIndex = filteredItems.empty() ? nullptr : ctx.MakeConstraint<TVarIndexConstraintNode>(std::move(filteredItems));
- }
+ }
if (varIndex) {
input->AddConstraint(varIndex);
}
@@ -420,44 +420,44 @@ private:
else if (outItemType->GetKind() == ETypeAnnotationKind::Struct) {
const TStructExprType* outStructType = outItemType->Cast<TStructExprType>();
- if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
+ if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
TPassthroughConstraintNode::TMapType filteredMapping;
- if constexpr (CheckMembersType) {
+ if constexpr (CheckMembersType) {
const TTypeAnnotationNode* inItemType = input->Head().GetTypeAnn();
while (inItemType->GetKind() == ETypeAnnotationKind::Optional) {
inItemType = inItemType->Cast<TOptionalExprType>()->GetItemType();
}
- const auto inStructType = inItemType->Cast<TStructExprType>();
+ const auto inStructType = inItemType->Cast<TStructExprType>();
const auto& inItems = inStructType->GetItems();
const auto& outItems = outStructType->GetItems();
- for (const auto& part : passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (const auto& item : part.second) {
- if (!item.first.empty()) {
- const auto outItem = outStructType->FindItem(item.first.front());
- const auto inItem = inStructType->FindItem(item.first.front());
- if (outItem && inItem && IsSameAnnotation(*outItems[*outItem]->GetItemType(), *inItems[*inItem]->GetItemType())) {
- filtered.push_back(item);
- }
- }
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
+ for (const auto& part : passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (const auto& item : part.second) {
+ if (!item.first.empty()) {
+ const auto outItem = outStructType->FindItem(item.first.front());
+ const auto inItem = inStructType->FindItem(item.first.front());
+ if (outItem && inItem && IsSameAnnotation(*outItems[*outItem]->GetItemType(), *inItems[*inItem]->GetItemType())) {
+ filtered.push_back(item);
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
+ }
}
}
} else {
- for (const auto& part: passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (const auto& item : part.second) {
- if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
- filtered.push_back(item);
- }
+ for (const auto& part: passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (const auto& item : part.second) {
+ if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
+ filtered.push_back(item);
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
}
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
}
}
if (!filteredMapping.empty()) {
@@ -476,24 +476,24 @@ private:
}
TStatus DivePrefixMembersWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- const auto prefixes = input->Child(1)->Children();
- if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
+ const auto prefixes = input->Child(1)->Children();
+ if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
TPassthroughConstraintNode::TMapType filteredMapping;
- for (const auto& part: passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (auto item: part.second) {
- for (const auto& p : prefixes) {
- if (const auto& prefix = p->Content(); !item.first.empty() && item.first.front().starts_with(prefix)) {
- item.first.front() = item.first.front().substr(prefix.length());
- filtered.insert_unique(std::move(item));
- break;
- }
- }
- }
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
+ for (const auto& part: passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (auto item: part.second) {
+ for (const auto& p : prefixes) {
+ if (const auto& prefix = p->Content(); !item.first.empty() && item.first.front().starts_with(prefix)) {
+ item.first.front() = item.first.front().substr(prefix.length());
+ filtered.insert_unique(std::move(item));
+ break;
+ }
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
+ }
}
if (!filteredMapping.empty()) {
input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(filteredMapping)));
@@ -521,27 +521,27 @@ private:
TStatus ExtractMembersWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
const TStructExprType* outItemType = GetItemType(*input->GetTypeAnn())->Cast<TStructExprType>();
- if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
+ if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
TPassthroughConstraintNode::TMapType filteredMapping;
- for (const auto& part: passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (const auto& item: part.second) {
- if (!item.first.empty() && outItemType->FindItem(item.first.front())) {
- filtered.push_back(item);
- }
- }
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
+ for (const auto& part: passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (const auto& item: part.second) {
+ if (!item.first.empty() && outItemType->FindItem(item.first.front())) {
+ filtered.push_back(item);
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
+ }
}
if (!filteredMapping.empty()) {
input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(filteredMapping)));
}
}
- if (const auto sorted = TSortedConstraintNode::FilterByType(input->Head().GetConstraint<TSortedConstraintNode>(), outItemType, ctx))
- input->AddConstraint(sorted);
+ if (const auto sorted = TSortedConstraintNode::FilterByType(input->Head().GetConstraint<TSortedConstraintNode>(), outItemType, ctx))
+ input->AddConstraint(sorted);
if (auto uniq = input->Child(0)->GetConstraint<TUniqueConstraintNode>()) {
if (AllOf(uniq->GetColumns(), [outItemType](TStringBuf col) { return outItemType->FindItem(col).Defined(); } )) {
@@ -559,28 +559,28 @@ private:
}
if (outItemType->GetKind() == ETypeAnnotationKind::Struct) {
- const auto outStructType = outItemType->Cast<TStructExprType>();
- if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
+ const auto outStructType = outItemType->Cast<TStructExprType>();
+ if (const auto passthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
TPassthroughConstraintNode::TMapType filteredMapping;
- for (const auto& part: passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (const auto& item: part.second) {
- if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
- filtered.push_back(item);
- }
- }
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
+ for (const auto& part: passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (const auto& item: part.second) {
+ if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
+ filtered.push_back(item);
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
+ }
}
if (!filteredMapping.empty()) {
input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(filteredMapping)));
}
}
- if (const auto sorted = TSortedConstraintNode::FilterByType(input->Head().GetConstraint<TSortedConstraintNode>(), outStructType, ctx))
- input->AddConstraint(sorted);
+ if (const auto sorted = TSortedConstraintNode::FilterByType(input->Head().GetConstraint<TSortedConstraintNode>(), outStructType, ctx))
+ input->AddConstraint(sorted);
if (auto uniq = input->Child(0)->GetConstraint<TUniqueConstraintNode>()) {
if (AllOf(uniq->GetColumns(), [outStructType](TStringBuf col) { return outStructType->FindItem(col).Defined(); } )) {
@@ -598,27 +598,27 @@ private:
auto& constr = multiItems[item.first];
const TStructExprType* outStructType = tupleUnderType->GetItems()[item.first]->Cast<TStructExprType>();
- if (const auto passthrough = item.second.GetConstraint<TPassthroughConstraintNode>()) {
+ if (const auto passthrough = item.second.GetConstraint<TPassthroughConstraintNode>()) {
TPassthroughConstraintNode::TMapType filteredMapping;
- for (const auto& part: passthrough->GetColumnMapping()) {
- TPassthroughConstraintNode::TPartType filtered;
- filtered.reserve(part.second.size());
- for (const auto& item: part.second) {
- if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
- filtered.push_back(item);
- }
+ for (const auto& part: passthrough->GetColumnMapping()) {
+ TPassthroughConstraintNode::TPartType filtered;
+ filtered.reserve(part.second.size());
+ for (const auto& item: part.second) {
+ if (!item.first.empty() && outStructType->FindItem(item.first.front())) {
+ filtered.push_back(item);
+ }
+ }
+ if (!filtered.empty()) {
+ filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
}
- if (!filtered.empty()) {
- filteredMapping.emplace(part.first ? part.first : passthrough, std::move(filtered));
- }
}
if (!filteredMapping.empty()) {
constr.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(filteredMapping)));
}
}
- if (const auto sorted = TSortedConstraintNode::FilterByType(item.second.GetConstraint<TSortedConstraintNode>(), outStructType, ctx))
- constr.AddConstraint(sorted);
+ if (const auto sorted = TSortedConstraintNode::FilterByType(item.second.GetConstraint<TSortedConstraintNode>(), outStructType, ctx))
+ constr.AddConstraint(sorted);
if (auto uniq = item.second.GetConstraint<TUniqueConstraintNode>()) {
if (AllOf(uniq->GetColumns(), [outStructType](TStringBuf col) { return outStructType->FindItem(col).Defined(); } )) {
@@ -636,234 +636,234 @@ private:
// TODO: Empty for false condition
template <bool UseSorted>
TStatus FilterWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- if (const auto status = UpdateLambdaConstraints(*input->Child(1)); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(*input->Child(1)); status != TStatus::Ok) {
return status;
}
- if constexpr (UseSorted) {
+ if constexpr (UseSorted) {
FromFirst<TSortedConstraintNode>(input, output, ctx);
}
return FromFirst<TPassthroughConstraintNode, TEmptyConstraintNode, TUniqueConstraintNode, TVarIndexConstraintNode, TMultiConstraintNode>(input, output, ctx);
}
- template<class TConstraint>
- static const TConstraint* GetConstraintFromWideResultLambda(const TExprNode& lambda, TExprContext& ctx);
-
- template<class TConstraintType>
- static const TConstraintType* GetLambdaConstraint(const TExprNode& lambda, TExprContext& ctx) {
- if (2U == lambda.ChildrenSize())
- return lambda.GetConstraint<TConstraintType>();
-
- TVector<const TConstraintSet*> constraints;
- constraints.reserve(lambda.ChildrenSize() - 1U);
- for (size_t i = 1U; i < lambda.ChildrenSize(); ++i) {
- constraints.emplace_back(&lambda.Child(i)->GetConstraintSet());
- }
- return TConstraintType::MakeCommon(constraints, ctx);
- }
-
- template<class TConstraintType, bool WideLambda>
- static const TConstraintType* GetConstraintFromLambda(const TExprNode& lambda, TExprContext& ctx) {
- if constexpr (WideLambda)
- return GetConstraintFromWideResultLambda<TConstraintType>(lambda, ctx);
- else
- return GetLambdaConstraint<TConstraintType>(lambda, ctx);
- }
-
- static TConstraintNode::TListType GetConstraintsForInputArgument(const TExprNode& node, std::unordered_set<const TPassthroughConstraintNode*>& explicitPasstrought, TExprContext& ctx) {
- TConstraintNode::TListType constraints;
- if (const auto inItemType = GetItemType(*node.Head().GetTypeAnn())) {
- if (inItemType->GetKind() == ETypeAnnotationKind::Variant) {
- if (inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
- const auto tupleType = inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
- constraints.push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(*inItemType->Cast<TVariantExprType>()));
- TMultiConstraintNode::TMapType multiItems;
- multiItems.reserve(tupleType->GetSize());
- for (size_t i = 0; i < tupleType->GetSize(); ++i) {
- multiItems.emplace_back(i, TConstraintSet{});
- const auto inputMulti = node.Head().GetConstraint<TMultiConstraintNode>();
- if (const auto inputConstr = inputMulti ? inputMulti->GetItem(i) : nullptr) {
- if (const auto uniq = inputConstr->GetConstraint<TUniqueConstraintNode>()) {
- multiItems.back().second.AddConstraint(uniq);
- }
- if (const auto pass = inputConstr->GetConstraint<TPassthroughConstraintNode>()) {
- multiItems.back().second.AddConstraint(pass);
- continue;
- }
- }
- switch (const auto variantItemType = tupleType->GetItems()[i]; variantItemType->GetKind()) {
-/*TODO: case ETypeAnnotationKind::Tuple:
- if (const auto argType = variantItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
- multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;*/
- case ETypeAnnotationKind::Struct:
- if (const auto argType = variantItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
- multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;
- default:
- break;
- }
- }
- if (!multiItems.empty()) {
- constraints.emplace_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(multiItems)));
- }
- }
- } else {
- if (const auto inputPassthrough = node.Head().GetConstraint<TPassthroughConstraintNode>()) {
- constraints.emplace_back(inputPassthrough);
- } else switch (inItemType->GetKind()) {
-/*TODO: case ETypeAnnotationKind::Tuple:
- if (const auto argType = inItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
- constraints.emplace_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;*/
- case ETypeAnnotationKind::Struct:
- if (const auto argType = inItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
- constraints.emplace_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;
- default:
- break;
- }
-
- if (const auto unique = node.Head().GetConstraint<TUniqueConstraintNode>()) {
- constraints.emplace_back(unique);
- }
-
- if (const auto groupBy = node.Head().GetConstraint<TGroupByConstraintNode>()) {
- constraints.emplace_back(groupBy);
- }
- }
- }
-
- return constraints;
- }
-
- template <bool UseSorted, bool Flat, bool WideInput = false, bool WideOutput = false>
+ template<class TConstraint>
+ static const TConstraint* GetConstraintFromWideResultLambda(const TExprNode& lambda, TExprContext& ctx);
+
+ template<class TConstraintType>
+ static const TConstraintType* GetLambdaConstraint(const TExprNode& lambda, TExprContext& ctx) {
+ if (2U == lambda.ChildrenSize())
+ return lambda.GetConstraint<TConstraintType>();
+
+ TVector<const TConstraintSet*> constraints;
+ constraints.reserve(lambda.ChildrenSize() - 1U);
+ for (size_t i = 1U; i < lambda.ChildrenSize(); ++i) {
+ constraints.emplace_back(&lambda.Child(i)->GetConstraintSet());
+ }
+ return TConstraintType::MakeCommon(constraints, ctx);
+ }
+
+ template<class TConstraintType, bool WideLambda>
+ static const TConstraintType* GetConstraintFromLambda(const TExprNode& lambda, TExprContext& ctx) {
+ if constexpr (WideLambda)
+ return GetConstraintFromWideResultLambda<TConstraintType>(lambda, ctx);
+ else
+ return GetLambdaConstraint<TConstraintType>(lambda, ctx);
+ }
+
+ static TConstraintNode::TListType GetConstraintsForInputArgument(const TExprNode& node, std::unordered_set<const TPassthroughConstraintNode*>& explicitPasstrought, TExprContext& ctx) {
+ TConstraintNode::TListType constraints;
+ if (const auto inItemType = GetItemType(*node.Head().GetTypeAnn())) {
+ if (inItemType->GetKind() == ETypeAnnotationKind::Variant) {
+ if (inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
+ const auto tupleType = inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
+ constraints.push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(*inItemType->Cast<TVariantExprType>()));
+ TMultiConstraintNode::TMapType multiItems;
+ multiItems.reserve(tupleType->GetSize());
+ for (size_t i = 0; i < tupleType->GetSize(); ++i) {
+ multiItems.emplace_back(i, TConstraintSet{});
+ const auto inputMulti = node.Head().GetConstraint<TMultiConstraintNode>();
+ if (const auto inputConstr = inputMulti ? inputMulti->GetItem(i) : nullptr) {
+ if (const auto uniq = inputConstr->GetConstraint<TUniqueConstraintNode>()) {
+ multiItems.back().second.AddConstraint(uniq);
+ }
+ if (const auto pass = inputConstr->GetConstraint<TPassthroughConstraintNode>()) {
+ multiItems.back().second.AddConstraint(pass);
+ continue;
+ }
+ }
+ switch (const auto variantItemType = tupleType->GetItems()[i]; variantItemType->GetKind()) {
+/*TODO: case ETypeAnnotationKind::Tuple:
+ if (const auto argType = variantItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
+ multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;*/
+ case ETypeAnnotationKind::Struct:
+ if (const auto argType = variantItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
+ multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (!multiItems.empty()) {
+ constraints.emplace_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(multiItems)));
+ }
+ }
+ } else {
+ if (const auto inputPassthrough = node.Head().GetConstraint<TPassthroughConstraintNode>()) {
+ constraints.emplace_back(inputPassthrough);
+ } else switch (inItemType->GetKind()) {
+/*TODO: case ETypeAnnotationKind::Tuple:
+ if (const auto argType = inItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
+ constraints.emplace_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;*/
+ case ETypeAnnotationKind::Struct:
+ if (const auto argType = inItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
+ constraints.emplace_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (const auto unique = node.Head().GetConstraint<TUniqueConstraintNode>()) {
+ constraints.emplace_back(unique);
+ }
+
+ if (const auto groupBy = node.Head().GetConstraint<TGroupByConstraintNode>()) {
+ constraints.emplace_back(groupBy);
+ }
+ }
+ }
+
+ return constraints;
+ }
+
+ template <bool UseSorted, bool Flat, bool WideInput = false, bool WideOutput = false>
TStatus MapWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- const auto inItemType = GetItemType(*input->Child(0)->GetTypeAnn());
+ const auto inItemType = GetItemType(*input->Child(0)->GetTypeAnn());
bool multiInput = false;
- TSmallVec<TConstraintNode::TListType> argConstraints(input->Tail().Head().ChildrenSize());
- std::unordered_set<const TPassthroughConstraintNode*> explicitPasstrought;
+ TSmallVec<TConstraintNode::TListType> argConstraints(input->Tail().Head().ChildrenSize());
+ std::unordered_set<const TPassthroughConstraintNode*> explicitPasstrought;
if (inItemType) {
- //TODO: Use GetConstraintsForInputArgument
+ //TODO: Use GetConstraintsForInputArgument
if (inItemType->GetKind() == ETypeAnnotationKind::Variant) {
if (inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
- const auto inputMulti = input->Head().GetConstraint<TMultiConstraintNode>();
- const auto tupleType = inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
- argConstraints.front().push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(*inItemType->Cast<TVariantExprType>()));
+ const auto inputMulti = input->Head().GetConstraint<TMultiConstraintNode>();
+ const auto tupleType = inItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>();
+ argConstraints.front().push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(*inItemType->Cast<TVariantExprType>()));
TMultiConstraintNode::TMapType multiItems;
- multiItems.reserve(tupleType->GetSize());
+ multiItems.reserve(tupleType->GetSize());
for (size_t i = 0; i < tupleType->GetSize(); ++i) {
- multiItems.emplace_back(i, TConstraintSet{});
- const auto inputConstr = inputMulti ? inputMulti->GetItem(i) : nullptr;
+ multiItems.emplace_back(i, TConstraintSet{});
+ const auto inputConstr = inputMulti ? inputMulti->GetItem(i) : nullptr;
if (inputConstr) {
- if (const auto empty = inputConstr->GetConstraint<TEmptyConstraintNode>()) {
+ if (const auto empty = inputConstr->GetConstraint<TEmptyConstraintNode>()) {
// TODO: multiItems.pop_back() instead
multiItems.back().second.AddConstraint(empty);
}
-
- if (const auto pass = inputConstr->GetConstraint<TPassthroughConstraintNode>()) {
- multiItems.back().second.AddConstraint(pass);
- continue;
- }
+
+ if (const auto pass = inputConstr->GetConstraint<TPassthroughConstraintNode>()) {
+ multiItems.back().second.AddConstraint(pass);
+ continue;
+ }
+ }
+ switch (const auto variantItemType = tupleType->GetItems()[i]; variantItemType->GetKind()) {
+/*TODO: case ETypeAnnotationKind::Tuple:
+ if (const auto argType = variantItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
+ multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;*/
+ case ETypeAnnotationKind::Struct:
+ if (const auto argType = variantItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
+ multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ if (inputConstr) {
+ if (auto uniq = inputConstr->GetConstraint<TUniqueConstraintNode>()) {
+ multiItems.back().second.AddConstraint(uniq);
+ }
+ }
+ }
+ break;
+ default:
+ break;
}
- switch (const auto variantItemType = tupleType->GetItems()[i]; variantItemType->GetKind()) {
-/*TODO: case ETypeAnnotationKind::Tuple:
- if (const auto argType = variantItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
- multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;*/
- case ETypeAnnotationKind::Struct:
- if (const auto argType = variantItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
- multiItems.back().second.AddConstraint(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- if (inputConstr) {
- if (auto uniq = inputConstr->GetConstraint<TUniqueConstraintNode>()) {
- multiItems.back().second.AddConstraint(uniq);
- }
- }
- }
- break;
- default:
- break;
- }
}
if (!multiItems.empty()) {
- argConstraints.front().push_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(multiItems)));
+ argConstraints.front().push_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(multiItems)));
}
multiInput = true;
}
} else {
- const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
- if constexpr (WideInput) {
- const auto structUnique = input->Head().GetConstraint<TUniqueConstraintNode>();
- for (ui32 i = 0U; i < argConstraints.size(); ++i) {
- const auto memberName = ctx.AppendString(ToString(i));
- if (structUnique && structUnique->GetColumns().has(memberName)) {
- argConstraints[i].emplace_back(ctx.MakeConstraint<TUniqueConstraintNode>(TVector<TStringBuf>{memberName}));
- }
- }
-
- const auto multiType = inItemType->Cast<TMultiExprType>();
- if (const auto passtrought = inputPassthrough ? inputPassthrough : multiType ->GetSize() > 0U ? *explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*multiType)).first : nullptr) {
- for (ui32 i = 0U; i < argConstraints.size(); ++i) {
- if (const auto fieldPasstrought = passtrought->ExtractField(ctx, ToString(i))) {
- argConstraints[i].emplace_back(fieldPasstrought);
- }
- }
- }
- } else {
- if (inputPassthrough)
- argConstraints.front().emplace_back(inputPassthrough);
- else switch (inItemType->GetKind()) {
-/*TODO: case ETypeAnnotationKind::Tuple:
- if (const auto argType = inItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
- argConstraints.front().push_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;*/
- case ETypeAnnotationKind::Struct:
- if (const auto argType = inItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
- argConstraints.front().push_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
- }
- break;
- default:
- break;
- }
-
- if (const auto unique = input->Head().GetConstraint<TUniqueConstraintNode>()) {
- argConstraints.front().push_back(unique);
- }
- }
- if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
- argConstraints.front().push_back(groupBy);
- }
- }
- }
-
- if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, argConstraints); status != TStatus::Ok) {
+ const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
+ if constexpr (WideInput) {
+ const auto structUnique = input->Head().GetConstraint<TUniqueConstraintNode>();
+ for (ui32 i = 0U; i < argConstraints.size(); ++i) {
+ const auto memberName = ctx.AppendString(ToString(i));
+ if (structUnique && structUnique->GetColumns().has(memberName)) {
+ argConstraints[i].emplace_back(ctx.MakeConstraint<TUniqueConstraintNode>(TVector<TStringBuf>{memberName}));
+ }
+ }
+
+ const auto multiType = inItemType->Cast<TMultiExprType>();
+ if (const auto passtrought = inputPassthrough ? inputPassthrough : multiType ->GetSize() > 0U ? *explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*multiType)).first : nullptr) {
+ for (ui32 i = 0U; i < argConstraints.size(); ++i) {
+ if (const auto fieldPasstrought = passtrought->ExtractField(ctx, ToString(i))) {
+ argConstraints[i].emplace_back(fieldPasstrought);
+ }
+ }
+ }
+ } else {
+ if (inputPassthrough)
+ argConstraints.front().emplace_back(inputPassthrough);
+ else switch (inItemType->GetKind()) {
+/*TODO: case ETypeAnnotationKind::Tuple:
+ if (const auto argType = inItemType->Cast<TTupleExprType>(); argType->GetSize() > 0U) {
+ argConstraints.front().push_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;*/
+ case ETypeAnnotationKind::Struct:
+ if (const auto argType = inItemType->Cast<TStructExprType>(); argType->GetSize() > 0U) {
+ argConstraints.front().push_back(*explicitPasstrought.emplace(ctx.MakeConstraint<TPassthroughConstraintNode>(*argType)).first);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (const auto unique = input->Head().GetConstraint<TUniqueConstraintNode>()) {
+ argConstraints.front().push_back(unique);
+ }
+ }
+ if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
+ argConstraints.front().push_back(groupBy);
+ }
+ }
+ }
+
+ if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, argConstraints); status != TStatus::Ok) {
return status;
}
bool hasOutSorted = false;
- const auto lambdaPassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, WideOutput>(input->Tail(), ctx);
+ const auto lambdaPassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, WideOutput>(input->Tail(), ctx);
if (lambdaPassthrough) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought) {
- mapping.erase(myPasstrought);
- }
- if (!mapping.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
- }
-
- if constexpr (UseSorted) {
- if (const auto sorted = input->Head().GetConstraint<TSortedConstraintNode>()) {
- if (const auto outSorted = GetPassthroughSortedConstraint(*sorted, *lambdaPassthrough, ctx)) {
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought) {
+ mapping.erase(myPasstrought);
+ }
+ if (!mapping.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
+ }
+
+ if constexpr (UseSorted) {
+ if (const auto sorted = input->Head().GetConstraint<TSortedConstraintNode>()) {
+ if (const auto outSorted = GetPassthroughSortedConstraint(*sorted, *lambdaPassthrough, ctx)) {
input->AddConstraint(outSorted);
hasOutSorted = true;
}
@@ -871,15 +871,15 @@ private:
}
}
- if (input->Head().GetConstraint<TUniqueConstraintNode>()) {
- if (const auto lambdaUnique = GetConstraintFromLambda<TUniqueConstraintNode, WideOutput>(input->Tail(), ctx)) {
+ if (input->Head().GetConstraint<TUniqueConstraintNode>()) {
+ if (const auto lambdaUnique = GetConstraintFromLambda<TUniqueConstraintNode, WideOutput>(input->Tail(), ctx)) {
input->AddConstraint(lambdaUnique);
}
}
- const auto lambdaVarIndex = GetConstraintFromLambda<TVarIndexConstraintNode, WideOutput>(input->Tail(), ctx);
- const auto lambdaMulti = GetConstraintFromLambda<TMultiConstraintNode, WideOutput>(input->Tail(), ctx);
- if (const auto varIndex = input->Head().GetConstraint<TVarIndexConstraintNode>()) {
+ const auto lambdaVarIndex = GetConstraintFromLambda<TVarIndexConstraintNode, WideOutput>(input->Tail(), ctx);
+ const auto lambdaMulti = GetConstraintFromLambda<TMultiConstraintNode, WideOutput>(input->Tail(), ctx);
+ if (const auto varIndex = input->Head().GetConstraint<TVarIndexConstraintNode>()) {
if (multiInput) {
if (lambdaVarIndex) {
if (auto outVarIndex = GetVarIndexOverVarIndexConstraint(*varIndex, *lambdaVarIndex, ctx)) {
@@ -904,71 +904,71 @@ private:
}
}
- const auto inputMulti = input->Head().GetConstraint<TMultiConstraintNode>();
+ const auto inputMulti = input->Head().GetConstraint<TMultiConstraintNode>();
if (lambdaMulti && !input->Child(0)->GetConstraint<TEmptyConstraintNode>()) {
TMultiConstraintNode::TMapType remappedItems;
for (auto& item: lambdaMulti->GetItems()) {
remappedItems.push_back(std::make_pair(item.first, TConstraintSet{}));
if (!multiInput) { // remapping one to many
- if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought)
- mapping.erase(myPasstrought);
- if (!mapping.empty()) {
- remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
- }
-
- if constexpr (UseSorted) {
- if (const auto sorted = input->Child(0)->GetConstraint<TSortedConstraintNode>()) {
- if (const auto outSorted = GetPassthroughSortedConstraint(*sorted, *lambdaPassthrough, ctx)) {
+ if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought)
+ mapping.erase(myPasstrought);
+ if (!mapping.empty()) {
+ remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
+ }
+
+ if constexpr (UseSorted) {
+ if (const auto sorted = input->Child(0)->GetConstraint<TSortedConstraintNode>()) {
+ if (const auto outSorted = GetPassthroughSortedConstraint(*sorted, *lambdaPassthrough, ctx)) {
remappedItems.back().second.AddConstraint(outSorted);
}
}
}
}
if (input->Child(0)->GetConstraint<TUniqueConstraintNode>()) {
- if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
+ if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
remappedItems.back().second.AddConstraint(lambdaUnique);
}
}
- if (const auto empty = item.second.template GetConstraint<TEmptyConstraintNode>()) {
+ if (const auto empty = item.second.template GetConstraint<TEmptyConstraintNode>()) {
remappedItems.pop_back();
}
}
- else if (lambdaVarIndex && inputMulti) {
+ else if (lambdaVarIndex && inputMulti) {
const auto range = lambdaVarIndex->GetIndexMapping().equal_range(item.first);
switch (std::distance(range.first, range.second)) {
case 0: // new index
break;
case 1: // remapping 1 to 1
- if (const auto origConstr = inputMulti->GetItem(range.first->second)) {
- if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought)
- mapping.erase(myPasstrought);
- if (!mapping.empty()) {
- remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
+ if (const auto origConstr = inputMulti->GetItem(range.first->second)) {
+ if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought)
+ mapping.erase(myPasstrought);
+ if (!mapping.empty()) {
+ remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
}
- if constexpr (UseSorted) {
- if (const auto sorted = origConstr->template GetConstraint<TSortedConstraintNode>()) {
+ if constexpr (UseSorted) {
+ if (const auto sorted = origConstr->template GetConstraint<TSortedConstraintNode>()) {
if (auto outSorted = GetPassthroughSortedConstraint(*sorted, *lambdaPassthrough, ctx)) {
remappedItems.back().second.AddConstraint(outSorted);
}
}
}
}
- if (origConstr->template GetConstraint<TUniqueConstraintNode>()) {
- if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
+ if (origConstr->template GetConstraint<TUniqueConstraintNode>()) {
+ if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
remappedItems.back().second.AddConstraint(lambdaUnique);
}
}
- if (const auto empty = item.second.template GetConstraint<TEmptyConstraintNode>()) {
+ if (const auto empty = item.second.template GetConstraint<TEmptyConstraintNode>()) {
remappedItems.pop_back();
}
} else {
@@ -979,7 +979,7 @@ private:
{
std::vector<const TConstraintSet*> nonEmpty;
for (auto i = range.first; i != range.second; ++i) {
- if (auto origConstr = inputMulti->GetItem(i->second)) {
+ if (auto origConstr = inputMulti->GetItem(i->second)) {
nonEmpty.push_back(origConstr);
}
}
@@ -1000,11 +1000,11 @@ private:
input->AddConstraint(ctx.MakeConstraint<TMultiConstraintNode>(std::move(remappedItems)));
}
}
- else if (inputMulti && lambdaVarIndex) { // Many to one
+ else if (inputMulti && lambdaVarIndex) { // Many to one
const auto range = lambdaVarIndex->GetIndexMapping().equal_range(0);
std::vector<const TConstraintSet*> nonEmpty;
for (auto i = range.first; i != range.second; ++i) {
- if (auto origConstr = inputMulti->GetItem(i->second)) {
+ if (auto origConstr = inputMulti->GetItem(i->second)) {
nonEmpty.push_back(origConstr);
}
}
@@ -1017,16 +1017,16 @@ private:
}
}
- if (const auto lambdaEmpty = GetConstraintFromLambda<TEmptyConstraintNode, WideOutput>(input->Tail(), ctx)) {
+ if (const auto lambdaEmpty = GetConstraintFromLambda<TEmptyConstraintNode, WideOutput>(input->Tail(), ctx)) {
if (TCoFlatMapBase::Match(input.Get())) {
input->AddConstraint(lambdaEmpty);
}
if (UseSorted && !hasOutSorted && !lambdaPassthrough) {
- if (const auto sorted = input->Child(0)->GetConstraint<TSortedConstraintNode>()) {
- const auto outItemType = GetItemType(*input->GetTypeAnn());
+ if (const auto sorted = input->Child(0)->GetConstraint<TSortedConstraintNode>()) {
+ const auto outItemType = GetItemType(*input->GetTypeAnn());
if (outItemType && outItemType->GetKind() == ETypeAnnotationKind::Struct) {
- if (const auto outSorted = TSortedConstraintNode::FilterByType(sorted, outItemType->Cast<TStructExprType>(), ctx)) {
- input->AddConstraint(outSorted);
+ if (const auto outSorted = TSortedConstraintNode::FilterByType(sorted, outItemType->Cast<TStructExprType>(), ctx)) {
+ input->AddConstraint(outSorted);
}
}
}
@@ -1039,13 +1039,13 @@ private:
template <bool UseSorted>
TStatus LMapWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
TConstraintNode::TListType argConstraints;
- for (const auto c: input->Head().GetAllConstraints()) {
+ for (const auto c: input->Head().GetAllConstraints()) {
if (UseSorted || c->GetName() != TSortedConstraintNode::Name()) {
argConstraints.push_back(c);
}
}
- if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, {argConstraints}); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, {argConstraints}); status != TStatus::Ok) {
return status;
}
@@ -1053,10 +1053,10 @@ private:
if (!UseSorted) {
except.insert(TSortedConstraintNode::Name());
}
- if (input->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ if (input->Tail().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
except.insert(TEmptyConstraintNode::Name());
}
- CopyExcept(*input, input->Tail(), except);
+ CopyExcept(*input, input->Tail(), except);
return FromFirst<TEmptyConstraintNode>(input, output, ctx);
}
@@ -1086,9 +1086,9 @@ private:
for (auto& child: input->Children()) {
inputStructs.push_back(child->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>());
}
- auto commonPrefixLength = sort->GetContent().size();
+ auto commonPrefixLength = sort->GetContent().size();
for (size_t i = 0; i < commonPrefixLength; ++i) {
- auto column = sort->GetContent()[i].first.front();
+ auto column = sort->GetContent()[i].first.front();
auto pos = resultStruct->FindItem(column);
YQL_ENSURE(pos, "Missing column " << TString{column}.Quote() << " in result type");
auto resultItemType = resultStruct->GetItems()[*pos];
@@ -1104,7 +1104,7 @@ private:
}
}
}
- sort = sort->CutPrefix(commonPrefixLength, ctx);
+ sort = sort->CutPrefix(commonPrefixLength, ctx);
}
if (sort) {
input->AddConstraint(sort);
@@ -1125,23 +1125,23 @@ private:
TStatus TakeWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
if (input->Tail().IsCallable("Uint64") && !FromString<ui64>(input->Tail().Head().Content())) {
- input->AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>());
+ input->AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>());
}
- return CopyAllFrom<0>(input, output, ctx);
+ return CopyAllFrom<0>(input, output, ctx);
}
TStatus MemberWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
TVector<TStringBuf> unique;
- const auto& memberName = input->Tail().Content();
- const auto& structNode = input->Head();
- if (const auto structPassthrough = structNode.GetConstraint<TPassthroughConstraintNode>()) {
- if (const auto p = structPassthrough->ExtractField(ctx, memberName)) {
- input->AddConstraint(p);
+ const auto& memberName = input->Tail().Content();
+ const auto& structNode = input->Head();
+ if (const auto structPassthrough = structNode.GetConstraint<TPassthroughConstraintNode>()) {
+ if (const auto p = structPassthrough->ExtractField(ctx, memberName)) {
+ input->AddConstraint(p);
}
}
- if (!TCoNothing::Match(&structNode)) {
- if (auto structUnique = structNode.GetConstraint<TUniqueConstraintNode>()) {
+ if (!TCoNothing::Match(&structNode)) {
+ if (auto structUnique = structNode.GetConstraint<TUniqueConstraintNode>()) {
if (structUnique->GetColumns().has(memberName)) {
unique.push_back(memberName);
}
@@ -1152,8 +1152,8 @@ private:
input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
}
- if (structNode.IsCallable("AsStruct")) {
- for (auto& child: structNode.Children()) {
+ if (structNode.IsCallable("AsStruct")) {
+ for (auto& child: structNode.Children()) {
if (child->Child(0)->Content() == memberName) {
TApplyConstraintFromInput<1, TVarIndexConstraintNode>::Do(child);
break;
@@ -1165,90 +1165,90 @@ private:
return TStatus::Ok;
}
- TStatus AsTupleWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
- TPassthroughConstraintNode::TMapType passthrough;
- passthrough.reserve(input->ChildrenSize());
-
- TVector<TStringBuf> unique;
- TVector<const TConstraintSet*> structConstraints;
- TNodeSet srcStructs, arguments;
-
- ui32 i = 0U;
- for (const auto& child : input->Children()) {
- const auto& name = ctx.AppendString(ToString(i++));
- if (const auto pass = child->GetConstraint<TPassthroughConstraintNode>()) {
- for (auto part : pass->GetColumnMapping()) {
- std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
- item.first.emplace_front(name);
- return item;
- });
- }
- }
-
- const auto valueNode = SkipModifiers(child.Get());
- if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
- auto memberName = valueNode->Child(1)->Content();
- auto structNode = valueNode->Child(0);
- if (auto structUnique = structNode->GetConstraint<TUniqueConstraintNode>()) {
- if (structUnique->GetColumns().has(memberName)) {
- if (!TCoNothing::Match(structNode)) {
- srcStructs.insert(structNode);
- unique.push_back(name);
- }
- }
- }
- structConstraints.push_back(&structNode->GetConstraintSet());
- }
- else if (valueNode->Type() == TExprNode::Argument && ETypeAnnotationKind::Struct != valueNode->GetTypeAnn()->GetKind()) {
- if (auto structUnique = valueNode->GetConstraint<TUniqueConstraintNode>()) {
- if (structUnique->GetColumns().size() == 1) {
- arguments.insert(valueNode);
- if (const auto scope = valueNode->GetDependencyScope())
- srcStructs.insert(scope->second);
- unique.push_back(name);
- }
- }
- structConstraints.push_back(&valueNode->GetConstraintSet());
- }
- }
- if (!passthrough.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passthrough)));
- }
- if (!unique.empty()) {
- if (srcStructs.empty() || (srcStructs.size() == 1 && (unique.size() == arguments.size() ||
- (!(*srcStructs.begin())->IsLambda() && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())))) {
- ::SortUnique(unique);
- input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
- }
- }
- if (auto varIndex = TVarIndexConstraintNode::MakeCommon(structConstraints, ctx)) {
- input->AddConstraint(varIndex);
- }
-
- return TStatus::Ok;
- }
-
+ TStatus AsTupleWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
+ TPassthroughConstraintNode::TMapType passthrough;
+ passthrough.reserve(input->ChildrenSize());
+
+ TVector<TStringBuf> unique;
+ TVector<const TConstraintSet*> structConstraints;
+ TNodeSet srcStructs, arguments;
+
+ ui32 i = 0U;
+ for (const auto& child : input->Children()) {
+ const auto& name = ctx.AppendString(ToString(i++));
+ if (const auto pass = child->GetConstraint<TPassthroughConstraintNode>()) {
+ for (auto part : pass->GetColumnMapping()) {
+ std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
+ item.first.emplace_front(name);
+ return item;
+ });
+ }
+ }
+
+ const auto valueNode = SkipModifiers(child.Get());
+ if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
+ auto memberName = valueNode->Child(1)->Content();
+ auto structNode = valueNode->Child(0);
+ if (auto structUnique = structNode->GetConstraint<TUniqueConstraintNode>()) {
+ if (structUnique->GetColumns().has(memberName)) {
+ if (!TCoNothing::Match(structNode)) {
+ srcStructs.insert(structNode);
+ unique.push_back(name);
+ }
+ }
+ }
+ structConstraints.push_back(&structNode->GetConstraintSet());
+ }
+ else if (valueNode->Type() == TExprNode::Argument && ETypeAnnotationKind::Struct != valueNode->GetTypeAnn()->GetKind()) {
+ if (auto structUnique = valueNode->GetConstraint<TUniqueConstraintNode>()) {
+ if (structUnique->GetColumns().size() == 1) {
+ arguments.insert(valueNode);
+ if (const auto scope = valueNode->GetDependencyScope())
+ srcStructs.insert(scope->second);
+ unique.push_back(name);
+ }
+ }
+ structConstraints.push_back(&valueNode->GetConstraintSet());
+ }
+ }
+ if (!passthrough.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passthrough)));
+ }
+ if (!unique.empty()) {
+ if (srcStructs.empty() || (srcStructs.size() == 1 && (unique.size() == arguments.size() ||
+ (!(*srcStructs.begin())->IsLambda() && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())))) {
+ ::SortUnique(unique);
+ input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
+ }
+ }
+ if (auto varIndex = TVarIndexConstraintNode::MakeCommon(structConstraints, ctx)) {
+ input->AddConstraint(varIndex);
+ }
+
+ return TStatus::Ok;
+ }
+
TStatus AsStructWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
TPassthroughConstraintNode::TMapType passthrough;
passthrough.reserve(input->ChildrenSize());
-
+
TVector<TStringBuf> unique;
TVector<const TConstraintSet*> structConstraints;
- TNodeSet srcStructs, arguments;
-
- for (const auto& child : input->Children()) {
- const auto& name = child->Head().Content();
- if (const auto pass = child->Tail().GetConstraint<TPassthroughConstraintNode>()) {
- for (auto part : pass->GetColumnMapping()) {
- std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
- item.first.emplace_front(name);
- return item;
- });
- }
- }
-
- const auto valueNode = SkipModifiers(child->Child(1));
- if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
+ TNodeSet srcStructs, arguments;
+
+ for (const auto& child : input->Children()) {
+ const auto& name = child->Head().Content();
+ if (const auto pass = child->Tail().GetConstraint<TPassthroughConstraintNode>()) {
+ for (auto part : pass->GetColumnMapping()) {
+ std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
+ item.first.emplace_front(name);
+ return item;
+ });
+ }
+ }
+
+ const auto valueNode = SkipModifiers(child->Child(1));
+ if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
auto memberName = valueNode->Child(1)->Content();
auto structNode = valueNode->Child(0);
if (auto structUnique = structNode->GetConstraint<TUniqueConstraintNode>()) {
@@ -1262,12 +1262,12 @@ private:
structConstraints.push_back(&structNode->GetConstraintSet());
}
else if (valueNode->Type() == TExprNode::Argument) {
-
+
if (auto structUnique = valueNode->GetConstraint<TUniqueConstraintNode>()) {
if (structUnique->GetColumns().size() == 1) {
- arguments.insert(valueNode);
- if (const auto scope = valueNode->GetDependencyScope())
- srcStructs.insert(scope->second);
+ arguments.insert(valueNode);
+ if (const auto scope = valueNode->GetDependencyScope())
+ srcStructs.insert(scope->second);
unique.push_back(name);
}
}
@@ -1278,8 +1278,8 @@ private:
input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passthrough)));
}
if (!unique.empty()) {
- if (srcStructs.empty() || (srcStructs.size() == 1 && (unique.size() == arguments.size() ||
- (!(*srcStructs.begin())->IsLambda() && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())))) {
+ if (srcStructs.empty() || (srcStructs.size() == 1 && (unique.size() == arguments.size() ||
+ (!(*srcStructs.begin())->IsLambda() && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())))) {
::SortUnique(unique);
input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
}
@@ -1292,35 +1292,35 @@ private:
}
TStatus AddMemberWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
- const auto& addStructNode = input->Head();
- const auto& name = input->Child(1)->Content();
-
- if (const auto structPassthrough = addStructNode.GetConstraint<TPassthroughConstraintNode>(), fieldPasstrought = input->Tail().GetConstraint<TPassthroughConstraintNode>(); fieldPasstrought) {
- auto mapping = structPassthrough ? structPassthrough->GetColumnMapping() : TPassthroughConstraintNode::TMapType();
- if (const auto self = mapping.find(nullptr); mapping.cend() != self)
- mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
- for (const auto& part : fieldPasstrought->GetColumnMapping()) {
- for (auto item : part.second) {
- item.first.emplace_front(name);
- mapping[part.first ? part.first : fieldPasstrought].insert_unique(std::move(item));
- }
- }
-
- input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- } else if (structPassthrough) {
- input->AddConstraint(structPassthrough);
- }
-
- auto valueNode = SkipModifiers(input->Child(2));
-
+ const auto& addStructNode = input->Head();
+ const auto& name = input->Child(1)->Content();
+
+ if (const auto structPassthrough = addStructNode.GetConstraint<TPassthroughConstraintNode>(), fieldPasstrought = input->Tail().GetConstraint<TPassthroughConstraintNode>(); fieldPasstrought) {
+ auto mapping = structPassthrough ? structPassthrough->GetColumnMapping() : TPassthroughConstraintNode::TMapType();
+ if (const auto self = mapping.find(nullptr); mapping.cend() != self)
+ mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
+ for (const auto& part : fieldPasstrought->GetColumnMapping()) {
+ for (auto item : part.second) {
+ item.first.emplace_front(name);
+ mapping[part.first ? part.first : fieldPasstrought].insert_unique(std::move(item));
+ }
+ }
+
+ input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ } else if (structPassthrough) {
+ input->AddConstraint(structPassthrough);
+ }
+
+ auto valueNode = SkipModifiers(input->Child(2));
+
TVector<const TConstraintSet*> structConstraints;
- structConstraints.push_back(&addStructNode.GetConstraintSet());
+ structConstraints.push_back(&addStructNode.GetConstraintSet());
TVector<TStringBuf> unique;
TNodeSet srcStructs;
- if (!TCoNothing::Match(&addStructNode)) {
- if (auto structUnique = addStructNode.GetConstraint<TUniqueConstraintNode>()) {
- srcStructs.insert(&addStructNode);
+ if (!TCoNothing::Match(&addStructNode)) {
+ if (auto structUnique = addStructNode.GetConstraint<TUniqueConstraintNode>()) {
+ srcStructs.insert(&addStructNode);
unique.insert(unique.end(), structUnique->GetColumns().begin(), structUnique->GetColumns().end());
}
}
@@ -1362,25 +1362,25 @@ private:
}
TStatus RemoveMemberWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- if (const auto structPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
- const TPassthroughConstraintNode::TKeyType key(1U, input->Tail().Content());
- auto mapping = structPassthrough->GetColumnMapping();
- if (const auto self = mapping.find(nullptr); mapping.cend() != self)
- mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
- for (auto p = mapping.begin(); mapping.end() != p;) {
- if (auto it = p->second.lower_bound(key); p->second.cend() > it && it->first.front() == key.front()) {
- do p->second.erase(it++);
- while (p->second.end() > it && it->first.front() == key.front());
- if (p->second.empty()) {
- mapping.erase(p++);
- continue;
- }
- }
- ++p;
- }
- if (!mapping.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
+ if (const auto structPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>()) {
+ const TPassthroughConstraintNode::TKeyType key(1U, input->Tail().Content());
+ auto mapping = structPassthrough->GetColumnMapping();
+ if (const auto self = mapping.find(nullptr); mapping.cend() != self)
+ mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
+ for (auto p = mapping.begin(); mapping.end() != p;) {
+ if (auto it = p->second.lower_bound(key); p->second.cend() > it && it->first.front() == key.front()) {
+ do p->second.erase(it++);
+ while (p->second.end() > it && it->first.front() == key.front());
+ if (p->second.empty()) {
+ mapping.erase(p++);
+ continue;
+ }
+ }
+ ++p;
+ }
+ if (!mapping.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
}
if (auto uniq = input->Child(0)->GetConstraint<TUniqueConstraintNode>()) {
@@ -1393,46 +1393,46 @@ private:
}
TStatus ReplaceMemberWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
- const auto name = input->Child(1)->Content();
+ const auto name = input->Child(1)->Content();
TVector<const TConstraintSet*> structConstraints;
structConstraints.push_back(&input->Child(0)->GetConstraintSet());
- if (const auto structPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>(), fieldPasstrought = input->Tail().GetConstraint<TPassthroughConstraintNode>();
- structPassthrough || fieldPasstrought) {
- auto mapping = structPassthrough ? structPassthrough->GetColumnMapping() : TPassthroughConstraintNode::TMapType();
- if (const auto self = mapping.find(nullptr); mapping.cend() != self)
- mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
- const TPassthroughConstraintNode::TKeyType key(1U, name);
- for (auto p = mapping.begin(); mapping.end() != p;) {
- if (auto it = p->second.lower_bound(key); p->second.cend() > it && it->first.front() == key.front()) {
- do p->second.erase(it++);
- while (p->second.end() > it && it->first.front() == key.front());
- if (p->second.empty()) {
- mapping.erase(p++);
- continue;
- }
- }
- ++p;
- }
- if (fieldPasstrought) {
- for (const auto& part : fieldPasstrought->GetColumnMapping()) {
- for (auto item : part.second) {
- item.first.emplace_front(name);
- mapping[part.first ? part.first : fieldPasstrought].insert_unique(std::move(item));
- }
- }
- }
+ if (const auto structPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>(), fieldPasstrought = input->Tail().GetConstraint<TPassthroughConstraintNode>();
+ structPassthrough || fieldPasstrought) {
+ auto mapping = structPassthrough ? structPassthrough->GetColumnMapping() : TPassthroughConstraintNode::TMapType();
+ if (const auto self = mapping.find(nullptr); mapping.cend() != self)
+ mapping.emplace(structPassthrough, std::move(mapping.extract(self).mapped()));
+ const TPassthroughConstraintNode::TKeyType key(1U, name);
+ for (auto p = mapping.begin(); mapping.end() != p;) {
+ if (auto it = p->second.lower_bound(key); p->second.cend() > it && it->first.front() == key.front()) {
+ do p->second.erase(it++);
+ while (p->second.end() > it && it->first.front() == key.front());
+ if (p->second.empty()) {
+ mapping.erase(p++);
+ continue;
+ }
+ }
+ ++p;
+ }
+ if (fieldPasstrought) {
+ for (const auto& part : fieldPasstrought->GetColumnMapping()) {
+ for (auto item : part.second) {
+ item.first.emplace_front(name);
+ mapping[part.first ? part.first : fieldPasstrought].insert_unique(std::move(item));
+ }
+ }
+ }
if (!mapping.empty()) {
input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
}
-
- if (structPassthrough && fieldPasstrought) {
- if (auto valueNode = SkipModifiers(input->Child(2)); TCoMember::Match(valueNode)) {
- auto structNode = valueNode->Child(0);
- structConstraints.push_back(&structNode->GetConstraintSet());
- }
- }
+
+ if (structPassthrough && fieldPasstrought) {
+ if (auto valueNode = SkipModifiers(input->Child(2)); TCoMember::Match(valueNode)) {
+ auto structNode = valueNode->Child(0);
+ structConstraints.push_back(&structNode->GetConstraintSet());
+ }
+ }
}
if (auto uniq = input->Child(0)->GetConstraint<TUniqueConstraintNode>()) {
@@ -1460,13 +1460,13 @@ private:
return TStatus::Ok;
}
- TStatus DictWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- if (input->ChildrenSize() == 1) {
- return FromEmpty(input, output, ctx);
- }
- return TStatus::Ok;
- }
-
+ TStatus DictWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
+ if (input->ChildrenSize() == 1) {
+ return FromEmpty(input, output, ctx);
+ }
+ return TStatus::Ok;
+ }
+
TStatus DictFromKeysWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
if (input->Child(1)->ChildrenSize() == 0) {
input->AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>());
@@ -1474,113 +1474,113 @@ private:
return TStatus::Ok;
}
- TStatus IfWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
- TVector<const TConstraintSet*> constraints;
- constraints.reserve((input->ChildrenSize() << 1U) + 1U);
- if (1U != input->Tail().ChildrenSize() || !input->Tail().IsCallable({"List", "Nothing"}))
- constraints.emplace_back(&input->Tail().GetConstraintSet());
-
- for (auto i = 0U; i < input->ChildrenSize() - 1U; ++i) {
- if (const auto child = input->Child(++i); 1U != child->ChildrenSize() || !child->IsCallable({"List", "Nothing"})) {// TODO: Use empty constraint.
- constraints.emplace_back(&child->GetConstraintSet());
- }
- }
-
- if (constraints.empty())
- input->AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>());
- else if (1U == constraints.size())
- input->SetConstraints(**constraints.cbegin());
- else
- TApplyCommonConstraint<TSortedConstraintNode
- , TUniqueConstraintNode
- , TPassthroughConstraintNode
- , TEmptyConstraintNode
- , TVarIndexConstraintNode
- , TMultiConstraintNode
- >::Do(input, constraints, ctx);
- return TStatus::Ok;
- }
-
- TStatus IfPresentWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
- auto optionals = input->ChildrenList();
- const auto lambdaIndex = optionals.size() - 2U;
- auto lambda = std::move(optionals[lambdaIndex]);
- optionals.resize(lambdaIndex);
-
- TVector<const TConstraintNode::TListType> constraints;
- constraints.reserve(optionals.size());
- std::transform(optionals.cbegin(), optionals.cend(), std::back_inserter(constraints), [](const TExprNode::TPtr& node){ return node->GetAllConstraints(); });
-
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(lambdaIndex), ctx, constraints); status != TStatus::Ok) {
+ TStatus IfWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
+ TVector<const TConstraintSet*> constraints;
+ constraints.reserve((input->ChildrenSize() << 1U) + 1U);
+ if (1U != input->Tail().ChildrenSize() || !input->Tail().IsCallable({"List", "Nothing"}))
+ constraints.emplace_back(&input->Tail().GetConstraintSet());
+
+ for (auto i = 0U; i < input->ChildrenSize() - 1U; ++i) {
+ if (const auto child = input->Child(++i); 1U != child->ChildrenSize() || !child->IsCallable({"List", "Nothing"})) {// TODO: Use empty constraint.
+ constraints.emplace_back(&child->GetConstraintSet());
+ }
+ }
+
+ if (constraints.empty())
+ input->AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>());
+ else if (1U == constraints.size())
+ input->SetConstraints(**constraints.cbegin());
+ else
+ TApplyCommonConstraint<TSortedConstraintNode
+ , TUniqueConstraintNode
+ , TPassthroughConstraintNode
+ , TEmptyConstraintNode
+ , TVarIndexConstraintNode
+ , TMultiConstraintNode
+ >::Do(input, constraints, ctx);
+ return TStatus::Ok;
+ }
+
+ TStatus IfPresentWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
+ auto optionals = input->ChildrenList();
+ const auto lambdaIndex = optionals.size() - 2U;
+ auto lambda = std::move(optionals[lambdaIndex]);
+ optionals.resize(lambdaIndex);
+
+ TVector<const TConstraintNode::TListType> constraints;
+ constraints.reserve(optionals.size());
+ std::transform(optionals.cbegin(), optionals.cend(), std::back_inserter(constraints), [](const TExprNode::TPtr& node){ return node->GetAllConstraints(); });
+
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(lambdaIndex), ctx, constraints); status != TStatus::Ok) {
return status;
}
-
- if (std::any_of(optionals.cbegin(), optionals.cend(), [] (const TExprNode::TPtr& node) { return bool(node->GetConstraint<TEmptyConstraintNode>()); })) {
- input->CopyConstraints(input->Tail());
- return TStatus::Ok;
- }
-
- const TVector<const TConstraintSet*> both = { &lambda->GetConstraintSet(), &input->Tail().GetConstraintSet() };
- TApplyCommonConstraint<TSortedConstraintNode
- , TUniqueConstraintNode
- , TPassthroughConstraintNode
- , TEmptyConstraintNode
- , TVarIndexConstraintNode
- , TMultiConstraintNode
- >::Do(input, both, ctx);
- return TStatus::Ok;
+
+ if (std::any_of(optionals.cbegin(), optionals.cend(), [] (const TExprNode::TPtr& node) { return bool(node->GetConstraint<TEmptyConstraintNode>()); })) {
+ input->CopyConstraints(input->Tail());
+ return TStatus::Ok;
+ }
+
+ const TVector<const TConstraintSet*> both = { &lambda->GetConstraintSet(), &input->Tail().GetConstraintSet() };
+ TApplyCommonConstraint<TSortedConstraintNode
+ , TUniqueConstraintNode
+ , TPassthroughConstraintNode
+ , TEmptyConstraintNode
+ , TVarIndexConstraintNode
+ , TMultiConstraintNode
+ >::Do(input, both, ctx);
+ return TStatus::Ok;
}
TStatus SwitchWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
TStatus status = TStatus::Ok;
TDynBitMap outFromChildren; // children, from which take a multi constraint for output
- if (const auto multi = input->Head().GetConstraint<TMultiConstraintNode>()) {
- for (size_t i = 2; i < input->ChildrenSize(); ++i) {
- TMultiConstraintNode::TMapType items;
- ui32 lambdaInputIndex = 0;
- for (auto& child : input->Child(i)->Children()) {
- const ui32 index = FromString<ui32>(child->Content());
- if (auto c = multi->GetItem(index)) {
- items[lambdaInputIndex] = *c;
- outFromChildren.Set(i + 1);
- }
- ++lambdaInputIndex;
- }
- TConstraintNode::TListType argConstraints;
- if (!items.empty()) {
- if (input->Child(i)->ChildrenSize() > 1) {
- argConstraints.push_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(items)));
- argConstraints.push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(input->Child(i)->ChildrenSize()));
- } else {
- argConstraints = items.front().second.GetAllConstraints();
- }
- }
-
- status = status.Combine(UpdateLambdaConstraints(input->ChildRef(++i), ctx, {argConstraints}));
+ if (const auto multi = input->Head().GetConstraint<TMultiConstraintNode>()) {
+ for (size_t i = 2; i < input->ChildrenSize(); ++i) {
+ TMultiConstraintNode::TMapType items;
+ ui32 lambdaInputIndex = 0;
+ for (auto& child : input->Child(i)->Children()) {
+ const ui32 index = FromString<ui32>(child->Content());
+ if (auto c = multi->GetItem(index)) {
+ items[lambdaInputIndex] = *c;
+ outFromChildren.Set(i + 1);
+ }
+ ++lambdaInputIndex;
+ }
+ TConstraintNode::TListType argConstraints;
+ if (!items.empty()) {
+ if (input->Child(i)->ChildrenSize() > 1) {
+ argConstraints.push_back(ctx.MakeConstraint<TMultiConstraintNode>(std::move(items)));
+ argConstraints.push_back(ctx.MakeConstraint<TVarIndexConstraintNode>(input->Child(i)->ChildrenSize()));
+ } else {
+ argConstraints = items.front().second.GetAllConstraints();
+ }
+ }
+
+ status = status.Combine(UpdateLambdaConstraints(input->ChildRef(++i), ctx, {argConstraints}));
}
} else {
- const bool inVar = GetSeqItemType(input->Head().GetTypeAnn())->GetKind() == ETypeAnnotationKind::Variant;
- const TSmallVec<TConstraintNode::TListType> argConstraints(1U, inVar ? TConstraintNode::TListType() : input->Head().GetAllConstraints());
- for (size_t i = 3; i < input->ChildrenSize(); i += 2) {
- status = status.Combine(UpdateLambdaConstraints(input->ChildRef(i), ctx, argConstraints));
+ const bool inVar = GetSeqItemType(input->Head().GetTypeAnn())->GetKind() == ETypeAnnotationKind::Variant;
+ const TSmallVec<TConstraintNode::TListType> argConstraints(1U, inVar ? TConstraintNode::TListType() : input->Head().GetAllConstraints());
+ for (size_t i = 3; i < input->ChildrenSize(); i += 2) {
+ status = status.Combine(UpdateLambdaConstraints(input->ChildRef(i), ctx, argConstraints));
}
outFromChildren.Set(0, input->ChildrenSize());
}
-
+
if (status != TStatus::Ok) {
return status;
}
- const auto inputVarIndex = input->Head().GetConstraint<TVarIndexConstraintNode>();
- const bool emptyInput = input->Head().GetConstraint<TEmptyConstraintNode>();
- if (GetSeqItemType(input->GetTypeAnn())->GetKind() == ETypeAnnotationKind::Variant) {
+ const auto inputVarIndex = input->Head().GetConstraint<TVarIndexConstraintNode>();
+ const bool emptyInput = input->Head().GetConstraint<TEmptyConstraintNode>();
+ if (GetSeqItemType(input->GetTypeAnn())->GetKind() == ETypeAnnotationKind::Variant) {
ui32 outIndexOffset = 0;
TMultiConstraintNode::TMapType multiItems;
TVarIndexConstraintNode::TMapType remapItems;
bool emptyOut = true;
for (size_t i = 2; i < input->ChildrenSize(); i += 2) {
const auto lambda = input->Child(i + 1);
- const auto lambdaItemType = GetSeqItemType(lambda->GetTypeAnn());
+ const auto lambdaItemType = GetSeqItemType(lambda->GetTypeAnn());
if (inputVarIndex) {
if (auto varIndex = lambda->GetConstraint<TVarIndexConstraintNode>()) {
@@ -1650,41 +1650,41 @@ private:
return FromFirst<TEmptyConstraintNode>(input, output, ctx);
}
- TStatus VisitWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
+ TStatus VisitWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
TStatus status = TStatus::Ok;
TDynBitMap outFromChildren; // children, from which take a multi constraint for output
TDynBitMap usedAlts;
- const auto inMulti = input->Head().GetConstraint<TMultiConstraintNode>();
- for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
- if (const auto child = input->Child(i); child->IsAtom()) {
- TSmallVec<TConstraintNode::TListType> argConstraints(1U);
- if (inMulti) {
- const auto index = FromString<ui32>(child->Content());
- usedAlts.Set(index);
- if (const auto c = inMulti->GetItem(index)) {
- argConstraints.front() = c->GetAllConstraints();
- outFromChildren.Set(i + 1U);
- }
- }
- status = status.Combine(UpdateLambdaConstraints(input->ChildRef(++i), ctx, argConstraints));
- } else if (inMulti) { // Check that we can fall to default branch
- for (auto& item: inMulti->GetItems()) {
- if (!usedAlts.Test(item.first)) {
- outFromChildren.Set(i);
- break;
- }
- }
- }
- }
-
+ const auto inMulti = input->Head().GetConstraint<TMultiConstraintNode>();
+ for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
+ if (const auto child = input->Child(i); child->IsAtom()) {
+ TSmallVec<TConstraintNode::TListType> argConstraints(1U);
+ if (inMulti) {
+ const auto index = FromString<ui32>(child->Content());
+ usedAlts.Set(index);
+ if (const auto c = inMulti->GetItem(index)) {
+ argConstraints.front() = c->GetAllConstraints();
+ outFromChildren.Set(i + 1U);
+ }
+ }
+ status = status.Combine(UpdateLambdaConstraints(input->ChildRef(++i), ctx, argConstraints));
+ } else if (inMulti) { // Check that we can fall to default branch
+ for (auto& item: inMulti->GetItems()) {
+ if (!usedAlts.Test(item.first)) {
+ outFromChildren.Set(i);
+ break;
+ }
+ }
+ }
+ }
+
if (status != TStatus::Ok) {
return status;
}
- if (!inMulti) {
- outFromChildren.Set(0, input->ChildrenSize());
- }
-
+ if (!inMulti) {
+ outFromChildren.Set(0, input->ChildrenSize());
+ }
+
auto outType = input->GetTypeAnn();
if (auto t = GetItemType(*outType)) {
outType = t;
@@ -1765,9 +1765,9 @@ private:
TVarIndexConstraintNode::TMapType varIndexItems;
for (ui32 i = 1; i < input->ChildrenSize(); ++i) {
if (input->Child(i)->IsAtom()) {
- const auto index = FromString<ui32>(input->Child(i++)->Content());
- if (outFromChildren.Test(i) && IsDepended(input->Child(i)->Tail(), input->Child(i)->Head().Head())) { // Somehow depends on arg
- const auto range = varIndex->GetIndexMapping().equal_range(index);
+ const auto index = FromString<ui32>(input->Child(i++)->Content());
+ if (outFromChildren.Test(i) && IsDepended(input->Child(i)->Tail(), input->Child(i)->Head().Head())) { // Somehow depends on arg
+ const auto range = varIndex->GetIndexMapping().equal_range(index);
for (auto i = range.first; i != range.second; ++i) {
varIndexItems.push_back(std::make_pair(0, i->second));
}
@@ -1898,28 +1898,28 @@ private:
return TStatus::Ok;
}
- TStatus NthWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
- TVector<TStringBuf> unique;
-
- const auto& memberName = input->Tail().Content();
- const auto& structNode = input->Head();
- if (const auto structPassthrough = structNode.GetConstraint<TPassthroughConstraintNode>()) {
- if (const auto p = structPassthrough->ExtractField(ctx, memberName)) {
- input->AddConstraint(p);
- }
- }
- if (!TCoNothing::Match(&structNode)) {
- if (auto structUnique = structNode.GetConstraint<TUniqueConstraintNode>()) {
- if (structUnique->GetColumns().has(memberName)) {
- unique.push_back(memberName);
- }
- }
- }
-
- if (!unique.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
- }
-
+ TStatus NthWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) const {
+ TVector<TStringBuf> unique;
+
+ const auto& memberName = input->Tail().Content();
+ const auto& structNode = input->Head();
+ if (const auto structPassthrough = structNode.GetConstraint<TPassthroughConstraintNode>()) {
+ if (const auto p = structPassthrough->ExtractField(ctx, memberName)) {
+ input->AddConstraint(p);
+ }
+ }
+ if (!TCoNothing::Match(&structNode)) {
+ if (auto structUnique = structNode.GetConstraint<TUniqueConstraintNode>()) {
+ if (structUnique->GetColumns().has(memberName)) {
+ unique.push_back(memberName);
+ }
+ }
+ }
+
+ if (!unique.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique)));
+ }
+
if (input->Child(0)->IsList()) {
input->CopyConstraints(*input->Child(0)->Child(FromString<ui32>(input->Child(1)->Content())));
}
@@ -1976,12 +1976,12 @@ private:
}
TStatus IsKeySwitchWrap(const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& /*ctx*/) const {
- if (const auto status = UpdateLambdaConstraints(*input->Child(TCoIsKeySwitch::idx_ItemKeyExtractor))
- .Combine(UpdateLambdaConstraints(*input->Child(TCoIsKeySwitch::idx_StateKeyExtractor))); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(*input->Child(TCoIsKeySwitch::idx_ItemKeyExtractor))
+ .Combine(UpdateLambdaConstraints(*input->Child(TCoIsKeySwitch::idx_StateKeyExtractor))); status != TStatus::Ok) {
return status;
}
- if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
+ if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
TVector<TStringBuf> keys;
ExtractKeys(*input->Child(2), keys);
if (!keys.empty()) {
@@ -1994,24 +1994,24 @@ private:
}
TStatus CondenseWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- const TStructExprType* inItemType = GetNonEmptyStructItemType(*input->Head().GetTypeAnn());
+ const TStructExprType* inItemType = GetNonEmptyStructItemType(*input->Head().GetTypeAnn());
const TStructExprType* outItemType = GetNonEmptyStructItemType(*input->GetTypeAnn());
if (!inItemType) {
return InheriteEmptyFromInput(input, output, ctx);
}
- const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
+ const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
if (input->Child(1)->IsLambda()) {
TConstraintNode::TListType argConstraints;
- if (inputPassthrough)
- argConstraints.emplace_back(inputPassthrough);
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, {argConstraints}); status != TStatus::Ok) {
+ if (inputPassthrough)
+ argConstraints.emplace_back(inputPassthrough);
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, {argConstraints}); status != TStatus::Ok) {
return status;
}
}
- const auto initState = input->Child(1);
- auto stateConstraints = initState->GetAllConstraints();
+ const auto initState = input->Child(1);
+ auto stateConstraints = initState->GetAllConstraints();
stateConstraints.erase(
std::remove_if(
stateConstraints.begin(),
@@ -2022,47 +2022,47 @@ private:
);
TConstraintNode::TListType itemConstraints;
- if (inputPassthrough)
- itemConstraints.emplace_back(inputPassthrough);
- if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
- itemConstraints.push_back(groupBy);
+ if (inputPassthrough)
+ itemConstraints.emplace_back(inputPassthrough);
+ if (const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>()) {
+ itemConstraints.push_back(groupBy);
}
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(2), ctx, {itemConstraints, stateConstraints})
- .Combine(UpdateLambdaConstraints(input->TailRef(), ctx, {itemConstraints, stateConstraints})); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(2), ctx, {itemConstraints, stateConstraints})
+ .Combine(UpdateLambdaConstraints(input->TailRef(), ctx, {itemConstraints, stateConstraints})); status != TStatus::Ok) {
return status;
}
- const TPassthroughConstraintNode* commonPassthrough = nullptr;
- const auto updateLambda = input->Child(3);
- if (const auto lambdaPassthrough = updateLambda->GetConstraint<TPassthroughConstraintNode>()) {
- if (initState->IsLambda()) {
- if (const auto initPassthrough = initState->GetConstraint<TPassthroughConstraintNode>()) {
- std::array<TConstraintSet, 2U> set;
- set.front().AddConstraint(initPassthrough);
- set.back().AddConstraint(lambdaPassthrough);
- if (commonPassthrough = TPassthroughConstraintNode::MakeCommon({&set.front(), &set.back()}, ctx))
- input->AddConstraint(commonPassthrough);
- }
- } else {
- input->AddConstraint(commonPassthrough = lambdaPassthrough);
- }
- }
-
- if (const auto switchLambda = input->Child(2); switchLambda->Tail().IsCallable(TCoBool::CallableName()) && IsFalse(switchLambda->Tail().Head().Content())) {
+ const TPassthroughConstraintNode* commonPassthrough = nullptr;
+ const auto updateLambda = input->Child(3);
+ if (const auto lambdaPassthrough = updateLambda->GetConstraint<TPassthroughConstraintNode>()) {
+ if (initState->IsLambda()) {
+ if (const auto initPassthrough = initState->GetConstraint<TPassthroughConstraintNode>()) {
+ std::array<TConstraintSet, 2U> set;
+ set.front().AddConstraint(initPassthrough);
+ set.back().AddConstraint(lambdaPassthrough);
+ if (commonPassthrough = TPassthroughConstraintNode::MakeCommon({&set.front(), &set.back()}, ctx))
+ input->AddConstraint(commonPassthrough);
+ }
+ } else {
+ input->AddConstraint(commonPassthrough = lambdaPassthrough);
+ }
+ }
+
+ if (const auto switchLambda = input->Child(2); switchLambda->Tail().IsCallable(TCoBool::CallableName()) && IsFalse(switchLambda->Tail().Head().Content())) {
if (outItemType) {
input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(*outItemType));
}
}
else {
TVector<TStringBuf> groupByKeys;
- if (const auto groupBy = switchLambda->GetConstraint<TGroupByConstraintNode>()) {
+ if (const auto groupBy = switchLambda->GetConstraint<TGroupByConstraintNode>()) {
groupByKeys.assign(groupBy->GetColumns().begin(), groupBy->GetColumns().end());
- } else if (switchLambda->Tail().IsCallable({"AggrNotEquals", "NotEquals"})) {
+ } else if (switchLambda->Tail().IsCallable({"AggrNotEquals", "NotEquals"})) {
ExtractSimpleKeys(switchLambda->Child(1)->Child(0), switchLambda->Child(0)->Child(0), groupByKeys);
}
- if (!groupByKeys.empty() && commonPassthrough) {
- const auto& mapping = commonPassthrough->GetReverseMapping();
+ if (!groupByKeys.empty() && commonPassthrough) {
+ const auto& mapping = commonPassthrough->GetReverseMapping();
TUniqueConstraintNode::TSetType uniqColumns;
for (auto key: groupByKeys) {
auto range = mapping.equal_range(key);
@@ -2084,111 +2084,111 @@ private:
return FromFirst<TEmptyConstraintNode>(input, output, ctx);
}
- TStatus WideCondense1Wrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- TSmallVec<TConstraintNode::TListType> argConstraints(input->Child(1)->Head().ChildrenSize());
- const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
- const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>();
- for (ui32 i = 0U; i < argConstraints.size(); ++i) {
- if (groupBy)
- argConstraints[i].push_back(groupBy);
- if (inputPassthrough)
- if (const auto fieldPasstrought = inputPassthrough->ExtractField(ctx, ToString(i)))
- argConstraints[i].emplace_back(fieldPasstrought);
- }
-
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, argConstraints); status != TStatus::Ok) {
+ TStatus WideCondense1Wrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
+ TSmallVec<TConstraintNode::TListType> argConstraints(input->Child(1)->Head().ChildrenSize());
+ const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
+ const auto groupBy = input->Head().GetConstraint<TGroupByConstraintNode>();
+ for (ui32 i = 0U; i < argConstraints.size(); ++i) {
+ if (groupBy)
+ argConstraints[i].push_back(groupBy);
+ if (inputPassthrough)
+ if (const auto fieldPasstrought = inputPassthrough->ExtractField(ctx, ToString(i)))
+ argConstraints[i].emplace_back(fieldPasstrought);
+ }
+
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, argConstraints); status != TStatus::Ok) {
return status;
- }
-
- const auto initLambda = input->Child(1);
- argConstraints.reserve(argConstraints.size() + initLambda->ChildrenSize() - 1U);
- for (ui32 i = 1U; i < initLambda->ChildrenSize(); ++i) {
- argConstraints.emplace_back(initLambda->Child(i)->GetAllConstraints());
- argConstraints.back().erase(
- std::remove_if(
- argConstraints.back().begin(),
- argConstraints.back().end(),
- [](const TConstraintNode* c) { return c->GetName() == TEmptyConstraintNode::Name(); }
- ),
- argConstraints.back().cend()
- );
- }
-
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(2), ctx, argConstraints)
- .Combine(UpdateLambdaConstraints(input->TailRef(), ctx, argConstraints)); status != TStatus::Ok) {
+ }
+
+ const auto initLambda = input->Child(1);
+ argConstraints.reserve(argConstraints.size() + initLambda->ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < initLambda->ChildrenSize(); ++i) {
+ argConstraints.emplace_back(initLambda->Child(i)->GetAllConstraints());
+ argConstraints.back().erase(
+ std::remove_if(
+ argConstraints.back().begin(),
+ argConstraints.back().end(),
+ [](const TConstraintNode* c) { return c->GetName() == TEmptyConstraintNode::Name(); }
+ ),
+ argConstraints.back().cend()
+ );
+ }
+
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(2), ctx, argConstraints)
+ .Combine(UpdateLambdaConstraints(input->TailRef(), ctx, argConstraints)); status != TStatus::Ok) {
return status;
- }
-
- const TPassthroughConstraintNode* commonPassthrough = nullptr;
- if (inputPassthrough) {
- const auto updateLambda = input->Child(3);
- const auto initPassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, true>(*initLambda, ctx);
- const auto updatePassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, true>(*updateLambda, ctx);
- if (initPassthrough && updatePassthrough) {
- std::array<TConstraintSet, 2U> set;
- set.front().AddConstraint(initPassthrough);
- set.back().AddConstraint(updatePassthrough);
- if (commonPassthrough = TPassthroughConstraintNode::MakeCommon({&set.front(), &set.back()}, ctx))
- input->AddConstraint(commonPassthrough);
- }
- }
-
- if (const auto switchLambda = input->Child(2); switchLambda->Tail().IsCallable(TCoBool::CallableName()) && IsFalse(switchLambda->Tail().Head().Content())) {
- TVector<TString> fields(initLambda->Head().ChildrenSize());
- ui32 i = 0U;
- std::generate_n(fields.begin(), initLambda->Head().ChildrenSize(), [&i](){ return ToString(i++); });
- input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(fields));
- } else {
- TVector<TStringBuf> groupByKeys;
- if (const auto groupBy = switchLambda->GetConstraint<TGroupByConstraintNode>()) {
- groupByKeys.assign(groupBy->GetColumns().begin(), groupBy->GetColumns().end());
- } else if (switchLambda->Tail().IsCallable({"AggrNotEquals", "NotEquals"})) {
- ExtractSimpleKeys(switchLambda->Child(1)->Child(0), switchLambda->Child(0)->Child(0), groupByKeys);
- }
- if (!groupByKeys.empty() && commonPassthrough) {
- auto mapping = commonPassthrough->GetReverseMapping();
- TUniqueConstraintNode::TSetType uniqColumns;
- for (auto key: groupByKeys) {
- auto range = mapping.equal_range(key);
- if (range.first != range.second) {
- for (auto i = range.first; i != range.second; ++i) {
- uniqColumns.insert_unique(i->second);
- }
- } else {
- uniqColumns.clear();
- break;
- }
- }
- if (!uniqColumns.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(uniqColumns)));
- }
- }
- }
-
- return FromFirst<TEmptyConstraintNode>(input, output, ctx);
- }
-
+ }
+
+ const TPassthroughConstraintNode* commonPassthrough = nullptr;
+ if (inputPassthrough) {
+ const auto updateLambda = input->Child(3);
+ const auto initPassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, true>(*initLambda, ctx);
+ const auto updatePassthrough = GetConstraintFromLambda<TPassthroughConstraintNode, true>(*updateLambda, ctx);
+ if (initPassthrough && updatePassthrough) {
+ std::array<TConstraintSet, 2U> set;
+ set.front().AddConstraint(initPassthrough);
+ set.back().AddConstraint(updatePassthrough);
+ if (commonPassthrough = TPassthroughConstraintNode::MakeCommon({&set.front(), &set.back()}, ctx))
+ input->AddConstraint(commonPassthrough);
+ }
+ }
+
+ if (const auto switchLambda = input->Child(2); switchLambda->Tail().IsCallable(TCoBool::CallableName()) && IsFalse(switchLambda->Tail().Head().Content())) {
+ TVector<TString> fields(initLambda->Head().ChildrenSize());
+ ui32 i = 0U;
+ std::generate_n(fields.begin(), initLambda->Head().ChildrenSize(), [&i](){ return ToString(i++); });
+ input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(fields));
+ } else {
+ TVector<TStringBuf> groupByKeys;
+ if (const auto groupBy = switchLambda->GetConstraint<TGroupByConstraintNode>()) {
+ groupByKeys.assign(groupBy->GetColumns().begin(), groupBy->GetColumns().end());
+ } else if (switchLambda->Tail().IsCallable({"AggrNotEquals", "NotEquals"})) {
+ ExtractSimpleKeys(switchLambda->Child(1)->Child(0), switchLambda->Child(0)->Child(0), groupByKeys);
+ }
+ if (!groupByKeys.empty() && commonPassthrough) {
+ auto mapping = commonPassthrough->GetReverseMapping();
+ TUniqueConstraintNode::TSetType uniqColumns;
+ for (auto key: groupByKeys) {
+ auto range = mapping.equal_range(key);
+ if (range.first != range.second) {
+ for (auto i = range.first; i != range.second; ++i) {
+ uniqColumns.insert_unique(i->second);
+ }
+ } else {
+ uniqColumns.clear();
+ break;
+ }
+ }
+ if (!uniqColumns.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(std::move(uniqColumns)));
+ }
+ }
+ }
+
+ return FromFirst<TEmptyConstraintNode>(input, output, ctx);
+ }
+
TStatus GroupByKeyWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- const TStructExprType* inItemType = GetNonEmptyStructItemType(*input->Head().GetTypeAnn());
+ const TStructExprType* inItemType = GetNonEmptyStructItemType(*input->Head().GetTypeAnn());
const TStructExprType* outItemType = GetNonEmptyStructItemType(*input->GetTypeAnn());
if (inItemType && outItemType) {
- const auto keySelector = input->Child(TCoGroupByKey::idx_KeySelectorLambda);
- if (const auto status = UpdateLambdaConstraints(*keySelector); status != TStatus::Ok) {
- return status;
- }
- TConstraintNode::TListType argConstraints;
- if (const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>())
- argConstraints.emplace_back(inputPassthrough);
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(TCoGroupByKey::idx_HandlerLambda), ctx, {TConstraintNode::TListType{}, argConstraints}); status != TStatus::Ok) {
- return status;
- }
-
- if (const auto handlerLambda = input->Child(TCoGroupByKey::idx_HandlerLambda); handlerLambda->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
+ const auto keySelector = input->Child(TCoGroupByKey::idx_KeySelectorLambda);
+ if (const auto status = UpdateLambdaConstraints(*keySelector); status != TStatus::Ok) {
+ return status;
+ }
+ TConstraintNode::TListType argConstraints;
+ if (const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>())
+ argConstraints.emplace_back(inputPassthrough);
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(TCoGroupByKey::idx_HandlerLambda), ctx, {TConstraintNode::TListType{}, argConstraints}); status != TStatus::Ok) {
+ return status;
+ }
+
+ if (const auto handlerLambda = input->Child(TCoGroupByKey::idx_HandlerLambda); handlerLambda->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Optional) {
TVector<TStringBuf> groupKeys;
ExtractKeys(*keySelector, groupKeys);
if (!groupKeys.empty()) {
- if (const auto passthrough = handlerLambda->GetConstraint<TPassthroughConstraintNode>()) {
- const auto mapping = passthrough->GetReverseMapping();
+ if (const auto passthrough = handlerLambda->GetConstraint<TPassthroughConstraintNode>()) {
+ const auto mapping = passthrough->GetReverseMapping();
TUniqueConstraintNode::TSetType uniqColumns;
for (auto key: groupKeys) {
auto range = mapping.equal_range(key);
@@ -2219,17 +2219,17 @@ private:
}
TStatus PartitionByKeyWrap(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) const {
- if (const auto status = UpdateLambdaConstraints(*input->Child(TCoPartitionByKeyBase::idx_KeySelectorLambda)); status != TStatus::Ok) {
- return status;
+ if (const auto status = UpdateLambdaConstraints(*input->Child(TCoPartitionByKeyBase::idx_KeySelectorLambda)); status != TStatus::Ok) {
+ return status;
+ }
+ if (const auto sortKeySelector = input->Child(TCoPartitionByKeyBase::idx_SortKeySelectorLambda); sortKeySelector->IsLambda()) {
+ if (const auto status = UpdateLambdaConstraints(*sortKeySelector); status != TStatus::Ok) {
+ return status;
+ }
}
- if (const auto sortKeySelector = input->Child(TCoPartitionByKeyBase::idx_SortKeySelectorLambda); sortKeySelector->IsLambda()) {
- if (const auto status = UpdateLambdaConstraints(*sortKeySelector); status != TStatus::Ok) {
- return status;
- }
- }
- std::unordered_set<const TPassthroughConstraintNode*> explicitPasstrought;
- auto argConstraints = GetConstraintsForInputArgument(*input, explicitPasstrought, ctx);
+ std::unordered_set<const TPassthroughConstraintNode*> explicitPasstrought;
+ auto argConstraints = GetConstraintsForInputArgument(*input, explicitPasstrought, ctx);
TVector<TStringBuf> partitionKeys;
ExtractKeys(*input->Child(TCoPartitionByKeyBase::idx_KeySelectorLambda), partitionKeys);
@@ -2237,23 +2237,23 @@ private:
argConstraints.push_back(ctx.MakeConstraint<TGroupByConstraintNode>(std::move(partitionKeys)));
}
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(TCoPartitionByKeyBase::idx_ListHandlerLambda), ctx, {argConstraints}); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(TCoPartitionByKeyBase::idx_ListHandlerLambda), ctx, {argConstraints}); status != TStatus::Ok) {
return status;
}
- const auto handlerLambda = input->Child(TCoPartitionByKeyBase::idx_ListHandlerLambda);
- const auto lambdaPassthrough = handlerLambda->GetConstraint<TPassthroughConstraintNode>();
- if (lambdaPassthrough) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought)
- mapping.erase(myPasstrought);
- if (!mapping.empty()) {
- input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
- }
- }
-
+ const auto handlerLambda = input->Child(TCoPartitionByKeyBase::idx_ListHandlerLambda);
+ const auto lambdaPassthrough = handlerLambda->GetConstraint<TPassthroughConstraintNode>();
+ if (lambdaPassthrough) {
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought)
+ mapping.erase(myPasstrought);
+ if (!mapping.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
+ }
+ }
+
if (!partitionKeys.empty() && lambdaPassthrough) {
if (auto uniq = handlerLambda->GetConstraint<TUniqueConstraintNode>()) {
auto mapping = lambdaPassthrough->GetReverseMapping();
@@ -2275,9 +2275,9 @@ private:
}
}
- const bool multiInput = ETypeAnnotationKind::Variant == GetItemType(*input->Head().GetTypeAnn())->GetKind();
+ const bool multiInput = ETypeAnnotationKind::Variant == GetItemType(*input->Head().GetTypeAnn())->GetKind();
const auto lambdaVarIndex = handlerLambda->GetConstraint<TVarIndexConstraintNode>();
- const auto multi = input->Head().GetConstraint<TMultiConstraintNode>();
+ const auto multi = input->Head().GetConstraint<TMultiConstraintNode>();
const auto lambdaMulti = handlerLambda->GetConstraint<TMultiConstraintNode>();
if (const auto varIndex = input->Head().GetConstraint<TVarIndexConstraintNode>()) {
@@ -2311,13 +2311,13 @@ private:
remappedItems.push_back(std::make_pair(item.first, TConstraintSet{}));
if (!multiInput) { // remapping one to many
if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought)
- mapping.erase(myPasstrought);
- if (!mapping.empty()) {
- remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought)
+ mapping.erase(myPasstrought);
+ if (!mapping.empty()) {
+ remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
}
if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
auto mapping = lambdaPassthrough->GetReverseMapping();
@@ -2351,13 +2351,13 @@ private:
case 1: // remapping 1 to 1
if (auto origConstr = multi->GetItem(range.first->second)) {
if (const auto lambdaPassthrough = item.second.template GetConstraint<TPassthroughConstraintNode>()) {
- if (!explicitPasstrought.contains(lambdaPassthrough)) {
- auto mapping = lambdaPassthrough->GetColumnMapping();
- for (const auto myPasstrought : explicitPasstrought)
- mapping.erase(myPasstrought);
- if (!mapping.empty()) {
- remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
- }
+ if (!explicitPasstrought.contains(lambdaPassthrough)) {
+ auto mapping = lambdaPassthrough->GetColumnMapping();
+ for (const auto myPasstrought : explicitPasstrought)
+ mapping.erase(myPasstrought);
+ if (!mapping.empty()) {
+ remappedItems.back().second.AddConstraint(ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(mapping)));
+ }
}
if (const auto lambdaUnique = item.second.template GetConstraint<TUniqueConstraintNode>()) {
auto mapping = lambdaPassthrough->GetReverseMapping();
@@ -2442,25 +2442,25 @@ private:
return TStatus::Ok;
}
- TStatus FoldWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
+ TStatus FoldWrap(const TExprNode::TPtr& input, TExprNode::TPtr&, TExprContext& ctx) const {
const TStructExprType* inItemType = GetNonEmptyStructItemType(*input->Child(0)->GetTypeAnn());
const TStructExprType* outItemType = GetNonEmptyStructItemType(*input->GetTypeAnn());
if (!inItemType || !outItemType) {
return UpdateAllChildLambdasConstraints(*input);
}
- const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
+ const auto inputPassthrough = input->Head().GetConstraint<TPassthroughConstraintNode>();
if (input->Child(1)->IsLambda()) {
- TConstraintNode::TListType argConstraints;
- if (inputPassthrough)
- argConstraints.emplace_back(inputPassthrough);
- if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, {argConstraints}); status != TStatus::Ok) {
+ TConstraintNode::TListType argConstraints;
+ if (inputPassthrough)
+ argConstraints.emplace_back(inputPassthrough);
+ if (const auto status = UpdateLambdaConstraints(input->ChildRef(1), ctx, {argConstraints}); status != TStatus::Ok) {
return status;
}
}
- const auto initState = input->Child(1);
- auto stateConstraints = initState->GetAllConstraints();
+ const auto initState = input->Child(1);
+ auto stateConstraints = initState->GetAllConstraints();
stateConstraints.erase(
std::remove_if(
stateConstraints.begin(),
@@ -2470,16 +2470,16 @@ private:
stateConstraints.end()
);
- TConstraintNode::TListType argConstraints;
- if (inputPassthrough)
- argConstraints.emplace_back(inputPassthrough);
+ TConstraintNode::TListType argConstraints;
+ if (inputPassthrough)
+ argConstraints.emplace_back(inputPassthrough);
- if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, {argConstraints, stateConstraints}); status != TStatus::Ok) {
+ if (const auto status = UpdateLambdaConstraints(input->TailRef(), ctx, {argConstraints, stateConstraints}); status != TStatus::Ok) {
return status;
}
- if (const auto lambdaPassthrough = input->Tail().GetConstraint<TPassthroughConstraintNode>()) {
- input->AddConstraint(lambdaPassthrough);
+ if (const auto lambdaPassthrough = input->Tail().GetConstraint<TPassthroughConstraintNode>()) {
+ input->AddConstraint(lambdaPassthrough);
}
return TStatus::Ok;
@@ -2529,16 +2529,16 @@ private:
return nullptr;
}
- if (GetSeqItemType(list.GetTypeAnn())->GetKind() == ETypeAnnotationKind::Struct) {
- TVector<bool> dirs;
- TVector<TStringBuf> keys;
- ExtractSimpleSortTraits(directions, keyExtractor, dirs, keys);
- YQL_ENSURE(dirs.size() == keys.size());
- TSortedConstraintNode::TContainerType content;
- for (auto i = 0U; i < keys.size(); ++i)
- content.emplace_back(TSortedConstraintNode::TContainerType::value_type::first_type{keys[i]}, dirs[i]);
- if (!content.empty()) {
- return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
+ if (GetSeqItemType(list.GetTypeAnn())->GetKind() == ETypeAnnotationKind::Struct) {
+ TVector<bool> dirs;
+ TVector<TStringBuf> keys;
+ ExtractSimpleSortTraits(directions, keyExtractor, dirs, keys);
+ YQL_ENSURE(dirs.size() == keys.size());
+ TSortedConstraintNode::TContainerType content;
+ for (auto i = 0U; i < keys.size(); ++i)
+ content.emplace_back(TSortedConstraintNode::TContainerType::value_type::first_type{keys[i]}, dirs[i]);
+ if (!content.empty()) {
+ return ctx.MakeConstraint<TSortedConstraintNode>(std::move(content));
}
}
return nullptr;
@@ -2563,29 +2563,29 @@ private:
static const TSortedConstraintNode* GetPassthroughSortedConstraint(const TSortedConstraintNode& inputSorted,
const TPassthroughConstraintNode& passthrough, TExprContext& ctx)
{
- const auto& reverseMapping = passthrough.GetReverseMapping();
- const auto& content = inputSorted.GetContent();
- TSortedConstraintNode::TContainerType filtered;
- for (auto i = 0U; i < content.size(); ++i) {
- TSortedConstraintNode::TContainerType::value_type nextItem;
- for (const auto& column : content[i].first) {
- auto range = reverseMapping.equal_range(column);
- if (range.first != range.second) {
- for (auto it = range.first; it != range.second; ++it) {
- nextItem.first.emplace_back(it->second);
- }
- }
- }
- if (nextItem.first.empty())
+ const auto& reverseMapping = passthrough.GetReverseMapping();
+ const auto& content = inputSorted.GetContent();
+ TSortedConstraintNode::TContainerType filtered;
+ for (auto i = 0U; i < content.size(); ++i) {
+ TSortedConstraintNode::TContainerType::value_type nextItem;
+ for (const auto& column : content[i].first) {
+ auto range = reverseMapping.equal_range(column);
+ if (range.first != range.second) {
+ for (auto it = range.first; it != range.second; ++it) {
+ nextItem.first.emplace_back(it->second);
+ }
+ }
+ }
+ if (nextItem.first.empty())
break;
-
- nextItem.second = content[i].second;
- ::Sort(nextItem.first);
- filtered.emplace_back(std::move(nextItem));
+
+ nextItem.second = content[i].second;
+ ::Sort(nextItem.first);
+ filtered.emplace_back(std::move(nextItem));
}
-
- if (!filtered.empty()) {
- return ctx.MakeConstraint<TSortedConstraintNode>(std::move(filtered));
+
+ if (!filtered.empty()) {
+ return ctx.MakeConstraint<TSortedConstraintNode>(std::move(filtered));
}
return nullptr;
}
@@ -2593,7 +2593,7 @@ private:
static const TUniqueConstraintNode* GetPassthroughUniqueConstraint(const TUniqueConstraintNode& inputUnique,
const TPassthroughConstraintNode& passthrough, TExprContext& ctx)
{
- const auto reverseMapping = passthrough.GetReverseMapping();
+ const auto reverseMapping = passthrough.GetReverseMapping();
TUniqueConstraintNode::TSetType remappedColumns;
for (auto col: inputUnique.GetColumns()) {
auto range = reverseMapping.equal_range(col);
@@ -2627,102 +2627,102 @@ private:
THashMap<TStringBuf, THandler> Functions;
};
-template<> const TPassthroughConstraintNode*
-TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TPassthroughConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
- TPassthroughConstraintNode::TMapType passthrough;
- for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
- if (const auto pass = lambda.Child(i)->GetConstraint<TPassthroughConstraintNode>()) {
- const auto& name = ctx.AppendString(ToString(i - 1U));
- for (const auto& part : pass->GetColumnMapping()) {
- std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
- item.first.emplace_front(name);
- return item;
- });
- }
- }
- }
-
- return passthrough.empty() ? nullptr: ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passthrough));
-}
-
-template<> const TUniqueConstraintNode*
-TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TUniqueConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
- TNodeSet srcStructs;
- TVector<TStringBuf> unique;
- unique.reserve(lambda.ChildrenSize() - 1U);
-
- for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
- auto valueNode = lambda.Child(i);
- const auto& name = ctx.AppendString(ToString(i - 1U));
- if (TCoCoalesce::Match(valueNode)) {
- if (valueNode->Child(0)->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || valueNode->ChildrenSize() == 1) {
- valueNode = valueNode->Child(0);
- }
- }
- if (TCoJust::Match(valueNode)) {
- valueNode = valueNode->Child(0);
- }
-
- if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
- const auto memberName = valueNode->Child(1)->Content();
- const auto structNode = valueNode->Child(0);
- if (const auto structUnique = structNode->GetConstraint<TUniqueConstraintNode>()) {
- if (structUnique->GetColumns().has(memberName)) {
- if (!TCoNothing::Match(structNode)) {
- srcStructs.insert(structNode);
- unique.push_back(name);
- }
- }
- }
- } else if (valueNode->Type() == TExprNode::Argument) {
- if (const auto structUnique = valueNode->GetConstraint<TUniqueConstraintNode>()) {
- if (structUnique->GetColumns().size() == 1) {
- srcStructs.insert(valueNode);
- unique.push_back(name);
- }
- }
- }
- }
-
- if (!unique.empty()) {
- if (srcStructs.empty() || (srcStructs.size() == 1 && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())) {
- ::SortUnique(unique);
- return ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique));
- }
- }
-
- return nullptr;
-}
-
-template<> const TVarIndexConstraintNode*
-TCallableConstraintTransformer::TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TVarIndexConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
- TVector<const TConstraintSet*> structConstraints;
- structConstraints.reserve(lambda.ChildrenSize() - 1U);
-
- for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
- auto valueNode = lambda.Child(i);
- if (TCoCoalesce::Match(valueNode)) {
- if (valueNode->Child(0)->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || valueNode->ChildrenSize() == 1) {
- valueNode = valueNode->Child(0);
- }
- }
- if (TCoJust::Match(valueNode)) {
- valueNode = valueNode->Child(0);
- }
-
- if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
- structConstraints.push_back(&valueNode->Head().GetConstraintSet());
- } else if (valueNode->Type() == TExprNode::Argument) {
- structConstraints.push_back(&valueNode->GetConstraintSet());
- }
- }
-
- return TVarIndexConstraintNode::MakeCommon(structConstraints, ctx);
-}
-
-template<class TConstraint> const TConstraint*
-TCallableConstraintTransformer::GetConstraintFromWideResultLambda(const TExprNode&, TExprContext&) { return nullptr; }
-
+template<> const TPassthroughConstraintNode*
+TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TPassthroughConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
+ TPassthroughConstraintNode::TMapType passthrough;
+ for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
+ if (const auto pass = lambda.Child(i)->GetConstraint<TPassthroughConstraintNode>()) {
+ const auto& name = ctx.AppendString(ToString(i - 1U));
+ for (const auto& part : pass->GetColumnMapping()) {
+ std::transform(part.second.cbegin(), part.second.cend(), std::back_inserter(passthrough[part.first ? part.first : pass]), [&name](TPassthroughConstraintNode::TPartType::value_type item) {
+ item.first.emplace_front(name);
+ return item;
+ });
+ }
+ }
+ }
+
+ return passthrough.empty() ? nullptr: ctx.MakeConstraint<TPassthroughConstraintNode>(std::move(passthrough));
+}
+
+template<> const TUniqueConstraintNode*
+TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TUniqueConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
+ TNodeSet srcStructs;
+ TVector<TStringBuf> unique;
+ unique.reserve(lambda.ChildrenSize() - 1U);
+
+ for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
+ auto valueNode = lambda.Child(i);
+ const auto& name = ctx.AppendString(ToString(i - 1U));
+ if (TCoCoalesce::Match(valueNode)) {
+ if (valueNode->Child(0)->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || valueNode->ChildrenSize() == 1) {
+ valueNode = valueNode->Child(0);
+ }
+ }
+ if (TCoJust::Match(valueNode)) {
+ valueNode = valueNode->Child(0);
+ }
+
+ if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
+ const auto memberName = valueNode->Child(1)->Content();
+ const auto structNode = valueNode->Child(0);
+ if (const auto structUnique = structNode->GetConstraint<TUniqueConstraintNode>()) {
+ if (structUnique->GetColumns().has(memberName)) {
+ if (!TCoNothing::Match(structNode)) {
+ srcStructs.insert(structNode);
+ unique.push_back(name);
+ }
+ }
+ }
+ } else if (valueNode->Type() == TExprNode::Argument) {
+ if (const auto structUnique = valueNode->GetConstraint<TUniqueConstraintNode>()) {
+ if (structUnique->GetColumns().size() == 1) {
+ srcStructs.insert(valueNode);
+ unique.push_back(name);
+ }
+ }
+ }
+ }
+
+ if (!unique.empty()) {
+ if (srcStructs.empty() || (srcStructs.size() == 1 && unique.size() == (*srcStructs.begin())->GetConstraint<TUniqueConstraintNode>()->GetColumns().size())) {
+ ::SortUnique(unique);
+ return ctx.MakeConstraint<TUniqueConstraintNode>(std::move(unique));
+ }
+ }
+
+ return nullptr;
+}
+
+template<> const TVarIndexConstraintNode*
+TCallableConstraintTransformer::TCallableConstraintTransformer::GetConstraintFromWideResultLambda<TVarIndexConstraintNode>(const TExprNode& lambda, TExprContext& ctx) {
+ TVector<const TConstraintSet*> structConstraints;
+ structConstraints.reserve(lambda.ChildrenSize() - 1U);
+
+ for (auto i = 1U; i < lambda.ChildrenSize(); ++i) {
+ auto valueNode = lambda.Child(i);
+ if (TCoCoalesce::Match(valueNode)) {
+ if (valueNode->Child(0)->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional || valueNode->ChildrenSize() == 1) {
+ valueNode = valueNode->Child(0);
+ }
+ }
+ if (TCoJust::Match(valueNode)) {
+ valueNode = valueNode->Child(0);
+ }
+
+ if (TCoMember::Match(valueNode) || TCoNth::Match(valueNode)) {
+ structConstraints.push_back(&valueNode->Head().GetConstraintSet());
+ } else if (valueNode->Type() == TExprNode::Argument) {
+ structConstraints.push_back(&valueNode->GetConstraintSet());
+ }
+ }
+
+ return TVarIndexConstraintNode::MakeCommon(structConstraints, ctx);
+}
+
+template<class TConstraint> const TConstraint*
+TCallableConstraintTransformer::GetConstraintFromWideResultLambda(const TExprNode&, TExprContext&) { return nullptr; }
+
class TDefaultCallableConstraintTransformer : public TSyncTransformerBase {
public:
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) override {
@@ -2749,7 +2749,7 @@ public:
UpdateStatusIfChanged(status, input, output);
if (status.Level != TStatus::Error && HasRenames) {
- output = ctx.ReplaceNodes(std::move(output), Processed);
+ output = ctx.ReplaceNodes(std::move(output), Processed);
}
Processed.clear();
@@ -2934,15 +2934,15 @@ private:
{
retStatus = TransformChildren(input, output, ctx);
if (retStatus == TStatus::Ok) {
- retStatus = CallableTransformer->Transform(input, output, ctx);
- if (retStatus == TStatus::Ok) {
- input->SetState(TExprNode::EState::ConstrComplete);
- CheckExpected(*input);
- break;
- }
- }
-
- if (retStatus != TStatus::Error && input != output) {
+ retStatus = CallableTransformer->Transform(input, output, ctx);
+ if (retStatus == TStatus::Ok) {
+ input->SetState(TExprNode::EState::ConstrComplete);
+ CheckExpected(*input);
+ break;
+ }
+ }
+
+ if (retStatus != TStatus::Error && input != output) {
processedPair.first->second = output;
}
break;
@@ -2950,10 +2950,10 @@ private:
case TExprNode::Lambda:
{
- YQL_ENSURE(input->ChildrenSize() > 0U);
+ YQL_ENSURE(input->ChildrenSize() > 0U);
TExprNode::TPtr out;
- auto argStatus = TransformNode(input->HeadPtr(), out, ctx);
- UpdateStatusIfChanged(argStatus, input->HeadPtr(), out);
+ auto argStatus = TransformNode(input->HeadPtr(), out, ctx);
+ UpdateStatusIfChanged(argStatus, input->HeadPtr(), out);
if (argStatus.Level == TStatus::Error) {
input->SetState(TExprNode::EState::Error);
return argStatus;
@@ -2962,35 +2962,35 @@ private:
if (argStatus.Level == TStatus::Repeat)
return TStatus::Ok;
- TStatus bodyStatus = TStatus::Ok;
- TExprNode::TListType newBody;
- newBody.reserve(input->ChildrenSize() - 1U);
- bool updatedChildren = false;
- for (ui32 i = 1U; i < input->ChildrenSize(); ++i) {
- const auto child = input->ChildPtr(i);
- TExprNode::TPtr newChild;
- auto childStatus = TransformNode(child, newChild, ctx);
- UpdateStatusIfChanged(childStatus, child, newChild);
- updatedChildren = updatedChildren || (newChild != child);
- bodyStatus = bodyStatus.Combine(childStatus);
- newBody.emplace_back(std::move(newChild));
- }
-
+ TStatus bodyStatus = TStatus::Ok;
+ TExprNode::TListType newBody;
+ newBody.reserve(input->ChildrenSize() - 1U);
+ bool updatedChildren = false;
+ for (ui32 i = 1U; i < input->ChildrenSize(); ++i) {
+ const auto child = input->ChildPtr(i);
+ TExprNode::TPtr newChild;
+ auto childStatus = TransformNode(child, newChild, ctx);
+ UpdateStatusIfChanged(childStatus, child, newChild);
+ updatedChildren = updatedChildren || (newChild != child);
+ bodyStatus = bodyStatus.Combine(childStatus);
+ newBody.emplace_back(std::move(newChild));
+ }
+
retStatus = argStatus.Combine(bodyStatus);
if (retStatus != TStatus::Ok) {
if (retStatus.Level == TStatus::Error) {
input->SetState(TExprNode::EState::Error);
}
- else if (updatedChildren) {
- output = ctx.DeepCopyLambda(*input, std::move(newBody));
+ else if (updatedChildren) {
+ output = ctx.DeepCopyLambda(*input, std::move(newBody));
processedPair.first->second = output;
HasRenames = true;
}
} else {
- if (input->ChildrenSize() != 2U)
- input->SetState(TExprNode::EState::ConstrComplete);
- else
- input->CopyConstraints(input->Tail());
+ if (input->ChildrenSize() != 2U)
+ input->SetState(TExprNode::EState::ConstrComplete);
+ else
+ input->CopyConstraints(input->Tail());
CheckExpected(*input);
}
break;
@@ -3109,18 +3109,18 @@ private:
}
void CheckExpected(const TExprNode& input) {
- if (const auto it = Types.ExpectedConstraints.find(input.UniqueId()); it != Types.ExpectedConstraints.cend()) {
+ if (const auto it = Types.ExpectedConstraints.find(input.UniqueId()); it != Types.ExpectedConstraints.cend()) {
for (const TConstraintNode* expectedConstr: it->second) {
if (!Types.DisableConstraintCheck.contains(expectedConstr->GetName())) {
- const auto newConstr = input.GetConstraint(expectedConstr->GetName());
+ const auto newConstr = input.GetConstraint(expectedConstr->GetName());
// Constraint Multi(0:{Empty},1:{Empty}, ..., N:{Empty}) can be reduced to Empty
- if (expectedConstr->GetName() == TMultiConstraintNode::Name()) {
- if (newConstr) {
- YQL_ENSURE(static_cast<const TMultiConstraintNode*>(newConstr)->FilteredIncludes(*expectedConstr, Types.DisableConstraintCheck), "Rewrite error, unequal " << *newConstr
- << " constraint in node " << input.Content() << ", previous was " << *expectedConstr);
- } else {
- YQL_ENSURE(input.GetConstraint<TEmptyConstraintNode>(), "Rewrite error, missing " << *expectedConstr << " constraint in node " << input.Content());
- }
+ if (expectedConstr->GetName() == TMultiConstraintNode::Name()) {
+ if (newConstr) {
+ YQL_ENSURE(static_cast<const TMultiConstraintNode*>(newConstr)->FilteredIncludes(*expectedConstr, Types.DisableConstraintCheck), "Rewrite error, unequal " << *newConstr
+ << " constraint in node " << input.Content() << ", previous was " << *expectedConstr);
+ } else {
+ YQL_ENSURE(input.GetConstraint<TEmptyConstraintNode>(), "Rewrite error, missing " << *expectedConstr << " constraint in node " << input.Content());
+ }
} else {
YQL_ENSURE(newConstr, "Rewrite error, missing " << *expectedConstr << " constraint in node " << input.Content());
YQL_ENSURE(newConstr->Includes(*expectedConstr), "Rewrite error, unequal " << *newConstr
@@ -3153,11 +3153,11 @@ TAutoPtr<IGraphTransformer> CreateDefCallableConstraintTransformer() {
IGraphTransformer::TStatus UpdateLambdaConstraints(const TExprNode& lambda) {
auto args = lambda.Child(0);
- for (const auto& arg: args->Children()) {
+ for (const auto& arg: args->Children()) {
if (arg->GetState() == TExprNode::EState::TypeComplete || arg->GetState() == TExprNode::EState::ConstrPending) {
arg->SetState(TExprNode::EState::ConstrComplete);
}
- YQL_ENSURE(arg->GetAllConstraints().empty());
+ YQL_ENSURE(arg->GetAllConstraints().empty());
}
if (args->GetState() == TExprNode::EState::TypeComplete || args->GetState() == TExprNode::EState::ConstrPending) {
@@ -3171,51 +3171,51 @@ IGraphTransformer::TStatus UpdateLambdaConstraints(const TExprNode& lambda) {
return IGraphTransformer::TStatus::Ok;
}
-IGraphTransformer::TStatus UpdateLambdaConstraints(TExprNode::TPtr& lambda, TExprContext& ctx, const TArrayRef<const TConstraintNode::TListType>& constraints) {
+IGraphTransformer::TStatus UpdateLambdaConstraints(TExprNode::TPtr& lambda, TExprContext& ctx, const TArrayRef<const TConstraintNode::TListType>& constraints) {
bool updateArgs = false;
- const auto args = lambda->Child(0);
+ const auto args = lambda->Child(0);
YQL_ENSURE(args->ChildrenSize() == constraints.size());
size_t i = 0;
- for (const auto constrList: constraints) {
- const auto arg = args->Child(i++);
+ for (const auto constrList: constraints) {
+ const auto arg = args->Child(i++);
if (arg->GetState() == TExprNode::EState::TypeComplete || arg->GetState() == TExprNode::EState::ConstrPending) {
- for (const auto c: constrList) {
+ for (const auto c: constrList) {
arg->AddConstraint(c);
}
arg->SetState(TExprNode::EState::ConstrComplete);
} else {
- if (constrList.size() != arg->GetAllConstraints().size() || !AllOf(constrList, [arg] (const TConstraintNode* c) { return arg->GetConstraint(c->GetName()) == c; })) {
+ if (constrList.size() != arg->GetAllConstraints().size() || !AllOf(constrList, [arg] (const TConstraintNode* c) { return arg->GetConstraint(c->GetName()) == c; })) {
updateArgs = true;
}
}
}
if (updateArgs) {
- TNodeOnNodeOwnedMap replaces(constraints.size());
- TExprNode::TListType argsChildren;
- argsChildren.reserve(constraints.size());
+ TNodeOnNodeOwnedMap replaces(constraints.size());
+ TExprNode::TListType argsChildren;
+ argsChildren.reserve(constraints.size());
i = 0;
- for (const auto constrList: constraints) {
- const auto arg = args->Child(i++);
- const auto newArg = ctx.ShallowCopy(*arg);
+ for (const auto constrList: constraints) {
+ const auto arg = args->Child(i++);
+ const auto newArg = ctx.ShallowCopy(*arg);
newArg->SetTypeAnn(arg->GetTypeAnn());
- for (const auto c: constrList) {
+ for (const auto c: constrList) {
newArg->AddConstraint(c);
}
newArg->SetState(TExprNode::EState::ConstrComplete);
YQL_ENSURE(replaces.emplace(arg, newArg).second);
- argsChildren.emplace_back(std::move(newArg));
+ argsChildren.emplace_back(std::move(newArg));
}
auto newArgs = ctx.NewArguments(args->Pos(), std::move(argsChildren));
newArgs->SetTypeAnn(ctx.MakeType<TUnitExprType>());
newArgs->SetState(TExprNode::EState::ConstrComplete);
- const auto type = lambda->GetTypeAnn();
- lambda = ctx.NewLambda(lambda->Pos(), std::move(newArgs), ctx.ReplaceNodes<true>(GetLambdaBody(*lambda), replaces));
- lambda->SetTypeAnn(type);
- lambda->Head().ForEachChild(std::bind(&TExprNode::SetDependencyScope, std::placeholders::_1, lambda.Get(), lambda.Get()));
- return IGraphTransformer::TStatus::Repeat;
+ const auto type = lambda->GetTypeAnn();
+ lambda = ctx.NewLambda(lambda->Pos(), std::move(newArgs), ctx.ReplaceNodes<true>(GetLambdaBody(*lambda), replaces));
+ lambda->SetTypeAnn(type);
+ lambda->Head().ForEachChild(std::bind(&TExprNode::SetDependencyScope, std::placeholders::_1, lambda.Get(), lambda.Get()));
+ return IGraphTransformer::TStatus::Repeat;
}
if (args->GetState() == TExprNode::EState::TypeComplete || args->GetState() == TExprNode::EState::ConstrPending) {
diff --git a/ydb/library/yql/core/yql_expr_constraint.h b/ydb/library/yql/core/yql_expr_constraint.h
index c5f089049c..76f64608ab 100644
--- a/ydb/library/yql/core/yql_expr_constraint.h
+++ b/ydb/library/yql/core/yql_expr_constraint.h
@@ -14,7 +14,7 @@ TAutoPtr<IGraphTransformer> CreateConstraintTransformer(TTypeAnnotationContext&
TAutoPtr<IGraphTransformer> CreateDefCallableConstraintTransformer();
IGraphTransformer::TStatus UpdateLambdaConstraints(const TExprNode& lambda);
-IGraphTransformer::TStatus UpdateLambdaConstraints(TExprNode::TPtr& lambda, TExprContext& ctx, const TArrayRef<const TConstraintNode::TListType>& constraints);
+IGraphTransformer::TStatus UpdateLambdaConstraints(TExprNode::TPtr& lambda, TExprContext& ctx, const TArrayRef<const TConstraintNode::TListType>& constraints);
IGraphTransformer::TStatus UpdateAllChildLambdasConstraints(const TExprNode& node);
}
diff --git a/ydb/library/yql/core/yql_expr_csee.cpp b/ydb/library/yql/core/yql_expr_csee.cpp
index 790322da1f..b0e7525521 100644
--- a/ydb/library/yql/core/yql_expr_csee.cpp
+++ b/ydb/library/yql/core/yql_expr_csee.cpp
@@ -26,7 +26,7 @@ namespace {
}
struct TLambdaFrame {
- TLambdaFrame(const TExprNode* lambda, const TLambdaFrame* prev)
+ TLambdaFrame(const TExprNode* lambda, const TLambdaFrame* prev)
: Lambda(lambda)
, Prev(prev)
{}
@@ -34,15 +34,15 @@ namespace {
TLambdaFrame() = default;
const TExprNode* Lambda = nullptr;
- const TLambdaFrame* Prev = nullptr;
+ const TLambdaFrame* Prev = nullptr;
};
bool IsArgInScope(const TLambdaFrame& frame, const TExprNode& arg) {
- for (auto curr = &frame; curr; curr = curr->Prev) {
- if (const auto lambda = curr->Lambda) {
+ for (auto curr = &frame; curr; curr = curr->Prev) {
+ if (const auto lambda = curr->Lambda) {
YQL_ENSURE(lambda->IsLambda());
- for (ui32 i = 0U; i < lambda->Head().ChildrenSize(); ++i) {
- if (lambda->Head().Child(i) == &arg) {
+ for (ui32 i = 0U; i < lambda->Head().ChildrenSize(); ++i) {
+ if (lambda->Head().Child(i) == &arg) {
return true;
}
}
@@ -51,65 +51,65 @@ namespace {
return false;
}
- ui16 GetDependencyLevel(const TExprNode& node) {
- if (const auto lambda = node.GetDependencyScope()->first) {
- return 1 + GetDependencyLevel(*lambda);
- }
- return 0;
- }
-
- enum class EDependencyScope : ui8 {
- None = 0,
- Inner = 1,
- Outer = 2,
- Mixed = Inner | Outer
- };
-
- EDependencyScope CheckDependencyScope(const TLambdaFrame& frame, const TExprNode& node) {
- if (!node.IsAtom()) {
- if (const auto scope = node.GetDependencyScope()) {
- const auto outerLambda = scope->first;
- const auto innerLambda = scope->second;
- if (bool innerFound = false; innerLambda || outerLambda) {
- for (auto curr = &frame; curr; curr = curr->Prev) {
- if (!innerFound && innerLambda) {
- if (curr->Lambda == innerLambda) {
- innerFound = true;
- } else {
- continue;
- }
- }
- if (curr->Lambda == outerLambda) {
- return curr->Lambda == &node ? EDependencyScope::None : EDependencyScope::Inner;
- }
- }
- return innerFound ? EDependencyScope::Mixed : EDependencyScope::Outer;
- }
- }
- }
- return EDependencyScope::None;
- }
+ ui16 GetDependencyLevel(const TExprNode& node) {
+ if (const auto lambda = node.GetDependencyScope()->first) {
+ return 1 + GetDependencyLevel(*lambda);
+ }
+ return 0;
+ }
+
+ enum class EDependencyScope : ui8 {
+ None = 0,
+ Inner = 1,
+ Outer = 2,
+ Mixed = Inner | Outer
+ };
+
+ EDependencyScope CheckDependencyScope(const TLambdaFrame& frame, const TExprNode& node) {
+ if (!node.IsAtom()) {
+ if (const auto scope = node.GetDependencyScope()) {
+ const auto outerLambda = scope->first;
+ const auto innerLambda = scope->second;
+ if (bool innerFound = false; innerLambda || outerLambda) {
+ for (auto curr = &frame; curr; curr = curr->Prev) {
+ if (!innerFound && innerLambda) {
+ if (curr->Lambda == innerLambda) {
+ innerFound = true;
+ } else {
+ continue;
+ }
+ }
+ if (curr->Lambda == outerLambda) {
+ return curr->Lambda == &node ? EDependencyScope::None : EDependencyScope::Inner;
+ }
+ }
+ return innerFound ? EDependencyScope::Mixed : EDependencyScope::Outer;
+ }
+ }
+ }
+ return EDependencyScope::None;
+ }
ui64 CalculateHash(ui16 depth, TExprNode& node, const TLambdaFrame& currFrame, const TColumnOrderStorage& coStore) {
- const auto dependency = CheckDependencyScope(currFrame, node);
- switch (dependency) {
- case EDependencyScope::None:
- if (const auto hash = node.GetHash()) {
- return hash;
- }
- break;
- case EDependencyScope::Inner:
- if (const auto hash = node.GetHashAbove()) {
- return hash;
- }
- break;
- case EDependencyScope::Outer:
- if (const auto hash = node.GetHashBelow()) {
- return hash;
- }
- break;
- case EDependencyScope::Mixed:
- break;
+ const auto dependency = CheckDependencyScope(currFrame, node);
+ switch (dependency) {
+ case EDependencyScope::None:
+ if (const auto hash = node.GetHash()) {
+ return hash;
+ }
+ break;
+ case EDependencyScope::Inner:
+ if (const auto hash = node.GetHashAbove()) {
+ return hash;
+ }
+ break;
+ case EDependencyScope::Outer:
+ if (const auto hash = node.GetHashBelow()) {
+ return hash;
+ }
+ break;
+ case EDependencyScope::Mixed:
+ break;
}
ui64 hash = node.GetTypeAnn()->GetHash();
@@ -121,7 +121,7 @@ namespace {
switch (node.Type()) {
case TExprNode::Atom: {
- if constexpr (UseDeterminsticHash) {
+ if constexpr (UseDeterminsticHash) {
hash = CseeHash(node.Content().data(), node.Content().size(), hash);
} else {
// can hash ptr due to intern
@@ -132,8 +132,8 @@ namespace {
hash = CseeHash(node.GetFlagsToCompare(), hash);
break;
}
- case TExprNode::Callable:
- if constexpr (UseDeterminsticHash) {
+ case TExprNode::Callable:
+ if constexpr (UseDeterminsticHash) {
hash = CseeHash(node.Content().data(), node.Content().size(), hash);
} else {
// can hash ptr due to intern
@@ -141,33 +141,33 @@ namespace {
hash = CseeHash(&ptr, sizeof(ptr), hash);
}
[[fallthrough]];
- case TExprNode::List: {
- const auto size = node.ChildrenSize();
+ case TExprNode::List: {
+ const auto size = node.ChildrenSize();
hash = CseeHash(size, hash);
- if (node.UnorderedChildren()) {
- TSmallVec<ui64> hashes;
- hashes.reserve(size);
- for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
+ if (node.UnorderedChildren()) {
+ TSmallVec<ui64> hashes;
+ hashes.reserve(size);
+ for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
hashes.emplace_back(CalculateHash(depth, *node.Child(i), currFrame, coStore));
- };
- std::sort(hashes.begin(), hashes.end());
- hash = std::accumulate(hashes.cbegin(), hashes.cend(), ~hash, [] (ui64 hash, ui64 childHash) {
+ };
+ std::sort(hashes.begin(), hashes.end());
+ hash = std::accumulate(hashes.cbegin(), hashes.cend(), ~hash, [] (ui64 hash, ui64 childHash) {
return CseeHash(childHash, hash);
- });
- } else {
- for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
+ });
+ } else {
+ for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
const auto childHash = CalculateHash(depth, *node.Child(i), currFrame, coStore);
hash = CseeHash(childHash, hash);
- }
+ }
}
break;
}
case TExprNode::Lambda: {
- if (const ui32 size = node.ChildrenSize())
+ if (const ui32 size = node.ChildrenSize())
hash = CseeHash(size, hash);
-
- const auto& args = node.Head();
+
+ const auto& args = node.Head();
hash = CseeHash(args.ChildrenSize(), hash);
for (ui32 i = 0; i < args.ChildrenSize(); ++i) {
@@ -179,31 +179,31 @@ namespace {
}
TLambdaFrame newFrame(&node, &currFrame);
- for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
+ for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
const auto lambdaHash = CalculateHash(depth + 1, *node.Child(i), newFrame, coStore);
hash = CseeHash(lambdaHash, hash);
- }
+ }
break;
}
- case TExprNode::Argument:
- switch (dependency) {
- case EDependencyScope::Inner: {
+ case TExprNode::Argument:
+ switch (dependency) {
+ case EDependencyScope::Inner: {
hash = CseeHash(GetDependencyLevel(node), hash);
hash = CseeHash(node.GetArgIndex(), hash);
- break;
+ break;
}
- case EDependencyScope::Outer: {
- if constexpr (UseDeterminsticHash) {
+ case EDependencyScope::Outer: {
+ if constexpr (UseDeterminsticHash) {
hash = CseeHash(node.UniqueId(), hash);
- } else {
- const auto ptr = &node;
+ } else {
+ const auto ptr = &node;
hash = CseeHash(&ptr, sizeof(ptr), hash);
- }
- break;
- }
- case EDependencyScope::None:
- case EDependencyScope::Mixed:
- Y_FAIL("Strange argument.");
+ }
+ break;
+ }
+ case EDependencyScope::None:
+ case EDependencyScope::Mixed:
+ Y_FAIL("Strange argument.");
}
break;
case TExprNode::World:
@@ -216,20 +216,20 @@ namespace {
hash = 1;
}
- switch (dependency) {
- case EDependencyScope::None:
- node.SetHash(hash);
- break;
- case EDependencyScope::Inner:
- node.SetHashAbove(hash);
- break;
- case EDependencyScope::Outer:
- node.SetHashBelow(hash);
- break;
- case EDependencyScope::Mixed:
- break;
- }
- return hash;
+ switch (dependency) {
+ case EDependencyScope::None:
+ node.SetHash(hash);
+ break;
+ case EDependencyScope::Inner:
+ node.SetHashAbove(hash);
+ break;
+ case EDependencyScope::Outer:
+ node.SetHashBelow(hash);
+ break;
+ case EDependencyScope::Mixed:
+ break;
+ }
+ return hash;
}
bool EqualNodes(const TExprNode& left, TLambdaFrame& currLeftFrame, const TExprNode& right, TLambdaFrame& currRightFrame,
@@ -250,7 +250,7 @@ namespace {
if (left.GetTypeAnn() != right.GetTypeAnn()) {
return false;
}
-
+
if (left.GetAllConstraints() != right.GetAllConstraints()) {
return false;
}
@@ -260,51 +260,51 @@ namespace {
}
switch (left.Type()) {
- case TExprNode::Atom:
- // compare pointers due to intern
- return left.Content().data() == right.Content().data() && left.GetFlagsToCompare() == right.GetFlagsToCompare();
+ case TExprNode::Atom:
+ // compare pointers due to intern
+ return left.Content().data() == right.Content().data() && left.GetFlagsToCompare() == right.GetFlagsToCompare();
- case TExprNode::Callable:
+ case TExprNode::Callable:
// compare pointers due to intern
if (left.Content().data() != right.Content().data()) {
return false;
}
[[fallthrough]];
- case TExprNode::List:
+ case TExprNode::List:
if (left.ChildrenSize() != right.ChildrenSize()) {
return false;
}
- if (left.UnorderedChildren() && right.UnorderedChildren()) {
- if (2U == left.ChildrenSize()) {
+ if (left.UnorderedChildren() && right.UnorderedChildren()) {
+ if (2U == left.ChildrenSize()) {
return EqualNodes(left.Head(), currLeftFrame, right.Head(), currRightFrame, visited, coStore)
&& EqualNodes(left.Tail(), currLeftFrame, right.Tail(), currRightFrame, visited, coStore)
|| EqualNodes(left.Head(), currLeftFrame, right.Tail(), currRightFrame, visited, coStore)
&& EqualNodes(left.Tail(), currLeftFrame, right.Head(), currRightFrame, visited, coStore);
- } else {
- TSmallVec<const TExprNode*> lNodes, rNodes;
- lNodes.reserve(left.ChildrenSize());
- rNodes.reserve(right.ChildrenSize());
-
- left.ForEachChild([&lNodes](const TExprNode& child){ return lNodes.emplace_back(&child); });
- right.ForEachChild([&rNodes](const TExprNode& child){ return rNodes.emplace_back(&child); });
-
- const auto order = [](const TExprNode* l, const TExprNode* r) { return l->GetHashAbove() < r->GetHashAbove(); };
- std::sort(lNodes.begin(), lNodes.end(), order);
- std::sort(rNodes.begin(), rNodes.end(), order);
-
- for (ui32 i = 0; i < lNodes.size(); ++i) {
+ } else {
+ TSmallVec<const TExprNode*> lNodes, rNodes;
+ lNodes.reserve(left.ChildrenSize());
+ rNodes.reserve(right.ChildrenSize());
+
+ left.ForEachChild([&lNodes](const TExprNode& child){ return lNodes.emplace_back(&child); });
+ right.ForEachChild([&rNodes](const TExprNode& child){ return rNodes.emplace_back(&child); });
+
+ const auto order = [](const TExprNode* l, const TExprNode* r) { return l->GetHashAbove() < r->GetHashAbove(); };
+ std::sort(lNodes.begin(), lNodes.end(), order);
+ std::sort(rNodes.begin(), rNodes.end(), order);
+
+ for (ui32 i = 0; i < lNodes.size(); ++i) {
if (!EqualNodes(*lNodes[i], currLeftFrame, *rNodes[i], currRightFrame, visited, coStore)) {
- return false;
- }
- }
+ return false;
+ }
+ }
}
- } else {
- for (ui32 i = 0; i < left.ChildrenSize(); ++i) {
+ } else {
+ for (ui32 i = 0; i < left.ChildrenSize(); ++i) {
if (!EqualNodes(*left.Child(i), currLeftFrame, *right.Child(i), currRightFrame, visited, coStore)) {
- return false;
- }
- }
+ return false;
+ }
+ }
}
return true;
@@ -313,12 +313,12 @@ namespace {
return false;
}
- if (left.ChildrenSize() != right.ChildrenSize()) {
- return false;
- }
-
- const auto& leftArgs = left.Head();
- const auto& rightArgs = right.Head();
+ if (left.ChildrenSize() != right.ChildrenSize()) {
+ return false;
+ }
+
+ const auto& leftArgs = left.Head();
+ const auto& rightArgs = right.Head();
if (leftArgs.ChildrenSize() != rightArgs.ChildrenSize()) {
return false;
}
@@ -337,16 +337,16 @@ namespace {
TLambdaFrame newLeftFrame(&left, &currLeftFrame);
TLambdaFrame newRightFrame(&right, &currRightFrame);
- for (ui32 i = 1U; i < left.ChildrenSize(); ++i) {
+ for (ui32 i = 1U; i < left.ChildrenSize(); ++i) {
if (!EqualNodes(*left.Child(i), newLeftFrame, *right.Child(i), newRightFrame, visited, coStore))
- return false;
- }
- return true;
+ return false;
+ }
+ return true;
}
case TExprNode::Argument: {
- if (currLeftFrame.Lambda && currRightFrame.Lambda && IsArgInScope(currLeftFrame, left) && IsArgInScope(currRightFrame, right)) {
- const ui16 leftRelativeLevel = GetDependencyLevel(left);
- const ui16 rightRelativeLevel = GetDependencyLevel(right);
+ if (currLeftFrame.Lambda && currRightFrame.Lambda && IsArgInScope(currLeftFrame, left) && IsArgInScope(currRightFrame, right)) {
+ const ui16 leftRelativeLevel = GetDependencyLevel(left);
+ const ui16 rightRelativeLevel = GetDependencyLevel(right);
return leftRelativeLevel == rightRelativeLevel && left.GetArgIndex() == right.GetArgIndex();
} else {
return &left == &right;
@@ -362,7 +362,7 @@ namespace {
return false;
}
- int CompareNodes(const TExprNode& left, const TExprNode& right, TNodeSet& visited) {
+ int CompareNodes(const TExprNode& left, const TExprNode& right, TNodeSet& visited) {
if (&left == &right) {
return 0;
}
@@ -376,7 +376,7 @@ namespace {
}
switch (left.Type()) {
- case TExprNode::Atom:
+ case TExprNode::Atom:
if (left.Content().size() != right.Content().size()) {
return (int)left.Content().size() - (int)right.Content().size();
}
@@ -384,12 +384,12 @@ namespace {
// compare pointers due to intern
if (left.Content().data() != right.Content().data()) {
if (const auto res = left.Content().compare(right.Content())) {
- return res;
- }
+ return res;
+ }
}
return (int)left.GetFlagsToCompare() - (int)right.GetFlagsToCompare();
- case TExprNode::Callable:
+ case TExprNode::Callable:
if (left.Content().size() != right.Content().size()) {
return (int)left.Content().size() - (int)right.Content().size();
}
@@ -397,46 +397,46 @@ namespace {
// compare pointers due to intern
if (left.Content().data() != right.Content().data()) {
if (const auto res = left.Content().compare(right.Content())) {
- return res;
- }
+ return res;
+ }
}
[[fallthrough]];
- case TExprNode::List:
+ case TExprNode::List:
if (left.ChildrenSize() != right.ChildrenSize()) {
return (int)left.ChildrenSize() - (int)right.ChildrenSize();
}
for (ui32 i = 0; i < left.ChildrenSize(); ++i) {
- if (const auto res = CompareNodes(*left.Child(i), *right.Child(i), visited)) {
+ if (const auto res = CompareNodes(*left.Child(i), *right.Child(i), visited)) {
return res;
}
}
return 0;
case TExprNode::Lambda: {
- if (left.ChildrenSize() != right.ChildrenSize()) {
- return (int)left.ChildrenSize() - (int)right.ChildrenSize();
- }
-
- const auto& leftArgs = left.Head();
- const auto& rightArgs = right.Head();
+ if (left.ChildrenSize() != right.ChildrenSize()) {
+ return (int)left.ChildrenSize() - (int)right.ChildrenSize();
+ }
+
+ const auto& leftArgs = left.Head();
+ const auto& rightArgs = right.Head();
if (leftArgs.ChildrenSize() != rightArgs.ChildrenSize()) {
return (int)leftArgs.ChildrenSize() - (int)rightArgs.ChildrenSize();
}
- for (ui32 i = 1U; i < left.ChildrenSize(); ++i) {
- if (const auto c = CompareNodes(*left.Child(i), *right.Child(i), visited))
- return c;
- }
- return 0;
+ for (ui32 i = 1U; i < left.ChildrenSize(); ++i) {
+ if (const auto c = CompareNodes(*left.Child(i), *right.Child(i), visited))
+ return c;
+ }
+ return 0;
}
- case TExprNode::Argument:
+ case TExprNode::Argument:
if (left.GetArgIndex() != right.GetArgIndex()) {
return (int)left.GetArgIndex() - (int)right.GetArgIndex();
}
- return (int)left.GetDependencyScope()->first->GetLambdaLevel() - (int)right.GetDependencyScope()->first->GetLambdaLevel();
+ return (int)left.GetDependencyScope()->first->GetLambdaLevel() - (int)right.GetDependencyScope()->first->GetLambdaLevel();
case TExprNode::Arguments:
break;
case TExprNode::World:
@@ -449,142 +449,142 @@ namespace {
void CalculateCompletness(TExprNode& node, bool insideDependsOn, ui16 level, TNodeSet& closures,
TNodeMap<TNodeSet>& visited, TNodeMap<TNodeSet>& visitedInsideDependsOn) {
- switch (node.Type()) {
- case TExprNode::Atom:
- node.SetDependencyScope(nullptr, nullptr);
- return;
- case TExprNode::Argument:
- closures.emplace(node.GetDependencyScope()->first);
- if (insideDependsOn) {
- node.SetUsedInDependsOn();
- }
- return;
- default: break;
+ switch (node.Type()) {
+ case TExprNode::Atom:
+ node.SetDependencyScope(nullptr, nullptr);
+ return;
+ case TExprNode::Argument:
+ closures.emplace(node.GetDependencyScope()->first);
+ if (insideDependsOn) {
+ node.SetUsedInDependsOn();
+ }
+ return;
+ default: break;
}
const auto ins = (insideDependsOn ? visitedInsideDependsOn : visited).emplace(&node, TNodeSet{});
- if (!ins.second) {
- closures.insert(ins.first->second.cbegin(), ins.first->second.cend());
+ if (!ins.second) {
+ closures.insert(ins.first->second.cbegin(), ins.first->second.cend());
return;
}
- auto& internal = ins.first->second;
-
- if (TExprNode::Lambda == node.Type()) {
- node.SetLambdaLevel(level);
- node.Head().ForEachChild(std::bind(&TExprNode::SetDependencyScope, std::placeholders::_1, &node, &node));
- for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
+ auto& internal = ins.first->second;
+
+ if (TExprNode::Lambda == node.Type()) {
+ node.SetLambdaLevel(level);
+ node.Head().ForEachChild(std::bind(&TExprNode::SetDependencyScope, std::placeholders::_1, &node, &node));
+ for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
CalculateCompletness(*node.Child(i), insideDependsOn, level + 1, internal, visited, visitedInsideDependsOn);
- }
- internal.erase(&node);
+ }
+ internal.erase(&node);
} else {
insideDependsOn = insideDependsOn || node.IsCallable("DependsOn");
node.ForEachChild(std::bind(&CalculateCompletness, std::placeholders::_1, insideDependsOn, level, std::ref(internal),
std::ref(visited), std::ref(visitedInsideDependsOn)));
- }
-
- const TExprNode* outerLambda = nullptr;
- const TExprNode* innerLambda = nullptr;
- for (const auto lambda : internal) {
- if (!outerLambda || lambda->GetLambdaLevel() < outerLambda->GetLambdaLevel()) {
- outerLambda = lambda;
- }
- if (!innerLambda || lambda->GetLambdaLevel() > innerLambda->GetLambdaLevel()) {
- innerLambda = lambda;
- }
- }
-
- node.SetDependencyScope(outerLambda, innerLambda);
- closures.insert(internal.cbegin(), internal.cend());
+ }
+
+ const TExprNode* outerLambda = nullptr;
+ const TExprNode* innerLambda = nullptr;
+ for (const auto lambda : internal) {
+ if (!outerLambda || lambda->GetLambdaLevel() < outerLambda->GetLambdaLevel()) {
+ outerLambda = lambda;
+ }
+ if (!innerLambda || lambda->GetLambdaLevel() > innerLambda->GetLambdaLevel()) {
+ innerLambda = lambda;
+ }
+ }
+
+ node.SetDependencyScope(outerLambda, innerLambda);
+ closures.insert(internal.cbegin(), internal.cend());
}
ui64 CalcHash(TExprNode& node, const TColumnOrderStorage& coStore) {
- TLambdaFrame frame;
+ TLambdaFrame frame;
return CalculateHash(0, node, frame, coStore);
- }
-
+ }
+
bool EqualNodes(const TExprNode& left, const TExprNode& right, const TColumnOrderStorage& coStore) {
- TNodeSet visited;
- TLambdaFrame frame;
+ TNodeSet visited;
+ TLambdaFrame frame;
return EqualNodes(left, frame, right, frame, visited, coStore);
- }
-
- TExprNode::TPtr VisitNode(TExprNode& node, TExprNode* currentLambda, ui16 level,
- std::unordered_multimap<ui64, TExprNode*>& uniqueNodes,
- std::unordered_multimap<ui64, TExprNode*>& incompleteNodes,
+ }
+
+ TExprNode::TPtr VisitNode(TExprNode& node, TExprNode* currentLambda, ui16 level,
+ std::unordered_multimap<ui64, TExprNode*>& uniqueNodes,
+ std::unordered_multimap<ui64, TExprNode*>& incompleteNodes,
TNodeMap<TExprNode*>& renames, const TColumnOrderStorage& coStore) {
if (node.Type() == TExprNode::Argument) {
return nullptr;
- }
-
- const auto find = renames.emplace(&node, nullptr);
- if (!find.second) {
- return find.first->second;
- }
-
+ }
+
+ const auto find = renames.emplace(&node, nullptr);
+ if (!find.second) {
+ return find.first->second;
+ }
+
const auto hash = CalcHash(node, coStore);
-
- if (node.Type() == TExprNode::Lambda) {
- for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
+
+ if (node.Type() == TExprNode::Lambda) {
+ for (ui32 i = 1U; i < node.ChildrenSize(); ++i) {
if (auto newNode = VisitNode(*node.Child(i), &node, level + 1U, uniqueNodes, incompleteNodes, renames, coStore)) {
- node.ChildRef(i) = std::move(newNode);
- }
+ node.ChildRef(i) = std::move(newNode);
+ }
}
} else {
for (ui32 i = 0; i < node.ChildrenSize(); ++i) {
if (auto newNode = VisitNode(*node.Child(i), currentLambda, level, uniqueNodes, incompleteNodes, renames, coStore)) {
- node.ChildRef(i) = std::move(newNode);
+ node.ChildRef(i) = std::move(newNode);
}
}
}
- if (const auto kind = node.GetTypeAnn()->GetKind(); ETypeAnnotationKind::Flow != kind && ETypeAnnotationKind::Stream != kind || node.IsLambda()) {
- auto& nodesSet = node.IsComplete() ? uniqueNodes : incompleteNodes;
-
- const auto pair = nodesSet.equal_range(hash);
- auto iter = pair.first;
- while (pair.second != iter) {
- // search for duplicates
- if (iter->second->Dead()) {
- iter = nodesSet.erase(iter);
- continue;
- }
+ if (const auto kind = node.GetTypeAnn()->GetKind(); ETypeAnnotationKind::Flow != kind && ETypeAnnotationKind::Stream != kind || node.IsLambda()) {
+ auto& nodesSet = node.IsComplete() ? uniqueNodes : incompleteNodes;
+
+ const auto pair = nodesSet.equal_range(hash);
+ auto iter = pair.first;
+ while (pair.second != iter) {
+ // search for duplicates
+ if (iter->second->Dead()) {
+ iter = nodesSet.erase(iter);
+ continue;
+ }
if (!EqualNodes(node, *iter->second, coStore)) {
#ifndef NDEBUG
- if (!GetEnv("YQL_ALLOW_CSEE_HASH_COLLISION")) {
- YQL_ENSURE(false, "Node -BEGIN-\n" << node.Dump() << "-END-" << " has same hash as -BEGIN-\n"
- << iter->second->Dump() << "-END-");
- }
-#endif
- ++iter;
- continue;
- }
-
- if (iter->second == &node)
- return nullptr;
-
- find.first->second = iter->second;
- if (node.Type() == TExprNode::Atom) {
- iter->second->NormalizeAtomFlags(node);
+ if (!GetEnv("YQL_ALLOW_CSEE_HASH_COLLISION")) {
+ YQL_ENSURE(false, "Node -BEGIN-\n" << node.Dump() << "-END-" << " has same hash as -BEGIN-\n"
+ << iter->second->Dump() << "-END-");
+ }
+#endif
+ ++iter;
+ continue;
+ }
+
+ if (iter->second == &node)
+ return nullptr;
+
+ find.first->second = iter->second;
+ if (node.Type() == TExprNode::Atom) {
+ iter->second->NormalizeAtomFlags(node);
}
- return iter->second;
+ return iter->second;
}
- nodesSet.emplace_hint(iter, hash, &node);
+ nodesSet.emplace_hint(iter, hash, &node);
}
return nullptr;
}
}
-IGraphTransformer::TStatus UpdateCompletness(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext&) {
+IGraphTransformer::TStatus UpdateCompletness(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext&) {
YQL_PROFILE_SCOPE(DEBUG, "UpdateCompletness");
output = input;
// process closures
- TNodeSet closures;
- TNodeMap<TNodeSet> visited;
+ TNodeSet closures;
+ TNodeMap<TNodeSet> visited;
TNodeMap<TNodeSet> visitedInsideDependsOn;
CalculateCompletness(*input, false, 0, closures, visited, visitedInsideDependsOn);
return IGraphTransformer::TStatus::Ok;
@@ -597,7 +597,7 @@ IGraphTransformer::TStatus EliminateCommonSubExpressions(const TExprNode::TPtr&
output = input;
TNodeMap<TExprNode*> renames;
//Cerr << "INPUT\n" << output->Dump() << "\n";
- std::unordered_multimap<ui64, TExprNode*> incompleteNodes;
+ std::unordered_multimap<ui64, TExprNode*> incompleteNodes;
const auto newNode = VisitNode(*output, nullptr, 0, ctx.UniqueNodes, incompleteNodes, renames, coStore);
YQL_ENSURE(forSubGraph || !newNode);
//Cerr << "OUTPUT\n" << output->Dump() << "\n";
@@ -606,7 +606,7 @@ IGraphTransformer::TStatus EliminateCommonSubExpressions(const TExprNode::TPtr&
int CompareNodes(const TExprNode& left, const TExprNode& right) {
TNodeSet visited;
- return CompareNodes(left, right, visited);
+ return CompareNodes(left, right, visited);
}
}
diff --git a/ydb/library/yql/core/yql_expr_optimize.cpp b/ydb/library/yql/core/yql_expr_optimize.cpp
index 2c88cf1fdd..677ca7fa53 100644
--- a/ydb/library/yql/core/yql_expr_optimize.cpp
+++ b/ydb/library/yql/core/yql_expr_optimize.cpp
@@ -11,7 +11,7 @@ namespace {
TOptimizer Optimizer;
TExprContext& Expr;
const TOptimizeExprSettings& Settings;
- TNodeOnNodeOwnedMap Memoization;
+ TNodeOnNodeOwnedMap Memoization;
const TNodeOnNodeOwnedMap* Replaces;
ui64 LastNodeId;
bool HasRemaps;
@@ -26,10 +26,10 @@ namespace {
{
}
- void RemapNode(const TExprNode& fromNode, const TExprNode::TPtr& toNode) final {
- YQL_ENSURE(fromNode.UniqueId() <= LastNodeId);
+ void RemapNode(const TExprNode& fromNode, const TExprNode::TPtr& toNode) final {
+ YQL_ENSURE(fromNode.UniqueId() <= LastNodeId);
YQL_ENSURE(toNode->UniqueId() > LastNodeId);
- Memoization[&fromNode] = toNode;
+ Memoization[&fromNode] = toNode;
HasRemaps = true;
if (Settings.ProcessedNodes) {
Settings.ProcessedNodes->erase(fromNode.UniqueId());
@@ -37,39 +37,39 @@ namespace {
}
};
- TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizer>& ctx, const TExprNode::TPtr& node) {
+ TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizer>& ctx, const TExprNode::TPtr& node) {
return (!ctx.Settings.VisitChanges && ctx.HasRemaps) ? node : ctx.Optimizer(node, ctx.Expr);
}
- TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizerEx>& ctx, const TExprNode::TPtr& node) {
+ TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizerEx>& ctx, const TExprNode::TPtr& node) {
return (!ctx.Settings.VisitChanges && ctx.HasRemaps) ? node : ctx.Optimizer(node, ctx.Expr, ctx);
}
- TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizerFast>& ctx, bool& changed, const TExprNode::TPtr& node) {
+ TExprNode::TPtr RunOptimizer(TOptimizationContext<TCallableOptimizerFast>& ctx, bool& changed, const TExprNode::TPtr& node) {
return (!ctx.Settings.VisitChanges && ctx.HasRemaps) ? node : ctx.Optimizer(node, changed, ctx.Expr);
- }
-
+ }
+
template<typename TContext>
- TExprNode::TPtr ApplyRemaps(const TExprNode::TPtr& node, TContext& ctx) {
- const auto memoization = ctx.Memoization.find(node.Get());
- if (ctx.Memoization.cend() != memoization && memoization->second && memoization->second != node) {
- return memoization->second;
+ TExprNode::TPtr ApplyRemaps(const TExprNode::TPtr& node, TContext& ctx) {
+ const auto memoization = ctx.Memoization.find(node.Get());
+ if (ctx.Memoization.cend() != memoization && memoization->second && memoization->second != node) {
+ return memoization->second;
}
TExprNode::TListType newChildren;
bool hasRemaps = false;
- for (const auto& child : node->Children()) {
- auto newChild = ApplyRemaps(child, ctx);
+ for (const auto& child : node->Children()) {
+ auto newChild = ApplyRemaps(child, ctx);
YQL_ENSURE(newChild);
if (newChild != child) {
hasRemaps = true;
}
- newChildren.emplace_back(std::move(newChild));
+ newChildren.emplace_back(std::move(newChild));
}
- return hasRemaps ? ctx.Expr.ChangeChildren(*node, std::move(newChildren)) : node;
+ return hasRemaps ? ctx.Expr.ChangeChildren(*node, std::move(newChildren)) : node;
}
void AddExpected(const TExprNode& src, const TExprNode& dst, const TOptimizeExprSettings& settings) {
@@ -90,27 +90,27 @@ namespace {
}
template<typename TContext>
- TExprNode::TPtr OptimizeNode(const TExprNode::TPtr& node, TContext& ctx, size_t level) {
- if (node->Type() == TExprNode::Atom || node->Type() == TExprNode::Argument ||
- node->Type() == TExprNode::Arguments || node->Type() == TExprNode::World) {
- return node;
+ TExprNode::TPtr OptimizeNode(const TExprNode::TPtr& node, TContext& ctx, size_t level) {
+ if (node->Type() == TExprNode::Atom || node->Type() == TExprNode::Argument ||
+ node->Type() == TExprNode::Arguments || node->Type() == TExprNode::World) {
+ return node;
}
- if (!ctx.Settings.VisitStarted && node->StartsExecution()) {
- return node;
+ if (!ctx.Settings.VisitStarted && node->StartsExecution()) {
+ return node;
}
- YQL_ENSURE(level < 3000U, "Too deep graph!");
-
+ YQL_ENSURE(level < 3000U, "Too deep graph!");
+
if (ctx.Settings.ProcessedNodes) {
- if (ctx.Settings.ProcessedNodes->find(node->UniqueId()) != ctx.Settings.ProcessedNodes->cend()) {
- return node;
+ if (ctx.Settings.ProcessedNodes->find(node->UniqueId()) != ctx.Settings.ProcessedNodes->cend()) {
+ return node;
}
}
- const auto it = ctx.Memoization.find(node.Get());
- if (it != ctx.Memoization.cend()) {
- return it->second ? it->second : node;
+ const auto it = ctx.Memoization.find(node.Get());
+ if (it != ctx.Memoization.cend()) {
+ return it->second ? it->second : node;
}
TExprNode::TPtr current = node;
@@ -121,29 +121,29 @@ namespace {
}
}
- TExprNode::TPtr ret;
+ TExprNode::TPtr ret;
if (current->Type() == TExprNode::Lambda) {
ret = current;
if (ctx.Settings.VisitLambdas) {
- TExprNode::TListType newBody;
- newBody.reserve(node->ChildrenSize() - 1U);
- bool bodyChanged = false;
- for (ui32 i = 1U; i < node->ChildrenSize(); ++i) {
- const auto& oldNode = node->ChildPtr(i);
- auto newNode = OptimizeNode(oldNode, ctx, level + 1);
- if (!newNode)
- return nullptr;
- bodyChanged = bodyChanged || newNode != oldNode;
- if (newNode->ForDisclosing()) {
- auto list = newNode->ChildrenList();
- std::move(list.begin(), list.end(), std::back_inserter(newBody));
- } else {
- newBody.emplace_back(std::move(newNode));
- }
- }
- if (bodyChanged) {
- ret = ctx.Expr.DeepCopyLambda(*current, std::move(newBody));
+ TExprNode::TListType newBody;
+ newBody.reserve(node->ChildrenSize() - 1U);
+ bool bodyChanged = false;
+ for (ui32 i = 1U; i < node->ChildrenSize(); ++i) {
+ const auto& oldNode = node->ChildPtr(i);
+ auto newNode = OptimizeNode(oldNode, ctx, level + 1);
+ if (!newNode)
+ return nullptr;
+ bodyChanged = bodyChanged || newNode != oldNode;
+ if (newNode->ForDisclosing()) {
+ auto list = newNode->ChildrenList();
+ std::move(list.begin(), list.end(), std::back_inserter(newBody));
+ } else {
+ newBody.emplace_back(std::move(newNode));
+ }
+ }
+ if (bodyChanged) {
+ ret = ctx.Expr.DeepCopyLambda(*current, std::move(newBody));
AddExpected(*node, *ret, ctx.Settings);
}
}
@@ -160,16 +160,16 @@ namespace {
hasRenames = true;
}
- if (newChild->ForDisclosing()) {
- auto list = newChild->ChildrenList();
- std::move(list.begin(), list.end(), std::back_inserter(newChildren));
- } else {
- newChildren.emplace_back(std::move(newChild));
- }
+ if (newChild->ForDisclosing()) {
+ auto list = newChild->ChildrenList();
+ std::move(list.begin(), list.end(), std::back_inserter(newChildren));
+ } else {
+ newChildren.emplace_back(std::move(newChild));
+ }
}
auto renamedNode = hasRenames ? ctx.Expr.ChangeChildren(*current, std::move(newChildren)) : TExprNode::TPtr();
- newChildren.clear();
+ newChildren.clear();
if (!ctx.Settings.VisitChanges && hasRenames && ctx.Settings.CustomInstantTypeTransformer) {
auto root = renamedNode ? renamedNode : current;
@@ -181,9 +181,9 @@ namespace {
YQL_ENSURE(root->GetTypeAnn());
if (status.HasRestart) {
- ret = std::move(root);
+ ret = std::move(root);
} else {
- renamedNode = std::move(root);
+ renamedNode = std::move(root);
hasRenames = false;
}
}
@@ -192,9 +192,9 @@ namespace {
const auto& nextNode = renamedNode ? renamedNode : current;
const bool visitTuples = ctx.Settings.VisitTuples && nextNode->Type() == TExprNode::List;
if ((nextNode->Type() != TExprNode::Callable && !visitTuples) || (hasRenames && !ctx.Settings.VisitChanges) || !ctx.Optimizer) {
- ret = nextNode;
+ ret = nextNode;
} else {
- ret = RunOptimizer(ctx, nextNode);
+ ret = RunOptimizer(ctx, nextNode);
if (!ret)
return nullptr;
}
@@ -203,12 +203,12 @@ namespace {
AddExpected(*node, *ret, ctx.Settings);
}
- if (node == ret && ctx.Settings.ProcessedNodes) {
- ctx.Settings.ProcessedNodes->insert(node->UniqueId());
+ if (node == ret && ctx.Settings.ProcessedNodes) {
+ ctx.Settings.ProcessedNodes->insert(node->UniqueId());
}
- if (node == ret) {
- YQL_ENSURE(ctx.Memoization.emplace(node.Get(), TExprNode::TPtr()).second);
+ if (node == ret) {
+ YQL_ENSURE(ctx.Memoization.emplace(node.Get(), TExprNode::TPtr()).second);
} else {
if (!node->Unique()) {
YQL_ENSURE(ctx.Memoization.emplace(node.Get(), ret).second);
@@ -216,97 +216,97 @@ namespace {
if (current != node && current != ret) {
ctx.Memoization.emplace(current.Get(), ret);
}
- }
+ }
return ret;
}
- TExprNode::TPtr OptimizeNode(const TExprNode::TPtr& node, bool& changed, TOptimizationContext<TCallableOptimizerFast>& ctx, size_t level) {
- if (node->Type() == TExprNode::Atom || node->Type() == TExprNode::Argument ||
- node->Type() == TExprNode::Arguments || node->Type() == TExprNode::World) {
- return node;
- }
-
- const auto it = ctx.Memoization.find(node.Get());
- if (it != ctx.Memoization.cend()) {
- changed = changed || bool(it->second);
- return it->second ? it->second : node;
- }
-
- YQL_ENSURE(level < 3000U, "Too deep graph!");
-
- TExprNode::TPtr ret;
- if (node->Type() == TExprNode::Lambda) {
+ TExprNode::TPtr OptimizeNode(const TExprNode::TPtr& node, bool& changed, TOptimizationContext<TCallableOptimizerFast>& ctx, size_t level) {
+ if (node->Type() == TExprNode::Atom || node->Type() == TExprNode::Argument ||
+ node->Type() == TExprNode::Arguments || node->Type() == TExprNode::World) {
+ return node;
+ }
+
+ const auto it = ctx.Memoization.find(node.Get());
+ if (it != ctx.Memoization.cend()) {
+ changed = changed || bool(it->second);
+ return it->second ? it->second : node;
+ }
+
+ YQL_ENSURE(level < 3000U, "Too deep graph!");
+
+ TExprNode::TPtr ret;
+ if (node->Type() == TExprNode::Lambda) {
ret = node;
-
+
if (ctx.Settings.VisitLambdas) {
- TExprNode::TListType newBody;
- newBody.reserve(node->ChildrenSize() - 1U);
+ TExprNode::TListType newBody;
+ newBody.reserve(node->ChildrenSize() - 1U);
bool bodyChanged = false;
- for (ui32 i = 1U; i < node->ChildrenSize(); ++i) {
- auto newNode = OptimizeNode(node->ChildPtr(i), bodyChanged, ctx, level + 1);
- if (!newNode)
- return nullptr;
- if (newNode->ForDisclosing()) {
- auto list = newNode->ChildrenList();
- std::move(list.begin(), list.end(), std::back_inserter(newBody));
- } else {
- newBody.emplace_back(std::move(newNode));
- }
- }
+ for (ui32 i = 1U; i < node->ChildrenSize(); ++i) {
+ auto newNode = OptimizeNode(node->ChildPtr(i), bodyChanged, ctx, level + 1);
+ if (!newNode)
+ return nullptr;
+ if (newNode->ForDisclosing()) {
+ auto list = newNode->ChildrenList();
+ std::move(list.begin(), list.end(), std::back_inserter(newBody));
+ } else {
+ newBody.emplace_back(std::move(newNode));
+ }
+ }
if (bodyChanged) {
- ret = ctx.Expr.DeepCopyLambda(*node, std::move(newBody));
+ ret = ctx.Expr.DeepCopyLambda(*node, std::move(newBody));
changed = true;
}
- }
- } else {
+ }
+ } else {
TExprNode::TListType newChildren;
- newChildren.reserve(node->ChildrenSize());
- bool hasRenames = false;
+ newChildren.reserve(node->ChildrenSize());
+ bool hasRenames = false;
for (auto& child : node->Children()) {
- bool childChanged = false;
+ bool childChanged = false;
auto newChild = OptimizeNode(child, childChanged, ctx, level + 1);
- if (!newChild)
- return nullptr;
-
- hasRenames = hasRenames || childChanged;
- if (newChild->ForDisclosing()) {
- auto list = newChild->ChildrenList();
- std::move(list.begin(), list.end(), std::back_inserter(newChildren));
- } else {
- newChildren.emplace_back(std::move(newChild));
- }
- }
-
+ if (!newChild)
+ return nullptr;
+
+ hasRenames = hasRenames || childChanged;
+ if (newChild->ForDisclosing()) {
+ auto list = newChild->ChildrenList();
+ std::move(list.begin(), list.end(), std::back_inserter(newChildren));
+ } else {
+ newChildren.emplace_back(std::move(newChild));
+ }
+ }
+
auto renamedNode = hasRenames ? ctx.Expr.ChangeChildren(*node, std::move(newChildren)) : TExprNode::TPtr();
- newChildren.clear();
-
- changed = changed || hasRenames;
-
- const auto& nextNode = renamedNode ? renamedNode : node;
+ newChildren.clear();
+
+ changed = changed || hasRenames;
+
+ const auto& nextNode = renamedNode ? renamedNode : node;
if (nextNode->Type() != TExprNode::Callable && (nextNode->Type() != TExprNode::List || !ctx.Settings.VisitTuples)) {
- ret = nextNode;
- } else {
- bool optimized = false;
- ret = RunOptimizer(ctx, optimized, nextNode);
- if (!ret)
- return nullptr;
- changed = changed || optimized;
- }
- }
-
- if (!node->Unique()) {
- YQL_ENSURE(ctx.Memoization.emplace(node.Get(), ret == node ? TExprNode::TPtr() : ret).second);
- }
- return ret;
- }
-
+ ret = nextNode;
+ } else {
+ bool optimized = false;
+ ret = RunOptimizer(ctx, optimized, nextNode);
+ if (!ret)
+ return nullptr;
+ changed = changed || optimized;
+ }
+ }
+
+ if (!node->Unique()) {
+ YQL_ENSURE(ctx.Memoization.emplace(node.Get(), ret == node ? TExprNode::TPtr() : ret).second);
+ }
+ return ret;
+ }
+
void VisitExprInternal(const TExprNode::TPtr& node, const TExprVisitPtrFunc& preFunc,
const TExprVisitPtrFunc& postFunc, TNodeSet& visitedNodes)
{
- if (!visitedNodes.emplace(node.Get()).second) {
+ if (!visitedNodes.emplace(node.Get()).second) {
return;
}
@@ -323,26 +323,26 @@ namespace {
void VisitExprInternal(const TExprNode& node, const TExprVisitRefFunc& preFunc,
const TExprVisitRefFunc& postFunc, TNodeSet& visitedNodes)
- {
- if (!visitedNodes.emplace(&node).second) {
- return;
- }
-
+ {
+ if (!visitedNodes.emplace(&node).second) {
+ return;
+ }
+
if (!preFunc || preFunc(node)) {
- node.ForEachChild([&](const TExprNode& child) {
- VisitExprInternal(child, preFunc, postFunc, visitedNodes);
- });
- }
+ node.ForEachChild([&](const TExprNode& child) {
+ VisitExprInternal(child, preFunc, postFunc, visitedNodes);
+ });
+ }
if (postFunc) {
postFunc(node);
}
- }
-
+ }
+
void VisitExprByFirstInternal(const TExprNode::TPtr& node, const TExprVisitPtrFunc& preFunc,
const TExprVisitPtrFunc& postFunc, TNodeSet& visitedNodes)
{
- if (!visitedNodes.emplace(node.Get()).second) {
+ if (!visitedNodes.emplace(node.Get()).second) {
return;
}
@@ -354,7 +354,7 @@ namespace {
}
}
else {
- VisitExprByFirstInternal(node->HeadPtr(), preFunc, postFunc, visitedNodes);
+ VisitExprByFirstInternal(node->HeadPtr(), preFunc, postFunc, visitedNodes);
}
}
}
@@ -367,7 +367,7 @@ namespace {
void VisitExprByFirstInternal(const TExprNode& node, const TExprVisitRefFunc& preFunc,
const TExprVisitRefFunc& postFunc, TNodeSet& visitedNodes)
{
- if (!visitedNodes.emplace(&node).second) {
+ if (!visitedNodes.emplace(&node).second) {
return;
}
@@ -379,7 +379,7 @@ namespace {
}
}
else {
- VisitExprByFirstInternal(node.Head(), preFunc, postFunc, visitedNodes);
+ VisitExprByFirstInternal(node.Head(), preFunc, postFunc, visitedNodes);
}
}
}
@@ -389,107 +389,107 @@ namespace {
}
}
- void VisitExprByPrimaryBranch(const TExprNode::TPtr& node, const TExprVisitPtrFunc& predicate, bool& primary, TNodeSet& visitedNodes)
- {
- if (!visitedNodes.emplace(node.Get()).second) {
- return;
- }
-
- if (!predicate(node) || !node->ChildrenSize())
- return;
-
- if (node->IsCallable({"If", "IfPresent", "And", "Or", "Xor", "Coalesce"})) {
- VisitExprByPrimaryBranch(node->HeadPtr(), predicate, primary, visitedNodes);
- } else {
- for (ui32 i = 0U; i < node->ChildrenSize(); ++i)
- VisitExprByPrimaryBranch(node->ChildPtr(i), predicate, primary, visitedNodes);
- return;
- }
-
- primary = false;
- for (ui32 i = 1U; i < node->ChildrenSize(); ++i)
- VisitExprByPrimaryBranch(node->ChildPtr(i), predicate, primary, visitedNodes);
- }
-
+ void VisitExprByPrimaryBranch(const TExprNode::TPtr& node, const TExprVisitPtrFunc& predicate, bool& primary, TNodeSet& visitedNodes)
+ {
+ if (!visitedNodes.emplace(node.Get()).second) {
+ return;
+ }
+
+ if (!predicate(node) || !node->ChildrenSize())
+ return;
+
+ if (node->IsCallable({"If", "IfPresent", "And", "Or", "Xor", "Coalesce"})) {
+ VisitExprByPrimaryBranch(node->HeadPtr(), predicate, primary, visitedNodes);
+ } else {
+ for (ui32 i = 0U; i < node->ChildrenSize(); ++i)
+ VisitExprByPrimaryBranch(node->ChildPtr(i), predicate, primary, visitedNodes);
+ return;
+ }
+
+ primary = false;
+ for (ui32 i = 1U; i < node->ChildrenSize(); ++i)
+ VisitExprByPrimaryBranch(node->ChildPtr(i), predicate, primary, visitedNodes);
+ }
+
template<typename TOptimizer>
- IGraphTransformer::TStatus OptimizeExprInternal(TExprNode::TPtr input, TExprNode::TPtr& output, TOptimizer optimizer,
- const TNodeOnNodeOwnedMap* replaces, TExprContext& ctx, const TOptimizeExprSettings& settings) try
+ IGraphTransformer::TStatus OptimizeExprInternal(TExprNode::TPtr input, TExprNode::TPtr& output, TOptimizer optimizer,
+ const TNodeOnNodeOwnedMap* replaces, TExprContext& ctx, const TOptimizeExprSettings& settings) try
{
- YQL_ENSURE(&input != &output);
- TOptimizationContext<TOptimizer> optCtx(optimizer, replaces, ctx, settings);
- output = OptimizeNode(input, optCtx, 0U);
+ YQL_ENSURE(&input != &output);
+ TOptimizationContext<TOptimizer> optCtx(optimizer, replaces, ctx, settings);
+ output = OptimizeNode(input, optCtx, 0U);
- if (!output)
- return IGraphTransformer::TStatus::Error;
+ if (!output)
+ return IGraphTransformer::TStatus::Error;
- if (optCtx.HasRemaps) {
- output = ApplyRemaps(output, optCtx);
+ if (optCtx.HasRemaps) {
+ output = ApplyRemaps(output, optCtx);
if (settings.ProcessedNodes) {
settings.ProcessedNodes->clear();
}
- }
+ }
+
+ if (!settings.VisitChanges && (output != input)) {
+ return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
+ }
+
+ return IGraphTransformer::TStatus::Ok;
+ } catch (const std::exception& e) {
+ ctx.AddError(ExceptionToIssue(e, ctx.GetPosition(input->Pos())));
+ return IGraphTransformer::TStatus::Error;
+ }
- if (!settings.VisitChanges && (output != input)) {
- return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
- }
+ IGraphTransformer::TStatus OptimizeExprInternal(TExprNode::TPtr input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
+ TExprContext& ctx, const TOptimizeExprSettings& settings) try
+ {
+ YQL_ENSURE(optimizer);
+ TOptimizationContext<TCallableOptimizerFast> optCtx(optimizer, nullptr, ctx, settings);
+ bool changed = false;
+ output = OptimizeNode(input, changed, optCtx, 0U);
+
+ if (!output)
+ return IGraphTransformer::TStatus::Error;
+
+ if (changed)
+ return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
- return IGraphTransformer::TStatus::Ok;
- } catch (const std::exception& e) {
- ctx.AddError(ExceptionToIssue(e, ctx.GetPosition(input->Pos())));
- return IGraphTransformer::TStatus::Error;
+ return IGraphTransformer::TStatus::Ok;
+ } catch (const std::exception& e) {
+ ctx.AddError(ExceptionToIssue(e, ctx.GetPosition(input->Pos())));
+ return IGraphTransformer::TStatus::Error;
}
-
- IGraphTransformer::TStatus OptimizeExprInternal(TExprNode::TPtr input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
- TExprContext& ctx, const TOptimizeExprSettings& settings) try
- {
- YQL_ENSURE(optimizer);
- TOptimizationContext<TCallableOptimizerFast> optCtx(optimizer, nullptr, ctx, settings);
- bool changed = false;
- output = OptimizeNode(input, changed, optCtx, 0U);
-
- if (!output)
- return IGraphTransformer::TStatus::Error;
-
- if (changed)
- return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
-
- return IGraphTransformer::TStatus::Ok;
- } catch (const std::exception& e) {
- ctx.AddError(ExceptionToIssue(e, ctx.GetPosition(input->Pos())));
- return IGraphTransformer::TStatus::Error;
- }
}
-IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizer optimizer,
+IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizer optimizer,
TExprContext& ctx, const TOptimizeExprSettings& settings)
{
return OptimizeExprInternal(input, output, optimizer, nullptr, ctx, settings);
}
-IGraphTransformer::TStatus OptimizeExprEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizerEx optimizer,
+IGraphTransformer::TStatus OptimizeExprEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizerEx optimizer,
TExprContext& ctx, const TOptimizeExprSettings& settings)
{
return OptimizeExprInternal(input, output, optimizer, nullptr, ctx, settings);
}
-IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
- TExprContext& ctx, const TOptimizeExprSettings& settings)
-{
- return OptimizeExprInternal(input, output, optimizer, ctx, settings);
-}
-
+IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
+ TExprContext& ctx, const TOptimizeExprSettings& settings)
+{
+ return OptimizeExprInternal(input, output, optimizer, ctx, settings);
+}
+
IGraphTransformer::TStatus RemapExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TNodeOnNodeOwnedMap& remaps,
TExprContext& ctx, const TOptimizeExprSettings& settings)
{
return OptimizeExprInternal<TCallableOptimizer>(input, output, {}, &remaps, ctx, settings);
}
-IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
if (ctx.Step.IsDone(TExprStep::ExpandApplyForLambdas))
return IGraphTransformer::TStatus::Ok;
TOptimizeExprSettings settings(nullptr);
- auto ret = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, bool& changed, TExprContext& ctx) -> TExprNode::TPtr {
+ auto ret = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, bool& changed, TExprContext& ctx) -> TExprNode::TPtr {
if (node->Content() == "WithOptionalArgs") {
if (!EnsureArgsCount(*node, 2, ctx)) {
return nullptr;
@@ -520,9 +520,9 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
return node;
}
- if (node->Content() != "Apply" && node->Content() != "NamedApply")
- return node;
-
+ if (node->Content() != "Apply" && node->Content() != "NamedApply")
+ return node;
+
ui32 optionalArgsCount = 0;
auto lambdaNode = node;
if (lambdaNode->ChildrenSize() > 0 && lambdaNode->Head().IsCallable("WithOptionalArgs")) {
@@ -536,14 +536,14 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
}
if (lambdaNode->Head().Type() != TExprNode::Lambda) {
- return node;
+ return node;
}
auto nullNode = ctx.NewCallable(input->Pos(), "Null", {});
const auto& lambda = lambdaNode->Head();
- const auto& args = lambda.Head();
- TExprNode::TPtr ret;
- if (node->Content() == "Apply") {
+ const auto& args = lambda.Head();
+ TExprNode::TPtr ret;
+ if (node->Content() == "Apply") {
const ui32 maxArgs = args.ChildrenSize();
const ui32 minArgs = args.ChildrenSize() - optionalArgsCount;
const ui32 providedArgs = node->ChildrenSize() - 1;
@@ -554,30 +554,30 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
return nullptr;
}
- TNodeOnNodeOwnedMap replaces;
- replaces.reserve(args.ChildrenSize());
- ui32 i = 0U;
- args.ForEachChild([&](const TExprNode& arg) {
+ TNodeOnNodeOwnedMap replaces;
+ replaces.reserve(args.ChildrenSize());
+ ui32 i = 0U;
+ args.ForEachChild([&](const TExprNode& arg) {
auto value = nullNode;
if (i < providedArgs) {
value = node->ChildPtr(++i);
}
replaces.emplace(&arg, value);
- });
- if (lambda.ChildrenSize() != 2U) {
- ret = ctx.NewList(node->Pos(), ctx.ReplaceNodes(GetLambdaBody(lambda), replaces));
- ret->SetDisclosing();
- } else {
- ret = ctx.ReplaceNodes(lambda.TailPtr(), replaces);
- }
- changed = true;
- } else if (node->Content() == "NamedApply") {
+ });
+ if (lambda.ChildrenSize() != 2U) {
+ ret = ctx.NewList(node->Pos(), ctx.ReplaceNodes(GetLambdaBody(lambda), replaces));
+ ret->SetDisclosing();
+ } else {
+ ret = ctx.ReplaceNodes(lambda.TailPtr(), replaces);
+ }
+ changed = true;
+ } else if (node->Content() == "NamedApply") {
if (!EnsureMinArgsCount(*node, 3, ctx)) {
return nullptr;
}
- if (!EnsureTuple(*node->Child(1), ctx)) {
+ if (!EnsureTuple(*node->Child(1), ctx)) {
return nullptr;
}
@@ -601,8 +601,8 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
}
}
- const auto depArgs = node->ChildrenSize() - 3U;
- const auto totalArgs = depArgs + node->Child(1)->ChildrenSize();
+ const auto depArgs = node->ChildrenSize() - 3U;
+ const auto totalArgs = depArgs + node->Child(1)->ChildrenSize();
if (totalArgs < args.ChildrenSize() - optionalArgsCount) {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Too few arguments, lambda has "
<< args.ChildrenSize() << " arguments with optional "<< optionalArgsCount << " arguments, but got: " << totalArgs));
@@ -610,12 +610,12 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
}
ui32 posArgs = Min(args.ChildrenSize(), node->Child(1)->ChildrenSize());
- TNodeOnNodeOwnedMap replaces;
+ TNodeOnNodeOwnedMap replaces;
replaces.reserve(args.ChildrenSize());
for (ui32 i = 0; i < posArgs; ++i) {
- replaces.emplace(args.Child(i), node->Child(1)->ChildPtr(i));
- }
-
+ replaces.emplace(args.Child(i), node->Child(1)->ChildPtr(i));
+ }
+
if (posArgs == node->Child(1)->ChildrenSize()) {
for (ui32 i = 3; i < node->ChildrenSize(); ++i) {
auto index = i - 3 + node->Child(1)->ChildrenSize();
@@ -631,120 +631,120 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
replaces.emplace(args.Child(i), nullNode);
}
- if (lambda.ChildrenSize() > 2U) {
- ret = ctx.NewList(node->Pos(), ctx.ReplaceNodes(GetLambdaBody(lambda), replaces));
- ret->SetDisclosing();
- } else {
- ret = ctx.ReplaceNodes(lambda.TailPtr(), replaces);
- }
- changed = true;
+ if (lambda.ChildrenSize() > 2U) {
+ ret = ctx.NewList(node->Pos(), ctx.ReplaceNodes(GetLambdaBody(lambda), replaces));
+ ret->SetDisclosing();
+ } else {
+ ret = ctx.ReplaceNodes(lambda.TailPtr(), replaces);
+ }
+ changed = true;
}
return ret;
}, ctx, settings);
if (ret.Level == IGraphTransformer::TStatus::Ok) {
- ret = ret.Combine(OptimizeExpr(output, output, [&](const TExprNode::TPtr& node, bool& changed, TExprContext& ctx) -> TExprNode::TPtr {
- if (node->Content() == "Combine") {
- if (!EnsureMinArgsCount(*node, 1, ctx)) {
- return nullptr;
- }
-
- ui32 flags = 0U;
+ ret = ret.Combine(OptimizeExpr(output, output, [&](const TExprNode::TPtr& node, bool& changed, TExprContext& ctx) -> TExprNode::TPtr {
+ if (node->Content() == "Combine") {
+ if (!EnsureMinArgsCount(*node, 1, ctx)) {
+ return nullptr;
+ }
+
+ ui32 flags = 0U;
TString content;
- for (const auto& child : node->Children()) {
- if (!EnsureAtom(*child, ctx)) {
- return nullptr;
- }
-
- const auto f = child->Flags();
-
- if ((TNodeFlags::MultilineContent | TNodeFlags::BinaryContent) & f) {
+ for (const auto& child : node->Children()) {
+ if (!EnsureAtom(*child, ctx)) {
+ return nullptr;
+ }
+
+ const auto f = child->Flags();
+
+ if ((TNodeFlags::MultilineContent | TNodeFlags::BinaryContent) & f) {
ctx.AddError(TIssue(ctx.GetPosition(child->Pos()), "Can't combine binary or multiline atoms."));
- return nullptr;
- }
-
- content += child->Content();
- flags |= f;
- }
-
- changed = true;
- return ctx.NewAtom(node->Pos(), content, flags);
- } else if (node->Content() == "Nth") {
- if (!EnsureArgsCount(*node, 2, ctx)) {
- return nullptr;
- }
-
- if (!node->Tail().IsAtom()) {
+ return nullptr;
+ }
+
+ content += child->Content();
+ flags |= f;
+ }
+
+ changed = true;
+ return ctx.NewAtom(node->Pos(), content, flags);
+ } else if (node->Content() == "Nth") {
+ if (!EnsureArgsCount(*node, 2, ctx)) {
+ return nullptr;
+ }
+
+ if (!node->Tail().IsAtom()) {
return node;
- }
-
- if (node->Head().Type() != TExprNode::List) {
- return node;
- }
-
- ui32 index = 0U;
- if (const auto& indexValue = node->Tail().Content(); !TryFromString(indexValue, index)) {
+ }
+
+ if (node->Head().Type() != TExprNode::List) {
+ return node;
+ }
+
+ ui32 index = 0U;
+ if (const auto& indexValue = node->Tail().Content(); !TryFromString(indexValue, index)) {
ctx.AddError(TIssue(ctx.GetPosition(node->Child(1)->Pos()), TStringBuilder() << "Index '" << indexValue << "' isn't UI32."));
- return nullptr;
- }
-
- if (const auto size = node->Head().ChildrenSize(); size <= index) {
- ctx.AddError(TIssue(ctx.GetPosition(node->Tail().Pos()), TStringBuilder() << "Index too large: (" << index << " >= " << size << ")."));
- return nullptr;
- }
-
- changed = true;
- return node->Head().ChildPtr(index);
- } else if (node->Content() == "NthArg") {
- if (!EnsureArgsCount(*node, 2, ctx)) {
- return nullptr;
- }
-
- if (!EnsureAtom(node->Head(), ctx)) {
- return nullptr;
- }
-
- if (!EnsureCallable(node->Tail(), ctx)) {
- return nullptr;
- }
-
+ return nullptr;
+ }
+
+ if (const auto size = node->Head().ChildrenSize(); size <= index) {
+ ctx.AddError(TIssue(ctx.GetPosition(node->Tail().Pos()), TStringBuilder() << "Index too large: (" << index << " >= " << size << ")."));
+ return nullptr;
+ }
+
+ changed = true;
+ return node->Head().ChildPtr(index);
+ } else if (node->Content() == "NthArg") {
+ if (!EnsureArgsCount(*node, 2, ctx)) {
+ return nullptr;
+ }
+
+ if (!EnsureAtom(node->Head(), ctx)) {
+ return nullptr;
+ }
+
+ if (!EnsureCallable(node->Tail(), ctx)) {
+ return nullptr;
+ }
+
if (node->Tail().IsCallable("Apply")) {
return node;
}
- ui32 index = 0U;
- if (const auto& indexValue = node->Head().Content(); !TryFromString(indexValue, index)) {
- ctx.AddError(TIssue(ctx.GetPosition(node->Head().Pos()), TStringBuilder() << "Index '" << indexValue << "' isn't UI32."));
- return nullptr;
- }
-
- if (const auto size = node->Tail().ChildrenSize(); size <= index) {
- ctx.AddError(TIssue(ctx.GetPosition(node->Head().Pos()), TStringBuilder() << "Index too large: (" << index << " >= " << size << ")."));
- return nullptr;
- }
-
- changed = true;
- return node->Tail().ChildPtr(index);
+ ui32 index = 0U;
+ if (const auto& indexValue = node->Head().Content(); !TryFromString(indexValue, index)) {
+ ctx.AddError(TIssue(ctx.GetPosition(node->Head().Pos()), TStringBuilder() << "Index '" << indexValue << "' isn't UI32."));
+ return nullptr;
+ }
+
+ if (const auto size = node->Tail().ChildrenSize(); size <= index) {
+ ctx.AddError(TIssue(ctx.GetPosition(node->Head().Pos()), TStringBuilder() << "Index too large: (" << index << " >= " << size << ")."));
+ return nullptr;
+ }
+
+ changed = true;
+ return node->Tail().ChildPtr(index);
}
else if (node->Content() == "Seq!") {
if (!EnsureMinArgsCount(*node, 1, ctx)) {
return nullptr;
}
- auto world = node->HeadPtr();
+ auto world = node->HeadPtr();
for (ui32 i = 1; i < node->ChildrenSize(); ++i) {
- const auto lambda = node->Child(i);
+ const auto lambda = node->Child(i);
if (!EnsureLambda(*lambda, ctx)) {
return nullptr;
}
- const auto& lambdaArgs = lambda->Head();
- if (!EnsureArgsCount(lambdaArgs, 1, ctx)) {
+ const auto& lambdaArgs = lambda->Head();
+ if (!EnsureArgsCount(lambdaArgs, 1, ctx)) {
return nullptr;
}
- world = ctx.ReplaceNode(lambda->TailPtr(), lambdaArgs.Head(), std::move(world));
+ world = ctx.ReplaceNode(lambda->TailPtr(), lambdaArgs.Head(), std::move(world));
}
changed = true;
@@ -804,31 +804,31 @@ IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::
changed = true;
return merged;
} else {
- return node;
+ return node;
}
}, ctx, settings));
- }
-
- if (ret.Level == IGraphTransformer::TStatus::Ok) {
+ }
+
+ if (ret.Level == IGraphTransformer::TStatus::Ok) {
ctx.Step.Done(TExprStep::ExpandApplyForLambdas);
}
return ret;
}
-TExprNode::TPtr ApplySyncListToWorld(const TExprNode::TPtr& main, const TSyncMap& syncList, TExprContext& ctx) {
+TExprNode::TPtr ApplySyncListToWorld(const TExprNode::TPtr& main, const TSyncMap& syncList, TExprContext& ctx) {
if (syncList.empty()) {
return main;
}
- using TPair = std::pair<TExprNode::TPtr, ui64>;
+ using TPair = std::pair<TExprNode::TPtr, ui64>;
TVector<TPair> sortedList(syncList.cbegin(), syncList.cend());
TExprNode::TListType syncChildren;
syncChildren.push_back(main);
Sort(sortedList, [](const TPair& x, const TPair& y) { return x.second < y.second; });
for (auto x : sortedList) {
if (x.first->IsCallable(RightName)) {
- auto world = ctx.NewCallable(main->Pos(), LeftName, { x.first->HeadPtr() });
+ auto world = ctx.NewCallable(main->Pos(), LeftName, { x.first->HeadPtr() });
syncChildren.push_back(world);
} else if (x.first->GetTypeAnn()->GetKind() == ETypeAnnotationKind::World) {
syncChildren.push_back(x.first);
@@ -838,11 +838,11 @@ TExprNode::TPtr ApplySyncListToWorld(const TExprNode::TPtr& main, const TSyncMap
}
}
- return ctx.NewCallable(main->Pos(), SyncName, std::move(syncChildren));
+ return ctx.NewCallable(main->Pos(), SyncName, std::move(syncChildren));
}
-void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func) {
- TNodeSet visitedNodes;
+void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func) {
+ TNodeSet visitedNodes;
VisitExprInternal(root, func, {}, visitedNodes);
}
@@ -851,8 +851,8 @@ void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& preFunc, co
VisitExprInternal(root, preFunc, postFunc, visitedNodes);
}
-void VisitExpr(const TExprNode& root, const TExprVisitRefFunc& func) {
- TNodeSet visitedNodes;
+void VisitExpr(const TExprNode& root, const TExprVisitRefFunc& func) {
+ TNodeSet visitedNodes;
VisitExprInternal(root, func, {}, visitedNodes);
}
@@ -879,14 +879,14 @@ void VisitExprByFirst(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func
VisitExprByFirstInternal(root, func, {}, visitedNodes);
}
-TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate) {
- TExprNode::TPtr result;
- VisitExpr(root, [&result, &predicate] (const TExprNode::TPtr& node) {
+TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate) {
+ TExprNode::TPtr result;
+ VisitExpr(root, [&result, &predicate] (const TExprNode::TPtr& node) {
if (result)
return false;
if (predicate(node)) {
- result = node;
+ result = node;
return false;
}
@@ -896,52 +896,52 @@ TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& p
return result;
}
-TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate) {
- TExprNode::TPtr result;
- VisitExpr(root, filter, [&result, &predicate] (const TExprNode::TPtr& node) {
- if (result)
- return false;
-
- if (predicate(node)) {
- result = node;
- return false;
- }
-
- return true;
- });
-
- return result;
-}
-
-TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate) {
- TExprNode::TListType result;
- VisitExpr(root, [&result, &predicate] (const TExprNode::TPtr& node) {
- if (predicate(node)) {
- result.emplace_back(node);
- }
-
- return true;
- });
-
- return result;
-}
-
-TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate) {
- TExprNode::TListType result;
- VisitExpr(root, filter, [&result, &predicate] (const TExprNode::TPtr& node) {
- if (predicate(node)) {
- result.emplace_back(node);
- }
-
- return true;
- });
-
- return result;
-}
-
-std::pair<TExprNode::TPtr, bool> FindSharedNode(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate)
+TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate) {
+ TExprNode::TPtr result;
+ VisitExpr(root, filter, [&result, &predicate] (const TExprNode::TPtr& node) {
+ if (result)
+ return false;
+
+ if (predicate(node)) {
+ result = node;
+ return false;
+ }
+
+ return true;
+ });
+
+ return result;
+}
+
+TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate) {
+ TExprNode::TListType result;
+ VisitExpr(root, [&result, &predicate] (const TExprNode::TPtr& node) {
+ if (predicate(node)) {
+ result.emplace_back(node);
+ }
+
+ return true;
+ });
+
+ return result;
+}
+
+TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate) {
+ TExprNode::TListType result;
+ VisitExpr(root, filter, [&result, &predicate] (const TExprNode::TPtr& node) {
+ if (predicate(node)) {
+ result.emplace_back(node);
+ }
+
+ return true;
+ });
+
+ return result;
+}
+
+std::pair<TExprNode::TPtr, bool> FindSharedNode(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate)
{
- TNodeSet nodes, visited;
+ TNodeSet nodes, visited;
VisitExpr(firstRoot, [&nodes, &predicate] (const TExprNode::TPtr& node) {
if (predicate(node)) {
nodes.insert(node.Get());
@@ -950,40 +950,40 @@ std::pair<TExprNode::TPtr, bool> FindSharedNode(const TExprNode::TPtr& firstRoot
return true;
});
- TExprNode::TPtr result;
- bool primary = true;
- VisitExprByPrimaryBranch(secondRoot, [&nodes, &result] (const TExprNode::TPtr& node) {
- if (result)
- return false;
-
- if (nodes.find(node.Get()) != nodes.end()) {
- result = node;
- return false;
- }
-
- return true;
- }, primary, visited);
-
- return std::make_pair(std::move(result), primary);
-}
-
-bool HaveSharedNodes(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate)
-{
- return bool(FindSharedNode(firstRoot, secondRoot, predicate).first);
+ TExprNode::TPtr result;
+ bool primary = true;
+ VisitExprByPrimaryBranch(secondRoot, [&nodes, &result] (const TExprNode::TPtr& node) {
+ if (result)
+ return false;
+
+ if (nodes.find(node.Get()) != nodes.end()) {
+ result = node;
+ return false;
+ }
+
+ return true;
+ }, primary, visited);
+
+ return std::make_pair(std::move(result), primary);
+}
+
+bool HaveSharedNodes(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate)
+{
+ return bool(FindSharedNode(firstRoot, secondRoot, predicate).first);
+}
+
+TExprNode::TPtr CloneCompleteFlow(TExprNode::TPtr&& node, TExprContext& ctx) {
+ const TExprNode* original = nullptr;
+ TExprNode::TPtr copy;
+ VisitExpr(*node, [&](const TExprNode& child) {
+ if (const auto kind = child.GetTypeAnn()->GetKind(); (ETypeAnnotationKind::Stream == kind || ETypeAnnotationKind::Flow == kind) && child.IsComplete() && child.IsCallable() && original != &child) {
+ original = &child;
+ copy = ctx.ShallowCopy(child);
+ return true;
+ }
+ return false;
+ });
+ return original ? ctx.ReplaceNode(std::move(node), *original, std::move(copy)) : std::move(node);
}
-TExprNode::TPtr CloneCompleteFlow(TExprNode::TPtr&& node, TExprContext& ctx) {
- const TExprNode* original = nullptr;
- TExprNode::TPtr copy;
- VisitExpr(*node, [&](const TExprNode& child) {
- if (const auto kind = child.GetTypeAnn()->GetKind(); (ETypeAnnotationKind::Stream == kind || ETypeAnnotationKind::Flow == kind) && child.IsComplete() && child.IsCallable() && original != &child) {
- original = &child;
- copy = ctx.ShallowCopy(child);
- return true;
- }
- return false;
- });
- return original ? ctx.ReplaceNode(std::move(node), *original, std::move(copy)) : std::move(node);
}
-
-}
diff --git a/ydb/library/yql/core/yql_expr_optimize.h b/ydb/library/yql/core/yql_expr_optimize.h
index 1e4edc03d2..ae5f0dea38 100644
--- a/ydb/library/yql/core/yql_expr_optimize.h
+++ b/ydb/library/yql/core/yql_expr_optimize.h
@@ -1,24 +1,24 @@
#pragma once
#include <ydb/library/yql/ast/yql_expr.h>
#include "yql_graph_transformer.h"
-#include "yql_type_annotation.h"
+#include "yql_type_annotation.h"
#include <util/generic/hash_set.h>
#include <functional>
namespace NYql {
-typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&)> TCallableOptimizer;
-typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, bool&, TExprContext&)> TCallableOptimizerFast;
+typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&)> TCallableOptimizer;
+typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, bool&, TExprContext&)> TCallableOptimizerFast;
+
+typedef std::unordered_set<ui64> TProcessedNodesSet;
-typedef std::unordered_set<ui64> TProcessedNodesSet;
-
struct TOptimizeExprSettings {
explicit TOptimizeExprSettings(TTypeAnnotationContext* types)
: Types(types)
{}
bool VisitChanges = false;
- TProcessedNodesSet* ProcessedNodes = nullptr;
+ TProcessedNodesSet* ProcessedNodes = nullptr;
bool VisitStarted = false;
IGraphTransformer* CustomInstantTypeTransformer = nullptr;
bool VisitLambdas = true;
@@ -26,12 +26,12 @@ struct TOptimizeExprSettings {
bool VisitTuples = false;
};
-IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizer optimizer,
+IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizer optimizer,
TExprContext& ctx, const TOptimizeExprSettings& settings);
-IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
+IGraphTransformer::TStatus OptimizeExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TCallableOptimizerFast& optimizer,
TExprContext& ctx, const TOptimizeExprSettings& settings);
-
+
IGraphTransformer::TStatus RemapExpr(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TNodeOnNodeOwnedMap& remaps,
TExprContext& ctx, const TOptimizeExprSettings& settings);
@@ -39,39 +39,39 @@ IGraphTransformer::TStatus RemapExpr(const TExprNode::TPtr& input, TExprNode::TP
class IOptimizationContext {
public:
virtual ~IOptimizationContext() = default;
- virtual void RemapNode(const TExprNode& fromNode, const TExprNode::TPtr& toNode) = 0;
+ virtual void RemapNode(const TExprNode& fromNode, const TExprNode::TPtr& toNode) = 0;
};
-typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&, IOptimizationContext&)> TCallableOptimizerEx;
+typedef std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&, IOptimizationContext&)> TCallableOptimizerEx;
-IGraphTransformer::TStatus OptimizeExprEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizerEx optimizer,
+IGraphTransformer::TStatus OptimizeExprEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TCallableOptimizerEx optimizer,
TExprContext& ctx, const TOptimizeExprSettings& settings);
-IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx);
-TExprNode::TPtr ApplySyncListToWorld(const TExprNode::TPtr& main, const TSyncMap& syncList, TExprContext& ctx);
+IGraphTransformer::TStatus ExpandApply(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx);
+TExprNode::TPtr ApplySyncListToWorld(const TExprNode::TPtr& main, const TSyncMap& syncList, TExprContext& ctx);
-typedef std::function<bool (const TExprNode::TPtr&)> TExprVisitPtrFunc;
-typedef std::function<bool (const TExprNode&)> TExprVisitRefFunc;
+typedef std::function<bool (const TExprNode::TPtr&)> TExprVisitPtrFunc;
+typedef std::function<bool (const TExprNode&)> TExprVisitRefFunc;
-void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func);
+void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func);
void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& preFunc, const TExprVisitPtrFunc& postFunc);
void VisitExpr(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func, TNodeSet& visitedNodes);
-void VisitExpr(const TExprNode& root, const TExprVisitRefFunc& func);
+void VisitExpr(const TExprNode& root, const TExprVisitRefFunc& func);
void VisitExprByFirst(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func);
void VisitExprByFirst(const TExprNode::TPtr& root, const TExprVisitPtrFunc& preFunc, const TExprVisitPtrFunc& postFunc);
void VisitExprByFirst(const TExprNode::TPtr& root, const TExprVisitPtrFunc& func, TNodeSet& visitedNodes);
void VisitExprByFirst(const TExprNode& root, const TExprVisitRefFunc& func);
-TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate);
-TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate);
-
-TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate);
-TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate);
-
-std::pair<TExprNode::TPtr, bool> FindSharedNode(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate);
-bool HaveSharedNodes(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate);
-
-TExprNode::TPtr CloneCompleteFlow(TExprNode::TPtr&& node, TExprContext& ctx);
-
+TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate);
+TExprNode::TPtr FindNode(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate);
+
+TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& predicate);
+TExprNode::TListType FindNodes(const TExprNode::TPtr& root, const TExprVisitPtrFunc& filter, const TExprVisitPtrFunc& predicate);
+
+std::pair<TExprNode::TPtr, bool> FindSharedNode(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate);
+bool HaveSharedNodes(const TExprNode::TPtr& firstRoot, const TExprNode::TPtr& secondRoot, const TExprVisitPtrFunc& predicate);
+
+TExprNode::TPtr CloneCompleteFlow(TExprNode::TPtr&& node, TExprContext& ctx);
+
}
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.cpp b/ydb/library/yql/core/yql_expr_type_annotation.cpp
index 6ba0593cec..f2b793af8d 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.cpp
+++ b/ydb/library/yql/core/yql_expr_type_annotation.cpp
@@ -43,19 +43,19 @@ TExprNode::TPtr RebuildDict(const TExprNode::TPtr& node, const TExprNode::TPtr&
.Param("item")
.Callable("Nth")
.Arg(0, "item")
- .Atom(1, "0", TNodeFlags::Default)
+ .Atom(1, "0", TNodeFlags::Default)
.Seal()
.Seal()
.Lambda(2) // payloadExtractor
.Param("item")
.Callable("Nth")
.Arg(0, "item")
- .Atom(1, "1", TNodeFlags::Default)
+ .Atom(1, "1", TNodeFlags::Default)
.Seal()
.Seal()
.List(3)
- .Atom(0, "Hashed", TNodeFlags::Default)
- .Atom(1, "One", TNodeFlags::Default)
+ .Atom(0, "Hashed", TNodeFlags::Default)
+ .Atom(1, "One", TNodeFlags::Default)
.Seal()
.Seal()
.Build();
@@ -82,26 +82,26 @@ TExprNode::TPtr RebuildVariant(const TExprNode::TPtr& node,
return ret;
}
-IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr& node,
+IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr& node,
const TTypeAnnotationNode& sourceType, const TTypeAnnotationNode& expectedType, TConvertFlags flags) {
-
+
if (IsSameAnnotation(sourceType, expectedType)) {
return IGraphTransformer::TStatus::Ok;
}
- if (expectedType.GetKind() == ETypeAnnotationKind::Stream) {
- switch (sourceType.GetKind()) {
- case ETypeAnnotationKind::List:
- case ETypeAnnotationKind::Flow:
- if (const auto itemType = expectedType.Cast<TStreamExprType>()->GetItemType(); IsSameAnnotation(*itemType, *GetSeqItemType(&sourceType))) {
- node = ctx.NewCallable(node->Pos(), "ToStream", {std::move(node)});
- return IGraphTransformer::TStatus::Repeat;
- }
+ if (expectedType.GetKind() == ETypeAnnotationKind::Stream) {
+ switch (sourceType.GetKind()) {
+ case ETypeAnnotationKind::List:
+ case ETypeAnnotationKind::Flow:
+ if (const auto itemType = expectedType.Cast<TStreamExprType>()->GetItemType(); IsSameAnnotation(*itemType, *GetSeqItemType(&sourceType))) {
+ node = ctx.NewCallable(node->Pos(), "ToStream", {std::move(node)});
+ return IGraphTransformer::TStatus::Repeat;
+ }
break;
- default: break;
- }
- }
-
+ default: break;
+ }
+ }
+
if (expectedType.GetKind() == ETypeAnnotationKind::Optional) {
auto nextType = expectedType.Cast<TOptionalExprType>()->GetItemType();
auto originalNode = node;
@@ -114,7 +114,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
node = originalNode;
if (node->IsCallable("Just")) {
auto sourceItemType = sourceType.Cast<TOptionalExprType>()->GetItemType();
- auto value = node->HeadRef();
+ auto value = node->HeadRef();
auto status = TryConvertToImpl(ctx, value, *sourceItemType, *nextType, flags);
if (status.Level != IGraphTransformer::TStatus::Error) {
node = ctx.NewCallable(node->Pos(), "Just", { value });
@@ -128,9 +128,9 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
if (status.Level != IGraphTransformer::TStatus::Error) {
auto lambda = ctx.NewLambda(node->Pos(),
ctx.NewArguments(node->Pos(), { originalArg }),
- std::move(arg));
+ std::move(arg));
- node = ctx.NewCallable(node->Pos(), "Map", { node, std::move(lambda) });
+ node = ctx.NewCallable(node->Pos(), "Map", { node, std::move(lambda) });
return IGraphTransformer::TStatus::Repeat;
}
}
@@ -156,43 +156,43 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
return IGraphTransformer::TStatus::Repeat;
}
} else if (expectedType.GetKind() == ETypeAnnotationKind::Resource && sourceType.GetKind() == ETypeAnnotationKind::Data) {
- const auto fromSlot = sourceType.Cast<TDataExprType>()->GetSlot();
- const auto to = expectedType.Cast<TResourceExprType>()->GetTag();
- if ((fromSlot == EDataSlot::Yson || fromSlot == EDataSlot::Json) && to == "Yson2.Node") {
- node = ctx.Builder(node->Pos())
- .Callable("Apply")
- .Callable(0, "Udf")
- .Atom(0, fromSlot == EDataSlot::Yson ? "Yson2.Parse" : "Yson2.ParseJson", TNodeFlags::Default)
- .Callable(1, "Void")
- .Seal()
- .Callable(2, "TupleType")
- .Callable(0, "TupleType")
- .Callable(0, "DataType")
- .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
- .Seal()
- .Seal()
- .Callable(1, "StructType")
- .Seal()
- .Callable(2, "TupleType")
- .Seal()
- .Seal()
- .Seal()
- .Add(1, std::move(node))
- .Seal()
- .Build();
-
- return IGraphTransformer::TStatus::Repeat;
- } else if ((fromSlot == EDataSlot::Yson || fromSlot == EDataSlot::Json) && to == "Yson.Node") {
+ const auto fromSlot = sourceType.Cast<TDataExprType>()->GetSlot();
+ const auto to = expectedType.Cast<TResourceExprType>()->GetTag();
+ if ((fromSlot == EDataSlot::Yson || fromSlot == EDataSlot::Json) && to == "Yson2.Node") {
+ node = ctx.Builder(node->Pos())
+ .Callable("Apply")
+ .Callable(0, "Udf")
+ .Atom(0, fromSlot == EDataSlot::Yson ? "Yson2.Parse" : "Yson2.ParseJson", TNodeFlags::Default)
+ .Callable(1, "Void")
+ .Seal()
+ .Callable(2, "TupleType")
+ .Callable(0, "TupleType")
+ .Callable(0, "DataType")
+ .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Callable(1, "StructType")
+ .Seal()
+ .Callable(2, "TupleType")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, std::move(node))
+ .Seal()
+ .Build();
+
+ return IGraphTransformer::TStatus::Repeat;
+ } else if ((fromSlot == EDataSlot::Yson || fromSlot == EDataSlot::Json) && to == "Yson.Node") {
node = ctx.Builder(node->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, fromSlot == EDataSlot::Yson ? "Yson.Parse" : "Yson.ParseJson", TNodeFlags::Default)
+ .Atom(0, fromSlot == EDataSlot::Yson ? "Yson.Parse" : "Yson.ParseJson", TNodeFlags::Default)
.Callable(1, "Void")
.Seal()
.Callable(2, "TupleType")
.Callable(0, "TupleType")
.Callable(0, "DataType")
- .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
+ .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
.Seal()
.Seal()
.Callable(1, "StructType")
@@ -201,23 +201,23 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
.Seal()
.Seal()
.Seal()
- .Add(1, std::move(node))
+ .Add(1, std::move(node))
.Seal()
.Build();
return IGraphTransformer::TStatus::Repeat;
- } else if ((GetDataTypeInfo(fromSlot).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)) && to == "DateTime2.TM") {
+ } else if ((GetDataTypeInfo(fromSlot).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)) && to == "DateTime2.TM") {
node = ctx.Builder(node->Pos())
.Callable("Apply")
.Callable(0, "Udf")
- .Atom(0, "DateTime2.Split", TNodeFlags::Default)
+ .Atom(0, "DateTime2.Split", TNodeFlags::Default)
.Callable(1, "Void")
.Seal()
.Callable(2, "TupleType")
.Callable(0, "TupleType")
.Callable(0, "DataType")
- .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
+ .Atom(0, sourceType.Cast<TDataExprType>()->GetName(), TNodeFlags::Default)
.Seal()
.Seal()
.Callable(1, "StructType")
@@ -226,7 +226,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
.Seal()
.Seal()
.Seal()
- .Add(1, std::move(node))
+ .Add(1, std::move(node))
.Seal()
.Build();
@@ -257,30 +257,30 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
return IGraphTransformer::TStatus::Repeat;
}
} else if (expectedType.GetKind() == ETypeAnnotationKind::Data && sourceType.GetKind() == ETypeAnnotationKind::Data) {
- const auto from = sourceType.Cast<TDataExprType>()->GetSlot();
- const auto to = expectedType.Cast<TDataExprType>()->GetSlot();
+ const auto from = sourceType.Cast<TDataExprType>()->GetSlot();
+ const auto to = expectedType.Cast<TDataExprType>()->GetSlot();
if (from == EDataSlot::Utf8 && to == EDataSlot::String) {
- node = ctx.NewCallable(node->Pos(), "ToString", { std::move(node) });
+ node = ctx.NewCallable(node->Pos(), "ToString", { std::move(node) });
return IGraphTransformer::TStatus::Repeat;
}
if (node->IsCallable("String") && to == EDataSlot::Utf8) {
- if (const auto atom = node->Head().Content(); IsUtf8(atom)) {
- node = ctx.RenameNode(*node, "Utf8");
+ if (const auto atom = node->Head().Content(); IsUtf8(atom)) {
+ node = ctx.RenameNode(*node, "Utf8");
return IGraphTransformer::TStatus::Repeat;
}
}
- if (node->IsCallable({"String", "Utf8"}) && to == EDataSlot::Yson) {
- if (const auto atom = node->Head().Content(); NDom::IsValidYson(atom)) {
- node = ctx.RenameNode(*node, "Yson");
+ if (node->IsCallable({"String", "Utf8"}) && to == EDataSlot::Yson) {
+ if (const auto atom = node->Head().Content(); NDom::IsValidYson(atom)) {
+ node = ctx.RenameNode(*node, "Yson");
return IGraphTransformer::TStatus::Repeat;
}
}
- if (node->IsCallable({"String", "Utf8"}) && to == EDataSlot::Json) {
- if (const auto atom = node->Head().Content(); NDom::IsValidJson(atom)) {
- node = ctx.RenameNode(*node, "Json");
+ if (node->IsCallable({"String", "Utf8"}) && to == EDataSlot::Json) {
+ if (const auto atom = node->Head().Content(); NDom::IsValidJson(atom)) {
+ node = ctx.RenameNode(*node, "Json");
return IGraphTransformer::TStatus::Repeat;
}
}
@@ -309,7 +309,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
} else if (IsDataTypeIntegral(from) && to == EDataSlot::Timestamp) {
node = ctx.Builder(node->Pos())
.Callable("UnsafeTimestampCast")
- .Callable(0, "BitCast")
+ .Callable(0, "BitCast")
.Add(0, node)
.Atom(1, "Uint64")
.Seal()
@@ -324,10 +324,10 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
bool negate = false;
for (;;) {
if (current->IsCallable("Plus")) {
- current = current->HeadPtr();
+ current = current->HeadPtr();
}
else if (current->IsCallable("Minus")) {
- current = current->HeadPtr();
+ current = current->HeadPtr();
negate = !negate;
}
else {
@@ -335,7 +335,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
}
}
- if (const auto maybeInt = TMaybeNode<TCoIntegralCtor>(current)) {
+ if (const auto maybeInt = TMaybeNode<TCoIntegralCtor>(current)) {
auto allowIntergral = AllowIntegralConversion(maybeInt.Cast(), negate, to);
allow = allow || allowIntergral;
isSafe = allowIntergral;
@@ -360,13 +360,13 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
}
}
- const auto pos = node->Pos();
- auto type = ExpandType(pos, expectedType, ctx);
- node = ctx.NewCallable(pos, useCast ? "SafeCast" : "Convert", {std::move(node), std::move(type)});
+ const auto pos = node->Pos();
+ auto type = ExpandType(pos, expectedType, ctx);
+ node = ctx.NewCallable(pos, useCast ? "SafeCast" : "Convert", {std::move(node), std::move(type)});
return IGraphTransformer::TStatus::Repeat;
}
}
- else if (expectedType.GetKind() == ETypeAnnotationKind::Struct && node->IsCallable({"Struct", "AsStruct"})) {
+ else if (expectedType.GetKind() == ETypeAnnotationKind::Struct && node->IsCallable({"Struct", "AsStruct"})) {
auto from = sourceType.Cast<TStructExprType>();
auto to = expectedType.Cast<TStructExprType>();
THashMap<TString, TExprNode::TPtr> columnTransforms;
@@ -388,7 +388,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
++usedFields;
auto oldType = from->GetItems()[*pos];
for (ui32 i = node->IsCallable("Struct") ? 1 : 0; i < node->ChildrenSize(); ++i) {
- if (node->Child(i)->Head().Content() == newField->GetName()) {
+ if (node->Child(i)->Head().Content() == newField->GetName()) {
field = node->Child(i)->ChildPtr(1);
break;
}
@@ -414,7 +414,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
ctx.NewAtom(node->Pos(), child.first), child.second }));
}
- node = ctx.NewCallable(node->Pos(), "AsStruct", std::move(nodeChildren));
+ node = ctx.NewCallable(node->Pos(), "AsStruct", std::move(nodeChildren));
return IGraphTransformer::TStatus::Repeat;
}
else if (expectedType.GetKind() == ETypeAnnotationKind::Struct && sourceType.GetKind() == ETypeAnnotationKind::Struct) {
@@ -469,7 +469,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
ctx.NewAtom(node->Pos(), child.first), child.second }));
}
- node = ctx.NewCallable(node->Pos(), "AsStruct", std::move(nodeChildren));
+ node = ctx.NewCallable(node->Pos(), "AsStruct", std::move(nodeChildren));
return IGraphTransformer::TStatus::Repeat;
}
else if (expectedType.GetKind() == ETypeAnnotationKind::Variant && node->IsCallable("Variant")) {
@@ -498,7 +498,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
if (toTargetIndex.Empty()) {
return IGraphTransformer::TStatus::Error;
}
- auto targetItem = node->HeadPtr();
+ auto targetItem = node->HeadPtr();
auto status = TryConvertToImpl(
ctx, targetItem,
*fromUnderlying->GetItems()[*fromTargetIndex]->GetItemType(),
@@ -545,7 +545,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
}
auto targetIndex = FromString<size_t>(node->Child(1)->Content());
- auto targetItem = node->HeadPtr();
+ auto targetItem = node->HeadPtr();
auto status = TryConvertToImpl(
ctx, targetItem,
*fromUnderlying->GetItems()[targetIndex],
@@ -658,7 +658,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
arg = ctx.Builder(node->Pos())
.Callable("Variant")
.Add(0, std::move(arg))
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Add(2, outTypeExpr)
.Seal()
.Build();
@@ -679,74 +679,74 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
else if (expectedType.GetKind() == ETypeAnnotationKind::Tuple && node->IsList()) {
auto from = sourceType.Cast<TTupleExprType>();
auto to = expectedType.Cast<TTupleExprType>();
- if (from->GetSize() <= to->GetSize()) {
+ if (from->GetSize() <= to->GetSize()) {
TExprNode::TListType valueTransforms;
- valueTransforms.reserve(to->GetSize());
+ valueTransforms.reserve(to->GetSize());
for (ui32 i = 0; i < from->GetSize(); ++i) {
- const auto oldType = from->GetItems()[i];
- const auto newType = to->GetItems()[i];
- auto value = node->ChildPtr(i);
- if (const auto status = TryConvertToImpl(ctx, value, *oldType, *newType, flags); status.Level == IGraphTransformer::TStatus::Error) {
+ const auto oldType = from->GetItems()[i];
+ const auto newType = to->GetItems()[i];
+ auto value = node->ChildPtr(i);
+ if (const auto status = TryConvertToImpl(ctx, value, *oldType, *newType, flags); status.Level == IGraphTransformer::TStatus::Error) {
return status;
}
valueTransforms.push_back(value);
}
- for (auto i = from->GetSize(); i < to->GetSize(); ++i) {
- switch (const auto newType = to->GetItems()[i]; newType->GetKind()) {
- case ETypeAnnotationKind::Optional:
- valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *newType, ctx)}));
- continue;
- case ETypeAnnotationKind::Null:
- valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Null", {}));
- continue;
- default:
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- node = ctx.NewList(node->Pos(), std::move(valueTransforms));
+ for (auto i = from->GetSize(); i < to->GetSize(); ++i) {
+ switch (const auto newType = to->GetItems()[i]; newType->GetKind()) {
+ case ETypeAnnotationKind::Optional:
+ valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *newType, ctx)}));
+ continue;
+ case ETypeAnnotationKind::Null:
+ valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Null", {}));
+ continue;
+ default:
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ node = ctx.NewList(node->Pos(), std::move(valueTransforms));
return IGraphTransformer::TStatus::Repeat;
}
}
else if (expectedType.GetKind() == ETypeAnnotationKind::Tuple && sourceType.GetKind() == ETypeAnnotationKind::Tuple) {
- const auto from = sourceType.Cast<TTupleExprType>();
- const auto to = expectedType.Cast<TTupleExprType>();
- if (from->GetSize() <= to->GetSize()) {
+ const auto from = sourceType.Cast<TTupleExprType>();
+ const auto to = expectedType.Cast<TTupleExprType>();
+ if (from->GetSize() <= to->GetSize()) {
TExprNode::TListType valueTransforms;
- valueTransforms.reserve(to->GetSize());
+ valueTransforms.reserve(to->GetSize());
for (ui32 i = 0; i < from->GetSize(); ++i) {
- const auto oldType = from->GetItems()[i];
- const auto newType = to->GetItems()[i];
+ const auto oldType = from->GetItems()[i];
+ const auto newType = to->GetItems()[i];
auto value = ctx.Builder(node->Pos())
.Callable("Nth")
.Add(0, node)
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Seal()
.Build();
- if (const auto status = TryConvertToImpl(ctx, value, *oldType, *newType, flags); status.Level == IGraphTransformer::TStatus::Error) {
+ if (const auto status = TryConvertToImpl(ctx, value, *oldType, *newType, flags); status.Level == IGraphTransformer::TStatus::Error) {
return status;
}
valueTransforms.push_back(value);
}
- for (auto i = from->GetSize(); i < to->GetSize(); ++i) {
- switch (const auto newType = to->GetItems()[i]; newType->GetKind()) {
- case ETypeAnnotationKind::Optional:
- valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *newType, ctx)}));
- continue;
- case ETypeAnnotationKind::Null:
- valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Null", {}));
- continue;
- default:
- return IGraphTransformer::TStatus::Error;
- }
- }
-
- node = ctx.NewList(node->Pos(), std::move(valueTransforms));
+ for (auto i = from->GetSize(); i < to->GetSize(); ++i) {
+ switch (const auto newType = to->GetItems()[i]; newType->GetKind()) {
+ case ETypeAnnotationKind::Optional:
+ valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Nothing", {ExpandType(node->Pos(), *newType, ctx)}));
+ continue;
+ case ETypeAnnotationKind::Null:
+ valueTransforms.push_back(ctx.NewCallable(node->Pos(), "Null", {}));
+ continue;
+ default:
+ return IGraphTransformer::TStatus::Error;
+ }
+ }
+
+ node = ctx.NewList(node->Pos(), std::move(valueTransforms));
return IGraphTransformer::TStatus::Repeat;
}
}
@@ -763,7 +763,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
}
for (ui32 i = node->IsCallable("List") ? 1 : 0; i < node->ChildrenSize(); ++i) {
- auto value = node->ChildPtr(i);
+ auto value = node->ChildPtr(i);
auto status = TryConvertToImpl(ctx, value, *oldItemType, *newItemType, flags);
if (status.Level == IGraphTransformer::TStatus::Error) {
return status;
@@ -772,7 +772,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
valueTransforms.push_back(value);
}
- node = ctx.NewCallable(node->Pos(), node->Content(), std::move(valueTransforms));
+ node = ctx.NewCallable(node->Pos(), node->Content(), std::move(valueTransforms));
return IGraphTransformer::TStatus::Repeat;
}
else if (expectedType.GetKind() == ETypeAnnotationKind::List && sourceType.GetKind() == ETypeAnnotationKind::List) {
@@ -784,7 +784,7 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
auto originalArg = arg;
auto status = TryConvertToImpl(ctx, arg, *from->GetItemType(), *nextType, flags);
if (status.Level != IGraphTransformer::TStatus::Error) {
- auto lambda = ctx.NewLambda(node->Pos(), ctx.NewArguments(node->Pos(), { originalArg }), std::move(arg));
+ auto lambda = ctx.NewLambda(node->Pos(), ctx.NewArguments(node->Pos(), { originalArg }), std::move(arg));
node = ctx.NewCallable(node->Pos(), "OrderedMap", { node, lambda });
@@ -878,118 +878,118 @@ IGraphTransformer::TStatus TryConvertToImpl(TExprContext& ctx, TExprNode::TPtr&
return IGraphTransformer::TStatus::Error;
}
-std::pair<ui8, ui8> GetDecimalParts(const TDataExprType& decimal) {
- const auto extra = static_cast<const TDataExprParamsType&>(decimal);
- const auto pr = FromString<ui8>(extra.GetParamOne());
- const auto sc = FromString<ui8>(extra.GetParamTwo());
- const auto dp = ui8(pr - sc);
- return {dp, sc};
-}
-
-using TFieldsOfStructs = std::unordered_map<std::string_view, std::array<const TTypeAnnotationNode*, 2U>>;
-
-TFieldsOfStructs GetFieldsTypes(const TStructExprType& left, const TStructExprType& right) {
- TFieldsOfStructs fields(std::max(left.GetSize(), right.GetSize()));
- using TPairOfTypes = typename TFieldsOfStructs::mapped_type;
- for (const auto& item : right.GetItems()) {
- YQL_ENSURE(fields.emplace(item->GetName(), TPairOfTypes{{nullptr, item->GetItemType()}}).second);
- }
- for (const auto& item : left.GetItems()) {
- const auto ins = fields.emplace(item->GetName(), TPairOfTypes{{item->GetItemType(), nullptr}});
- if (!ins.second) {
- ins.first->second.front() = item->GetItemType();
- }
- }
- return fields;
-}
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TDataExprType* source, const TDataExprType* target) {
- const auto sSlot = source->GetSlot();
- const auto tSlot = target->GetSlot();
-
- if (sSlot == tSlot) {
- if (EDataSlot::Decimal == sSlot) {
- if (*static_cast<const TDataExprParamsType*>(source) == *static_cast<const TDataExprParamsType*>(target)) {
- return NUdf::ECastOptions::Complete;
- }
-
- const auto sParts = GetDecimalParts(*source);
- const auto tParts = GetDecimalParts(*target);
-
- if (sParts.first <= tParts.first && sParts.second <= tParts.second) {
- return NUdf::ECastOptions::Complete;
- }
- if (std::min(sParts.first, tParts.first) + std::min(sParts.second, tParts.second)) {
- return Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
- }
- return NUdf::ECastOptions::Impossible;
- }
- return NUdf::ECastOptions::Complete;
- }
-
- if (EDataSlot::Decimal == tSlot && IsDataTypeIntegral(sSlot)) {
- const auto tParts = GetDecimalParts(*target);
- const auto dSrc = NUdf::GetDataTypeInfo(sSlot).DecimalDigits;
- if (dSrc <= tParts.first) {
- return NUdf::ECastOptions::Complete;
- }
- return tParts.first ? Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData : NUdf::ECastOptions::Impossible;
- }
-
- if (EDataSlot::Decimal == sSlot && IsDataTypeIntegral(tSlot)) {
- const auto sParts = GetDecimalParts(*source);
- const auto dDst = NUdf::GetDataTypeInfo(tSlot).DecimalDigits;
- if (!sParts.first) {
- return NUdf::ECastOptions::Impossible;
- }
- return Strong ? NUdf::ECastOptions::MayFail:
- NUdf::ECastOptions::MayFail |
- ((sParts.first >= dDst || sParts.second >0u) ? NUdf::ECastOptions::MayLoseData : NUdf::ECastOptions::Complete);
- }
-
- const auto option = *NUdf::GetCastResult(sSlot, tSlot);
- if (!(Strong && NUdf::ECastOptions::MayLoseData & option)) {
- return option;
- }
- return NUdf::IsComparable(sSlot, tSlot) ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::Impossible;
-}
-
-template <bool Strong>
-NUdf::TCastResultOptions ReduceCastResult(NUdf::TCastResultOptions result);
-
-template <>
-NUdf::TCastResultOptions ReduceCastResult<false>(NUdf::TCastResultOptions result) {
- constexpr auto fail = NUdf::ECastOptions::MayFail | NUdf::ECastOptions::AnywayLoseData;
- if (result & fail) {
- return result & ~fail | NUdf::ECastOptions::MayLoseData;
- }
- return result;
-}
-
-template <>
-NUdf::TCastResultOptions ReduceCastResult<true>(NUdf::TCastResultOptions result) {
- if (result & NUdf::ECastOptions::AnywayLoseData) {
- return NUdf::ECastOptions::Impossible;
- }
-
- if (result & NUdf::ECastOptions::MayLoseData) {
- return result & ~NUdf::ECastOptions::MayLoseData | NUdf::ECastOptions::MayFail;
- }
- return result;
-}
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TOptionalExprType* source, const TOptionalExprType* target) {
- return ReduceCastResult<Strong>(CastResult<Strong>(source->GetItemType(), target->GetItemType()));
-}
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TListExprType* source, const TListExprType* target) {
- return ReduceCastResult<Strong>(CastResult<Strong>(source->GetItemType(), target->GetItemType()));
-}
-
-template <bool Strong>
+std::pair<ui8, ui8> GetDecimalParts(const TDataExprType& decimal) {
+ const auto extra = static_cast<const TDataExprParamsType&>(decimal);
+ const auto pr = FromString<ui8>(extra.GetParamOne());
+ const auto sc = FromString<ui8>(extra.GetParamTwo());
+ const auto dp = ui8(pr - sc);
+ return {dp, sc};
+}
+
+using TFieldsOfStructs = std::unordered_map<std::string_view, std::array<const TTypeAnnotationNode*, 2U>>;
+
+TFieldsOfStructs GetFieldsTypes(const TStructExprType& left, const TStructExprType& right) {
+ TFieldsOfStructs fields(std::max(left.GetSize(), right.GetSize()));
+ using TPairOfTypes = typename TFieldsOfStructs::mapped_type;
+ for (const auto& item : right.GetItems()) {
+ YQL_ENSURE(fields.emplace(item->GetName(), TPairOfTypes{{nullptr, item->GetItemType()}}).second);
+ }
+ for (const auto& item : left.GetItems()) {
+ const auto ins = fields.emplace(item->GetName(), TPairOfTypes{{item->GetItemType(), nullptr}});
+ if (!ins.second) {
+ ins.first->second.front() = item->GetItemType();
+ }
+ }
+ return fields;
+}
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TDataExprType* source, const TDataExprType* target) {
+ const auto sSlot = source->GetSlot();
+ const auto tSlot = target->GetSlot();
+
+ if (sSlot == tSlot) {
+ if (EDataSlot::Decimal == sSlot) {
+ if (*static_cast<const TDataExprParamsType*>(source) == *static_cast<const TDataExprParamsType*>(target)) {
+ return NUdf::ECastOptions::Complete;
+ }
+
+ const auto sParts = GetDecimalParts(*source);
+ const auto tParts = GetDecimalParts(*target);
+
+ if (sParts.first <= tParts.first && sParts.second <= tParts.second) {
+ return NUdf::ECastOptions::Complete;
+ }
+ if (std::min(sParts.first, tParts.first) + std::min(sParts.second, tParts.second)) {
+ return Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
+ }
+ return NUdf::ECastOptions::Impossible;
+ }
+ return NUdf::ECastOptions::Complete;
+ }
+
+ if (EDataSlot::Decimal == tSlot && IsDataTypeIntegral(sSlot)) {
+ const auto tParts = GetDecimalParts(*target);
+ const auto dSrc = NUdf::GetDataTypeInfo(sSlot).DecimalDigits;
+ if (dSrc <= tParts.first) {
+ return NUdf::ECastOptions::Complete;
+ }
+ return tParts.first ? Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData : NUdf::ECastOptions::Impossible;
+ }
+
+ if (EDataSlot::Decimal == sSlot && IsDataTypeIntegral(tSlot)) {
+ const auto sParts = GetDecimalParts(*source);
+ const auto dDst = NUdf::GetDataTypeInfo(tSlot).DecimalDigits;
+ if (!sParts.first) {
+ return NUdf::ECastOptions::Impossible;
+ }
+ return Strong ? NUdf::ECastOptions::MayFail:
+ NUdf::ECastOptions::MayFail |
+ ((sParts.first >= dDst || sParts.second >0u) ? NUdf::ECastOptions::MayLoseData : NUdf::ECastOptions::Complete);
+ }
+
+ const auto option = *NUdf::GetCastResult(sSlot, tSlot);
+ if (!(Strong && NUdf::ECastOptions::MayLoseData & option)) {
+ return option;
+ }
+ return NUdf::IsComparable(sSlot, tSlot) ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::Impossible;
+}
+
+template <bool Strong>
+NUdf::TCastResultOptions ReduceCastResult(NUdf::TCastResultOptions result);
+
+template <>
+NUdf::TCastResultOptions ReduceCastResult<false>(NUdf::TCastResultOptions result) {
+ constexpr auto fail = NUdf::ECastOptions::MayFail | NUdf::ECastOptions::AnywayLoseData;
+ if (result & fail) {
+ return result & ~fail | NUdf::ECastOptions::MayLoseData;
+ }
+ return result;
+}
+
+template <>
+NUdf::TCastResultOptions ReduceCastResult<true>(NUdf::TCastResultOptions result) {
+ if (result & NUdf::ECastOptions::AnywayLoseData) {
+ return NUdf::ECastOptions::Impossible;
+ }
+
+ if (result & NUdf::ECastOptions::MayLoseData) {
+ return result & ~NUdf::ECastOptions::MayLoseData | NUdf::ECastOptions::MayFail;
+ }
+ return result;
+}
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TOptionalExprType* source, const TOptionalExprType* target) {
+ return ReduceCastResult<Strong>(CastResult<Strong>(source->GetItemType(), target->GetItemType()));
+}
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TListExprType* source, const TListExprType* target) {
+ return ReduceCastResult<Strong>(CastResult<Strong>(source->GetItemType(), target->GetItemType()));
+}
+
+template <bool Strong>
NUdf::TCastResultOptions CastResult(const TStreamExprType* source, const TStreamExprType* target) {
return ReduceCastResult<Strong>(CastResult<Strong>(source->GetItemType(), target->GetItemType()));
}
@@ -1000,188 +1000,188 @@ NUdf::TCastResultOptions CastResult(const TFlowExprType* source, const TFlowExpr
}
template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TDictExprType* source, const TDictExprType* target) {
- return ReduceCastResult<Strong>(CastResult<Strong>(source->GetKeyType(), target->GetKeyType()) | CastResult<Strong>(source->GetPayloadType(), target->GetPayloadType()));
-}
-
-template <bool Strong, bool AllOrAnyElements = true>
-NUdf::TCastResultOptions CastResult(const TTupleExprType* source, const TTupleExprType* target) {
- if (!target->GetSize()) {
- return source->GetSize() ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::Complete;
- }
-
- const auto& sItems = source->GetItems();
- const auto& tItems = target->GetItems();
-
- NUdf::TCastResultOptions result = NUdf::ECastOptions::Complete;
- for (size_t i = 0U; i < std::max(sItems.size(), tItems.size()); ++i) {
- if (i >= sItems.size()) {
- if (AllOrAnyElements && tItems[i]->GetKind() != ETypeAnnotationKind::Optional && tItems[i]->GetKind() != ETypeAnnotationKind::Null) {
- return NUdf::ECastOptions::Impossible;
- }
- } else if (i >= tItems.size()) {
- if (sItems[i]->GetKind() != ETypeAnnotationKind::Null) {
- if (sItems[i]->GetKind() == ETypeAnnotationKind::Optional) {
- result |= Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
- } else {
- if (Strong && AllOrAnyElements) {
- return NUdf::ECastOptions::Impossible;
- } else {
- result |= AllOrAnyElements ? NUdf::ECastOptions::AnywayLoseData : NUdf::ECastOptions::MayFail;
- }
- }
- }
- } else {
- result |= CastResult<Strong>(sItems[i], tItems[i]);
- if (result & NUdf::ECastOptions::Impossible) {
- return NUdf::ECastOptions::Impossible;
- }
- }
- }
- return result;
-}
-
-template <bool Strong, bool AllOrAnyMembers = true>
-NUdf::TCastResultOptions CastResult(const TStructExprType* source, const TStructExprType* target) {
- const auto& fields = GetFieldsTypes(*source, *target);
- if (fields.empty()) {
- return NUdf::ECastOptions::Complete;
- }
-
- NUdf::TCastResultOptions result = NUdf::ECastOptions::Complete;
- bool hasCommon = false;
- for (const auto& field : fields) {
- if (!field.second.front()) {
- if (AllOrAnyMembers && field.second.back()->GetKind() != ETypeAnnotationKind::Optional && field.second.back()->GetKind() != ETypeAnnotationKind::Null) {
- return NUdf::ECastOptions::Impossible;
- }
- } else if (!field.second.back()) {
- if (field.second.front()->GetKind() != ETypeAnnotationKind::Null) {
- if (field.second.front()->GetKind() == ETypeAnnotationKind::Optional) {
- result |= Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
- } else {
- if (Strong && AllOrAnyMembers) {
- return NUdf::ECastOptions::Impossible;
- } else {
- result |= AllOrAnyMembers ? NUdf::ECastOptions::AnywayLoseData : NUdf::ECastOptions::MayFail;
- }
- }
- }
- } else {
- hasCommon = true;
- result |= CastResult<Strong>(field.second.front(), field.second.back());
- }
-
- if (result & NUdf::ECastOptions::Impossible) {
- return NUdf::ECastOptions::Impossible;
- }
- }
- return hasCommon ? result : NUdf::ECastOptions::Impossible;
-}
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TVariantExprType* source, const TVariantExprType* target) {
- const auto sourceUnderType = source->GetUnderlyingType();
- const auto targetUnderType = target->GetUnderlyingType();
- if (sourceUnderType->GetKind() == ETypeAnnotationKind::Struct && targetUnderType->GetKind() == ETypeAnnotationKind::Struct) {
- return CastResult<Strong, false>(sourceUnderType->Cast<TStructExprType>(), targetUnderType->Cast<TStructExprType>());
- }
- if (sourceUnderType->GetKind() == ETypeAnnotationKind::Tuple && targetUnderType->GetKind() == ETypeAnnotationKind::Tuple) {
- return CastResult<Strong, false>(sourceUnderType->Cast<TTupleExprType>(), targetUnderType->Cast<TTupleExprType>());
- }
- return NUdf::ECastOptions::Impossible;
-}
-
-ECompareOptions AddOptional(ECompareOptions result) {
- return ECompareOptions::Comparable == result ? ECompareOptions::Optional : result;
-}
-
-template <bool Equality>
-ECompareOptions Join(ECompareOptions state, ECompareOptions item) {
- if (ECompareOptions::Uncomparable == state || ECompareOptions::Uncomparable == item) {
- return ECompareOptions::Uncomparable;
- }
-
- if (ECompareOptions::Null == state) {
- return !Equality && ECompareOptions::Null == item ? ECompareOptions::Null : ECompareOptions::Optional;
- }
-
- if (ECompareOptions::Null == item || ECompareOptions::Optional == item) {
- return ECompareOptions::Optional;
- }
-
- return state;
-}
-
-ECompareOptions CanCompare(const TDataExprType* left, const TDataExprType* right) {
- return NUdf::IsComparable(left->GetSlot(), right->GetSlot()) ?
- ECompareOptions::Comparable : ECompareOptions::Uncomparable;
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TTaggedExprType* left, const TTaggedExprType* right) {
- if (left->GetTag() != right->GetTag())
- return ECompareOptions::Uncomparable;
-
- return CanCompare<Equality>(left->GetBaseType(), right->GetBaseType());
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TOptionalExprType* left, const TOptionalExprType* right) {
- return AddOptional(CanCompare<Equality>(left->GetItemType(), right->GetItemType()));
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TListExprType* left, const TListExprType* right) {
- return CanCompare<Equality>(left->GetItemType(), right->GetItemType());
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TDictExprType* left, const TDictExprType* right) {
- return Equality ? CanCompare<Equality>(left->GetPayloadType(), right->GetPayloadType()) : ECompareOptions::Uncomparable;
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TTupleExprType* left, const TTupleExprType* right) {
- const auto& lItems = left->GetItems();
- const auto& rItems = right->GetItems();
-
- ECompareOptions result = left->GetSize() == right->GetSize() ? ECompareOptions::Comparable : ECompareOptions::Optional;
- for (size_t i = 0U; i < std::min(lItems.size(), rItems.size()) && ECompareOptions::Uncomparable != result; ++i) {
- result = Join<Equality>(result, CanCompare<Equality>(lItems[i], rItems[i]));
- }
- return result;
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TStructExprType* left, const TStructExprType* right) {
- if (!Equality) {
- return ECompareOptions::Uncomparable;
- }
-
- if (!left->GetSize() && !right->GetSize()) {
- return ECompareOptions::Comparable;
- }
-
- const auto& fields = GetFieldsTypes(*left, *right);
-
- bool hasMissed = false, hasCommon = false;
- for (const auto& field : fields) {
- switch (CanCompare<Equality>(field.second.front(), field.second.back())) {
- case ECompareOptions::Null: hasMissed = true; continue;
- case ECompareOptions::Uncomparable: return ECompareOptions::Uncomparable;
+NUdf::TCastResultOptions CastResult(const TDictExprType* source, const TDictExprType* target) {
+ return ReduceCastResult<Strong>(CastResult<Strong>(source->GetKeyType(), target->GetKeyType()) | CastResult<Strong>(source->GetPayloadType(), target->GetPayloadType()));
+}
+
+template <bool Strong, bool AllOrAnyElements = true>
+NUdf::TCastResultOptions CastResult(const TTupleExprType* source, const TTupleExprType* target) {
+ if (!target->GetSize()) {
+ return source->GetSize() ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::Complete;
+ }
+
+ const auto& sItems = source->GetItems();
+ const auto& tItems = target->GetItems();
+
+ NUdf::TCastResultOptions result = NUdf::ECastOptions::Complete;
+ for (size_t i = 0U; i < std::max(sItems.size(), tItems.size()); ++i) {
+ if (i >= sItems.size()) {
+ if (AllOrAnyElements && tItems[i]->GetKind() != ETypeAnnotationKind::Optional && tItems[i]->GetKind() != ETypeAnnotationKind::Null) {
+ return NUdf::ECastOptions::Impossible;
+ }
+ } else if (i >= tItems.size()) {
+ if (sItems[i]->GetKind() != ETypeAnnotationKind::Null) {
+ if (sItems[i]->GetKind() == ETypeAnnotationKind::Optional) {
+ result |= Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
+ } else {
+ if (Strong && AllOrAnyElements) {
+ return NUdf::ECastOptions::Impossible;
+ } else {
+ result |= AllOrAnyElements ? NUdf::ECastOptions::AnywayLoseData : NUdf::ECastOptions::MayFail;
+ }
+ }
+ }
+ } else {
+ result |= CastResult<Strong>(sItems[i], tItems[i]);
+ if (result & NUdf::ECastOptions::Impossible) {
+ return NUdf::ECastOptions::Impossible;
+ }
+ }
+ }
+ return result;
+}
+
+template <bool Strong, bool AllOrAnyMembers = true>
+NUdf::TCastResultOptions CastResult(const TStructExprType* source, const TStructExprType* target) {
+ const auto& fields = GetFieldsTypes(*source, *target);
+ if (fields.empty()) {
+ return NUdf::ECastOptions::Complete;
+ }
+
+ NUdf::TCastResultOptions result = NUdf::ECastOptions::Complete;
+ bool hasCommon = false;
+ for (const auto& field : fields) {
+ if (!field.second.front()) {
+ if (AllOrAnyMembers && field.second.back()->GetKind() != ETypeAnnotationKind::Optional && field.second.back()->GetKind() != ETypeAnnotationKind::Null) {
+ return NUdf::ECastOptions::Impossible;
+ }
+ } else if (!field.second.back()) {
+ if (field.second.front()->GetKind() != ETypeAnnotationKind::Null) {
+ if (field.second.front()->GetKind() == ETypeAnnotationKind::Optional) {
+ result |= Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData;
+ } else {
+ if (Strong && AllOrAnyMembers) {
+ return NUdf::ECastOptions::Impossible;
+ } else {
+ result |= AllOrAnyMembers ? NUdf::ECastOptions::AnywayLoseData : NUdf::ECastOptions::MayFail;
+ }
+ }
+ }
+ } else {
+ hasCommon = true;
+ result |= CastResult<Strong>(field.second.front(), field.second.back());
+ }
+
+ if (result & NUdf::ECastOptions::Impossible) {
+ return NUdf::ECastOptions::Impossible;
+ }
+ }
+ return hasCommon ? result : NUdf::ECastOptions::Impossible;
+}
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TVariantExprType* source, const TVariantExprType* target) {
+ const auto sourceUnderType = source->GetUnderlyingType();
+ const auto targetUnderType = target->GetUnderlyingType();
+ if (sourceUnderType->GetKind() == ETypeAnnotationKind::Struct && targetUnderType->GetKind() == ETypeAnnotationKind::Struct) {
+ return CastResult<Strong, false>(sourceUnderType->Cast<TStructExprType>(), targetUnderType->Cast<TStructExprType>());
+ }
+ if (sourceUnderType->GetKind() == ETypeAnnotationKind::Tuple && targetUnderType->GetKind() == ETypeAnnotationKind::Tuple) {
+ return CastResult<Strong, false>(sourceUnderType->Cast<TTupleExprType>(), targetUnderType->Cast<TTupleExprType>());
+ }
+ return NUdf::ECastOptions::Impossible;
+}
+
+ECompareOptions AddOptional(ECompareOptions result) {
+ return ECompareOptions::Comparable == result ? ECompareOptions::Optional : result;
+}
+
+template <bool Equality>
+ECompareOptions Join(ECompareOptions state, ECompareOptions item) {
+ if (ECompareOptions::Uncomparable == state || ECompareOptions::Uncomparable == item) {
+ return ECompareOptions::Uncomparable;
+ }
+
+ if (ECompareOptions::Null == state) {
+ return !Equality && ECompareOptions::Null == item ? ECompareOptions::Null : ECompareOptions::Optional;
+ }
+
+ if (ECompareOptions::Null == item || ECompareOptions::Optional == item) {
+ return ECompareOptions::Optional;
+ }
+
+ return state;
+}
+
+ECompareOptions CanCompare(const TDataExprType* left, const TDataExprType* right) {
+ return NUdf::IsComparable(left->GetSlot(), right->GetSlot()) ?
+ ECompareOptions::Comparable : ECompareOptions::Uncomparable;
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TTaggedExprType* left, const TTaggedExprType* right) {
+ if (left->GetTag() != right->GetTag())
+ return ECompareOptions::Uncomparable;
+
+ return CanCompare<Equality>(left->GetBaseType(), right->GetBaseType());
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TOptionalExprType* left, const TOptionalExprType* right) {
+ return AddOptional(CanCompare<Equality>(left->GetItemType(), right->GetItemType()));
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TListExprType* left, const TListExprType* right) {
+ return CanCompare<Equality>(left->GetItemType(), right->GetItemType());
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TDictExprType* left, const TDictExprType* right) {
+ return Equality ? CanCompare<Equality>(left->GetPayloadType(), right->GetPayloadType()) : ECompareOptions::Uncomparable;
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TTupleExprType* left, const TTupleExprType* right) {
+ const auto& lItems = left->GetItems();
+ const auto& rItems = right->GetItems();
+
+ ECompareOptions result = left->GetSize() == right->GetSize() ? ECompareOptions::Comparable : ECompareOptions::Optional;
+ for (size_t i = 0U; i < std::min(lItems.size(), rItems.size()) && ECompareOptions::Uncomparable != result; ++i) {
+ result = Join<Equality>(result, CanCompare<Equality>(lItems[i], rItems[i]));
+ }
+ return result;
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TStructExprType* left, const TStructExprType* right) {
+ if (!Equality) {
+ return ECompareOptions::Uncomparable;
+ }
+
+ if (!left->GetSize() && !right->GetSize()) {
+ return ECompareOptions::Comparable;
+ }
+
+ const auto& fields = GetFieldsTypes(*left, *right);
+
+ bool hasMissed = false, hasCommon = false;
+ for (const auto& field : fields) {
+ switch (CanCompare<Equality>(field.second.front(), field.second.back())) {
+ case ECompareOptions::Null: hasMissed = true; continue;
+ case ECompareOptions::Uncomparable: return ECompareOptions::Uncomparable;
case ECompareOptions::Optional: hasMissed = true; [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
case ECompareOptions::Comparable: hasCommon = true; break;
- }
- }
-
- return hasCommon ?
- hasMissed ? ECompareOptions::Optional : ECompareOptions::Comparable:
- ECompareOptions::Null;
-}
-
-template <bool Equality>
-ECompareOptions CanCompare(const TVariantExprType* left, const TVariantExprType* right) {
+ }
+ }
+
+ return hasCommon ?
+ hasMissed ? ECompareOptions::Optional : ECompareOptions::Comparable:
+ ECompareOptions::Null;
+}
+
+template <bool Equality>
+ECompareOptions CanCompare(const TVariantExprType* left, const TVariantExprType* right) {
auto leftUnderlyingType = left->GetUnderlyingType();
auto rightUnderlyingType = right->GetUnderlyingType();
if (leftUnderlyingType->GetKind() == ETypeAnnotationKind::Tuple ||
@@ -1209,226 +1209,226 @@ ECompareOptions CanCompare(const TVariantExprType* left, const TVariantExprType*
}
return hasMissed ? ECompareOptions::Optional : ECompareOptions::Comparable;
-}
-
-const TTupleExprType* DryType(const TTupleExprType* type, bool& hasOptional, TExprContext& ctx) {
- auto items = type->GetItems();
- for (auto& item : items) {
- if (const auto dry = DryType(item, hasOptional, ctx))
- item = dry;
- else
- return nullptr;
- }
- return ctx.MakeType<TTupleExprType>(items);
-}
-
-template<bool Strict = true>
-const TStructExprType* DryType(const TStructExprType* type, bool& hasOptional, TExprContext& ctx) {
- auto items = type->GetItems();
- auto it = items.begin();
- for (const auto& item : items) {
- if (const auto dry = DryType(item->GetItemType(), hasOptional, ctx))
- *it++ = ctx.MakeType<TItemExprType>(item->GetName(), dry);
- else if constexpr (Strict)
- return nullptr;
- }
- items.erase(it, items.cend());
- return items.empty() ? nullptr : ctx.MakeType<TStructExprType>(items);
-}
-
-const TListExprType* DryType(const TListExprType* type, bool& hasOptional, TExprContext& ctx) {
- if (const auto itemType = DryType(type->GetItemType(), hasOptional, ctx))
- return ctx.MakeType<TListExprType>(itemType);
- return nullptr;
-}
-
-const TDictExprType* DryType(const TDictExprType* type, bool& hasOptional, TExprContext& ctx) {
- if (const auto dryKey = DryType(type->GetKeyType(), hasOptional, ctx))
- if (const auto dry = DryType(type->GetPayloadType(), hasOptional, ctx))
- return ctx.MakeType<TDictExprType>(dryKey, dry);
- return nullptr;
-}
-
-const TVariantExprType* DryType(const TVariantExprType* type, bool& hasOptional, TExprContext& ctx) {
- switch (const auto underType = type->GetUnderlyingType(); underType->GetKind()) {
- case ETypeAnnotationKind::Tuple:
- if (const auto dry = DryType(underType->Cast<TTupleExprType>(), hasOptional, ctx))
- return ctx.MakeType<TVariantExprType>(dry);
- break;
- case ETypeAnnotationKind::Struct:
- if (const auto dry = DryType<false>(underType->Cast<TStructExprType>(), hasOptional, ctx))
- return ctx.MakeType<TVariantExprType>(dry);
- break;
- default:
- break;
-
- }
- return nullptr;
-}
-
-const TTaggedExprType* DryType(const TTaggedExprType* type, bool& hasOptional, TExprContext& ctx) {
- if (const auto dry = DryType(type->GetBaseType(), hasOptional, ctx))
- return ctx.MakeType<TTaggedExprType>(dry, type->GetTag());
- return nullptr;
-}
-
-const TDataExprType* CommonType(TPositionHandle pos, const TDataExprType* one, const TDataExprType* two, TExprContext& ctx) {
- const auto slot1 = one->GetSlot();
- const auto slot2 = two->GetSlot();
- if (IsDataTypeDecimal(slot1) && IsDataTypeDecimal(slot2)) {
- const auto parts1 = GetDecimalParts(*one);
- const auto parts2 = GetDecimalParts(*two);
- const auto whole = std::min<ui8>(NDecimal::MaxPrecision, std::max<ui8>(parts1.first - parts1.second, parts2.first - parts2.second));
- const auto scale = std::min<ui8>(NDecimal::MaxPrecision - whole, std::max<ui8>(parts1.second, parts2.second));
- return ctx.MakeType<TDataExprParamsType>(EDataSlot::Decimal, ToString(whole + scale), ToString(scale));
- } else if (!(IsDataTypeDecimal(slot1) || IsDataTypeDecimal(slot2))) {
- if (const auto super = GetSuperType(slot1, slot2))
- return ctx.MakeType<TDataExprType>(*super);
- }
-
- ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Cannot infer common type for " << GetDataTypeInfo(slot1).Name << " and " << GetDataTypeInfo(slot2).Name));
- return nullptr;
-}
-
-const TDataExprType* CommonType(TPositionHandle pos, const TResourceExprType* resource, const TDataExprType* data, TExprContext& ctx) {
- const auto slot = data->GetSlot();
- const auto& tag = resource->GetTag();
- if (tag == "Yson2.Node" && EDataSlot::Yson == slot)
- return data;
-
- ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Incompatible resourse '" << tag << "' with " << GetDataTypeInfo(slot).Name));
- return nullptr;
-}
-
-template<bool Strict, class SequenceType>
-const SequenceType* CommonItemType(TPositionHandle pos, const SequenceType* one, const SequenceType* two, TExprContext& ctx) {
- if (const auto join = CommonType<Strict>(pos, one->GetItemType(), two->GetItemType(), ctx))
- return ctx.MakeType<SequenceType>(join);
- return nullptr;
-}
-
-template<bool Strict>
-const TDictExprType* CommonType(TPositionHandle pos, const TDictExprType* one, const TDictExprType* two, TExprContext& ctx) {
- if (const auto joinKey = CommonType<Strict>(pos, one->GetKeyType(), two->GetKeyType(), ctx))
- if (const auto join = CommonType<Strict>(pos, one->GetPayloadType(), two->GetPayloadType(), ctx))
- return ctx.MakeType<TDictExprType>(joinKey, join);
- return nullptr;
-}
-
-template<bool Strict, bool Relaxed = false>
-const TStructExprType* CommonType(TPositionHandle pos, const TStructExprType* one, const TStructExprType* two, TExprContext& ctx) {
- auto itemsOne = one->GetItems();
- auto itemsTwo = two->GetItems();
-
- if constexpr (Strict) {
- if constexpr (Relaxed) {
- auto it1 = itemsOne.cbegin();
- auto it2 = itemsTwo.cbegin();
- while (it1 < itemsOne.cend() && it2 < itemsTwo.cend()) {
- const auto& name1 = (*it1)->GetName();
- const auto& name2 = (*it2)->GetName();
- if (name1 < name2)
- it1 = itemsOne.erase(it1);
- else if (name1 > name2)
- it2 = itemsTwo.erase(it2);
- else {
- ++it1;
- ++it2;
- }
- }
- itemsOne.erase(it1, itemsOne.cend());
- itemsTwo.erase(it2, itemsTwo.cend());
- } else if (itemsOne.size() != itemsTwo.size())
- return nullptr;
- } else {
- auto it1 = itemsOne.cbegin();
- auto it2 = itemsTwo.cbegin();
- while (it1 < itemsOne.cend() || it2 < itemsTwo.cend()) {
- if (itemsTwo.cend() == it2 || (itemsOne.cend() > it1 && (*it1)->GetName() < (*it2)->GetName()))
- it2 = itemsTwo.emplace(it2, Relaxed ? *it1 : ctx.MakeType<TItemExprType>((*it1)->GetName(), ctx.MakeType<TNullExprType>()));
- else if (itemsOne.cend() == it1 || (itemsTwo.cend() > it2 && (*it1)->GetName() > (*it2)->GetName()))
- it1 = itemsOne.emplace(it1, Relaxed ? *it2 : ctx.MakeType<TItemExprType>((*it2)->GetName(), ctx.MakeType<TNullExprType>()));
- else {
- ++it1;
- ++it2;
- }
- }
- }
-
- for (auto i = 0U; i < itemsTwo.size(); ++i) {
- const auto& name = itemsOne[i]->GetName();
- if (name != itemsTwo[i]->GetName())
- return nullptr;
-
- if (const auto join = CommonType<Strict>(pos, itemsOne[i]->GetItemType(), itemsTwo[i]->GetItemType(), ctx))
- itemsOne[i] = ctx.MakeType<TItemExprType>(name, join);
- else
- return nullptr;
- }
- return ctx.MakeType<TStructExprType>(itemsOne);
-}
-
-template<bool Strict, bool Relaxed = false>
-const TTupleExprType* CommonType(TPositionHandle pos, const TTupleExprType* one, const TTupleExprType* two, TExprContext& ctx) {
- auto itemsOne = one->GetItems();
- auto itemsTwo = two->GetItems();
-
- if constexpr (Strict && !Relaxed) {
- if (itemsOne.size() != itemsTwo.size())
- return nullptr;
- } else {
- const auto size = Strict ? std::min(itemsOne.size(), itemsTwo.size()) : std::max(itemsOne.size(), itemsTwo.size());
- itemsOne.resize(size);
- itemsTwo.resize(size);
- }
-
- for (auto i = 0U; i < itemsTwo.size(); ++i) {
- if (const auto join = CommonType<Strict>(pos,
- itemsOne[i] ? itemsOne[i] : Relaxed ? itemsTwo[i] : ctx.MakeType<TNullExprType>(),
- itemsTwo[i] ? itemsTwo[i] : Relaxed ? itemsOne[i] : ctx.MakeType<TNullExprType>(),
- ctx))
- itemsOne[i] = join;
- else
- return nullptr;
- }
- return ctx.MakeType<TTupleExprType>(itemsOne);
-}
-
-template<bool Strict>
-const TVariantExprType* CommonType(TPositionHandle pos, const TVariantExprType* one, const TVariantExprType* two, TExprContext& ctx) {
- const auto underOne = one->GetUnderlyingType();
- const auto underTwo = two->GetUnderlyingType();
- const auto kind = underOne->GetKind();
- if (underTwo->GetKind() != kind)
- return nullptr;
-
- switch (kind) {
- case ETypeAnnotationKind::Tuple:
- if (const auto dry = CommonType<Strict, true>(pos, underOne->Cast<TTupleExprType>(), underTwo->Cast<TTupleExprType>(), ctx))
- return ctx.MakeType<TVariantExprType>(dry);
- break;
- case ETypeAnnotationKind::Struct:
- if (const auto dry = CommonType<Strict, true>(pos, underOne->Cast<TStructExprType>(), underTwo->Cast<TStructExprType>(), ctx))
- return ctx.MakeType<TVariantExprType>(dry);
- break;
- default:
- break;
- }
- return nullptr;
-}
-
-template<bool Strict>
-const TTaggedExprType* CommonType(TPositionHandle pos, const TTaggedExprType* one, const TTaggedExprType* two, TExprContext& ctx) {
- const auto& tag = one->GetTag();
- if (two->GetTag() != tag) {
- ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Different tags '" << tag << "' and '" << two->GetTag() << "'."));
- return nullptr;
- }
- if (const auto join = CommonType<Strict>(pos, one->GetBaseType(), two->GetBaseType(), ctx))
- return ctx.MakeType<TTaggedExprType>(join, tag);
- return nullptr;
-}
-
+}
+
+const TTupleExprType* DryType(const TTupleExprType* type, bool& hasOptional, TExprContext& ctx) {
+ auto items = type->GetItems();
+ for (auto& item : items) {
+ if (const auto dry = DryType(item, hasOptional, ctx))
+ item = dry;
+ else
+ return nullptr;
+ }
+ return ctx.MakeType<TTupleExprType>(items);
+}
+
+template<bool Strict = true>
+const TStructExprType* DryType(const TStructExprType* type, bool& hasOptional, TExprContext& ctx) {
+ auto items = type->GetItems();
+ auto it = items.begin();
+ for (const auto& item : items) {
+ if (const auto dry = DryType(item->GetItemType(), hasOptional, ctx))
+ *it++ = ctx.MakeType<TItemExprType>(item->GetName(), dry);
+ else if constexpr (Strict)
+ return nullptr;
+ }
+ items.erase(it, items.cend());
+ return items.empty() ? nullptr : ctx.MakeType<TStructExprType>(items);
+}
+
+const TListExprType* DryType(const TListExprType* type, bool& hasOptional, TExprContext& ctx) {
+ if (const auto itemType = DryType(type->GetItemType(), hasOptional, ctx))
+ return ctx.MakeType<TListExprType>(itemType);
+ return nullptr;
+}
+
+const TDictExprType* DryType(const TDictExprType* type, bool& hasOptional, TExprContext& ctx) {
+ if (const auto dryKey = DryType(type->GetKeyType(), hasOptional, ctx))
+ if (const auto dry = DryType(type->GetPayloadType(), hasOptional, ctx))
+ return ctx.MakeType<TDictExprType>(dryKey, dry);
+ return nullptr;
+}
+
+const TVariantExprType* DryType(const TVariantExprType* type, bool& hasOptional, TExprContext& ctx) {
+ switch (const auto underType = type->GetUnderlyingType(); underType->GetKind()) {
+ case ETypeAnnotationKind::Tuple:
+ if (const auto dry = DryType(underType->Cast<TTupleExprType>(), hasOptional, ctx))
+ return ctx.MakeType<TVariantExprType>(dry);
+ break;
+ case ETypeAnnotationKind::Struct:
+ if (const auto dry = DryType<false>(underType->Cast<TStructExprType>(), hasOptional, ctx))
+ return ctx.MakeType<TVariantExprType>(dry);
+ break;
+ default:
+ break;
+
+ }
+ return nullptr;
+}
+
+const TTaggedExprType* DryType(const TTaggedExprType* type, bool& hasOptional, TExprContext& ctx) {
+ if (const auto dry = DryType(type->GetBaseType(), hasOptional, ctx))
+ return ctx.MakeType<TTaggedExprType>(dry, type->GetTag());
+ return nullptr;
+}
+
+const TDataExprType* CommonType(TPositionHandle pos, const TDataExprType* one, const TDataExprType* two, TExprContext& ctx) {
+ const auto slot1 = one->GetSlot();
+ const auto slot2 = two->GetSlot();
+ if (IsDataTypeDecimal(slot1) && IsDataTypeDecimal(slot2)) {
+ const auto parts1 = GetDecimalParts(*one);
+ const auto parts2 = GetDecimalParts(*two);
+ const auto whole = std::min<ui8>(NDecimal::MaxPrecision, std::max<ui8>(parts1.first - parts1.second, parts2.first - parts2.second));
+ const auto scale = std::min<ui8>(NDecimal::MaxPrecision - whole, std::max<ui8>(parts1.second, parts2.second));
+ return ctx.MakeType<TDataExprParamsType>(EDataSlot::Decimal, ToString(whole + scale), ToString(scale));
+ } else if (!(IsDataTypeDecimal(slot1) || IsDataTypeDecimal(slot2))) {
+ if (const auto super = GetSuperType(slot1, slot2))
+ return ctx.MakeType<TDataExprType>(*super);
+ }
+
+ ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Cannot infer common type for " << GetDataTypeInfo(slot1).Name << " and " << GetDataTypeInfo(slot2).Name));
+ return nullptr;
+}
+
+const TDataExprType* CommonType(TPositionHandle pos, const TResourceExprType* resource, const TDataExprType* data, TExprContext& ctx) {
+ const auto slot = data->GetSlot();
+ const auto& tag = resource->GetTag();
+ if (tag == "Yson2.Node" && EDataSlot::Yson == slot)
+ return data;
+
+ ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Incompatible resourse '" << tag << "' with " << GetDataTypeInfo(slot).Name));
+ return nullptr;
+}
+
+template<bool Strict, class SequenceType>
+const SequenceType* CommonItemType(TPositionHandle pos, const SequenceType* one, const SequenceType* two, TExprContext& ctx) {
+ if (const auto join = CommonType<Strict>(pos, one->GetItemType(), two->GetItemType(), ctx))
+ return ctx.MakeType<SequenceType>(join);
+ return nullptr;
+}
+
+template<bool Strict>
+const TDictExprType* CommonType(TPositionHandle pos, const TDictExprType* one, const TDictExprType* two, TExprContext& ctx) {
+ if (const auto joinKey = CommonType<Strict>(pos, one->GetKeyType(), two->GetKeyType(), ctx))
+ if (const auto join = CommonType<Strict>(pos, one->GetPayloadType(), two->GetPayloadType(), ctx))
+ return ctx.MakeType<TDictExprType>(joinKey, join);
+ return nullptr;
+}
+
+template<bool Strict, bool Relaxed = false>
+const TStructExprType* CommonType(TPositionHandle pos, const TStructExprType* one, const TStructExprType* two, TExprContext& ctx) {
+ auto itemsOne = one->GetItems();
+ auto itemsTwo = two->GetItems();
+
+ if constexpr (Strict) {
+ if constexpr (Relaxed) {
+ auto it1 = itemsOne.cbegin();
+ auto it2 = itemsTwo.cbegin();
+ while (it1 < itemsOne.cend() && it2 < itemsTwo.cend()) {
+ const auto& name1 = (*it1)->GetName();
+ const auto& name2 = (*it2)->GetName();
+ if (name1 < name2)
+ it1 = itemsOne.erase(it1);
+ else if (name1 > name2)
+ it2 = itemsTwo.erase(it2);
+ else {
+ ++it1;
+ ++it2;
+ }
+ }
+ itemsOne.erase(it1, itemsOne.cend());
+ itemsTwo.erase(it2, itemsTwo.cend());
+ } else if (itemsOne.size() != itemsTwo.size())
+ return nullptr;
+ } else {
+ auto it1 = itemsOne.cbegin();
+ auto it2 = itemsTwo.cbegin();
+ while (it1 < itemsOne.cend() || it2 < itemsTwo.cend()) {
+ if (itemsTwo.cend() == it2 || (itemsOne.cend() > it1 && (*it1)->GetName() < (*it2)->GetName()))
+ it2 = itemsTwo.emplace(it2, Relaxed ? *it1 : ctx.MakeType<TItemExprType>((*it1)->GetName(), ctx.MakeType<TNullExprType>()));
+ else if (itemsOne.cend() == it1 || (itemsTwo.cend() > it2 && (*it1)->GetName() > (*it2)->GetName()))
+ it1 = itemsOne.emplace(it1, Relaxed ? *it2 : ctx.MakeType<TItemExprType>((*it2)->GetName(), ctx.MakeType<TNullExprType>()));
+ else {
+ ++it1;
+ ++it2;
+ }
+ }
+ }
+
+ for (auto i = 0U; i < itemsTwo.size(); ++i) {
+ const auto& name = itemsOne[i]->GetName();
+ if (name != itemsTwo[i]->GetName())
+ return nullptr;
+
+ if (const auto join = CommonType<Strict>(pos, itemsOne[i]->GetItemType(), itemsTwo[i]->GetItemType(), ctx))
+ itemsOne[i] = ctx.MakeType<TItemExprType>(name, join);
+ else
+ return nullptr;
+ }
+ return ctx.MakeType<TStructExprType>(itemsOne);
+}
+
+template<bool Strict, bool Relaxed = false>
+const TTupleExprType* CommonType(TPositionHandle pos, const TTupleExprType* one, const TTupleExprType* two, TExprContext& ctx) {
+ auto itemsOne = one->GetItems();
+ auto itemsTwo = two->GetItems();
+
+ if constexpr (Strict && !Relaxed) {
+ if (itemsOne.size() != itemsTwo.size())
+ return nullptr;
+ } else {
+ const auto size = Strict ? std::min(itemsOne.size(), itemsTwo.size()) : std::max(itemsOne.size(), itemsTwo.size());
+ itemsOne.resize(size);
+ itemsTwo.resize(size);
+ }
+
+ for (auto i = 0U; i < itemsTwo.size(); ++i) {
+ if (const auto join = CommonType<Strict>(pos,
+ itemsOne[i] ? itemsOne[i] : Relaxed ? itemsTwo[i] : ctx.MakeType<TNullExprType>(),
+ itemsTwo[i] ? itemsTwo[i] : Relaxed ? itemsOne[i] : ctx.MakeType<TNullExprType>(),
+ ctx))
+ itemsOne[i] = join;
+ else
+ return nullptr;
+ }
+ return ctx.MakeType<TTupleExprType>(itemsOne);
+}
+
+template<bool Strict>
+const TVariantExprType* CommonType(TPositionHandle pos, const TVariantExprType* one, const TVariantExprType* two, TExprContext& ctx) {
+ const auto underOne = one->GetUnderlyingType();
+ const auto underTwo = two->GetUnderlyingType();
+ const auto kind = underOne->GetKind();
+ if (underTwo->GetKind() != kind)
+ return nullptr;
+
+ switch (kind) {
+ case ETypeAnnotationKind::Tuple:
+ if (const auto dry = CommonType<Strict, true>(pos, underOne->Cast<TTupleExprType>(), underTwo->Cast<TTupleExprType>(), ctx))
+ return ctx.MakeType<TVariantExprType>(dry);
+ break;
+ case ETypeAnnotationKind::Struct:
+ if (const auto dry = CommonType<Strict, true>(pos, underOne->Cast<TStructExprType>(), underTwo->Cast<TStructExprType>(), ctx))
+ return ctx.MakeType<TVariantExprType>(dry);
+ break;
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+template<bool Strict>
+const TTaggedExprType* CommonType(TPositionHandle pos, const TTaggedExprType* one, const TTaggedExprType* two, TExprContext& ctx) {
+ const auto& tag = one->GetTag();
+ if (two->GetTag() != tag) {
+ ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Different tags '" << tag << "' and '" << two->GetTag() << "'."));
+ return nullptr;
+ }
+ if (const auto join = CommonType<Strict>(pos, one->GetBaseType(), two->GetBaseType(), ctx))
+ return ctx.MakeType<TTaggedExprType>(join, tag);
+ return nullptr;
+}
+
TExprNode::TPtr TryExpandSimpleType(TPositionHandle pos, const TStringBuf& type, TExprContext& ctx) {
TExprNode::TPtr result;
// backend is always ready for pragma FlexibleTypes;
@@ -1447,101 +1447,101 @@ TExprNode::TPtr TryExpandSimpleType(TPositionHandle pos, const TStringBuf& type,
return result;
}
-} // namespace
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target) {
- const auto sKind = source->GetKind();
- const auto tKind = target->GetKind();
-
- if (sKind == tKind) {
- switch (sKind) {
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::Null:
- return NUdf::ECastOptions::Complete;
- case ETypeAnnotationKind::Optional:
- return CastResult<Strong>(source->Cast<TOptionalExprType>(), target->Cast<TOptionalExprType>());
- case ETypeAnnotationKind::List:
- return CastResult<Strong>(source->Cast<TListExprType>(), target->Cast<TListExprType>());
- case ETypeAnnotationKind::Dict:
- return CastResult<Strong>(source->Cast<TDictExprType>(), target->Cast<TDictExprType>());
- case ETypeAnnotationKind::Tuple:
- return CastResult<Strong>(source->Cast<TTupleExprType>(), target->Cast<TTupleExprType>());
- case ETypeAnnotationKind::Struct:
- return CastResult<Strong>(source->Cast<TStructExprType>(), target->Cast<TStructExprType>());
- case ETypeAnnotationKind::Variant:
- return CastResult<Strong>(source->Cast<TVariantExprType>(), target->Cast<TVariantExprType>());
- case ETypeAnnotationKind::Data:
- return CastResult<Strong>(source->Cast<TDataExprType>(), target->Cast<TDataExprType>());
+} // namespace
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target) {
+ const auto sKind = source->GetKind();
+ const auto tKind = target->GetKind();
+
+ if (sKind == tKind) {
+ switch (sKind) {
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::Null:
+ return NUdf::ECastOptions::Complete;
+ case ETypeAnnotationKind::Optional:
+ return CastResult<Strong>(source->Cast<TOptionalExprType>(), target->Cast<TOptionalExprType>());
+ case ETypeAnnotationKind::List:
+ return CastResult<Strong>(source->Cast<TListExprType>(), target->Cast<TListExprType>());
+ case ETypeAnnotationKind::Dict:
+ return CastResult<Strong>(source->Cast<TDictExprType>(), target->Cast<TDictExprType>());
+ case ETypeAnnotationKind::Tuple:
+ return CastResult<Strong>(source->Cast<TTupleExprType>(), target->Cast<TTupleExprType>());
+ case ETypeAnnotationKind::Struct:
+ return CastResult<Strong>(source->Cast<TStructExprType>(), target->Cast<TStructExprType>());
+ case ETypeAnnotationKind::Variant:
+ return CastResult<Strong>(source->Cast<TVariantExprType>(), target->Cast<TVariantExprType>());
+ case ETypeAnnotationKind::Data:
+ return CastResult<Strong>(source->Cast<TDataExprType>(), target->Cast<TDataExprType>());
case ETypeAnnotationKind::Stream:
return CastResult<Strong>(source->Cast<TStreamExprType>(), target->Cast<TStreamExprType>());
case ETypeAnnotationKind::Flow:
return CastResult<Strong>(source->Cast<TFlowExprType>(), target->Cast<TFlowExprType>());
case ETypeAnnotationKind::Resource:
return source->Cast<TResourceExprType>()->GetTag() == target->Cast<TResourceExprType>()->GetTag() ? NUdf::ECastOptions::Complete : NUdf::ECastOptions::Impossible;
- default: break;
- }
- } else if (sKind == ETypeAnnotationKind::Null) {
- return tKind == ETypeAnnotationKind::Optional ? NUdf::ECastOptions::Complete : Strong ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::MayFail;
- } else if (tKind == ETypeAnnotationKind::Null) {
- return sKind == ETypeAnnotationKind::Optional ?
- Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData:
- Strong ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::AnywayLoseData;
- } else if (tKind == ETypeAnnotationKind::Optional) {
- return ReduceCastResult<Strong>(CastResult<Strong>(source, target->Cast<TOptionalExprType>()->GetItemType()));
- } else if (sKind == ETypeAnnotationKind::Optional) {
- return NUdf::ECastOptions::MayFail | CastResult<Strong>(source->Cast<TOptionalExprType>()->GetItemType(), target);
+ default: break;
+ }
+ } else if (sKind == ETypeAnnotationKind::Null) {
+ return tKind == ETypeAnnotationKind::Optional ? NUdf::ECastOptions::Complete : Strong ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::MayFail;
+ } else if (tKind == ETypeAnnotationKind::Null) {
+ return sKind == ETypeAnnotationKind::Optional ?
+ Strong ? NUdf::ECastOptions::MayFail : NUdf::ECastOptions::MayLoseData:
+ Strong ? NUdf::ECastOptions::Impossible : NUdf::ECastOptions::AnywayLoseData;
+ } else if (tKind == ETypeAnnotationKind::Optional) {
+ return ReduceCastResult<Strong>(CastResult<Strong>(source, target->Cast<TOptionalExprType>()->GetItemType()));
+ } else if (sKind == ETypeAnnotationKind::Optional) {
+ return NUdf::ECastOptions::MayFail | CastResult<Strong>(source->Cast<TOptionalExprType>()->GetItemType(), target);
} else if (tKind == ETypeAnnotationKind::List && sKind == ETypeAnnotationKind::EmptyList) {
return NUdf::ECastOptions::Complete;
} else if (tKind == ETypeAnnotationKind::Dict && sKind == ETypeAnnotationKind::EmptyDict) {
return NUdf::ECastOptions::Complete;
- }
-
- return NUdf::ECastOptions::Impossible;
-}
-
-template NUdf::TCastResultOptions CastResult<true>(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
-template NUdf::TCastResultOptions CastResult<false>(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
-
-template <bool Equality>
-ECompareOptions CanCompare(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right) {
- if (!(left && right)) {
- return ECompareOptions::Null;
- }
-
- const auto lKind = left->GetKind();
- const auto rKind = right->GetKind();
-
- if (lKind == rKind) {
- switch (lKind) {
- case ETypeAnnotationKind::Void: return ECompareOptions::Comparable;
- case ETypeAnnotationKind::Null: return ECompareOptions::Null;
+ }
+
+ return NUdf::ECastOptions::Impossible;
+}
+
+template NUdf::TCastResultOptions CastResult<true>(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
+template NUdf::TCastResultOptions CastResult<false>(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
+
+template <bool Equality>
+ECompareOptions CanCompare(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right) {
+ if (!(left && right)) {
+ return ECompareOptions::Null;
+ }
+
+ const auto lKind = left->GetKind();
+ const auto rKind = right->GetKind();
+
+ if (lKind == rKind) {
+ switch (lKind) {
+ case ETypeAnnotationKind::Void: return ECompareOptions::Comparable;
+ case ETypeAnnotationKind::Null: return ECompareOptions::Null;
case ETypeAnnotationKind::EmptyList: return ECompareOptions::Comparable;
case ETypeAnnotationKind::EmptyDict: return Equality ? ECompareOptions::Comparable : ECompareOptions::Uncomparable;
- case ETypeAnnotationKind::Optional:
- return CanCompare<Equality>(left->Cast<TOptionalExprType>(), right->Cast<TOptionalExprType>());
- case ETypeAnnotationKind::List:
- return CanCompare<Equality>(left->Cast<TListExprType>(), right->Cast<TListExprType>());
- case ETypeAnnotationKind::Dict:
- return CanCompare<Equality>(left->Cast<TDictExprType>(), right->Cast<TDictExprType>());
- case ETypeAnnotationKind::Tuple:
- return CanCompare<Equality>(left->Cast<TTupleExprType>(), right->Cast<TTupleExprType>());
- case ETypeAnnotationKind::Struct:
- return CanCompare<Equality>(left->Cast<TStructExprType>(), right->Cast<TStructExprType>());
- case ETypeAnnotationKind::Variant:
- return CanCompare<Equality>(left->Cast<TVariantExprType>(), right->Cast<TVariantExprType>());
- case ETypeAnnotationKind::Tagged:
- return CanCompare<Equality>(left->Cast<TTaggedExprType>(), right->Cast<TTaggedExprType>());
- case ETypeAnnotationKind::Data:
- return CanCompare(left->Cast<TDataExprType>(), right->Cast<TDataExprType>());
- default: break;
- }
- } else if (lKind == ETypeAnnotationKind::Null || rKind == ETypeAnnotationKind::Null) {
- return ECompareOptions::Null;
- } else if (lKind == ETypeAnnotationKind::Optional) {
- return AddOptional(CanCompare<Equality>(left->Cast<TOptionalExprType>()->GetItemType(), right));
- } else if (rKind == ETypeAnnotationKind::Optional) {
- return AddOptional(CanCompare<Equality>(left, right->Cast<TOptionalExprType>()->GetItemType()));
+ case ETypeAnnotationKind::Optional:
+ return CanCompare<Equality>(left->Cast<TOptionalExprType>(), right->Cast<TOptionalExprType>());
+ case ETypeAnnotationKind::List:
+ return CanCompare<Equality>(left->Cast<TListExprType>(), right->Cast<TListExprType>());
+ case ETypeAnnotationKind::Dict:
+ return CanCompare<Equality>(left->Cast<TDictExprType>(), right->Cast<TDictExprType>());
+ case ETypeAnnotationKind::Tuple:
+ return CanCompare<Equality>(left->Cast<TTupleExprType>(), right->Cast<TTupleExprType>());
+ case ETypeAnnotationKind::Struct:
+ return CanCompare<Equality>(left->Cast<TStructExprType>(), right->Cast<TStructExprType>());
+ case ETypeAnnotationKind::Variant:
+ return CanCompare<Equality>(left->Cast<TVariantExprType>(), right->Cast<TVariantExprType>());
+ case ETypeAnnotationKind::Tagged:
+ return CanCompare<Equality>(left->Cast<TTaggedExprType>(), right->Cast<TTaggedExprType>());
+ case ETypeAnnotationKind::Data:
+ return CanCompare(left->Cast<TDataExprType>(), right->Cast<TDataExprType>());
+ default: break;
+ }
+ } else if (lKind == ETypeAnnotationKind::Null || rKind == ETypeAnnotationKind::Null) {
+ return ECompareOptions::Null;
+ } else if (lKind == ETypeAnnotationKind::Optional) {
+ return AddOptional(CanCompare<Equality>(left->Cast<TOptionalExprType>()->GetItemType(), right));
+ } else if (rKind == ETypeAnnotationKind::Optional) {
+ return AddOptional(CanCompare<Equality>(left, right->Cast<TOptionalExprType>()->GetItemType()));
} else if (lKind == ETypeAnnotationKind::EmptyList && rKind == ETypeAnnotationKind::List) {
return CanCompare<Equality>(right->Cast<TListExprType>(), right->Cast<TListExprType>());
} else if (rKind == ETypeAnnotationKind::EmptyList && lKind == ETypeAnnotationKind::List) {
@@ -1550,151 +1550,151 @@ ECompareOptions CanCompare(const TTypeAnnotationNode* left, const TTypeAnnotatio
return CanCompare<Equality>(right->Cast<TDictExprType>(), right->Cast<TDictExprType>());
} else if (rKind == ETypeAnnotationKind::EmptyDict && lKind == ETypeAnnotationKind::Dict) {
return CanCompare<Equality>(left->Cast<TDictExprType>(), left->Cast<TDictExprType>());
- }
-
- return ECompareOptions::Uncomparable;
-}
-
-template ECompareOptions CanCompare<true>(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right);
-template ECompareOptions CanCompare<false>(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right);
-
-const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, bool& hasOptional, TExprContext& ctx) {
- if (type) {
- switch (type->GetKind()) {
- case ETypeAnnotationKind::Optional:
- hasOptional = true;
- return DryType(type->Cast<TOptionalExprType>()->GetItemType(), hasOptional, ctx);
- case ETypeAnnotationKind::Data:
- case ETypeAnnotationKind::Void:
- case ETypeAnnotationKind::EmptyList:
- case ETypeAnnotationKind::EmptyDict:
- return type;
- case ETypeAnnotationKind::Tuple:
- return DryType(type->Cast<TTupleExprType>(), hasOptional, ctx);
- case ETypeAnnotationKind::Struct:
- return DryType(type->Cast<TStructExprType>(), hasOptional, ctx);
- case ETypeAnnotationKind::List:
- return DryType(type->Cast<TListExprType>(), hasOptional, ctx);
- case ETypeAnnotationKind::Dict:
- return DryType(type->Cast<TDictExprType>(), hasOptional, ctx);
- case ETypeAnnotationKind::Variant:
- return DryType(type->Cast<TVariantExprType>(), hasOptional, ctx);
- case ETypeAnnotationKind::Tagged:
- return DryType(type->Cast<TTaggedExprType>(), hasOptional, ctx);
- default:
- break;
- }
- }
-
- return nullptr;
-}
-
-const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, TExprContext& ctx) {
- if (bool optional = false; const auto dry = DryType(type, optional, ctx))
- return optional ? ctx.MakeType<TOptionalExprType>(dry) : dry;
- return nullptr;
-}
-
-const TTypeAnnotationNode* JoinDryKeyType(const TTypeAnnotationNode* primary, const TTypeAnnotationNode* secondary, bool& hasOptional, TExprContext& ctx) {
- if (const auto dry = DryType(primary, hasOptional, ctx))
- if (!((NUdf::ECastOptions::AnywayLoseData | NUdf::ECastOptions::Impossible) & CastResult<true>(secondary, dry)))
- return dry;
- return nullptr;
-}
-
-template<bool Strict>
-const TTypeAnnotationNode* CommonType(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx) {
- if (!(one && two))
- return nullptr;
-
- if (IsSameAnnotation(*one, *two))
- return two;
-
- if (const auto kindOne = one->GetKind(), kindTwo = two->GetKind(); kindOne == kindTwo) {
- switch (kindOne) {
- case ETypeAnnotationKind::Data:
- return CommonType(pos, one->Cast<TDataExprType>(), two->Cast<TDataExprType>(), ctx);
- case ETypeAnnotationKind::Optional:
- return CommonItemType<Strict>(pos, one->Cast<TOptionalExprType>(), two->Cast<TOptionalExprType>(), ctx);
- case ETypeAnnotationKind::List:
- return CommonItemType<Strict>(pos, one->Cast<TListExprType>(), two->Cast<TListExprType>(), ctx);
- case ETypeAnnotationKind::Flow:
- return CommonItemType<Strict>(pos, one->Cast<TFlowExprType>(), two->Cast<TFlowExprType>(), ctx);
- case ETypeAnnotationKind::Stream:
- return CommonItemType<Strict>(pos, one->Cast<TStreamExprType>(), two->Cast<TStreamExprType>(), ctx);
- case ETypeAnnotationKind::Dict:
- return CommonType<Strict>(pos, one->Cast<TDictExprType>(), two->Cast<TDictExprType>(), ctx);
- case ETypeAnnotationKind::Tuple:
- return CommonType<Strict>(pos, one->Cast<TTupleExprType>(), two->Cast<TTupleExprType>(), ctx);
- case ETypeAnnotationKind::Struct:
- return CommonType<Strict>(pos, one->Cast<TStructExprType>(), two->Cast<TStructExprType>(), ctx);
- case ETypeAnnotationKind::Variant:
- return CommonType<Strict>(pos, one->Cast<TVariantExprType>(), two->Cast<TVariantExprType>(), ctx);
- case ETypeAnnotationKind::Tagged:
- return CommonType<Strict>(pos, one->Cast<TTaggedExprType>(), two->Cast<TTaggedExprType>(), ctx);
- default:
- break;
- }
- } else {
- if constexpr (!Strict) {
- if (ETypeAnnotationKind::Optional == kindOne) {
- if (ETypeAnnotationKind::Null == kindTwo)
- return one;
- else if (const auto itemType = CommonType<Strict>(pos, one->Cast<TOptionalExprType>()->GetItemType(), two, ctx))
- return ctx.MakeType<TOptionalExprType>(itemType);
- } else if (ETypeAnnotationKind::Optional == kindTwo) {
- if (ETypeAnnotationKind::Null == kindOne)
- return two;
- else if (const auto itemType = CommonType<Strict>(pos, one, two->Cast<TOptionalExprType>()->GetItemType(), ctx))
- return ctx.MakeType<TOptionalExprType>(itemType);
- } else if (ETypeAnnotationKind::Null == kindOne) {
- return ctx.MakeType<TOptionalExprType>(two);
- } else if (ETypeAnnotationKind::Null == kindTwo) {
- return ctx.MakeType<TOptionalExprType>(one);
- } else if (ETypeAnnotationKind::EmptyList == kindOne && ETypeAnnotationKind::List == kindTwo
- || ETypeAnnotationKind::EmptyDict == kindOne && ETypeAnnotationKind::Dict == kindTwo) {
- return two;
- } else if (ETypeAnnotationKind::EmptyList == kindTwo && ETypeAnnotationKind::List == kindOne
- || ETypeAnnotationKind::EmptyDict == kindTwo && ETypeAnnotationKind::Dict == kindOne) {
- return one;
- } else if (ETypeAnnotationKind::Resource == kindOne && ETypeAnnotationKind::Data == kindTwo) {
- if constexpr (!Strict)
- return CommonType(pos, one->Cast<TResourceExprType>(), two->Cast<TDataExprType>(), ctx);
- } else if (ETypeAnnotationKind::Resource == kindTwo && ETypeAnnotationKind::Data == kindOne) {
- if constexpr (!Strict)
- return CommonType(pos, two->Cast<TResourceExprType>(), one->Cast<TDataExprType>(), ctx);
- }
- }
-
- ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Cannot infer common type for " << kindOne << " and " << kindTwo));
- }
-
- return nullptr;
-}
-
-template const TTypeAnnotationNode* CommonType<true>(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
-template const TTypeAnnotationNode* CommonType<false>(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
-
-const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode::TSpanType& types, TExprContext& ctx) {
- switch (types.size()) {
- case 0U: return nullptr;
- case 1U: return types.front();
- case 2U: return CommonType<false>(position, types.front(), types.back(), ctx);
- default: break;
- }
-
- const auto left = types.size() >> 1U, right = types.size() - left;
- return CommonType<false>(position, CommonType(position, types.first(left), ctx), CommonType(position, types.last(right), ctx), ctx);
-}
-
-const TTypeAnnotationNode* CommonTypeForChildren(const TExprNode& node, TExprContext& ctx) {
- TTypeAnnotationNode::TListType types;
- types.reserve(node.ChildrenSize());
- node.ForEachChild([&](const TExprNode& item) { types.emplace_back(item.GetTypeAnn()); });
- return CommonType(node.Pos(), types, ctx);
-}
-
-size_t GetOptionalLevel(const TTypeAnnotationNode* type) {
+ }
+
+ return ECompareOptions::Uncomparable;
+}
+
+template ECompareOptions CanCompare<true>(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right);
+template ECompareOptions CanCompare<false>(const TTypeAnnotationNode* left, const TTypeAnnotationNode* right);
+
+const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, bool& hasOptional, TExprContext& ctx) {
+ if (type) {
+ switch (type->GetKind()) {
+ case ETypeAnnotationKind::Optional:
+ hasOptional = true;
+ return DryType(type->Cast<TOptionalExprType>()->GetItemType(), hasOptional, ctx);
+ case ETypeAnnotationKind::Data:
+ case ETypeAnnotationKind::Void:
+ case ETypeAnnotationKind::EmptyList:
+ case ETypeAnnotationKind::EmptyDict:
+ return type;
+ case ETypeAnnotationKind::Tuple:
+ return DryType(type->Cast<TTupleExprType>(), hasOptional, ctx);
+ case ETypeAnnotationKind::Struct:
+ return DryType(type->Cast<TStructExprType>(), hasOptional, ctx);
+ case ETypeAnnotationKind::List:
+ return DryType(type->Cast<TListExprType>(), hasOptional, ctx);
+ case ETypeAnnotationKind::Dict:
+ return DryType(type->Cast<TDictExprType>(), hasOptional, ctx);
+ case ETypeAnnotationKind::Variant:
+ return DryType(type->Cast<TVariantExprType>(), hasOptional, ctx);
+ case ETypeAnnotationKind::Tagged:
+ return DryType(type->Cast<TTaggedExprType>(), hasOptional, ctx);
+ default:
+ break;
+ }
+ }
+
+ return nullptr;
+}
+
+const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, TExprContext& ctx) {
+ if (bool optional = false; const auto dry = DryType(type, optional, ctx))
+ return optional ? ctx.MakeType<TOptionalExprType>(dry) : dry;
+ return nullptr;
+}
+
+const TTypeAnnotationNode* JoinDryKeyType(const TTypeAnnotationNode* primary, const TTypeAnnotationNode* secondary, bool& hasOptional, TExprContext& ctx) {
+ if (const auto dry = DryType(primary, hasOptional, ctx))
+ if (!((NUdf::ECastOptions::AnywayLoseData | NUdf::ECastOptions::Impossible) & CastResult<true>(secondary, dry)))
+ return dry;
+ return nullptr;
+}
+
+template<bool Strict>
+const TTypeAnnotationNode* CommonType(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx) {
+ if (!(one && two))
+ return nullptr;
+
+ if (IsSameAnnotation(*one, *two))
+ return two;
+
+ if (const auto kindOne = one->GetKind(), kindTwo = two->GetKind(); kindOne == kindTwo) {
+ switch (kindOne) {
+ case ETypeAnnotationKind::Data:
+ return CommonType(pos, one->Cast<TDataExprType>(), two->Cast<TDataExprType>(), ctx);
+ case ETypeAnnotationKind::Optional:
+ return CommonItemType<Strict>(pos, one->Cast<TOptionalExprType>(), two->Cast<TOptionalExprType>(), ctx);
+ case ETypeAnnotationKind::List:
+ return CommonItemType<Strict>(pos, one->Cast<TListExprType>(), two->Cast<TListExprType>(), ctx);
+ case ETypeAnnotationKind::Flow:
+ return CommonItemType<Strict>(pos, one->Cast<TFlowExprType>(), two->Cast<TFlowExprType>(), ctx);
+ case ETypeAnnotationKind::Stream:
+ return CommonItemType<Strict>(pos, one->Cast<TStreamExprType>(), two->Cast<TStreamExprType>(), ctx);
+ case ETypeAnnotationKind::Dict:
+ return CommonType<Strict>(pos, one->Cast<TDictExprType>(), two->Cast<TDictExprType>(), ctx);
+ case ETypeAnnotationKind::Tuple:
+ return CommonType<Strict>(pos, one->Cast<TTupleExprType>(), two->Cast<TTupleExprType>(), ctx);
+ case ETypeAnnotationKind::Struct:
+ return CommonType<Strict>(pos, one->Cast<TStructExprType>(), two->Cast<TStructExprType>(), ctx);
+ case ETypeAnnotationKind::Variant:
+ return CommonType<Strict>(pos, one->Cast<TVariantExprType>(), two->Cast<TVariantExprType>(), ctx);
+ case ETypeAnnotationKind::Tagged:
+ return CommonType<Strict>(pos, one->Cast<TTaggedExprType>(), two->Cast<TTaggedExprType>(), ctx);
+ default:
+ break;
+ }
+ } else {
+ if constexpr (!Strict) {
+ if (ETypeAnnotationKind::Optional == kindOne) {
+ if (ETypeAnnotationKind::Null == kindTwo)
+ return one;
+ else if (const auto itemType = CommonType<Strict>(pos, one->Cast<TOptionalExprType>()->GetItemType(), two, ctx))
+ return ctx.MakeType<TOptionalExprType>(itemType);
+ } else if (ETypeAnnotationKind::Optional == kindTwo) {
+ if (ETypeAnnotationKind::Null == kindOne)
+ return two;
+ else if (const auto itemType = CommonType<Strict>(pos, one, two->Cast<TOptionalExprType>()->GetItemType(), ctx))
+ return ctx.MakeType<TOptionalExprType>(itemType);
+ } else if (ETypeAnnotationKind::Null == kindOne) {
+ return ctx.MakeType<TOptionalExprType>(two);
+ } else if (ETypeAnnotationKind::Null == kindTwo) {
+ return ctx.MakeType<TOptionalExprType>(one);
+ } else if (ETypeAnnotationKind::EmptyList == kindOne && ETypeAnnotationKind::List == kindTwo
+ || ETypeAnnotationKind::EmptyDict == kindOne && ETypeAnnotationKind::Dict == kindTwo) {
+ return two;
+ } else if (ETypeAnnotationKind::EmptyList == kindTwo && ETypeAnnotationKind::List == kindOne
+ || ETypeAnnotationKind::EmptyDict == kindTwo && ETypeAnnotationKind::Dict == kindOne) {
+ return one;
+ } else if (ETypeAnnotationKind::Resource == kindOne && ETypeAnnotationKind::Data == kindTwo) {
+ if constexpr (!Strict)
+ return CommonType(pos, one->Cast<TResourceExprType>(), two->Cast<TDataExprType>(), ctx);
+ } else if (ETypeAnnotationKind::Resource == kindTwo && ETypeAnnotationKind::Data == kindOne) {
+ if constexpr (!Strict)
+ return CommonType(pos, two->Cast<TResourceExprType>(), one->Cast<TDataExprType>(), ctx);
+ }
+ }
+
+ ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Cannot infer common type for " << kindOne << " and " << kindTwo));
+ }
+
+ return nullptr;
+}
+
+template const TTypeAnnotationNode* CommonType<true>(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
+template const TTypeAnnotationNode* CommonType<false>(TPositionHandle pos, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
+
+const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode::TSpanType& types, TExprContext& ctx) {
+ switch (types.size()) {
+ case 0U: return nullptr;
+ case 1U: return types.front();
+ case 2U: return CommonType<false>(position, types.front(), types.back(), ctx);
+ default: break;
+ }
+
+ const auto left = types.size() >> 1U, right = types.size() - left;
+ return CommonType<false>(position, CommonType(position, types.first(left), ctx), CommonType(position, types.last(right), ctx), ctx);
+}
+
+const TTypeAnnotationNode* CommonTypeForChildren(const TExprNode& node, TExprContext& ctx) {
+ TTypeAnnotationNode::TListType types;
+ types.reserve(node.ChildrenSize());
+ node.ForEachChild([&](const TExprNode& item) { types.emplace_back(item.GetTypeAnn()); });
+ return CommonType(node.Pos(), types, ctx);
+}
+
+size_t GetOptionalLevel(const TTypeAnnotationNode* type) {
size_t level = 0;
YQL_ENSURE(type);
while (type->GetKind() == ETypeAnnotationKind::Optional) {
@@ -1702,8 +1702,8 @@ size_t GetOptionalLevel(const TTypeAnnotationNode* type) {
++level;
}
return level;
-}
-
+}
+
void ClearExprTypeAnnotations(TExprNode& root) {
for (auto& child : root.Children()) {
ClearExprTypeAnnotations(*child);
@@ -1819,10 +1819,10 @@ bool EnsureMaxArgsCount(const TExprNode& node, ui32 expectedArgs, TExprContext&
return true;
}
-bool EnsureMinMaxArgsCount(const TExprNode& node, ui32 minArgs, ui32 maxArgs, TExprContext& ctx) {
- return EnsureMinArgsCount(node, minArgs, ctx) && EnsureMaxArgsCount(node, maxArgs, ctx);
-}
-
+bool EnsureMinMaxArgsCount(const TExprNode& node, ui32 minArgs, ui32 maxArgs, TExprContext& ctx) {
+ return EnsureMinArgsCount(node, minArgs, ctx) && EnsureMaxArgsCount(node, maxArgs, ctx);
+}
+
bool EnsureCallableMinArgsCount(const TPositionHandle& pos, ui32 args, ui32 expectedArgs, TExprContext& ctx) {
if (args < expectedArgs) {
ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Callable expected at least " << expectedArgs << " argument(s), but got " << args));
@@ -1850,15 +1850,15 @@ bool EnsureAtom(const TExprNode& node, TExprContext& ctx) {
return true;
}
-bool EnsureCallable(const TExprNode& node, TExprContext& ctx) {
+bool EnsureCallable(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || node.Type() != TExprNode::Callable) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected callable, but got: " << node.Type()));
- return false;
- }
-
- return true;
-}
-
+ return false;
+ }
+
+ return true;
+}
+
bool EnsureTuple(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || node.Type() != TExprNode::List) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected tuple, but got: " << node.Type()));
@@ -1976,30 +1976,30 @@ bool EnsureTupleTypeSize(TPositionHandle position, const TTypeAnnotationNode* ty
return true;
}
-bool EnsureMultiType(const TExprNode& node, TExprContext& ctx) {
- if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected multi type, but got lambda"));
- return false;
- }
-
- if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Multi) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected multi type, but got: " << *node.GetTypeAnn()));
- return false;
- }
-
- return true;
-}
-
-bool EnsureMultiType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
- if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Multi) {
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected multi type, but got: " << type));
- return false;
- }
-
- return true;
-}
-
+bool EnsureMultiType(const TExprNode& node, TExprContext& ctx) {
+ if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected multi type, but got lambda"));
+ return false;
+ }
+
+ if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Multi) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected multi type, but got: " << *node.GetTypeAnn()));
+ return false;
+ }
+
+ return true;
+}
+
+bool EnsureMultiType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
+ if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Multi) {
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected multi type, but got: " << type));
+ return false;
+ }
+
+ return true;
+}
+
bool EnsureVariantType(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
YQL_ENSURE(node.Type() == TExprNode::Lambda);
@@ -2055,8 +2055,8 @@ IGraphTransformer::TStatus ConvertToLambda(TExprNode::TPtr& node, TExprContext&
const ui32 maxLambdaArgs = actualLambda.Child(0)->ChildrenSize();
const ui32 minLambdaArgs = maxLambdaArgs - optionalArgsCount;
- if (actualLambda.ChildrenSize() == 2U && actualLambda.Tail().IsLambda()) {
- ctx.AddError(TIssue(ctx.GetPosition(node->Tail().Pos()), TStringBuilder() << "Free lambda is not expected here"));
+ if (actualLambda.ChildrenSize() == 2U && actualLambda.Tail().IsLambda()) {
+ ctx.AddError(TIssue(ctx.GetPosition(node->Tail().Pos()), TStringBuilder() << "Free lambda is not expected here"));
return IGraphTransformer::TStatus::Error;
}
@@ -2139,8 +2139,8 @@ IGraphTransformer::TStatus ConvertToLambda(TExprNode::TPtr& node, TExprContext&
auto body = ctx.NewCallable(node->Pos(), "Apply", TExprNode::TListType(args));
args.erase(args.begin());
- auto arguments = ctx.NewArguments(node->Pos(), std::move(args));
- node = ctx.NewLambda(node->Pos(), std::move(arguments), std::move(body));
+ auto arguments = ctx.NewArguments(node->Pos(), std::move(args));
+ node = ctx.NewLambda(node->Pos(), std::move(arguments), std::move(body));
return IGraphTransformer::TStatus::Repeat;
}
@@ -2187,40 +2187,40 @@ bool EnsureSpecificDataType(TPositionHandle position, const TTypeAnnotationNode&
return true;
}
-bool EnsureStringOrUtf8Type(const TExprNode& node, TExprContext& ctx) {
- if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got lambda."));
- return false;
- }
-
- if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got: " << *node.GetTypeAnn()));
- return false;
- }
-
- if (const auto dataSlot = node.GetTypeAnn()->Cast<TDataExprType>()->GetSlot(); dataSlot != EDataSlot::String && dataSlot != EDataSlot::Utf8) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got: " << *node.GetTypeAnn()));
- return false;
- }
-
- return true;
-}
-
-bool EnsureStringOrUtf8Type(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
- if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Data) {
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected String or Utf8, but got: " << type));
- return false;
- }
-
- if (const auto dataSlot = type.Cast<TDataExprType>()->GetSlot(); dataSlot != EDataSlot::String && dataSlot != EDataSlot::Utf8) {
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected String or Utf8, but got: " << type));
- return false;
- }
-
- return true;
-}
-
+bool EnsureStringOrUtf8Type(const TExprNode& node, TExprContext& ctx) {
+ if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got lambda."));
+ return false;
+ }
+
+ if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Data) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got: " << *node.GetTypeAnn()));
+ return false;
+ }
+
+ if (const auto dataSlot = node.GetTypeAnn()->Cast<TDataExprType>()->GetSlot(); dataSlot != EDataSlot::String && dataSlot != EDataSlot::Utf8) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected String or Utf8, but got: " << *node.GetTypeAnn()));
+ return false;
+ }
+
+ return true;
+}
+
+bool EnsureStringOrUtf8Type(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
+ if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Data) {
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected String or Utf8, but got: " << type));
+ return false;
+ }
+
+ if (const auto dataSlot = type.Cast<TDataExprType>()->GetSlot(); dataSlot != EDataSlot::String && dataSlot != EDataSlot::Utf8) {
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected String or Utf8, but got: " << type));
+ return false;
+ }
+
+ return true;
+}
+
bool EnsureStructType(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
YQL_ENSURE(node.Type() == TExprNode::Lambda);
@@ -2357,7 +2357,7 @@ bool EnsureSpecificDataSource(const TExprNode& node, TStringBuf expectedCategory
return false;
}
- auto category = node.Head().Content();
+ auto category = node.Head().Content();
if (category != expectedCategory) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected datasource category: " << expectedCategory <<
", but got: " << category));
@@ -2379,7 +2379,7 @@ bool EnsureSpecificDataSink(const TExprNode& node, TStringBuf expectedCategory,
return false;
}
- auto category = node.Head().Content();
+ auto category = node.Head().Content();
if (category != expectedCategory) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected datasink category: " << expectedCategory <<
", but got: " << category));
@@ -2488,54 +2488,54 @@ bool EnsureStreamType(TPositionHandle position, const TTypeAnnotationNode& type,
return true;
}
-bool EnsureFlowType(const TExprNode& node, TExprContext& ctx) {
+bool EnsureFlowType(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected flow type, but got lambda"));
- return false;
- }
-
+ return false;
+ }
+
if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected flow type, but got: " << *node.GetTypeAnn()));
- return false;
- }
-
- return true;
-}
-
+ return false;
+ }
+
+ return true;
+}
+
bool EnsureFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
- if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Flow) {
+ if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Flow) {
ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected flow type, but got: " << type));
- return false;
- }
-
- return true;
-}
-
-bool EnsureWideFlowType(const TExprNode& node, TExprContext& ctx) {
- if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected wide flow type, but got lambda"));
- return false;
- }
-
- if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow || node.GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Multi) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected wide flow type, but got: " << *node.GetTypeAnn()));
- return false;
- }
-
- return true;
-}
-
-bool EnsureWideFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
- if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Flow || type.Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Multi) {
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected wide flow type, but got: " << type));
- return false;
- }
-
- return true;
-}
-
+ return false;
+ }
+
+ return true;
+}
+
+bool EnsureWideFlowType(const TExprNode& node, TExprContext& ctx) {
+ if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected wide flow type, but got lambda"));
+ return false;
+ }
+
+ if (node.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Flow || node.GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Multi) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected wide flow type, but got: " << *node.GetTypeAnn()));
+ return false;
+ }
+
+ return true;
+}
+
+bool EnsureWideFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
+ if (HasError(&type, ctx) || type.GetKind() != ETypeAnnotationKind::Flow || type.Cast<TFlowExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Multi) {
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected wide flow type, but got: " << type));
+ return false;
+ }
+
+ return true;
+}
+
bool EnsureOptionalType(const TExprNode& node, TExprContext& ctx) {
if (!node.GetTypeAnn()) {
YQL_ENSURE(node.Type() == TExprNode::Lambda);
@@ -2578,8 +2578,8 @@ IGraphTransformer::TStatus EnsureTypeRewrite(TExprNode::TPtr& node, TExprContext
YQL_ENSURE(node->Type() == TExprNode::Lambda);
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Expected type, but got lambda"));
return IGraphTransformer::TStatus::Error;
- }
-
+ }
+
if (node->IsCallable({"SqlColumnOrType", "SqlPlainColumnOrType", "SqlColumnFromType"})) {
ui32 typeNameIdx = node->IsCallable("SqlColumnFromType") ? 2 : 1;
auto typeNameNode = node->Child(typeNameIdx);
@@ -2591,16 +2591,16 @@ IGraphTransformer::TStatus EnsureTypeRewrite(TExprNode::TPtr& node, TExprContext
}
node = typeNode;
return IGraphTransformer::TStatus::Repeat;
- }
-
+ }
+
if (type->GetKind() != ETypeAnnotationKind::Type) {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Expected type, but got: " << *type));
return IGraphTransformer::TStatus::Error;
}
return IGraphTransformer::TStatus::Ok;
-}
-
+}
+
IGraphTransformer::TStatus EnsureTypeOrAtomRewrite(TExprNode::TPtr& node, TExprContext& ctx) {
if (node->Type() != TExprNode::Atom) {
return EnsureTypeRewrite(node, ctx);
@@ -2609,24 +2609,24 @@ IGraphTransformer::TStatus EnsureTypeOrAtomRewrite(TExprNode::TPtr& node, TExprC
return IGraphTransformer::TStatus::Ok;
}
-bool EnsureDryType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
- if (const auto dry = DryType(&type, ctx); !(dry && IsSameAnnotation(*dry, type))) {
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected dry type, but got: " << type));
- return false;
- }
- return true;
-}
-
-bool EnsureDryType(const TExprNode& node, TExprContext& ctx) {
- if (!node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected dry type, but got lambda."));
- return false;
- }
-
- return EnsureDryType(node.Pos(), *node.GetTypeAnn(), ctx);
-}
-
+bool EnsureDryType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx) {
+ if (const auto dry = DryType(&type, ctx); !(dry && IsSameAnnotation(*dry, type))) {
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() << "Expected dry type, but got: " << type));
+ return false;
+ }
+ return true;
+}
+
+bool EnsureDryType(const TExprNode& node, TExprContext& ctx) {
+ if (!node.GetTypeAnn()) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected dry type, but got lambda."));
+ return false;
+ }
+
+ return EnsureDryType(node.Pos(), *node.GetTypeAnn(), ctx);
+}
+
bool EnsureDictType(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx) || !node.GetTypeAnn()) {
YQL_ENSURE(node.Type() == TExprNode::Lambda);
@@ -2777,7 +2777,7 @@ bool EnsureComparableType(TPositionHandle position, const TTypeAnnotationNode& t
if (!type.IsComparable()) {
ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder()
- << "Expected comparable type, i.e. combination of Data, Optional, List or Tuple, but got:" << type));
+ << "Expected comparable type, i.e. combination of Data, Optional, List or Tuple, but got:" << type));
return false;
}
return true;
@@ -2791,42 +2791,42 @@ bool EnsureEquatableType(TPositionHandle position, const TTypeAnnotationNode& ty
if (!type.IsEquatable()) {
ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder()
<< "Expected equatable type, i.e. combination of Data, Optional, List, Dict, Tuple, Struct, or Variant, but got:" << type));
- return false;
- }
+ return false;
+ }
return true;
-}
-
-bool IsInstantEqual(const TTypeAnnotationNode& type) {
- switch (type.GetKind()) {
- case ETypeAnnotationKind::Null: return true;
- case ETypeAnnotationKind::Void: return true;
- case ETypeAnnotationKind::Tuple: {
- const auto tupleType = type.Cast<TTupleExprType>();
- if (const auto size = tupleType->GetSize()) {
- for (const auto& item : tupleType->GetItems()) {
- if (!IsInstantEqual(*item)) {
- return false;
- }
- }
- }
- break;
- }
- case ETypeAnnotationKind::Struct: {
- const auto structType = type.Cast<TStructExprType>();
- if (const auto size = structType->GetSize()) {
- for (const auto& item : structType->GetItems()) {
- if (!IsInstantEqual(*item)) {
- return false;
- }
- }
- }
- break;
- }
- default: return false;
- }
- return true;
-}
-
+}
+
+bool IsInstantEqual(const TTypeAnnotationNode& type) {
+ switch (type.GetKind()) {
+ case ETypeAnnotationKind::Null: return true;
+ case ETypeAnnotationKind::Void: return true;
+ case ETypeAnnotationKind::Tuple: {
+ const auto tupleType = type.Cast<TTupleExprType>();
+ if (const auto size = tupleType->GetSize()) {
+ for (const auto& item : tupleType->GetItems()) {
+ if (!IsInstantEqual(*item)) {
+ return false;
+ }
+ }
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Struct: {
+ const auto structType = type.Cast<TStructExprType>();
+ if (const auto size = structType->GetSize()) {
+ for (const auto& item : structType->GetItems()) {
+ if (!IsInstantEqual(*item)) {
+ return false;
+ }
+ }
+ }
+ break;
+ }
+ default: return false;
+ }
+ return true;
+}
+
static bool EnsureKeyProperty(TPositionHandle position, const TTypeAnnotationNode* keyType,
const std::function<bool(TPositionHandle, EDataSlot, TExprContext&)>& propertyCheck, TExprContext& ctx) {
@@ -2872,16 +2872,16 @@ bool EnsureEquatableKey(TPositionHandle position, const TTypeAnnotationNode* key
return EnsureKeyProperty(position, keyType, EnsureEquatableDataType, ctx);
}
-bool UpdateLambdaAllArgumentsTypes(TExprNode::TPtr& lambda, const std::vector<const TTypeAnnotationNode*>& argumentsAnnotations, TExprContext& ctx) {
+bool UpdateLambdaAllArgumentsTypes(TExprNode::TPtr& lambda, const std::vector<const TTypeAnnotationNode*>& argumentsAnnotations, TExprContext& ctx) {
YQL_ENSURE(lambda->Type() == TExprNode::Lambda);
-
- const auto& args = lambda->Head();
- auto argsChildren = args.ChildrenList();
- YQL_ENSURE(argsChildren.size() == argumentsAnnotations.size());
-
+
+ const auto& args = lambda->Head();
+ auto argsChildren = args.ChildrenList();
+ YQL_ENSURE(argsChildren.size() == argumentsAnnotations.size());
+
bool updateArgs = false;
- for (size_t i = 0U; i < argumentsAnnotations.size(); ++i) {
- const auto arg = args.Child(i);
+ for (size_t i = 0U; i < argumentsAnnotations.size(); ++i) {
+ const auto arg = args.Child(i);
if (!arg->GetTypeAnn() || !IsSameAnnotation(*arg->GetTypeAnn(), *argumentsAnnotations[i])) {
updateArgs = true;
break;
@@ -2902,20 +2902,20 @@ bool UpdateLambdaAllArgumentsTypes(TExprNode::TPtr& lambda, const std::vector<co
argsChildren[i] = std::move(newArg);
}
- auto newArgs = ctx.NewArguments(args.Pos(), std::move(argsChildren));
+ auto newArgs = ctx.NewArguments(args.Pos(), std::move(argsChildren));
newArgs->SetTypeAnn(ctx.MakeType<TUnitExprType>());
- lambda = ctx.NewLambda(lambda->Pos(), std::move(newArgs), ctx.ReplaceNodes(GetLambdaBody(*lambda), replaces));
+ lambda = ctx.NewLambda(lambda->Pos(), std::move(newArgs), ctx.ReplaceNodes(GetLambdaBody(*lambda), replaces));
return true;
}
-bool UpdateLambdaArgumentsType(const TExprNode& lambda, TExprContext& ctx) {
- YQL_ENSURE(lambda.Type() == TExprNode::Lambda);
- const auto args = lambda.Child(0);
- YQL_ENSURE(0U == args->ChildrenSize());
+bool UpdateLambdaArgumentsType(const TExprNode& lambda, TExprContext& ctx) {
+ YQL_ENSURE(lambda.Type() == TExprNode::Lambda);
+ const auto args = lambda.Child(0);
+ YQL_ENSURE(0U == args->ChildrenSize());
args->SetTypeAnn(ctx.MakeType<TUnitExprType>());
- return true;
-}
-
+ return true;
+}
+
bool EnsureDataOrOptionalOfData(const TExprNode& node, bool& isOptional, const TDataExprType*& dataType, TExprContext& ctx) {
if (!node.GetTypeAnn()) {
YQL_ENSURE(node.Type() == TExprNode::Lambda);
@@ -3053,35 +3053,35 @@ bool EnsureListOrOptionalType(const TExprNode& node, TExprContext& ctx) {
return true;
}
-bool EnsureListOrOptionalListType(const TExprNode& node, TExprContext& ctx) {
- if (HasError(node.GetTypeAnn(), ctx)) {
- return false;
- }
-
- const auto type = node.GetTypeAnn();
- if (!type) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
+bool EnsureListOrOptionalListType(const TExprNode& node, TExprContext& ctx) {
+ if (HasError(node.GetTypeAnn(), ctx)) {
+ return false;
+ }
+
+ const auto type = node.GetTypeAnn();
+ if (!type) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected either list or optional of list, but got lambda"));
- return false;
- }
-
- const auto kind = type->GetKind();
- if (kind != ETypeAnnotationKind::List && kind != ETypeAnnotationKind::Optional) {
+ return false;
+ }
+
+ const auto kind = type->GetKind();
+ if (kind != ETypeAnnotationKind::List && kind != ETypeAnnotationKind::Optional) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected either list or optional of list, but got: " << *type));
- return false;
- }
-
- if (kind == ETypeAnnotationKind::Optional) {
- const auto itemType = type->Cast<TOptionalExprType>()->GetItemType();
- if (itemType->GetKind() != ETypeAnnotationKind::List) {
+ return false;
+ }
+
+ if (kind == ETypeAnnotationKind::Optional) {
+ const auto itemType = type->Cast<TOptionalExprType>()->GetItemType();
+ if (itemType->GetKind() != ETypeAnnotationKind::List) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Expected either list or optional of list, but got: " << *itemType));
- return false;
- }
- }
-
- return true;
-}
-
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool EnsureSeqType(const TExprNode& node, TExprContext& ctx, bool* isStream) {
if (HasError(node.GetTypeAnn(), ctx)) {
return false;
@@ -3150,76 +3150,76 @@ bool EnsureSeqOrOptionalType(TPositionHandle position, const TTypeAnnotationNode
return true;
}
-template <bool WithOptional, bool WithList, bool WithStream>
-bool EnsureNewSeqType(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType) {
- if (HasError(node.GetTypeAnn(), ctx)) {
- return false;
- }
-
- if (!node.GetTypeAnn()) {
- YQL_ENSURE(node.Type() == TExprNode::Lambda);
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() <<
- (WithList ?
- (WithOptional ? "Expected flow, list, stream or optional, but got lambda." : "Expected flow, list or stream, but got lambda."):
- (WithOptional ? "Expected flow, stream or optional, but got lambda." : "Expected flow or stream, but got lambda.")
- )));
- return false;
- }
-
- return EnsureNewSeqType<WithOptional, WithList, WithStream>(node.Pos(), *node.GetTypeAnn(), ctx, itemType);
-}
-
-template <bool WithOptional, bool WithList, bool WithStream>
-bool EnsureNewSeqType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx, const TTypeAnnotationNode** itemType) {
- if (HasError(&type, ctx)) {
- return false;
- }
-
- switch (type.GetKind()) {
- case ETypeAnnotationKind::Flow:
- if (itemType) {
- *itemType = type.Cast<TFlowExprType>()->GetItemType();
- }
- return true;
- case ETypeAnnotationKind::Stream:
- if constexpr (WithStream) {
- if (itemType) {
- *itemType = type.Cast<TStreamExprType>()->GetItemType();
- }
- }
- return true;
- case ETypeAnnotationKind::List:
- if constexpr (WithList) {
- if (itemType) {
- *itemType = type.Cast<TListExprType>()->GetItemType();
- }
- return true;
- }
- break;
- case ETypeAnnotationKind::Optional:
- if constexpr (WithOptional) {
- if (itemType) {
- *itemType = type.Cast<TOptionalExprType>()->GetItemType();
- }
- return true;
- }
- break;
- default: break;
- }
- ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() <<
- (WithList ?
- (WithOptional ? "Expected flow, list, stream or optional, but got: " : "Expected flow, list or stream, but got: "):
- (WithOptional ? "Expected flow, stream or optional, but got: " : "Expected flow or stream, but got: ")
- ) << type));
- return false;
-}
-
-template bool EnsureNewSeqType<true, false, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
-template bool EnsureNewSeqType<false, false, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
-template bool EnsureNewSeqType<true, true, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
-template bool EnsureNewSeqType<false, true, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
-template bool EnsureNewSeqType<false, true, false>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
-
+template <bool WithOptional, bool WithList, bool WithStream>
+bool EnsureNewSeqType(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType) {
+ if (HasError(node.GetTypeAnn(), ctx)) {
+ return false;
+ }
+
+ if (!node.GetTypeAnn()) {
+ YQL_ENSURE(node.Type() == TExprNode::Lambda);
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() <<
+ (WithList ?
+ (WithOptional ? "Expected flow, list, stream or optional, but got lambda." : "Expected flow, list or stream, but got lambda."):
+ (WithOptional ? "Expected flow, stream or optional, but got lambda." : "Expected flow or stream, but got lambda.")
+ )));
+ return false;
+ }
+
+ return EnsureNewSeqType<WithOptional, WithList, WithStream>(node.Pos(), *node.GetTypeAnn(), ctx, itemType);
+}
+
+template <bool WithOptional, bool WithList, bool WithStream>
+bool EnsureNewSeqType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx, const TTypeAnnotationNode** itemType) {
+ if (HasError(&type, ctx)) {
+ return false;
+ }
+
+ switch (type.GetKind()) {
+ case ETypeAnnotationKind::Flow:
+ if (itemType) {
+ *itemType = type.Cast<TFlowExprType>()->GetItemType();
+ }
+ return true;
+ case ETypeAnnotationKind::Stream:
+ if constexpr (WithStream) {
+ if (itemType) {
+ *itemType = type.Cast<TStreamExprType>()->GetItemType();
+ }
+ }
+ return true;
+ case ETypeAnnotationKind::List:
+ if constexpr (WithList) {
+ if (itemType) {
+ *itemType = type.Cast<TListExprType>()->GetItemType();
+ }
+ return true;
+ }
+ break;
+ case ETypeAnnotationKind::Optional:
+ if constexpr (WithOptional) {
+ if (itemType) {
+ *itemType = type.Cast<TOptionalExprType>()->GetItemType();
+ }
+ return true;
+ }
+ break;
+ default: break;
+ }
+ ctx.AddError(TIssue(ctx.GetPosition(position), TStringBuilder() <<
+ (WithList ?
+ (WithOptional ? "Expected flow, list, stream or optional, but got: " : "Expected flow, list or stream, but got: "):
+ (WithOptional ? "Expected flow, stream or optional, but got: " : "Expected flow or stream, but got: ")
+ ) << type));
+ return false;
+}
+
+template bool EnsureNewSeqType<true, false, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
+template bool EnsureNewSeqType<false, false, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
+template bool EnsureNewSeqType<true, true, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
+template bool EnsureNewSeqType<false, true, true>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
+template bool EnsureNewSeqType<false, true, false>(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType);
+
bool EnsureStructOrOptionalStructType(const TExprNode& node, TExprContext& ctx) {
if (HasError(node.GetTypeAnn(), ctx)) {
return false;
@@ -3320,18 +3320,18 @@ bool EnsureCodeResourceType(const TExprNode& node, TExprContext& ctx) {
return true;
}
-const TTypeAnnotationNode* MakeSequenceType(ETypeAnnotationKind sequenceKind, const TTypeAnnotationNode& itemType, TExprContext& ctx) {
- switch (sequenceKind) {
- case ETypeAnnotationKind::Optional: return ctx.MakeType<TOptionalExprType>(&itemType);
- case ETypeAnnotationKind::Flow: return ctx.MakeType<TFlowExprType>(&itemType);
- case ETypeAnnotationKind::List: return ctx.MakeType<TListExprType>(&itemType);
- case ETypeAnnotationKind::Stream: return ctx.MakeType<TStreamExprType>(&itemType);
- default: break;
- }
-
- ythrow yexception() << "Wrong sequence kind.";
-}
-
+const TTypeAnnotationNode* MakeSequenceType(ETypeAnnotationKind sequenceKind, const TTypeAnnotationNode& itemType, TExprContext& ctx) {
+ switch (sequenceKind) {
+ case ETypeAnnotationKind::Optional: return ctx.MakeType<TOptionalExprType>(&itemType);
+ case ETypeAnnotationKind::Flow: return ctx.MakeType<TFlowExprType>(&itemType);
+ case ETypeAnnotationKind::List: return ctx.MakeType<TListExprType>(&itemType);
+ case ETypeAnnotationKind::Stream: return ctx.MakeType<TStreamExprType>(&itemType);
+ default: break;
+ }
+
+ ythrow yexception() << "Wrong sequence kind.";
+}
+
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
TExprContext& ctx, TConvertFlags flags) {
if (HasError(node->GetTypeAnn(), ctx)) {
@@ -3341,7 +3341,7 @@ IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnota
if (node->Type() == TExprNode::Lambda) {
if (expectedType.GetKind() == ETypeAnnotationKind::Callable) {
auto callableType = expectedType.Cast<TCallableExprType>();
- auto lambdaArgsCount = node->Head().ChildrenSize();
+ auto lambdaArgsCount = node->Head().ChildrenSize();
if (lambdaArgsCount != callableType->GetArgumentsSize()) {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << "Wrong number of lambda arguments: "
<< lambdaArgsCount << ", failed to convert lambda to " << expectedType));
@@ -3360,7 +3360,7 @@ IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnota
return TryConvertTo(node, *node->GetTypeAnn(), expectedType, ctx, flags);
}
-IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
+IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags) {
if (HasError(node->GetTypeAnn(), ctx)) {
return IGraphTransformer::TStatus::Error;
@@ -3375,12 +3375,12 @@ IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnota
return status;
}
-IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
+IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
TExprContext& ctx, TConvertFlags flags) {
if (node->Type() == TExprNode::Lambda) {
if (expectedType.GetKind() == ETypeAnnotationKind::Callable) {
auto callableType = expectedType.Cast<TCallableExprType>();
- auto lambdaArgsCount = node->Head().ChildrenSize();
+ auto lambdaArgsCount = node->Head().ChildrenSize();
if (lambdaArgsCount != callableType->GetArgumentsSize()) {
return IGraphTransformer::TStatus::Error;
}
@@ -3396,7 +3396,7 @@ IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TType
return TrySilentConvertTo(node, *node->GetTypeAnn(), expectedType, ctx, flags);
}
-IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
+IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags) {
return TryConvertToImpl(ctx, node, sourceType, expectedType, flags);
}
@@ -3413,16 +3413,16 @@ bool IsDataTypeIntegral(EDataSlot dataSlot) {
return NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::IntegralType;
}
-bool IsDataTypeSigned(EDataSlot dataSlot) {
- return NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::SignedIntegralType;
-}
-
+bool IsDataTypeSigned(EDataSlot dataSlot) {
+ return NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::SignedIntegralType;
+}
+
bool IsDataTypeUnsigned(EDataSlot dataSlot) {
return NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::UnsignedIntegralType;
}
-bool IsDataTypeDateOrTzDateOrInterval(EDataSlot dataSlot) {
- return NUdf::GetDataTypeInfo(dataSlot).Features & (NUdf::DateType | NUdf::TzDateType | NUdf::TimeIntervalType);
+bool IsDataTypeDateOrTzDateOrInterval(EDataSlot dataSlot) {
+ return NUdf::GetDataTypeInfo(dataSlot).Features & (NUdf::DateType | NUdf::TzDateType | NUdf::TimeIntervalType);
}
bool IsDataTypeDateOrTzDate(EDataSlot dataSlot) {
@@ -3434,7 +3434,7 @@ bool IsDataTypeInterval(EDataSlot dataSlot) {
}
bool IsDataTypeDate(EDataSlot dataSlot) {
- return (NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::DateType);
+ return (NUdf::GetDataTypeInfo(dataSlot).Features & NUdf::DateType);
}
bool IsDataTypeTzDate(EDataSlot dataSlot) {
@@ -3455,8 +3455,8 @@ EDataSlot WithTzDate(EDataSlot dataSlot) {
}
return dataSlot;
-}
-
+}
+
EDataSlot WithoutTzDate(EDataSlot dataSlot) {
if (dataSlot == EDataSlot::TzDate) {
return EDataSlot::Date;
@@ -3471,30 +3471,30 @@ EDataSlot WithoutTzDate(EDataSlot dataSlot) {
}
return dataSlot;
-}
-
-EDataSlot MakeSigned(EDataSlot dataSlot) {
- switch (dataSlot) {
- case EDataSlot::Uint8: return EDataSlot::Int8;
- case EDataSlot::Uint16: return EDataSlot::Int16;
- case EDataSlot::Uint32: return EDataSlot::Int32;
- case EDataSlot::Uint64: return EDataSlot::Int64;
- default: return dataSlot;
- }
-}
-
-EDataSlot MakeUnsigned(EDataSlot dataSlot) {
- switch (dataSlot) {
- case EDataSlot::Int8: return EDataSlot::Uint8;
- case EDataSlot::Int16: return EDataSlot::Uint16;
- case EDataSlot::Int32: return EDataSlot::Uint32;
- case EDataSlot::Int64: return EDataSlot::Uint64;
- default: return dataSlot;
- }
-}
-
+}
+
+EDataSlot MakeSigned(EDataSlot dataSlot) {
+ switch (dataSlot) {
+ case EDataSlot::Uint8: return EDataSlot::Int8;
+ case EDataSlot::Uint16: return EDataSlot::Int16;
+ case EDataSlot::Uint32: return EDataSlot::Int32;
+ case EDataSlot::Uint64: return EDataSlot::Int64;
+ default: return dataSlot;
+ }
+}
+
+EDataSlot MakeUnsigned(EDataSlot dataSlot) {
+ switch (dataSlot) {
+ case EDataSlot::Int8: return EDataSlot::Uint8;
+ case EDataSlot::Int16: return EDataSlot::Uint16;
+ case EDataSlot::Int32: return EDataSlot::Uint32;
+ case EDataSlot::Int64: return EDataSlot::Uint64;
+ default: return dataSlot;
+ }
+}
+
bool IsDataTypeDecimal(EDataSlot dataSlot) {
- return dataSlot == EDataSlot::Decimal;
+ return dataSlot == EDataSlot::Decimal;
}
ui8 GetDecimalWidthOfIntegral(EDataSlot dataSlot) {
@@ -3541,32 +3541,32 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, TExprNo
IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const TTypeAnnotationNode& type1,
TExprNode::TPtr& node2, const TTypeAnnotationNode& type2, TExprContext& ctx,
const TTypeAnnotationNode*& commonType, TConvertFlags flags) {
- if (IsSameAnnotation(type1, type2)) {
- commonType = &type1;
- return IGraphTransformer::TStatus::Ok;
- }
-
+ if (IsSameAnnotation(type1, type2)) {
+ commonType = &type1;
+ return IGraphTransformer::TStatus::Ok;
+ }
+
auto newFlags = flags;
newFlags.Set(NConvertFlags::DisableTruncation);
- if (const auto status = TrySilentConvertTo(node1, type1, type2, ctx, newFlags); status != IGraphTransformer::TStatus::Error) {
+ if (const auto status = TrySilentConvertTo(node1, type1, type2, ctx, newFlags); status != IGraphTransformer::TStatus::Error) {
commonType = &type2;
- return status;
+ return status;
}
- if (const auto status = TrySilentConvertTo(node2, type2, type1, ctx, newFlags); status != IGraphTransformer::TStatus::Error) {
+ if (const auto status = TrySilentConvertTo(node2, type2, type1, ctx, newFlags); status != IGraphTransformer::TStatus::Error) {
commonType = &type1;
- return status;
+ return status;
}
if (type2.GetKind() == ETypeAnnotationKind::Optional && type1.GetKind() != ETypeAnnotationKind::Optional) {
auto type1Opt = ctx.MakeType<TOptionalExprType>(&type1);
auto prev = node1;
- node1 = ctx.NewCallable(node1->Pos(), "Just", { std::move(node1) });
+ node1 = ctx.NewCallable(node1->Pos(), "Just", { std::move(node1) });
const TTypeAnnotationNode* commonItemType;
- if (SilentInferCommonType(node1, *type1Opt, node2, type2, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(node1, *type1Opt, node2, type2, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
commonType = commonItemType;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
node1 = prev;
@@ -3575,12 +3575,12 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
if (type1.GetKind() == ETypeAnnotationKind::Optional && type2.GetKind() != ETypeAnnotationKind::Optional) {
auto type2Opt = ctx.MakeType<TOptionalExprType>(&type2);
auto prev = node2;
- node2 = ctx.NewCallable(node2->Pos(), "Just", { std::move(node2) });
+ node2 = ctx.NewCallable(node2->Pos(), "Just", { std::move(node2) });
const TTypeAnnotationNode* commonItemType;
- if (SilentInferCommonType(node1, type1, node2, *type2Opt, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(node1, type1, node2, *type2Opt, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
commonType = commonItemType;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
node2 = prev;
@@ -3590,13 +3590,13 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
if (type2.GetKind() == ETypeAnnotationKind::Optional) {
node1 = ctx.NewCallable(node1->Pos(), "Nothing", { ExpandType(node2->Pos(), type2, ctx) });
commonType = &type2;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
} else {
auto type2Opt = ctx.MakeType<TOptionalExprType>(&type2);
node1 = ctx.NewCallable(node1->Pos(), "Nothing", { ExpandType(node2->Pos(), *type2Opt, ctx) });
- node2 = ctx.NewCallable(node2->Pos(), "Just", { std::move(node2) });
+ node2 = ctx.NewCallable(node2->Pos(), "Just", { std::move(node2) });
commonType = type2Opt;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
@@ -3604,14 +3604,14 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
if (type1.GetKind() == ETypeAnnotationKind::Optional) {
node2 = ctx.NewCallable(node2->Pos(), "Nothing", { ExpandType(node1->Pos(), type1, ctx) });
commonType = &type1;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
else {
auto type1Opt = ctx.MakeType<TOptionalExprType>(&type1);
node2 = ctx.NewCallable(node2->Pos(), "Nothing", { ExpandType(node1->Pos(), *type1Opt, ctx) });
- node1 = ctx.NewCallable(node1->Pos(), "Just", { std::move(node1) });
+ node1 = ctx.NewCallable(node1->Pos(), "Just", { std::move(node1) });
commonType = type1Opt;
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
@@ -3632,7 +3632,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto item1 = arg1;
auto item2 = arg2;
const TTypeAnnotationNode* commonItemType;
- if (SilentInferCommonType(item1, *item1type, item2, *item2type, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(item1, *item1type, item2, *item2type, ctx, commonItemType, flags) != IGraphTransformer::TStatus::Error) {
if (item1 != arg1) {
node1 = ctx.Builder(node1->Pos())
.Callable("OrderedMap")
@@ -3656,7 +3656,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
} else {
commonType = ctx.MakeType<TOptionalExprType>(commonItemType);
}
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
@@ -3671,11 +3671,11 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
for (ui32 i = 0; i < tupleType1->GetSize(); ++i) {
auto item1type = tupleType1->GetItems()[i];
auto item2type = tupleType2->GetItems()[i];
- auto atom = ctx.NewAtom(TPositionHandle(), ToString(i), TNodeFlags::Default);
+ auto atom = ctx.NewAtom(TPositionHandle(), ToString(i), TNodeFlags::Default);
auto arg1 = ctx.NewCallable(node1->Pos(), "Nth", { node1, atom });
auto arg2 = ctx.NewCallable(node2->Pos(), "Nth", { node2, atom });
const TTypeAnnotationNode* commonItemType;
- if (SilentInferCommonType(arg1, *item1type, arg2, *item2type, ctx, commonItemType, flags) == IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(arg1, *item1type, arg2, *item2type, ctx, commonItemType, flags) == IGraphTransformer::TStatus::Error) {
hasError = true;
break;
}
@@ -3689,7 +3689,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
commonType = ctx.MakeType<TTupleExprType>(commonItemTypes);
node1 = ctx.NewList(node1->Pos(), std::move(leftItems));
node2 = ctx.NewList(node2->Pos(), std::move(rightItems));
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
}
@@ -3720,7 +3720,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto arg1 = ctx.NewCallable(node1->Pos(), "Member", { node1, atom });
auto arg2 = ctx.NewCallable(node2->Pos(), "Member", { node2, atom });
const TTypeAnnotationNode* commonItemType;
- if (SilentInferCommonType(arg1, *member1->GetItemType(), arg2, *member2->GetItemType(), ctx, commonItemType, flags) == IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(arg1, *member1->GetItemType(), arg2, *member2->GetItemType(), ctx, commonItemType, flags) == IGraphTransformer::TStatus::Error) {
hasError = true;
break;
}
@@ -3786,7 +3786,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
commonType = ctx.MakeType<TStructExprType>(commonItemTypes);
node1 = ctx.NewCallable(node1->Pos(), "AsStruct", std::move(leftItems));
node2 = ctx.NewCallable(node2->Pos(), "AsStruct", std::move(rightItems));
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
@@ -3798,15 +3798,15 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
if (key1type == key2type) {
auto arg1 = ctx.NewArgument(node1->Pos(), "arg1");
auto arg2 = ctx.NewArgument(node2->Pos(), "arg2");
- auto key1 = ctx.NewCallable(node1->Pos(), "Nth", { arg1, ctx.NewAtom(node1->Pos(), "0", TNodeFlags::Default) });
- auto value1 = ctx.NewCallable(node1->Pos(), "Nth", { arg1, ctx.NewAtom(node1->Pos(), "1", TNodeFlags::Default) });
- auto key2 = ctx.NewCallable(node2->Pos(), "Nth", { arg2, ctx.NewAtom(node2->Pos(), "0", TNodeFlags::Default) });
- auto value2 = ctx.NewCallable(node2->Pos(), "Nth", { arg2, ctx.NewAtom(node2->Pos(), "1", TNodeFlags::Default) });
+ auto key1 = ctx.NewCallable(node1->Pos(), "Nth", { arg1, ctx.NewAtom(node1->Pos(), "0", TNodeFlags::Default) });
+ auto value1 = ctx.NewCallable(node1->Pos(), "Nth", { arg1, ctx.NewAtom(node1->Pos(), "1", TNodeFlags::Default) });
+ auto key2 = ctx.NewCallable(node2->Pos(), "Nth", { arg2, ctx.NewAtom(node2->Pos(), "0", TNodeFlags::Default) });
+ auto value2 = ctx.NewCallable(node2->Pos(), "Nth", { arg2, ctx.NewAtom(node2->Pos(), "1", TNodeFlags::Default) });
auto oldValue1 = value1;
auto oldValue2 = value2;
const TTypeAnnotationNode* commonPayloadType;
- if (SilentInferCommonType(value1, *payload1type, value2, *payload2type, ctx, commonPayloadType, flags) != IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(value1, *payload1type, value2, *payload2type, ctx, commonPayloadType, flags) != IGraphTransformer::TStatus::Error) {
if (oldValue1 != value1) {
auto body1 = ctx.NewList(node1->Pos(), { key1, value1 });
auto lambda1 = ctx.NewLambda(node1->Pos(), ctx.NewArguments(node1->Pos(), { arg1 }), std::move(body1));
@@ -3820,7 +3820,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
}
commonType = ctx.MakeType<TDictExprType>(key1type, commonPayloadType);
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
}
@@ -3834,11 +3834,11 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
const TTypeAnnotationNode* commonBaseType;
auto arg1 = ctx.NewCallable(node1->Pos(), "Untag", { node1, atom });
auto arg2 = ctx.NewCallable(node2->Pos(), "Untag", { node2, atom });
- if (SilentInferCommonType(arg1, *taggedType1->GetBaseType(), arg2, *taggedType2->GetBaseType(), ctx, commonBaseType, flags) != IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(arg1, *taggedType1->GetBaseType(), arg2, *taggedType2->GetBaseType(), ctx, commonBaseType, flags) != IGraphTransformer::TStatus::Error) {
commonType = ctx.MakeType<TTaggedExprType>(commonBaseType, taggedType1->GetTag());
node1 = ctx.NewCallable(node1->Pos(), "AsTagged", { arg1, atom });
node2 = ctx.NewCallable(node2->Pos(), "AsTagged", { arg2, atom });
- return IGraphTransformer::TStatus::Repeat;
+ return IGraphTransformer::TStatus::Repeat;
}
}
}
@@ -3875,7 +3875,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto originalArg2 = arg2;
const TTypeAnnotationNode* commonBaseType;
- if (SilentInferCommonType(arg1, *elem1, arg2, *elem2, ctx, commonBaseType, flags) == IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(arg1, *elem1, arg2, *elem2, ctx, commonBaseType, flags) == IGraphTransformer::TStatus::Error) {
return IGraphTransformer::TStatus::Error;
}
@@ -3895,7 +3895,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto arg1 = ctx.Builder(node1->Pos())
.Callable("Variant")
.Add(0, std::move(args1[i]))
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Add(2, commonTypeExpr)
.Seal()
.Build();
@@ -3906,7 +3906,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto arg2 = ctx.Builder(node2->Pos())
.Callable("Variant")
.Add(0, std::move(args2[i]))
- .Atom(1, ToString(i), TNodeFlags::Default)
+ .Atom(1, ToString(i), TNodeFlags::Default)
.Add(2, commonTypeExpr)
.Seal()
.Build();
@@ -3956,7 +3956,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
auto originalArg2 = arg2;
const TTypeAnnotationNode* commonBaseType;
- if (SilentInferCommonType(arg1, *elem1->GetItemType(), arg2, *elem2->GetItemType(), ctx, commonBaseType, flags) == IGraphTransformer::TStatus::Error) {
+ if (SilentInferCommonType(arg1, *elem1->GetItemType(), arg2, *elem2->GetItemType(), ctx, commonBaseType, flags) == IGraphTransformer::TStatus::Error) {
return IGraphTransformer::TStatus::Error;
}
@@ -4017,30 +4017,30 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
node2 = RebuildVariant(node2, transforms2, ctx);
}
- return changed1 || changed2 ? IGraphTransformer::TStatus::Repeat : IGraphTransformer::TStatus::Ok;
+ return changed1 || changed2 ? IGraphTransformer::TStatus::Repeat : IGraphTransformer::TStatus::Ok;
}
return IGraphTransformer::TStatus::Error;
}
-IGraphTransformer::TStatus ConvertChildrenToType(const TExprNode::TPtr& input, const TTypeAnnotationNode* targetType, TExprContext& ctx) {
- if (!input->ChildrenSize()) {
+IGraphTransformer::TStatus ConvertChildrenToType(const TExprNode::TPtr& input, const TTypeAnnotationNode* targetType, TExprContext& ctx) {
+ if (!input->ChildrenSize()) {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus status = IGraphTransformer::TStatus::Ok;
- for (auto i = 0U; i < input->ChildrenSize(); ++i) {
+ IGraphTransformer::TStatus status = IGraphTransformer::TStatus::Ok;
+ for (auto i = 0U; i < input->ChildrenSize(); ++i) {
const auto child = input->Child(i);
if (!EnsureComputable(*child, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- status = status.Combine(TryConvertTo(input->ChildRef(i), *targetType, ctx));
- if (IGraphTransformer::TStatus::Error == status)
- break;
+ status = status.Combine(TryConvertTo(input->ChildRef(i), *targetType, ctx));
+ if (IGraphTransformer::TStatus::Error == status)
+ break;
}
- return status;
+ return status;
}
bool IsSqlInCollectionItemsNullable(const NNodes::TCoSqlIn& node) {
@@ -4130,7 +4130,7 @@ EDataSlot GetNumericDataTypeByLevel(ui32 level) {
return EDataSlot::Int64;
case 8:
return EDataSlot::Float;
- case 9:
+ case 9:
return EDataSlot::Double;
default:
ythrow yexception() << "Unknown numeric level: " << level;
@@ -4198,7 +4198,7 @@ bool AllowIntegralConversion(TCoIntegralCtor node, bool negate, EDataSlot toType
bool hasSign;
bool isSigned;
ui64 value;
- ExtractIntegralValue(node.Ref(), negate, hasSign, isSigned, value);
+ ExtractIntegralValue(node.Ref(), negate, hasSign, isSigned, value);
bool allow = false;
@@ -4237,16 +4237,16 @@ bool AllowIntegralConversion(TCoIntegralCtor node, bool negate, EDataSlot toType
return allow;
}
-void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSign, bool& isSigned, ui64& value) {
+void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSign, bool& isSigned, ui64& value) {
hasSign = false;
isSigned = false;
value = 0;
- const auto& atom = constructor.Head();
- if (constructor.Content().StartsWith("Int")) {
+ const auto& atom = constructor.Head();
+ if (constructor.Content().StartsWith("Int")) {
isSigned = true;
- if (atom.Flags() & TNodeFlags::BinaryContent) {
- if (constructor.Content().EndsWith("8")) {
- auto raw = i8(atom.Content().front());
+ if (atom.Flags() & TNodeFlags::BinaryContent) {
+ if (constructor.Content().EndsWith("8")) {
+ auto raw = i8(atom.Content().front());
if (raw < 0) {
hasSign = true;
value = -raw;
@@ -4254,8 +4254,26 @@ void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSi
else {
value = raw;
}
- } else if (constructor.Content().EndsWith("16")) {
- auto raw = *reinterpret_cast<const i16*>(atom.Content().data());
+ } else if (constructor.Content().EndsWith("16")) {
+ auto raw = *reinterpret_cast<const i16*>(atom.Content().data());
+ if (raw < 0) {
+ hasSign = true;
+ value = -raw;
+ }
+ else {
+ value = raw;
+ }
+ } else if (constructor.Content().EndsWith("32")) {
+ auto raw = *reinterpret_cast<const i32*>(atom.Content().data());
+ if (raw < 0) {
+ hasSign = true;
+ value = -raw;
+ }
+ else {
+ value = raw;
+ }
+ } else if (constructor.Content().EndsWith("64")) {
+ auto raw = *reinterpret_cast<const i64*>(atom.Content().data());
if (raw < 0) {
hasSign = true;
value = -raw;
@@ -4263,41 +4281,23 @@ void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSi
else {
value = raw;
}
- } else if (constructor.Content().EndsWith("32")) {
- auto raw = *reinterpret_cast<const i32*>(atom.Content().data());
- if (raw < 0) {
- hasSign = true;
- value = -raw;
- }
- else {
- value = raw;
- }
- } else if (constructor.Content().EndsWith("64")) {
- auto raw = *reinterpret_cast<const i64*>(atom.Content().data());
- if (raw < 0) {
- hasSign = true;
- value = -raw;
- }
- else {
- value = raw;
- }
}
}
else {
- hasSign = atom.Content().StartsWith('-');
+ hasSign = atom.Content().StartsWith('-');
auto strValue = hasSign
- ? atom.Content().Tail(1)
- : atom.Content();
+ ? atom.Content().Tail(1)
+ : atom.Content();
value = ::FromString<ui64>(strValue);
}
}
else {
- if (atom.Flags() & TNodeFlags::BinaryContent) {
- memcpy(&value, atom.Content().data(), atom.Content().size());
+ if (atom.Flags() & TNodeFlags::BinaryContent) {
+ memcpy(&value, atom.Content().data(), atom.Content().size());
}
else {
- value = FromString<ui64>(atom.Content());
+ value = FromString<ui64>(atom.Content());
}
}
@@ -4313,7 +4313,7 @@ void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSi
else if (constructor.IsCallable("Uint16")) {
value = value & 0xFFFFu;
}
- else if (constructor.IsCallable("Uint32")) {
+ else if (constructor.IsCallable("Uint32")) {
value = value & 0xFFFFFFFFu;
}
}
@@ -4610,11 +4610,11 @@ TString GetTypeDiff(const TTypeAnnotationNode& left, const TTypeAnnotationNode&
<< GetStructDiff(*left.Cast<TStructExprType>(), *right.Cast<TStructExprType>())
<< '>';
return res;
- case ETypeAnnotationKind::Flow:
+ case ETypeAnnotationKind::Flow:
res << TStringBuf("Flow<")
- << GetTypeDiff(*left.Cast<TFlowExprType>()->GetItemType(), *right.Cast<TFlowExprType>()->GetItemType())
- << '>';
- return res;
+ << GetTypeDiff(*left.Cast<TFlowExprType>()->GetItemType(), *right.Cast<TFlowExprType>()->GetItemType())
+ << '>';
+ return res;
default:
res << left << TStringBuf("!=") << right;
return res;
@@ -4632,16 +4632,16 @@ TExprNode::TPtr ExpandTypeNoCache(TPositionHandle position, const TTypeAnnotatio
return ctx.NewCallable(position, "EmptyListType", {});
case ETypeAnnotationKind::EmptyDict:
return ctx.NewCallable(position, "EmptyDictType", {});
- case ETypeAnnotationKind::Multi:
- {
- TExprNode::TListType tupleItems;
- for (auto& child : type.Cast<TMultiExprType>()->GetItems()) {
- tupleItems.push_back(ExpandType(position, *child, ctx));
- }
-
- auto ret = ctx.NewCallable(position, "MultiType", std::move(tupleItems));
- return ret;
- }
+ case ETypeAnnotationKind::Multi:
+ {
+ TExprNode::TListType tupleItems;
+ for (auto& child : type.Cast<TMultiExprType>()->GetItems()) {
+ tupleItems.push_back(ExpandType(position, *child, ctx));
+ }
+
+ auto ret = ctx.NewCallable(position, "MultiType", std::move(tupleItems));
+ return ret;
+ }
case ETypeAnnotationKind::Tuple:
{
TExprNode::TListType tupleItems;
@@ -4677,16 +4677,16 @@ TExprNode::TPtr ExpandTypeNoCache(TPositionHandle position, const TTypeAnnotatio
case ETypeAnnotationKind::Data:
{
- const auto data = type.Cast<TDataExprType>();
- if (const auto params = dynamic_cast<const TDataExprParamsType*>(data)) {
+ const auto data = type.Cast<TDataExprType>();
+ if (const auto params = dynamic_cast<const TDataExprParamsType*>(data)) {
return ctx.NewCallable(position, "DataType", {
ctx.NewAtom(position, params->GetName(), TNodeFlags::Default),
ctx.NewAtom(position, params->GetParamOne(), TNodeFlags::Default),
ctx.NewAtom(position, params->GetParamTwo(), TNodeFlags::Default)
});
- } else {
+ } else {
return ctx.NewCallable(position, "DataType", {ctx.NewAtom(position, data->GetName(), TNodeFlags::Default)});
- }
+ }
}
case ETypeAnnotationKind::Optional:
@@ -4784,13 +4784,13 @@ TExprNode::TPtr ExpandTypeNoCache(TPositionHandle position, const TTypeAnnotatio
return ret;
}
- case ETypeAnnotationKind::Flow:
- {
- auto ret = ctx.NewCallable(position, "FlowType",
- {ExpandType(position, *type.Cast<TFlowExprType>()->GetItemType(), ctx)});
- return ret;
- }
-
+ case ETypeAnnotationKind::Flow:
+ {
+ auto ret = ctx.NewCallable(position, "FlowType",
+ {ExpandType(position, *type.Cast<TFlowExprType>()->GetItemType(), ctx)});
+ return ret;
+ }
+
case ETypeAnnotationKind::Tagged:
{
auto taggedType = type.Cast<TTaggedExprType>();
@@ -4896,24 +4896,24 @@ IGraphTransformer::TStatus NormalizeKeyValueTuples(const TExprNode::TPtr& input,
return IGraphTransformer::TStatus::Ok;
}
-std::optional<ui32> GetFieldPosition(const TMultiExprType& multiType, const TStringBuf& field) {
- if (ui32 pos; TryFromString(field, pos) && pos < multiType.GetSize())
- return {pos};
- return std::nullopt;
-}
-
-std::optional<ui32> GetFieldPosition(const TTupleExprType& tupleType, const TStringBuf& field) {
- if (ui32 pos; TryFromString(field, pos) && pos < tupleType.GetSize())
- return {pos};
- return std::nullopt;
-}
-
-std::optional<ui32> GetFieldPosition(const TStructExprType& structType, const TStringBuf& field) {
- if (const auto find = structType.FindItem(field))
- return {*find};
- return std::nullopt;
-}
-
+std::optional<ui32> GetFieldPosition(const TMultiExprType& multiType, const TStringBuf& field) {
+ if (ui32 pos; TryFromString(field, pos) && pos < multiType.GetSize())
+ return {pos};
+ return std::nullopt;
+}
+
+std::optional<ui32> GetFieldPosition(const TTupleExprType& tupleType, const TStringBuf& field) {
+ if (ui32 pos; TryFromString(field, pos) && pos < tupleType.GetSize())
+ return {pos};
+ return std::nullopt;
+}
+
+std::optional<ui32> GetFieldPosition(const TStructExprType& structType, const TStringBuf& field) {
+ if (const auto find = structType.FindItem(field))
+ return {*find};
+ return std::nullopt;
+}
+
bool IsCallableTypeHasStreams(const TCallableExprType* callableType) {
for (;;) {
if (callableType->GetReturnType()->GetKind() == ETypeAnnotationKind::Stream) {
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.h b/ydb/library/yql/core/yql_expr_type_annotation.h
index 1f32e5cc7c..a865aa27cd 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.h
+++ b/ydb/library/yql/core/yql_expr_type_annotation.h
@@ -23,19 +23,19 @@ T FromString(const TExprNode& node, NKikimr::NUdf::EDataSlot slot) {
}
}
} else {
- if (const auto out = NKikimr::NMiniKQL::ValueFromString(slot, node.Content())) {
- return out.Get<T>();
- } else if (slot == NKikimr::NUdf::EDataSlot::Bool) {
- T value = T();
+ if (const auto out = NKikimr::NMiniKQL::ValueFromString(slot, node.Content())) {
+ return out.Get<T>();
+ } else if (slot == NKikimr::NUdf::EDataSlot::Bool) {
+ T value = T();
if (node.Content() == TStringBuf("0")) {
- *(ui8*)&value = 0;
- return value;
+ *(ui8*)&value = 0;
+ return value;
} else if (node.Content() == TStringBuf("1")) {
- *(ui8*)&value = 1;
- return value;
- }
- } else if (NKikimr::NUdf::GetDataTypeInfo(slot).Features &
- (NKikimr::NUdf::EDataTypeFeatures::DateType | NKikimr::NUdf::EDataTypeFeatures::TimeIntervalType)) {
+ *(ui8*)&value = 1;
+ return value;
+ }
+ } else if (NKikimr::NUdf::GetDataTypeInfo(slot).Features &
+ (NKikimr::NUdf::EDataTypeFeatures::DateType | NKikimr::NUdf::EDataTypeFeatures::TimeIntervalType)) {
T ret;
if (TryFromString<T>(node.Content(), ret) &&
NKikimr::NMiniKQL::IsValidValue(slot, NKikimr::NUdf::TUnboxedValuePod(ret))) {
@@ -44,26 +44,26 @@ T FromString(const TExprNode& node, NKikimr::NUdf::EDataSlot slot) {
}
}
- const auto typeName = NKikimr::NUdf::GetDataTypeInfo(slot).Name;
+ const auto typeName = NKikimr::NUdf::GetDataTypeInfo(slot).Name;
ythrow TNodeException(node) << "Bad atom format for type: " << typeName << ", value: " << TString(node.Content()).Quote();
}
-IGraphTransformer::TStatus CheckWholeProgramType(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx);
+IGraphTransformer::TStatus CheckWholeProgramType(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx);
void ClearExprTypeAnnotations(TExprNode& root);
bool AreAllNodesTypeAnnotated(const TExprNode& root);
void EnsureAllNodesTypeAnnotated(const TExprNode& root);
bool IsDataOrOptionalOfData(const TTypeAnnotationNode* typeAnnotation, bool& isOptional, const TDataExprType*& dataType);
bool IsDataOrOptionalOfData(const TTypeAnnotationNode* typeAnnotation);
-bool UpdateLambdaAllArgumentsTypes(TExprNode::TPtr& lambda, const std::vector<const TTypeAnnotationNode*>& argumentsAnnotations, TExprContext& ctx);
-bool UpdateLambdaArgumentsType(const TExprNode& lambda, TExprContext& ctx);
+bool UpdateLambdaAllArgumentsTypes(TExprNode::TPtr& lambda, const std::vector<const TTypeAnnotationNode*>& argumentsAnnotations, TExprContext& ctx);
+bool UpdateLambdaArgumentsType(const TExprNode& lambda, TExprContext& ctx);
bool EnsureArgsCount(const TExprNode& node, ui32 expectedArgs, TExprContext& ctx);
bool EnsureMinArgsCount(const TExprNode& node, ui32 expectedArgs, TExprContext& ctx);
bool EnsureMaxArgsCount(const TExprNode& node, ui32 expectedArgs, TExprContext& ctx);
-bool EnsureMinMaxArgsCount(const TExprNode& node, ui32 minArgs, ui32 maxArgs, TExprContext& ctx);
+bool EnsureMinMaxArgsCount(const TExprNode& node, ui32 minArgs, ui32 maxArgs, TExprContext& ctx);
bool EnsureCallableMinArgsCount(const TPositionHandle& pos, ui32 args, ui32 expectedArgs, TExprContext& ctx);
bool EnsureCallableMaxArgsCount(const TPositionHandle& pos, ui32 args, ui32 expectedArgs, TExprContext& ctx);
bool EnsureAtom(const TExprNode& node, TExprContext& ctx);
-bool EnsureCallable(const TExprNode& node, TExprContext& ctx);
+bool EnsureCallable(const TExprNode& node, TExprContext& ctx);
bool EnsureTuple(const TExprNode& node, TExprContext& ctx);
bool EnsureTupleOfAtoms(const TExprNode& node, TExprContext& ctx);
bool EnsureLambda(const TExprNode& node, TExprContext& ctx);
@@ -76,16 +76,16 @@ bool EnsureTupleType(const TExprNode& node, TExprContext& ctx);
bool EnsureTupleType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureTupleTypeSize(const TExprNode& node, ui32 expectedSize, TExprContext& ctx);
bool EnsureTupleTypeSize(TPositionHandle position, const TTypeAnnotationNode* type, ui32 expectedSize, TExprContext& ctx);
-bool EnsureMultiType(const TExprNode& node, TExprContext& ctx);
-bool EnsureMultiType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
+bool EnsureMultiType(const TExprNode& node, TExprContext& ctx);
+bool EnsureMultiType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureVariantType(const TExprNode& node, TExprContext& ctx);
bool EnsureVariantType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureDataType(const TExprNode& node, TExprContext& ctx);
bool EnsureDataType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureSpecificDataType(const TExprNode& node, EDataSlot expectedDataSlot, TExprContext& ctx, bool allowOptional = false);
bool EnsureSpecificDataType(TPositionHandle position, const TTypeAnnotationNode& type, EDataSlot expectedDataSlot, TExprContext& ctx);
-bool EnsureStringOrUtf8Type(const TExprNode& node, TExprContext& ctx);
-bool EnsureStringOrUtf8Type(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
+bool EnsureStringOrUtf8Type(const TExprNode& node, TExprContext& ctx);
+bool EnsureStringOrUtf8Type(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureStructType(const TExprNode& node, TExprContext& ctx);
bool EnsureStructType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureTypeWithStructType(const TExprNode& node, TExprContext& ctx);
@@ -105,17 +105,17 @@ bool EnsureListOfVoidType(const TExprNode& node, TExprContext& ctx);
bool EnsureListOfVoidType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureStreamType(const TExprNode& node, TExprContext& ctx);
bool EnsureStreamType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
-bool EnsureFlowType(const TExprNode& node, TExprContext& ctx);
+bool EnsureFlowType(const TExprNode& node, TExprContext& ctx);
bool EnsureFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
-bool EnsureWideFlowType(const TExprNode& node, TExprContext& ctx);
-bool EnsureWideFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
+bool EnsureWideFlowType(const TExprNode& node, TExprContext& ctx);
+bool EnsureWideFlowType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureOptionalType(const TExprNode& node, TExprContext& ctx);
bool EnsureOptionalType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureType(const TExprNode& node, TExprContext& ctx);
IGraphTransformer::TStatus EnsureTypeRewrite(TExprNode::TPtr& node, TExprContext& ctx);
IGraphTransformer::TStatus EnsureTypeOrAtomRewrite(TExprNode::TPtr& node, TExprContext& ctx);
-bool EnsureDryType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
-bool EnsureDryType(const TExprNode& node, TExprContext& ctx);
+bool EnsureDryType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
+bool EnsureDryType(const TExprNode& node, TExprContext& ctx);
bool EnsureDictType(const TExprNode& node, TExprContext& ctx);
bool EnsureDictType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureVoidType(const TExprNode& node, TExprContext& ctx);
@@ -142,17 +142,17 @@ bool EnsureComputableType(TPositionHandle position, const TTypeAnnotationNode& t
bool EnsureInspectable(const TExprNode& node, TExprContext& ctx);
bool EnsureInspectableType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureListOrOptionalType(const TExprNode& node, TExprContext& ctx);
-bool EnsureListOrOptionalListType(const TExprNode& node, TExprContext& ctx);
+bool EnsureListOrOptionalListType(const TExprNode& node, TExprContext& ctx);
bool EnsureStructOrOptionalStructType(const TExprNode& node, TExprContext& ctx);
bool EnsureStructOrOptionalStructType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool EnsureSeqType(const TExprNode& node, TExprContext& ctx, bool* isStream = nullptr);
bool EnsureSeqType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx, bool* isStream = nullptr);
bool EnsureSeqOrOptionalType(const TExprNode& node, TExprContext& ctx);
bool EnsureSeqOrOptionalType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
-template <bool WithOptional, bool WithList = true, bool WithStream = true>
-bool EnsureNewSeqType(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType = nullptr);
-template <bool WithOptional, bool WithList = true, bool WithStream = true>
-bool EnsureNewSeqType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx, const TTypeAnnotationNode** itemType = nullptr);
+template <bool WithOptional, bool WithList = true, bool WithStream = true>
+bool EnsureNewSeqType(const TExprNode& node, TExprContext& ctx, const TTypeAnnotationNode** itemType = nullptr);
+template <bool WithOptional, bool WithList = true, bool WithStream = true>
+bool EnsureNewSeqType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx, const TTypeAnnotationNode** itemType = nullptr);
bool EnsureDependsOn(const TExprNode& node, TExprContext& ctx);
bool EnsureDependsOnTail(const TExprNode& node, TExprContext& ctx, unsigned requiredArgumentCount, unsigned requiredDependsOnCount = 0);
@@ -161,35 +161,35 @@ bool EnsureTypeHandleResourceType(const TExprNode& node, TExprContext& ctx);
const TTypeAnnotationNode* MakeCodeResourceType(TExprContext& ctx);
bool EnsureCodeResourceType(const TExprNode& node, TExprContext& ctx);
-const TTypeAnnotationNode* MakeSequenceType(ETypeAnnotationKind sequenceKind, const TTypeAnnotationNode& itemType, TExprContext& ctx);
-
-template <bool Strong>
-NUdf::TCastResultOptions CastResult(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
-
-enum class ECompareOptions {
- Null = -1,
- Uncomparable = 0,
- Comparable = 1,
- Optional = 2
-};
-
-template <bool Equality>
-ECompareOptions CanCompare(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
-
-const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, TExprContext& ctx);
-const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, bool& hasOptional, TExprContext& ctx);
-
-// Key type for left or right join.
-const TTypeAnnotationNode* JoinDryKeyType(const TTypeAnnotationNode* primary, const TTypeAnnotationNode* secondary, bool& hasOptional, TExprContext& ctx);
-
-template <bool Strict> // Strict + DryType before - common type for join key.
-const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
-
-const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode::TSpanType& types, TExprContext& ctx);
-const TTypeAnnotationNode* CommonTypeForChildren(const TExprNode& node, TExprContext& ctx);
-
-size_t GetOptionalLevel(const TTypeAnnotationNode* type);
-
+const TTypeAnnotationNode* MakeSequenceType(ETypeAnnotationKind sequenceKind, const TTypeAnnotationNode& itemType, TExprContext& ctx);
+
+template <bool Strong>
+NUdf::TCastResultOptions CastResult(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
+
+enum class ECompareOptions {
+ Null = -1,
+ Uncomparable = 0,
+ Comparable = 1,
+ Optional = 2
+};
+
+template <bool Equality>
+ECompareOptions CanCompare(const TTypeAnnotationNode* source, const TTypeAnnotationNode* target);
+
+const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, TExprContext& ctx);
+const TTypeAnnotationNode* DryType(const TTypeAnnotationNode* type, bool& hasOptional, TExprContext& ctx);
+
+// Key type for left or right join.
+const TTypeAnnotationNode* JoinDryKeyType(const TTypeAnnotationNode* primary, const TTypeAnnotationNode* secondary, bool& hasOptional, TExprContext& ctx);
+
+template <bool Strict> // Strict + DryType before - common type for join key.
+const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode* one, const TTypeAnnotationNode* two, TExprContext& ctx);
+
+const TTypeAnnotationNode* CommonType(TPositionHandle position, const TTypeAnnotationNode::TSpanType& types, TExprContext& ctx);
+const TTypeAnnotationNode* CommonTypeForChildren(const TExprNode& node, TExprContext& ctx);
+
+size_t GetOptionalLevel(const TTypeAnnotationNode* type);
+
namespace NConvertFlags {
enum EFlags {
@@ -204,13 +204,13 @@ using TConvertFlags = TEnumBitSet<EFlags, DisableTruncation, Last>;
using NConvertFlags::TConvertFlags;
-IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
+IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags = {});
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
TExprContext& ctx, TConvertFlags flags = {});
IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType, TExprContext& ctx,
TConvertFlags flags = {});
-IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
+IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags = {});
TMaybe<EDataSlot> GetSuperType(EDataSlot dataSlot1, EDataSlot dataSlot2);
IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, TExprNode::TPtr& node2, TExprContext& ctx,
@@ -218,23 +218,23 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, TExprNo
IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const TTypeAnnotationNode& type1,
TExprNode::TPtr& node2, const TTypeAnnotationNode& type2, TExprContext& ctx,
const TTypeAnnotationNode*& commonType, TConvertFlags flags = {});
-IGraphTransformer::TStatus ConvertChildrenToType(const TExprNode::TPtr& input,const TTypeAnnotationNode* targetType, TExprContext& ctx);
+IGraphTransformer::TStatus ConvertChildrenToType(const TExprNode::TPtr& input,const TTypeAnnotationNode* targetType, TExprContext& ctx);
bool IsSqlInCollectionItemsNullable(const NNodes::TCoSqlIn& node);
bool IsDataTypeNumeric(EDataSlot dataSlot);
bool IsDataTypeFloat(EDataSlot dataSlot);
bool IsDataTypeIntegral(EDataSlot dataSlot);
-bool IsDataTypeSigned(EDataSlot dataSlot);
+bool IsDataTypeSigned(EDataSlot dataSlot);
bool IsDataTypeUnsigned(EDataSlot dataSlot);
bool IsDataTypeDate(EDataSlot dataSlot);
bool IsDataTypeTzDate(EDataSlot dataSlot);
EDataSlot WithTzDate(EDataSlot dataSlot);
EDataSlot WithoutTzDate(EDataSlot dataSlot);
-EDataSlot MakeSigned(EDataSlot dataSlot);
-EDataSlot MakeUnsigned(EDataSlot dataSlot);
+EDataSlot MakeSigned(EDataSlot dataSlot);
+EDataSlot MakeUnsigned(EDataSlot dataSlot);
bool IsDataTypeDecimal(EDataSlot dataSlot);
-bool IsDataTypeDateOrTzDateOrInterval(EDataSlot dataSlot);
+bool IsDataTypeDateOrTzDateOrInterval(EDataSlot dataSlot);
bool IsDataTypeDateOrTzDate(EDataSlot dataSlot);
bool IsDataTypeInterval(EDataSlot dataSlot);
ui8 GetDecimalWidthOfIntegral(EDataSlot dataSlot);
@@ -248,7 +248,7 @@ bool IsPureIsolatedLambda(const TExprNode& lambdaBody);
TString GetIntegralAtomValue(ui64 value, bool hasSign);
bool AllowIntegralConversion(NNodes::TCoIntegralCtor node, bool negate, EDataSlot toType,
TString* atomValue = nullptr);
-void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSign, bool& isSigned, ui64& value);
+void ExtractIntegralValue(const TExprNode& constructor, bool negate, bool& hasSign, bool& isSigned, ui64& value);
bool IsDataTypeString(EDataSlot dataSlot);
bool EnsureComparableDataType(TPositionHandle position, EDataSlot dataSlot, TExprContext& ctx);
bool EnsureEquatableDataType(TPositionHandle position, EDataSlot dataSlot, TExprContext& ctx);
@@ -262,7 +262,7 @@ bool IsNull(const TExprNode& node);
bool IsNull(const TTypeAnnotationNode& type);
bool IsEmptyList(const TExprNode& node);
bool IsEmptyList(const TTypeAnnotationNode& type);
-bool IsInstantEqual(const TTypeAnnotationNode& type);
+bool IsInstantEqual(const TTypeAnnotationNode& type);
TString GetTypeDiff(const TTypeAnnotationNode& left, const TTypeAnnotationNode& right);
TExprNode::TPtr ExpandType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
@@ -274,10 +274,10 @@ IGraphTransformer::TStatus NormalizeTupleOfAtoms(const TExprNode::TPtr& input, u
IGraphTransformer::TStatus NormalizeKeyValueTuples(const TExprNode::TPtr& input, ui32 startIndex, TExprNode::TPtr& output,
TExprContext& ctx, bool deduplicate = false);
-std::optional<ui32> GetFieldPosition(const TMultiExprType& tupleType, const TStringBuf& field);
-std::optional<ui32> GetFieldPosition(const TTupleExprType& tupleType, const TStringBuf& field);
-std::optional<ui32> GetFieldPosition(const TStructExprType& structType, const TStringBuf& field);
-
+std::optional<ui32> GetFieldPosition(const TMultiExprType& tupleType, const TStringBuf& field);
+std::optional<ui32> GetFieldPosition(const TTupleExprType& tupleType, const TStringBuf& field);
+std::optional<ui32> GetFieldPosition(const TStructExprType& structType, const TStringBuf& field);
+
bool IsCallableTypeHasStreams(const TCallableExprType* callableType);
}
diff --git a/ydb/library/yql/core/yql_gc_transformer.cpp b/ydb/library/yql/core/yql_gc_transformer.cpp
index 5455a66bdf..d74099da4d 100644
--- a/ydb/library/yql/core/yql_gc_transformer.cpp
+++ b/ydb/library/yql/core/yql_gc_transformer.cpp
@@ -7,49 +7,49 @@ namespace {
class TGcNodeTransformer : public TSyncTransformerBase {
public:
- TGcNodeTransformer()
+ TGcNodeTransformer()
{}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) override {
- output = input;
+ output = input;
- if (!CurrentThreshold)
- CurrentThreshold = ctx.GcConfig.Settings.NodeCountThreshold;
-
- if (ctx.NodeAllocationCounter < LastGcCount + CurrentThreshold) {
+ if (!CurrentThreshold)
+ CurrentThreshold = ctx.GcConfig.Settings.NodeCountThreshold;
+
+ if (ctx.NodeAllocationCounter < LastGcCount + CurrentThreshold) {
return TStatus::Ok;
}
- const auto oldSize = ctx.ExprNodes.size();
- const auto zombies = std::partition(ctx.ExprNodes.begin(), ctx.ExprNodes.end(), std::bind(std::logical_not<bool>(), std::bind(&TExprNode::Dead, std::placeholders::_1)));
-
- for (auto it = zombies; ctx.ExprNodes.cend() != it; ++it) {
- const auto dead = it->get();
- if (const auto hash = dead->GetHashAbove()) {
- const auto range = ctx.UniqueNodes.equal_range(hash);
- for (auto jt = range.first; range.second != jt;) {
- if (jt->second == dead) {
- jt = ctx.UniqueNodes.erase(jt);
- } else {
- ++jt;
- }
- }
- }
+ const auto oldSize = ctx.ExprNodes.size();
+ const auto zombies = std::partition(ctx.ExprNodes.begin(), ctx.ExprNodes.end(), std::bind(std::logical_not<bool>(), std::bind(&TExprNode::Dead, std::placeholders::_1)));
+
+ for (auto it = zombies; ctx.ExprNodes.cend() != it; ++it) {
+ const auto dead = it->get();
+ if (const auto hash = dead->GetHashAbove()) {
+ const auto range = ctx.UniqueNodes.equal_range(hash);
+ for (auto jt = range.first; range.second != jt;) {
+ if (jt->second == dead) {
+ jt = ctx.UniqueNodes.erase(jt);
+ } else {
+ ++jt;
+ }
+ }
+ }
}
- ctx.ExprNodes.erase(zombies, ctx.ExprNodes.cend());
- const auto liveSize = ctx.ExprNodes.size();
+ ctx.ExprNodes.erase(zombies, ctx.ExprNodes.cend());
+ const auto liveSize = ctx.ExprNodes.size();
- Y_VERIFY(liveSize >= ctx.UniqueNodes.size());
-
- // Update statistic.
- ++ctx.GcConfig.Statistics.CollectCount;
- ctx.GcConfig.Statistics.TotalCollectedNodes += oldSize - liveSize;
+ Y_VERIFY(liveSize >= ctx.UniqueNodes.size());
+
+ // Update statistic.
+ ++ctx.GcConfig.Statistics.CollectCount;
+ ctx.GcConfig.Statistics.TotalCollectedNodes += oldSize - liveSize;
LastGcCount = ctx.NodeAllocationCounter;
// adjust next treshold
- CurrentThreshold = Max(ctx.GcConfig.Settings.NodeCountThreshold, liveSize);
-
+ CurrentThreshold = Max(ctx.GcConfig.Settings.NodeCountThreshold, liveSize);
+
if (liveSize > ctx.NodesAllocationLimit) {
ctx.AddError(YqlIssue(TPosition(), TIssuesIds::CORE_GC_NODES_LIMIT_EXCEEDED, TStringBuilder()
<< "Too many allocated nodes, allowed: " << ctx.NodesAllocationLimit
@@ -57,7 +57,7 @@ public:
return TStatus::Error;
}
- const auto poolSize = ctx.StringPool.MemoryAllocated() + ctx.StringPool.MemoryWaste();
+ const auto poolSize = ctx.StringPool.MemoryAllocated() + ctx.StringPool.MemoryWaste();
if (poolSize > ctx.StringsAllocationLimit) {
ctx.AddError(YqlIssue(TPosition(), TIssuesIds::CORE_GC_STRINGS_LIMIT_EXCEEDED, TStringBuilder()
<< "Too large string pool, allowed: " << ctx.StringsAllocationLimit
@@ -69,13 +69,13 @@ public:
private:
ui64 LastGcCount = 0;
- ui64 CurrentThreshold = 0;
+ ui64 CurrentThreshold = 0;
};
}
-TAutoPtr<IGraphTransformer> CreateGcNodeTransformer() {
- return new TGcNodeTransformer();
+TAutoPtr<IGraphTransformer> CreateGcNodeTransformer() {
+ return new TGcNodeTransformer();
}
}
diff --git a/ydb/library/yql/core/yql_gc_transformer.h b/ydb/library/yql/core/yql_gc_transformer.h
index 0272eddc84..5db64e8f14 100644
--- a/ydb/library/yql/core/yql_gc_transformer.h
+++ b/ydb/library/yql/core/yql_gc_transformer.h
@@ -5,6 +5,6 @@
namespace NYql {
-TAutoPtr<IGraphTransformer> CreateGcNodeTransformer();
+TAutoPtr<IGraphTransformer> CreateGcNodeTransformer();
}
diff --git a/ydb/library/yql/core/yql_graph_transformer.cpp b/ydb/library/yql/core/yql_graph_transformer.cpp
index d4d8aa9870..26193c4c40 100644
--- a/ydb/library/yql/core/yql_graph_transformer.cpp
+++ b/ydb/library/yql/core/yql_graph_transformer.cpp
@@ -67,7 +67,7 @@ public:
#else
Y_UNUSED(DoCheckArguments);
Y_UNUSED(CheckArgumentsCount);
-#endif
+#endif
status = HandleStatus(status);
return status;
}
@@ -228,7 +228,7 @@ TAutoPtr<IGraphTransformer> CreateChoiceGraphTransformer(
return new TChoiceGraphTransformer(condition, left, right);
}
-IGraphTransformer::TStatus SyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx) {
+IGraphTransformer::TStatus SyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx) {
try {
for (; ctx.RepeatTransformCounter < ctx.RepeatTransformLimit; ++ctx.RepeatTransformCounter) {
TExprNode::TPtr newRoot;
@@ -279,7 +279,7 @@ IGraphTransformer::TStatus SyncTransform(IGraphTransformer& transformer, TExprNo
return IGraphTransformer::TStatus::Error;
}
-IGraphTransformer::TStatus InstantTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool breakOnRestart) {
+IGraphTransformer::TStatus InstantTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool breakOnRestart) {
try {
for (; ctx.RepeatTransformCounter < ctx.RepeatTransformLimit; ++ctx.RepeatTransformCounter) {
TExprNode::TPtr newRoot;
@@ -313,7 +313,7 @@ IGraphTransformer::TStatus InstantTransform(IGraphTransformer& transformer, TExp
return IGraphTransformer::TStatus::Error;
}
-NThreading::TFuture<IGraphTransformer::TStatus> AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx,
+NThreading::TFuture<IGraphTransformer::TStatus> AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx,
bool applyAsyncChanges) {
try {
if (applyAsyncChanges) {
@@ -376,7 +376,7 @@ NThreading::TFuture<IGraphTransformer::TStatus> AsyncTransform(IGraphTransformer
}
-void AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges,
+void AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges,
std::function<void(const IGraphTransformer::TStatus&)> asyncCallback) {
NThreading::TFuture<IGraphTransformer::TStatus> status = AsyncTransform(transformer, root, ctx, applyAsyncChanges);
status.Subscribe(
diff --git a/ydb/library/yql/core/yql_graph_transformer.h b/ydb/library/yql/core/yql_graph_transformer.h
index a063d0be18..60d87727dd 100644
--- a/ydb/library/yql/core/yql_graph_transformer.h
+++ b/ydb/library/yql/core/yql_graph_transformer.h
@@ -97,9 +97,9 @@ public:
virtual ~IGraphTransformer() {}
- virtual TStatus Transform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) = 0;
- virtual NThreading::TFuture<void> GetAsyncFuture(const TExprNode& input) = 0;
- virtual TStatus ApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) = 0;
+ virtual TStatus Transform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) = 0;
+ virtual NThreading::TFuture<void> GetAsyncFuture(const TExprNode& input) = 0;
+ virtual TStatus ApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) = 0;
virtual void Rewind() {}
virtual TStatistics GetStatistics() const { return TStatistics::NotPresent(); }
@@ -225,12 +225,12 @@ TAutoPtr<IGraphTransformer> CreateChoiceGraphTransformer(
const TTransformStage& left,
const TTransformStage& right);
-IGraphTransformer::TStatus SyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx);
-IGraphTransformer::TStatus InstantTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool breakOnRestart = false);
+IGraphTransformer::TStatus SyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx);
+IGraphTransformer::TStatus InstantTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool breakOnRestart = false);
-NThreading::TFuture<IGraphTransformer::TStatus> AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges);
+NThreading::TFuture<IGraphTransformer::TStatus> AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges);
-void AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges,
+void AsyncTransform(IGraphTransformer& transformer, TExprNode::TPtr& root, TExprContext& ctx, bool applyAsyncChanges,
std::function<void(const IGraphTransformer::TStatus&)> asyncCallback);
class TSyncTransformerBase : public TGraphTransformerBase {
@@ -276,11 +276,11 @@ private:
};
template <typename TFunctor>
-THolder<IGraphTransformer> CreateFunctorTransformer(TFunctor functor) {
+THolder<IGraphTransformer> CreateFunctorTransformer(TFunctor functor) {
return MakeHolder<TFunctorTransformer<TFunctor>>(std::move(functor));
}
-typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&)> TAsyncTransformCallback;
+typedef std::function<IGraphTransformer::TStatus(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&)> TAsyncTransformCallback;
typedef NThreading::TFuture<TAsyncTransformCallback> TAsyncTransformCallbackFuture;
template <typename TDerived>
@@ -356,7 +356,7 @@ std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture>
WrapFuture(const TFuture& future, const TResultExtractor& extractor, const TString& message = "") {
return WrapFutureCallback(future, [extractor](const NThreading::TFutureType<TFuture>& res, const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) {
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(extractor(res, input, ctx));
+ input->SetResult(extractor(res, input, ctx));
return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Ok);
}, message);
}
@@ -391,7 +391,7 @@ inline std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture> Sync
return SyncStatus(IGraphTransformer::TStatus::Repeat);
}
-typedef std::unordered_map<TExprNode::TPtr, ui64, TExprNode::TPtrHash> TSyncMap;
+typedef std::unordered_map<TExprNode::TPtr, ui64, TExprNode::TPtrHash> TSyncMap;
}
template<>
diff --git a/ydb/library/yql/core/yql_join.cpp b/ydb/library/yql/core/yql_join.cpp
index 9f06dfb5c3..9a9ded7a32 100644
--- a/ydb/library/yql/core/yql_join.cpp
+++ b/ydb/library/yql/core/yql_join.cpp
@@ -221,9 +221,9 @@ namespace {
<< " has type: " << *rightKeyTypes[i] << ")"));
return IGraphTransformer::TStatus::Error;
}
- if (ECompareOptions::Uncomparable == CanCompare<true>(leftKeyTypes[i], rightKeyTypes[i])) {
+ if (ECompareOptions::Uncomparable == CanCompare<true>(leftKeyTypes[i], rightKeyTypes[i])) {
ctx.AddError(TIssue(ctx.GetPosition(joins.Pos()),
- TStringBuilder() << "Cannot compare key columns (" << leftKeys[i].first << "." << leftKeys[i].second
+ TStringBuilder() << "Cannot compare key columns (" << leftKeys[i].first << "." << leftKeys[i].second
<< " has type: " << *leftKeyTypes[i] << ", " << rightKeys[i].first << "." << rightKeys[i].second
<< " has type: " << *rightKeyTypes[i] << ")"));
return IGraphTransformer::TStatus::Error;
@@ -857,7 +857,7 @@ bool IsRightJoinSideOptional(const TStringBuf& joinType) {
}
TExprNode::TPtr FilterOutNullJoinColumns(TPositionHandle pos, const TExprNode::TPtr& input,
- const TJoinLabel& label, const TSet<TString>& optionalKeyColumns, TExprContext& ctx) {
+ const TJoinLabel& label, const TSet<TString>& optionalKeyColumns, TExprContext& ctx) {
if (optionalKeyColumns.empty()) {
return input;
}
@@ -871,9 +871,9 @@ TExprNode::TPtr FilterOutNullJoinColumns(TPositionHandle pos, const TExprNode::T
optColumns.push_back(ctx.NewAtom(pos, memberName));
}
- auto optTuple = ctx.NewList(pos, std::move(optColumns));
+ auto optTuple = ctx.NewList(pos, std::move(optColumns));
return ctx.Builder(pos)
- .Callable("SkipNullMembers")
+ .Callable("SkipNullMembers")
.Add(0, input)
.Add(1, optTuple)
.Seal()
@@ -882,7 +882,7 @@ TExprNode::TPtr FilterOutNullJoinColumns(TPositionHandle pos, const TExprNode::T
TMap<TStringBuf, TVector<TStringBuf>> LoadJoinRenameMap(const TExprNode& settings) {
TMap<TStringBuf, TVector<TStringBuf>> res;
- for (const auto& child : settings.Children()) {
+ for (const auto& child : settings.Children()) {
if (child->Child(0)->Content() == "rename") {
auto& v = res[child->Child(1)->Content()];
if (!child->Child(2)->Content().empty()) {
@@ -910,7 +910,7 @@ TSet<TVector<TStringBuf>> LoadJoinSortSets(const TExprNode& settings) {
THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode& joins,
const TJoinLabels& labels, TExprContext& ctx) {
- return GetJoinColumnTypes(joins, labels, joins.Child(0)->Content(), ctx);
+ return GetJoinColumnTypes(joins, labels, joins.Child(0)->Content(), ctx);
}
THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode& joins,
@@ -920,26 +920,26 @@ THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode
THashMap<TString, const TTypeAnnotationNode*> rightType;
bool isLeftOptional = IsLeftJoinSideOptional(joinType);
bool isRightOptional = IsRightJoinSideOptional(joinType);
- if (joins.Child(1)->IsAtom()) {
- auto name = joins.Child(1)->Content();
+ if (joins.Child(1)->IsAtom()) {
+ auto name = joins.Child(1)->Content();
auto input = *labels.FindInput(name);
for (auto& x : input->InputType->GetItems()) {
leftType[input->FullName(x->GetName())] = x->GetItemType();
}
}
else {
- leftType = GetJoinColumnTypes(*joins.Child(1), labels, ctx);
+ leftType = GetJoinColumnTypes(*joins.Child(1), labels, ctx);
}
- if (joins.Child(2)->IsAtom()) {
- auto name = joins.Child(2)->Content();
+ if (joins.Child(2)->IsAtom()) {
+ auto name = joins.Child(2)->Content();
auto input = *labels.FindInput(name);
for (auto& x : input->InputType->GetItems()) {
rightType[input->FullName(x->GetName())] = x->GetItemType();
}
}
else {
- rightType = GetJoinColumnTypes(*joins.Child(2), labels, ctx);
+ rightType = GetJoinColumnTypes(*joins.Child(2), labels, ctx);
}
if (isLeftOptional) {
@@ -969,31 +969,31 @@ THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode
return finalType;
}
-bool AreSameJoinKeys(const TExprNode& joins, const TStringBuf& table1, const TStringBuf& column1, const TStringBuf& table2, const TStringBuf& column2) {
- if (!joins.Child(1)->IsAtom()) {
- if (AreSameJoinKeys(*joins.Child(1), table1, column1, table2, column2)) {
+bool AreSameJoinKeys(const TExprNode& joins, const TStringBuf& table1, const TStringBuf& column1, const TStringBuf& table2, const TStringBuf& column2) {
+ if (!joins.Child(1)->IsAtom()) {
+ if (AreSameJoinKeys(*joins.Child(1), table1, column1, table2, column2)) {
return true;
}
}
- if (!joins.Child(2)->IsAtom()) {
- if (AreSameJoinKeys(*joins.Child(2), table1, column1, table2, column2)) {
+ if (!joins.Child(2)->IsAtom()) {
+ if (AreSameJoinKeys(*joins.Child(2), table1, column1, table2, column2)) {
return true;
}
}
- for (ui32 i = 0; i < joins.Child(3)->ChildrenSize(); i += 2) {
- if (joins.Child(3)->Child(i)->Content() == table1) {
- if (joins.Child(4)->Child(i)->Content() == table2 &&
- joins.Child(3)->Child(i + 1)->Content() == column1 &&
- joins.Child(4)->Child(i + 1)->Content() == column2) {
+ for (ui32 i = 0; i < joins.Child(3)->ChildrenSize(); i += 2) {
+ if (joins.Child(3)->Child(i)->Content() == table1) {
+ if (joins.Child(4)->Child(i)->Content() == table2 &&
+ joins.Child(3)->Child(i + 1)->Content() == column1 &&
+ joins.Child(4)->Child(i + 1)->Content() == column2) {
return true;
}
}
- else if (joins.Child(3)->Child(i)->Content() == table2) {
- if (joins.Child(4)->Child(i)->Content() == table1 &&
- joins.Child(3)->Child(i + 1)->Content() == column2 &&
- joins.Child(4)->Child(i + 1)->Content() == column1) {
+ else if (joins.Child(3)->Child(i)->Content() == table2) {
+ if (joins.Child(4)->Child(i)->Content() == table1 &&
+ joins.Child(3)->Child(i + 1)->Content() == column2 &&
+ joins.Child(4)->Child(i + 1)->Content() == column1) {
return true;
}
}
@@ -1244,299 +1244,299 @@ TExprNode::TPtr RemapNonConvertibleMemberForJoin(TPositionHandle pos, const TExp
return result;
}
-TExprNode::TPtr PrepareListForJoin(TExprNode::TPtr list, const TTypeAnnotationNode::TListType& keyTypes, TExprNode::TListType& keys, TExprNode::TListType& payloads, bool payload, bool optional, bool filter, TExprContext& ctx) {
- const auto pos = list->Pos();
-
- if (keyTypes.empty() && 1U == keys.size()) {
- return payload ?
- ctx.Builder(pos)
- .Callable("Map")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .List()
- .Add(0, std::move(keys.front()))
- .Callable(1, "FilterMembers")
- .Arg(0, "row")
- .List(1)
- .Add(std::move(payloads))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable("List")
- .Callable(0, "ListType")
- .Callable(0, "DataType")
- .Atom(0, "Bool", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Build();
- }
-
- if (1U == keyTypes.size()) {
- const auto keyType = ctx.MakeType<TOptionalExprType>(keyTypes.front());
- list = payload ? optional ?
- ctx.Builder(pos)
- .Callable("Map")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .List()
- .Callable(0, "StrictCast")
- .Callable(0, "Member")
- .Arg(0, "row")
- .Add(1, std::move(keys.front()))
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Callable(1, "FilterMembers")
- .Arg(0, "row")
- .List(1)
- .Add(std::move(payloads))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable("FlatMap")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable("FlatMap")
- .Callable(0, "StrictCast")
- .Callable(0, "Member")
- .Arg(0, "row")
- .Add(1, std::move(keys.front()))
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Lambda(1)
- .Param("key")
- .Callable("Just")
- .List(0)
- .Arg(0, "key")
- .Callable(1, "FilterMembers")
- .Arg(0, "row")
- .List(1)
- .Add(std::move(payloads))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable(optional ? "Map" : "FlatMap")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable("StrictCast")
- .Callable(0, "Member")
- .Arg(0, "row")
- .Add(1, std::move(keys.front()))
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Seal()
- .Seal()
- .Build();
- } else {
- const auto keyType = ctx.MakeType<TOptionalExprType>(ctx.MakeType<TTupleExprType>(keyTypes));
- list = payload ? optional ?
- ctx.Builder(pos)
- .Callable("Map")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .List()
- .Callable(0, "StrictCast")
- .List(0)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (auto& key : keys) {
- parent.Callable(pos++, "Member")
- .Arg(0, "row")
- .Add(1, std::move(key))
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Callable(1, "FilterMembers")
- .Arg(0, "row")
- .List(1)
- .Add(std::move(payloads))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable("FlatMap")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable("FlatMap")
- .Callable(0, "StrictCast")
- .List(0)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (auto& key : keys) {
- parent.Callable(pos++, "Member")
- .Arg(0, "row")
- .Add(1, std::move(key))
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Lambda(1)
- .Param("key")
- .Callable("Just")
- .List(0)
- .Arg(0, "key")
- .Callable(1, "FilterMembers")
- .Arg(0, "row")
- .List(1)
- .Add(std::move(payloads))
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable(optional ? "Map" : "FlatMap")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable("StrictCast")
- .List(0)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (auto& key : keys) {
- parent.Callable(pos++, "Member")
- .Arg(0, "row")
- .Add(1, std::move(key))
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Add(1, ExpandType(pos, *keyType, ctx))
- .Seal()
- .Seal()
- .Seal()
- .Build();
- }
-
- if (optional && filter) {
- list = payload ?
- ctx.Builder(pos)
- .Callable("Filter")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable(0, "Exists")
- .Callable(0, "Nth")
- .Arg(0, "row")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(pos)
- .Callable("Filter")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable(0, "Exists")
- .Arg(0, "row")
- .Seal()
- .Seal()
- .Seal()
- .Build();
- }
-
- return list;
-}
-
-template <bool Squeeze>
-TExprNode::TPtr MakeDictForJoin(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx) {
- return payload ?
- ctx.Builder(list->Pos())
- .Callable(Squeeze ? "SqueezeToDict" : "ToDict")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Callable("Nth")
- .Arg(0, "row")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Lambda(2)
- .Param("row")
- .Callable("Nth")
- .Arg(0, "row")
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Seal()
- .List(3)
- .Atom(0, multi ? "Many" : "One", TNodeFlags::Default)
- .Atom(1, "Hashed", TNodeFlags::Default)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if constexpr (Squeeze)
- parent.Atom(2, "Compact", TNodeFlags::Default);
- return parent;
-
- })
- .Seal()
- .Seal()
- .Build():
- ctx.Builder(list->Pos())
- .Callable(Squeeze ? "SqueezeToDict" : "ToDict")
- .Add(0, std::move(list))
- .Lambda(1)
- .Param("row")
- .Arg("row")
- .Seal()
- .Lambda(2)
- .Param("stub")
- .Callable("Void").Seal()
- .Seal()
- .List(3)
- .Atom(0, multi ? "Many" : "One", TNodeFlags::Default)
- .Atom(1, "Hashed", TNodeFlags::Default)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if constexpr (Squeeze)
- parent.Atom(2, "Compact", TNodeFlags::Default);
- return parent;
-
- })
- .Seal()
- .Seal()
- .Build();
-}
-
-template TExprNode::TPtr MakeDictForJoin<true>(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
-template TExprNode::TPtr MakeDictForJoin<false>(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
-
+TExprNode::TPtr PrepareListForJoin(TExprNode::TPtr list, const TTypeAnnotationNode::TListType& keyTypes, TExprNode::TListType& keys, TExprNode::TListType& payloads, bool payload, bool optional, bool filter, TExprContext& ctx) {
+ const auto pos = list->Pos();
+
+ if (keyTypes.empty() && 1U == keys.size()) {
+ return payload ?
+ ctx.Builder(pos)
+ .Callable("Map")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .List()
+ .Add(0, std::move(keys.front()))
+ .Callable(1, "FilterMembers")
+ .Arg(0, "row")
+ .List(1)
+ .Add(std::move(payloads))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable("List")
+ .Callable(0, "ListType")
+ .Callable(0, "DataType")
+ .Atom(0, "Bool", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ if (1U == keyTypes.size()) {
+ const auto keyType = ctx.MakeType<TOptionalExprType>(keyTypes.front());
+ list = payload ? optional ?
+ ctx.Builder(pos)
+ .Callable("Map")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .List()
+ .Callable(0, "StrictCast")
+ .Callable(0, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(keys.front()))
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Callable(1, "FilterMembers")
+ .Arg(0, "row")
+ .List(1)
+ .Add(std::move(payloads))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable("FlatMap")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable("FlatMap")
+ .Callable(0, "StrictCast")
+ .Callable(0, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(keys.front()))
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Lambda(1)
+ .Param("key")
+ .Callable("Just")
+ .List(0)
+ .Arg(0, "key")
+ .Callable(1, "FilterMembers")
+ .Arg(0, "row")
+ .List(1)
+ .Add(std::move(payloads))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable(optional ? "Map" : "FlatMap")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable("StrictCast")
+ .Callable(0, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(keys.front()))
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ } else {
+ const auto keyType = ctx.MakeType<TOptionalExprType>(ctx.MakeType<TTupleExprType>(keyTypes));
+ list = payload ? optional ?
+ ctx.Builder(pos)
+ .Callable("Map")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .List()
+ .Callable(0, "StrictCast")
+ .List(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (auto& key : keys) {
+ parent.Callable(pos++, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(key))
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Callable(1, "FilterMembers")
+ .Arg(0, "row")
+ .List(1)
+ .Add(std::move(payloads))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable("FlatMap")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable("FlatMap")
+ .Callable(0, "StrictCast")
+ .List(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (auto& key : keys) {
+ parent.Callable(pos++, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(key))
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Lambda(1)
+ .Param("key")
+ .Callable("Just")
+ .List(0)
+ .Arg(0, "key")
+ .Callable(1, "FilterMembers")
+ .Arg(0, "row")
+ .List(1)
+ .Add(std::move(payloads))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable(optional ? "Map" : "FlatMap")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable("StrictCast")
+ .List(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (auto& key : keys) {
+ parent.Callable(pos++, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(key))
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Add(1, ExpandType(pos, *keyType, ctx))
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ if (optional && filter) {
+ list = payload ?
+ ctx.Builder(pos)
+ .Callable("Filter")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable(0, "Exists")
+ .Callable(0, "Nth")
+ .Arg(0, "row")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(pos)
+ .Callable("Filter")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable(0, "Exists")
+ .Arg(0, "row")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ return list;
+}
+
+template <bool Squeeze>
+TExprNode::TPtr MakeDictForJoin(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx) {
+ return payload ?
+ ctx.Builder(list->Pos())
+ .Callable(Squeeze ? "SqueezeToDict" : "ToDict")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Callable("Nth")
+ .Arg(0, "row")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Lambda(2)
+ .Param("row")
+ .Callable("Nth")
+ .Arg(0, "row")
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .List(3)
+ .Atom(0, multi ? "Many" : "One", TNodeFlags::Default)
+ .Atom(1, "Hashed", TNodeFlags::Default)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if constexpr (Squeeze)
+ parent.Atom(2, "Compact", TNodeFlags::Default);
+ return parent;
+
+ })
+ .Seal()
+ .Seal()
+ .Build():
+ ctx.Builder(list->Pos())
+ .Callable(Squeeze ? "SqueezeToDict" : "ToDict")
+ .Add(0, std::move(list))
+ .Lambda(1)
+ .Param("row")
+ .Arg("row")
+ .Seal()
+ .Lambda(2)
+ .Param("stub")
+ .Callable("Void").Seal()
+ .Seal()
+ .List(3)
+ .Atom(0, multi ? "Many" : "One", TNodeFlags::Default)
+ .Atom(1, "Hashed", TNodeFlags::Default)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if constexpr (Squeeze)
+ parent.Atom(2, "Compact", TNodeFlags::Default);
+ return parent;
+
+ })
+ .Seal()
+ .Seal()
+ .Build();
+}
+
+template TExprNode::TPtr MakeDictForJoin<true>(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
+template TExprNode::TPtr MakeDictForJoin<false>(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
+
} // namespace NYql
diff --git a/ydb/library/yql/core/yql_join.h b/ydb/library/yql/core/yql_join.h
index 4bc834c7a1..b01b950c2d 100644
--- a/ydb/library/yql/core/yql_join.h
+++ b/ydb/library/yql/core/yql_join.h
@@ -81,7 +81,7 @@ bool IsLeftJoinSideOptional(const TStringBuf& joinType);
bool IsRightJoinSideOptional(const TStringBuf& joinType);
TExprNode::TPtr FilterOutNullJoinColumns(TPositionHandle pos, const TExprNode::TPtr& input,
- const TJoinLabel& label, const TSet<TString>& optionalKeyColumns, TExprContext& ctx);
+ const TJoinLabel& label, const TSet<TString>& optionalKeyColumns, TExprContext& ctx);
TMap<TStringBuf, TVector<TStringBuf>> LoadJoinRenameMap(const TExprNode& settings);
TSet<TVector<TStringBuf>> LoadJoinSortSets(const TExprNode& settings);
@@ -92,7 +92,7 @@ THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode
THashMap<TString, const TTypeAnnotationNode*> GetJoinColumnTypes(const TExprNode& joins,
const TJoinLabels& labels, const TStringBuf& joinType, TExprContext& ctx);
-bool AreSameJoinKeys(const TExprNode& joins, const TStringBuf& table1, const TStringBuf& column1, const TStringBuf& table2, const TStringBuf& column2);
+bool AreSameJoinKeys(const TExprNode& joins, const TStringBuf& table1, const TStringBuf& column1, const TStringBuf& table2, const TStringBuf& column2);
// returns (is required side + allow skip nulls);
std::pair<bool, bool> IsRequiredSide(const TExprNode::TPtr& joinTree, const TJoinLabels& labels, ui32 inputIndex);
@@ -137,9 +137,9 @@ TExprNode::TPtr BuildEquiJoinLinkSettings(const TEquiJoinLinkSettings& linkSetti
TExprNode::TPtr RemapNonConvertibleMemberForJoin(TPositionHandle pos, const TExprNode::TPtr& memberValue,
const TTypeAnnotationNode& memberType, const TTypeAnnotationNode& unifiedType, TExprContext& ctx);
-TExprNode::TPtr PrepareListForJoin(TExprNode::TPtr list, const TTypeAnnotationNode::TListType& keyTypes, TExprNode::TListType& keys, TExprNode::TListType& payloads, bool payload, bool optional, bool filter, TExprContext& ctx);
-
-template<bool Squeeze = false>
-TExprNode::TPtr MakeDictForJoin(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
-
+TExprNode::TPtr PrepareListForJoin(TExprNode::TPtr list, const TTypeAnnotationNode::TListType& keyTypes, TExprNode::TListType& keys, TExprNode::TListType& payloads, bool payload, bool optional, bool filter, TExprContext& ctx);
+
+template<bool Squeeze = false>
+TExprNode::TPtr MakeDictForJoin(TExprNode::TPtr&& list, bool payload, bool multi, TExprContext& ctx);
+
}
diff --git a/ydb/library/yql/core/yql_library_compiler.cpp b/ydb/library/yql/core/yql_library_compiler.cpp
index db18c2b1fd..79296792e6 100644
--- a/ydb/library/yql/core/yql_library_compiler.cpp
+++ b/ydb/library/yql/core/yql_library_compiler.cpp
@@ -1,47 +1,47 @@
-#include "yql_library_compiler.h"
+#include "yql_library_compiler.h"
#include "yql_expr_optimize.h"
-
-#include <util/system/file.h>
-
-#include <unordered_set>
-#include <unordered_map>
-
-namespace NYql {
-
-namespace {
-
+
+#include <util/system/file.h>
+
+#include <unordered_set>
+#include <unordered_map>
+
+namespace NYql {
+
+namespace {
+
bool ReplaceNodes(TExprNode& node, const TNodeOnNodeOwnedMap& replaces, bool& hasChanges, TNodeSet& visited, TNodeSet& parents)
-{
- if (!node.ChildrenSize()) {
+{
+ if (!node.ChildrenSize()) {
return true;
}
-
- const auto pair = parents.emplace(&node);
+
+ const auto pair = parents.emplace(&node);
if (!pair.second) {
- return false;
+ return false;
}
-
+
if (!visited.emplace(&node).second) {
parents.erase(pair.first);
return true;
}
- for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
- auto& child = node.ChildRef(i);
- if (const auto it = replaces.find(node.Child(i)); replaces.cend() != it) {
- child = it->second;
- hasChanges = true;
+ for (ui32 i = 0U; i < node.ChildrenSize(); ++i) {
+ auto& child = node.ChildRef(i);
+ if (const auto it = replaces.find(node.Child(i)); replaces.cend() != it) {
+ child = it->second;
+ hasChanges = true;
}
-
+
if (!ReplaceNodes(*node.Child(i), replaces, hasChanges, visited, parents)) {
- child.Reset();
- return false;
- }
- }
- parents.erase(pair.first);
- return true;
-}
-
+ child.Reset();
+ return false;
+ }
+ }
+ parents.erase(pair.first);
+ return true;
+}
+
bool ReplaceNodes(TExprNode& node, const TNodeOnNodeOwnedMap& replaces, bool& hasChanges) {
TNodeSet visited;
TNodeSet parents;
@@ -49,17 +49,17 @@ bool ReplaceNodes(TExprNode& node, const TNodeOnNodeOwnedMap& replaces, bool& ha
}
TString Load(const TString& path)
-{
+{
TFile file(path, EOpenModeFlag::RdOnly);
- if (file.GetLength() <= 0)
+ if (file.GetLength() <= 0)
return TString();
std::vector<TString::value_type> buffer(file.GetLength());
- file.Load(buffer.data(), buffer.size());
+ file.Load(buffer.data(), buffer.size());
return TString(buffer.data(), buffer.size());
-}
-
-}
-
+}
+
+}
+
bool OptimizeLibrary(TLibraryCohesion& cohesion, TExprContext& ctx) {
TExprNode::TListType tupleItems;
for (const auto& x : cohesion.Exports.Symbols()) {
@@ -88,7 +88,7 @@ bool OptimizeLibrary(TLibraryCohesion& cohesion, TExprContext& ctx) {
}
bool CompileLibrary(const TString& alias, const TString& script, TExprContext& ctx, TLibraryCohesion& cohesion, bool optimize)
-{
+{
const auto& res = ParseAst(script, nullptr, alias);
if (!res.IsOk()) {
for (const auto& originalError : res.Issues) {
@@ -98,20 +98,20 @@ bool CompileLibrary(const TString& alias, const TString& script, TExprContext& c
error.Message = message;
ctx.AddError(error);
}
- return false;
+ return false;
}
-
- if (!CompileExpr(*res.Root, cohesion, ctx))
- return false;
-
+
+ if (!CompileExpr(*res.Root, cohesion, ctx))
+ return false;
+
if (!optimize) {
return true;
}
return OptimizeLibrary(cohesion, ctx);
-}
-
-bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const TModulesTable* loadedModules) {
+}
+
+bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const TModulesTable* loadedModules) {
std::function<const TExportTable*(const TString&)> f = [loadedModules](const TString& normalizedModuleName) -> const TExportTable* {
if (!loadedModules) {
return nullptr;
@@ -123,26 +123,26 @@ bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx,
return LinkLibraries(libs, ctx, ctxToClone, f);
}
-bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const std::function<const TExportTable*(const TString&)>& module2ExportTable)
-{
- TNodeOnNodeOwnedMap clones, replaces;
- for (const auto& lib : libs) {
- for (const auto& import : lib.second.Imports) {
- if (import.first->Dead()) {
- continue;
- }
-
- if (import.second.first == lib.first) {
+bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const std::function<const TExportTable*(const TString&)>& module2ExportTable)
+{
+ TNodeOnNodeOwnedMap clones, replaces;
+ for (const auto& lib : libs) {
+ for (const auto& import : lib.second.Imports) {
+ if (import.first->Dead()) {
+ continue;
+ }
+
+ if (import.second.first == lib.first) {
ctx.AddError(TIssue(ctxToClone.GetPosition(import.first->Pos()),
TStringBuilder() << "Library '" << lib.first << "' tries to import itself."));
- return false;
- }
-
- const auto* exportTable = module2ExportTable(TModuleResolver::NormalizeModuleName(import.second.first));
- const bool externalModule = exportTable;
+ return false;
+ }
+
+ const auto* exportTable = module2ExportTable(TModuleResolver::NormalizeModuleName(import.second.first));
+ const bool externalModule = exportTable;
if (!exportTable) {
- if (const auto it = libs.find(import.second.first); libs.cend() != it) {
+ if (const auto it = libs.find(import.second.first); libs.cend() != it) {
exportTable = &it->second.Exports;
}
}
@@ -150,48 +150,48 @@ bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx,
if (!exportTable) {
ctx.AddError(TIssue(ctxToClone.GetPosition(import.first->Pos()),
TStringBuilder() << "Library '" << lib.first << "' has unresolved dependency from '" << import.second.first << "'."));
- return false;
- }
-
- if (const auto ex = exportTable->Symbols().find(import.second.second); exportTable->Symbols().cend() != ex) {
- replaces[import.first] = externalModule ? ctxToClone.DeepCopy(*ex->second, exportTable->ExprCtx(), clones, true, false) : ex->second;
- } else {
+ return false;
+ }
+
+ if (const auto ex = exportTable->Symbols().find(import.second.second); exportTable->Symbols().cend() != ex) {
+ replaces[import.first] = externalModule ? ctxToClone.DeepCopy(*ex->second, exportTable->ExprCtx(), clones, true, false) : ex->second;
+ } else {
ctx.AddError(TIssue(ctxToClone.GetPosition(import.first->Pos()),
TStringBuilder() << "Library '" << lib.first << "' has unresolved symbol '" << import.second.second << "' from '" << import.second.first << "'."));
- return false;
- }
- }
- }
-
- if (!replaces.empty()) {
- for (auto& lib : libs) {
- for (auto& expo : lib.second.Exports.Symbols(lib.second.Exports.ExprCtx())) {
- if (const auto find = replaces.find(expo.second.Get()); replaces.cend() != find)
- expo.second = find->second;
- }
- }
- }
-
- for (bool hasChanges = !replaces.empty(); hasChanges;) {
- hasChanges = false;
- for (const auto& lib : libs) {
+ return false;
+ }
+ }
+ }
+
+ if (!replaces.empty()) {
+ for (auto& lib : libs) {
+ for (auto& expo : lib.second.Exports.Symbols(lib.second.Exports.ExprCtx())) {
+ if (const auto find = replaces.find(expo.second.Get()); replaces.cend() != find)
+ expo.second = find->second;
+ }
+ }
+ }
+
+ for (bool hasChanges = !replaces.empty(); hasChanges;) {
+ hasChanges = false;
+ for (const auto& lib : libs) {
for (const auto& expo : lib.second.Exports.Symbols()) {
- if (!ReplaceNodes(*expo.second, replaces, hasChanges)) {
+ if (!ReplaceNodes(*expo.second, replaces, hasChanges)) {
ctx.AddError(TIssue(ctxToClone.GetPosition(expo.second->Pos()),
TStringBuilder() << "Cross reference detected under '" << expo.first << "' in '" << lib.first << "'."));
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
bool CompileLibraries(const TUserDataTable& userData, TExprContext& ctx, TModulesTable& modules, bool optimize)
-{
+{
THashMap<TString, TLibraryCohesion> libs;
- for (const auto& data : userData) {
+ for (const auto& data : userData) {
if (data.first.IsFile() && data.second.Usage.Test(EUserDataBlockUsage::Library)) {
TString libraryData;
const TString& alias = data.first.Alias();
@@ -207,10 +207,10 @@ bool CompileLibraries(const TUserDataTable& userData, TExprContext& ctx, TModule
else
return false;
}
- }
- }
-
+ }
+ }
+
return LinkLibraries(libs, ctx, ctx);
-}
-
-}
+}
+
+}
diff --git a/ydb/library/yql/core/yql_library_compiler.h b/ydb/library/yql/core/yql_library_compiler.h
index b219923c4f..eb6abb83a5 100644
--- a/ydb/library/yql/core/yql_library_compiler.h
+++ b/ydb/library/yql/core/yql_library_compiler.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/ast/yql_expr.h>
-#include "yql_type_annotation.h"
-
-namespace NYql {
-
+#include "yql_type_annotation.h"
+
+namespace NYql {
+
bool OptimizeLibrary(TLibraryCohesion& cohesion, TExprContext& ctx);
bool CompileLibrary(const TString& alias, const TString& script, TExprContext& ctx, TLibraryCohesion& cohesion, bool optimize = true);
-bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const std::function<const TExportTable*(const TString&)>& module2ExportTable);
-bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const TModulesTable* loadedModules = nullptr);
-
+bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const std::function<const TExportTable*(const TString&)>& module2ExportTable);
+bool LinkLibraries(THashMap<TString, TLibraryCohesion>& libs, TExprContext& ctx, TExprContext& ctxToClone, const TModulesTable* loadedModules = nullptr);
+
bool CompileLibraries(const TUserDataTable& userData, TExprContext& ctx, TModulesTable& modules, bool optimize = true);
-}
+}
diff --git a/ydb/library/yql/core/yql_opt_aggregate.cpp b/ydb/library/yql/core/yql_opt_aggregate.cpp
index 21b8a55c83..226339b8c5 100644
--- a/ydb/library/yql/core/yql_opt_aggregate.cpp
+++ b/ydb/library/yql/core/yql_opt_aggregate.cpp
@@ -1,18 +1,18 @@
-#include "yql_opt_aggregate.h"
-#include "yql_opt_utils.h"
+#include "yql_opt_aggregate.h"
+#include "yql_opt_utils.h"
#include "yql_opt_window.h"
-#include "yql_expr_type_annotation.h"
-
-namespace NYql {
-
+#include "yql_expr_type_annotation.h"
+
+namespace NYql {
+
TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx, bool forceCompact) {
- auto list = node->HeadPtr();
+ auto list = node->HeadPtr();
auto keyColumns = node->ChildPtr(1);
- auto aggregatedColumns = node->Child(2);
+ auto aggregatedColumns = node->Child(2);
auto settings = node->Child(3);
- YQL_ENSURE(!HasSetting(*settings, "hopping"), "Aggregate with hopping unsupported here.");
-
+ YQL_ENSURE(!HasSetting(*settings, "hopping"), "Aggregate with hopping unsupported here.");
+
static const TStringBuf sessionStartMemberName = "_yql_group_session_start";
const TExprNode::TPtr voidNode = ctx.NewCallable(node->Pos(), "Void", {});
@@ -82,818 +82,818 @@ TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx,
effectiveCompact = true;
}
}
-
+
const bool compact = effectiveCompact;
const auto rowType = ctx.MakeType<TStructExprType>(rowItems);
-
- auto preMap = ctx.Builder(node->Pos())
- .Lambda()
- .Param("premap")
- .Callable("Just").Arg(0, "premap").Seal()
- .Seal().Build();
-
- bool needPickle = false;
- TVector<const TTypeAnnotationNode*> keyItemTypes;
- for (auto keyColumn : keyColumns->Children()) {
- auto index = rowType->FindItem(keyColumn->Content());
- YQL_ENSURE(index, "Unknown column: " << keyColumn->Content());
- auto type = rowType->GetItems()[*index]->GetItemType();
- keyItemTypes.push_back(type);
+
+ auto preMap = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("premap")
+ .Callable("Just").Arg(0, "premap").Seal()
+ .Seal().Build();
+
+ bool needPickle = false;
+ TVector<const TTypeAnnotationNode*> keyItemTypes;
+ for (auto keyColumn : keyColumns->Children()) {
+ auto index = rowType->FindItem(keyColumn->Content());
+ YQL_ENSURE(index, "Unknown column: " << keyColumn->Content());
+ auto type = rowType->GetItems()[*index]->GetItemType();
+ keyItemTypes.push_back(type);
needPickle = needPickle || !IsDataOrOptionalOfData(type);
- }
-
- const TTypeAnnotationNode* pickleType = nullptr;
- TExprNode::TPtr pickleTypeNode;
- if (needPickle) {
- pickleType = keyColumns->ChildrenSize() > 1 ? ctx.MakeType<TTupleExprType>(keyItemTypes) : keyItemTypes[0];
- pickleTypeNode = ExpandType(node->Pos(), *pickleType, ctx);
- }
-
- auto keyExtractor = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (keyColumns->ChildrenSize() == 0) {
- return parent.Callable("Uint32").Atom(0, "0", TNodeFlags::Default).Seal();
- }
- else if (keyColumns->ChildrenSize() == 1) {
- return parent.Callable("Member").Arg(0, "item").Add(1, keyColumns->HeadPtr()).Seal();
- }
- else {
- auto listBuilder = parent.List();
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- listBuilder
- .Callable(pos++, "Member")
- .Arg(0, "item")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal();
- }
-
- return listBuilder.Seal();
- }
- })
- .Seal()
- .Build();
-
- if (needPickle) {
- keyExtractor = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Callable("StablePickle")
- .Apply(0, *keyExtractor)
- .With(0, "item")
- .Seal()
- .Seal()
- .Seal()
- .Build();
- }
-
- TExprNode::TListType initialColumnNames;
- TExprNode::TListType finalColumnNames;
- TExprNode::TListType distinctFields;
- using TIdxSet = std::set<ui32>;
- std::unordered_map<std::string_view, TIdxSet> distinct2Columns;
- std::unordered_map<std::string_view, bool> distinctFieldNeedsPickle;
- std::unordered_map<std::string_view, TExprNode::TPtr> udfSetCreate;
- std::unordered_map<std::string_view, TExprNode::TPtr> udfAddValue;
- std::unordered_map<std::string_view, TExprNode::TPtr> udfWasChanged;
- TIdxSet nondistinctColumns;
- for (auto child : aggregatedColumns->Children()) {
- if (const auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr) {
- const auto ins = distinct2Columns.emplace(distinctField->Content(), TIdxSet());
- if (ins.second) {
- distinctFields.push_back(distinctField);
- }
- ins.first->second.insert(initialColumnNames.size());
- } else {
- nondistinctColumns.insert(initialColumnNames.size());
- }
-
- if (child->Head().IsAtom()) {
- finalColumnNames.push_back(child->HeadPtr());
- } else {
- finalColumnNames.push_back(child->Head().HeadPtr());
- }
-
- initialColumnNames.push_back(ctx.NewAtom(finalColumnNames.back()->Pos(), "_yql_agg_" + ToString(initialColumnNames.size()), TNodeFlags::Default));
- }
-
- TExprNode::TListType nothingStates;
- for (ui32 index = 0; index < aggregatedColumns->ChildrenSize(); ++index) {
- auto trait = aggregatedColumns->Child(index)->Child(1);
-
- auto saveLambda = trait->Child(3);
- auto saveLambdaType = saveLambda->GetTypeAnn();
- auto typeNode = ExpandType(node->Pos(), *saveLambdaType, ctx);
- nothingStates.push_back(ctx.Builder(node->Pos())
- .Callable("Nothing")
- .Callable(0, "OptionalType")
- .Add(0, std::move(typeNode))
- .Seal()
- .Seal()
- .Build()
- );
- }
-
- TExprNode::TPtr groupInput;
-
- if (!nondistinctColumns.empty()) {
- auto combineInit = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 ndx = 0;
- for (ui32 i: nondistinctColumns) {
- auto trait = aggregatedColumns->Child(i)->Child(1);
- auto initLambda = trait->Child(1);
- if (initLambda->Head().ChildrenSize() == 1) {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *initLambda)
- .With(0)
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal()
- .Done()
- .Seal()
- .Seal();
- } else {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *initLambda)
- .With(0)
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal()
- .Done()
- .With(1)
- .Callable("Uint32")
- .Atom(0, ToString(i), TNodeFlags::Default)
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
- auto combineUpdate = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Param("state")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 ndx = 0;
- for (ui32 i: nondistinctColumns) {
- auto trait = aggregatedColumns->Child(i)->Child(1);
- auto updateLambda = trait->Child(2);
- if (updateLambda->Head().ChildrenSize() == 2) {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *updateLambda)
- .With(0)
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal()
- .Done()
- .With(1)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Seal();
- } else {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *updateLambda)
- .With(0)
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal()
- .Done()
- .With(1)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .With(2)
- .Callable("Uint32")
- .Atom(0, ToString(i), TNodeFlags::Default)
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
- auto combineSave = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("state")
- .Callable("Just")
- .Callable(0, "AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
- if (nondistinctColumns.find(i) == nondistinctColumns.end()) {
- parent.List(i)
- .Add(0, initialColumnNames[i])
- .Add(1, nothingStates[i])
- .Seal();
- } else {
- auto trait = aggregatedColumns->Child(i)->Child(1);
- auto saveLambda = trait->Child(3);
- if (!distinctFields.empty()) {
- parent.List(i)
- .Add(0, initialColumnNames[i])
- .Callable(1, "Just")
- .Apply(0, *saveLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Seal();
- } else {
- parent.List(i)
- .Add(0, initialColumnNames[i])
- .Apply(1, *saveLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- }
- }
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- auto listBuilder = parent.List(initialColumnNames.size() + i);
- listBuilder.Add(0, keyColumns->ChildPtr(i));
- if (keyColumns->ChildrenSize() > 1) {
- if (needPickle) {
- listBuilder
- .Callable(1, "Nth")
- .Callable(0, "Unpickle")
- .Add(0, pickleTypeNode)
- .Arg(1, "key")
- .Seal()
- .Atom(1, ToString(pos), TNodeFlags::Default)
- .Seal();
- } else {
- listBuilder
- .Callable(1, "Nth")
- .Arg(0, "key")
- .Atom(1, ToString(pos), TNodeFlags::Default)
- .Seal();
- }
- ++pos;
- } else {
- if (needPickle) {
- listBuilder.Callable(1, "Unpickle")
- .Add(0, pickleTypeNode)
- .Arg(1, "key")
- .Seal();
- } else {
- listBuilder.Arg(1, "key");
- }
- }
- listBuilder.Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Build();
-
- groupInput = ctx.Builder(node->Pos())
- .Callable("CombineByKey")
- .Add(0, list)
- .Add(1, preMap)
- .Add(2, keyExtractor)
- .Add(3, std::move(combineInit))
- .Add(4, std::move(combineUpdate))
- .Add(5, std::move(combineSave))
- .Seal()
- .Build();
- }
-
- for (ui32 index = 0; index < distinctFields.size(); ++index) {
- auto distinctField = distinctFields[index];
- auto& indicies = distinct2Columns[distinctField->Content()];
- auto distinctIndex = rowType->FindItem(distinctField->Content());
- YQL_ENSURE(distinctIndex, "Unknown field: " << distinctField->Content());
- auto distinctType = rowType->GetItems()[*distinctIndex]->GetItemType();
- TVector<const TTypeAnnotationNode*> distinctKeyItemTypes = keyItemTypes;
- distinctKeyItemTypes.push_back(distinctType);
- bool needDistinctPickle = compact ? false : needPickle;
- auto valueType = distinctType;
- if (distinctType->GetKind() == ETypeAnnotationKind::Optional) {
- distinctType = distinctType->Cast<TOptionalExprType>()->GetItemType();
- }
-
- if (distinctType->GetKind() != ETypeAnnotationKind::Data) {
- needDistinctPickle = true;
- valueType = ctx.MakeType<TDataExprType>(EDataSlot::String);
- }
-
- const auto expandedValueType = needDistinctPickle ?
- ctx.Builder(node->Pos())
- .Callable("DataType")
- .Atom(0, "String", TNodeFlags::Default)
- .Seal()
- .Build():
- ExpandType(node->Pos(), *valueType, ctx);
-
- distinctFieldNeedsPickle[distinctField->Content()] = needDistinctPickle;
- auto udfSetCreateValue = ctx.Builder(node->Pos())
- .Callable("Udf")
- .Atom(0, "Set.Create")
- .Callable(1, "Void").Seal()
- .Callable(2, "TupleType")
- .Callable(0, "TupleType")
- .Add(0, expandedValueType)
- .Callable(1, "DataType")
- .Atom(0, "Uint32", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Callable(1, "StructType").Seal()
- .Add(2, expandedValueType)
- .Seal()
- .Seal()
- .Build();
-
- udfSetCreate[distinctField->Content()] = udfSetCreateValue;
- auto resourceType = ctx.Builder(node->Pos())
- .Callable("TypeOf")
- .Callable(0, "Apply")
- .Add(0, udfSetCreateValue)
- .Callable(1, "InstanceOf")
- .Add(0, expandedValueType)
- .Seal()
- .Callable(2, "Uint32")
- .Atom(0, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Seal()
- .Build();
-
- udfAddValue[distinctField->Content()] = ctx.Builder(node->Pos())
- .Callable("Udf")
- .Atom(0, "Set.AddValue")
- .Callable(1, "Void").Seal()
- .Callable(2, "TupleType")
- .Callable(0, "TupleType")
- .Add(0, resourceType)
- .Add(1, expandedValueType)
- .Seal()
- .Callable(1, "StructType").Seal()
- .Add(2, expandedValueType)
- .Seal()
- .Seal()
- .Build();
-
- udfWasChanged[distinctField->Content()] = ctx.Builder(node->Pos())
- .Callable("Udf")
- .Atom(0, "Set.WasChanged")
- .Callable(1, "Void").Seal()
- .Callable(2, "TupleType")
- .Callable(0, "TupleType")
- .Add(0, resourceType)
- .Seal()
- .Callable(1, "StructType").Seal()
- .Add(2, expandedValueType)
- .Seal()
- .Seal()
- .Build();
-
- auto distinctKeyExtractor = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (keyColumns->ChildrenSize() != 0) {
- auto listBuilder = parent.List();
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- listBuilder
- .Callable(pos++, "Member")
- .Arg(0, "item")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal();
- }
- listBuilder
- .Callable(pos, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
-
- return listBuilder.Seal();
- } else {
- return parent
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- }
- })
- .Seal()
- .Build();
-
- const TTypeAnnotationNode* distinctPickleType = nullptr;
- TExprNode::TPtr distinctPickleTypeNode;
- if (needDistinctPickle) {
- distinctPickleType = keyColumns->ChildrenSize() > 0 ? ctx.MakeType<TTupleExprType>(distinctKeyItemTypes) : distinctKeyItemTypes.front();
- distinctPickleTypeNode = ExpandType(node->Pos(), *distinctPickleType, ctx);
- }
-
- if (needDistinctPickle) {
- distinctKeyExtractor = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Callable("StablePickle")
- .Apply(0, *distinctKeyExtractor).With(0, "item").Seal()
- .Seal()
- .Seal()
- .Build();
- }
-
- auto distinctCombineInit = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 ndx = 0;
- for (ui32 i: indicies) {
- auto trait = aggregatedColumns->Child(i)->Child(1);
- auto initLambda = trait->Child(1);
- if (initLambda->Head().ChildrenSize() == 1) {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *initLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal()
- .Done()
- .Seal()
- .Seal();
- } else {
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *initLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal()
- .Done()
- .With(1)
- .Callable("Uint32")
- .Atom(0, ToString(i), TNodeFlags::Default)
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
- auto distinctCombineUpdate = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Param("state")
- .Arg("state")
- .Seal()
- .Build();
-
- ui32 ndx = 0;
- auto distinctCombineSave = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("state")
- .Callable("Just")
- .Callable(0, "AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i: indicies) {
- auto trait = aggregatedColumns->Child(i)->Child(1);
- auto saveLambda = trait->Child(3);
- parent.List(ndx++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *saveLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (keyColumns->ChildrenSize() > 0) {
- if (needDistinctPickle) {
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- parent.List(ndx++)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Nth")
- .Callable(0, "Unpickle")
- .Add(0, distinctPickleTypeNode)
- .Arg(1, "key")
- .Seal()
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal()
- .Seal();
- }
- parent.List(ndx++)
- .Add(0, distinctField)
- .Callable(1, "Nth")
- .Callable(0, "Unpickle")
- .Add(0, distinctPickleTypeNode)
- .Arg(1, "key")
- .Seal()
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal()
- .Seal();
-
- } else {
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- parent.List(ndx++)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Nth")
- .Arg(0, "key")
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal()
- .Seal();
- }
- parent.List(ndx++)
- .Add(0, distinctField)
- .Callable(1, "Nth")
- .Arg(0, "key")
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal()
- .Seal();
- }
- } else {
- if (needDistinctPickle) {
- parent.List(ndx++)
- .Add(0, distinctField)
- .Callable(1, "Unpickle")
- .Add(0, distinctPickleTypeNode)
- .Arg(1, "key")
- .Seal()
- .Seal();
- } else {
- parent.List(ndx++)
- .Add(0, distinctField)
- .Arg(1, "key")
- .Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Build();
-
- auto distinctCombiner = ctx.Builder(node->Pos())
- .Callable("CombineByKey")
- .Add(0, list)
- .Add(1, preMap)
- .Add(2, distinctKeyExtractor)
- .Add(3, std::move(distinctCombineInit))
- .Add(4, std::move(distinctCombineUpdate))
- .Add(5, std::move(distinctCombineSave))
- .Seal()
- .Build();
-
- auto distinctGrouper = ctx.Builder(node->Pos())
- .Callable("PartitionsByKeys")
- .Add(0, std::move(distinctCombiner))
- .Add(1, distinctKeyExtractor)
- .Callable(2, "Void").Seal()
- .Callable(3, "Void").Seal()
- .Lambda(4)
- .Param("groups")
- .Callable("Map")
- .Callable(0, "Condense1")
- .Arg(0, "groups")
- .Lambda(1)
- .Param("item")
- .Arg("item")
- .Seal()
- .Lambda(2)
- .Param("item")
- .Param("state")
- .Callable("IsKeySwitch")
- .Arg(0, "item")
- .Arg(1, "state")
- .Add(2, distinctKeyExtractor)
- .Add(3, distinctKeyExtractor)
- .Seal()
- .Seal()
- .Lambda(3)
- .Param("item")
- .Param("state")
- .Arg("item")
- .Seal()
- .Seal()
- .Lambda(1)
- .Param("state")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
- if (indicies.find(i) != indicies.end()) {
- parent.List(i)
- .Add(0, initialColumnNames[i])
- .Callable(1, "Just")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Seal()
- .Seal();
- } else {
- parent.List(i)
- .Add(0, initialColumnNames[i])
- .Add(1, nothingStates[i])
- .Seal();
- }
- }
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (keyColumns->ChildrenSize() > 0) {
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- parent.List(initialColumnNames.size() + i)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Member")
- .Arg(0, "state")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal().Seal();
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Seal()
- .Build();
-
- if (!groupInput) {
- groupInput = std::move(distinctGrouper);
- } else {
- groupInput = ctx.Builder(node->Pos())
- .Callable("Extend")
- .Add(0, std::move(groupInput))
- .Add(1, std::move(distinctGrouper))
- .Seal()
- .Build();
- }
- }
-
- // If no aggregation functions than add addional combiner
+ }
+
+ const TTypeAnnotationNode* pickleType = nullptr;
+ TExprNode::TPtr pickleTypeNode;
+ if (needPickle) {
+ pickleType = keyColumns->ChildrenSize() > 1 ? ctx.MakeType<TTupleExprType>(keyItemTypes) : keyItemTypes[0];
+ pickleTypeNode = ExpandType(node->Pos(), *pickleType, ctx);
+ }
+
+ auto keyExtractor = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (keyColumns->ChildrenSize() == 0) {
+ return parent.Callable("Uint32").Atom(0, "0", TNodeFlags::Default).Seal();
+ }
+ else if (keyColumns->ChildrenSize() == 1) {
+ return parent.Callable("Member").Arg(0, "item").Add(1, keyColumns->HeadPtr()).Seal();
+ }
+ else {
+ auto listBuilder = parent.List();
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ listBuilder
+ .Callable(pos++, "Member")
+ .Arg(0, "item")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal();
+ }
+
+ return listBuilder.Seal();
+ }
+ })
+ .Seal()
+ .Build();
+
+ if (needPickle) {
+ keyExtractor = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Callable("StablePickle")
+ .Apply(0, *keyExtractor)
+ .With(0, "item")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ TExprNode::TListType initialColumnNames;
+ TExprNode::TListType finalColumnNames;
+ TExprNode::TListType distinctFields;
+ using TIdxSet = std::set<ui32>;
+ std::unordered_map<std::string_view, TIdxSet> distinct2Columns;
+ std::unordered_map<std::string_view, bool> distinctFieldNeedsPickle;
+ std::unordered_map<std::string_view, TExprNode::TPtr> udfSetCreate;
+ std::unordered_map<std::string_view, TExprNode::TPtr> udfAddValue;
+ std::unordered_map<std::string_view, TExprNode::TPtr> udfWasChanged;
+ TIdxSet nondistinctColumns;
+ for (auto child : aggregatedColumns->Children()) {
+ if (const auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr) {
+ const auto ins = distinct2Columns.emplace(distinctField->Content(), TIdxSet());
+ if (ins.second) {
+ distinctFields.push_back(distinctField);
+ }
+ ins.first->second.insert(initialColumnNames.size());
+ } else {
+ nondistinctColumns.insert(initialColumnNames.size());
+ }
+
+ if (child->Head().IsAtom()) {
+ finalColumnNames.push_back(child->HeadPtr());
+ } else {
+ finalColumnNames.push_back(child->Head().HeadPtr());
+ }
+
+ initialColumnNames.push_back(ctx.NewAtom(finalColumnNames.back()->Pos(), "_yql_agg_" + ToString(initialColumnNames.size()), TNodeFlags::Default));
+ }
+
+ TExprNode::TListType nothingStates;
+ for (ui32 index = 0; index < aggregatedColumns->ChildrenSize(); ++index) {
+ auto trait = aggregatedColumns->Child(index)->Child(1);
+
+ auto saveLambda = trait->Child(3);
+ auto saveLambdaType = saveLambda->GetTypeAnn();
+ auto typeNode = ExpandType(node->Pos(), *saveLambdaType, ctx);
+ nothingStates.push_back(ctx.Builder(node->Pos())
+ .Callable("Nothing")
+ .Callable(0, "OptionalType")
+ .Add(0, std::move(typeNode))
+ .Seal()
+ .Seal()
+ .Build()
+ );
+ }
+
+ TExprNode::TPtr groupInput;
+
+ if (!nondistinctColumns.empty()) {
+ auto combineInit = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 ndx = 0;
+ for (ui32 i: nondistinctColumns) {
+ auto trait = aggregatedColumns->Child(i)->Child(1);
+ auto initLambda = trait->Child(1);
+ if (initLambda->Head().ChildrenSize() == 1) {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *initLambda)
+ .With(0)
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *initLambda)
+ .With(0)
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("Uint32")
+ .Atom(0, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto combineUpdate = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Param("state")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 ndx = 0;
+ for (ui32 i: nondistinctColumns) {
+ auto trait = aggregatedColumns->Child(i)->Child(1);
+ auto updateLambda = trait->Child(2);
+ if (updateLambda->Head().ChildrenSize() == 2) {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *updateLambda)
+ .With(0)
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *updateLambda)
+ .With(0)
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .With(2)
+ .Callable("Uint32")
+ .Atom(0, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto combineSave = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("state")
+ .Callable("Just")
+ .Callable(0, "AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
+ if (nondistinctColumns.find(i) == nondistinctColumns.end()) {
+ parent.List(i)
+ .Add(0, initialColumnNames[i])
+ .Add(1, nothingStates[i])
+ .Seal();
+ } else {
+ auto trait = aggregatedColumns->Child(i)->Child(1);
+ auto saveLambda = trait->Child(3);
+ if (!distinctFields.empty()) {
+ parent.List(i)
+ .Add(0, initialColumnNames[i])
+ .Callable(1, "Just")
+ .Apply(0, *saveLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(i)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *saveLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ }
+ }
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ auto listBuilder = parent.List(initialColumnNames.size() + i);
+ listBuilder.Add(0, keyColumns->ChildPtr(i));
+ if (keyColumns->ChildrenSize() > 1) {
+ if (needPickle) {
+ listBuilder
+ .Callable(1, "Nth")
+ .Callable(0, "Unpickle")
+ .Add(0, pickleTypeNode)
+ .Arg(1, "key")
+ .Seal()
+ .Atom(1, ToString(pos), TNodeFlags::Default)
+ .Seal();
+ } else {
+ listBuilder
+ .Callable(1, "Nth")
+ .Arg(0, "key")
+ .Atom(1, ToString(pos), TNodeFlags::Default)
+ .Seal();
+ }
+ ++pos;
+ } else {
+ if (needPickle) {
+ listBuilder.Callable(1, "Unpickle")
+ .Add(0, pickleTypeNode)
+ .Arg(1, "key")
+ .Seal();
+ } else {
+ listBuilder.Arg(1, "key");
+ }
+ }
+ listBuilder.Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+
+ groupInput = ctx.Builder(node->Pos())
+ .Callable("CombineByKey")
+ .Add(0, list)
+ .Add(1, preMap)
+ .Add(2, keyExtractor)
+ .Add(3, std::move(combineInit))
+ .Add(4, std::move(combineUpdate))
+ .Add(5, std::move(combineSave))
+ .Seal()
+ .Build();
+ }
+
+ for (ui32 index = 0; index < distinctFields.size(); ++index) {
+ auto distinctField = distinctFields[index];
+ auto& indicies = distinct2Columns[distinctField->Content()];
+ auto distinctIndex = rowType->FindItem(distinctField->Content());
+ YQL_ENSURE(distinctIndex, "Unknown field: " << distinctField->Content());
+ auto distinctType = rowType->GetItems()[*distinctIndex]->GetItemType();
+ TVector<const TTypeAnnotationNode*> distinctKeyItemTypes = keyItemTypes;
+ distinctKeyItemTypes.push_back(distinctType);
+ bool needDistinctPickle = compact ? false : needPickle;
+ auto valueType = distinctType;
+ if (distinctType->GetKind() == ETypeAnnotationKind::Optional) {
+ distinctType = distinctType->Cast<TOptionalExprType>()->GetItemType();
+ }
+
+ if (distinctType->GetKind() != ETypeAnnotationKind::Data) {
+ needDistinctPickle = true;
+ valueType = ctx.MakeType<TDataExprType>(EDataSlot::String);
+ }
+
+ const auto expandedValueType = needDistinctPickle ?
+ ctx.Builder(node->Pos())
+ .Callable("DataType")
+ .Atom(0, "String", TNodeFlags::Default)
+ .Seal()
+ .Build():
+ ExpandType(node->Pos(), *valueType, ctx);
+
+ distinctFieldNeedsPickle[distinctField->Content()] = needDistinctPickle;
+ auto udfSetCreateValue = ctx.Builder(node->Pos())
+ .Callable("Udf")
+ .Atom(0, "Set.Create")
+ .Callable(1, "Void").Seal()
+ .Callable(2, "TupleType")
+ .Callable(0, "TupleType")
+ .Add(0, expandedValueType)
+ .Callable(1, "DataType")
+ .Atom(0, "Uint32", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Callable(1, "StructType").Seal()
+ .Add(2, expandedValueType)
+ .Seal()
+ .Seal()
+ .Build();
+
+ udfSetCreate[distinctField->Content()] = udfSetCreateValue;
+ auto resourceType = ctx.Builder(node->Pos())
+ .Callable("TypeOf")
+ .Callable(0, "Apply")
+ .Add(0, udfSetCreateValue)
+ .Callable(1, "InstanceOf")
+ .Add(0, expandedValueType)
+ .Seal()
+ .Callable(2, "Uint32")
+ .Atom(0, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+
+ udfAddValue[distinctField->Content()] = ctx.Builder(node->Pos())
+ .Callable("Udf")
+ .Atom(0, "Set.AddValue")
+ .Callable(1, "Void").Seal()
+ .Callable(2, "TupleType")
+ .Callable(0, "TupleType")
+ .Add(0, resourceType)
+ .Add(1, expandedValueType)
+ .Seal()
+ .Callable(1, "StructType").Seal()
+ .Add(2, expandedValueType)
+ .Seal()
+ .Seal()
+ .Build();
+
+ udfWasChanged[distinctField->Content()] = ctx.Builder(node->Pos())
+ .Callable("Udf")
+ .Atom(0, "Set.WasChanged")
+ .Callable(1, "Void").Seal()
+ .Callable(2, "TupleType")
+ .Callable(0, "TupleType")
+ .Add(0, resourceType)
+ .Seal()
+ .Callable(1, "StructType").Seal()
+ .Add(2, expandedValueType)
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto distinctKeyExtractor = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (keyColumns->ChildrenSize() != 0) {
+ auto listBuilder = parent.List();
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ listBuilder
+ .Callable(pos++, "Member")
+ .Arg(0, "item")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal();
+ }
+ listBuilder
+ .Callable(pos, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+
+ return listBuilder.Seal();
+ } else {
+ return parent
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ }
+ })
+ .Seal()
+ .Build();
+
+ const TTypeAnnotationNode* distinctPickleType = nullptr;
+ TExprNode::TPtr distinctPickleTypeNode;
+ if (needDistinctPickle) {
+ distinctPickleType = keyColumns->ChildrenSize() > 0 ? ctx.MakeType<TTupleExprType>(distinctKeyItemTypes) : distinctKeyItemTypes.front();
+ distinctPickleTypeNode = ExpandType(node->Pos(), *distinctPickleType, ctx);
+ }
+
+ if (needDistinctPickle) {
+ distinctKeyExtractor = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Callable("StablePickle")
+ .Apply(0, *distinctKeyExtractor).With(0, "item").Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
+ auto distinctCombineInit = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 ndx = 0;
+ for (ui32 i: indicies) {
+ auto trait = aggregatedColumns->Child(i)->Child(1);
+ auto initLambda = trait->Child(1);
+ if (initLambda->Head().ChildrenSize() == 1) {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *initLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *initLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("Uint32")
+ .Atom(0, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto distinctCombineUpdate = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Param("state")
+ .Arg("state")
+ .Seal()
+ .Build();
+
+ ui32 ndx = 0;
+ auto distinctCombineSave = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("state")
+ .Callable("Just")
+ .Callable(0, "AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i: indicies) {
+ auto trait = aggregatedColumns->Child(i)->Child(1);
+ auto saveLambda = trait->Child(3);
+ parent.List(ndx++)
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *saveLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (keyColumns->ChildrenSize() > 0) {
+ if (needDistinctPickle) {
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ parent.List(ndx++)
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Nth")
+ .Callable(0, "Unpickle")
+ .Add(0, distinctPickleTypeNode)
+ .Arg(1, "key")
+ .Seal()
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ }
+ parent.List(ndx++)
+ .Add(0, distinctField)
+ .Callable(1, "Nth")
+ .Callable(0, "Unpickle")
+ .Add(0, distinctPickleTypeNode)
+ .Arg(1, "key")
+ .Seal()
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+
+ } else {
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ parent.List(ndx++)
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Nth")
+ .Arg(0, "key")
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ }
+ parent.List(ndx++)
+ .Add(0, distinctField)
+ .Callable(1, "Nth")
+ .Arg(0, "key")
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ }
+ } else {
+ if (needDistinctPickle) {
+ parent.List(ndx++)
+ .Add(0, distinctField)
+ .Callable(1, "Unpickle")
+ .Add(0, distinctPickleTypeNode)
+ .Arg(1, "key")
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(ndx++)
+ .Add(0, distinctField)
+ .Arg(1, "key")
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto distinctCombiner = ctx.Builder(node->Pos())
+ .Callable("CombineByKey")
+ .Add(0, list)
+ .Add(1, preMap)
+ .Add(2, distinctKeyExtractor)
+ .Add(3, std::move(distinctCombineInit))
+ .Add(4, std::move(distinctCombineUpdate))
+ .Add(5, std::move(distinctCombineSave))
+ .Seal()
+ .Build();
+
+ auto distinctGrouper = ctx.Builder(node->Pos())
+ .Callable("PartitionsByKeys")
+ .Add(0, std::move(distinctCombiner))
+ .Add(1, distinctKeyExtractor)
+ .Callable(2, "Void").Seal()
+ .Callable(3, "Void").Seal()
+ .Lambda(4)
+ .Param("groups")
+ .Callable("Map")
+ .Callable(0, "Condense1")
+ .Arg(0, "groups")
+ .Lambda(1)
+ .Param("item")
+ .Arg("item")
+ .Seal()
+ .Lambda(2)
+ .Param("item")
+ .Param("state")
+ .Callable("IsKeySwitch")
+ .Arg(0, "item")
+ .Arg(1, "state")
+ .Add(2, distinctKeyExtractor)
+ .Add(3, distinctKeyExtractor)
+ .Seal()
+ .Seal()
+ .Lambda(3)
+ .Param("item")
+ .Param("state")
+ .Arg("item")
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Param("state")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
+ if (indicies.find(i) != indicies.end()) {
+ parent.List(i)
+ .Add(0, initialColumnNames[i])
+ .Callable(1, "Just")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Seal()
+ .Seal();
+ } else {
+ parent.List(i)
+ .Add(0, initialColumnNames[i])
+ .Add(1, nothingStates[i])
+ .Seal();
+ }
+ }
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (keyColumns->ChildrenSize() > 0) {
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ parent.List(initialColumnNames.size() + i)
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Member")
+ .Arg(0, "state")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal().Seal();
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+
+ if (!groupInput) {
+ groupInput = std::move(distinctGrouper);
+ } else {
+ groupInput = ctx.Builder(node->Pos())
+ .Callable("Extend")
+ .Add(0, std::move(groupInput))
+ .Add(1, std::move(distinctGrouper))
+ .Seal()
+ .Build();
+ }
+ }
+
+ // If no aggregation functions than add addional combiner
if (aggregatedColumns->ChildrenSize() == 0 && keyColumns->ChildrenSize() > 0 && !sessionUpdate) {
- // Return key as-is
- auto uniqCombineInit = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 pos = 0;
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- auto listBuilder = parent.List(i);
- listBuilder.Add(0, keyColumns->Child(i));
- if (keyColumns->ChildrenSize() > 1) {
- if (needPickle) {
- listBuilder
- .Callable(1, "Nth")
- .Callable(0, "Unpickle")
- .Add(0, pickleTypeNode)
- .Arg(1, "key")
- .Seal()
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal();
- } else {
- listBuilder
- .Callable(1, "Nth")
- .Arg(0, "key")
- .Atom(1, ToString(pos++), TNodeFlags::Default)
- .Seal();
- }
- } else {
- if (needPickle) {
- listBuilder.Callable(1, "Unpickle")
- .Add(0, pickleTypeNode)
- .Arg(1, "key")
- .Seal();
- } else {
- listBuilder.Arg(1, "key");
- }
- }
- listBuilder.Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
- auto uniqCombineUpdate = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("item")
- .Param("state")
- .Arg("state")
- .Seal()
- .Build();
-
- // Return state as-is
- auto uniqCombineSave = ctx.Builder(node->Pos())
- .Lambda()
- .Param("key")
- .Param("state")
- .Callable("Just")
- .Arg(0, "state")
- .Seal()
- .Seal()
- .Build();
-
- if (!groupInput) {
- groupInput = list;
- }
-
- groupInput = ctx.Builder(node->Pos())
- .Callable("CombineByKey")
- .Add(0, std::move(groupInput))
- .Add(1, preMap)
- .Add(2, keyExtractor)
- .Add(3, std::move(uniqCombineInit))
- .Add(4, std::move(uniqCombineUpdate))
- .Add(5, std::move(uniqCombineSave))
- .Seal()
- .Build();
- }
-
+ // Return key as-is
+ auto uniqCombineInit = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 pos = 0;
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ auto listBuilder = parent.List(i);
+ listBuilder.Add(0, keyColumns->Child(i));
+ if (keyColumns->ChildrenSize() > 1) {
+ if (needPickle) {
+ listBuilder
+ .Callable(1, "Nth")
+ .Callable(0, "Unpickle")
+ .Add(0, pickleTypeNode)
+ .Arg(1, "key")
+ .Seal()
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal();
+ } else {
+ listBuilder
+ .Callable(1, "Nth")
+ .Arg(0, "key")
+ .Atom(1, ToString(pos++), TNodeFlags::Default)
+ .Seal();
+ }
+ } else {
+ if (needPickle) {
+ listBuilder.Callable(1, "Unpickle")
+ .Add(0, pickleTypeNode)
+ .Arg(1, "key")
+ .Seal();
+ } else {
+ listBuilder.Arg(1, "key");
+ }
+ }
+ listBuilder.Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
+ auto uniqCombineUpdate = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("item")
+ .Param("state")
+ .Arg("state")
+ .Seal()
+ .Build();
+
+ // Return state as-is
+ auto uniqCombineSave = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("key")
+ .Param("state")
+ .Callable("Just")
+ .Arg(0, "state")
+ .Seal()
+ .Seal()
+ .Build();
+
+ if (!groupInput) {
+ groupInput = list;
+ }
+
+ groupInput = ctx.Builder(node->Pos())
+ .Callable("CombineByKey")
+ .Add(0, std::move(groupInput))
+ .Add(1, preMap)
+ .Add(2, keyExtractor)
+ .Add(3, std::move(uniqCombineInit))
+ .Add(4, std::move(uniqCombineUpdate))
+ .Add(5, std::move(uniqCombineSave))
+ .Seal()
+ .Build();
+ }
+
ui32 index = 0U;
- auto groupInit = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- parent
+ auto groupInit = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ parent
.List(index++)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Member")
- .Arg(0, "item")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal()
- .Seal();
- }
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Member")
+ .Arg(0, "item")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal()
+ .Seal();
+ }
if (sessionUpdate) {
parent
.List(index++)
@@ -904,155 +904,155 @@ TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx,
.Seal()
.Seal();
}
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
- auto child = aggregatedColumns->Child(i);
- auto trait = child->Child(1);
- if (!compact) {
- auto loadLambda = trait->Child(4);
-
- if (!distinctFields.empty()) {
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
+ auto child = aggregatedColumns->Child(i);
+ auto trait = child->Child(1);
+ if (!compact) {
+ auto loadLambda = trait->Child(4);
+
+ if (!distinctFields.empty()) {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Callable(1, "Map")
- .Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Add(1, loadLambda)
- .Seal()
- .Seal();
- } else {
+ .Add(0, initialColumnNames[i])
+ .Callable(1, "Map")
+ .Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Add(1, loadLambda)
+ .Seal()
+ .Seal();
+ } else {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *loadLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal();
- }
- } else {
- auto initLambda = trait->Child(1);
- auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
- auto initApply = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- parent.Apply(1, *initLambda)
- .With(0)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (distinctField) {
- parent
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- } else {
- parent
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal();
- }
-
- return parent;
- })
- .Done()
- .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
- if (initLambda->Head().ChildrenSize() == 2) {
- parent.With(1)
- .Callable("Uint32")
- .Atom(0, ToString(i), TNodeFlags::Default)
- .Seal()
- .Done();
- }
-
- return parent;
- })
- .Seal();
-
- return parent;
- };
-
- if (distinctField) {
- const bool isFirst = *distinct2Columns[distinctField->Content()].begin() == i;
- if (isFirst) {
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *loadLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal();
+ }
+ } else {
+ auto initLambda = trait->Child(1);
+ auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
+ auto initApply = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ parent.Apply(1, *initLambda)
+ .With(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (distinctField) {
+ parent
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ } else {
+ parent
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *initLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Done()
+ .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
+ if (initLambda->Head().ChildrenSize() == 2) {
+ parent.With(1)
+ .Callable("Uint32")
+ .Atom(0, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Done();
+ }
+
+ return parent;
+ })
+ .Seal();
+
+ return parent;
+ };
+
+ if (distinctField) {
+ const bool isFirst = *distinct2Columns[distinctField->Content()].begin() == i;
+ if (isFirst) {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .List(1)
- .Callable(0, "NamedApply")
- .Add(0, udfSetCreate[distinctField->Content()])
- .List(1)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (!distinctFieldNeedsPickle[distinctField->Content()]) {
- parent.Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- } else {
- parent.Callable(0, "StablePickle")
- .Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal()
- .Seal();
- }
-
- return parent;
- })
- .Callable(1, "Uint32")
- .Atom(0, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
- .Callable(2, "AsStruct").Seal()
- .Callable(3, "DependsOn")
- .Callable(0, "String")
- .Add(0, distinctField)
- .Seal()
- .Seal()
- .Seal()
- .Do(initApply)
- .Seal()
- .Seal();
- } else {
+ .Add(0, initialColumnNames[i])
+ .List(1)
+ .Callable(0, "NamedApply")
+ .Add(0, udfSetCreate[distinctField->Content()])
+ .List(1)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (!distinctFieldNeedsPickle[distinctField->Content()]) {
+ parent.Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ } else {
+ parent.Callable(0, "StablePickle")
+ .Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal()
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Callable(1, "Uint32")
+ .Atom(0, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
+ .Callable(2, "AsStruct").Seal()
+ .Callable(3, "DependsOn")
+ .Callable(0, "String")
+ .Add(0, distinctField)
+ .Seal()
+ .Seal()
+ .Seal()
+ .Do(initApply)
+ .Seal()
+ .Seal();
+ } else {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Do(initApply)
- .Seal();
- }
- } else {
+ .Add(0, initialColumnNames[i])
+ .Do(initApply)
+ .Seal();
+ }
+ } else {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Do(initApply)
- .Seal();
- }
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
+ .Add(0, initialColumnNames[i])
+ .Do(initApply)
+ .Seal();
+ }
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
index = 0;
- auto groupMerge = ctx.Builder(node->Pos())
- .Lambda()
- .Param("item")
- .Param("state")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
- parent
+ auto groupMerge = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("item")
+ .Param("state")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ parent
.List(index++)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Member")
- .Arg(0, "state")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal()
- .Seal();
- }
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Member")
+ .Arg(0, "state")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal()
+ .Seal();
+ }
if (sessionUpdate) {
parent
.List(index++)
@@ -1063,247 +1063,247 @@ TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx,
.Seal()
.Seal();
}
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
- auto child = aggregatedColumns->Child(i);
- auto trait = child->Child(1);
- if (!compact) {
- auto loadLambda = trait->Child(4);
- auto mergeLambda = trait->Child(5);
-
- if (!distinctFields.empty()) {
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
+ auto child = aggregatedColumns->Child(i);
+ auto trait = child->Child(1);
+ if (!compact) {
+ auto loadLambda = trait->Child(4);
+ auto mergeLambda = trait->Child(5);
+
+ if (!distinctFields.empty()) {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Callable(1, "OptionalReduce")
- .Callable(0, "Map")
- .Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Add(1, loadLambda)
- .Seal()
- .Callable(1, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Add(2, mergeLambda)
- .Seal()
- .Seal();
- } else {
+ .Add(0, initialColumnNames[i])
+ .Callable(1, "OptionalReduce")
+ .Callable(0, "Map")
+ .Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Add(1, loadLambda)
+ .Seal()
+ .Callable(1, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Add(2, mergeLambda)
+ .Seal()
+ .Seal();
+ } else {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Apply(1, *mergeLambda)
- .With(0)
- .Apply(*loadLambda)
- .With(0)
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Done()
- .With(1)
- .Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Done()
- .Seal()
- .Seal();
- }
- } else {
- auto updateLambda = trait->Child(2);
- auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
- const bool isFirst = distinctField ? (*distinct2Columns[distinctField->Content()].begin() == i) : false;
- auto updateApply = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- parent.Apply(1, *updateLambda)
- .With(0)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (distinctField) {
- parent
- .Callable("Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- } else {
- parent
- .Callable("CastStruct")
- .Arg(0, "item")
- .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
- .Seal();
- }
-
- return parent;
- })
- .Done()
- .With(1)
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (distinctField && isFirst) {
- parent.Callable("Nth")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Atom(1, "1", TNodeFlags::Default)
- .Seal();
- } else {
- parent.Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal();
- }
-
- return parent;
- })
- .Done()
- .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
- if (updateLambda->Head().ChildrenSize() == 3) {
- parent
- .With(2)
- .Callable("Uint32")
- .Atom(0, ToString(i), TNodeFlags::Default)
- .Seal()
- .Done();
- }
-
- return parent;
- })
- .Seal();
-
- return parent;
- };
-
- if (distinctField) {
- auto distinctIndex = *distinct2Columns[distinctField->Content()].begin();
- ui32 newValueIndex = 0;
- auto newValue = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- parent.Callable(newValueIndex, "NamedApply")
- .Add(0, udfAddValue[distinctField->Content()])
- .List(1)
- .Callable(0, "Nth")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[distinctIndex])
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (!distinctFieldNeedsPickle[distinctField->Content()]) {
- parent.Callable(1, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- } else {
- parent.Callable(1, "StablePickle")
- .Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal()
- .Seal();
- }
-
- return parent;
- })
- .Seal()
- .Callable(2, "AsStruct").Seal()
- .Seal();
-
- return parent;
- };
-
+ .Add(0, initialColumnNames[i])
+ .Apply(1, *mergeLambda)
+ .With(0)
+ .Apply(*loadLambda)
+ .With(0)
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Done()
+ .With(1)
+ .Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal();
+ }
+ } else {
+ auto updateLambda = trait->Child(2);
+ auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
+ const bool isFirst = distinctField ? (*distinct2Columns[distinctField->Content()].begin() == i) : false;
+ auto updateApply = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ parent.Apply(1, *updateLambda)
+ .With(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (distinctField) {
+ parent
+ .Callable("Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ } else {
+ parent
+ .Callable("CastStruct")
+ .Arg(0, "item")
+ .Add(1, ExpandType(node->Pos(), *updateLambda->Head().Head().GetTypeAnn(), ctx))
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Done()
+ .With(1)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (distinctField && isFirst) {
+ parent.Callable("Nth")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal();
+ } else {
+ parent.Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Done()
+ .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
+ if (updateLambda->Head().ChildrenSize() == 3) {
+ parent
+ .With(2)
+ .Callable("Uint32")
+ .Atom(0, ToString(i), TNodeFlags::Default)
+ .Seal()
+ .Done();
+ }
+
+ return parent;
+ })
+ .Seal();
+
+ return parent;
+ };
+
+ if (distinctField) {
+ auto distinctIndex = *distinct2Columns[distinctField->Content()].begin();
+ ui32 newValueIndex = 0;
+ auto newValue = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ parent.Callable(newValueIndex, "NamedApply")
+ .Add(0, udfAddValue[distinctField->Content()])
+ .List(1)
+ .Callable(0, "Nth")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[distinctIndex])
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (!distinctFieldNeedsPickle[distinctField->Content()]) {
+ parent.Callable(1, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ } else {
+ parent.Callable(1, "StablePickle")
+ .Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal()
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Seal()
+ .Callable(2, "AsStruct").Seal()
+ .Seal();
+
+ return parent;
+ };
+
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Callable(1, "If")
- .Callable(0, "NamedApply")
- .Add(0, udfWasChanged[distinctField->Content()])
- .List(1)
- .Callable(0, "NamedApply")
- .Add(0, udfAddValue[distinctField->Content()])
- .List(1)
- .Callable(0, "Nth")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[distinctIndex])
- .Seal()
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (!distinctFieldNeedsPickle[distinctField->Content()]) {
- parent.Callable(1, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal();
- } else {
- parent.Callable(1, "StablePickle")
- .Callable(0, "Member")
- .Arg(0, "item")
- .Add(1, distinctField)
- .Seal()
- .Seal();
- }
-
- return parent;
- })
- .Seal()
- .Callable(2, "AsStruct").Seal()
- .Seal()
- .Seal()
- .Callable(2, "AsStruct").Seal()
- .Seal()
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- if (distinctIndex == i) {
- parent.List(1)
- .Do(newValue)
- .Do(updateApply)
- .Seal();
- } else {
- parent.Do(updateApply);
- }
-
- return parent;
- })
- .Callable(2, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Seal()
- .Seal();
- } else {
+ .Add(0, initialColumnNames[i])
+ .Callable(1, "If")
+ .Callable(0, "NamedApply")
+ .Add(0, udfWasChanged[distinctField->Content()])
+ .List(1)
+ .Callable(0, "NamedApply")
+ .Add(0, udfAddValue[distinctField->Content()])
+ .List(1)
+ .Callable(0, "Nth")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[distinctIndex])
+ .Seal()
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (!distinctFieldNeedsPickle[distinctField->Content()]) {
+ parent.Callable(1, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal();
+ } else {
+ parent.Callable(1, "StablePickle")
+ .Callable(0, "Member")
+ .Arg(0, "item")
+ .Add(1, distinctField)
+ .Seal()
+ .Seal();
+ }
+
+ return parent;
+ })
+ .Seal()
+ .Callable(2, "AsStruct").Seal()
+ .Seal()
+ .Seal()
+ .Callable(2, "AsStruct").Seal()
+ .Seal()
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ if (distinctIndex == i) {
+ parent.List(1)
+ .Do(newValue)
+ .Do(updateApply)
+ .Seal();
+ } else {
+ parent.Do(updateApply);
+ }
+
+ return parent;
+ })
+ .Callable(2, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Seal()
+ .Seal();
+ } else {
parent.List(index++)
- .Add(0, initialColumnNames[i])
- .Do(updateApply)
- .Seal();
- }
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
+ .Add(0, initialColumnNames[i])
+ .Do(updateApply)
+ .Seal();
+ }
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
index = 0U;
- auto groupSave = ctx.Builder(node->Pos())
- .Lambda()
- .Param("state")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
+ auto groupSave = ctx.Builder(node->Pos())
+ .Lambda()
+ .Param("state")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < keyColumns->ChildrenSize(); ++i) {
if (keyColumns->Child(i)->Content() == sessionStartMemberName) {
continue;
}
- parent
- .List(index++)
- .Add(0, keyColumns->ChildPtr(i))
- .Callable(1, "Member")
- .Arg(0, "state")
- .Add(1, keyColumns->ChildPtr(i))
- .Seal()
- .Seal();
- }
+ parent
+ .List(index++)
+ .Add(0, keyColumns->ChildPtr(i))
+ .Callable(1, "Member")
+ .Arg(0, "state")
+ .Add(1, keyColumns->ChildPtr(i))
+ .Seal()
+ .Seal();
+ }
if (sessionOutputColumn) {
parent
@@ -1315,107 +1315,107 @@ TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx,
.Seal()
.Seal();
}
- return parent;
- })
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
- auto child = aggregatedColumns->Child(i);
- auto trait = child->Child(1);
- auto finishLambda = trait->Child(6);
-
- if (!compact && !distinctFields.empty()) {
- if (child->Head().IsAtom()) {
- parent.List(index++)
- .Add(0, finalColumnNames[i])
- .Callable(1, "Unwrap")
- .Callable(0, "Map")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Add(1, finishLambda)
- .Seal()
- .Seal()
- .Seal();
- } else {
- const auto& multiFields = child->Child(0);
- for (ui32 field = 0; field < multiFields->ChildrenSize(); ++field) {
- parent.List(index++)
- .Atom(0, multiFields->Child(field)->Content())
- .Callable(1, "Nth")
- .Callable(0, "Unwrap")
- .Callable(0, "Map")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Add(1, finishLambda)
- .Seal()
- .Seal()
- .Atom(1, ToString(field), TNodeFlags::Default)
- .Seal()
- .Seal();
- }
- }
- } else {
- auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
- auto stateExtractor = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- const bool isFirst = distinctField ? (*distinct2Columns[distinctField->Content()].begin() == i) : false;
- if (distinctField && isFirst) {
- parent.Callable("Nth")
- .Callable(0, "Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal()
- .Atom(1, "1", TNodeFlags::Default)
- .Seal();
- } else {
- parent.Callable("Member")
- .Arg(0, "state")
- .Add(1, initialColumnNames[i])
- .Seal();
- }
-
- return parent;
- };
-
- if (child->Head().IsAtom()) {
- parent.List(index++)
- .Add(0, finalColumnNames[i])
- .Apply(1, *finishLambda)
- .With(0)
- .Do(stateExtractor)
- .Done()
- .Seal()
- .Seal();
- } else {
- const auto& multiFields = child->Head();
- for (ui32 field = 0; field < multiFields.ChildrenSize(); ++field) {
- parent.List(index++)
- .Atom(0, multiFields.Child(field)->Content())
- .Callable(1, "Nth")
- .Apply(0, *finishLambda)
- .With(0)
- .Do(stateExtractor)
- .Done()
- .Seal()
- .Atom(1, ToString(field), TNodeFlags::Default)
- .Seal()
- .Seal();
- }
- }
- }
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Build();
-
- if (compact || !groupInput) {
- groupInput = std::move(list);
- }
-
+ return parent;
+ })
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ for (ui32 i = 0; i < initialColumnNames.size(); ++i) {
+ auto child = aggregatedColumns->Child(i);
+ auto trait = child->Child(1);
+ auto finishLambda = trait->Child(6);
+
+ if (!compact && !distinctFields.empty()) {
+ if (child->Head().IsAtom()) {
+ parent.List(index++)
+ .Add(0, finalColumnNames[i])
+ .Callable(1, "Unwrap")
+ .Callable(0, "Map")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Add(1, finishLambda)
+ .Seal()
+ .Seal()
+ .Seal();
+ } else {
+ const auto& multiFields = child->Child(0);
+ for (ui32 field = 0; field < multiFields->ChildrenSize(); ++field) {
+ parent.List(index++)
+ .Atom(0, multiFields->Child(field)->Content())
+ .Callable(1, "Nth")
+ .Callable(0, "Unwrap")
+ .Callable(0, "Map")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Add(1, finishLambda)
+ .Seal()
+ .Seal()
+ .Atom(1, ToString(field), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ }
+ }
+ } else {
+ auto distinctField = (child->ChildrenSize() == 3) ? child->Child(2) : nullptr;
+ auto stateExtractor = [&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ const bool isFirst = distinctField ? (*distinct2Columns[distinctField->Content()].begin() == i) : false;
+ if (distinctField && isFirst) {
+ parent.Callable("Nth")
+ .Callable(0, "Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal()
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal();
+ } else {
+ parent.Callable("Member")
+ .Arg(0, "state")
+ .Add(1, initialColumnNames[i])
+ .Seal();
+ }
+
+ return parent;
+ };
+
+ if (child->Head().IsAtom()) {
+ parent.List(index++)
+ .Add(0, finalColumnNames[i])
+ .Apply(1, *finishLambda)
+ .With(0)
+ .Do(stateExtractor)
+ .Done()
+ .Seal()
+ .Seal();
+ } else {
+ const auto& multiFields = child->Head();
+ for (ui32 field = 0; field < multiFields.ChildrenSize(); ++field) {
+ parent.List(index++)
+ .Atom(0, multiFields.Child(field)->Content())
+ .Callable(1, "Nth")
+ .Apply(0, *finishLambda)
+ .With(0)
+ .Do(stateExtractor)
+ .Done()
+ .Seal()
+ .Atom(1, ToString(field), TNodeFlags::Default)
+ .Seal()
+ .Seal();
+ }
+ }
+ }
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Build();
+
+ if (compact || !groupInput) {
+ groupInput = std::move(list);
+ }
+
TExprNode::TPtr preprocessLambda;
TExprNode::TPtr condenseSwitch;
if (sessionUpdate) {
@@ -1496,33 +1496,33 @@ TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx,
.Build();
}
- auto grouper = ctx.Builder(node->Pos())
- .Callable("PartitionsByKeys")
- .Add(0, std::move(groupInput))
- .Add(1, keyExtractor)
+ auto grouper = ctx.Builder(node->Pos())
+ .Callable("PartitionsByKeys")
+ .Add(0, std::move(groupInput))
+ .Add(1, keyExtractor)
.Add(2, sortOrder)
.Add(3, sortKey)
- .Lambda(4)
- .Param("stream")
- .Callable("Map")
- .Callable(0, "Condense1")
+ .Lambda(4)
+ .Param("stream")
+ .Callable("Map")
+ .Callable(0, "Condense1")
.Apply(0, preprocessLambda)
.With(0, "stream")
.Seal()
- .Add(1, std::move(groupInit))
+ .Add(1, std::move(groupInit))
.Add(2, condenseSwitch)
- .Add(3, std::move(groupMerge))
- .Seal()
- .Add(1, std::move(groupSave))
- .Seal()
- .Seal()
- .Seal().Build();
-
+ .Add(3, std::move(groupMerge))
+ .Seal()
+ .Add(1, std::move(groupSave))
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
if (keyColumns->ChildrenSize() == 0 && !sessionSetting) {
- return MakeSingleGroupRow(*node, grouper, ctx);
- }
-
- return grouper;
-}
-
-}
+ return MakeSingleGroupRow(*node, grouper, ctx);
+ }
+
+ return grouper;
+}
+
+}
diff --git a/ydb/library/yql/core/yql_opt_aggregate.h b/ydb/library/yql/core/yql_opt_aggregate.h
index 2192ae6542..d254bffecf 100644
--- a/ydb/library/yql/core/yql_opt_aggregate.h
+++ b/ydb/library/yql/core/yql_opt_aggregate.h
@@ -1,12 +1,12 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
-
-namespace NYql {
-
+
+namespace NYql {
+
TExprNode::TPtr ExpandAggregate(const TExprNode::TPtr& node, TExprContext& ctx, bool forceCompact = false);
inline TExprNode::TPtr ExpandAggregateCompact(const TExprNode::TPtr& node, TExprContext& ctx) {
return ExpandAggregate(node, ctx, true);
}
-
-}
-
+
+}
+
diff --git a/ydb/library/yql/core/yql_opt_proposed_by_data.cpp b/ydb/library/yql/core/yql_opt_proposed_by_data.cpp
index 25ed4bf3fb..23a912303f 100644
--- a/ydb/library/yql/core/yql_opt_proposed_by_data.cpp
+++ b/ydb/library/yql/core/yql_opt_proposed_by_data.cpp
@@ -20,7 +20,7 @@ public:
, Finish(finish)
{}
-private:
+private:
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
HasRepeats = false;
if (Source == ESource::DataSource || Source == ESource::All) {
@@ -60,7 +60,7 @@ private:
return TStatus::Ok;
}
- ChooseRoot(std::move(input), output);
+ ChooseRoot(std::move(input), output);
return TStatus(TStatus::Repeat, true);
}
@@ -79,12 +79,12 @@ private:
}
TStatus HandleProvider(IDataProvider* provider, const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- TExprNode::TPtr newRoot;
+ TExprNode::TPtr newRoot;
TStatus status = GetTransformer(provider).Transform(input, newRoot, ctx);
-
+
if (status.Level == TStatus::Ok || status.Level == TStatus::Repeat) {
- if (newRoot && newRoot != input) {
+ if (newRoot && newRoot != input) {
NewRoots.push_back(newRoot);
}
} else if (status.Level == TStatus::Async) {
@@ -108,10 +108,10 @@ private:
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
for (auto& x : PendingProviders) {
- TExprNode::TPtr newRoot;
+ TExprNode::TPtr newRoot;
TStatus status = GetTransformer(x).ApplyAsyncChanges(input, newRoot, ctx);
if (status.Level == TStatus::Ok || status.Level == TStatus::Repeat) {
- if (newRoot && newRoot != input) {
+ if (newRoot && newRoot != input) {
NewRoots.push_back(newRoot);
}
HasRepeats = HasRepeats || status == TStatus::Repeat;
@@ -129,14 +129,14 @@ private:
: TStatus::Ok;
}
- ChooseRoot(std::move(input), output);
+ ChooseRoot(std::move(input), output);
return TStatus(TStatus::Repeat, true);
}
- void ChooseRoot(TExprNode::TPtr&& input, TExprNode::TPtr& output) {
+ void ChooseRoot(TExprNode::TPtr&& input, TExprNode::TPtr& output) {
// just get first
- output = std::move(NewRoots.empty() ? input : NewRoots.front());
- NewRoots.clear();
+ output = std::move(NewRoots.empty() ? input : NewRoots.front());
+ NewRoots.clear();
}
const TTypeAnnotationContext& Types;
diff --git a/ydb/library/yql/core/yql_opt_rewrite_io.cpp b/ydb/library/yql/core/yql_opt_rewrite_io.cpp
index 8707050201..ea96f34b68 100644
--- a/ydb/library/yql/core/yql_opt_rewrite_io.cpp
+++ b/ydb/library/yql/core/yql_opt_rewrite_io.cpp
@@ -3,31 +3,31 @@
namespace NYql {
-IGraphTransformer::TStatus RewriteIO(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TTypeAnnotationContext& types, TExprContext& ctx) {
+IGraphTransformer::TStatus RewriteIO(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TTypeAnnotationContext& types, TExprContext& ctx) {
if (ctx.Step.IsDone(TExprStep::RewriteIO)) {
return IGraphTransformer::TStatus::Ok;
}
TOptimizeExprSettings settings(nullptr);
settings.VisitChanges = true;
- auto ret = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
- YQL_ENSURE(node->Type() == TExprNode::Callable);
- if (node->Content() == LeftName || node->Content() == RightName) {
- auto child = node->Child(0);
+ auto ret = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ YQL_ENSURE(node->Type() == TExprNode::Callable);
+ if (node->Content() == LeftName || node->Content() == RightName) {
+ auto child = node->Child(0);
if (child->IsCallable(ReadName)) {
auto dataSourceName = child->Child(1)->Child(0)->Content();
auto datasource = types.DataSourceMap.FindPtr(dataSourceName);
YQL_ENSURE(datasource);
return (*datasource)->RewriteIO(node, ctx);
}
- } else if (node->IsCallable(WriteName)) {
- auto dataSinkName = node->Child(1)->Child(0)->Content();
+ } else if (node->IsCallable(WriteName)) {
+ auto dataSinkName = node->Child(1)->Child(0)->Content();
auto datasink = types.DataSinkMap.FindPtr(dataSinkName);
YQL_ENSURE(datasink);
return (*datasink)->RewriteIO(node, ctx);
}
- return node;
+ return node;
}, ctx, settings);
if (ret.Level == IGraphTransformer::TStatus::Error) {
@@ -38,11 +38,11 @@ IGraphTransformer::TStatus RewriteIO(const TExprNode::TPtr& input, TExprNode::TP
return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
}
- for (const auto& ds : types.DataSinks)
+ for (const auto& ds : types.DataSinks)
ds->PostRewriteIO();
- for (const auto& ds : types.DataSources)
+ for (const auto& ds : types.DataSources)
ds->PostRewriteIO();
-
+
ctx.Step.Done(TExprStep::RewriteIO);
return IGraphTransformer::TStatus::Ok;
}
diff --git a/ydb/library/yql/core/yql_opt_rewrite_io.h b/ydb/library/yql/core/yql_opt_rewrite_io.h
index f813886c8d..d5cbf3800b 100644
--- a/ydb/library/yql/core/yql_opt_rewrite_io.h
+++ b/ydb/library/yql/core/yql_opt_rewrite_io.h
@@ -7,6 +7,6 @@
namespace NYql {
-IGraphTransformer::TStatus RewriteIO(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TTypeAnnotationContext& types, TExprContext& ctx);
+IGraphTransformer::TStatus RewriteIO(const TExprNode::TPtr& input, TExprNode::TPtr& output, const TTypeAnnotationContext& types, TExprContext& ctx);
}
diff --git a/ydb/library/yql/core/yql_opt_utils.cpp b/ydb/library/yql/core/yql_opt_utils.cpp
index bb3b202a67..69aa84a500 100644
--- a/ydb/library/yql/core/yql_opt_utils.cpp
+++ b/ydb/library/yql/core/yql_opt_utils.cpp
@@ -14,13 +14,13 @@ namespace NYql {
using namespace NNodes;
-TExprNode::TPtr MakeBoolNothing(TPositionHandle position, TExprContext& ctx) {
- return ctx.NewCallable(position, "Nothing", {
- ctx.NewCallable(position, "OptionalType", {
- ctx.NewCallable(position, "DataType", {
- ctx.NewAtom(position, "Bool", TNodeFlags::Default) }) }) });
-}
-
+TExprNode::TPtr MakeBoolNothing(TPositionHandle position, TExprContext& ctx) {
+ return ctx.NewCallable(position, "Nothing", {
+ ctx.NewCallable(position, "OptionalType", {
+ ctx.NewCallable(position, "DataType", {
+ ctx.NewAtom(position, "Bool", TNodeFlags::Default) }) }) });
+}
+
TExprNode::TPtr MakeNull(TPositionHandle position, TExprContext& ctx) {
return ctx.NewCallable(position, "Null", {});
}
@@ -38,15 +38,15 @@ TExprNode::TPtr MakeConstMap(TPositionHandle position, const TExprNode::TPtr& in
.Build();
}
-template <bool Bool>
-TExprNode::TPtr MakeBool(TPositionHandle position, TExprContext& ctx) {
- return ctx.NewCallable(position, "Bool", { ctx.NewAtom(position, Bool ? "true" : "false", TNodeFlags::Default) });
-}
-
-TExprNode::TPtr MakeBool(TPositionHandle position, bool value, TExprContext& ctx) {
- return value ? MakeBool<true>(position, ctx) : MakeBool<false>(position, ctx);
-}
-
+template <bool Bool>
+TExprNode::TPtr MakeBool(TPositionHandle position, TExprContext& ctx) {
+ return ctx.NewCallable(position, "Bool", { ctx.NewAtom(position, Bool ? "true" : "false", TNodeFlags::Default) });
+}
+
+TExprNode::TPtr MakeBool(TPositionHandle position, bool value, TExprContext& ctx) {
+ return value ? MakeBool<true>(position, ctx) : MakeBool<false>(position, ctx);
+}
+
TExprNode::TPtr MakeOptionalBool(TPositionHandle position, bool value, TExprContext& ctx) {
return ctx.NewCallable(position, "Just", { MakeBool(position, value, ctx)});
}
@@ -61,16 +61,16 @@ TExprNode::TPtr MakeIdentityLambda(TPositionHandle position, TExprContext& ctx)
}
bool IsJustOrSingleAsList(const TExprNode& node) {
- return node.ChildrenSize() == 1U && node.IsCallable({"Just", "AsList"});
+ return node.ChildrenSize() == 1U && node.IsCallable({"Just", "AsList"});
+}
+
+bool IsTransparentIfPresent(const TExprNode& node) {
+ return (node.IsCallable("FlatMap") || (3U == node.ChildrenSize() && node.IsCallable("IfPresent") && node.Tail().IsCallable("Nothing")))
+ && node.Child(1U)->Tail().IsCallable("Just");
}
-bool IsTransparentIfPresent(const TExprNode& node) {
- return (node.IsCallable("FlatMap") || (3U == node.ChildrenSize() && node.IsCallable("IfPresent") && node.Tail().IsCallable("Nothing")))
- && node.Child(1U)->Tail().IsCallable("Just");
-}
-
bool IsPredicateFlatMap(const TExprNode& node) {
- return node.IsCallable({"FlatListIf", "ListIf", "OptionalIf", "FlatOptionalIf"});
+ return node.IsCallable({"FlatListIf", "ListIf", "OptionalIf", "FlatOptionalIf"});
}
bool IsFilterFlatMap(const NNodes::TCoLambda& lambda) {
@@ -86,7 +86,7 @@ bool IsFilterFlatMap(const NNodes::TCoLambda& lambda) {
}
bool IsListReorder(const TExprNode& node) {
- return node.IsCallable({"Sort", "Reverse"});
+ return node.IsCallable({"Sort", "Reverse"});
}
bool IsRenameFlatMap(const NNodes::TCoFlatMapBase& node, TExprNode::TPtr& structNode) {
@@ -205,8 +205,8 @@ TExprNode::TPtr KeepColumnOrder(const TExprNode::TPtr& node, const TExprNode& sr
.Build();
}
-template<class TFieldsSet>
-bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TFieldsSet& usedFields, const TParentsMap& parentsMap, bool allowDependsOn) {
+template<class TFieldsSet>
+bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TFieldsSet& usedFields, const TParentsMap& parentsMap, bool allowDependsOn) {
if (arg.GetTypeAnn()->GetKind() != ETypeAnnotationKind::Struct) {
return false;
}
@@ -215,7 +215,7 @@ bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TField
return false;
}
- const auto inputStructType = arg.GetTypeAnn()->Cast<TStructExprType>();
+ const auto inputStructType = arg.GetTypeAnn()->Cast<TStructExprType>();
if (!IsDepended(*start, arg)) {
return inputStructType->GetSize() > 0;
}
@@ -226,19 +226,19 @@ bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TField
return true;
});
- const auto parents = parentsMap.find(&arg);
+ const auto parents = parentsMap.find(&arg);
YQL_ENSURE(parents != parentsMap.cend());
- for (const auto& parent : parents->second) {
+ for (const auto& parent : parents->second) {
if (nodes.cend() == nodes.find(parent)) {
continue;
}
if (parent->IsCallable("Member")) {
- if constexpr (std::is_same_v<typename TFieldsSet::key_type, typename TFieldsSet::value_type>)
- usedFields.emplace(parent->Tail().Content());
- else
- usedFields.emplace(parent->Tail().Content(), parent->TailPtr());
- } else if (allowDependsOn && parent->IsCallable("DependsOn")) {
+ if constexpr (std::is_same_v<typename TFieldsSet::key_type, typename TFieldsSet::value_type>)
+ usedFields.emplace(parent->Tail().Content());
+ else
+ usedFields.emplace(parent->Tail().Content(), parent->TailPtr());
+ } else if (allowDependsOn && parent->IsCallable("DependsOn")) {
continue;
} else {
// unknown node
@@ -250,10 +250,10 @@ bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TField
return usedFields.size() < inputStructType->GetSize();
}
-template bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TSet<TStringBuf>& usedFields, const TParentsMap& parentsMap, bool allowDependsOn);
+template bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TSet<TStringBuf>& usedFields, const TParentsMap& parentsMap, bool allowDependsOn);
template bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TSet<TString>& usedFields, const TParentsMap& parentsMap, bool allowDependsOn);
-template bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, std::map<std::string_view, TExprNode::TPtr>& usedFields, const TParentsMap& parentsMap, bool allowDependsOn);
-
+template bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, std::map<std::string_view, TExprNode::TPtr>& usedFields, const TParentsMap& parentsMap, bool allowDependsOn);
+
template<class TFieldsSet>
TExprNode::TPtr FilterByFields(TPositionHandle position, const TExprNode::TPtr& input, const TFieldsSet& subsetFields,
TExprContext& ctx, bool singleValue) {
@@ -329,15 +329,15 @@ const TTypeAnnotationNode* RemoveAllOptionals(const TTypeAnnotationNode* type) {
return type;
}
-const TTypeAnnotationNode* GetSeqItemType(const TTypeAnnotationNode* type) {
- switch (type->GetKind()) {
- case ETypeAnnotationKind::List: return type->Cast<TListExprType>()->GetItemType();
- case ETypeAnnotationKind::Flow: return type->Cast<TFlowExprType>()->GetItemType();
- case ETypeAnnotationKind::Stream: return type->Cast<TStreamExprType>()->GetItemType();
- case ETypeAnnotationKind::Optional: return type->Cast<TOptionalExprType>()->GetItemType();
- default: break;
+const TTypeAnnotationNode* GetSeqItemType(const TTypeAnnotationNode* type) {
+ switch (type->GetKind()) {
+ case ETypeAnnotationKind::List: return type->Cast<TListExprType>()->GetItemType();
+ case ETypeAnnotationKind::Flow: return type->Cast<TFlowExprType>()->GetItemType();
+ case ETypeAnnotationKind::Stream: return type->Cast<TStreamExprType>()->GetItemType();
+ case ETypeAnnotationKind::Optional: return type->Cast<TOptionalExprType>()->GetItemType();
+ default: break;
}
-
+
THROW yexception() << "Impossible to get item type from " << *type;
}
@@ -512,7 +512,7 @@ TExprNode::TPtr MakeSingleGroupRow(const TExprNode& aggregateNode, TExprNode::TP
.Build();
}
-bool UpdateStructMembers(TExprContext& ctx, const TExprNode::TPtr& node, const TStringBuf& goal, TExprNode::TListType& members, MemberUpdaterFunc updaterFunc, const TTypeAnnotationNode* nodeType) {
+bool UpdateStructMembers(TExprContext& ctx, const TExprNode::TPtr& node, const TStringBuf& goal, TExprNode::TListType& members, MemberUpdaterFunc updaterFunc, const TTypeAnnotationNode* nodeType) {
if (!nodeType) {
nodeType = node->GetTypeAnn();
Y_VERIFY_DEBUG(nodeType || !"Unset node type for UpdateStructMembers");
@@ -1002,7 +1002,7 @@ void ExtractSimpleSortTraits(const TExprNode& sortDirections, const TExprNode& k
}
}
-const TExprNode& SkipCallables(const TExprNode& node, const std::initializer_list<std::string_view>& skipCallables) {
+const TExprNode& SkipCallables(const TExprNode& node, const std::initializer_list<std::string_view>& skipCallables) {
const TExprNode* p = &node;
while (p->IsCallable(skipCallables)) {
p = &p->Head();
@@ -1100,199 +1100,199 @@ TExprNode::TPtr BuildKeySelector(TPositionHandle pos, const TStructExprType& row
return ctx.NewLambda(pos, ctx.NewArguments(pos, {keyExtractorArg}), std::move(tuple));
}
-template <bool Cannonize, bool EnableNewOptimizers>
-TExprNode::TPtr OptimizeIfPresent(const TExprNode::TPtr& node, TExprContext& ctx) {
- auto optionals = node->ChildrenList();
- optionals.resize(optionals.size() - 2U);
- const auto& lambda = *node->Child(optionals.size());
- if (lambda.Tail().GetDependencyScope()->second != &lambda) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " where then branch isn't depended on optional";
- if (1U == optionals.size()) {
- return ctx.Builder(node->Pos())
- .Callable("If")
- .Callable(0, "Exists")
- .Add(0, std::move(optionals.front()))
- .Seal()
- .Add(1, lambda.TailPtr())
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
-
- std::for_each(optionals.begin(), optionals.end(), [&ctx](TExprNode::TPtr& node) {
- const auto p = node->Pos();
- node = ctx.NewCallable(p, "Exists", {std::move(node)});
- });
- return ctx.Builder(node->Pos())
- .Callable("If")
- .Callable(0, "And")
- .Add(std::move(optionals))
- .Seal()
- .Add(1, lambda.TailPtr())
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
-
- if (std::any_of(optionals.cbegin(), optionals.cend(), [](const TExprNode::TPtr& node) { return node->IsCallable("Nothing"); })) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing.";
- return node->TailPtr();
- }
-
- if (std::any_of(optionals.cbegin(), optionals.cend(), [](const TExprNode::TPtr& node) { return node->IsCallable("Just"); })) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over Just.";
- TExprNode::TListType args;
- args.reserve(optionals.size());
- std::for_each(optionals.begin(), optionals.end(), [&args](TExprNode::TPtr& arg) {
- if (arg->IsCallable("Just"))
- arg = arg->HeadPtr();
- else
- args.emplace_back(std::move(arg));
- });
-
- if (args.empty()) {
- TNodeOnNodeOwnedMap replaces(optionals.size());
- for (ui32 i = 0U; i < optionals.size(); ++i)
- replaces.emplace(lambda.Head().Child(i), std::move(optionals[i]));
- return ctx.ReplaceNodes(lambda.TailPtr(), replaces);
- }
-
- auto simplify = ctx.Builder(node->Pos())
- .Lambda()
- .Params("items", optionals.size() - args.size())
- .Apply(lambda)
- .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
- for (auto i = 0U, j = 0U; i < optionals.size(); ++i) {
- if (auto opt = std::move(optionals[i]))
- parent.With(i, std::move(opt));
- else
- parent.With(i, "items", j++);
- }
- return parent;
- })
- .Seal()
- .Seal().Build();
-
- args.emplace_back(std::move(simplify));
- args.emplace_back(node->TailPtr());
- return ctx.ChangeChildren(*node, std::move(args));
- }
-
- if (3U == node->ChildrenSize()) {
- if (&lambda.Tail() == &lambda.Head().Head()) {
- YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content() << " as Coalesce";
- return ctx.NewCallable(node->Pos(), "Coalesce", {node->HeadPtr(), node->TailPtr()});
- }
-
- if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
- return ctx.Builder(node->Pos())
- .Callable(node->Content())
- .Add(0, input.HeadPtr())
- .Lambda(1)
- .Param("item")
- .Apply(*node->Child(1))
- .With(0)
- .ApplyPartial(input.Child(1)->HeadPtr(), input.Child(1)->Tail().HeadPtr())
- .With(0, "item")
- .Seal()
- .Done()
- .Seal()
- .Seal()
- .Add(2, node->TailPtr())
- .Seal().Build();
- }
-
- if constexpr (Cannonize) {
- if (node->Tail().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " with else " << node->Tail().Content();
- return ctx.NewCallable(node->Pos(), "FlatMap", { node->HeadPtr(), node->ChildPtr(1) });
- }
- }
- }
-
- if constexpr (!Cannonize && EnableNewOptimizers) {
- if (lambda.Tail().IsCallable("IfPresent") && &node->Tail() == &lambda.Tail().Tail() && lambda.Tail().Head().GetDependencyScope()->second != &lambda) {
- auto innerOptionals = lambda.Tail().ChildrenList();
- innerOptionals.resize(innerOptionals.size() - 2U);
- const auto find = std::find_if(innerOptionals.cbegin(), innerOptionals.cend(), [l = &lambda] (const TExprNode::TPtr& child) {
- return child->GetDependencyScope()->second == l;
- });
- const auto count = std::distance(innerOptionals.cbegin(), find);
- YQL_CLOG(DEBUG, Core) << node->Content() << " pull " << count << " arg(s) from inner " << lambda.Tail().Content();
-
- auto& innerLambda = *lambda.Tail().Child(innerOptionals.size());
-
- auto args = lambda.Head().ChildrenList();
- auto innerArgs = innerLambda.Head().ChildrenList();
-
- const auto splitter = [count](TExprNode::TListType& src, TExprNode::TListType& dst) {
- dst.reserve(dst.size() + count);
- auto it = src.begin();
- std::advance(it, count);
- std::move(src.begin(), it, std::back_inserter(dst));
- src.erase(src.cbegin(), it);
- };
-
- splitter(innerArgs, args);
- splitter(innerOptionals, optionals);
-
- auto body = innerLambda.TailPtr();
- if (!(innerArgs.empty() || innerOptionals.empty())) {
- innerOptionals.emplace_back(ctx.DeepCopyLambda(*ctx.NewLambda(innerLambda.Pos(), ctx.NewArguments(innerLambda.Head().Pos(), std::move(innerArgs)), std::move(body))));
- innerOptionals.emplace_back(lambda.Tail().TailPtr());
- body = ctx.ChangeChildren(lambda.Tail(), std::move(innerOptionals));
- }
-
- optionals.emplace_back(ctx.DeepCopyLambda(*ctx.NewLambda(lambda.Pos(), ctx.NewArguments(lambda.Head().Pos(), std::move(args)), std::move(body))));
- optionals.emplace_back(node->TailPtr());
- return ctx.ChangeChildren(*node, std::move(optionals));
- }
- }
-
- return node;
+template <bool Cannonize, bool EnableNewOptimizers>
+TExprNode::TPtr OptimizeIfPresent(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto optionals = node->ChildrenList();
+ optionals.resize(optionals.size() - 2U);
+ const auto& lambda = *node->Child(optionals.size());
+ if (lambda.Tail().GetDependencyScope()->second != &lambda) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " where then branch isn't depended on optional";
+ if (1U == optionals.size()) {
+ return ctx.Builder(node->Pos())
+ .Callable("If")
+ .Callable(0, "Exists")
+ .Add(0, std::move(optionals.front()))
+ .Seal()
+ .Add(1, lambda.TailPtr())
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+
+ std::for_each(optionals.begin(), optionals.end(), [&ctx](TExprNode::TPtr& node) {
+ const auto p = node->Pos();
+ node = ctx.NewCallable(p, "Exists", {std::move(node)});
+ });
+ return ctx.Builder(node->Pos())
+ .Callable("If")
+ .Callable(0, "And")
+ .Add(std::move(optionals))
+ .Seal()
+ .Add(1, lambda.TailPtr())
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+
+ if (std::any_of(optionals.cbegin(), optionals.cend(), [](const TExprNode::TPtr& node) { return node->IsCallable("Nothing"); })) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Nothing.";
+ return node->TailPtr();
+ }
+
+ if (std::any_of(optionals.cbegin(), optionals.cend(), [](const TExprNode::TPtr& node) { return node->IsCallable("Just"); })) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over Just.";
+ TExprNode::TListType args;
+ args.reserve(optionals.size());
+ std::for_each(optionals.begin(), optionals.end(), [&args](TExprNode::TPtr& arg) {
+ if (arg->IsCallable("Just"))
+ arg = arg->HeadPtr();
+ else
+ args.emplace_back(std::move(arg));
+ });
+
+ if (args.empty()) {
+ TNodeOnNodeOwnedMap replaces(optionals.size());
+ for (ui32 i = 0U; i < optionals.size(); ++i)
+ replaces.emplace(lambda.Head().Child(i), std::move(optionals[i]));
+ return ctx.ReplaceNodes(lambda.TailPtr(), replaces);
+ }
+
+ auto simplify = ctx.Builder(node->Pos())
+ .Lambda()
+ .Params("items", optionals.size() - args.size())
+ .Apply(lambda)
+ .Do([&](TExprNodeReplaceBuilder& parent) -> TExprNodeReplaceBuilder& {
+ for (auto i = 0U, j = 0U; i < optionals.size(); ++i) {
+ if (auto opt = std::move(optionals[i]))
+ parent.With(i, std::move(opt));
+ else
+ parent.With(i, "items", j++);
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal().Build();
+
+ args.emplace_back(std::move(simplify));
+ args.emplace_back(node->TailPtr());
+ return ctx.ChangeChildren(*node, std::move(args));
+ }
+
+ if (3U == node->ChildrenSize()) {
+ if (&lambda.Tail() == &lambda.Head().Head()) {
+ YQL_CLOG(DEBUG, Core) << "Simplify " << node->Content() << " as Coalesce";
+ return ctx.NewCallable(node->Pos(), "Coalesce", {node->HeadPtr(), node->TailPtr()});
+ }
+
+ if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
+ return ctx.Builder(node->Pos())
+ .Callable(node->Content())
+ .Add(0, input.HeadPtr())
+ .Lambda(1)
+ .Param("item")
+ .Apply(*node->Child(1))
+ .With(0)
+ .ApplyPartial(input.Child(1)->HeadPtr(), input.Child(1)->Tail().HeadPtr())
+ .With(0, "item")
+ .Seal()
+ .Done()
+ .Seal()
+ .Seal()
+ .Add(2, node->TailPtr())
+ .Seal().Build();
+ }
+
+ if constexpr (Cannonize) {
+ if (node->Tail().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " with else " << node->Tail().Content();
+ return ctx.NewCallable(node->Pos(), "FlatMap", { node->HeadPtr(), node->ChildPtr(1) });
+ }
+ }
+ }
+
+ if constexpr (!Cannonize && EnableNewOptimizers) {
+ if (lambda.Tail().IsCallable("IfPresent") && &node->Tail() == &lambda.Tail().Tail() && lambda.Tail().Head().GetDependencyScope()->second != &lambda) {
+ auto innerOptionals = lambda.Tail().ChildrenList();
+ innerOptionals.resize(innerOptionals.size() - 2U);
+ const auto find = std::find_if(innerOptionals.cbegin(), innerOptionals.cend(), [l = &lambda] (const TExprNode::TPtr& child) {
+ return child->GetDependencyScope()->second == l;
+ });
+ const auto count = std::distance(innerOptionals.cbegin(), find);
+ YQL_CLOG(DEBUG, Core) << node->Content() << " pull " << count << " arg(s) from inner " << lambda.Tail().Content();
+
+ auto& innerLambda = *lambda.Tail().Child(innerOptionals.size());
+
+ auto args = lambda.Head().ChildrenList();
+ auto innerArgs = innerLambda.Head().ChildrenList();
+
+ const auto splitter = [count](TExprNode::TListType& src, TExprNode::TListType& dst) {
+ dst.reserve(dst.size() + count);
+ auto it = src.begin();
+ std::advance(it, count);
+ std::move(src.begin(), it, std::back_inserter(dst));
+ src.erase(src.cbegin(), it);
+ };
+
+ splitter(innerArgs, args);
+ splitter(innerOptionals, optionals);
+
+ auto body = innerLambda.TailPtr();
+ if (!(innerArgs.empty() || innerOptionals.empty())) {
+ innerOptionals.emplace_back(ctx.DeepCopyLambda(*ctx.NewLambda(innerLambda.Pos(), ctx.NewArguments(innerLambda.Head().Pos(), std::move(innerArgs)), std::move(body))));
+ innerOptionals.emplace_back(lambda.Tail().TailPtr());
+ body = ctx.ChangeChildren(lambda.Tail(), std::move(innerOptionals));
+ }
+
+ optionals.emplace_back(ctx.DeepCopyLambda(*ctx.NewLambda(lambda.Pos(), ctx.NewArguments(lambda.Head().Pos(), std::move(args)), std::move(body))));
+ optionals.emplace_back(node->TailPtr());
+ return ctx.ChangeChildren(*node, std::move(optionals));
+ }
+ }
+
+ return node;
}
-
-template TExprNode::TPtr OptimizeIfPresent<true, true>(const TExprNode::TPtr& node, TExprContext& ctx);
-template TExprNode::TPtr OptimizeIfPresent<false, true>(const TExprNode::TPtr& node, TExprContext& ctx);
-template TExprNode::TPtr OptimizeIfPresent<false, false>(const TExprNode::TPtr& node, TExprContext& ctx);
-
-TExprNode::TPtr OptimizeExists(const TExprNode::TPtr& node, TExprContext& ctx) {
- if (HasError(node->Head().GetTypeAnn(), ctx)) {
- return TExprNode::TPtr();
- }
-
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Void) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return MakeBool<false>(node->Pos(), ctx);
- }
-
- if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Null) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return MakeBool<false>(node->Pos(), ctx);
- }
-
- if (node->Head().IsCallable("Just")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return MakeBool<true>(node->Pos(), ctx);
- }
-
- if (node->Head().IsCallable("Nothing")) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return MakeBool<false>(node->Pos(), ctx);
- }
-
- if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over non-optional";
- return MakeBool<true>(node->Pos(), ctx);
- }
-
- if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
- return ctx.ChangeChildren(*node, {input.HeadPtr()});
- }
-
- return node;
+
+template TExprNode::TPtr OptimizeIfPresent<true, true>(const TExprNode::TPtr& node, TExprContext& ctx);
+template TExprNode::TPtr OptimizeIfPresent<false, true>(const TExprNode::TPtr& node, TExprContext& ctx);
+template TExprNode::TPtr OptimizeIfPresent<false, false>(const TExprNode::TPtr& node, TExprContext& ctx);
+
+TExprNode::TPtr OptimizeExists(const TExprNode::TPtr& node, TExprContext& ctx) {
+ if (HasError(node->Head().GetTypeAnn(), ctx)) {
+ return TExprNode::TPtr();
+ }
+
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Void) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return MakeBool<false>(node->Pos(), ctx);
+ }
+
+ if (node->Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Null) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return MakeBool<false>(node->Pos(), ctx);
+ }
+
+ if (node->Head().IsCallable("Just")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return MakeBool<true>(node->Pos(), ctx);
+ }
+
+ if (node->Head().IsCallable("Nothing")) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return MakeBool<false>(node->Pos(), ctx);
+ }
+
+ if (node->Head().GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over non-optional";
+ return MakeBool<true>(node->Pos(), ctx);
+ }
+
+ if (const auto& input = node->Head(); IsTransparentIfPresent(input)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over transparent " << input.Content();
+ return ctx.ChangeChildren(*node, {input.HeadPtr()});
+ }
+
+ return node;
}
-
+
bool WarnUnroderedSubquery(const TExprNode& unourderedSubquery, TExprContext& ctx) {
YQL_ENSURE(unourderedSubquery.IsCallable("UnorderedSubquery"));
@@ -1304,7 +1304,7 @@ bool WarnUnroderedSubquery(const TExprNode& unourderedSubquery, TExprContext& ct
issue.AddSubIssue(MakeIntrusive<TIssue>(subIssue));
return ctx.AddWarning(issue);
-}
+}
TExprNode::TPtr DuplicateIndependentStreams(TExprNode::TPtr lambda, const std::function<bool(const TExprNode*)>& stopTraverse, TExprContext& ctx) {
TNodeOnNodeOwnedMap replaces;
diff --git a/ydb/library/yql/core/yql_opt_utils.h b/ydb/library/yql/core/yql_opt_utils.h
index f0f054b73f..00635fea81 100644
--- a/ydb/library/yql/core/yql_opt_utils.h
+++ b/ydb/library/yql/core/yql_opt_utils.h
@@ -13,7 +13,7 @@ namespace NYql {
struct TTypeAnnotationContext;
bool IsJustOrSingleAsList(const TExprNode& node);
-bool IsTransparentIfPresent(const TExprNode& node);
+bool IsTransparentIfPresent(const TExprNode& node);
bool IsPredicateFlatMap(const TExprNode& node);
bool IsFilterFlatMap(const NNodes::TCoLambda& lambda);
bool IsListReorder(const TExprNode& node);
@@ -25,9 +25,9 @@ bool IsTablePropsDependent(const TExprNode& node);
TExprNode::TPtr KeepColumnOrder(const TExprNode::TPtr& node, const TExprNode& src, TExprContext& ctx, const TTypeAnnotationContext& typeCtx);
// returns true if usedFields contains subset of fields
-template<class TFieldsSet>
-bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TFieldsSet& usedFields, const TParentsMap& parentsMap, bool allowDependsOn = true);
-
+template<class TFieldsSet>
+bool HaveFieldsSubset(const TExprNode::TPtr& start, const TExprNode& arg, TFieldsSet& usedFields, const TParentsMap& parentsMap, bool allowDependsOn = true);
+
template<class TFieldsSet>
TExprNode::TPtr FilterByFields(TPositionHandle position, const TExprNode::TPtr& input, const TFieldsSet& subsetFields,
TExprContext& ctx, bool singleValue);
@@ -51,10 +51,10 @@ TExprNode::TPtr ReplaceSetting(const TExprNode& settings, TPositionHandle pos, c
TMaybe<TIssue> ParseToDictSettings(const TExprNode& node, TExprContext& ctx, TMaybe<bool>& isMany, TMaybe<bool>& isHashed, TMaybe<ui64>& itemsCount, bool& isCompact);
-using MemberUpdaterFunc = std::function<bool (TString& memberName, const TTypeAnnotationNode* TypeAnnotation)>;
-bool UpdateStructMembers(TExprContext& ctx, const TExprNode::TPtr& node, const TStringBuf& goal, TExprNode::TListType& members,
- MemberUpdaterFunc updaterFunc = MemberUpdaterFunc(), const TTypeAnnotationNode* nodeType = nullptr);
-
+using MemberUpdaterFunc = std::function<bool (TString& memberName, const TTypeAnnotationNode* TypeAnnotation)>;
+bool UpdateStructMembers(TExprContext& ctx, const TExprNode::TPtr& node, const TStringBuf& goal, TExprNode::TListType& members,
+ MemberUpdaterFunc updaterFunc = MemberUpdaterFunc(), const TTypeAnnotationNode* nodeType = nullptr);
+
TExprNode::TPtr MakeSingleGroupRow(const TExprNode& aggregateNode, TExprNode::TPtr reduced, TExprContext& ctx);
TExprNode::TPtr ExpandRemoveMember(const TExprNode::TPtr& node, TExprContext& ctx);
TExprNode::TPtr ExpandRemovePrefixMembers(const TExprNode::TPtr& node, TExprContext& ctx);
@@ -74,27 +74,27 @@ void ExtractSimpleSortTraits(const TExprNode& sortDirections, const TExprNode& k
TExprNode::TPtr MakeNull(TPositionHandle position, TExprContext& ctx);
TExprNode::TPtr MakeConstMap(TPositionHandle position, const TExprNode::TPtr& input, const TExprNode::TPtr& value, TExprContext& ctx);
-TExprNode::TPtr MakeBoolNothing(TPositionHandle position, TExprContext& ctx);
-TExprNode::TPtr MakeBool(TPositionHandle position, bool value, TExprContext& ctx);
+TExprNode::TPtr MakeBoolNothing(TPositionHandle position, TExprContext& ctx);
+TExprNode::TPtr MakeBool(TPositionHandle position, bool value, TExprContext& ctx);
TExprNode::TPtr MakeOptionalBool(TPositionHandle position, bool value, TExprContext& ctx);
-template <bool Bool>
-TExprNode::TPtr MakeBool(TPositionHandle position, TExprContext& ctx);
+template <bool Bool>
+TExprNode::TPtr MakeBool(TPositionHandle position, TExprContext& ctx);
TExprNode::TPtr MakeIdentityLambda(TPositionHandle position, TExprContext& ctx);
-
+
constexpr std::initializer_list<std::string_view> SkippableCallables = {"Unordered", "AssumeSorted", "AssumeUnique", "AssumeColumnOrder", "AssumeAllMembersNullableAtOnce"};
-const TExprNode& SkipCallables(const TExprNode& node, const std::initializer_list<std::string_view>& skipCallables);
-
+const TExprNode& SkipCallables(const TExprNode& node, const std::initializer_list<std::string_view>& skipCallables);
+
void ExtractSortKeyAndOrder(TPositionHandle pos, const TExprNode::TPtr& sortTraitsNode, TExprNode::TPtr& sortKey, TExprNode::TPtr& sortOrder, TExprContext& ctx);
void ExtractSessionWindowParams(TPositionHandle pos, const TExprNode::TPtr& sessionTraits, TExprNode::TPtr& sessionKey,
const TTypeAnnotationNode*& sessionKeyType, const TTypeAnnotationNode*& sessionParamsType, TExprNode::TPtr& sessionSortTraits, TExprNode::TPtr& sessionInit,
TExprNode::TPtr& sessionUpdate, TExprContext& ctx);
TExprNode::TPtr BuildKeySelector(TPositionHandle pos, const TStructExprType& rowType, const TExprNode::TPtr& keyColumns, TExprContext& ctx);
-
-template <bool Cannonize, bool EnableNewOptimizers = true>
-TExprNode::TPtr OptimizeIfPresent(const TExprNode::TPtr& node, TExprContext& ctx);
-TExprNode::TPtr OptimizeExists(const TExprNode::TPtr& node, TExprContext& ctx);
+
+template <bool Cannonize, bool EnableNewOptimizers = true>
+TExprNode::TPtr OptimizeIfPresent(const TExprNode::TPtr& node, TExprContext& ctx);
+TExprNode::TPtr OptimizeExists(const TExprNode::TPtr& node, TExprContext& ctx);
bool WarnUnroderedSubquery(const TExprNode& unourderedSubquery, TExprContext& ctx);
TExprNode::TPtr DuplicateIndependentStreams(TExprNode::TPtr lambda, const std::function<bool(const TExprNode*)>& stopTraverse, TExprContext& ctx);
diff --git a/ydb/library/yql/core/yql_opt_window.cpp b/ydb/library/yql/core/yql_opt_window.cpp
index 2dfe56fe93..5fc03d35d9 100644
--- a/ydb/library/yql/core/yql_opt_window.cpp
+++ b/ydb/library/yql/core/yql_opt_window.cpp
@@ -357,18 +357,18 @@ TExprNode::TPtr CoalesceQueueOutput(TPositionHandle pos, const TExprNode::TPtr&
.Build();
}
- if (defaultValue->IsCallable("EmptyList")) {
- return ctx.Builder(pos)
- .Callable("FlatMap")
- .Add(0, output)
- .Lambda(1)
- .Param("item")
- .Arg("item")
- .Seal()
- .Seal()
- .Build();
- }
-
+ if (defaultValue->IsCallable("EmptyList")) {
+ return ctx.Builder(pos)
+ .Callable("FlatMap")
+ .Add(0, output)
+ .Lambda(1)
+ .Param("item")
+ .Arg("item")
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
return ctx.Builder(pos)
.Callable("Coalesce")
.Add(0, output)
@@ -377,7 +377,7 @@ TExprNode::TPtr CoalesceQueueOutput(TPositionHandle pos, const TExprNode::TPtr&
.Build();
}
-TExprNode::TPtr BuildInitLambdaForChain1Map(TPositionHandle pos, const TExprNode::TPtr& initStateLambda,
+TExprNode::TPtr BuildInitLambdaForChain1Map(TPositionHandle pos, const TExprNode::TPtr& initStateLambda,
const TExprNode::TPtr& calculateLambda, TExprContext& ctx)
{
return ctx.Builder(pos)
@@ -399,7 +399,7 @@ TExprNode::TPtr BuildInitLambdaForChain1Map(TPositionHandle pos, const TExprNode
.Build();
}
-TExprNode::TPtr BuildUpdateLambdaForChain1Map(TPositionHandle pos, const TExprNode::TPtr& updateStateLambda,
+TExprNode::TPtr BuildUpdateLambdaForChain1Map(TPositionHandle pos, const TExprNode::TPtr& updateStateLambda,
const TExprNode::TPtr& calculateLambda, TExprContext& ctx)
{
return ctx.Builder(pos)
@@ -426,11 +426,11 @@ TExprNode::TPtr BuildUpdateLambdaForChain1Map(TPositionHandle pos, const TExprNo
-class TChain1MapTraits : public TThrRefBase, public TNonCopyable {
+class TChain1MapTraits : public TThrRefBase, public TNonCopyable {
public:
- using TPtr = TIntrusivePtr<TChain1MapTraits>;
+ using TPtr = TIntrusivePtr<TChain1MapTraits>;
- TChain1MapTraits(TStringBuf name, TPositionHandle pos)
+ TChain1MapTraits(TStringBuf name, TPositionHandle pos)
: Name(name)
, Pos(pos)
{
@@ -459,16 +459,16 @@ public:
return {};
}
- virtual ~TChain1MapTraits() = default;
+ virtual ~TChain1MapTraits() = default;
private:
const TStringBuf Name;
const TPositionHandle Pos;
};
-class TChain1MapTraitsLagLead : public TChain1MapTraits {
+class TChain1MapTraitsLagLead : public TChain1MapTraits {
public:
- TChain1MapTraitsLagLead(TStringBuf name, const TRawTrait& raw, TMaybe<ui64> queueOffset)
- : TChain1MapTraits(name, raw.Pos)
+ TChain1MapTraitsLagLead(TStringBuf name, const TRawTrait& raw, TMaybe<ui64> queueOffset)
+ : TChain1MapTraits(name, raw.Pos)
, QueueOffset(queueOffset)
, LeadLagLambda(raw.CalculateLambda)
{
@@ -531,10 +531,10 @@ private:
};
-class TChain1MapTraitsRowNumber : public TChain1MapTraits {
+class TChain1MapTraitsRowNumber : public TChain1MapTraits {
public:
- TChain1MapTraitsRowNumber(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraits(name, raw.Pos)
+ TChain1MapTraitsRowNumber(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraits(name, raw.Pos)
{
}
@@ -572,10 +572,10 @@ public:
}
};
-class TChain1MapTraitsRankBase : public TChain1MapTraits {
+class TChain1MapTraitsRankBase : public TChain1MapTraits {
public:
- TChain1MapTraitsRankBase(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraits(name, raw.Pos)
+ TChain1MapTraitsRankBase(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraits(name, raw.Pos)
, ExtractForCompareLambda(raw.CalculateLambda->ChildPtr(1))
, Ansi(HasSetting(*raw.CalculateLambda->Child(2), "ansi"))
, KeyType(raw.OutputType)
@@ -618,7 +618,7 @@ public:
.Seal()
.Build();
- return BuildInitLambdaForChain1Map(GetPos(), initRowLambda, BuildCalculateLambda(ctx), ctx);
+ return BuildInitLambdaForChain1Map(GetPos(), initRowLambda, BuildCalculateLambda(ctx), ctx);
}
// Lambda(row, state) -> AsTuple(output, state)
@@ -677,7 +677,7 @@ public:
.Seal()
.Build();
- return BuildUpdateLambdaForChain1Map(GetPos(), updateRowLambda, BuildCalculateLambda(ctx), ctx);
+ return BuildUpdateLambdaForChain1Map(GetPos(), updateRowLambda, BuildCalculateLambda(ctx), ctx);
}
virtual TExprNode::TPtr BuildRawInitLambda(TExprContext& ctx) const = 0;
@@ -715,10 +715,10 @@ private:
const TTypeAnnotationNode* const KeyType;
};
-class TChain1MapTraitsRank : public TChain1MapTraitsRankBase {
+class TChain1MapTraitsRank : public TChain1MapTraitsRankBase {
public:
- TChain1MapTraitsRank(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraitsRankBase(name, raw)
+ TChain1MapTraitsRank(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraitsRankBase(name, raw)
{
}
@@ -782,10 +782,10 @@ public:
}
};
-class TChain1MapTraitsDenseRank : public TChain1MapTraitsRankBase {
+class TChain1MapTraitsDenseRank : public TChain1MapTraitsRankBase {
public:
- TChain1MapTraitsDenseRank(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraitsRankBase(name, raw)
+ TChain1MapTraitsDenseRank(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraitsRankBase(name, raw)
{
}
@@ -840,10 +840,10 @@ public:
}
};
-class TChain1MapTraitsStateBase : public TChain1MapTraits {
+class TChain1MapTraitsStateBase : public TChain1MapTraits {
public:
- TChain1MapTraitsStateBase(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraits(name, raw.Pos)
+ TChain1MapTraitsStateBase(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraits(name, raw.Pos)
, InitLambda(raw.InitLambda)
, UpdateLambda(raw.UpdateLambda)
, CalculateLambda(raw.CalculateLambda)
@@ -876,10 +876,10 @@ private:
};
-class TChain1MapTraitsCurrentOrLagging : public TChain1MapTraitsStateBase {
+class TChain1MapTraitsCurrentOrLagging : public TChain1MapTraitsStateBase {
public:
- TChain1MapTraitsCurrentOrLagging(TStringBuf name, const TRawTrait& raw, TMaybe<ui64> lagQueueIndex)
- : TChain1MapTraitsStateBase(name, raw)
+ TChain1MapTraitsCurrentOrLagging(TStringBuf name, const TRawTrait& raw, TMaybe<ui64> lagQueueIndex)
+ : TChain1MapTraitsStateBase(name, raw)
, LaggingQueueIndex(lagQueueIndex)
, OutputIsOptional(raw.OutputType->GetKind() == ETypeAnnotationKind::Optional)
{
@@ -888,13 +888,13 @@ public:
// Lambda(row) -> AsTuple(output, state)
TExprNode::TPtr BuildInitLambda(const TExprNode::TPtr& dataQueue, TExprContext& ctx) const override {
Y_UNUSED(dataQueue);
- return BuildInitLambdaForChain1Map(GetPos(), GetInitLambda(), GetCalculateLambda(), ctx);
+ return BuildInitLambdaForChain1Map(GetPos(), GetInitLambda(), GetCalculateLambda(), ctx);
}
// Lambda(row, state) -> AsTuple(output, state)
TExprNode::TPtr BuildUpdateLambda(const TExprNode::TPtr& dataQueue, TExprContext& ctx) const override {
Y_UNUSED(dataQueue);
- return BuildUpdateLambdaForChain1Map(GetPos(), GetUpdateLambda(), GetCalculateLambda(), ctx);
+ return BuildUpdateLambdaForChain1Map(GetPos(), GetUpdateLambda(), GetCalculateLambda(), ctx);
}
TExprNode::TPtr ExtractLaggingOutput(const TExprNode::TPtr& lagQueue,
@@ -924,10 +924,10 @@ private:
const bool OutputIsOptional;
};
-class TChain1MapTraitsLeading : public TChain1MapTraitsStateBase {
+class TChain1MapTraitsLeading : public TChain1MapTraitsStateBase {
public:
- TChain1MapTraitsLeading(TStringBuf name, const TRawTrait& raw, ui64 currentRowIndex, ui64 lastRowIndex)
- : TChain1MapTraitsStateBase(name, raw)
+ TChain1MapTraitsLeading(TStringBuf name, const TRawTrait& raw, ui64 currentRowIndex, ui64 lastRowIndex)
+ : TChain1MapTraitsStateBase(name, raw)
, QueueBegin(currentRowIndex + 1)
, QueueEnd(lastRowIndex + 1)
{
@@ -1007,10 +1007,10 @@ private:
};
-class TChain1MapTraitsFull : public TChain1MapTraitsStateBase {
+class TChain1MapTraitsFull : public TChain1MapTraitsStateBase {
public:
- TChain1MapTraitsFull(TStringBuf name, const TRawTrait& raw, ui64 currentRowIndex)
- : TChain1MapTraitsStateBase(name, raw)
+ TChain1MapTraitsFull(TStringBuf name, const TRawTrait& raw, ui64 currentRowIndex)
+ : TChain1MapTraitsStateBase(name, raw)
, QueueBegin(currentRowIndex + 1)
{
}
@@ -1067,10 +1067,10 @@ private:
};
-class TChain1MapTraitsGeneric : public TChain1MapTraitsStateBase {
+class TChain1MapTraitsGeneric : public TChain1MapTraitsStateBase {
public:
- TChain1MapTraitsGeneric(TStringBuf name, const TRawTrait& raw, ui64 queueBegin, ui64 queueEnd)
- : TChain1MapTraitsStateBase(name, raw)
+ TChain1MapTraitsGeneric(TStringBuf name, const TRawTrait& raw, ui64 queueBegin, ui64 queueEnd)
+ : TChain1MapTraitsStateBase(name, raw)
, QueueBegin(queueBegin)
, QueueEnd(queueEnd)
, FrameNeverEmpty(raw.FrameSettings.NeverEmpty)
@@ -1153,10 +1153,10 @@ private:
const bool OutputIsOptional;
};
-class TChain1MapTraitsEmpty : public TChain1MapTraitsStateBase {
+class TChain1MapTraitsEmpty : public TChain1MapTraitsStateBase {
public:
- TChain1MapTraitsEmpty(TStringBuf name, const TRawTrait& raw)
- : TChain1MapTraitsStateBase(name, raw)
+ TChain1MapTraitsEmpty(TStringBuf name, const TRawTrait& raw)
+ : TChain1MapTraitsStateBase(name, raw)
, RawOutputType(raw.OutputType)
{
}
@@ -1193,7 +1193,7 @@ public:
private:
TExprNode::TPtr BuildFinalOutput(TExprContext& ctx) const {
- const auto defaultValue = GetDefaultValue();
+ const auto defaultValue = GetDefaultValue();
if (defaultValue->IsCallable("Null")) {
auto resultingType = RawOutputType;
@@ -1207,31 +1207,31 @@ private:
.Seal()
.Build();
}
- if (defaultValue->IsCallable("EmptyList")) {
- auto resultingType = RawOutputType;
- if (resultingType->GetKind() != ETypeAnnotationKind::List) {
- resultingType = ctx.MakeType<TListExprType>(resultingType);
- }
-
- return ctx.Builder(GetPos())
- .Callable("List")
- .Add(0, ExpandType(GetPos(), *resultingType, ctx))
- .Seal()
- .Build();
- }
+ if (defaultValue->IsCallable("EmptyList")) {
+ auto resultingType = RawOutputType;
+ if (resultingType->GetKind() != ETypeAnnotationKind::List) {
+ resultingType = ctx.MakeType<TListExprType>(resultingType);
+ }
+
+ return ctx.Builder(GetPos())
+ .Callable("List")
+ .Add(0, ExpandType(GetPos(), *resultingType, ctx))
+ .Seal()
+ .Build();
+ }
return defaultValue;
}
const TTypeAnnotationNode* const RawOutputType;
};
-TVector<TChain1MapTraits::TPtr> BuildFoldMapTraits(ui64& dataOutpace, ui64& dataLag, ui64& lagQueueSize,
+TVector<TChain1MapTraits::TPtr> BuildFoldMapTraits(ui64& dataOutpace, ui64& dataLag, ui64& lagQueueSize,
const TTypeAnnotationNode*& lagQueueItemType, const TExprNode::TPtr& frames, TExprContext& ctx)
{
dataOutpace = dataLag = lagQueueSize = 0;
lagQueueItemType = nullptr;
- TVector<TChain1MapTraits::TPtr> result;
+ TVector<TChain1MapTraits::TPtr> result;
TCalcOverWindowTraits traits = ExtractCalcOverWindowTraits(frames, ctx);
@@ -1262,14 +1262,14 @@ TVector<TChain1MapTraits::TPtr> BuildFoldMapTraits(ui64& dataOutpace, ui64& data
queueOffset = currentRowIndex + *trait.CalculateLambdaLead;
}
- result.push_back(new TChain1MapTraitsLagLead(name, trait, queueOffset));
+ result.push_back(new TChain1MapTraitsLagLead(name, trait, queueOffset));
} else if (trait.CalculateLambda->IsCallable("RowNumber")) {
- result.push_back(new TChain1MapTraitsRowNumber(name, trait));
+ result.push_back(new TChain1MapTraitsRowNumber(name, trait));
} else if (trait.CalculateLambda->IsCallable("Rank")) {
- result.push_back(new TChain1MapTraitsRank(name, trait));
+ result.push_back(new TChain1MapTraitsRank(name, trait));
} else {
YQL_ENSURE(trait.CalculateLambda->IsCallable("DenseRank"));
- result.push_back(new TChain1MapTraitsDenseRank(name, trait));
+ result.push_back(new TChain1MapTraitsDenseRank(name, trait));
}
continue;
@@ -1286,18 +1286,18 @@ TVector<TChain1MapTraits::TPtr> BuildFoldMapTraits(ui64& dataOutpace, ui64& data
lagQueueIndex = lagQueueSize + end;
}
- result.push_back(new TChain1MapTraitsCurrentOrLagging(name, trait, lagQueueIndex));
+ result.push_back(new TChain1MapTraitsCurrentOrLagging(name, trait, lagQueueIndex));
break;
}
case EFrameType::LEADING: {
auto end = *trait.FrameSettings.Last;
YQL_ENSURE(end > 0);
ui64 lastRowIndex = currentRowIndex + ui64(end);
- result.push_back(new TChain1MapTraitsLeading(name, trait, currentRowIndex, lastRowIndex));
+ result.push_back(new TChain1MapTraitsLeading(name, trait, currentRowIndex, lastRowIndex));
break;
}
case EFrameType::FULL: {
- result.push_back(new TChain1MapTraitsFull(name, trait, currentRowIndex));
+ result.push_back(new TChain1MapTraitsFull(name, trait, currentRowIndex));
break;
}
case EFrameType::GENERIC: {
@@ -1306,11 +1306,11 @@ TVector<TChain1MapTraits::TPtr> BuildFoldMapTraits(ui64& dataOutpace, ui64& data
YQL_ENSURE(first.Defined());
ui64 beginIndex = currentRowIndex + *first;
ui64 endIndex = last.Defined() ? (currentRowIndex + *last + 1) : Max<ui64>();
- result.push_back(new TChain1MapTraitsGeneric(name, trait, beginIndex, endIndex));
+ result.push_back(new TChain1MapTraitsGeneric(name, trait, beginIndex, endIndex));
break;
}
case EFrameType::EMPTY: {
- result.push_back(new TChain1MapTraitsEmpty(name, trait));
+ result.push_back(new TChain1MapTraitsEmpty(name, trait));
break;
}
}
@@ -1392,7 +1392,7 @@ TExprNode::TPtr SelectMembers(TPositionHandle pos, const T& members, const TExpr
}
TExprNode::TPtr HandleLaggingItems(TPositionHandle pos, const TExprNode::TPtr& rowArg,
- const TExprNode::TPtr& tupleOfOutputAndState, const TVector<TChain1MapTraits::TPtr>& traits,
+ const TExprNode::TPtr& tupleOfOutputAndState, const TVector<TChain1MapTraits::TPtr>& traits,
const TExprNode::TPtr& lagQueue, TExprContext& ctx)
{
@@ -1466,7 +1466,7 @@ TExprNode::TPtr HandleLaggingItems(TPositionHandle pos, const TExprNode::TPtr& r
}
-TExprNode::TPtr BuildChain1MapInitLambda(TPositionHandle pos, const TVector<TChain1MapTraits::TPtr>& traits,
+TExprNode::TPtr BuildChain1MapInitLambda(TPositionHandle pos, const TVector<TChain1MapTraits::TPtr>& traits,
const TExprNode::TPtr& dataQueue, ui64 lagQueueSize, const TTypeAnnotationNode* lagQueueItemType, TExprContext& ctx)
{
auto rowArg = ctx.NewArgument(pos, "row");
@@ -1500,30 +1500,30 @@ TExprNode::TPtr BuildChain1MapInitLambda(TPositionHandle pos, const TVector<TCha
return ctx.NewLambda(pos, ctx.NewArguments(pos, {rowArg}), std::move(finalBody));
}
-TExprNode::TPtr BuildChain1MapUpdateLambda(TPositionHandle pos, const TVector<TChain1MapTraits::TPtr>& traits,
+TExprNode::TPtr BuildChain1MapUpdateLambda(TPositionHandle pos, const TVector<TChain1MapTraits::TPtr>& traits,
const TExprNode::TPtr& dataQueue, bool haveLagQueue, TExprContext& ctx)
{
- const auto rowArg = ctx.NewArgument(pos, "row");
- const auto stateArg = ctx.NewArgument(pos, "state");
- auto state = ctx.Builder(pos)
- .Callable("Nth")
- .Add(0, stateArg)
- .Atom(1, "1", TNodeFlags::Default)
- .Seal()
- .Build();
+ const auto rowArg = ctx.NewArgument(pos, "row");
+ const auto stateArg = ctx.NewArgument(pos, "state");
+ auto state = ctx.Builder(pos)
+ .Callable("Nth")
+ .Add(0, stateArg)
+ .Atom(1, "1", TNodeFlags::Default)
+ .Seal()
+ .Build();
TExprNode::TPtr lagQueue;
if (haveLagQueue) {
- lagQueue = ctx.Builder(pos)
+ lagQueue = ctx.Builder(pos)
.Callable("Nth")
- .Add(0, state)
- .Atom(1, "1", TNodeFlags::Default)
+ .Add(0, state)
+ .Atom(1, "1", TNodeFlags::Default)
.Seal()
.Build();
- state = ctx.Builder(pos)
+ state = ctx.Builder(pos)
.Callable("Nth")
- .Add(0, std::move(state))
- .Atom(1, "0", TNodeFlags::Default)
+ .Add(0, std::move(state))
+ .Atom(1, "0", TNodeFlags::Default)
.Seal()
.Build();
}
@@ -1994,27 +1994,27 @@ TExprNode::TPtr ExpandNonCompactFullFrames(TPositionHandle pos, const TExprNode:
.Build();
}
- auto aggregated = ctx.Builder(pos)
- .Callable("PartitionsByKeys")
- .Add(0, input)
- .Add(1, keySelector)
- .Add(2, sortOrder)
- .Add(3, sortKey)
- .Lambda(4)
- .Param("stream")
- .Callable("Map")
- .Callable(0, "Condense1")
+ auto aggregated = ctx.Builder(pos)
+ .Callable("PartitionsByKeys")
+ .Add(0, input)
+ .Add(1, keySelector)
+ .Add(2, sortOrder)
+ .Add(3, sortKey)
+ .Lambda(4)
+ .Param("stream")
+ .Callable("Map")
+ .Callable(0, "Condense1")
.Apply(0, preprocessLambda)
.With(0, "stream")
.Seal()
- .Add(1, BuildFold1Lambda(pos, frames, EFold1LambdaKind::INIT, keyColumns, ctx))
+ .Add(1, BuildFold1Lambda(pos, frames, EFold1LambdaKind::INIT, keyColumns, ctx))
.Add(2, condenseSwitch)
- .Add(3, BuildFold1Lambda(pos, frames, EFold1LambdaKind::UPDATE, keyColumns, ctx))
+ .Add(3, BuildFold1Lambda(pos, frames, EFold1LambdaKind::UPDATE, keyColumns, ctx))
.Seal()
- .Add(1, BuildFold1Lambda(pos, frames, EFold1LambdaKind::CALCULATE, keyColumns, ctx))
+ .Add(1, BuildFold1Lambda(pos, frames, EFold1LambdaKind::CALCULATE, keyColumns, ctx))
.Seal()
.Seal()
- .Seal().Build();
+ .Seal().Build();
if (sessionUpdate) {
// preprocess input without aggregation
@@ -2242,7 +2242,7 @@ TExprNode::TPtr ExpandSingleCalcOverWindow(TPositionHandle pos, const TExprNode:
ui64 dataLag;
ui64 lagQueueSize;
const TTypeAnnotationNode* lagQueueItemType;
- TVector<TChain1MapTraits::TPtr> traits = BuildFoldMapTraits(dataOutpace, dataLag, lagQueueSize, lagQueueItemType, frames, ctx);
+ TVector<TChain1MapTraits::TPtr> traits = BuildFoldMapTraits(dataOutpace, dataLag, lagQueueSize, lagQueueItemType, frames, ctx);
TExprNode::TPtr sessionKey;
TExprNode::TPtr sessionSortTraits;
@@ -2316,21 +2316,21 @@ TExprNode::TPtr ExpandSingleCalcOverWindow(TPositionHandle pos, const TExprNode:
.Build();
}
-
+
processed = ctx.Builder(pos)
- .Callable("OrderedMap")
- .Callable(0, "Chain1Map")
- .Add(0, std::move(processed))
- .Add(1, BuildChain1MapInitLambda(pos, traits, dataQueue, lagQueueSize, lagQueueItemType, ctx))
- .Add(2, BuildChain1MapUpdateLambda(pos, traits, dataQueue, lagQueueSize != 0, ctx))
- .Seal()
- .Lambda(1)
- .Param("pair")
- .Callable("Nth")
- .Arg(0, "pair")
- .Atom(1, "0", TNodeFlags::Default)
- .Seal()
- .Seal()
+ .Callable("OrderedMap")
+ .Callable(0, "Chain1Map")
+ .Add(0, std::move(processed))
+ .Add(1, BuildChain1MapInitLambda(pos, traits, dataQueue, lagQueueSize, lagQueueItemType, ctx))
+ .Add(2, BuildChain1MapUpdateLambda(pos, traits, dataQueue, lagQueueSize != 0, ctx))
+ .Seal()
+ .Lambda(1)
+ .Param("pair")
+ .Callable("Nth")
+ .Arg(0, "pair")
+ .Atom(1, "0", TNodeFlags::Default)
+ .Seal()
+ .Seal()
.Seal()
.Build();
diff --git a/ydb/library/yql/core/yql_type_annotation.cpp b/ydb/library/yql/core/yql_type_annotation.cpp
index 72769fa3d5..9f50af3b63 100644
--- a/ydb/library/yql/core/yql_type_annotation.cpp
+++ b/ydb/library/yql/core/yql_type_annotation.cpp
@@ -11,7 +11,7 @@
#include <util/stream/file.h>
#include <util/string/join.h>
-
+
namespace NYql {
using namespace NKikimr;
@@ -21,9 +21,9 @@ bool TTypeAnnotationContext::Initialize(TExprContext& ctx) {
InitializeResult = DoInitialize(ctx);
}
- return *InitializeResult;
-}
-
+ return *InitializeResult;
+}
+
bool TTypeAnnotationContext::DoInitialize(TExprContext& ctx) {
for (auto& x : DataSources) {
if (!x->Initialize(ctx)) {
diff --git a/ydb/library/yql/core/yql_type_annotation.h b/ydb/library/yql/core/yql_type_annotation.h
index a5b7811585..1a1f1fb476 100644
--- a/ydb/library/yql/core/yql_type_annotation.h
+++ b/ydb/library/yql/core/yql_type_annotation.h
@@ -8,12 +8,12 @@
#include <ydb/library/yql/public/udf/udf_validate.h>
#include <ydb/library/yql/ast/yql_expr.h>
-
+
#include <library/cpp/yson/node/node.h>
#include <library/cpp/time_provider/time_provider.h>
#include <library/cpp/random_provider/random_provider.h>
#include <library/cpp/enumbitset/enumbitset.h>
-
+
#include <util/generic/hash.h>
#include <util/generic/hash_set.h>
#include <util/generic/set.h>
@@ -192,10 +192,10 @@ struct TTypeAnnotationContext: public TThrRefBase {
TYqlOperationOptions OperationOptions;
TVector<TCredentialTablePtr> Credentials;
TUserCredentials UserCredentials;
- IModuleResolver::TPtr Modules;
+ IModuleResolver::TPtr Modules;
NUdf::EValidateMode ValidateMode = NUdf::EValidateMode::None;
bool DisableNativeUdfSupport = false;
- TMaybe<TString> OptLLVM;
+ TMaybe<TString> OptLLVM;
bool IsReadOnly = false;
TAutoPtr<IGraphTransformer> CustomInstantTypeTransformer;
bool Diagnostics = false;
@@ -209,7 +209,7 @@ struct TTypeAnnotationContext: public TThrRefBase {
ui32 EvaluateForLimit = 500;
ui32 EvaluateOrderByColumnLimit = 100;
bool PullUpFlatMapOverJoin = true;
- bool DeprecatedSQL = false;
+ bool DeprecatedSQL = false;
THashMap<std::tuple<TString, TString, const TTypeAnnotationNode*>,
std::tuple<const TTypeAnnotationNode*, const TTypeAnnotationNode*, const TTypeAnnotationNode*>>
UdfTypeCache; // (name,typecfg,type)->(type,run config type,new user type)
@@ -230,30 +230,30 @@ struct TTypeAnnotationContext: public TThrRefBase {
IGraphTransformer::TStatus SetColumnOrder(const TExprNode& node, const TColumnOrder& columnOrder, TExprContext& ctx);
// cached constants
- std::optional<ui64> CachedNow;
- std::tuple<std::optional<ui64>, std::optional<double>, std::optional<TGUID>> CachedRandom;
-
- std::optional<bool> InitializeResult;
-
- template <typename T>
- T GetRandom() const noexcept;
-
- template <typename T>
- T GetCachedRandom() noexcept {
- auto& cached = std::get<std::optional<T>>(CachedRandom);
- if (!cached) {
- cached = GetRandom<T>();
- }
- return *cached;
- }
-
- ui64 GetCachedNow() noexcept {
- if (!CachedNow) {
- CachedNow = TimeProvider->Now().GetValue();
- }
- return *CachedNow;
- }
-
+ std::optional<ui64> CachedNow;
+ std::tuple<std::optional<ui64>, std::optional<double>, std::optional<TGUID>> CachedRandom;
+
+ std::optional<bool> InitializeResult;
+
+ template <typename T>
+ T GetRandom() const noexcept;
+
+ template <typename T>
+ T GetCachedRandom() noexcept {
+ auto& cached = std::get<std::optional<T>>(CachedRandom);
+ if (!cached) {
+ cached = GetRandom<T>();
+ }
+ return *cached;
+ }
+
+ ui64 GetCachedNow() noexcept {
+ if (!CachedNow) {
+ CachedNow = TimeProvider->Now().GetValue();
+ }
+ return *CachedNow;
+ }
+
void AddDataSource(TStringBuf name, TIntrusivePtr<IDataProvider> provider) {
DataSourceMap[name] = provider;
DataSources.push_back(std::move(provider));
@@ -300,21 +300,21 @@ struct TTypeAnnotationContext: public TThrRefBase {
}
};
-template <> inline
-double TTypeAnnotationContext::GetRandom<double>() const noexcept {
- return RandomProvider->GenRandReal2();
-}
-
-template <> inline
-ui64 TTypeAnnotationContext::GetRandom<ui64>() const noexcept {
- return RandomProvider->GenRand64();
-}
-
-template <> inline
-TGUID TTypeAnnotationContext::GetRandom<TGUID>() const noexcept {
- return RandomProvider->GenUuid4();
-}
-
+template <> inline
+double TTypeAnnotationContext::GetRandom<double>() const noexcept {
+ return RandomProvider->GenRandReal2();
+}
+
+template <> inline
+ui64 TTypeAnnotationContext::GetRandom<ui64>() const noexcept {
+ return RandomProvider->GenRand64();
+}
+
+template <> inline
+TGUID TTypeAnnotationContext::GetRandom<TGUID>() const noexcept {
+ return RandomProvider->GenUuid4();
+}
+
using TTypeAnnotationContextPtr = TIntrusivePtr<TTypeAnnotationContext>;
} // namespace NYql
diff --git a/ydb/library/yql/core/yql_type_helpers.cpp b/ydb/library/yql/core/yql_type_helpers.cpp
index 7ced38c7cb..9ae7cab56f 100644
--- a/ydb/library/yql/core/yql_type_helpers.cpp
+++ b/ydb/library/yql/core/yql_type_helpers.cpp
@@ -50,7 +50,7 @@ bool SilentGetSequenceItemType(TPosition pos, const TTypeAnnotationNode& inputTy
return false;
}
- if (allowMultiIO && itemType->GetKind() != ETypeAnnotationKind::Struct && itemType->GetKind() != ETypeAnnotationKind::Multi) {
+ if (allowMultiIO && itemType->GetKind() != ETypeAnnotationKind::Struct && itemType->GetKind() != ETypeAnnotationKind::Multi) {
if (itemType->GetKind() != ETypeAnnotationKind::Variant) {
error = TIssue(pos, TStringBuilder() << "Expected Struct or Variant as row type, but got: " << *itemType);
return false;
@@ -75,8 +75,8 @@ bool SilentGetSequenceItemType(TPosition pos, const TTypeAnnotationNode& inputTy
}
}
} else {
- if (itemType->GetKind() != ETypeAnnotationKind::Struct && itemType->GetKind() != ETypeAnnotationKind::Multi) {
- error = TIssue(pos, TStringBuilder() << "Expected Struct or Multi as row type, but got: " << *itemType);
+ if (itemType->GetKind() != ETypeAnnotationKind::Struct && itemType->GetKind() != ETypeAnnotationKind::Multi) {
+ error = TIssue(pos, TStringBuilder() << "Expected Struct or Multi as row type, but got: " << *itemType);
return false;
}
}
diff --git a/ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h b/ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h
index 8e8838f1ee..deaadefb42 100644
--- a/ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h
+++ b/ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h
@@ -1225,8 +1225,8 @@ protected:
if (freeSpace > 0) {
NKikimr::NMiniKQL::TUnboxedValueVector batch;
Y_VERIFY(source.SourceActor);
- bool finished = false;
- const i64 space = source.SourceActor->GetSourceData(batch, finished, freeSpace);
+ bool finished = false;
+ const i64 space = source.SourceActor->GetSourceData(batch, finished, freeSpace);
const ui64 index = inputIndex;
CA_LOG_D("Poll source " << index
<< ". Buffer free space: " << freeSpace
@@ -1251,7 +1251,7 @@ protected:
TString desc = issues.ToString();
CA_LOG_E("Source[" << inputIndex << "] fatal error: " << desc);
InternalError(TIssuesIds::DEFAULT_ERROR, desc);
- }
+ }
void OnSinkError(ui64 outputIndex, const TIssues& issues, bool isFatal) override {
if (!isFatal) {
diff --git a/ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h b/ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h
index 55fff74c4b..d2a646cab6 100644
--- a/ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h
+++ b/ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h
@@ -48,7 +48,7 @@ struct IDqSourceActor {
// Gets data and returns space used by filled data batch.
// Method should be called under bound mkql allocator.
// Could throw YQL errors.
- virtual i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& batch, bool& finished, i64 freeSpace) = 0;
+ virtual i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& batch, bool& finished, i64 freeSpace) = 0;
// Checkpointing.
virtual void SaveState(const NDqProto::TCheckpoint& checkpoint, NDqProto::TSourceState& state) = 0;
diff --git a/ydb/library/yql/dq/opt/dq_opt.cpp b/ydb/library/yql/dq/opt/dq_opt.cpp
index 729cd6117e..f60f29dd46 100644
--- a/ydb/library/yql/dq/opt/dq_opt.cpp
+++ b/ydb/library/yql/dq/opt/dq_opt.cpp
@@ -13,14 +13,14 @@ TDqStageSettings TDqStageSettings::Parse(const TDqStageBase& node) {
TDqStageSettings settings{};
for (const auto& tuple : node.Settings()) {
- if (const auto name = tuple.Name().Value(); name == IdSettingName) {
+ if (const auto name = tuple.Name().Value(); name == IdSettingName) {
YQL_ENSURE(tuple.Value().Maybe<TCoAtom>());
settings.Id = tuple.Value().Cast<TCoAtom>().Value();
} else if (name == LogicalIdSettingName) {
YQL_ENSURE(tuple.Value().Maybe<TCoAtom>());
settings.LogicalId = FromString<ui64>(tuple.Value().Cast<TCoAtom>().Value());
- } else if (name == SinglePartitionSettingName) {
- settings.SinglePartition = true;
+ } else if (name == SinglePartitionSettingName) {
+ settings.SinglePartition = true;
} else if (name == IsExternalSetting) {
settings.IsExternalFunction = true;
} else if (name == TransformNameSetting) {
@@ -70,12 +70,12 @@ NNodes::TCoNameValueTupleList TDqStageSettings::BuildNode(TExprContext& ctx, TPo
.Done());
}
- if (SinglePartition) {
- settings.push_back(Build<TCoNameValueTuple>(ctx, pos)
- .Name().Build(SinglePartitionSettingName)
- .Done());
- }
-
+ if (SinglePartition) {
+ settings.push_back(Build<TCoNameValueTuple>(ctx, pos)
+ .Name().Build(SinglePartitionSettingName)
+ .Done());
+ }
+
return Build<TCoNameValueTupleList>(ctx, pos)
.Add(settings)
.Done();
diff --git a/ydb/library/yql/dq/opt/dq_opt.h b/ydb/library/yql/dq/opt/dq_opt.h
index 9fde06b0e4..5b3146d0f4 100644
--- a/ydb/library/yql/dq/opt/dq_opt.h
+++ b/ydb/library/yql/dq/opt/dq_opt.h
@@ -11,7 +11,7 @@ namespace NYql::NDq {
struct TDqStageSettings {
static constexpr TStringBuf LogicalIdSettingName = "_logical_id";
static constexpr TStringBuf IdSettingName = "_id";
- static constexpr TStringBuf SinglePartitionSettingName = "_single_partition";
+ static constexpr TStringBuf SinglePartitionSettingName = "_single_partition";
static constexpr TStringBuf IsExternalSetting = "is_external_function";
static constexpr TStringBuf TransformNameSetting = "transform_name";
static constexpr TStringBuf TransformTypeSetting = "transform_type";
@@ -19,7 +19,7 @@ struct TDqStageSettings {
ui64 LogicalId = 0;
TString Id;
- bool SinglePartition = false;
+ bool SinglePartition = false;
bool IsExternalFunction = false;
NDqProto::ETransformType TransformType = NDqProto::TRANSFORM_YANDEX_CLOUD;
diff --git a/ydb/library/yql/dq/opt/dq_opt_build.cpp b/ydb/library/yql/dq/opt/dq_opt_build.cpp
index 8292678d5e..e57b85a911 100644
--- a/ydb/library/yql/dq/opt/dq_opt_build.cpp
+++ b/ydb/library/yql/dq/opt/dq_opt_build.cpp
@@ -30,49 +30,49 @@ TExprBase RewriteProgramResultToStream(const TExprBase& result, TExprContext& ct
.Done();
}
- if (const auto itemType = result.Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
- ETypeAnnotationKind::Struct == itemType->GetKind() && result.Ref().IsCallable({"PartitionsByKeys", "CombineByKey"})) {
- if (const auto structType = itemType->Cast<TStructExprType>(); structType->GetSize() > 0U) {
- return TCoFromFlow(ctx.Builder(result.Pos())
- .Callable("FromFlow")
- .Callable(0, "NarrowMap")
- .Callable(0, "ExpandMap")
- .Add(0, result.Ptr())
- .Lambda(1)
- .Param("item")
- .Do([&](TExprNodeBuilder& lambda) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : structType->GetItems()) {
- lambda.Callable(i++, "Member")
- .Arg(0, "item")
- .Atom(1, item->GetName())
- .Seal();
- }
- return lambda;
- })
- .Seal()
- .Seal()
- .Lambda(1)
- .Params("fields", structType->GetSize())
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : structType->GetItems()) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build());
- }
- }
-
+ if (const auto itemType = result.Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType();
+ ETypeAnnotationKind::Struct == itemType->GetKind() && result.Ref().IsCallable({"PartitionsByKeys", "CombineByKey"})) {
+ if (const auto structType = itemType->Cast<TStructExprType>(); structType->GetSize() > 0U) {
+ return TCoFromFlow(ctx.Builder(result.Pos())
+ .Callable("FromFlow")
+ .Callable(0, "NarrowMap")
+ .Callable(0, "ExpandMap")
+ .Add(0, result.Ptr())
+ .Lambda(1)
+ .Param("item")
+ .Do([&](TExprNodeBuilder& lambda) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : structType->GetItems()) {
+ lambda.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Atom(1, item->GetName())
+ .Seal();
+ }
+ return lambda;
+ })
+ .Seal()
+ .Seal()
+ .Lambda(1)
+ .Params("fields", structType->GetSize())
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : structType->GetItems()) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build());
+ }
+ }
+
return Build<TCoFromFlow>(ctx, result.Pos()) // TODO: TDqOutputReader?
.Input(result)
.Done();
diff --git a/ydb/library/yql/dq/opt/dq_opt_log.cpp b/ydb/library/yql/dq/opt/dq_opt_log.cpp
index 7a68f5ba73..fed0f09f0f 100644
--- a/ydb/library/yql/dq/opt/dq_opt_log.cpp
+++ b/ydb/library/yql/dq/opt/dq_opt_log.cpp
@@ -18,7 +18,7 @@ TExprBase DqRewriteAggregate(TExprBase node, TExprContext& ctx) {
return node;
}
- auto result = ExpandAggregate(node.Ptr(), ctx);
+ auto result = ExpandAggregate(node.Ptr(), ctx);
YQL_ENSURE(result);
return TExprBase(result);
diff --git a/ydb/library/yql/dq/opt/dq_opt_peephole.cpp b/ydb/library/yql/dq/opt/dq_opt_peephole.cpp
index 92dcc6e6c3..87ac170eea 100644
--- a/ydb/library/yql/dq/opt/dq_opt_peephole.cpp
+++ b/ydb/library/yql/dq/opt/dq_opt_peephole.cpp
@@ -135,104 +135,104 @@ TExprBase DqPeepholeRewriteMapJoin(const TExprBase& node, TExprContext& ctx) {
if (!node.Maybe<TDqPhyMapJoin>()) {
return node;
}
- const auto mapJoin = node.Cast<TDqPhyMapJoin>();
- const auto pos = mapJoin.Pos();
+ const auto mapJoin = node.Cast<TDqPhyMapJoin>();
+ const auto pos = mapJoin.Pos();
- const auto leftTableLabel = GetTableLabel(mapJoin.LeftLabel());
- const auto rightTableLabel = GetTableLabel(mapJoin.RightLabel());
+ const auto leftTableLabel = GetTableLabel(mapJoin.LeftLabel());
+ const auto rightTableLabel = GetTableLabel(mapJoin.RightLabel());
auto [leftKeyColumnNodes, rightKeyColumnNodes] = JoinKeysToAtoms(ctx, mapJoin, leftTableLabel, rightTableLabel);
- const auto keyWidth = leftKeyColumnNodes.size();
+ const auto keyWidth = leftKeyColumnNodes.size();
- const auto makeRenames = [&ctx, pos](TStringBuf label, const TStructExprType& type) {
+ const auto makeRenames = [&ctx, pos](TStringBuf label, const TStructExprType& type) {
TExprNode::TListType renames;
- for (const auto& member : type.GetItems()) {
- renames.emplace_back(ctx.NewAtom(pos, member->GetName()));
- renames.emplace_back(ctx.NewAtom(pos, GetColumnName(label, member)));
+ for (const auto& member : type.GetItems()) {
+ renames.emplace_back(ctx.NewAtom(pos, member->GetName()));
+ renames.emplace_back(ctx.NewAtom(pos, GetColumnName(label, member)));
}
return renames;
};
- const auto itemTypeLeft = GetSeqItemType(mapJoin.LeftInput().Ref().GetTypeAnn())->Cast<TStructExprType>();
- const auto itemTypeRight = GetSeqItemType(mapJoin.RightInput().Ref().GetTypeAnn())->Cast<TStructExprType>();
-
- TExprNode::TListType leftRenames = makeRenames(leftTableLabel, *itemTypeLeft);
- TExprNode::TListType rightRenames, rightPayloads;
- const bool withRightSide = mapJoin.JoinType().Value() != "LeftOnly" && mapJoin.JoinType().Value() != "LeftSemi";
- if (withRightSide) {
- rightRenames = makeRenames(rightTableLabel, *itemTypeRight);
- rightPayloads.reserve(rightRenames.size() >> 1U);
- for (auto it = rightRenames.cbegin(); rightRenames.cend() != it; ++++it)
- rightPayloads.emplace_back(*it);
+ const auto itemTypeLeft = GetSeqItemType(mapJoin.LeftInput().Ref().GetTypeAnn())->Cast<TStructExprType>();
+ const auto itemTypeRight = GetSeqItemType(mapJoin.RightInput().Ref().GetTypeAnn())->Cast<TStructExprType>();
+
+ TExprNode::TListType leftRenames = makeRenames(leftTableLabel, *itemTypeLeft);
+ TExprNode::TListType rightRenames, rightPayloads;
+ const bool withRightSide = mapJoin.JoinType().Value() != "LeftOnly" && mapJoin.JoinType().Value() != "LeftSemi";
+ if (withRightSide) {
+ rightRenames = makeRenames(rightTableLabel, *itemTypeRight);
+ rightPayloads.reserve(rightRenames.size() >> 1U);
+ for (auto it = rightRenames.cbegin(); rightRenames.cend() != it; ++++it)
+ rightPayloads.emplace_back(*it);
}
- TTypeAnnotationNode::TListType keyTypes(keyWidth);
- for (auto i = 0U; i < keyTypes.size(); ++i) {
- const auto keyTypeLeft = itemTypeLeft->FindItemType(leftKeyColumnNodes[i]->Content());
- const auto keyTypeRight = itemTypeRight->FindItemType(rightKeyColumnNodes[i]->Content());
- bool optKey = false;
- keyTypes[i] = JoinDryKeyType(keyTypeLeft, keyTypeRight, optKey, ctx);
- if (!keyTypes[i])
- keyTypes.clear();
- }
-
- auto leftInput = ctx.NewCallable(mapJoin.LeftInput().Pos(), "ToFlow", {mapJoin.LeftInput().Ptr()});
- auto rightInput = ctx.NewCallable(mapJoin.RightInput().Pos(), "ToFlow", {mapJoin.RightInput().Ptr()});
-
- if (keyTypes.empty()) {
- const auto type = mapJoin.Ref().GetTypeAnn();
- if (mapJoin.JoinType().Value() == "Inner" || mapJoin.JoinType().Value() == "LeftSemi")
- return TExprBase(ctx.NewCallable(pos, "EmptyIterator", {ExpandType(pos, *type, ctx)}));
-
- const auto structType = GetSeqItemType(type)->Cast<TStructExprType>();
- return TExprBase(ctx.Builder(pos)
- .Callable("Map")
- .Add(0, std::move(leftInput))
- .Lambda(0)
- .Param("row")
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 idx = 0U;
- for (auto i = 0U; i < leftRenames.size(); ++++i) {
- parent.List(idx++)
- .Add(0, std::move(leftRenames[i + 1U]))
- .Callable(1, "Member")
- .Arg(0, "row")
- .Add(1, std::move(leftRenames[i]))
- .Seal()
- .Seal();
- }
- for (auto i = 0U; i < rightRenames.size(); ++i) {
- const auto memberType = structType->FindItemType(rightRenames[++i]->Content());
- parent.List(idx++)
- .Add(0, std::move(rightRenames[i]))
- .Callable(1, "Nothing")
- .Add(0, ExpandType(pos, *memberType, ctx))
- .Seal()
- .Seal();
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal().Build()
- );
- }
-
- const bool payloads = !rightPayloads.empty();
- rightInput = MakeDictForJoin<true>(PrepareListForJoin(std::move(rightInput), keyTypes, rightKeyColumnNodes, rightPayloads, payloads, false, true, ctx), payloads, withRightSide, ctx);
-
- return Build<TCoFlatMap>(ctx, pos)
- .Input(std::move(rightInput))
- .Lambda()
- .Args({"dict"})
- .Body<TCoMapJoinCore>()
- .LeftInput(std::move(leftInput))
- .RightDict("dict")
- .JoinKind(mapJoin.JoinType())
- .LeftKeysColumns(ctx.NewList(pos, std::move(leftKeyColumnNodes)))
- .LeftRenames(ctx.NewList(pos, std::move(leftRenames)))
- .RightRenames(ctx.NewList(pos, std::move(rightRenames)))
+ TTypeAnnotationNode::TListType keyTypes(keyWidth);
+ for (auto i = 0U; i < keyTypes.size(); ++i) {
+ const auto keyTypeLeft = itemTypeLeft->FindItemType(leftKeyColumnNodes[i]->Content());
+ const auto keyTypeRight = itemTypeRight->FindItemType(rightKeyColumnNodes[i]->Content());
+ bool optKey = false;
+ keyTypes[i] = JoinDryKeyType(keyTypeLeft, keyTypeRight, optKey, ctx);
+ if (!keyTypes[i])
+ keyTypes.clear();
+ }
+
+ auto leftInput = ctx.NewCallable(mapJoin.LeftInput().Pos(), "ToFlow", {mapJoin.LeftInput().Ptr()});
+ auto rightInput = ctx.NewCallable(mapJoin.RightInput().Pos(), "ToFlow", {mapJoin.RightInput().Ptr()});
+
+ if (keyTypes.empty()) {
+ const auto type = mapJoin.Ref().GetTypeAnn();
+ if (mapJoin.JoinType().Value() == "Inner" || mapJoin.JoinType().Value() == "LeftSemi")
+ return TExprBase(ctx.NewCallable(pos, "EmptyIterator", {ExpandType(pos, *type, ctx)}));
+
+ const auto structType = GetSeqItemType(type)->Cast<TStructExprType>();
+ return TExprBase(ctx.Builder(pos)
+ .Callable("Map")
+ .Add(0, std::move(leftInput))
+ .Lambda(0)
+ .Param("row")
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 idx = 0U;
+ for (auto i = 0U; i < leftRenames.size(); ++++i) {
+ parent.List(idx++)
+ .Add(0, std::move(leftRenames[i + 1U]))
+ .Callable(1, "Member")
+ .Arg(0, "row")
+ .Add(1, std::move(leftRenames[i]))
+ .Seal()
+ .Seal();
+ }
+ for (auto i = 0U; i < rightRenames.size(); ++i) {
+ const auto memberType = structType->FindItemType(rightRenames[++i]->Content());
+ parent.List(idx++)
+ .Add(0, std::move(rightRenames[i]))
+ .Callable(1, "Nothing")
+ .Add(0, ExpandType(pos, *memberType, ctx))
+ .Seal()
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal().Build()
+ );
+ }
+
+ const bool payloads = !rightPayloads.empty();
+ rightInput = MakeDictForJoin<true>(PrepareListForJoin(std::move(rightInput), keyTypes, rightKeyColumnNodes, rightPayloads, payloads, false, true, ctx), payloads, withRightSide, ctx);
+
+ return Build<TCoFlatMap>(ctx, pos)
+ .Input(std::move(rightInput))
+ .Lambda()
+ .Args({"dict"})
+ .Body<TCoMapJoinCore>()
+ .LeftInput(std::move(leftInput))
+ .RightDict("dict")
+ .JoinKind(mapJoin.JoinType())
+ .LeftKeysColumns(ctx.NewList(pos, std::move(leftKeyColumnNodes)))
+ .LeftRenames(ctx.NewList(pos, std::move(leftRenames)))
+ .RightRenames(ctx.NewList(pos, std::move(rightRenames)))
.Build()
.Build()
.Done();
@@ -396,7 +396,7 @@ NNodes::TExprBase DqPeepholeRewriteJoinDict(const NNodes::TExprBase& node, TExpr
for (auto i = 0U; i < leftKeys.size(); ++i) {
auto leftKeyType = leftRowType->FindItemType(leftKeys[i]->Content());
auto rightKeyType = rightRowType->FindItemType(rightKeys[i]->Content());
- keyTypeItems.emplace_back(CommonType<true>(node.Pos(), DryType(leftKeyType, optKeyLeft, ctx), DryType(rightKeyType, optKeyRight, ctx), ctx));
+ keyTypeItems.emplace_back(CommonType<true>(node.Pos(), DryType(leftKeyType, optKeyLeft, ctx), DryType(rightKeyType, optKeyRight, ctx), ctx));
badKey = !keyTypeItems.back();
if (badKey) {
YQL_CLOG(DEBUG, CoreDq) << "Not comparable keys in join: " << leftKeys[i]->Content()
diff --git a/ydb/library/yql/dq/opt/dq_opt_phy.cpp b/ydb/library/yql/dq/opt/dq_opt_phy.cpp
index e911c7edef..cbe871059d 100644
--- a/ydb/library/yql/dq/opt/dq_opt_phy.cpp
+++ b/ydb/library/yql/dq/opt/dq_opt_phy.cpp
@@ -107,21 +107,21 @@ TExprBase DqBuildPartitionsStageStub(TExprBase node, TExprContext& ctx, const TP
return node;
}
- auto handler = partition.ListHandlerLambda();
-
- if (ETypeAnnotationKind::List == handler.Ref().GetTypeAnn()->GetKind()) {
- handler = Build<TCoLambda>(ctx, handler.Pos())
- .Args({"flow"})
- .template Body<TCoToFlow>()
- .template Input<TExprApplier>()
- .Apply(handler)
- .template With<TCoForwardList>(0)
- .Stream("flow")
- .Build()
- .Build()
- .Build().Done();
- }
-
+ auto handler = partition.ListHandlerLambda();
+
+ if (ETypeAnnotationKind::List == handler.Ref().GetTypeAnn()->GetKind()) {
+ handler = Build<TCoLambda>(ctx, handler.Pos())
+ .Args({"flow"})
+ .template Body<TCoToFlow>()
+ .template Input<TExprApplier>()
+ .Apply(handler)
+ .template With<TCoForwardList>(0)
+ .Stream("flow")
+ .Build()
+ .Build()
+ .Build().Done();
+ }
+
auto partitionStage = Build<TDqStage>(ctx, node.Pos())
.Inputs()
.Add(newConnection)
@@ -138,8 +138,8 @@ TExprBase DqBuildPartitionsStageStub(TExprBase node, TExprContext& ctx, const TP
.ListHandlerLambda()
.Args({"list"})
.template Body<TExprApplier>()
- .Apply(handler)
- .With(handler.Args().Arg(0), "list")
+ .Apply(handler)
+ .With(handler.Args().Arg(0), "list")
.Build()
.Build()
.Build()
@@ -336,11 +336,11 @@ TExprBase DqPushExtractMembersToStage(TExprBase node, TExprContext& ctx, IOptimi
TExprBase DqBuildFlatmapStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage)
{
- if (!node.Maybe<TCoFlatMapBase>().Input().Maybe<TDqCnUnionAll>()) {
+ if (!node.Maybe<TCoFlatMapBase>().Input().Maybe<TDqCnUnionAll>()) {
return node;
}
- auto flatmap = node.Cast<TCoFlatMapBase>();
+ auto flatmap = node.Cast<TCoFlatMapBase>();
auto dqUnion = flatmap.Input().Cast<TDqCnUnionAll>();
if (!IsSingleConsumerConnection(dqUnion, parentsMap, allowStageMultiUsage)) {
return node;
@@ -350,14 +350,14 @@ TExprBase DqBuildFlatmapStage(TExprBase node, TExprContext& ctx, IOptimizationCo
return node;
}
- auto lambda = TCoLambda(ctx.Builder(flatmap.Lambda().Pos())
- .Lambda()
- .Param("stream")
- .Callable(flatmap.Ref().Content())
- .Arg(0, "stream")
+ auto lambda = TCoLambda(ctx.Builder(flatmap.Lambda().Pos())
+ .Lambda()
+ .Param("stream")
+ .Callable(flatmap.Ref().Content())
+ .Arg(0, "stream")
.Add(1, ctx.DeepCopyLambda(flatmap.Lambda().Ref()))
- .Seal()
- .Seal().Build());
+ .Seal()
+ .Seal().Build());
auto pushResult = DqPushLambdaToStageUnionAll(dqUnion, lambda, {}, ctx, optCtx);
if (pushResult) {
@@ -385,39 +385,39 @@ TExprBase DqBuildFlatmapStage(TExprBase node, TExprContext& ctx, IOptimizationCo
template <typename BaseLMap>
TExprBase DqPushBaseLMapToStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage = true)
-{
+{
if (!node.Maybe<BaseLMap>().Input().template Maybe<TDqCnUnionAll>()) {
- return node;
- }
-
+ return node;
+ }
+
auto lmap = node.Cast<BaseLMap>();
auto dqUnion = lmap.Input().template Cast<TDqCnUnionAll>();
if (!IsSingleConsumerConnection(dqUnion, parentsMap, allowStageMultiUsage)) {
return node;
}
-
+
if (!CanPushDqExpr(lmap.Lambda(), dqUnion)) {
- return node;
- }
-
- auto lambda = Build<TCoLambda>(ctx, lmap.Lambda().Pos())
- .Args({"stream"})
+ return node;
+ }
+
+ auto lambda = Build<TCoLambda>(ctx, lmap.Lambda().Pos())
+ .Args({"stream"})
.template Body<TCoToStream>()
.template Input<TExprApplier>()
.Apply(lmap.Lambda())
.With(lmap.Lambda().Args().Arg(0), "stream")
.Build()
- .Build()
- .Done();
-
+ .Build()
+ .Done();
+
auto result = DqPushLambdaToStageUnionAll(dqUnion, lambda, {}, ctx, optCtx);
- if (!result) {
- return node;
- }
-
- return result.Cast();
-}
-
+ if (!result) {
+ return node;
+ }
+
+ return result.Cast();
+}
+
TExprBase DqPushOrderedLMapToStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage)
{
@@ -639,15 +639,15 @@ TExprBase DqBuildAggregationResultStage(TExprBase node, TExprContext& ctx, IOpti
return node;
}
- const auto asList = node.Cast<TCoAsList>();
-
+ const auto asList = node.Cast<TCoAsList>();
+
TVector<TExprBase> resultConnections;
for (const auto& listItem : asList) {
if (!listItem.Maybe<TCoAsStruct>()) {
return node;
}
- const auto asStruct = listItem.Cast<TCoAsStruct>();
+ const auto asStruct = listItem.Cast<TCoAsStruct>();
TExprNode::TPtr connection;
bool hasDirectConnection = false;
@@ -707,8 +707,8 @@ TExprBase DqBuildAggregationResultStage(TExprBase node, TExprContext& ctx, IOpti
return node;
}
- const auto pos = listItem.Pos();
- auto newArg = ctx.NewArgument(pos, "result");
+ const auto pos = listItem.Pos();
+ auto newArg = ctx.NewArgument(pos, "result");
auto lambda = ctx.NewLambda(pos,
ctx.NewArguments(pos, {newArg}),
ctx.ReplaceNode(asStruct.Ptr(), *connection, std::move(newArg))
@@ -743,20 +743,20 @@ TExprBase DqBuildAggregationResultStage(TExprBase node, TExprContext& ctx, IOpti
.Done().Ptr();
}
- auto resultConnection = Build<TDqCnUnionAll>(ctx, pos)
- .Output()
- .Stage<TDqStage>()
- .Inputs()
- .Add(std::move(connection))
- .Build()
- .Program()
+ auto resultConnection = Build<TDqCnUnionAll>(ctx, pos)
+ .Output()
+ .Stage<TDqStage>()
+ .Inputs()
+ .Add(std::move(connection))
+ .Build()
+ .Program()
.Args(programArg)
- .Body<TCoMap>()
+ .Body<TCoMap>()
.Input(mapInput)
- .Lambda(std::move(lambda))
+ .Lambda(std::move(lambda))
.Build()
.Build()
- .Settings(TDqStageSettings().BuildNode(ctx, pos))
+ .Settings(TDqStageSettings().BuildNode(ctx, pos))
.Build()
.Index().Build("0")
.Build()
@@ -958,11 +958,11 @@ TExprBase DqBuildTopSortStage(TExprBase node, TExprContext& ctx, IOptimizationCo
TExprBase DqBuildSortStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage)
{
- if (!node.Maybe<TCoSortBase>().Input().Maybe<TDqCnUnionAll>()) {
+ if (!node.Maybe<TCoSortBase>().Input().Maybe<TDqCnUnionAll>()) {
return node;
}
- auto sort = node.Cast<TCoSortBase>();
+ auto sort = node.Cast<TCoSortBase>();
auto dqUnion = sort.Input().Cast<TDqCnUnionAll>();
if (!IsSingleConsumerConnection(dqUnion, parentsMap, allowStageMultiUsage)) {
@@ -1252,19 +1252,19 @@ TExprBase DqRewriteLengthOfStageOutput(TExprBase node, TExprContext& ctx, IOptim
.Build()
.InitHandlerLambda()
.Args({"key", "item"})
- .Body<TCoUint64>()
- .Literal().Build("1")
- .Build()
+ .Body<TCoUint64>()
+ .Literal().Build("1")
+ .Build()
.Build()
.UpdateHandlerLambda()
.Args({"key", "item", "state"})
- .Body<TCoInc>()
- .Value("state")
+ .Body<TCoInc>()
+ .Value("state")
.Build()
.Build()
.FinishHandlerLambda()
.Args({"key", "state"})
- .Body<TCoJust>()
+ .Body<TCoJust>()
.Input<TCoAsStruct>()
.Add<TCoNameValueTuple>()
.Name(field)
diff --git a/ydb/library/yql/dq/opt/dq_opt_phy.h b/ydb/library/yql/dq/opt/dq_opt_phy.h
index 7f35c8aa95..70a9d70082 100644
--- a/ydb/library/yql/dq/opt/dq_opt_phy.h
+++ b/ydb/library/yql/dq/opt/dq_opt_phy.h
@@ -23,9 +23,9 @@ NNodes::TExprBase DqPushSkipNullMembersToStage(NNodes::TExprBase node, TExprCont
NNodes::TExprBase DqPushExtractMembersToStage(NNodes::TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage = true);
-NNodes::TExprBase DqPushOrderedLMapToStage(NNodes::TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
+NNodes::TExprBase DqPushOrderedLMapToStage(NNodes::TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage = true);
-
+
NNodes::TExprBase DqPushLMapToStage(NNodes::TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx,
const TParentsMap& parentsMap, bool allowStageMultiUsage = true);
diff --git a/ydb/library/yql/dq/runtime/dq_input_impl.h b/ydb/library/yql/dq/runtime/dq_input_impl.h
index 17edacdd1b..dca47f85dd 100644
--- a/ydb/library/yql/dq/runtime/dq_input_impl.h
+++ b/ydb/library/yql/dq/runtime/dq_input_impl.h
@@ -85,7 +85,7 @@ public:
return true;
}
- void Finish() override {
+ void Finish() override {
Finished = true;
}
diff --git a/ydb/library/yql/dq/runtime/dq_source.h b/ydb/library/yql/dq/runtime/dq_source.h
index 81c3dd266e..01509873f5 100644
--- a/ydb/library/yql/dq/runtime/dq_source.h
+++ b/ydb/library/yql/dq/runtime/dq_source.h
@@ -18,8 +18,8 @@ public:
virtual void Push(NKikimr::NMiniKQL::TUnboxedValueVector&& batch, i64 space) = 0;
- virtual void Finish() = 0;
-
+ virtual void Finish() = 0;
+
virtual const TDqSourceStats* GetStats() const = 0;
};
diff --git a/ydb/library/yql/dq/runtime/dq_tasks_runner.h b/ydb/library/yql/dq/runtime/dq_tasks_runner.h
index 304a392d94..a0cc816e91 100644
--- a/ydb/library/yql/dq/runtime/dq_tasks_runner.h
+++ b/ydb/library/yql/dq/runtime/dq_tasks_runner.h
@@ -124,7 +124,7 @@ struct TDqTaskRunnerSettings {
bool CollectProfileStats = false;
bool TerminateOnError = false;
bool AllowGeneratorsInUnboxedValues = true;
- TString OptLLVM = "";
+ TString OptLLVM = "";
THashMap<TString, TString> SecureParams;
THashMap<TString, TString> TaskParams;
};
diff --git a/ydb/library/yql/dq/tasks/dq_task_program.cpp b/ydb/library/yql/dq/tasks/dq_task_program.cpp
index 652c8a00c1..d06a6023b3 100644
--- a/ydb/library/yql/dq/tasks/dq_task_program.cpp
+++ b/ydb/library/yql/dq/tasks/dq_task_program.cpp
@@ -44,7 +44,7 @@ TString BuildProgram(NNodes::TCoLambda program, const TStructExprType& paramsTyp
inputNodes.push_back(inputNode);
}
- NYql::NCommon::TMkqlBuildContext ctx(compiler, pgmBuilder, exprCtx, program.Ref().UniqueId(), std::move(arguments));
+ NYql::NCommon::TMkqlBuildContext ctx(compiler, pgmBuilder, exprCtx, program.Ref().UniqueId(), std::move(arguments));
ctx.Parameters = paramsNode;
TRuntimeNode rootNode = MkqlBuildExpr(program.Body().Ref(), ctx);
diff --git a/ydb/library/yql/minikql/aligned_page_pool.cpp b/ydb/library/yql/minikql/aligned_page_pool.cpp
index 1b941eec2e..e015c255c8 100644
--- a/ydb/library/yql/minikql/aligned_page_pool.cpp
+++ b/ydb/library/yql/minikql/aligned_page_pool.cpp
@@ -122,8 +122,8 @@ TAlignedPagePool::~TAlignedPagePool() {
for (auto it = ActiveBlocks.cbegin(); ActiveBlocks.cend() != it; ActiveBlocks.erase(it++)) {
activeBlocksSize += it->second;
Free(it->first, it->second);
- }
-
+ }
+
if (activeBlocksSize > 0 || FreePages.size() != AllPages.size() || OffloadedActiveBytes) {
if (Counters.LostPagesBytesFreeCntr) {
(*Counters.LostPagesBytesFreeCntr) += OffloadedActiveBytes + activeBlocksSize + (AllPages.size() - FreePages.size()) * POOL_PAGE_SIZE;
@@ -146,14 +146,14 @@ TAlignedPagePool::~TAlignedPagePool() {
}
TotalAllocated = 0;
}
-
+
void TAlignedPagePool::ReleaseFreePages() {
TotalAllocated -= FreePages.size() * POOL_PAGE_SIZE;
if (Counters.TotalBytesAllocatedCntr) {
(*Counters.TotalBytesAllocatedCntr) -= FreePages.size() * POOL_PAGE_SIZE;
}
- for (; !FreePages.empty(); FreePages.pop()) {
+ for (; !FreePages.empty(); FreePages.pop()) {
AllPages.erase(FreePages.top());
TGlobalPools::Instance().Get(0).PushPage(FreePages.top());
}
@@ -189,7 +189,7 @@ void TAlignedPagePool::OffloadAlloc(ui64 size) {
UpdatePeaks();
}
-void TAlignedPagePool::OffloadFree(ui64 size) noexcept {
+void TAlignedPagePool::OffloadFree(ui64 size) noexcept {
TotalAllocated -= size;
OffloadedActiveBytes -= size;
if (Counters.TotalBytesAllocatedCntr) {
@@ -201,8 +201,8 @@ void* TAlignedPagePool::GetPage() {
++PageAllocCount;
if (!FreePages.empty()) {
++PageHitCount;
- const auto res = FreePages.top();
- FreePages.pop();
+ const auto res = FreePages.top();
+ FreePages.pop();
return res;
}
@@ -219,44 +219,44 @@ void* TAlignedPagePool::GetPage() {
(*Counters.TotalBytesAllocatedCntr) += POOL_PAGE_SIZE;
}
++PageGlobalHitCount;
- AllPages.emplace(ptr);
+ AllPages.emplace(ptr);
UpdatePeaks();
return ptr;
}
++PageMissCount;
- const auto res = Alloc(POOL_PAGE_SIZE);
- AllPages.emplace(res);
- return res;
+ const auto res = Alloc(POOL_PAGE_SIZE);
+ AllPages.emplace(res);
+ return res;
}
-void TAlignedPagePool::ReturnPage(void* addr) noexcept {
+void TAlignedPagePool::ReturnPage(void* addr) noexcept {
Y_VERIFY_DEBUG(AllPages.find(addr) != AllPages.end());
- FreePages.emplace(addr);
-}
-
-void* TAlignedPagePool::GetBlock(size_t size) {
+ FreePages.emplace(addr);
+}
+
+void* TAlignedPagePool::GetBlock(size_t size) {
Y_VERIFY_DEBUG(size >= POOL_PAGE_SIZE);
- if (size == POOL_PAGE_SIZE) {
- return GetPage();
- } else {
- const auto ptr = Alloc(size);
- Y_VERIFY_DEBUG(ActiveBlocks.emplace(ptr, size).second);
- return ptr;
- }
-}
-
-void TAlignedPagePool::ReturnBlock(void* ptr, size_t size) noexcept {
+ if (size == POOL_PAGE_SIZE) {
+ return GetPage();
+ } else {
+ const auto ptr = Alloc(size);
+ Y_VERIFY_DEBUG(ActiveBlocks.emplace(ptr, size).second);
+ return ptr;
+ }
+}
+
+void TAlignedPagePool::ReturnBlock(void* ptr, size_t size) noexcept {
Y_VERIFY_DEBUG(size >= POOL_PAGE_SIZE);
- if (size == POOL_PAGE_SIZE) {
- ReturnPage(ptr);
- } else {
- Free(ptr, size);
- Y_VERIFY_DEBUG(ActiveBlocks.erase(ptr));
- }
-}
-
+ if (size == POOL_PAGE_SIZE) {
+ ReturnPage(ptr);
+ } else {
+ Free(ptr, size);
+ Y_VERIFY_DEBUG(ActiveBlocks.erase(ptr));
+ }
+}
+
void* TAlignedPagePool::Alloc(size_t size) {
void* res = nullptr;
size = AlignUp(size, SYS_PAGE_SIZE);
@@ -370,7 +370,7 @@ void* TAlignedPagePool::Alloc(size_t size) {
return res;
}
-void TAlignedPagePool::Free(void* ptr, size_t size) noexcept {
+void TAlignedPagePool::Free(void* ptr, size_t size) noexcept {
size = AlignUp(size, SYS_PAGE_SIZE);
if (size <= MaxMidSize)
size = FastClp2(size);
@@ -380,9 +380,9 @@ void TAlignedPagePool::Free(void* ptr, size_t size) noexcept {
TGlobalPools::Instance().Get(level).PushPage(ptr);
} else {
#ifdef _win_
- Y_VERIFY(::VirtualFree(ptr, 0, MEM_RELEASE));
+ Y_VERIFY(::VirtualFree(ptr, 0, MEM_RELEASE));
#else
- Y_VERIFY(!::munmap(ptr, size));
+ Y_VERIFY(!::munmap(ptr, size));
#endif
}
diff --git a/ydb/library/yql/minikql/aligned_page_pool.h b/ydb/library/yql/minikql/aligned_page_pool.h
index 033f3e9d58..2ef2878655 100644
--- a/ydb/library/yql/minikql/aligned_page_pool.h
+++ b/ydb/library/yql/minikql/aligned_page_pool.h
@@ -8,10 +8,10 @@
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <type_traits>
-#include <stack>
-#include <vector>
-#include <unordered_set>
-#include <unordered_map>
+#include <stack>
+#include <vector>
+#include <unordered_set>
+#include <unordered_map>
namespace NKikimr {
@@ -56,29 +56,29 @@ public:
~TAlignedPagePool();
- inline size_t GetAllocated() const noexcept {
+ inline size_t GetAllocated() const noexcept {
return TotalAllocated;
}
- inline size_t GetUsed() const noexcept {
+ inline size_t GetUsed() const noexcept {
return TotalAllocated - GetFreePageCount() * POOL_PAGE_SIZE;
}
- inline size_t GetFreePageCount() const noexcept {
+ inline size_t GetFreePageCount() const noexcept {
return FreePages.size();
}
- static inline const void* GetPageStart(const void* addr) noexcept {
+ static inline const void* GetPageStart(const void* addr) noexcept {
return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(addr) & PAGE_ADDR_MASK);
}
- static inline void* GetPageStart(void* addr) noexcept {
+ static inline void* GetPageStart(void* addr) noexcept {
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & PAGE_ADDR_MASK);
}
void* GetPage();
- void ReturnPage(void* addr) noexcept;
+ void ReturnPage(void* addr) noexcept;
void Swap(TAlignedPagePool& other) {
DoSwap(FreePages, other.FreePages);
@@ -104,62 +104,62 @@ public:
void PrintStat(size_t usedPages, IOutputStream& out) const;
- void* GetBlock(size_t size);
+ void* GetBlock(size_t size);
- void ReturnBlock(void* ptr, size_t size) noexcept;
+ void ReturnBlock(void* ptr, size_t size) noexcept;
- size_t GetPeakAllocated() const noexcept {
+ size_t GetPeakAllocated() const noexcept {
return PeakAllocated;
}
- size_t GetPeakUsed() const noexcept {
+ size_t GetPeakUsed() const noexcept {
return PeakUsed;
}
- ui64 GetAllocCount() const noexcept {
+ ui64 GetAllocCount() const noexcept {
return AllocCount;
}
- ui64 GetPageAllocCount() const noexcept {
+ ui64 GetPageAllocCount() const noexcept {
return PageAllocCount;
}
- ui64 GetPageHitCount() const noexcept {
+ ui64 GetPageHitCount() const noexcept {
return PageHitCount;
}
- ui64 GetPageGlobalHitCount() const noexcept {
+ ui64 GetPageGlobalHitCount() const noexcept {
return PageGlobalHitCount;
}
- ui64 GetPageMissCount() const noexcept {
+ ui64 GetPageMissCount() const noexcept {
return PageMissCount;
}
- ui64 GetOffloadedAllocCount() const noexcept {
+ ui64 GetOffloadedAllocCount() const noexcept {
return OffloadedAllocCount;
}
- ui64 GetOffloadedBytes() const noexcept {
+ ui64 GetOffloadedBytes() const noexcept {
return OffloadedBytes;
}
void OffloadAlloc(ui64 size);
- void OffloadFree(ui64 size) noexcept;
+ void OffloadFree(ui64 size) noexcept;
static ui64 GetGlobalPagePoolSize();
- ui64 GetLimit() const noexcept {
+ ui64 GetLimit() const noexcept {
return Limit;
}
- void SetLimit(size_t limit) noexcept {
+ void SetLimit(size_t limit) noexcept {
Limit = limit;
}
void ReleaseFreePages();
- void DisableStrictAllocationCheck() noexcept {
+ void DisableStrictAllocationCheck() noexcept {
CheckLostMem = false;
}
@@ -178,7 +178,7 @@ public:
protected:
void* Alloc(size_t size);
- void Free(void* ptr, size_t size) noexcept;
+ void Free(void* ptr, size_t size) noexcept;
void UpdatePeaks() {
PeakAllocated = Max(PeakAllocated, GetAllocated());
@@ -189,8 +189,8 @@ protected:
protected:
std::stack<void*, std::vector<void*>> FreePages;
- std::unordered_set<void*> AllPages;
- std::unordered_map<void*, size_t> ActiveBlocks;
+ std::unordered_set<void*> AllPages;
+ std::unordered_map<void*, size_t> ActiveBlocks;
size_t TotalAllocated = 0;
size_t PeakAllocated = 0;
size_t PeakUsed = 0;
diff --git a/ydb/library/yql/minikql/codegen/codegen.cpp b/ydb/library/yql/minikql/codegen/codegen.cpp
index 00c712c23b..6e4096af22 100644
--- a/ydb/library/yql/minikql/codegen/codegen.cpp
+++ b/ydb/library/yql/minikql/codegen/codegen.cpp
@@ -2,8 +2,8 @@
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/MCJIT.h>
-#include <llvm/IR/DiagnosticInfo.h>
-#include <llvm/IR/DiagnosticPrinter.h>
+#include <llvm/IR/DiagnosticInfo.h>
+#include <llvm/IR/DiagnosticPrinter.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
@@ -15,15 +15,15 @@
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/TargetSelect.h>
-#include <llvm/Support/Timer.h>
+#include <llvm/Support/Timer.h>
#include <llvm/Support/ErrorHandling.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
-#include <llvm/Transforms/Instrumentation.h>
+#include <llvm/Transforms/Instrumentation.h>
#include <llvm/Transforms/Instrumentation/AddressSanitizer.h>
#include <llvm/Transforms/Instrumentation/MemorySanitizer.h>
#include <llvm/Transforms/Instrumentation/ThreadSanitizer.h>
-#include <llvm/LinkAllPasses.h>
+#include <llvm/LinkAllPasses.h>
#include <contrib/libs/re2/re2/re2.h>
@@ -108,38 +108,38 @@ typedef union
}s;
} utwords;
-typedef union
-{
- ti_int all;
- struct
- {
- du_int low;
- di_int high;
- }s;
-} twords;
-
-typedef union
-{
- du_int all;
- struct
- {
- su_int low;
- su_int high;
- }s;
-} udwords;
-
-typedef union
-{
- su_int u;
- float f;
-} float_bits;
-
-typedef union
-{
- udwords u;
- double f;
-} double_bits;
-
+typedef union
+{
+ ti_int all;
+ struct
+ {
+ du_int low;
+ di_int high;
+ }s;
+} twords;
+
+typedef union
+{
+ du_int all;
+ struct
+ {
+ su_int low;
+ su_int high;
+ }s;
+} udwords;
+
+typedef union
+{
+ su_int u;
+ float f;
+} float_bits;
+
+typedef union
+{
+ udwords u;
+ double f;
+} double_bits;
+
int __builtin_ctzll(ui64 value) {
DWORD trailing_zero = 0;
if (_BitScanForward64(&trailing_zero, value)) {
@@ -161,16 +161,16 @@ int __builtin_clzll(ui64 value) {
#define __divti3 __divti3impl
#define __udivmodti4 __udivmodti4impl
#define __modti3 __modti3impl
-#define __clzti2 __clzti2impl
-#define __floattisf __floattisfimpl
-#define __floattidf __floattidfimpl
+#define __clzti2 __clzti2impl
+#define __floattisf __floattisfimpl
+#define __floattidf __floattidfimpl
#include <contrib/libs/cxxsupp/builtins/udivmodti4.c>
#include <contrib/libs/cxxsupp/builtins/divti3.c>
#include <contrib/libs/cxxsupp/builtins/modti3.c>
-#include <contrib/libs/cxxsupp/builtins/clzti2.c>
-#include <contrib/libs/cxxsupp/builtins/floattisf.c>
-#include <contrib/libs/cxxsupp/builtins/floattidf.c>
+#include <contrib/libs/cxxsupp/builtins/clzti2.c>
+#include <contrib/libs/cxxsupp/builtins/floattisf.c>
+#include <contrib/libs/cxxsupp/builtins/floattidf.c>
#include <intrin.h>
#include <xmmintrin.h>
@@ -259,26 +259,26 @@ namespace {
class TCodegen : public ICodegen, private llvm::JITEventListener {
public:
- TCodegen(ETarget target, ESanitize sanitize)
- : Target_(target), Sanitize_(sanitize)
- , EffectiveTarget_(Target_), EffectiveSanitize_(Sanitize_)
+ TCodegen(ETarget target, ESanitize sanitize)
+ : Target_(target), Sanitize_(sanitize)
+ , EffectiveTarget_(Target_), EffectiveSanitize_(Sanitize_)
{
Singleton<TCodegenInit>();
Context_.setDiagnosticHandlerCallBack(&DiagnosticHandler, this);
-
+
std::unique_ptr<llvm::Module> module(new llvm::Module("yql", Context_));
- Module_ = module.get();
+ Module_ = module.get();
std::string triple;
- if (EffectiveTarget_ == ETarget::Native && EffectiveSanitize_ == ESanitize::Auto) {
+ if (EffectiveTarget_ == ETarget::Native && EffectiveSanitize_ == ESanitize::Auto) {
#if defined(_asan_enabled_)
- EffectiveSanitize_ = ESanitize::Asan;
-#elif defined(_tsan_enabled_)
- EffectiveSanitize_ = ESanitize::Tsan;
-#elif defined(_msan_enabled_)
- EffectiveSanitize_ = ESanitize::Msan;
-#endif
- }
-
+ EffectiveSanitize_ = ESanitize::Asan;
+#elif defined(_tsan_enabled_)
+ EffectiveSanitize_ = ESanitize::Tsan;
+#elif defined(_msan_enabled_)
+ EffectiveSanitize_ = ESanitize::Msan;
+#endif
+ }
+
if (EffectiveTarget_ == ETarget::CurrentOS || EffectiveTarget_ == ETarget::Native) {
#if defined(_linux_)
EffectiveTarget_ = ETarget::Linux;
@@ -291,7 +291,7 @@ public:
#endif
}
-
+
switch (EffectiveTarget_) {
case ETarget::Linux:
triple = "x86_64-unknown-linux-gnu";
@@ -307,7 +307,7 @@ public:
}
Triple_ = llvm::Triple::normalize(triple);
- Module_->setTargetTriple(Triple_);
+ Module_->setTargetTriple(Triple_);
llvm::TargetOptions targetOptions;
targetOptions.EnableFastISel = true;
@@ -332,7 +332,7 @@ public:
if (!Engine_)
ythrow yexception() << "Failed to construct ExecutionEngine: " << what;
- Module_->setDataLayout(Engine_->getDataLayout().getStringRepresentation());
+ Module_->setDataLayout(Engine_->getDataLayout().getStringRepresentation());
Engine_->RegisterJITEventListener(this);
}
@@ -361,8 +361,8 @@ public:
}
- llvm::Module& GetModule() override {
- return *Module_;
+ llvm::Module& GetModule() override {
+ return *Module_;
}
llvm::ExecutionEngine& GetEngine() override {
@@ -370,10 +370,10 @@ public:
}
void Verify() override {
- std::string what;
- llvm::raw_string_ostream os(what);
- if (llvm::verifyModule(*Module_, &os)) {
- ythrow yexception() << "Verification error: " << what;
+ std::string what;
+ llvm::raw_string_ostream os(what);
+ if (llvm::verifyModule(*Module_, &os)) {
+ ythrow yexception() << "Verification error: " << what;
}
}
@@ -437,10 +437,10 @@ public:
function.addFnAttr("target-features", "+sse,+sse2");
}
- if (dumpTimers) {
- llvm::TimePassesIsEnabled = true;
- }
-
+ if (dumpTimers) {
+ llvm::TimePassesIsEnabled = true;
+ }
+
std::unique_ptr<llvm::legacy::PassManager> modulePassManager;
std::unique_ptr<llvm::legacy::FunctionPassManager> functionPassManager;
@@ -481,14 +481,14 @@ public:
AddThreadSanitizerPass);
}
- functionPassManager = std::make_unique<llvm::legacy::FunctionPassManager>(Module_);
+ functionPassManager = std::make_unique<llvm::legacy::FunctionPassManager>(Module_);
modulePassManager = std::make_unique<llvm::legacy::PassManager>();
passManagerBuilder.populateModulePassManager(*modulePassManager);
passManagerBuilder.populateFunctionPassManager(*functionPassManager);
functionPassManager->doInitialization();
- for (auto it = Module_->begin(), jt = Module_->end(); it != jt; ++it) {
+ for (auto it = Module_->begin(), jt = Module_->end(); it != jt; ++it) {
if (!it->isDeclaration()) {
functionPassManager->run(*it);
}
@@ -496,7 +496,7 @@ public:
functionPassManager->doFinalization();
auto modulePassStart = Now();
- modulePassManager->run(*Module_);
+ modulePassManager->run(*Module_);
if (compileStats) {
compileStats->ModulePassTime = (Now() - modulePassStart).MilliSeconds();
}
@@ -527,10 +527,10 @@ public:
}
std::sort(SortedFuncs_.begin(), SortedFuncs_.end(), CompareFuncOffsets);
- if (dumpTimers) {
- llvm::TimerGroup::printAll(llvm::errs());
- llvm::TimePassesIsEnabled = false;
- }
+ if (dumpTimers) {
+ llvm::TimerGroup::printAll(llvm::errs());
+ llvm::TimePassesIsEnabled = false;
+ }
}
void* GetPointerToFunction(llvm::Function* function) override {
@@ -619,7 +619,7 @@ public:
llvm::SMDiagnostic error;
auto buffer = llvm::MemoryBuffer::getMemBuffer(
llvm::StringRef(bitcode.data(), bitcode.size()));
- std::unique_ptr<llvm::Module> module = llvm::parseIR(buffer->getMemBufferRef(), error, Context_);
+ std::unique_ptr<llvm::Module> module = llvm::parseIR(buffer->getMemBufferRef(), error, Context_);
if (!module) {
std::string what;
@@ -629,12 +629,12 @@ public:
}
module->setTargetTriple(Triple_);
- module->setDataLayout(Engine_->getDataLayout().getStringRepresentation());
+ module->setDataLayout(Engine_->getDataLayout().getStringRepresentation());
if (uniqId) {
module->setModuleIdentifier(llvm::StringRef(uniqId.data(), uniqId.size()));
}
-
- if (llvm::Linker::linkModules(*Module_, std::move(module))) {
+
+ if (llvm::Linker::linkModules(*Module_, std::move(module))) {
TString err;
err.append("LLVM: error linking module");
if (uniqId) {
@@ -644,14 +644,14 @@ public:
err.append(": ").append(Diagnostic_.c_str(), Diagnostic_.size());
}
ythrow yexception() << err;
- }
+ }
if (uniqId) {
LoadedModules_.emplace(uniqId);
}
}
- void AddGlobalMapping(TStringBuf name, const void* address) override {
+ void AddGlobalMapping(TStringBuf name, const void* address) override {
ReverseGlobalMapping_[address] = TString(name);
Engine_->updateGlobalMapping(llvm::StringRef(name.data(), name.size()), (uint64_t)address);
}
@@ -672,16 +672,16 @@ public:
}
private:
- void OnDiagnosticInfo(const llvm::DiagnosticInfo &info) {
- llvm::raw_string_ostream ostream(Diagnostic_);
- llvm::DiagnosticPrinterRawOStream printer(ostream);
- info.print(printer);
- }
-
- static void DiagnosticHandler(const llvm::DiagnosticInfo &info, void* context) {
- return static_cast<TCodegen*>(context)->OnDiagnosticInfo(info);
- }
-
+ void OnDiagnosticInfo(const llvm::DiagnosticInfo &info) {
+ llvm::raw_string_ostream ostream(Diagnostic_);
+ llvm::DiagnosticPrinterRawOStream printer(ostream);
+ info.print(printer);
+ }
+
+ static void DiagnosticHandler(const llvm::DiagnosticInfo &info, void* context) {
+ return static_cast<TCodegen*>(context)->OnDiagnosticInfo(info);
+ }
+
void AllocateTls() {
for (const auto& glob : Module_->globals()) {
auto nameRef = glob.getName();
@@ -722,13 +722,13 @@ private:
}
const ETarget Target_;
- const ESanitize Sanitize_;
+ const ESanitize Sanitize_;
ETarget EffectiveTarget_;
- ESanitize EffectiveSanitize_;
+ ESanitize EffectiveSanitize_;
llvm::LLVMContext Context_;
- std::string Diagnostic_;
+ std::string Diagnostic_;
std::string Triple_;
- llvm::Module* Module_;
+ llvm::Module* Module_;
llvm::JITEventListener* PerfListener_ = nullptr;
std::unique_ptr<llvm::ExecutionEngine> Engine_;
std::vector<std::pair<llvm::object::SectionRef, ui64>> CodeSections_;
@@ -740,9 +740,9 @@ private:
THashSet<TString> LoadedModules_;
};
-ICodegen::TPtr
-ICodegen::Make(ETarget target, ESanitize sanitize) {
- return std::make_unique<TCodegen>(target, sanitize);
+ICodegen::TPtr
+ICodegen::Make(ETarget target, ESanitize sanitize) {
+ return std::make_unique<TCodegen>(target, sanitize);
}
}
diff --git a/ydb/library/yql/minikql/codegen/codegen.h b/ydb/library/yql/minikql/codegen/codegen.h
index 6290ad69f7..41326b6e0f 100644
--- a/ydb/library/yql/minikql/codegen/codegen.h
+++ b/ydb/library/yql/minikql/codegen/codegen.h
@@ -24,13 +24,13 @@ enum class ETarget {
Darwin
};
-enum class ESanitize {
- Auto,
- Asan,
- Msan,
+enum class ESanitize {
+ Auto,
+ Asan,
+ Msan,
Tsan
-};
-
+};
+
struct TCodegenStats {
ui64 TotalFunctions = 0;
ui64 TotalInstructions = 0;
@@ -47,7 +47,7 @@ public:
virtual ~ICodegen() = default;
virtual ETarget GetEffectiveTarget() const = 0;
virtual llvm::LLVMContext& GetContext() = 0;
- virtual llvm::Module& GetModule() = 0;
+ virtual llvm::Module& GetModule() = 0;
virtual llvm::ExecutionEngine& GetEngine() = 0;
virtual void Verify() = 0;
virtual void GetStats(TCodegenStats& stats) = 0;
@@ -57,11 +57,11 @@ public:
virtual ui64 GetFunctionCodeSize(llvm::Function* function) = 0;
virtual void ShowGeneratedFunctions(IOutputStream* out) = 0;
virtual void LoadBitCode(TStringBuf bitcode, TStringBuf uniqId) = 0;
- virtual void AddGlobalMapping(TStringBuf name, const void* address) = 0;
+ virtual void AddGlobalMapping(TStringBuf name, const void* address) = 0;
virtual void TogglePerfJITEventListener() = 0;
-
- typedef std::unique_ptr<ICodegen> TPtr;
- static TPtr Make(ETarget target, ESanitize sanitize = ESanitize::Auto);
+
+ typedef std::unique_ptr<ICodegen> TPtr;
+ static TPtr Make(ETarget target, ESanitize sanitize = ESanitize::Auto);
};
}
diff --git a/ydb/library/yql/minikql/codegen/codegen_ut.cpp b/ydb/library/yql/minikql/codegen/codegen_ut.cpp
index 8907f9589f..332e3fdcdc 100644
--- a/ydb/library/yql/minikql/codegen/codegen_ut.cpp
+++ b/ydb/library/yql/minikql/codegen/codegen_ut.cpp
@@ -13,11 +13,11 @@ using namespace NYql::NCodegen;
using namespace llvm;
extern "C" int mul(int x, int y) {
- return x * y;
-}
-
-extern "C" int sum(int x, int y) {
- return x + y;
+ return x * y;
+}
+
+extern "C" int sum(int x, int y) {
+ return x + y;
}
namespace {
@@ -37,8 +37,8 @@ struct T128 {
};
Function *CreateFibFunction(Module &M, LLVMContext &Context) {
- const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context)}, false);
-
+ const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context)}, false);
+
// Create the fib function and insert it into module M. This function is said
// to return an int and take an int parameter.
Function *FibF = cast<Function>(M.getOrInsertFunction("fib", funcType).getCallee());
@@ -51,7 +51,7 @@ Function *CreateFibFunction(Module &M, LLVMContext &Context) {
Value *Two = ConstantInt::get(Type::getInt32Ty(Context), 2);
// Get pointer to the integer argument of the add1 function...
- auto ArgX = FibF->arg_begin(); // Get the arg.
+ auto ArgX = FibF->arg_begin(); // Get the arg.
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the true_block.
@@ -60,19 +60,19 @@ Function *CreateFibFunction(Module &M, LLVMContext &Context) {
BasicBlock* RecurseBB = BasicBlock::Create(Context, "recurse", FibF);
// Create the "if (arg <= 2) goto exitbb"
- Value *CondInst = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, &*ArgX, Two, "cond", BB);
+ Value *CondInst = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, &*ArgX, Two, "cond", BB);
BranchInst::Create(RetBB, RecurseBB, CondInst, BB);
// Create: ret int 1
ReturnInst::Create(Context, One, RetBB);
// create fib(x-1)
- Value *Sub = BinaryOperator::CreateSub(&*ArgX, One, "arg", RecurseBB);
+ Value *Sub = BinaryOperator::CreateSub(&*ArgX, One, "arg", RecurseBB);
CallInst *CallFibX1 = CallInst::Create(FibF, Sub, "fibx1", RecurseBB);
CallFibX1->setTailCall();
// create fib(x-2)
- Sub = BinaryOperator::CreateSub(&*ArgX, Two, "arg", RecurseBB);
+ Sub = BinaryOperator::CreateSub(&*ArgX, Two, "arg", RecurseBB);
CallInst *CallFibX2 = CallInst::Create(FibF, Sub, "fibx2", RecurseBB);
CallFibX2->setTailCall();
@@ -88,8 +88,8 @@ Function *CreateFibFunction(Module &M, LLVMContext &Context) {
}
Function *CreateBadFibFunction(Module &M, LLVMContext &Context) {
- const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context)}, false);
-
+ const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context)}, false);
+
// Create the fib function and insert it into module M. This function is said
// to return an int and take an int parameter.
Function *FibF = cast<Function>(M.getOrInsertFunction("bad_fib", funcType).getCallee());
@@ -104,20 +104,20 @@ Function *CreateBadFibFunction(Module &M, LLVMContext &Context) {
}
Function *CreateMulFunction(Module &M, LLVMContext &Context) {
- const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
+ const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
Function *MulF = cast<Function>(M.getOrInsertFunction("mul", funcType).getCallee());
-
+
// Add a basic block to the function.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", MulF);
- auto args = MulF->arg_begin();
- auto ArgX = args; // Get the arg 1.
+ auto args = MulF->arg_begin();
+ auto ArgX = args; // Get the arg 1.
ArgX->setName("x");
- auto ArgY = ++args; // Get the arg 2.
+ auto ArgY = ++args; // Get the arg 2.
ArgY->setName("y");
// arg1 * arg2
- Value *Mul = BinaryOperator::CreateMul(&*ArgX, &*ArgY, "res", BB);
+ Value *Mul = BinaryOperator::CreateMul(&*ArgX, &*ArgY, "res", BB);
// Create the return instruction and add it to the basic block
ReturnInst::Create(Context, Mul, BB);
@@ -125,90 +125,90 @@ Function *CreateMulFunction(Module &M, LLVMContext &Context) {
return MulF;
}
-Function *CreateUseNativeFunction(Module &M, LLVMContext &Context) {
- const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
-
+Function *CreateUseNativeFunction(Module &M, LLVMContext &Context) {
+ const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
+
Function *func = cast<Function>(M.getOrInsertFunction("add", funcType).getCallee());
-
- // Add a basic block to the function.
- BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
- auto args = func->arg_begin();
- auto ArgX = args; // Get the arg 1.
- ArgX->setName("x");
- auto ArgY = ++args; // Get the arg 2.
- ArgY->setName("y");
-
- Function* func_mul = M.getFunction("mul");
- if (!func_mul) {
- func_mul = Function::Create(
- /*Type=*/FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false),
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"mul", &M); // (external, no body)
- func_mul->setCallingConv(CallingConv::C);
- }
-
- // arg1 * arg2
- Value *Mul = CallInst::Create(func_mul, {&*ArgX, &*ArgY}, "res", BB);
-
- // Create the return instruction and add it to the basic block
- ReturnInst::Create(Context, Mul, BB);
- return func;
+
+ // Add a basic block to the function.
+ BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
+ auto args = func->arg_begin();
+ auto ArgX = args; // Get the arg 1.
+ ArgX->setName("x");
+ auto ArgY = ++args; // Get the arg 2.
+ ArgY->setName("y");
+
+ Function* func_mul = M.getFunction("mul");
+ if (!func_mul) {
+ func_mul = Function::Create(
+ /*Type=*/FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false),
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"mul", &M); // (external, no body)
+ func_mul->setCallingConv(CallingConv::C);
+ }
+
+ // arg1 * arg2
+ Value *Mul = CallInst::Create(func_mul, {&*ArgX, &*ArgY}, "res", BB);
+
+ // Create the return instruction and add it to the basic block
+ ReturnInst::Create(Context, Mul, BB);
+ return func;
}
-Function *CreateUseExternalFromGeneratedFunction(Module& main, LLVMContext &Context) {
- const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
-
+Function *CreateUseExternalFromGeneratedFunction(Module& main, LLVMContext &Context) {
+ const auto funcType = FunctionType::get(Type::getInt32Ty(Context), {Type::getInt32Ty(Context), Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false);
+
Function *func = cast<Function>(main.getOrInsertFunction("sum_sqr_3", funcType).getCallee());
-
- // Add a basic block to the function.
- BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
- auto args = func->arg_begin();
- auto ArgX = args; // Get the arg 1.
- ArgX->setName("x");
- auto ArgY = ++args; // Get the arg 2.
- ArgY->setName("y");
- auto ArgZ = ++args; // Get the arg 3.
- ArgZ->setName("z");
-
- Function* sum_sqr = main.getFunction("sum_sqr");
-
- Value *tmp = CallInst::Create(sum_sqr, {&*ArgX, &*ArgY}, "tmp", BB);
- Value *res = CallInst::Create(sum_sqr, {&*ArgZ, tmp}, "res", BB);
-
- // Create the return instruction and add it to the basic block
- ReturnInst::Create(Context, res, BB);
- return func;
-}
-
+
+ // Add a basic block to the function.
+ BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
+ auto args = func->arg_begin();
+ auto ArgX = args; // Get the arg 1.
+ ArgX->setName("x");
+ auto ArgY = ++args; // Get the arg 2.
+ ArgY->setName("y");
+ auto ArgZ = ++args; // Get the arg 3.
+ ArgZ->setName("z");
+
+ Function* sum_sqr = main.getFunction("sum_sqr");
+
+ Value *tmp = CallInst::Create(sum_sqr, {&*ArgX, &*ArgY}, "tmp", BB);
+ Value *res = CallInst::Create(sum_sqr, {&*ArgZ, tmp}, "res", BB);
+
+ // Create the return instruction and add it to the basic block
+ ReturnInst::Create(Context, res, BB);
+ return func;
+}
+
Function *CreateUseExternalFromGeneratedFunction128(const ICodegen::TPtr& codegen, bool ir) {
Module& main = codegen->GetModule();
LLVMContext &Context = codegen->GetContext();
auto typeInt128 = Type::getInt128Ty(Context);
auto pointerInt128 = PointerType::getUnqual(typeInt128);
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(typeInt128, {typeInt128, typeInt128, typeInt128}, false):
- FunctionType::get(Type::getVoidTy(Context), {pointerInt128, pointerInt128, pointerInt128, pointerInt128}, false);
-
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(typeInt128, {typeInt128, typeInt128, typeInt128}, false):
+ FunctionType::get(Type::getVoidTy(Context), {pointerInt128, pointerInt128, pointerInt128, pointerInt128}, false);
+
Function *func = cast<Function>(main.getOrInsertFunction("sum_sqr_3", funcType).getCallee());
- auto args = func->arg_begin();
-
- // Add a basic block to the function.
- BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
+ auto args = func->arg_begin();
+
+ // Add a basic block to the function.
+ BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", func);
llvm::Argument* retArg = nullptr;
if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
- retArg = &*args++;
- retArg->addAttr(Attribute::StructRet);
- retArg->addAttr(Attribute::NoAlias);
+ retArg = &*args++;
+ retArg->addAttr(Attribute::StructRet);
+ retArg->addAttr(Attribute::NoAlias);
}
- auto ArgX = args++; // Get the arg 1.
- ArgX->setName("x");
- auto ArgY = args++; // Get the arg 2.
- ArgY->setName("y");
- auto ArgZ = args++; // Get the arg 3.
- ArgZ->setName("z");
-
+ auto ArgX = args++; // Get the arg 1.
+ ArgX->setName("x");
+ auto ArgY = args++; // Get the arg 2.
+ ArgY->setName("y");
+ auto ArgZ = args++; // Get the arg 3.
+ ArgZ->setName("z");
+
const auto type = FunctionType::get(Type::getVoidTy(Context), { pointerInt128, pointerInt128, pointerInt128 }, false);
const auto sum_sqr = main.getOrInsertFunction(ir ? "sum_sqr_128_ir" : "sum_sqr_128", type).getCallee();
@@ -230,7 +230,7 @@ Function *CreateUseExternalFromGeneratedFunction128(const ICodegen::TPtr& codege
new StoreInst(&*ArgX, argXPtr, BB);
new StoreInst(&*ArgY, argYPtr, BB);
new StoreInst(&*ArgZ, argZPtr, BB);
-
+
CallInst::Create(sum_sqr, { &*tmp1, &*argXPtr, &*argYPtr }, "", BB);
CallInst::Create(sum_sqr, { &*tmp2, &*argZPtr, &*tmp1 }, "", BB);
auto res = new LoadInst(tmp2, "load_res", BB);
@@ -238,17 +238,17 @@ Function *CreateUseExternalFromGeneratedFunction128(const ICodegen::TPtr& codege
// Create the return instruction and add it to the basic block
ReturnInst::Create(Context, res, BB);
}
- return func;
-}
-
-}
-
-#if !defined(_ubsan_enabled_) && !defined(HAVE_VALGRIND)
+ return func;
+}
+
+}
+
+#if !defined(_ubsan_enabled_) && !defined(HAVE_VALGRIND)
Y_UNIT_TEST_SUITE(TCodegenTests) {
Y_UNIT_TEST(FibNative) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto func = CreateFibFunction(codegen->GetModule(), codegen->GetContext());
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto func = CreateFibFunction(codegen->GetModule(), codegen->GetContext());
codegen->Verify();
codegen->Compile();
typedef int(*TFunc)(int);
@@ -257,8 +257,8 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
}
Y_UNIT_TEST(FibCurrentOS) {
- auto codegen = ICodegen::Make(ETarget::CurrentOS);
- auto func = CreateFibFunction(codegen->GetModule(), codegen->GetContext());
+ auto codegen = ICodegen::Make(ETarget::CurrentOS);
+ auto func = CreateFibFunction(codegen->GetModule(), codegen->GetContext());
codegen->Verify();
codegen->Compile();
typedef int(*TFunc)(int);
@@ -267,16 +267,16 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
}
Y_UNIT_TEST(BadFib) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto func = CreateBadFibFunction(codegen->GetModule(), codegen->GetContext());
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto func = CreateBadFibFunction(codegen->GetModule(), codegen->GetContext());
UNIT_ASSERT_EXCEPTION(codegen->Verify(), yexception);
}
Y_UNIT_TEST(FibFromBitCode) {
- auto codegen = ICodegen::Make(ETarget::Native);
+ auto codegen = ICodegen::Make(ETarget::Native);
auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = codegen->GetModule().getFunction("fib");
+ auto func = codegen->GetModule().getFunction("fib");
codegen->Verify();
codegen->ExportSymbol(func);
codegen->Compile();
@@ -286,25 +286,25 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
}
Y_UNIT_TEST(LinkWithNativeFunction) {
- auto codegen = ICodegen::Make(ETarget::Native);
+ auto codegen = ICodegen::Make(ETarget::Native);
auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = codegen->GetModule().getFunction("sum_sqr");
- codegen->AddGlobalMapping("mul", (void*)&sum);
+ auto func = codegen->GetModule().getFunction("sum_sqr");
+ codegen->AddGlobalMapping("mul", (void*)&sum);
codegen->ExportSymbol(func);
codegen->Verify();
codegen->Compile();
typedef int(*TFunc)(int, int);
auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- UNIT_ASSERT_VALUES_EQUAL(funcPtr(3, 4), 14);
+ UNIT_ASSERT_VALUES_EQUAL(funcPtr(3, 4), 14);
}
Y_UNIT_TEST(LinkWithGeneratedFunction) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto mulFunc = CreateMulFunction(codegen->GetModule(), codegen->GetContext());
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto mulFunc = CreateMulFunction(codegen->GetModule(), codegen->GetContext());
auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = codegen->GetModule().getFunction("sum_sqr");
+ auto func = codegen->GetModule().getFunction("sum_sqr");
codegen->ExportSymbol(func);
codegen->Verify();
codegen->Compile();
@@ -314,10 +314,10 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
}
Y_UNIT_TEST(ReuseExternalCode) {
- auto codegen = ICodegen::Make(ETarget::Native);
+ auto codegen = ICodegen::Make(ETarget::Native);
auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = codegen->GetModule().getFunction("sum_sqr2");
+ auto func = codegen->GetModule().getFunction("sum_sqr2");
codegen->ExportSymbol(func);
codegen->Verify();
codegen->Compile();
@@ -325,55 +325,55 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
UNIT_ASSERT_VALUES_EQUAL(funcPtr(3, 4), 25);
}
-
+
Y_UNIT_TEST(UseObjectReference) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto bitcode = NResource::Find("/llvm_bc/Funcs");
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = codegen->GetModule().getFunction("str_size");
+ auto func = codegen->GetModule().getFunction("str_size");
codegen->ExportSymbol(func);
- codegen->Verify();
- codegen->Compile();
- typedef size_t(*TFunc)(const std::string&);
- auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- const std::string hw("Hello World!");
- UNIT_ASSERT_VALUES_EQUAL(funcPtr(hw), 12);
- }
-
+ codegen->Verify();
+ codegen->Compile();
+ typedef size_t(*TFunc)(const std::string&);
+ auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
+ const std::string hw("Hello World!");
+ UNIT_ASSERT_VALUES_EQUAL(funcPtr(hw), 12);
+ }
+
Y_UNIT_TEST(UseNativeFromGeneratedFunction) {
- auto codegen = ICodegen::Make(ETarget::Native);
+ auto codegen = ICodegen::Make(ETarget::Native);
auto func = CreateUseNativeFunction(codegen->GetModule(), codegen->GetContext());
codegen->AddGlobalMapping("mul", (void*)&mul);
codegen->ExportSymbol(func);
- codegen->Verify();
- codegen->Compile();
- typedef int(*TFunc)(int, int);
+ codegen->Verify();
+ codegen->Compile();
+ typedef int(*TFunc)(int, int);
auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- UNIT_ASSERT_VALUES_EQUAL(funcPtr(3, 4), 12);
- }
-
+ UNIT_ASSERT_VALUES_EQUAL(funcPtr(3, 4), 12);
+ }
+
Y_UNIT_TEST(UseExternalFromGeneratedFunction) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto bitcode = NResource::Find("/llvm_bc/Funcs");
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
- auto func = CreateUseExternalFromGeneratedFunction(codegen->GetModule(), codegen->GetContext());
+ auto func = CreateUseExternalFromGeneratedFunction(codegen->GetModule(), codegen->GetContext());
codegen->ExportSymbol(func);
codegen->AddGlobalMapping("mul", (void*)&mul);
- codegen->Verify();
- codegen->Compile();
- typedef int(*TFunc)(int, int, int);
- auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- UNIT_ASSERT_VALUES_EQUAL(funcPtr(7, 4, 8), 4289);
- }
-
+ codegen->Verify();
+ codegen->Compile();
+ typedef int(*TFunc)(int, int, int);
+ auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
+ UNIT_ASSERT_VALUES_EQUAL(funcPtr(7, 4, 8), 4289);
+ }
+
Y_UNIT_TEST(UseExternalFromGeneratedFunction_128bit_Compiled) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto bitcode = NResource::Find("/llvm_bc/Funcs");
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
auto func = CreateUseExternalFromGeneratedFunction128(codegen, false);
codegen->ExportSymbol(func);
- codegen->Verify();
- codegen->Compile();
+ codegen->Verify();
+ codegen->Compile();
TStringStream str;
codegen->ShowGeneratedFunctions(&str);
#ifdef _win_
@@ -381,25 +381,25 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
UNIT_ASSERT(funcPtr(T128(7), T128(4), T128(8)) == T128(4289));
#else
- typedef unsigned __int128(*TFunc)(__int128, __int128, __int128);
- auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- UNIT_ASSERT(funcPtr(7, 4, 8) == 4289);
+ typedef unsigned __int128(*TFunc)(__int128, __int128, __int128);
+ auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
+ UNIT_ASSERT(funcPtr(7, 4, 8) == 4289);
#endif
#if !defined(_asan_enabled_) && !defined(_msan_enabled_) && !defined(_tsan_enabled_) && !defined(_hardening_enabled_)
if (str.Str().Contains("call")) {
UNIT_FAIL("Expected inline, disasm:\n" + str.Str());
}
-#endif
- }
-
+#endif
+ }
+
Y_UNIT_TEST(UseExternalFromGeneratedFunction_128bit_Bitcode) {
- auto codegen = ICodegen::Make(ETarget::Native);
- auto bitcode = NResource::Find("/llvm_bc/Funcs");
+ auto codegen = ICodegen::Make(ETarget::Native);
+ auto bitcode = NResource::Find("/llvm_bc/Funcs");
codegen->LoadBitCode(bitcode, "Funcs");
auto func = CreateUseExternalFromGeneratedFunction128(codegen, true);
codegen->ExportSymbol(func);
- codegen->Verify();
- codegen->Compile();
+ codegen->Verify();
+ codegen->Compile();
TStringStream str;
codegen->ShowGeneratedFunctions(&str);
#ifdef _win_
@@ -407,16 +407,16 @@ Y_UNIT_TEST_SUITE(TCodegenTests) {
auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
UNIT_ASSERT(funcPtr(T128(7), T128(4), T128(8)) == T128(4289));
#else
- typedef unsigned __int128(*TFunc)(__int128, __int128, __int128);
- auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
- UNIT_ASSERT(funcPtr(7, 4, 8) == 4289);
+ typedef unsigned __int128(*TFunc)(__int128, __int128, __int128);
+ auto funcPtr = (TFunc)codegen->GetPointerToFunction(func);
+ UNIT_ASSERT(funcPtr(7, 4, 8) == 4289);
#endif
#if !defined(_asan_enabled_) && !defined(_msan_enabled_) && !defined(_tsan_enabled_)
if (str.Str().Contains("call")) {
UNIT_FAIL("Expected inline, disasm:\n" + str.Str());
}
-#endif
- }
+#endif
+ }
}
#endif
diff --git a/ydb/library/yql/minikql/codegen/ut/128_bit.ll b/ydb/library/yql/minikql/codegen/ut/128_bit.ll
index c4656b5da4..d026e84f86 100644
--- a/ydb/library/yql/minikql/codegen/ut/128_bit.ll
+++ b/ydb/library/yql/minikql/codegen/ut/128_bit.ll
@@ -1,8 +1,8 @@
; ModuleID = '128_bit_ir.cpp'
source_filename = "128_bit_ir.cpp"
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
-
+
; Function Attrs: alwaysinline norecurse nounwind uwtable
define void @sum_sqr_128_ir(i128* nocapture, i128* nocapture readonly, i128* nocapture readonly) local_unnamed_addr #0 {
%4 = load i128, i128* %1, align 16, !tbaa !2
@@ -12,8 +12,8 @@ define void @sum_sqr_128_ir(i128* nocapture, i128* nocapture readonly, i128* noc
%8 = add nuw nsw i128 %7, %5
store i128 %8, i128* %0, align 16, !tbaa !2
ret void
-}
-
+}
+
attributes #0 = { alwaysinline norecurse nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
diff --git a/ydb/library/yql/minikql/codegen/ut/str.cpp b/ydb/library/yql/minikql/codegen/ut/str.cpp
index 2be47d9ef7..30e88b8850 100644
--- a/ydb/library/yql/minikql/codegen/ut/str.cpp
+++ b/ydb/library/yql/minikql/codegen/ut/str.cpp
@@ -1,5 +1,5 @@
-#include <string>
-
-extern "C" size_t str_size(const std::string& str) {
- return str.size();
-}
+#include <string>
+
+extern "C" size_t str_size(const std::string& str) {
+ return str.size();
+}
diff --git a/ydb/library/yql/minikql/codegen/ya.make b/ydb/library/yql/minikql/codegen/ya.make
index 647837d434..cdc45b7d26 100644
--- a/ydb/library/yql/minikql/codegen/ya.make
+++ b/ydb/library/yql/minikql/codegen/ya.make
@@ -23,19 +23,19 @@ ENDIF()
PEERDIR(
contrib/libs/re2
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Target/X86/Disassembler
- contrib/libs/llvm12/lib/Transforms/IPO
- contrib/libs/llvm12/lib/Transforms/ObjCARC
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Target/X86/Disassembler
+ contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/Transforms/ObjCARC
)
IF (OS_LINUX)
PEERDIR(
- contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents
+ contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents
)
ENDIF()
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_addmember.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_addmember.cpp
index 21265d3df3..12b0eac013 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_addmember.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_addmember.cpp
@@ -6,163 +6,163 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TAddMemberWrapper : public TMutableCodegeneratorFallbackNode<TAddMemberWrapper> {
- typedef TMutableCodegeneratorFallbackNode<TAddMemberWrapper> TBaseComputation;
+namespace {
+
+class TAddMemberWrapper : public TMutableCodegeneratorFallbackNode<TAddMemberWrapper> {
+ typedef TMutableCodegeneratorFallbackNode<TAddMemberWrapper> TBaseComputation;
public:
TAddMemberWrapper(TComputationMutables& mutables, IComputationNode* structObj, IComputationNode* member, ui32 index,
- std::vector<EValueRepresentation>&& representations)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ std::vector<EValueRepresentation>&& representations)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, StructObj(structObj)
, Member(member)
, Index(index)
- , Representations(std::move(representations))
+ , Representations(std::move(representations))
, Cache(mutables)
- {}
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& baseStruct = StructObj->GetValue(ctx);
-
- NUdf::TUnboxedValue* itemsPtr = nullptr;
- const auto result = Cache.NewArray(ctx, Representations.size() + 1U, itemsPtr);
- if (const auto ptr = baseStruct.GetElements()) {
- for (ui32 i = 0; i < Index; ++i) {
- *itemsPtr++ = ptr[i];
- }
+
+ NUdf::TUnboxedValue* itemsPtr = nullptr;
+ const auto result = Cache.NewArray(ctx, Representations.size() + 1U, itemsPtr);
+ if (const auto ptr = baseStruct.GetElements()) {
+ for (ui32 i = 0; i < Index; ++i) {
+ *itemsPtr++ = ptr[i];
+ }
*itemsPtr++ = Member->GetValue(ctx);
-
- for (ui32 i = Index; i < Representations.size(); ++i) {
- *itemsPtr++ = ptr[i];
- }
- } else {
- for (ui32 i = 0; i < Index; ++i) {
- *itemsPtr++ = baseStruct.GetElement(i);
- }
-
+
+ for (ui32 i = Index; i < Representations.size(); ++i) {
+ *itemsPtr++ = ptr[i];
+ }
+ } else {
+ for (ui32 i = 0; i < Index; ++i) {
+ *itemsPtr++ = baseStruct.GetElement(i);
+ }
+
*itemsPtr++ = Member->GetValue(ctx);
-
- for (ui32 i = Index; i < Representations.size(); ++i) {
- *itemsPtr++ = baseStruct.GetElement(i);
- }
+
+ for (ui32 i = Index; i < Representations.size(); ++i) {
+ *itemsPtr++ = baseStruct.GetElement(i);
+ }
}
- return result;
+ return result;
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- if (Representations.size() > CodegenArraysFallbackLimit)
- return TBaseComputation::DoGenerateGetValue(ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto newSize = Representations.size() + 1U;
-
- const auto valType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valType);
- const auto idxType = Type::getInt32Ty(context);
- const auto type = ArrayType::get(valType, newSize);
- const auto itms = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
- const auto result = Cache.GenNewArray(newSize, itms, ctx, block);
- const auto itemsPtr = new LoadInst(itms, "items", block);
-
- const auto array = GetNodeValue(StructObj, ctx, block);
- const auto zero = ConstantInt::get(idxType, 0);
-
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, ConstantInt::get(idxType, Index)}, "item", block);
- GetNodeValue(itemPtr, Member, ctx, block);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, array, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- for (ui32 i = 0; i < Index; ++i) {
- const auto index = ConstantInt::get(idxType, i);
- const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "dst", block);
- const auto item = new LoadInst(srcPtr, "item", block);
- new StoreInst(item, dstPtr, block);
- ValueAddRef(Representations[i], dstPtr, ctx, block);
- }
-
- for (ui32 i = Index + 1U; i < newSize; ++i) {
- const auto oldIndex = ConstantInt::get(idxType, --i);
- const auto newIndex = ConstantInt::get(idxType, ++i);
- const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "src", block);
- const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "dst", block);
- const auto item = new LoadInst(srcPtr, "item", block);
- new StoreInst(item, dstPtr, block);
- ValueAddRef(Representations[i - 1U], dstPtr, ctx, block);
- }
- BranchInst::Create(done, block);
- }
- {
- block = slow;
- for (ui32 i = 0; i < Index; ++i) {
- const auto index = ConstantInt::get(idxType, i);
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, index);
- }
-
- for (ui32 i = Index + 1U; i < newSize; ++i) {
- const auto oldIndex = ConstantInt::get(idxType, --i);
- const auto newIndex = ConstantInt::get(idxType, ++i);
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, oldIndex);
- }
- BranchInst::Create(done, block);
- }
- block = done;
- if (StructObj->IsTemporaryValue())
- CleanupBoxed(array, ctx, block);
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(StructObj);
- DependsOn(Member);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ if (Representations.size() > CodegenArraysFallbackLimit)
+ return TBaseComputation::DoGenerateGetValue(ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto newSize = Representations.size() + 1U;
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valType);
+ const auto idxType = Type::getInt32Ty(context);
+ const auto type = ArrayType::get(valType, newSize);
+ const auto itms = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
+ const auto result = Cache.GenNewArray(newSize, itms, ctx, block);
+ const auto itemsPtr = new LoadInst(itms, "items", block);
+
+ const auto array = GetNodeValue(StructObj, ctx, block);
+ const auto zero = ConstantInt::get(idxType, 0);
+
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, ConstantInt::get(idxType, Index)}, "item", block);
+ GetNodeValue(itemPtr, Member, ctx, block);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, array, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ for (ui32 i = 0; i < Index; ++i) {
+ const auto index = ConstantInt::get(idxType, i);
+ const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "dst", block);
+ const auto item = new LoadInst(srcPtr, "item", block);
+ new StoreInst(item, dstPtr, block);
+ ValueAddRef(Representations[i], dstPtr, ctx, block);
+ }
+
+ for (ui32 i = Index + 1U; i < newSize; ++i) {
+ const auto oldIndex = ConstantInt::get(idxType, --i);
+ const auto newIndex = ConstantInt::get(idxType, ++i);
+ const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "src", block);
+ const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "dst", block);
+ const auto item = new LoadInst(srcPtr, "item", block);
+ new StoreInst(item, dstPtr, block);
+ ValueAddRef(Representations[i - 1U], dstPtr, ctx, block);
+ }
+ BranchInst::Create(done, block);
+ }
+ {
+ block = slow;
+ for (ui32 i = 0; i < Index; ++i) {
+ const auto index = ConstantInt::get(idxType, i);
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, index);
+ }
+
+ for (ui32 i = Index + 1U; i < newSize; ++i) {
+ const auto oldIndex = ConstantInt::get(idxType, --i);
+ const auto newIndex = ConstantInt::get(idxType, ++i);
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, oldIndex);
+ }
+ BranchInst::Create(done, block);
+ }
+ block = done;
+ if (StructObj->IsTemporaryValue())
+ CleanupBoxed(array, ctx, block);
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(StructObj);
+ DependsOn(Member);
}
IComputationNode* const StructObj;
IComputationNode* const Member;
const ui32 Index;
- const std::vector<EValueRepresentation> Representations;
-
- const TContainerCacheOnContext Cache;
+ const std::vector<EValueRepresentation> Representations;
+
+ const TContainerCacheOnContext Cache;
};
-}
-
+}
+
IComputationNode* WrapAddMember(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
- const auto structType = AS_TYPE(TStructType, callable.GetInput(0));
- const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(2));
+ const auto structType = AS_TYPE(TStructType, callable.GetInput(0));
+ const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(2));
- const ui32 index = indexData->AsValue().Get<ui32>();
+ const ui32 index = indexData->AsValue().Get<ui32>();
MKQL_ENSURE(index <= structType->GetMembersCount(), "Bad member index");
- std::vector<EValueRepresentation> representations;
- representations.reserve(structType->GetMembersCount());
- for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
- representations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
- }
-
- const auto structObj = LocateNode(ctx.NodeLocator, callable, 0);
- const auto member = LocateNode(ctx.NodeLocator, callable, 1);
- return new TAddMemberWrapper(ctx.Mutables, structObj, member, index, std::move(representations));
+ std::vector<EValueRepresentation> representations;
+ representations.reserve(structType->GetMembersCount());
+ for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
+ representations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
+ }
+
+ const auto structObj = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto member = LocateNode(ctx.NodeLocator, callable, 1);
+ return new TAddMemberWrapper(ctx.Mutables, structObj, member, index, std::move(representations));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_aggrcount.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_aggrcount.cpp
index ca14f7a8c3..2c934a95d4 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_aggrcount.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_aggrcount.cpp
@@ -6,53 +6,53 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TAggrCountInitWrapper : public TDecoratorCodegeneratorNode<TAggrCountInitWrapper> {
- typedef TDecoratorCodegeneratorNode<TAggrCountInitWrapper> TBaseComputation;
+namespace {
+
+class TAggrCountInitWrapper : public TDecoratorCodegeneratorNode<TAggrCountInitWrapper> {
+ typedef TDecoratorCodegeneratorNode<TAggrCountInitWrapper> TBaseComputation;
public:
- TAggrCountInitWrapper(IComputationNode* value)
- : TBaseComputation(value)
- {}
+ TAggrCountInitWrapper(IComputationNode* value)
+ : TBaseComputation(value)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
+ return NUdf::TUnboxedValuePod(ui64(value ? 1ULL : 0ULL));
+ }
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
- return NUdf::TUnboxedValuePod(ui64(value ? 1ULL : 0ULL));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
+ const auto check = IsExists(value, block);
+ if (Node->IsTemporaryValue())
+ ValueCleanup(Node->GetRepresentation(), value, ctx, block);
+ return MakeBoolean(check, ctx.Codegen->GetContext(), block);
}
+#endif
+};
+
+class TAggrCountUpdateWrapper : public TDecoratorCodegeneratorNode<TAggrCountUpdateWrapper> {
+ typedef TDecoratorCodegeneratorNode<TAggrCountUpdateWrapper> TBaseComputation;
+public:
+ TAggrCountUpdateWrapper(IComputationNode* state)
+ : TBaseComputation(state)
+ {}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
- const auto check = IsExists(value, block);
- if (Node->IsTemporaryValue())
- ValueCleanup(Node->GetRepresentation(), value, ctx, block);
- return MakeBoolean(check, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-class TAggrCountUpdateWrapper : public TDecoratorCodegeneratorNode<TAggrCountUpdateWrapper> {
- typedef TDecoratorCodegeneratorNode<TAggrCountUpdateWrapper> TBaseComputation;
-public:
- TAggrCountUpdateWrapper(IComputationNode* state)
- : TBaseComputation(state)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
- return NUdf::TUnboxedValuePod(value.Get<ui64>() + 1U);
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
+ return NUdf::TUnboxedValuePod(value.Get<ui64>() + 1U);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*& block) const {
- return BinaryOperator::CreateAdd(value, ConstantInt::get(value->getType(), 1), "incr", block);
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*& block) const {
+ return BinaryOperator::CreateAdd(value, ConstantInt::get(value->getType(), 1), "incr", block);
+ }
+#endif
};
-class TAggrCountIfUpdateWrapper : public TMutableCodegeneratorNode<TAggrCountIfUpdateWrapper> {
- typedef TMutableCodegeneratorNode<TAggrCountIfUpdateWrapper> TBaseComputation;
+class TAggrCountIfUpdateWrapper : public TMutableCodegeneratorNode<TAggrCountIfUpdateWrapper> {
+ typedef TMutableCodegeneratorNode<TAggrCountIfUpdateWrapper> TBaseComputation;
public:
- TAggrCountIfUpdateWrapper(TComputationMutables& mutables, IComputationNode* value, IComputationNode* state)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Arg(value)
+ TAggrCountIfUpdateWrapper(TComputationMutables& mutables, IComputationNode* value, IComputationNode* state)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Arg(value)
, State(state)
{
}
@@ -62,36 +62,36 @@ public:
return Arg->GetValue(compCtx) ? NUdf::TUnboxedValuePod(state.Get<ui64>() + 1U) : state.Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- const auto state = GetNodeValue(State, ctx, block);
- const auto value = GetNodeValue(Arg, ctx, block);
- const auto check = IsExists(value, block);
- if (Arg->IsTemporaryValue())
- ValueCleanup(Arg->GetRepresentation(), value, ctx, block);
- const auto zext = new ZExtInst(check, state->getType(), "zext", block);
- const auto incr = BinaryOperator::CreateAdd(state, zext, "incr", block);
- return incr;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(Arg);
- DependsOn(State);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ const auto state = GetNodeValue(State, ctx, block);
+ const auto value = GetNodeValue(Arg, ctx, block);
+ const auto check = IsExists(value, block);
+ if (Arg->IsTemporaryValue())
+ ValueCleanup(Arg->GetRepresentation(), value, ctx, block);
+ const auto zext = new ZExtInst(check, state->getType(), "zext", block);
+ const auto incr = BinaryOperator::CreateAdd(state, zext, "incr", block);
+ return incr;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Arg);
+ DependsOn(State);
}
- IComputationNode* const Arg;
+ IComputationNode* const Arg;
IComputationNode* const State;
};
-}
-
+}
+
IComputationNode* WrapAggrCountInit(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
if (callable.GetInput(0).GetStaticType()->IsOptional()) {
- return new TAggrCountInitWrapper(LocateNode(ctx.NodeLocator, callable, 0));
+ return new TAggrCountInitWrapper(LocateNode(ctx.NodeLocator, callable, 0));
} else {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(ui64(1ULL)));
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(ui64(1ULL)));
}
}
@@ -99,9 +99,9 @@ IComputationNode* WrapAggrCountUpdate(TCallable& callable, const TComputationNod
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
MKQL_ENSURE(AS_TYPE(TDataType, callable.GetInput(1))->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64 type");
if (callable.GetInput(0).GetStaticType()->IsOptional()) {
- return new TAggrCountIfUpdateWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1));
+ return new TAggrCountIfUpdateWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1));
} else {
- return new TAggrCountUpdateWrapper(LocateNode(ctx.NodeLocator, callable, 1));
+ return new TAggrCountUpdateWrapper(LocateNode(ctx.NodeLocator, callable, 1));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_append.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_append.cpp
index 1708dfe17a..703b82141b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_append.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_append.cpp
@@ -6,119 +6,119 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsVoid>
-class TAppendWrapper : public TMutableCodegeneratorNode<TAppendWrapper<IsVoid>> {
- typedef TMutableCodegeneratorNode<TAppendWrapper<IsVoid>> TBaseComputation;
+namespace {
+
+template<bool IsVoid>
+class TAppendWrapper : public TMutableCodegeneratorNode<TAppendWrapper<IsVoid>> {
+ typedef TMutableCodegeneratorNode<TAppendWrapper<IsVoid>> TBaseComputation;
public:
TAppendWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(mutables, left->GetRepresentation())
+ : TBaseComputation(mutables, left->GetRepresentation())
, Left(left)
, Right(right)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto left = Left->GetValue(ctx);
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto left = Left->GetValue(ctx);
auto right = Right->GetValue(ctx);
- if (IsVoid && !right.IsBoxed())
- return left.Release();
-
- return ctx.HolderFactory.Append(left.Release(), right.Release());
+ if (IsVoid && !right.IsBoxed())
+ return left.Release();
+
+ return ctx.HolderFactory.Append(left.Release(), right.Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Append));
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsVoid) {
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(left->getType(), 2, "result", done);
- result->addIncoming(left, block);
-
- const uint64_t init[] = {0x0ULL, 0x300000000000000ULL};
- const auto mask = ConstantInt::get(right->getType(), APInt(128, 2, init));
- const auto boxed = BinaryOperator::CreateAnd(right, mask, "boxed", block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, boxed, mask, "check", block);
- BranchInst::Create(work, done, check, block);
- block = work;
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(left->getType(), {factory->getType(), left->getType(), right->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
- result->addIncoming(res, block);
- } else {
- const auto retPtr = new AllocaInst(left->getType(), 0U, "ret_ptr", block);
- const auto itemPtr = new AllocaInst(right->getType(), 0U, "item_ptr", block);
- new StoreInst(left, retPtr, block);
- new StoreInst(right, itemPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- result->addIncoming(res, block);
- }
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(left->getType(), {factory->getType(), left->getType(), right->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
- return res;
- } else {
- const auto retPtr = new AllocaInst(left->getType(), 0U, "ret_ptr", block);
- const auto itemPtr = new AllocaInst(right->getType(), 0U, "item_ptr", block);
- new StoreInst(left, retPtr, block);
- new StoreInst(right, itemPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- return res;
- }
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Append));
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsVoid) {
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(left->getType(), 2, "result", done);
+ result->addIncoming(left, block);
+
+ const uint64_t init[] = {0x0ULL, 0x300000000000000ULL};
+ const auto mask = ConstantInt::get(right->getType(), APInt(128, 2, init));
+ const auto boxed = BinaryOperator::CreateAnd(right, mask, "boxed", block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, boxed, mask, "check", block);
+ BranchInst::Create(work, done, check, block);
+ block = work;
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(left->getType(), {factory->getType(), left->getType(), right->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
+ result->addIncoming(res, block);
+ } else {
+ const auto retPtr = new AllocaInst(left->getType(), 0U, "ret_ptr", block);
+ const auto itemPtr = new AllocaInst(right->getType(), 0U, "item_ptr", block);
+ new StoreInst(left, retPtr, block);
+ new StoreInst(right, itemPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ result->addIncoming(res, block);
+ }
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(left->getType(), {factory->getType(), left->getType(), right->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
+ return res;
+ } else {
+ const auto retPtr = new AllocaInst(left->getType(), 0U, "ret_ptr", block);
+ const auto itemPtr = new AllocaInst(right->getType(), 0U, "item_ptr", block);
+ new StoreInst(left, retPtr, block);
+ new StoreInst(right, itemPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ return res;
+ }
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
}
IComputationNode* const Left;
IComputationNode* const Right;
};
-}
-
+}
+
IComputationNode* WrapAppend(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto leftType = AS_TYPE(TListType, callable.GetInput(0));
- const auto rightType = callable.GetInput(1).GetStaticType();
+ const auto leftType = AS_TYPE(TListType, callable.GetInput(0));
+ const auto rightType = callable.GetInput(1).GetStaticType();
- MKQL_ENSURE(leftType->GetItemType()->IsSameType(*rightType), "Mismatch item type");
+ MKQL_ENSURE(leftType->GetItemType()->IsSameType(*rightType), "Mismatch item type");
- const auto left = LocateNode(ctx.NodeLocator, callable, 0);
- const auto right = LocateNode(ctx.NodeLocator, callable, 1);
- if (rightType->IsVoid())
+ const auto left = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto right = LocateNode(ctx.NodeLocator, callable, 1);
+ if (rightType->IsVoid())
return new TAppendWrapper<true>(ctx.Mutables, left, right);
- else
+ else
return new TAppendWrapper<false>(ctx.Mutables, left, right);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_apply.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_apply.cpp
index ae71a81fee..a613c9dcd9 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_apply.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_apply.cpp
@@ -8,110 +8,110 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TApplyWrapper: public TMutableCodegeneratorPtrNode<TApplyWrapper> {
- typedef TMutableCodegeneratorPtrNode<TApplyWrapper> TBaseComputation;
+namespace {
+
+class TApplyWrapper: public TMutableCodegeneratorPtrNode<TApplyWrapper> {
+ typedef TMutableCodegeneratorPtrNode<TApplyWrapper> TBaseComputation;
public:
TApplyWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* callableNode,
TComputationNodePtrVector&& argNodes, ui32 usedArgs, const NUdf::TSourcePosition& pos)
- : TBaseComputation(mutables, kind)
+ : TBaseComputation(mutables, kind)
, CallableNode(callableNode)
, ArgNodes(std::move(argNodes))
, UsedArgs(usedArgs)
, Position(pos)
{
- Stateless = false;
+ Stateless = false;
}
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
NStackArray::TStackArray<NUdf::TUnboxedValue> values(ALLOC_ON_STACK(NUdf::TUnboxedValue, UsedArgs));
- for (size_t i = 0; i < UsedArgs; ++i) {
- if (const auto valueNode = ArgNodes[i]) {
+ for (size_t i = 0; i < UsedArgs; ++i) {
+ if (const auto valueNode = ArgNodes[i]) {
values[i] = valueNode->GetValue(ctx);
}
}
- const auto callable = CallableNode->GetValue(ctx);
- const auto prev = ctx.CalleePosition;
- ctx.CalleePosition = &Position;
- const auto ret = callable.Run(ctx.Builder, values.data());
- ctx.CalleePosition = prev;
+ const auto callable = CallableNode->GetValue(ctx);
+ const auto prev = ctx.CalleePosition;
+ ctx.CalleePosition = &Position;
+ const auto ret = callable.Run(ctx.Builder, values.data());
+ ctx.CalleePosition = prev;
return ret;
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto idxType = Type::getInt32Ty(context);
- const auto valType = Type::getInt128Ty(context);
-
- const auto args = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(ArrayType::get(valType, ArgNodes.size()), 0U, "args", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(ArrayType::get(valType, ArgNodes.size()), 0U, "args", block);
-
- ui32 i = 0;
- std::vector<std::pair<Value*, EValueRepresentation>> argsv;
- argsv.reserve(ArgNodes.size());
- for (const auto node : ArgNodes) {
- const auto argPtr = GetElementPtrInst::CreateInBounds(args, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i++)}, "arg_ptr", block);
- if (node) {
- GetNodeValue(argPtr, node, ctx, block);
- argsv.emplace_back(argPtr, node->GetRepresentation());
- } else {
- new StoreInst(ConstantInt::get(valType, 0), argPtr, block);
- }
- }
-
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto idxType = Type::getInt32Ty(context);
+ const auto valType = Type::getInt128Ty(context);
+
+ const auto args = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(ArrayType::get(valType, ArgNodes.size()), 0U, "args", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(ArrayType::get(valType, ArgNodes.size()), 0U, "args", block);
+
+ ui32 i = 0;
+ std::vector<std::pair<Value*, EValueRepresentation>> argsv;
+ argsv.reserve(ArgNodes.size());
+ for (const auto node : ArgNodes) {
+ const auto argPtr = GetElementPtrInst::CreateInBounds(args, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i++)}, "arg_ptr", block);
+ if (node) {
+ GetNodeValue(argPtr, node, ctx, block);
+ argsv.emplace_back(argPtr, node->GetRepresentation());
+ } else {
+ new StoreInst(ConstantInt::get(valType, 0), argPtr, block);
+ }
+ }
+
if (const auto codegen = dynamic_cast<ICodegeneratorRunNode*>(CallableNode)) {
codegen->CreateRun(ctx, block, pointer, args);
} else {
const auto callable = GetNodeValue(CallableNode, ctx, block);
- const auto calleePtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, 6)}, "callee_ptr", block);
- const auto previous = new LoadInst(calleePtr, "previous", block);
- const auto callee = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), ui64(&Position)), previous->getType(), "callee", block);
- new StoreInst(callee, calleePtr, block);
+ const auto calleePtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, 6)}, "callee_ptr", block);
+ const auto previous = new LoadInst(calleePtr, "previous", block);
+ const auto callee = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), ui64(&Position)), previous->getType(), "callee", block);
+ new StoreInst(callee, calleePtr, block);
CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Run>(pointer, callable, ctx.Codegen, block, ctx.GetBuilder(), args);
- new StoreInst(previous, calleePtr, block);
+ new StoreInst(previous, calleePtr, block);
if (CallableNode->IsTemporaryValue()) {
CleanupBoxed(callable, ctx, block);
}
}
- for (const auto& arg : argsv) {
- ValueUnRef(arg.second, arg.first, ctx, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(CallableNode);
- for (const auto node : ArgNodes) {
+ for (const auto& arg : argsv) {
+ ValueUnRef(arg.second, arg.first, ctx, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(CallableNode);
+ for (const auto node : ArgNodes) {
if (node) {
- DependsOn(node);
+ DependsOn(node);
}
}
}
- IComputationNode *const CallableNode;
- const TComputationNodePtrVector ArgNodes;
+ IComputationNode *const CallableNode;
+ const TComputationNodePtrVector ArgNodes;
const ui32 UsedArgs;
- const NUdf::TSourcePosition Position;
+ const NUdf::TSourcePosition Position;
};
-}
-
+}
+
IComputationNode* WrapApply(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
const bool withPos = callable.GetType()->GetName() == "Apply2";
const ui32 deltaArgs = withPos ? 3 : 0;
MKQL_ENSURE(callable.GetInputsCount() >= 2 + deltaArgs, "Expected at least " << (2 + deltaArgs) << " arguments");
- const auto function = callable.GetInput(0);
+ const auto function = callable.GetInput(0);
MKQL_ENSURE(!function.IsImmediate() && function.GetNode()->GetType()->IsCallable(),
"First argument of Apply must be a callable");
- const auto functionCallable = static_cast<TCallable*>(function.GetNode());
- const auto returnType = functionCallable->GetType()->GetReturnType();
+ const auto functionCallable = static_cast<TCallable*>(function.GetNode());
+ const auto returnType = functionCallable->GetType()->GetReturnType();
MKQL_ENSURE(returnType->IsCallable(), "Expected callable as return type");
const TStringBuf file = withPos ? AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef() : NUdf::TStringRef();
@@ -119,11 +119,11 @@ IComputationNode* WrapApply(TCallable& callable, const TComputationNodeFactoryCo
const ui32 column = withPos ? AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().Get<ui32>() : 0;
const ui32 inputsCount = callable.GetInputsCount() - deltaArgs;
- const ui32 argsCount = inputsCount - 2;
+ const ui32 argsCount = inputsCount - 2;
- const ui32 dependentCount = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
+ const ui32 dependentCount = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
MKQL_ENSURE(dependentCount <= argsCount, "Too many dependent nodes");
- const ui32 usedArgs = argsCount - dependentCount;
+ const ui32 usedArgs = argsCount - dependentCount;
auto callableType = static_cast<TCallableType*>(returnType);
MKQL_ENSURE(usedArgs <= callableType->GetArgumentsCount(), "Too many arguments");
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_callable.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_callable.cpp
index d4f8e55003..06010bd4e5 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_callable.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_callable.cpp
@@ -6,73 +6,73 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TCallableWrapper : public TCustomValueCodegeneratorNode<TCallableWrapper> {
- typedef TCustomValueCodegeneratorNode<TCallableWrapper> TBaseComputation;
-private:
+namespace {
+
+class TCallableWrapper : public TCustomValueCodegeneratorNode<TCallableWrapper> {
+ typedef TCustomValueCodegeneratorNode<TCallableWrapper> TBaseComputation;
+private:
class TValue : public TComputationValue<TValue> {
public:
TValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, IComputationNode* resultNode,
- const TComputationExternalNodePtrVector& argNodes)
+ const TComputationExternalNodePtrVector& argNodes)
: TComputationValue(memInfo)
, CompCtx(compCtx)
, ResultNode(resultNode)
, ArgNodes(argNodes)
{}
- private:
- NUdf::TUnboxedValue Run(const NUdf::IValueBuilder*, const NUdf::TUnboxedValuePod* args) const override
- {
- for (const auto node : ArgNodes) {
+ private:
+ NUdf::TUnboxedValue Run(const NUdf::IValueBuilder*, const NUdf::TUnboxedValuePod* args) const override
+ {
+ for (const auto node : ArgNodes) {
node->SetValue(CompCtx, NUdf::TUnboxedValuePod(*args++));
- }
-
+ }
+
return ResultNode->GetValue(CompCtx);
- }
+ }
TComputationContext& CompCtx;
- IComputationNode *const ResultNode;
- const TComputationExternalNodePtrVector ArgNodes;
+ IComputationNode *const ResultNode;
+ const TComputationExternalNodePtrVector ArgNodes;
};
- class TCodegenValue : public TComputationValue<TCodegenValue> {
- public:
- using TBase = TComputationValue<TCodegenValue>;
-
- using TRunPtr = NUdf::TUnboxedValuePod (*)(TComputationContext*, const NUdf::TUnboxedValuePod*);
-
- TCodegenValue(TMemoryUsageInfo* memInfo, TRunPtr run, TComputationContext* ctx)
- : TBase(memInfo)
- , RunFunc(run)
- , Ctx(ctx)
- {}
-
- private:
- NUdf::TUnboxedValue Run(const NUdf::IValueBuilder*, const NUdf::TUnboxedValuePod* args) const override {
- return RunFunc(Ctx, args);
- }
-
- const TRunPtr RunFunc;
- TComputationContext* const Ctx;
- };
-public:
- TCallableWrapper(TComputationMutables& mutables, IComputationNode* resultNode, TComputationExternalNodePtrVector&& argNodes)
+ class TCodegenValue : public TComputationValue<TCodegenValue> {
+ public:
+ using TBase = TComputationValue<TCodegenValue>;
+
+ using TRunPtr = NUdf::TUnboxedValuePod (*)(TComputationContext*, const NUdf::TUnboxedValuePod*);
+
+ TCodegenValue(TMemoryUsageInfo* memInfo, TRunPtr run, TComputationContext* ctx)
+ : TBase(memInfo)
+ , RunFunc(run)
+ , Ctx(ctx)
+ {}
+
+ private:
+ NUdf::TUnboxedValue Run(const NUdf::IValueBuilder*, const NUdf::TUnboxedValuePod* args) const override {
+ return RunFunc(Ctx, args);
+ }
+
+ const TRunPtr RunFunc;
+ TComputationContext* const Ctx;
+ };
+public:
+ TCallableWrapper(TComputationMutables& mutables, IComputationNode* resultNode, TComputationExternalNodePtrVector&& argNodes)
: TBaseComputation(mutables)
, ResultNode(resultNode)
, ArgNodes(std::move(argNodes))
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Run)
- return ctx.HolderFactory.Create<TCodegenValue>(Run, &ctx);
-#endif
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Run)
+ return ctx.HolderFactory.Create<TCodegenValue>(Run, &ctx);
+#endif
return ctx.HolderFactory.Create<TValue>(ctx, ResultNode, ArgNodes);
}
-private:
+private:
void RegisterDependencies() const final {
for (const auto& arg : ArgNodes) {
Own(arg);
@@ -81,98 +81,98 @@ private:
DependsOn(ResultNode);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- RunFunc = GenerateRun(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ RunFunc = GenerateRun(codegen);
codegen->ExportSymbol(RunFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (RunFunc)
- Run = reinterpret_cast<TRunPtr>(codegen->GetPointerToFunction(RunFunc));
- }
-
- Function* GenerateRun(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Run");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto argsType = ArrayType::get(valueType, ArgNodes.size());
- const auto contextType = GetCompContextType(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(valueType, {PointerType::getUnqual(contextType), PointerType::getUnqual(argsType)}, false):
- FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType), PointerType::getUnqual(argsType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (RunFunc)
+ Run = reinterpret_cast<TRunPtr>(codegen->GetPointerToFunction(RunFunc));
+ }
+
+ Function* GenerateRun(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Run");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto argsType = ArrayType::get(valueType, ArgNodes.size());
+ const auto contextType = GetCompContextType(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(valueType, {PointerType::getUnqual(contextType), PointerType::getUnqual(argsType)}, false):
+ FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType), PointerType::getUnqual(argsType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- const auto resultArg = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? &*args++ : nullptr;
- if (resultArg) {
- resultArg->addAttr(Attribute::StructRet);
- resultArg->addAttr(Attribute::NoAlias);
- }
-
- ctx.Ctx = &*args;
- const auto argsPtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto arguments = new LoadInst(argsPtr, "arguments", block);
-
- unsigned i = 0U;
- for (const auto node : ArgNodes) {
- const auto arg = ExtractValueInst::Create(arguments, {i++}, "arg", block);
- const auto codegenArgNode = dynamic_cast<ICodegeneratorExternalNode*>(node);
+
+ auto args = ctx.Func->arg_begin();
+
+ const auto resultArg = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? &*args++ : nullptr;
+ if (resultArg) {
+ resultArg->addAttr(Attribute::StructRet);
+ resultArg->addAttr(Attribute::NoAlias);
+ }
+
+ ctx.Ctx = &*args;
+ const auto argsPtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto arguments = new LoadInst(argsPtr, "arguments", block);
+
+ unsigned i = 0U;
+ for (const auto node : ArgNodes) {
+ const auto arg = ExtractValueInst::Create(arguments, {i++}, "arg", block);
+ const auto codegenArgNode = dynamic_cast<ICodegeneratorExternalNode*>(node);
MKQL_ENSURE(codegenArgNode, "Argument must be codegenerator node.");
- codegenArgNode->CreateSetValue(ctx, block, arg);
- }
-
- const auto result = GetNodeValue(ResultNode, ctx, block);
-
- if (resultArg) {
- new StoreInst(result, resultArg, block);
- ReturnInst::Create(context, block);
- } else {
- ReturnInst::Create(context, result, block);
- }
- return ctx.Func;
- }
-
- using TRunPtr = TCodegenValue::TRunPtr;
-
- Function* RunFunc = nullptr;
-
- TRunPtr Run = nullptr;
-#endif
-
- IComputationNode *const ResultNode;
- const TComputationExternalNodePtrVector ArgNodes;
+ codegenArgNode->CreateSetValue(ctx, block, arg);
+ }
+
+ const auto result = GetNodeValue(ResultNode, ctx, block);
+
+ if (resultArg) {
+ new StoreInst(result, resultArg, block);
+ ReturnInst::Create(context, block);
+ } else {
+ ReturnInst::Create(context, result, block);
+ }
+ return ctx.Func;
+ }
+
+ using TRunPtr = TCodegenValue::TRunPtr;
+
+ Function* RunFunc = nullptr;
+
+ TRunPtr Run = nullptr;
+#endif
+
+ IComputationNode *const ResultNode;
+ const TComputationExternalNodePtrVector ArgNodes;
};
-}
-
+}
+
IComputationNode* WrapCallable(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected at least one argument");
-
- const auto argsCount = callable.GetInputsCount() - 1U;
- const auto resultNode = LocateNode(ctx.NodeLocator, callable, argsCount);
-
- TComputationExternalNodePtrVector argNodes(argsCount);
- for (ui32 i = 0U; i < argsCount; ++i) {
- const auto listItem = AS_CALLABLE("Arg", callable.GetInput(i));
+ MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected at least one argument");
+
+ const auto argsCount = callable.GetInputsCount() - 1U;
+ const auto resultNode = LocateNode(ctx.NodeLocator, callable, argsCount);
+
+ TComputationExternalNodePtrVector argNodes(argsCount);
+ for (ui32 i = 0U; i < argsCount; ++i) {
+ const auto listItem = AS_CALLABLE("Arg", callable.GetInput(i));
MKQL_ENSURE(listItem->GetType()->GetName() == "Arg", "Wrong Callable arguments");
MKQL_ENSURE(listItem->GetInputsCount() == 0, "Wrong Callable arguments");
MKQL_ENSURE(listItem->GetType()->IsMergeDisabled(), "Merge mode is not disabled");
- argNodes[i] = LocateExternalNode(ctx.NodeLocator, callable, i);
+ argNodes[i] = LocateExternalNode(ctx.NodeLocator, callable, i);
}
return new TCallableWrapper(ctx.Mutables, resultNode, std::move(argNodes));
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.cpp
index bba74ca67a..8f145ae459 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.cpp
@@ -1,4 +1,4 @@
-#include "mkql_chain1_map.h"
+#include "mkql_chain1_map.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_custom_list.h>
@@ -7,143 +7,143 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-struct TComputationNodes {
- IComputationExternalNode* const ItemArg;
- IComputationExternalNode* const StateArg;
- IComputationNode* const InitItem;
- IComputationNode* const InitState;
- IComputationNode* const UpdateItem;
- IComputationNode* const UpdateState;
-};
-
-class TFold1MapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFold1MapFlowWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TFold1MapFlowWrapper> TBaseComputation;
-public:
- TFold1MapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow,
- IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
- IComputationNode* initItem, IComputationNode* initState,
- IComputationNode* updateItem, IComputationNode* updateState)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
- Flow(flow), ComputationNodes({itemArg, stateArg, initItem, initState, updateItem, updateState})
-
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- auto item = Flow->GetValue(ctx);
- if (item.IsSpecial()) {
- return item;
- }
-
- ComputationNodes.ItemArg->SetValue(ctx, std::move(item));
-
- const bool init = state.IsInvalid();
- const auto value = (init ? ComputationNodes.InitItem : ComputationNodes.UpdateItem)->GetValue(ctx);
- ComputationNodes.StateArg->SetValue(ctx, (init ? ComputationNodes.InitState : ComputationNodes.UpdateState)->GetValue(ctx));
-
- if (init) {
- state = NUdf::TUnboxedValuePod(true);
- }
-
- return value;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", done);
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(done, good, IsSpecial(item, block), block);
-
- block = good;
- codegenItemArg->CreateSetValue(ctx, block, item);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- const auto state = new LoadInst(statePtr, "load", block);
- BranchInst::Create(init, next, IsInvalid(state, block), block);
-
- block = init;
- const auto one = GetNodeValue(ComputationNodes.InitItem, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.InitState, ctx, block));
- result->addIncoming(one, block);
- new StoreInst(GetTrue(context), statePtr, block);
- BranchInst::Create(done, block);
-
- block = next;
- const auto two = GetNodeValue(ComputationNodes.UpdateItem, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.UpdateState, ctx, block));
- result->addIncoming(two, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- DependsOn(flow, ComputationNodes.InitItem);
- DependsOn(flow, ComputationNodes.InitState);
- DependsOn(flow, ComputationNodes.UpdateItem);
- DependsOn(flow, ComputationNodes.UpdateState);
- Own(flow, ComputationNodes.ItemArg);
- Own(flow, ComputationNodes.StateArg);
- }
- }
-
- IComputationNode* const Flow;
- const TComputationNodes ComputationNodes;
-};
-
+namespace {
+
+struct TComputationNodes {
+ IComputationExternalNode* const ItemArg;
+ IComputationExternalNode* const StateArg;
+ IComputationNode* const InitItem;
+ IComputationNode* const InitState;
+ IComputationNode* const UpdateItem;
+ IComputationNode* const UpdateState;
+};
+
+class TFold1MapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFold1MapFlowWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TFold1MapFlowWrapper> TBaseComputation;
+public:
+ TFold1MapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow,
+ IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
+ IComputationNode* initItem, IComputationNode* initState,
+ IComputationNode* updateItem, IComputationNode* updateState)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
+ Flow(flow), ComputationNodes({itemArg, stateArg, initItem, initState, updateItem, updateState})
+
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ auto item = Flow->GetValue(ctx);
+ if (item.IsSpecial()) {
+ return item;
+ }
+
+ ComputationNodes.ItemArg->SetValue(ctx, std::move(item));
+
+ const bool init = state.IsInvalid();
+ const auto value = (init ? ComputationNodes.InitItem : ComputationNodes.UpdateItem)->GetValue(ctx);
+ ComputationNodes.StateArg->SetValue(ctx, (init ? ComputationNodes.InitState : ComputationNodes.UpdateState)->GetValue(ctx));
+
+ if (init) {
+ state = NUdf::TUnboxedValuePod(true);
+ }
+
+ return value;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", done);
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(done, good, IsSpecial(item, block), block);
+
+ block = good;
+ codegenItemArg->CreateSetValue(ctx, block, item);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ const auto state = new LoadInst(statePtr, "load", block);
+ BranchInst::Create(init, next, IsInvalid(state, block), block);
+
+ block = init;
+ const auto one = GetNodeValue(ComputationNodes.InitItem, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.InitState, ctx, block));
+ result->addIncoming(one, block);
+ new StoreInst(GetTrue(context), statePtr, block);
+ BranchInst::Create(done, block);
+
+ block = next;
+ const auto two = GetNodeValue(ComputationNodes.UpdateItem, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.UpdateState, ctx, block));
+ result->addIncoming(two, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ DependsOn(flow, ComputationNodes.InitItem);
+ DependsOn(flow, ComputationNodes.InitState);
+ DependsOn(flow, ComputationNodes.UpdateItem);
+ DependsOn(flow, ComputationNodes.UpdateState);
+ Own(flow, ComputationNodes.ItemArg);
+ Own(flow, ComputationNodes.StateArg);
+ }
+ }
+
+ IComputationNode* const Flow;
+ const TComputationNodes ComputationNodes;
+};
+
template <bool IsStream>
-class TBaseChain1MapWrapper {
+class TBaseChain1MapWrapper {
public:
class TListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, const TComputationNodes& computationNodes)
- : TComputationValue<TIterator>(memInfo)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
+ , Iter(std::move(iter))
, ComputationNodes(computationNodes)
{}
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- if (!Iter.Next(ComputationNodes.ItemArg->RefValue(CompCtx))) {
- return false;
- }
-
- ++Length;
-
- auto itemNode = Length == 1 ? ComputationNodes.InitItem : ComputationNodes.UpdateItem;
- auto stateNode = Length == 1 ? ComputationNodes.InitState : ComputationNodes.UpdateState;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ if (!Iter.Next(ComputationNodes.ItemArg->RefValue(CompCtx))) {
+ return false;
+ }
+
+ ++Length;
+
+ auto itemNode = Length == 1 ? ComputationNodes.InitItem : ComputationNodes.UpdateItem;
+ auto stateNode = Length == 1 ? ComputationNodes.InitState : ComputationNodes.UpdateState;
value = itemNode->GetValue(CompCtx);
ComputationNodes.StateArg->SetValue(CompCtx, stateNode->GetValue(CompCtx));
- return true;
- }
-
+ return true;
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue Iter;
+ const TComputationNodes& ComputationNodes;
ui64 Length = 0;
};
@@ -154,30 +154,30 @@ public:
, ComputationNodes(computationNodes)
{}
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), ComputationNodes);
- }
-
- ui64 GetListLength() const final {
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), ComputationNodes);
+ }
+
+ ui64 GetListLength() const final {
if (!Length) {
Length = List.GetListLength();
}
- return *Length;
+ return *Length;
}
- bool HasListItems() const final {
+ bool HasListItems() const final {
if (!HasItems) {
HasItems = List.HasListItems();
}
return *HasItems;
}
-
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue List;
+ const TComputationNodes& ComputationNodes;
};
class TStreamValue : public TComputationValue<TStreamValue> {
@@ -191,9 +191,9 @@ public:
, ComputationNodes(computationNodes)
{}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value) final {
- const auto status = List.Fetch(ComputationNodes.ItemArg->RefValue(CompCtx));
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value) final {
+ const auto status = List.Fetch(ComputationNodes.ItemArg->RefValue(CompCtx));
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -208,342 +208,342 @@ public:
}
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue List;
+ const TComputationNodes& ComputationNodes;
ui64 Length = 0;
};
- TBaseChain1MapWrapper(IComputationNode* list, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
+ TBaseChain1MapWrapper(IComputationNode* list, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
IComputationNode* initItem, IComputationNode* initState,
IComputationNode* updateItem, IComputationNode* updateState)
- : List(list), ComputationNodes({itemArg, stateArg, initItem, initState, updateItem, updateState})
+ : List(list), ComputationNodes({itemArg, stateArg, initItem, initState, updateItem, updateState})
{}
-#ifndef MKQL_DISABLE_CODEGEN
- template<bool IsFirst>
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto newItem = IsFirst ? ComputationNodes.InitItem : ComputationNodes.UpdateItem;
- const auto newState = IsFirst ? ComputationNodes.InitState : ComputationNodes.UpdateState;
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ template<bool IsFirst>
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto newItem = IsFirst ? ComputationNodes.InitItem : ComputationNodes.UpdateItem;
+ const auto newState = IsFirst ? ComputationNodes.InitState : ComputationNodes.UpdateState;
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
-
- BranchInst::Create(done, good, icmp, block);
- block = good;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, newItem, ctx, block);
-
- const auto nextState = GetNodeValue(newState, ctx, block);
-
- codegenStateArg->CreateSetValue(ctx, block, nextState);
-
- BranchInst::Create(done, block);
- block = done;
-
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TChainMapPtr = std::conditional_t<IsStream, TStreamCodegenValueOne::TFetchPtr, TListCodegenValueOne::TNextPtr>;
-
- Function* MapFuncOne = nullptr;
- Function* MapFuncTwo = nullptr;
-
- TChainMapPtr MapOne = nullptr;
- TChainMapPtr MapTwo = nullptr;
-#endif
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
+
+ BranchInst::Create(done, good, icmp, block);
+ block = good;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, newItem, ctx, block);
+
+ const auto nextState = GetNodeValue(newState, ctx, block);
+
+ codegenStateArg->CreateSetValue(ctx, block, nextState);
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TChainMapPtr = std::conditional_t<IsStream, TStreamCodegenValueOne::TFetchPtr, TListCodegenValueOne::TNextPtr>;
+
+ Function* MapFuncOne = nullptr;
+ Function* MapFuncTwo = nullptr;
+
+ TChainMapPtr MapOne = nullptr;
+ TChainMapPtr MapTwo = nullptr;
+#endif
+
IComputationNode* const List;
- const TComputationNodes ComputationNodes;
+ const TComputationNodes ComputationNodes;
};
-class TStreamChain1MapWrapper : public TCustomValueCodegeneratorNode<TStreamChain1MapWrapper>, private TBaseChain1MapWrapper<true> {
- typedef TCustomValueCodegeneratorNode<TStreamChain1MapWrapper> TBaseComputation;
- typedef TBaseChain1MapWrapper<true> TBaseWrapper;
-public:
- TStreamChain1MapWrapper(TComputationMutables& mutables, IComputationNode* list,
- IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
- IComputationNode* initItem, IComputationNode* initState,
- IComputationNode* updateItem, IComputationNode* updateState
- ) : TBaseComputation(mutables), TBaseWrapper(list, itemArg, stateArg, initItem, initState, updateItem, updateState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && MapOne && MapTwo)
- return ctx.HolderFactory.Create<TStreamCodegenValueOne>(MapOne, MapTwo, &ctx, List->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), ComputationNodes);
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(ComputationNodes.InitItem);
- DependsOn(ComputationNodes.InitState);
- DependsOn(ComputationNodes.UpdateItem);
- DependsOn(ComputationNodes.UpdateState);
- Own(ComputationNodes.ItemArg);
- Own(ComputationNodes.StateArg);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- MapFuncOne = GenerateMapper<true>(codegen, TBaseComputation::MakeName("Fetch_One"));
- MapFuncTwo = GenerateMapper<false>(codegen, TBaseComputation::MakeName("Fetch_Two"));
- codegen->ExportSymbol(MapFuncOne);
- codegen->ExportSymbol(MapFuncTwo);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (MapFuncOne)
- MapOne = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncOne));
- if (MapFuncTwo)
- MapTwo = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncTwo));
- }
-#endif
-};
-
-class TListChain1MapWrapper : public TBothWaysCodegeneratorNode<TListChain1MapWrapper>, private TBaseChain1MapWrapper<false> {
- typedef TBothWaysCodegeneratorNode<TListChain1MapWrapper> TBaseComputation;
- typedef TBaseChain1MapWrapper<false> TBaseWrapper;
-public:
- TListChain1MapWrapper(TComputationMutables& mutables, IComputationNode* list,
- IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
- IComputationNode* initItem, IComputationNode* initState,
- IComputationNode* updateItem, IComputationNode* updateState
- ) : TBaseComputation(mutables), TBaseWrapper(list, itemArg, stateArg, initItem, initState, updateItem, updateState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- auto size = list.GetListLength();
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
- if (size) {
- ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
- *items++ = ComputationNodes.InitItem->GetValue(ctx);
- ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.InitState->GetValue(ctx));
- while (--size) {
- ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
- *items++ = ComputationNodes.UpdateItem->GetValue(ctx);
- ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.UpdateState->GetValue(ctx));
- }
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), ComputationNodes);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<TListCodegenValueOne>(MapOne, MapTwo, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto map = PHINode::Create(list->getType(), 3U, "map", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, size, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0), "good", block);
- map->addIncoming(array, block);
-
- BranchInst::Create(init, done, good, block);
-
- block = init;
- const auto head = new LoadInst(elements, "head", block);
- codegenItemArg->CreateSetValue(ctx, block, head);
- GetNodeValue(items, ComputationNodes.InitItem, ctx, block);
- const auto state = GetNodeValue(ComputationNodes.InitState, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, state);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- index->addIncoming(ConstantInt::get(size->getType(), 1), block);
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
- BranchInst::Create(next, stop, more, block);
-
- block = next;
- const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto item = new LoadInst(src, "item", block);
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
- GetNodeValue(dst, ComputationNodes.UpdateItem, ctx, block);
- const auto newState = GetNodeValue(ComputationNodes.UpdateState, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, newState);
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
- index->addIncoming(plus, block);
- BranchInst::Create(loop, block);
-
- block = stop;
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- map->addIncoming(array, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListChain1MapWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- map->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- map->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return map;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(ComputationNodes.InitItem);
- DependsOn(ComputationNodes.InitState);
- DependsOn(ComputationNodes.UpdateItem);
- DependsOn(ComputationNodes.UpdateState);
- Own(ComputationNodes.ItemArg);
- Own(ComputationNodes.StateArg);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListChain1MapWrapper>::GenerateFunctions(codegen);
- MapFuncOne = GenerateMapper<true>(codegen, TBaseComputation::MakeName("Next_One"));
- MapFuncTwo = GenerateMapper<false>(codegen, TBaseComputation::MakeName("Next_Two"));
- codegen->ExportSymbol(MapFuncOne);
- codegen->ExportSymbol(MapFuncTwo);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListChain1MapWrapper>::FinalizeFunctions(codegen);
- if (MapFuncOne)
- MapOne = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncOne));
- if (MapFuncTwo)
- MapTwo = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncTwo));
- }
-#endif
-};
-
-}
-
-IComputationNode* WrapChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 7, "Expected 7 args");
- const auto type = callable.GetType()->GetReturnType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initItem = LocateNode(ctx.NodeLocator, callable, 2);
- const auto initState = LocateNode(ctx.NodeLocator, callable, 3);
- const auto updateItem = LocateNode(ctx.NodeLocator, callable, 5);
- const auto updateState = LocateNode(ctx.NodeLocator, callable, 6);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto stateArg = LocateExternalNode(ctx.NodeLocator, callable, 4);
- if (type->IsFlow()) {
- return new TFold1MapFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
- } else if (type->IsStream()) {
- return new TStreamChain1MapWrapper(ctx.Mutables, flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
- } else if (type->IsList()) {
- return new TListChain1MapWrapper(ctx.Mutables, flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
- }
-
- THROW yexception() << "Expected flow, list or stream.";
+class TStreamChain1MapWrapper : public TCustomValueCodegeneratorNode<TStreamChain1MapWrapper>, private TBaseChain1MapWrapper<true> {
+ typedef TCustomValueCodegeneratorNode<TStreamChain1MapWrapper> TBaseComputation;
+ typedef TBaseChain1MapWrapper<true> TBaseWrapper;
+public:
+ TStreamChain1MapWrapper(TComputationMutables& mutables, IComputationNode* list,
+ IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
+ IComputationNode* initItem, IComputationNode* initState,
+ IComputationNode* updateItem, IComputationNode* updateState
+ ) : TBaseComputation(mutables), TBaseWrapper(list, itemArg, stateArg, initItem, initState, updateItem, updateState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && MapOne && MapTwo)
+ return ctx.HolderFactory.Create<TStreamCodegenValueOne>(MapOne, MapTwo, &ctx, List->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), ComputationNodes);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(ComputationNodes.InitItem);
+ DependsOn(ComputationNodes.InitState);
+ DependsOn(ComputationNodes.UpdateItem);
+ DependsOn(ComputationNodes.UpdateState);
+ Own(ComputationNodes.ItemArg);
+ Own(ComputationNodes.StateArg);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ MapFuncOne = GenerateMapper<true>(codegen, TBaseComputation::MakeName("Fetch_One"));
+ MapFuncTwo = GenerateMapper<false>(codegen, TBaseComputation::MakeName("Fetch_Two"));
+ codegen->ExportSymbol(MapFuncOne);
+ codegen->ExportSymbol(MapFuncTwo);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (MapFuncOne)
+ MapOne = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncOne));
+ if (MapFuncTwo)
+ MapTwo = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncTwo));
+ }
+#endif
+};
+
+class TListChain1MapWrapper : public TBothWaysCodegeneratorNode<TListChain1MapWrapper>, private TBaseChain1MapWrapper<false> {
+ typedef TBothWaysCodegeneratorNode<TListChain1MapWrapper> TBaseComputation;
+ typedef TBaseChain1MapWrapper<false> TBaseWrapper;
+public:
+ TListChain1MapWrapper(TComputationMutables& mutables, IComputationNode* list,
+ IComputationExternalNode* itemArg, IComputationExternalNode* stateArg,
+ IComputationNode* initItem, IComputationNode* initState,
+ IComputationNode* updateItem, IComputationNode* updateState
+ ) : TBaseComputation(mutables), TBaseWrapper(list, itemArg, stateArg, initItem, initState, updateItem, updateState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ auto size = list.GetListLength();
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
+ if (size) {
+ ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
+ *items++ = ComputationNodes.InitItem->GetValue(ctx);
+ ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.InitState->GetValue(ctx));
+ while (--size) {
+ ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
+ *items++ = ComputationNodes.UpdateItem->GetValue(ctx);
+ ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.UpdateState->GetValue(ctx));
+ }
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), ComputationNodes);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<TListCodegenValueOne>(MapOne, MapTwo, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto map = PHINode::Create(list->getType(), 3U, "map", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, size, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0), "good", block);
+ map->addIncoming(array, block);
+
+ BranchInst::Create(init, done, good, block);
+
+ block = init;
+ const auto head = new LoadInst(elements, "head", block);
+ codegenItemArg->CreateSetValue(ctx, block, head);
+ GetNodeValue(items, ComputationNodes.InitItem, ctx, block);
+ const auto state = GetNodeValue(ComputationNodes.InitState, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, state);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ index->addIncoming(ConstantInt::get(size->getType(), 1), block);
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
+ BranchInst::Create(next, stop, more, block);
+
+ block = next;
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto item = new LoadInst(src, "item", block);
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
+ GetNodeValue(dst, ComputationNodes.UpdateItem, ctx, block);
+ const auto newState = GetNodeValue(ComputationNodes.UpdateState, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, newState);
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ map->addIncoming(array, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListChain1MapWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ map->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ map->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return map;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(ComputationNodes.InitItem);
+ DependsOn(ComputationNodes.InitState);
+ DependsOn(ComputationNodes.UpdateItem);
+ DependsOn(ComputationNodes.UpdateState);
+ Own(ComputationNodes.ItemArg);
+ Own(ComputationNodes.StateArg);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListChain1MapWrapper>::GenerateFunctions(codegen);
+ MapFuncOne = GenerateMapper<true>(codegen, TBaseComputation::MakeName("Next_One"));
+ MapFuncTwo = GenerateMapper<false>(codegen, TBaseComputation::MakeName("Next_Two"));
+ codegen->ExportSymbol(MapFuncOne);
+ codegen->ExportSymbol(MapFuncTwo);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListChain1MapWrapper>::FinalizeFunctions(codegen);
+ if (MapFuncOne)
+ MapOne = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncOne));
+ if (MapFuncTwo)
+ MapTwo = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(MapFuncTwo));
+ }
+#endif
+};
+
+}
+
+IComputationNode* WrapChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 7, "Expected 7 args");
+ const auto type = callable.GetType()->GetReturnType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initItem = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto initState = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto updateItem = LocateNode(ctx.NodeLocator, callable, 5);
+ const auto updateState = LocateNode(ctx.NodeLocator, callable, 6);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto stateArg = LocateExternalNode(ctx.NodeLocator, callable, 4);
+ if (type->IsFlow()) {
+ return new TFold1MapFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
+ } else if (type->IsStream()) {
+ return new TStreamChain1MapWrapper(ctx.Mutables, flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
+ } else if (type->IsList()) {
+ return new TListChain1MapWrapper(ctx.Mutables, flow, itemArg, stateArg, initItem, initState, updateItem, updateState);
+ }
+
+ THROW yexception() << "Expected flow, list or stream.";
+}
+
}
-
}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.h b/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.h
index d2ad9575f1..13a6f739de 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chain1_map.h
@@ -4,7 +4,7 @@
namespace NKikimr {
namespace NMiniKQL {
-IComputationNode* WrapChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.cpp
index 1b9c343e44..138944888a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.cpp
@@ -1,4 +1,4 @@
-#include "mkql_chain_map.h"
+#include "mkql_chain_map.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_custom_list.h>
@@ -7,195 +7,195 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-struct TComputationNodes {
- IComputationExternalNode* const ItemArg;
- IComputationExternalNode* const StateArg;
- IComputationNode* const NewItem;
- IComputationNode* const NewState;
-};
-
-class TFoldMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFoldMapFlowWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TFoldMapFlowWrapper> TBaseComputation;
-public:
- TFoldMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* initialState, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
- Flow(flow), Init(initialState), ComputationNodes({itemArg, stateArg, newItem, newState})
-
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- ComputationNodes.StateArg->SetValue(ctx, Init->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(true);
- }
-
- auto item = Flow->GetValue(ctx);
- if (item.IsSpecial()) {
- return item;
- }
-
- ComputationNodes.ItemArg->SetValue(ctx, std::move(item));
- const auto value = ComputationNodes.NewItem->GetValue(ctx);
- ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.NewState->GetValue(ctx));
- return value;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- const auto state = new LoadInst(statePtr, "load", block);
- BranchInst::Create(init, work, IsInvalid(state, block), block);
-
- block = init;
- new StoreInst(GetTrue(context), statePtr, block);
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(Init, ctx, block));
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(done, good, IsSpecial(item, block), block);
-
- block = good;
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto value = GetNodeValue(ComputationNodes.NewItem, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.NewState, ctx, block));
- result->addIncoming(value, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- DependsOn(flow, Init);
- DependsOn(flow, ComputationNodes.NewItem);
- DependsOn(flow, ComputationNodes.NewState);
- Own(flow, ComputationNodes.ItemArg);
- Own(flow, ComputationNodes.StateArg);
- }
- }
-
- IComputationNode* const Flow;
- IComputationNode* const Init;
- const TComputationNodes ComputationNodes;
-};
-
+namespace {
+
+struct TComputationNodes {
+ IComputationExternalNode* const ItemArg;
+ IComputationExternalNode* const StateArg;
+ IComputationNode* const NewItem;
+ IComputationNode* const NewState;
+};
+
+class TFoldMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFoldMapFlowWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TFoldMapFlowWrapper> TBaseComputation;
+public:
+ TFoldMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* initialState, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
+ Flow(flow), Init(initialState), ComputationNodes({itemArg, stateArg, newItem, newState})
+
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ ComputationNodes.StateArg->SetValue(ctx, Init->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(true);
+ }
+
+ auto item = Flow->GetValue(ctx);
+ if (item.IsSpecial()) {
+ return item;
+ }
+
+ ComputationNodes.ItemArg->SetValue(ctx, std::move(item));
+ const auto value = ComputationNodes.NewItem->GetValue(ctx);
+ ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.NewState->GetValue(ctx));
+ return value;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ const auto state = new LoadInst(statePtr, "load", block);
+ BranchInst::Create(init, work, IsInvalid(state, block), block);
+
+ block = init;
+ new StoreInst(GetTrue(context), statePtr, block);
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(Init, ctx, block));
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(done, good, IsSpecial(item, block), block);
+
+ block = good;
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto value = GetNodeValue(ComputationNodes.NewItem, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(ComputationNodes.NewState, ctx, block));
+ result->addIncoming(value, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ DependsOn(flow, Init);
+ DependsOn(flow, ComputationNodes.NewItem);
+ DependsOn(flow, ComputationNodes.NewState);
+ Own(flow, ComputationNodes.ItemArg);
+ Own(flow, ComputationNodes.StateArg);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationNode* const Init;
+ const TComputationNodes ComputationNodes;
+};
+
template <bool IsStream>
-class TBaseChainMapWrapper {
+class TBaseChainMapWrapper {
public:
class TListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, const NUdf::TUnboxedValue& init, const TComputationNodes& computationNodes)
- : TComputationValue<TIterator>(memInfo)
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, const NUdf::TUnboxedValue& init, const TComputationNodes& computationNodes)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , ComputationNodes(computationNodes)
- , Iter(std::move(iter))
- , Init(init)
+ , ComputationNodes(computationNodes)
+ , Iter(std::move(iter))
+ , Init(init)
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- if (!Init.IsInvalid()) {
- ComputationNodes.StateArg->SetValue(CompCtx, std::move(Init));
- Init = NUdf::TUnboxedValue::Invalid();
- }
-
- if (!Iter.Next(ComputationNodes.ItemArg->RefValue(CompCtx))) {
- return false;
- }
-
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ if (!Init.IsInvalid()) {
+ ComputationNodes.StateArg->SetValue(CompCtx, std::move(Init));
+ Init = NUdf::TUnboxedValue::Invalid();
+ }
+
+ if (!Iter.Next(ComputationNodes.ItemArg->RefValue(CompCtx))) {
+ return false;
+ }
+
value = ComputationNodes.NewItem->GetValue(CompCtx);
ComputationNodes.StateArg->SetValue(CompCtx, ComputationNodes.NewState->GetValue(CompCtx));
- return true;
- }
-
+ return true;
+ }
+
TComputationContext& CompCtx;
- const TComputationNodes& ComputationNodes;
- const NUdf::TUnboxedValue Iter;
- NUdf::TUnboxedValue Init;
+ const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue Iter;
+ NUdf::TUnboxedValue Init;
};
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, NUdf::TUnboxedValue&& init, const TComputationNodes& computationNodes)
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, NUdf::TUnboxedValue&& init, const TComputationNodes& computationNodes)
: TCustomListValue(memInfo)
, CompCtx(compCtx)
, List(std::move(list))
- , Init(std::move(init))
+ , Init(std::move(init))
, ComputationNodes(computationNodes)
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Init, ComputationNodes);
- }
-
- ui64 GetListLength() const final {
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Init, ComputationNodes);
+ }
+
+ ui64 GetListLength() const final {
if (!Length) {
Length = List.GetListLength();
}
- return *Length;
+ return *Length;
}
- bool HasListItems() const final {
+ bool HasListItems() const final {
if (!HasItems) {
HasItems = List.HasListItems();
}
return *HasItems;
}
-
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- const NUdf::TUnboxedValue Init;
- const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue List;
+ const NUdf::TUnboxedValue Init;
+ const TComputationNodes& ComputationNodes;
};
class TStreamValue : public TComputationValue<TStreamValue> {
public:
using TBase = TComputationValue<TStreamValue>;
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, NUdf::TUnboxedValue&& init, const TComputationNodes& computationNodes)
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, NUdf::TUnboxedValue&& init, const TComputationNodes& computationNodes)
: TBase(memInfo)
, CompCtx(compCtx)
- , ComputationNodes(computationNodes)
+ , ComputationNodes(computationNodes)
, List(std::move(list))
- , Init(std::move(init))
- {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value) final {
- if (!Init.IsInvalid()) {
- ComputationNodes.StateArg->SetValue(CompCtx, std::move(Init));
- Init = NUdf::TUnboxedValuePod::Invalid();
- }
-
- const auto status = List.Fetch(ComputationNodes.ItemArg->RefValue(CompCtx));
+ , Init(std::move(init))
+ {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value) final {
+ if (!Init.IsInvalid()) {
+ ComputationNodes.StateArg->SetValue(CompCtx, std::move(Init));
+ Init = NUdf::TUnboxedValuePod::Invalid();
+ }
+
+ const auto status = List.Fetch(ComputationNodes.ItemArg->RefValue(CompCtx));
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -206,323 +206,323 @@ public:
}
TComputationContext& CompCtx;
- const TComputationNodes& ComputationNodes;
- const NUdf::TUnboxedValue List;
- NUdf::TUnboxedValue Init;
+ const TComputationNodes& ComputationNodes;
+ const NUdf::TUnboxedValue List;
+ NUdf::TUnboxedValue Init;
};
- TBaseChainMapWrapper(IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
- : List(list), Init(init), ComputationNodes({itemArg, stateArg, newItem, newState})
+ TBaseChainMapWrapper(IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
+ : List(list), Init(init), ComputationNodes({itemArg, stateArg, newItem, newState})
{}
-#ifndef MKQL_DISABLE_CODEGEN
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto initArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- const auto load = new LoadInst(initArg, "load", block);
- BranchInst::Create(work, init, IsInvalid(load, block), block);
- block = init;
-
- codegenStateArg->CreateSetValue(ctx, block, initArg);
- new StoreInst(GetInvalid(context), initArg, block);
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
-
- BranchInst::Create(done, good, icmp, block);
- block = good;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, ComputationNodes.NewItem, ctx, block);
-
- const auto newState = GetNodeValue(ComputationNodes.NewState, ctx, block);
-
- codegenStateArg->CreateSetValue(ctx, block, newState);
-
- BranchInst::Create(done, block);
- block = done;
-
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TChainMapPtr = std::conditional_t<IsStream, TStreamCodegenStatefulValue::TFetchPtr, TCustomListCodegenStatefulValue::TNextPtr>;
-
- Function* ChainMapFunc = nullptr;
-
- TChainMapPtr ChainMap = nullptr;
-#endif
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto initArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ const auto load = new LoadInst(initArg, "load", block);
+ BranchInst::Create(work, init, IsInvalid(load, block), block);
+ block = init;
+
+ codegenStateArg->CreateSetValue(ctx, block, initArg);
+ new StoreInst(GetInvalid(context), initArg, block);
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
+
+ BranchInst::Create(done, good, icmp, block);
+ block = good;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, ComputationNodes.NewItem, ctx, block);
+
+ const auto newState = GetNodeValue(ComputationNodes.NewState, ctx, block);
+
+ codegenStateArg->CreateSetValue(ctx, block, newState);
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TChainMapPtr = std::conditional_t<IsStream, TStreamCodegenStatefulValue::TFetchPtr, TCustomListCodegenStatefulValue::TNextPtr>;
+
+ Function* ChainMapFunc = nullptr;
+
+ TChainMapPtr ChainMap = nullptr;
+#endif
+
IComputationNode* const List;
- IComputationNode* const Init;
- const TComputationNodes ComputationNodes;
+ IComputationNode* const Init;
+ const TComputationNodes ComputationNodes;
+};
+
+class TStreamChainMapWrapper : public TCustomValueCodegeneratorNode<TStreamChainMapWrapper>, private TBaseChainMapWrapper<true> {
+ typedef TCustomValueCodegeneratorNode<TStreamChainMapWrapper> TBaseComputation;
+ typedef TBaseChainMapWrapper<true> TBaseWrapper;
+public:
+ TStreamChainMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
+ : TBaseComputation(mutables), TBaseWrapper(list, init, itemArg, stateArg, newItem, newState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && ChainMap)
+ return ctx.HolderFactory.Create<TStreamCodegenStatefulValue>(ChainMap, &ctx, List->GetValue(ctx), Init->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), Init->GetValue(ctx), ComputationNodes);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Init);
+ DependsOn(ComputationNodes.NewItem);
+ DependsOn(ComputationNodes.NewState);
+ Own(ComputationNodes.ItemArg);
+ Own(ComputationNodes.StateArg);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ ChainMapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(ChainMapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (ChainMapFunc)
+ ChainMap = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(ChainMapFunc));
+ }
+#endif
+};
+
+class TListChainMapWrapper : public TBothWaysCodegeneratorNode<TListChainMapWrapper>, private TBaseChainMapWrapper<false> {
+ typedef TBothWaysCodegeneratorNode<TListChainMapWrapper> TBaseComputation;
+ typedef TBaseChainMapWrapper<false> TBaseWrapper;
+public:
+ TListChainMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
+ : TBaseComputation(mutables), TBaseWrapper(list, init, itemArg, stateArg, newItem, newState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto init = Init->GetValue(ctx);
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ auto size = list.GetListLength();
+
+ ComputationNodes.StateArg->SetValue(ctx, std::move(init));
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
+ while (size--) {
+ ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
+ *items++ = ComputationNodes.NewItem->GetValue(ctx);
+ ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.NewState->GetValue(ctx));
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), std::move(init), ComputationNodes);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value, const NUdf::TUnboxedValuePod init) const {
+ return ctx.HolderFactory.Create<TCustomListCodegenStatefulValue>(ChainMap, &ctx, value, init);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto init = GetNodeValue(Init, ctx, block);
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto map = PHINode::Create(list->getType(), 2U, "map", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ codegenStateArg->CreateSetValue(ctx, block, init);
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, size, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ index->addIncoming(ConstantInt::get(size->getType(), 0), block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
+ BranchInst::Create(next, stop, more, block);
+
+ block = next;
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto item = new LoadInst(src, "item", block);
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
+ GetNodeValue(dst, ComputationNodes.NewItem, ctx, block);
+ const auto newState = GetNodeValue(ComputationNodes.NewState, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, newState);
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ map->addIncoming(array, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListChainMapWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType(), init->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list, init}, "value", block);
+ map->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ const auto initPtr = new AllocaInst(init->getType(), 0U, "init", block);
+ new StoreInst(list, resultPtr, block);
+ new StoreInst(init, initPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType(), initPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr, initPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ map->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return map;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Init);
+ DependsOn(ComputationNodes.NewItem);
+ DependsOn(ComputationNodes.NewState);
+ Own(ComputationNodes.ItemArg);
+ Own(ComputationNodes.StateArg);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListChainMapWrapper>::GenerateFunctions(codegen);
+ ChainMapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(ChainMapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListChainMapWrapper>::FinalizeFunctions(codegen);
+ if (ChainMapFunc)
+ ChainMap = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(ChainMapFunc));
+ }
+#endif
};
-class TStreamChainMapWrapper : public TCustomValueCodegeneratorNode<TStreamChainMapWrapper>, private TBaseChainMapWrapper<true> {
- typedef TCustomValueCodegeneratorNode<TStreamChainMapWrapper> TBaseComputation;
- typedef TBaseChainMapWrapper<true> TBaseWrapper;
-public:
- TStreamChainMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
- : TBaseComputation(mutables), TBaseWrapper(list, init, itemArg, stateArg, newItem, newState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && ChainMap)
- return ctx.HolderFactory.Create<TStreamCodegenStatefulValue>(ChainMap, &ctx, List->GetValue(ctx), Init->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), Init->GetValue(ctx), ComputationNodes);
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Init);
- DependsOn(ComputationNodes.NewItem);
- DependsOn(ComputationNodes.NewState);
- Own(ComputationNodes.ItemArg);
- Own(ComputationNodes.StateArg);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- ChainMapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(ChainMapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (ChainMapFunc)
- ChainMap = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(ChainMapFunc));
- }
-#endif
-};
-
-class TListChainMapWrapper : public TBothWaysCodegeneratorNode<TListChainMapWrapper>, private TBaseChainMapWrapper<false> {
- typedef TBothWaysCodegeneratorNode<TListChainMapWrapper> TBaseComputation;
- typedef TBaseChainMapWrapper<false> TBaseWrapper;
-public:
- TListChainMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* init, IComputationExternalNode* itemArg, IComputationExternalNode* stateArg, IComputationNode* newItem, IComputationNode* newState)
- : TBaseComputation(mutables), TBaseWrapper(list, init, itemArg, stateArg, newItem, newState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto init = Init->GetValue(ctx);
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- auto size = list.GetListLength();
-
- ComputationNodes.StateArg->SetValue(ctx, std::move(init));
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
- while (size--) {
- ComputationNodes.ItemArg->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
- *items++ = ComputationNodes.NewItem->GetValue(ctx);
- ComputationNodes.StateArg->SetValue(ctx, ComputationNodes.NewState->GetValue(ctx));
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), std::move(init), ComputationNodes);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value, const NUdf::TUnboxedValuePod init) const {
- return ctx.HolderFactory.Create<TCustomListCodegenStatefulValue>(ChainMap, &ctx, value, init);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.ItemArg);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(ComputationNodes.StateArg);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto init = GetNodeValue(Init, ctx, block);
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto map = PHINode::Create(list->getType(), 2U, "map", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- codegenStateArg->CreateSetValue(ctx, block, init);
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, size, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- index->addIncoming(ConstantInt::get(size->getType(), 0), block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
- BranchInst::Create(next, stop, more, block);
-
- block = next;
- const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto item = new LoadInst(src, "item", block);
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
- GetNodeValue(dst, ComputationNodes.NewItem, ctx, block);
- const auto newState = GetNodeValue(ComputationNodes.NewState, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, newState);
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
- index->addIncoming(plus, block);
- BranchInst::Create(loop, block);
-
- block = stop;
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- map->addIncoming(array, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListChainMapWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType(), init->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list, init}, "value", block);
- map->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- const auto initPtr = new AllocaInst(init->getType(), 0U, "init", block);
- new StoreInst(list, resultPtr, block);
- new StoreInst(init, initPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType(), initPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr, initPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- map->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return map;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Init);
- DependsOn(ComputationNodes.NewItem);
- DependsOn(ComputationNodes.NewState);
- Own(ComputationNodes.ItemArg);
- Own(ComputationNodes.StateArg);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListChainMapWrapper>::GenerateFunctions(codegen);
- ChainMapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(ChainMapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListChainMapWrapper>::FinalizeFunctions(codegen);
- if (ChainMapFunc)
- ChainMap = reinterpret_cast<TChainMapPtr>(codegen->GetPointerToFunction(ChainMapFunc));
- }
-#endif
-};
-
-}
-
-IComputationNode* WrapChainMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
- const auto type = callable.GetType()->GetReturnType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initialState = LocateNode(ctx.NodeLocator, callable, 1);
- const auto newItem = LocateNode(ctx.NodeLocator, callable, 4);
- const auto newState = LocateNode(ctx.NodeLocator, callable, 5);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
- const auto stateArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
- if (type->IsFlow()) {
- return new TFoldMapFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, initialState, itemArg, stateArg, newItem, newState);
- } else if (type->IsStream()) {
- return new TStreamChainMapWrapper(ctx.Mutables, flow, initialState, itemArg, stateArg, newItem, newState);
- } else if (type->IsList()) {
- return new TListChainMapWrapper(ctx.Mutables, flow, initialState, itemArg, stateArg, newItem, newState);
- }
-
- THROW yexception() << "Expected flow, list or stream.";
}
-
+
+IComputationNode* WrapChainMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
+ const auto type = callable.GetType()->GetReturnType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initialState = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto newItem = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto newState = LocateNode(ctx.NodeLocator, callable, 5);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ const auto stateArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ if (type->IsFlow()) {
+ return new TFoldMapFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, initialState, itemArg, stateArg, newItem, newState);
+ } else if (type->IsStream()) {
+ return new TStreamChainMapWrapper(ctx.Mutables, flow, initialState, itemArg, stateArg, newItem, newState);
+ } else if (type->IsList()) {
+ return new TListChainMapWrapper(ctx.Mutables, flow, initialState, itemArg, stateArg, newItem, newState);
+ }
+
+ THROW yexception() << "Expected flow, list or stream.";
+}
+
+}
}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.h b/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.h
index 0f65046c34..e792fed7d1 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chain_map.h
@@ -4,7 +4,7 @@
namespace NKikimr {
namespace NMiniKQL {
-IComputationNode* WrapChainMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapChainMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chopper.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_chopper.cpp
index 3a17d7c3e1..48c931dac6 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chopper.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chopper.cpp
@@ -1,819 +1,819 @@
-#include "mkql_chopper.h"
-
+#include "mkql_chopper.h"
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-class TChopperFlowWrapper : public TStatefulFlowCodegeneratorNode<TChopperFlowWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TChopperFlowWrapper> TBaseComputation;
-public:
- enum class EState : ui64 {
- Work,
- Chop,
- Next,
- Skip
- };
-
- TChopperFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, IComputationExternalNode* input, IComputationNode* output)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
- , Flow(flow)
- , ItemArg(itemArg)
- , Key(key)
- , KeyArg(keyArg)
- , Chop(chop)
- , Input(input)
- , Output(output)
- {
- Input->SetGetter(std::bind(&TChopperFlowWrapper::Getter, this, std::bind(&TChopperFlowWrapper::RefState, this, std::placeholders::_1), std::placeholders::_1));
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.Release();
- } else {
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- ItemArg->SetValue(ctx, std::move(item));
- KeyArg->SetValue(ctx, Key->GetValue(ctx));
- }
- } else if (EState::Skip == EState(state.Get<ui64>())) {
- do if (auto next = Flow->GetValue(ctx); next.IsSpecial())
- return next.Release();
- else
- ItemArg->SetValue(ctx, std::move(next));
- while (!Chop->GetValue(ctx).Get<bool>());
-
- KeyArg->SetValue(ctx, Key->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- }
-
- while (true) {
- auto output = Output->GetValue(ctx);
- if (output.IsFinish()) {
- Input->InvalidateValue(ctx);
- switch (EState(state.Get<ui64>())) {
- case EState::Work:
- case EState::Next:
- do if (auto next = Flow->GetValue(ctx); next.IsSpecial()) {
- if (next.IsYield()) {
- state = NUdf::TUnboxedValuePod(ui64(EState::Skip));
- }
- return next.Release();
- } else {
- ItemArg->SetValue(ctx, std::move(next));
- } while (!Chop->GetValue(ctx).Get<bool>());
- case EState::Chop:
- KeyArg->SetValue(ctx, Key->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- default:
- continue;
- }
- }
- return output.Release();
- }
- }
-
- NUdf::TUnboxedValuePod Getter(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (EState::Next == EState(state.Get<ui64>())) {
- state = NUdf::TUnboxedValuePod(ui64(EState::Work));
- return ItemArg->GetValue(ctx).Release();
- }
-
- auto item = Flow->GetValue(ctx);
- if (!item.IsSpecial()) {
- ItemArg->SetValue(ctx, NUdf::TUnboxedValue(item));
-
- if (Chop->GetValue(ctx).Get<bool>()) {
- state = NUdf::TUnboxedValuePod(ui64(EState::Chop));
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
- }
- return item.Release();
- }
-#ifndef MKQL_DISABLE_CODEGEN
-private:
- Function* GenerateHandler(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- TStringStream out;
- out << this->DebugString() << "::Handler_(" << static_cast<const void*>(this) << ").";
- const auto& name = out.Str();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+class TChopperFlowWrapper : public TStatefulFlowCodegeneratorNode<TChopperFlowWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TChopperFlowWrapper> TBaseComputation;
+public:
+ enum class EState : ui64 {
+ Work,
+ Chop,
+ Next,
+ Skip
+ };
+
+ TChopperFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, IComputationExternalNode* input, IComputationNode* output)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
+ , Flow(flow)
+ , ItemArg(itemArg)
+ , Key(key)
+ , KeyArg(keyArg)
+ , Chop(chop)
+ , Input(input)
+ , Output(output)
+ {
+ Input->SetGetter(std::bind(&TChopperFlowWrapper::Getter, this, std::bind(&TChopperFlowWrapper::RefState, this, std::placeholders::_1), std::placeholders::_1));
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.Release();
+ } else {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ ItemArg->SetValue(ctx, std::move(item));
+ KeyArg->SetValue(ctx, Key->GetValue(ctx));
+ }
+ } else if (EState::Skip == EState(state.Get<ui64>())) {
+ do if (auto next = Flow->GetValue(ctx); next.IsSpecial())
+ return next.Release();
+ else
+ ItemArg->SetValue(ctx, std::move(next));
+ while (!Chop->GetValue(ctx).Get<bool>());
+
+ KeyArg->SetValue(ctx, Key->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ }
+
+ while (true) {
+ auto output = Output->GetValue(ctx);
+ if (output.IsFinish()) {
+ Input->InvalidateValue(ctx);
+ switch (EState(state.Get<ui64>())) {
+ case EState::Work:
+ case EState::Next:
+ do if (auto next = Flow->GetValue(ctx); next.IsSpecial()) {
+ if (next.IsYield()) {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Skip));
+ }
+ return next.Release();
+ } else {
+ ItemArg->SetValue(ctx, std::move(next));
+ } while (!Chop->GetValue(ctx).Get<bool>());
+ case EState::Chop:
+ KeyArg->SetValue(ctx, Key->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ default:
+ continue;
+ }
+ }
+ return output.Release();
+ }
+ }
+
+ NUdf::TUnboxedValuePod Getter(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (EState::Next == EState(state.Get<ui64>())) {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Work));
+ return ItemArg->GetValue(ctx).Release();
+ }
+
+ auto item = Flow->GetValue(ctx);
+ if (!item.IsSpecial()) {
+ ItemArg->SetValue(ctx, NUdf::TUnboxedValue(item));
+
+ if (Chop->GetValue(ctx).Get<bool>()) {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Chop));
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+ }
+ return item.Release();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+private:
+ Function* GenerateHandler(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ TStringStream out;
+ out << this->DebugString() << "::Handler_(" << static_cast<const void*>(this) << ").";
+ const auto& name = out.Str();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
+
MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
- const auto valueType = Type::getInt128Ty(context);
- const auto funcType = FunctionType::get(valueType, {PointerType::getUnqual(GetCompContextType(context))}, false);
-
- TCodegenContext ctx(codegen);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto funcType = FunctionType::get(valueType, {PointerType::getUnqual(GetCompContextType(context))}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*ctx.Func->arg_begin();
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto indexType = Type::getInt32Ty(context);
-
- auto block = main;
-
- const auto load = BasicBlock::Create(context, "load", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
- const auto entry = new LoadInst(statePtr, "entry", block);
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, entry, GetConstant(ui64(EState::Next), context), "next", block);
-
- BranchInst::Create(load, work, next, block);
-
- {
- block = load;
- new StoreInst(GetConstant(ui64(EState::Work), context), statePtr, block);
- const auto item = GetNodeValue(ItemArg, ctx, block);
- ReturnInst::Create(context, item, block);
- }
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- block = work;
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- BranchInst::Create(exit, good, IsSpecial(item, block), block);
-
- block = good;
-
- codegenItemArg->CreateSetValue(ctx, block, item);
-
- const auto chop = GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(step, exit, cast, block);
-
- block = step;
-
- new StoreInst(GetConstant(ui64(EState::Chop), context), statePtr, block);
- ReturnInst::Create(context, GetFinish(context), block);
-
- block = exit;
- ReturnInst::Create(context, item, block);
- }
-
- return ctx.Func;
- }
-public:
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
-
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*ctx.Func->arg_begin();
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto indexType = Type::getInt32Ty(context);
+
+ auto block = main;
+
+ const auto load = BasicBlock::Create(context, "load", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+ const auto entry = new LoadInst(statePtr, "entry", block);
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, entry, GetConstant(ui64(EState::Next), context), "next", block);
+
+ BranchInst::Create(load, work, next, block);
+
+ {
+ block = load;
+ new StoreInst(GetConstant(ui64(EState::Work), context), statePtr, block);
+ const auto item = GetNodeValue(ItemArg, ctx, block);
+ ReturnInst::Create(context, item, block);
+ }
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ block = work;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ BranchInst::Create(exit, good, IsSpecial(item, block), block);
+
+ block = good;
+
+ codegenItemArg->CreateSetValue(ctx, block, item);
+
+ const auto chop = GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(step, exit, cast, block);
+
+ block = step;
+
+ new StoreInst(GetConstant(ui64(EState::Chop), context), statePtr, block);
+ ReturnInst::Create(context, GetFinish(context), block);
+
+ block = exit;
+ ReturnInst::Create(context, item, block);
+ }
+
+ return ctx.Func;
+ }
+public:
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+
MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
MKQL_ENSURE(codegenInput, "Input arg must be codegenerator node.");
- codegenInput->SetValueGetter(GenerateHandler(ctx.Codegen));
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 5U, "result", exit);
-
- const auto first = new LoadInst(statePtr, "first", block);
- const auto enter = SwitchInst::Create(first, loop, 2U, block);
- enter->addCase(GetInvalid(context), init);
- enter->addCase(GetConstant(ui64(EState::Skip), context), pass);
-
-
- {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- block = init;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(exit, next, IsSpecial(item, block), block);
-
- block = next;
-
- new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto key = GetNodeValue(Key, ctx, block);
- codegenKeyArg->CreateSetValue(ctx, block, key);
-
- BranchInst::Create(loop, block);
- }
-
- {
- const auto part = BasicBlock::Create(context, "part", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- block = loop;
-
- const auto item = GetNodeValue(Output, ctx, block);
- const auto state = new LoadInst(statePtr, "state", block);
-
- result->addIncoming(item, block);
- BranchInst::Create(part, exit, IsFinish(item, block), block);
-
- block = part;
-
- codegenInput->CreateInvalidate(ctx, block);
-
- result->addIncoming(GetFinish(context), block);
-
- const auto choise = SwitchInst::Create(state, exit, 3U, block);
- choise->addCase(GetConstant(ui64(EState::Next), context), pass);
- choise->addCase(GetConstant(ui64(EState::Work), context), pass);
- choise->addCase(GetConstant(ui64(EState::Chop), context), step);
-
- block = pass;
-
- const auto next = GetNodeValue(Flow, ctx, block);
-
- result->addIncoming(next, block);
-
- const auto way = SwitchInst::Create(next, good, 2U, block);
- way->addCase(GetFinish(context), exit);
- way->addCase(GetYield(context), skip);
-
- block = good;
-
- codegenItemArg->CreateSetValue(ctx, block, next);
-
- const auto chop = GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(step, pass, cast, block);
-
- block = step;
-
- new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
- const auto key = GetNodeValue(Key, ctx, block);
- codegenKeyArg->CreateSetValue(ctx, block, key);
-
- BranchInst::Create(loop, block);
-
- block = skip;
- new StoreInst(GetConstant(ui64(EState::Skip), context), statePtr, block);
- result->addIncoming(next, block);
- BranchInst::Create(exit, block);
- }
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, ItemArg);
- DependsOn(flow, Key);
- Own(flow, KeyArg);
- DependsOn(flow, Chop);
-
- Own(flow, Input);
- DependsOn(flow, Output);
- }
- }
-
- IComputationNode *const Flow;
-
- IComputationExternalNode *const ItemArg;
- IComputationNode *const Key;
- IComputationExternalNode *const KeyArg;
- IComputationNode *const Chop;
-
- IComputationExternalNode *const Input;
- IComputationNode *const Output;
-};
-
-class TChopperWrapper : public TCustomValueCodegeneratorNode<TChopperWrapper> {
- typedef TCustomValueCodegeneratorNode<TChopperWrapper> TBaseComputation;
-private:
- enum class EState : ui8 {
- Init,
- Work,
- Chop,
- Next,
- Skip,
- };
- using TStatePtr = std::shared_ptr<EState>;
-
- class TSubStream : public TComputationValue<TSubStream> {
- public:
- using TBase = TComputationValue<TSubStream>;
-
- TSubStream(TMemoryUsageInfo* memInfo, const TStatePtr& state, const NUdf::TUnboxedValue& stream, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, TComputationContext& ctx)
- : TBase(memInfo), State(state), Stream(stream)
- , ItemArg(itemArg)
- , Key(key)
- , KeyArg(keyArg)
- , Chop(chop)
- , Ctx(ctx)
- {}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- auto& state = *State;
- if (EState::Next == state) {
- state = EState::Work;
- result = ItemArg->GetValue(Ctx);
- return NUdf::EFetchStatus::Ok;
- }
-
- while (true) {
- switch (const auto status = Stream.Fetch(result)) {
- case NUdf::EFetchStatus::Ok: {
- ItemArg->SetValue(Ctx, NUdf::TUnboxedValue(result));
-
- if (Chop->GetValue(Ctx).Get<bool>()) {
- state = EState::Chop;
- return NUdf::EFetchStatus::Finish;
- }
-
- return status;
- }
-
- case NUdf::EFetchStatus::Finish:
- case NUdf::EFetchStatus::Yield:
- return status;
- }
- }
- }
-
- const TStatePtr State;
- const NUdf::TUnboxedValue Stream;
-
- IComputationExternalNode *const ItemArg;
- IComputationNode *const Key;
- IComputationExternalNode *const KeyArg;
- IComputationNode *const Chop;
-
- TComputationContext& Ctx;
- };
-
- class TMainStream : public TComputationValue<TMainStream> {
- public:
- TMainStream(TMemoryUsageInfo* memInfo, TStatePtr&& state, NUdf::TUnboxedValue&& stream, const IComputationExternalNode *itemArg, const IComputationNode *key, const IComputationExternalNode *keyArg, const IComputationNode *chop, const IComputationExternalNode *input, const IComputationNode *output, TComputationContext& ctx)
- : TComputationValue(memInfo), State(std::move(state)), ItemArg(itemArg), Key(key), KeyArg(keyArg), Chop(chop), Input(input), Output(output), InputStream(std::move(stream)), Ctx(ctx)
- {}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- while (true) {
- if (Stream) {
- if (const auto status = Stream.Fetch(result); NUdf::EFetchStatus::Finish != status) {
- return status;
- }
-
- Stream = NUdf::TUnboxedValuePod();
- Input->InvalidateValue(Ctx);
- }
-
- switch (auto& state = *State) {
- case EState::Init:
- if (const auto status = InputStream.Fetch(ItemArg->RefValue(Ctx)); NUdf::EFetchStatus::Ok != status) {
- return status;
- }
- state = EState::Next;
- KeyArg->SetValue(Ctx, Key->GetValue(Ctx));
- break;
- case EState::Work:
- case EState::Next:
- case EState::Skip:
- do switch (const auto status = InputStream.Fetch(ItemArg->RefValue(Ctx))) {
- case NUdf::EFetchStatus::Ok:
- break;
- case NUdf::EFetchStatus::Yield:
- state = EState::Skip;
- case NUdf::EFetchStatus::Finish:
- return status;
- } while (!Chop->GetValue(Ctx).Get<bool>());
+ codegenInput->SetValueGetter(GenerateHandler(ctx.Codegen));
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 5U, "result", exit);
+
+ const auto first = new LoadInst(statePtr, "first", block);
+ const auto enter = SwitchInst::Create(first, loop, 2U, block);
+ enter->addCase(GetInvalid(context), init);
+ enter->addCase(GetConstant(ui64(EState::Skip), context), pass);
+
+
+ {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ block = init;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(exit, next, IsSpecial(item, block), block);
+
+ block = next;
+
+ new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto key = GetNodeValue(Key, ctx, block);
+ codegenKeyArg->CreateSetValue(ctx, block, key);
+
+ BranchInst::Create(loop, block);
+ }
+
+ {
+ const auto part = BasicBlock::Create(context, "part", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ block = loop;
+
+ const auto item = GetNodeValue(Output, ctx, block);
+ const auto state = new LoadInst(statePtr, "state", block);
+
+ result->addIncoming(item, block);
+ BranchInst::Create(part, exit, IsFinish(item, block), block);
+
+ block = part;
+
+ codegenInput->CreateInvalidate(ctx, block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ const auto choise = SwitchInst::Create(state, exit, 3U, block);
+ choise->addCase(GetConstant(ui64(EState::Next), context), pass);
+ choise->addCase(GetConstant(ui64(EState::Work), context), pass);
+ choise->addCase(GetConstant(ui64(EState::Chop), context), step);
+
+ block = pass;
+
+ const auto next = GetNodeValue(Flow, ctx, block);
+
+ result->addIncoming(next, block);
+
+ const auto way = SwitchInst::Create(next, good, 2U, block);
+ way->addCase(GetFinish(context), exit);
+ way->addCase(GetYield(context), skip);
+
+ block = good;
+
+ codegenItemArg->CreateSetValue(ctx, block, next);
+
+ const auto chop = GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(step, pass, cast, block);
+
+ block = step;
+
+ new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
+ const auto key = GetNodeValue(Key, ctx, block);
+ codegenKeyArg->CreateSetValue(ctx, block, key);
+
+ BranchInst::Create(loop, block);
+
+ block = skip;
+ new StoreInst(GetConstant(ui64(EState::Skip), context), statePtr, block);
+ result->addIncoming(next, block);
+ BranchInst::Create(exit, block);
+ }
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, ItemArg);
+ DependsOn(flow, Key);
+ Own(flow, KeyArg);
+ DependsOn(flow, Chop);
+
+ Own(flow, Input);
+ DependsOn(flow, Output);
+ }
+ }
+
+ IComputationNode *const Flow;
+
+ IComputationExternalNode *const ItemArg;
+ IComputationNode *const Key;
+ IComputationExternalNode *const KeyArg;
+ IComputationNode *const Chop;
+
+ IComputationExternalNode *const Input;
+ IComputationNode *const Output;
+};
+
+class TChopperWrapper : public TCustomValueCodegeneratorNode<TChopperWrapper> {
+ typedef TCustomValueCodegeneratorNode<TChopperWrapper> TBaseComputation;
+private:
+ enum class EState : ui8 {
+ Init,
+ Work,
+ Chop,
+ Next,
+ Skip,
+ };
+ using TStatePtr = std::shared_ptr<EState>;
+
+ class TSubStream : public TComputationValue<TSubStream> {
+ public:
+ using TBase = TComputationValue<TSubStream>;
+
+ TSubStream(TMemoryUsageInfo* memInfo, const TStatePtr& state, const NUdf::TUnboxedValue& stream, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, TComputationContext& ctx)
+ : TBase(memInfo), State(state), Stream(stream)
+ , ItemArg(itemArg)
+ , Key(key)
+ , KeyArg(keyArg)
+ , Chop(chop)
+ , Ctx(ctx)
+ {}
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ auto& state = *State;
+ if (EState::Next == state) {
+ state = EState::Work;
+ result = ItemArg->GetValue(Ctx);
+ return NUdf::EFetchStatus::Ok;
+ }
+
+ while (true) {
+ switch (const auto status = Stream.Fetch(result)) {
+ case NUdf::EFetchStatus::Ok: {
+ ItemArg->SetValue(Ctx, NUdf::TUnboxedValue(result));
+
+ if (Chop->GetValue(Ctx).Get<bool>()) {
+ state = EState::Chop;
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ return status;
+ }
+
+ case NUdf::EFetchStatus::Finish:
+ case NUdf::EFetchStatus::Yield:
+ return status;
+ }
+ }
+ }
+
+ const TStatePtr State;
+ const NUdf::TUnboxedValue Stream;
+
+ IComputationExternalNode *const ItemArg;
+ IComputationNode *const Key;
+ IComputationExternalNode *const KeyArg;
+ IComputationNode *const Chop;
+
+ TComputationContext& Ctx;
+ };
+
+ class TMainStream : public TComputationValue<TMainStream> {
+ public:
+ TMainStream(TMemoryUsageInfo* memInfo, TStatePtr&& state, NUdf::TUnboxedValue&& stream, const IComputationExternalNode *itemArg, const IComputationNode *key, const IComputationExternalNode *keyArg, const IComputationNode *chop, const IComputationExternalNode *input, const IComputationNode *output, TComputationContext& ctx)
+ : TComputationValue(memInfo), State(std::move(state)), ItemArg(itemArg), Key(key), KeyArg(keyArg), Chop(chop), Input(input), Output(output), InputStream(std::move(stream)), Ctx(ctx)
+ {}
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ while (true) {
+ if (Stream) {
+ if (const auto status = Stream.Fetch(result); NUdf::EFetchStatus::Finish != status) {
+ return status;
+ }
+
+ Stream = NUdf::TUnboxedValuePod();
+ Input->InvalidateValue(Ctx);
+ }
+
+ switch (auto& state = *State) {
+ case EState::Init:
+ if (const auto status = InputStream.Fetch(ItemArg->RefValue(Ctx)); NUdf::EFetchStatus::Ok != status) {
+ return status;
+ }
+ state = EState::Next;
+ KeyArg->SetValue(Ctx, Key->GetValue(Ctx));
+ break;
+ case EState::Work:
+ case EState::Next:
+ case EState::Skip:
+ do switch (const auto status = InputStream.Fetch(ItemArg->RefValue(Ctx))) {
+ case NUdf::EFetchStatus::Ok:
+ break;
+ case NUdf::EFetchStatus::Yield:
+ state = EState::Skip;
+ case NUdf::EFetchStatus::Finish:
+ return status;
+ } while (!Chop->GetValue(Ctx).Get<bool>());
[[fallthrough]];
- case EState::Chop:
- state = EState::Next;
- KeyArg->SetValue(Ctx, Key->GetValue(Ctx));
- break;
- }
- Stream = Output->GetValue(Ctx);
- }
- }
-
- const TStatePtr State;
- const IComputationExternalNode *const ItemArg;
- const IComputationNode* Key;
- const IComputationNode* Chop;
- const IComputationExternalNode* KeyArg;
- const IComputationExternalNode* Input;
- const IComputationNode* Output;
- const NUdf::TUnboxedValue InputStream;
- NUdf::TUnboxedValue Stream;
- TComputationContext& Ctx;
- };
-#ifndef MKQL_DISABLE_CODEGEN
- class TCodegenInput : public TComputationValue<TCodegenInput> {
- public:
- using TBase = TComputationValue<TCodegenInput>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, EState&, NUdf::TUnboxedValuePod&);
-
- TCodegenInput(TMemoryUsageInfo* memInfo, TFetchPtr fetch, const NUdf::TUnboxedValue& stream, TComputationContext* ctx, const TStatePtr& init)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Stream(stream)
- , Ctx(ctx)
- , State(init)
- {}
-
- protected:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), *State, result);
- }
-
- const TFetchPtr FetchFunc;
- const NUdf::TUnboxedValue Stream;
- TComputationContext* const Ctx;
- const TStatePtr State;
- };
-
- class TCodegenOutput : public TComputationValue<TCodegenOutput> {
- public:
- using TBase = TComputationValue<TCodegenOutput>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod&, EState&, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
- TCodegenOutput(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, TStatePtr&& init, NUdf::TUnboxedValue&& input)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , State(std::move(init))
- , InputStream(std::move(input))
- {}
-
- protected:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, Stream, *State, InputStream, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const TStatePtr State;
- const NUdf::TUnboxedValue InputStream;
- NUdf::TUnboxedValue Stream;
- };
-#endif
-public:
- TChopperWrapper(TComputationMutables& mutables, IComputationNode* stream, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, IComputationExternalNode* input, IComputationNode* output)
- : TBaseComputation(mutables)
- , Stream(stream)
- , ItemArg(itemArg)
- , Key(key)
- , KeyArg(keyArg)
- , Chop(chop)
- , Input(input)
- , Output(output)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto sharedState = std::allocate_shared<EState, TMKQLAllocator<EState>>(TMKQLAllocator<EState>(), EState::Init);
- auto stream = Stream->GetValue(ctx);
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && InputPtr)
- Input->SetValue(ctx, ctx.HolderFactory.Create<TCodegenInput>(InputPtr, stream, &ctx, sharedState));
- else
-#endif
- Input->SetValue(ctx, ctx.HolderFactory.Create<TSubStream>(sharedState, stream, ItemArg, Key, KeyArg, Chop, ctx));
-
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && OutputPtr)
- return ctx.HolderFactory.Create<TCodegenOutput>(OutputPtr, &ctx, std::move(sharedState), std::move(stream));
-#endif
- return ctx.HolderFactory.Create<TMainStream>(std::move(sharedState), std::move(stream), ItemArg, Key, KeyArg, Chop, Input, Output, ctx);
- }
-private:
- void RegisterDependencies() const final {
- DependsOn(Stream);
-
- Own(ItemArg);
- DependsOn(Key);
- Own(KeyArg);
- DependsOn(Chop);
-
- Own(Input);
- DependsOn(Output);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- InputFunc = GenerateInput(codegen);
- OutputFunc = GenerateOutput(codegen);
- codegen->ExportSymbol(InputFunc);
- codegen->ExportSymbol(OutputFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (InputFunc)
- InputPtr = reinterpret_cast<TInputPtr>(codegen->GetPointerToFunction(InputFunc));
- if (OutputFunc)
- OutputPtr = reinterpret_cast<TOutputPtr>(codegen->GetPointerToFunction(OutputFunc));
- }
-
- Function* GenerateInput(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = MakeName("Input");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
-
+ case EState::Chop:
+ state = EState::Next;
+ KeyArg->SetValue(Ctx, Key->GetValue(Ctx));
+ break;
+ }
+ Stream = Output->GetValue(Ctx);
+ }
+ }
+
+ const TStatePtr State;
+ const IComputationExternalNode *const ItemArg;
+ const IComputationNode* Key;
+ const IComputationNode* Chop;
+ const IComputationExternalNode* KeyArg;
+ const IComputationExternalNode* Input;
+ const IComputationNode* Output;
+ const NUdf::TUnboxedValue InputStream;
+ NUdf::TUnboxedValue Stream;
+ TComputationContext& Ctx;
+ };
+#ifndef MKQL_DISABLE_CODEGEN
+ class TCodegenInput : public TComputationValue<TCodegenInput> {
+ public:
+ using TBase = TComputationValue<TCodegenInput>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, EState&, NUdf::TUnboxedValuePod&);
+
+ TCodegenInput(TMemoryUsageInfo* memInfo, TFetchPtr fetch, const NUdf::TUnboxedValue& stream, TComputationContext* ctx, const TStatePtr& init)
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Stream(stream)
+ , Ctx(ctx)
+ , State(init)
+ {}
+
+ protected:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), *State, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ const NUdf::TUnboxedValue Stream;
+ TComputationContext* const Ctx;
+ const TStatePtr State;
+ };
+
+ class TCodegenOutput : public TComputationValue<TCodegenOutput> {
+ public:
+ using TBase = TComputationValue<TCodegenOutput>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod&, EState&, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
+ TCodegenOutput(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, TStatePtr&& init, NUdf::TUnboxedValue&& input)
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , State(std::move(init))
+ , InputStream(std::move(input))
+ {}
+
+ protected:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, Stream, *State, InputStream, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const TStatePtr State;
+ const NUdf::TUnboxedValue InputStream;
+ NUdf::TUnboxedValue Stream;
+ };
+#endif
+public:
+ TChopperWrapper(TComputationMutables& mutables, IComputationNode* stream, IComputationExternalNode* itemArg, IComputationNode* key, IComputationExternalNode* keyArg, IComputationNode* chop, IComputationExternalNode* input, IComputationNode* output)
+ : TBaseComputation(mutables)
+ , Stream(stream)
+ , ItemArg(itemArg)
+ , Key(key)
+ , KeyArg(keyArg)
+ , Chop(chop)
+ , Input(input)
+ , Output(output)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto sharedState = std::allocate_shared<EState, TMKQLAllocator<EState>>(TMKQLAllocator<EState>(), EState::Init);
+ auto stream = Stream->GetValue(ctx);
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && InputPtr)
+ Input->SetValue(ctx, ctx.HolderFactory.Create<TCodegenInput>(InputPtr, stream, &ctx, sharedState));
+ else
+#endif
+ Input->SetValue(ctx, ctx.HolderFactory.Create<TSubStream>(sharedState, stream, ItemArg, Key, KeyArg, Chop, ctx));
+
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && OutputPtr)
+ return ctx.HolderFactory.Create<TCodegenOutput>(OutputPtr, &ctx, std::move(sharedState), std::move(stream));
+#endif
+ return ctx.HolderFactory.Create<TMainStream>(std::move(sharedState), std::move(stream), ItemArg, Key, KeyArg, Chop, Input, Output, ctx);
+ }
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Stream);
+
+ Own(ItemArg);
+ DependsOn(Key);
+ Own(KeyArg);
+ DependsOn(Chop);
+
+ Own(Input);
+ DependsOn(Output);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ InputFunc = GenerateInput(codegen);
+ OutputFunc = GenerateOutput(codegen);
+ codegen->ExportSymbol(InputFunc);
+ codegen->ExportSymbol(OutputFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (InputFunc)
+ InputPtr = reinterpret_cast<TInputPtr>(codegen->GetPointerToFunction(InputFunc));
+ if (OutputFunc)
+ OutputPtr = reinterpret_cast<TOutputPtr>(codegen->GetPointerToFunction(OutputFunc));
+ }
+
+ Function* GenerateInput(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = MakeName("Input");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
+
MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto stateType = Type::getInt8Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(stateType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto stateType = Type::getInt8Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(stateType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto stateArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto load = BasicBlock::Create(context, "load", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto first = new LoadInst(stateArg, "first", block);
- const auto reload = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, first, ConstantInt::get(stateType, ui8(EState::Next)), "reload", block);
-
- BranchInst::Create(load, work, reload, block);
-
- {
- block = load;
-
- new StoreInst(ConstantInt::get(stateType, ui8(EState::Work)), stateArg, block);
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, ItemArg, ctx, block);
- ReturnInst::Create(context, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), block);
- }
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- block = work;
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
- const auto none = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), "none", block);
-
- BranchInst::Create(exit, good, none, block);
-
- block = good;
-
- const auto chop = GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(step, pass, cast, block);
-
- block = step;
-
- new StoreInst(ConstantInt::get(stateType, ui8(EState::Chop)), stateArg, block);
- ReturnInst::Create(context, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Finish)), block);
-
- block = pass;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, ItemArg, ctx, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- ReturnInst::Create(context, status, block);
- }
-
- return ctx.Func;
- }
-
- Function* GenerateOutput(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = MakeName("Output");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto stateArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto load = BasicBlock::Create(context, "load", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto first = new LoadInst(stateArg, "first", block);
+ const auto reload = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, first, ConstantInt::get(stateType, ui8(EState::Next)), "reload", block);
+
+ BranchInst::Create(load, work, reload, block);
+
+ {
+ block = load;
+
+ new StoreInst(ConstantInt::get(stateType, ui8(EState::Work)), stateArg, block);
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, ItemArg, ctx, block);
+ ReturnInst::Create(context, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), block);
+ }
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ block = work;
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
+ const auto none = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), "none", block);
+
+ BranchInst::Create(exit, good, none, block);
+
+ block = good;
+
+ const auto chop = GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(step, pass, cast, block);
+
+ block = step;
+
+ new StoreInst(ConstantInt::get(stateType, ui8(EState::Chop)), stateArg, block);
+ ReturnInst::Create(context, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Finish)), block);
+
+ block = pass;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, ItemArg, ctx, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ ReturnInst::Create(context, status, block);
+ }
+
+ return ctx.Func;
+ }
+
+ Function* GenerateOutput(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = MakeName("Output");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(ItemArg);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(KeyArg);
+
MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
MKQL_ENSURE(codegenInput, "Input arg must be codegenerator node.");
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto stateType = Type::getInt8Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType), PointerType::getUnqual(stateType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto stateType = Type::getInt8Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType), PointerType::getUnqual(stateType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto streamArg = &*++args;
- const auto stateArg = &*++args;
- const auto inputArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
-
- auto block = main;
-
- const auto input = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(inputArg, "load_input", false, block) : static_cast<Value*>(inputArg);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto stream = new LoadInst(streamArg, "stream", block);
- BranchInst::Create(next, work, IsEmpty(stream, block), block);
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
-
- block = work;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, valuePtr);
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
-
- BranchInst::Create(good, step, icmp, block);
-
- block = good;
-
- ReturnInst::Create(context, status, block);
-
- block = step;
-
- UnRefBoxed(stream, ctx, block);
- new StoreInst(ConstantInt::get(stream->getType(), 0), streamArg, block);
- codegenInput->CreateInvalidate(ctx, block);
- BranchInst::Create(next, block);
- }
-
- block = next;
-
- const auto state = new LoadInst(stateArg, "state", block);
- const auto choise = SwitchInst::Create(state, skip, 2U, block);
- choise->addCase(ConstantInt::get(stateType, ui8(EState::Init)), init);
- choise->addCase(ConstantInt::get(stateType, ui8(EState::Chop)), pass);
-
- {
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- block = init;
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, input, codegen, block, itemPtr);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), "special", block);
-
- BranchInst::Create(exit, pass, special, block);
-
- block = exit;
-
- ReturnInst::Create(context, status, block);
- }
-
- {
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- block = skip;
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, input, codegen, block, itemPtr);
-
- const auto way = SwitchInst::Create(status, test, 2U, block);
- way->addCase(ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Yield)), exit);
- way->addCase(ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Finish)), done);
-
- block = exit;
-
- new StoreInst(ConstantInt::get(stateType, ui8(EState::Skip)), stateArg, block);
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
-
- block = test;
-
- const auto chop = GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(pass, skip, cast, block);
- }
-
- block = pass;
-
- new StoreInst(ConstantInt::get(stateType, ui8(EState::Next)), stateArg, block);
- const auto key = GetNodeValue(Key, ctx, block);
- codegenKeyArg->CreateSetValue(ctx, block, key);
- BranchInst::Create(pull, block);
-
- block = pull;
-
- GetNodeValue(streamArg, Output, ctx, block);
- BranchInst::Create(loop, block);
-
- return ctx.Func;
- }
-
- using TInputPtr = typename TCodegenInput::TFetchPtr;
- using TOutputPtr = typename TCodegenOutput::TFetchPtr;
-
- Function* InputFunc = nullptr;
- Function* OutputFunc = nullptr;
-
- TInputPtr InputPtr = nullptr;
- TOutputPtr OutputPtr = nullptr;
-#endif
- IComputationNode *const Stream;
-
- IComputationExternalNode *const ItemArg;
- IComputationNode *const Key;
- IComputationExternalNode *const KeyArg;
- IComputationNode *const Chop;
-
- IComputationExternalNode *const Input;
- IComputationNode *const Output;
-};
-
-}
-
-IComputationNode* WrapChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 7U, "Expected seven args.");
- const auto type = callable.GetType()->GetReturnType();
-
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto keyResult = LocateNode(ctx.NodeLocator, callable, 2);
- const auto switchResult = LocateNode(ctx.NodeLocator, callable, 4);
- const auto output = LocateNode(ctx.NodeLocator, callable, 6);
-
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto keyArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
- const auto input = LocateExternalNode(ctx.NodeLocator, callable, 5);
-
- if (type->IsFlow()) {
- const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
- return new TChopperFlowWrapper(ctx.Mutables, kind, stream, itemArg, keyResult, keyArg, switchResult, input, output);
- } else if (type->IsStream()) {
- return new TChopperWrapper(ctx.Mutables, stream, itemArg, keyResult, keyArg, switchResult, input, output);
- }
-
- THROW yexception() << "Expected flow or stream.";
-}
-
-}
-}
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto streamArg = &*++args;
+ const auto stateArg = &*++args;
+ const auto inputArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+
+ auto block = main;
+
+ const auto input = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(inputArg, "load_input", false, block) : static_cast<Value*>(inputArg);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto stream = new LoadInst(streamArg, "stream", block);
+ BranchInst::Create(next, work, IsEmpty(stream, block), block);
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+
+ block = work;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, valuePtr);
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
+
+ BranchInst::Create(good, step, icmp, block);
+
+ block = good;
+
+ ReturnInst::Create(context, status, block);
+
+ block = step;
+
+ UnRefBoxed(stream, ctx, block);
+ new StoreInst(ConstantInt::get(stream->getType(), 0), streamArg, block);
+ codegenInput->CreateInvalidate(ctx, block);
+ BranchInst::Create(next, block);
+ }
+
+ block = next;
+
+ const auto state = new LoadInst(stateArg, "state", block);
+ const auto choise = SwitchInst::Create(state, skip, 2U, block);
+ choise->addCase(ConstantInt::get(stateType, ui8(EState::Init)), init);
+ choise->addCase(ConstantInt::get(stateType, ui8(EState::Chop)), pass);
+
+ {
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ block = init;
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, input, codegen, block, itemPtr);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Ok)), "special", block);
+
+ BranchInst::Create(exit, pass, special, block);
+
+ block = exit;
+
+ ReturnInst::Create(context, status, block);
+ }
+
+ {
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ block = skip;
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, input, codegen, block, itemPtr);
+
+ const auto way = SwitchInst::Create(status, test, 2U, block);
+ way->addCase(ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Yield)), exit);
+ way->addCase(ConstantInt::get(statusType, ui32(NUdf::EFetchStatus::Finish)), done);
+
+ block = exit;
+
+ new StoreInst(ConstantInt::get(stateType, ui8(EState::Skip)), stateArg, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+
+ block = test;
+
+ const auto chop = GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(pass, skip, cast, block);
+ }
+
+ block = pass;
+
+ new StoreInst(ConstantInt::get(stateType, ui8(EState::Next)), stateArg, block);
+ const auto key = GetNodeValue(Key, ctx, block);
+ codegenKeyArg->CreateSetValue(ctx, block, key);
+ BranchInst::Create(pull, block);
+
+ block = pull;
+
+ GetNodeValue(streamArg, Output, ctx, block);
+ BranchInst::Create(loop, block);
+
+ return ctx.Func;
+ }
+
+ using TInputPtr = typename TCodegenInput::TFetchPtr;
+ using TOutputPtr = typename TCodegenOutput::TFetchPtr;
+
+ Function* InputFunc = nullptr;
+ Function* OutputFunc = nullptr;
+
+ TInputPtr InputPtr = nullptr;
+ TOutputPtr OutputPtr = nullptr;
+#endif
+ IComputationNode *const Stream;
+
+ IComputationExternalNode *const ItemArg;
+ IComputationNode *const Key;
+ IComputationExternalNode *const KeyArg;
+ IComputationNode *const Chop;
+
+ IComputationExternalNode *const Input;
+ IComputationNode *const Output;
+};
+
+}
+
+IComputationNode* WrapChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 7U, "Expected seven args.");
+ const auto type = callable.GetType()->GetReturnType();
+
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto keyResult = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto switchResult = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto output = LocateNode(ctx.NodeLocator, callable, 6);
+
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto keyArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto input = LocateExternalNode(ctx.NodeLocator, callable, 5);
+
+ if (type->IsFlow()) {
+ const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
+ return new TChopperFlowWrapper(ctx.Mutables, kind, stream, itemArg, keyResult, keyArg, switchResult, input, output);
+ } else if (type->IsStream()) {
+ return new TChopperWrapper(ctx.Mutables, stream, itemArg, keyResult, keyArg, switchResult, input, output);
+ }
+
+ THROW yexception() << "Expected flow or stream.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_chopper.h b/ydb/library/yql/minikql/comp_nodes/mkql_chopper.h
index 5b3ef88a02..3c5da555de 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_chopper.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_chopper.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_coalesce.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_coalesce.cpp
index 4f531c667d..826646a505 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_coalesce.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_coalesce.cpp
@@ -6,59 +6,59 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool Unpack>
-class TCoalesceWrapper : public TBinaryCodegeneratorNode<TCoalesceWrapper<Unpack>> {
- typedef TBinaryCodegeneratorNode<TCoalesceWrapper<Unpack>> TBaseComputation;
+namespace {
+
+template<bool Unpack>
+class TCoalesceWrapper : public TBinaryCodegeneratorNode<TCoalesceWrapper<Unpack>> {
+ typedef TBinaryCodegeneratorNode<TCoalesceWrapper<Unpack>> TBaseComputation;
public:
- TCoalesceWrapper(IComputationNode* left, IComputationNode* right, EValueRepresentation kind)
- : TBaseComputation(left, right, kind)
+ TCoalesceWrapper(IComputationNode* left, IComputationNode* right, EValueRepresentation kind)
+ : TBaseComputation(left, right, kind)
{
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- if (auto left = this->Left->GetValue(compCtx)) {
- return left.Release().template GetOptionalValueIf<Unpack>();
+ if (auto left = this->Left->GetValue(compCtx)) {
+ return left.Release().template GetOptionalValueIf<Unpack>();
}
- return this->Right->GetValue(compCtx).Release();
+ return this->Right->GetValue(compCtx).Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto left = GetNodeValue(this->Left, ctx, block);
-
- const auto null = BasicBlock::Create(context, "null", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(left->getType(), 2, "result", done);
-
- BranchInst::Create(good, null, IsExists(left, block), block);
-
- block = null;
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- result->addIncoming(right, block);
- BranchInst::Create(done, block);
-
- block = good;
-
- const auto unpack = Unpack ? GetOptionalValue(context, left, block) : left;
- result->addIncoming(unpack, block);
-
- BranchInst::Create(done, block);
- block = done;
- return result;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto left = GetNodeValue(this->Left, ctx, block);
+
+ const auto null = BasicBlock::Create(context, "null", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(left->getType(), 2, "result", done);
+
+ BranchInst::Create(good, null, IsExists(left, block), block);
+
+ block = null;
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ result->addIncoming(right, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+
+ const auto unpack = Unpack ? GetOptionalValue(context, left, block) : left;
+ result->addIncoming(unpack, block);
+
+ BranchInst::Create(done, block);
+ block = done;
+ return result;
+ }
+#endif
};
-}
-
+}
+
IComputationNode* WrapCoalesce(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
@@ -72,12 +72,12 @@ IComputationNode* WrapCoalesce(TCallable& callable, const TComputationNodeFactor
MKQL_ENSURE(leftType->IsSameType(*rightType), "Mismatch types");
}
- const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
-
- if (isRightOptional)
- return new TCoalesceWrapper<false>(LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1), kind);
- else
- return new TCoalesceWrapper<true>(LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1), kind);
+ const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
+
+ if (isRightOptional)
+ return new TCoalesceWrapper<false>(LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1), kind);
+ else
+ return new TCoalesceWrapper<true>(LocateNode(ctx.NodeLocator, callable, 0), LocateNode(ctx.NodeLocator, callable, 1), kind);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_collect.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_collect.cpp
index e77eefd822..db7d2c22f0 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_collect.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_collect.cpp
@@ -5,214 +5,214 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TCollectFlowWrapper : public TMutableCodegeneratorRootNode<TCollectFlowWrapper> {
-using TBaseComputation = TMutableCodegeneratorRootNode<TCollectFlowWrapper>;
-public:
- TCollectFlowWrapper(TComputationMutables& mutables, IComputationNode* flow)
- : TBaseComputation(mutables, EValueRepresentation::Boxed), Flow(flow)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- for (NUdf::TUnboxedValue list = ctx.HolderFactory.GetEmptyContainer();;) {
- auto item = Flow->GetValue(ctx);
- if (item.IsFinish()) {
- return list.Release();
- }
- MKQL_ENSURE(!item.IsYield(), "Unexpected flow status!");
- list = ctx.HolderFactory.Append(list.Release(), item.Release());
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto empty = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetEmptyContainer));
- const auto append = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Append));
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto burn = BasicBlock::Create(context, "burn", ctx.Func);
-
- const auto list = PHINode::Create(valueType, 2U, "list", work);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {factory->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, empty, PointerType::getUnqual(funType), "empty", block);
- const auto first = CallInst::Create(funcPtr, {factory}, "init", block);
- list->addIncoming(first, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, empty, PointerType::getUnqual(funType), "empty", block);
- CallInst::Create(funcPtr, {factory, ptr}, "", block);
- const auto first = new LoadInst(ptr, "init", block);
- list->addIncoming(first, block);
- }
-
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto select = SwitchInst::Create(item, good, 2U, block);
- select->addCase(GetFinish(context), done);
- select->addCase(GetYield(context), burn);
-
- {
- block = good;
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {factory->getType(), list->getType(), item->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, append, PointerType::getUnqual(funType), "append", block);
- const auto next = CallInst::Create(funcPtr, {factory, list, item}, "next", block);
- list->addIncoming(next, block);
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- const auto itemPtr = new AllocaInst(item->getType(), 0U, "item_ptr", block);
- new StoreInst(list, retPtr, block);
- new StoreInst(item, itemPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, append, PointerType::getUnqual(funType), "append", block);
- CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
- const auto next = new LoadInst(retPtr, "next", block);
- list->addIncoming(next, block);
- }
- BranchInst::Create(work, block);
- }
-
- {
- block = burn;
- const auto thrower = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TCollectFlowWrapper::Throw));
- const auto throwerPtr = CastInst::Create(Instruction::IntToPtr, thrower, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
- CallInst::Create(throwerPtr, {}, "", block);
- new UnreachableInst(context, block);
- }
-
- block = done;
- return list;
- }
-#endif
-private:
- [[noreturn]] static void Throw() {
- UdfTerminate("Unexpected flow status!");
- }
-
- void RegisterDependencies() const final {
- this->DependsOn(Flow);
- }
-
- IComputationNode* const Flow;
-};
-
+namespace {
+
+class TCollectFlowWrapper : public TMutableCodegeneratorRootNode<TCollectFlowWrapper> {
+using TBaseComputation = TMutableCodegeneratorRootNode<TCollectFlowWrapper>;
+public:
+ TCollectFlowWrapper(TComputationMutables& mutables, IComputationNode* flow)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed), Flow(flow)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ for (NUdf::TUnboxedValue list = ctx.HolderFactory.GetEmptyContainer();;) {
+ auto item = Flow->GetValue(ctx);
+ if (item.IsFinish()) {
+ return list.Release();
+ }
+ MKQL_ENSURE(!item.IsYield(), "Unexpected flow status!");
+ list = ctx.HolderFactory.Append(list.Release(), item.Release());
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto empty = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetEmptyContainer));
+ const auto append = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Append));
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto burn = BasicBlock::Create(context, "burn", ctx.Func);
+
+ const auto list = PHINode::Create(valueType, 2U, "list", work);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {factory->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, empty, PointerType::getUnqual(funType), "empty", block);
+ const auto first = CallInst::Create(funcPtr, {factory}, "init", block);
+ list->addIncoming(first, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, empty, PointerType::getUnqual(funType), "empty", block);
+ CallInst::Create(funcPtr, {factory, ptr}, "", block);
+ const auto first = new LoadInst(ptr, "init", block);
+ list->addIncoming(first, block);
+ }
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto select = SwitchInst::Create(item, good, 2U, block);
+ select->addCase(GetFinish(context), done);
+ select->addCase(GetYield(context), burn);
+
+ {
+ block = good;
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {factory->getType(), list->getType(), item->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, append, PointerType::getUnqual(funType), "append", block);
+ const auto next = CallInst::Create(funcPtr, {factory, list, item}, "next", block);
+ list->addIncoming(next, block);
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ const auto itemPtr = new AllocaInst(item->getType(), 0U, "item_ptr", block);
+ new StoreInst(list, retPtr, block);
+ new StoreInst(item, itemPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType(), itemPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, append, PointerType::getUnqual(funType), "append", block);
+ CallInst::Create(funcPtr, {factory, retPtr, retPtr, itemPtr}, "", block);
+ const auto next = new LoadInst(retPtr, "next", block);
+ list->addIncoming(next, block);
+ }
+ BranchInst::Create(work, block);
+ }
+
+ {
+ block = burn;
+ const auto thrower = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TCollectFlowWrapper::Throw));
+ const auto throwerPtr = CastInst::Create(Instruction::IntToPtr, thrower, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
+ CallInst::Create(throwerPtr, {}, "", block);
+ new UnreachableInst(context, block);
+ }
+
+ block = done;
+ return list;
+ }
+#endif
+private:
+ [[noreturn]] static void Throw() {
+ UdfTerminate("Unexpected flow status!");
+ }
+
+ void RegisterDependencies() const final {
+ this->DependsOn(Flow);
+ }
+
+ IComputationNode* const Flow;
+};
+
template <bool IsList>
-class TCollectWrapper : public TMutableCodegeneratorNode<TCollectWrapper<IsList>> {
- typedef TMutableCodegeneratorNode<TCollectWrapper<IsList>> TBaseComputation;
+class TCollectWrapper : public TMutableCodegeneratorNode<TCollectWrapper<IsList>> {
+ typedef TMutableCodegeneratorNode<TCollectWrapper<IsList>> TBaseComputation;
public:
TCollectWrapper(TComputationMutables& mutables, IComputationNode* seq)
- : TBaseComputation(mutables, EValueRepresentation::Boxed), Seq(seq)
- {}
+ : TBaseComputation(mutables, EValueRepresentation::Boxed), Seq(seq)
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto seq = Seq->GetValue(ctx);
- if (IsList && seq.GetElements()) {
- return seq.Release();
- }
-
- return ctx.HolderFactory.Collect<!IsList>(seq.Release());
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Collect<!IsList>));
-
- const auto seq = GetNodeValue(Seq, ctx, block);
-
- if constexpr (IsList) {
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, seq, ctx.Codegen, block);
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
- result->addIncoming(seq, block);
- BranchInst::Create(work, done, null, block);
-
- block = work;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(seq->getType(), {factory->getType(), seq->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, seq}, "res", block);
- result->addIncoming(res, block);
- } else {
- const auto ptr = new AllocaInst(seq->getType(), 0U, "ptr", block);
- new StoreInst(seq, ptr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, ptr, ptr}, "", block);
- const auto res = new LoadInst(ptr, "res", block);
- result->addIncoming(res, block);
+ if (IsList && seq.GetElements()) {
+ return seq.Release();
+ }
+
+ return ctx.HolderFactory.Collect<!IsList>(seq.Release());
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Collect<!IsList>));
+
+ const auto seq = GetNodeValue(Seq, ctx, block);
+
+ if constexpr (IsList) {
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, seq, ctx.Codegen, block);
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+ result->addIncoming(seq, block);
+ BranchInst::Create(work, done, null, block);
+
+ block = work;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(seq->getType(), {factory->getType(), seq->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, seq}, "res", block);
+ result->addIncoming(res, block);
+ } else {
+ const auto ptr = new AllocaInst(seq->getType(), 0U, "ptr", block);
+ new StoreInst(seq, ptr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, ptr, ptr}, "", block);
+ const auto res = new LoadInst(ptr, "res", block);
+ result->addIncoming(res, block);
+ }
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(seq->getType(), {factory->getType(), seq->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, seq}, "res", block);
+ return res;
+ } else {
+ const auto ptr = new AllocaInst(seq->getType(), 0U, "ptr", block);
+ new StoreInst(seq, ptr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, ptr, ptr}, "", block);
+ const auto res = new LoadInst(ptr, "res", block);
+ return res;
}
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(seq->getType(), {factory->getType(), seq->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, seq}, "res", block);
- return res;
- } else {
- const auto ptr = new AllocaInst(seq->getType(), 0U, "ptr", block);
- new StoreInst(seq, ptr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), ptr->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, ptr, ptr}, "", block);
- const auto res = new LoadInst(ptr, "res", block);
- return res;
- }
- }
+ }
}
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Seq);
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Seq);
}
IComputationNode* const Seq;
};
-}
-
+}
+
IComputationNode* WrapCollect(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- const auto type = callable.GetInput(0).GetStaticType();
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
-
- if (type->IsFlow()) {
- return new TCollectFlowWrapper(ctx.Mutables, list);
- } else if (type->IsList()) {
- return new TCollectWrapper<true>(ctx.Mutables, list);
- } else if (type->IsStream()) {
- return new TCollectWrapper<false>(ctx.Mutables, list);
+ const auto type = callable.GetInput(0).GetStaticType();
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+
+ if (type->IsFlow()) {
+ return new TCollectFlowWrapper(ctx.Mutables, list);
+ } else if (type->IsList()) {
+ return new TCollectWrapper<true>(ctx.Mutables, list);
+ } else if (type->IsStream()) {
+ return new TCollectWrapper<false>(ctx.Mutables, list);
}
-
- THROW yexception() << "Expected flow, list or stream.";
+
+ THROW yexception() << "Expected flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_combine.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_combine.cpp
index 984b299cbe..4e13f63a14 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_combine.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_combine.cpp
@@ -11,1019 +11,1019 @@ namespace NMiniKQL {
TStatKey Combine_FlushesCount("Combine_FlushesCount", true);
TStatKey Combine_MaxRowsCount("Combine_MaxRowsCount", false);
-namespace {
-
-using TEqualsPtr = bool(*)(NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod);
-using THashPtr = NYql::NUdf::THashType(*)(NUdf::TUnboxedValuePod);
-
-using TEqualsFunc = std::function<bool(NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod)>;
-using THashFunc = std::function<NYql::NUdf::THashType(NUdf::TUnboxedValuePod)>;
-
-using TDependsOn = std::function<void(IComputationNode*)>;
-using TOwn = std::function<void(IComputationExternalNode*)>;
-
-struct TCombineCoreNodes {
- IComputationExternalNode* ItemNode;
- IComputationExternalNode* KeyNode;
- IComputationExternalNode* StateNode;
-
- IComputationNode* KeyResultNode;
- IComputationNode* InitResultNode;
- IComputationNode* UpdateResultNode;
- IComputationNode* FinishResultNode;
-
- NUdf::TUnboxedValuePod ExtractKey(TComputationContext& compCtx, NUdf::TUnboxedValue value) const {
- ItemNode->SetValue(compCtx, std::move(value));
- auto key = KeyResultNode->GetValue(compCtx);
- const auto result = static_cast<const NUdf::TUnboxedValuePod&>(key);
- KeyNode->SetValue(compCtx, std::move(key));
- return result;
- }
-
- void ProcessItem(TComputationContext& compCtx, NUdf::TUnboxedValuePod& state) const {
- if (auto& st = static_cast<NUdf::TUnboxedValue&>(state); state.IsInvalid()) {
- st = InitResultNode->GetValue(compCtx);
- } else {
- StateNode->SetValue(compCtx, std::move(st));
- st = UpdateResultNode->GetValue(compCtx);
- }
- }
-
- NUdf::TUnboxedValuePod FinishItem(TComputationContext& compCtx, NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& state) const {
- KeyNode->SetValue(compCtx, std::move(key));
- StateNode->SetValue(compCtx, std::move(state));
- return FinishResultNode->GetValue(compCtx).Release();
- }
-
- void RegisterDependencies(const TDependsOn& dependsOn, const TOwn& own) const {
- own(ItemNode);
- own(KeyNode);
- own(StateNode);
-
- dependsOn(KeyResultNode);
- dependsOn(InitResultNode);
- dependsOn(UpdateResultNode);
- dependsOn(FinishResultNode);
- }
-};
-
-class TState : public TComputationValue<TState> {
-using TBase = TComputationValue<TState>;
-using TStateMap = std::unordered_map<
- NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod,
- THashFunc, TEqualsFunc,
- TMKQLAllocator<std::pair<const NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod>>>;
-public:
- TState(TMemoryUsageInfo* memInfo, const THashFunc& hash, const TEqualsFunc& equal)
- : TBase(memInfo), States(0, hash, equal)
- {
- States.max_load_factor(1.2f);
- }
-
- NUdf::TUnboxedValuePod& At(const NUdf::TUnboxedValuePod key) {
- const auto ins = States.emplace(key, NUdf::TUnboxedValuePod::Invalid());
- if (ins.second) {
- key.Ref();
- }
- return ins.first->second;
- }
-
- bool IsEmpty() const {
- return States.empty();
- }
-
- void PushStat(IStatsRegistry* stats) const {
- if (!States.empty()) {
- MKQL_SET_MAX_STAT(stats, Combine_MaxRowsCount, static_cast<i64>(States.size()));
- MKQL_INC_STAT(stats, Combine_FlushesCount);
- }
- }
-
- bool Extract(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& state) {
- if (States.empty()) {
- return false;
- }
-
- const auto& node = States.extract(States.cbegin());
- static_cast<NUdf::TUnboxedValuePod&>(key) = node.key();
- static_cast<NUdf::TUnboxedValuePod&>(state) = node.mapped();
- return true;
- }
-
- NUdf::EFetchStatus InputStatus = NUdf::EFetchStatus::Ok;
-
-private:
- TStateMap States;
-};
-
-template <bool IsMultiRowState, bool StateContainerOpt, bool TrackRss>
-class TCombineCoreFlowWrapper: public std::conditional_t<IsMultiRowState,
- TPairStateFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>,
- TStatefulFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
- using TBaseComputation = std::conditional_t<IsMultiRowState,
- TPairStateFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>,
- TStatefulFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>>;
-public:
- TCombineCoreFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, const TCombineCoreNodes& nodes, TKeyTypes&& keyTypes, bool isTuple, ui64 memLimit)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
- , Flow(flow)
- , Nodes(nodes)
- , KeyTypes(std::move(keyTypes))
- , IsTuple(isTuple)
- , MemLimit(memLimit)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- while (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
- if (ptr->IsEmpty()) {
- switch (ptr->InputStatus) {
- case NUdf::EFetchStatus::Ok: break;
- case NUdf::EFetchStatus::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case NUdf::EFetchStatus::Yield:
- ptr->InputStatus = NUdf::EFetchStatus::Ok;
- return NUdf::TUnboxedValuePod::MakeYield();
- }
-
- const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
-
- do {
- auto item = Flow->GetValue(ctx);
- if (item.IsYield()) {
- ptr->InputStatus = NUdf::EFetchStatus::Yield;
- break;
- } else if (item.IsFinish()) {
- ptr->InputStatus = NUdf::EFetchStatus::Finish;
- break;
- }
- const auto key = Nodes.ExtractKey(ctx, item);
- Nodes.ProcessItem(ctx, ptr->At(key));
- } while (!ctx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
-
- ptr->PushStat(ctx.Stats);
- }
-
- if (NUdf::TUnboxedValue key, state; ptr->Extract(key, state)) {
- if (const auto out = Nodes.FinishItem(ctx, key, state)) {
- return out.template GetOptionalValueIf<!IsMultiRowState && StateContainerOpt>();
- }
- }
- }
+namespace {
+
+using TEqualsPtr = bool(*)(NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod);
+using THashPtr = NYql::NUdf::THashType(*)(NUdf::TUnboxedValuePod);
+
+using TEqualsFunc = std::function<bool(NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod)>;
+using THashFunc = std::function<NYql::NUdf::THashType(NUdf::TUnboxedValuePod)>;
+
+using TDependsOn = std::function<void(IComputationNode*)>;
+using TOwn = std::function<void(IComputationExternalNode*)>;
+
+struct TCombineCoreNodes {
+ IComputationExternalNode* ItemNode;
+ IComputationExternalNode* KeyNode;
+ IComputationExternalNode* StateNode;
+
+ IComputationNode* KeyResultNode;
+ IComputationNode* InitResultNode;
+ IComputationNode* UpdateResultNode;
+ IComputationNode* FinishResultNode;
+
+ NUdf::TUnboxedValuePod ExtractKey(TComputationContext& compCtx, NUdf::TUnboxedValue value) const {
+ ItemNode->SetValue(compCtx, std::move(value));
+ auto key = KeyResultNode->GetValue(compCtx);
+ const auto result = static_cast<const NUdf::TUnboxedValuePod&>(key);
+ KeyNode->SetValue(compCtx, std::move(key));
+ return result;
+ }
+
+ void ProcessItem(TComputationContext& compCtx, NUdf::TUnboxedValuePod& state) const {
+ if (auto& st = static_cast<NUdf::TUnboxedValue&>(state); state.IsInvalid()) {
+ st = InitResultNode->GetValue(compCtx);
+ } else {
+ StateNode->SetValue(compCtx, std::move(st));
+ st = UpdateResultNode->GetValue(compCtx);
+ }
+ }
+
+ NUdf::TUnboxedValuePod FinishItem(TComputationContext& compCtx, NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& state) const {
+ KeyNode->SetValue(compCtx, std::move(key));
+ StateNode->SetValue(compCtx, std::move(state));
+ return FinishResultNode->GetValue(compCtx).Release();
+ }
+
+ void RegisterDependencies(const TDependsOn& dependsOn, const TOwn& own) const {
+ own(ItemNode);
+ own(KeyNode);
+ own(StateNode);
+
+ dependsOn(KeyResultNode);
+ dependsOn(InitResultNode);
+ dependsOn(UpdateResultNode);
+ dependsOn(FinishResultNode);
+ }
+};
+
+class TState : public TComputationValue<TState> {
+using TBase = TComputationValue<TState>;
+using TStateMap = std::unordered_map<
+ NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod,
+ THashFunc, TEqualsFunc,
+ TMKQLAllocator<std::pair<const NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod>>>;
+public:
+ TState(TMemoryUsageInfo* memInfo, const THashFunc& hash, const TEqualsFunc& equal)
+ : TBase(memInfo), States(0, hash, equal)
+ {
+ States.max_load_factor(1.2f);
+ }
+
+ NUdf::TUnboxedValuePod& At(const NUdf::TUnboxedValuePod key) {
+ const auto ins = States.emplace(key, NUdf::TUnboxedValuePod::Invalid());
+ if (ins.second) {
+ key.Ref();
+ }
+ return ins.first->second;
+ }
+
+ bool IsEmpty() const {
+ return States.empty();
+ }
+
+ void PushStat(IStatsRegistry* stats) const {
+ if (!States.empty()) {
+ MKQL_SET_MAX_STAT(stats, Combine_MaxRowsCount, static_cast<i64>(States.size()));
+ MKQL_INC_STAT(stats, Combine_FlushesCount);
+ }
+ }
+
+ bool Extract(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& state) {
+ if (States.empty()) {
+ return false;
+ }
+
+ const auto& node = States.extract(States.cbegin());
+ static_cast<NUdf::TUnboxedValuePod&>(key) = node.key();
+ static_cast<NUdf::TUnboxedValuePod&>(state) = node.mapped();
+ return true;
+ }
+
+ NUdf::EFetchStatus InputStatus = NUdf::EFetchStatus::Ok;
+
+private:
+ TStateMap States;
+};
+
+template <bool IsMultiRowState, bool StateContainerOpt, bool TrackRss>
+class TCombineCoreFlowWrapper: public std::conditional_t<IsMultiRowState,
+ TPairStateFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>,
+ TStatefulFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+ using TBaseComputation = std::conditional_t<IsMultiRowState,
+ TPairStateFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>,
+ TStatefulFlowCodegeneratorNode<TCombineCoreFlowWrapper<IsMultiRowState, StateContainerOpt, TrackRss>>>;
+public:
+ TCombineCoreFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, const TCombineCoreNodes& nodes, TKeyTypes&& keyTypes, bool isTuple, ui64 memLimit)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
+ , Flow(flow)
+ , Nodes(nodes)
+ , KeyTypes(std::move(keyTypes))
+ , IsTuple(isTuple)
+ , MemLimit(memLimit)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ while (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
+ if (ptr->IsEmpty()) {
+ switch (ptr->InputStatus) {
+ case NUdf::EFetchStatus::Ok: break;
+ case NUdf::EFetchStatus::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case NUdf::EFetchStatus::Yield:
+ ptr->InputStatus = NUdf::EFetchStatus::Ok;
+ return NUdf::TUnboxedValuePod::MakeYield();
+ }
+
+ const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
+
+ do {
+ auto item = Flow->GetValue(ctx);
+ if (item.IsYield()) {
+ ptr->InputStatus = NUdf::EFetchStatus::Yield;
+ break;
+ } else if (item.IsFinish()) {
+ ptr->InputStatus = NUdf::EFetchStatus::Finish;
+ break;
+ }
+ const auto key = Nodes.ExtractKey(ctx, item);
+ Nodes.ProcessItem(ctx, ptr->At(key));
+ } while (!ctx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
+
+ ptr->PushStat(ctx.Stats);
+ }
+
+ if (NUdf::TUnboxedValue key, state; ptr->Extract(key, state)) {
+ if (const auto out = Nodes.FinishItem(ctx, key, state)) {
+ return out.template GetOptionalValueIf<!IsMultiRowState && StateContainerOpt>();
+ }
+ }
+ }
Y_UNREACHABLE();
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, NUdf::TUnboxedValue& current, TComputationContext& ctx) const {
- while (true) {
- if (current.HasValue()) {
- if constexpr (StateContainerOpt) {
- NUdf::TUnboxedValue result;
- switch (const auto status = current.Fetch(result)) {
- case NUdf::EFetchStatus::Ok: return result.Release();
- case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
- case NUdf::EFetchStatus::Finish: break;
- }
- } else if (NUdf::TUnboxedValue result; current.Next(result)) {
- return result.Release();
- }
- current.Clear();
- }
-
- if (NUdf::TUnboxedValue output = DoCalculate(state, ctx); output.IsSpecial()) {
- return output.Release();
- } else {
- current = StateContainerOpt ? std::move(output) : output.GetListIterator();
- }
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.ItemNode);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.KeyNode);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.StateNode);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- statusType, // status
- structPtrType // map
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto onePtr = new AllocaInst(valueType, 0U, "one_ptr", &ctx.Func->getEntryBlock().back());
- const auto twoPtr = new AllocaInst(valueType, 0U, "two_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(ConstantInt::get(valueType, 0), onePtr, block);
- new StoreInst(ConstantInt::get(valueType, 0), twoPtr, block);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
-
- BranchInst::Create(main, make, HasValue(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TCombineCoreFlowWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
- const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
- const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "cast", block);
- const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(next, full, empty, block);
-
- {
- block = next;
-
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
-
- const auto last = new LoadInst(statusPtr, "last", block);
-
- result->addIncoming(GetFinish(context), block);
- const auto choise = SwitchInst::Create(last, pull, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), over);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
- result->addIncoming(GetYield(context), block);
- BranchInst::Create(over, block);
-
- block = pull;
-
- const auto used = GetMemoryUsed(MemLimit, ctx, block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto finsh = IsFinish(item, block);
- const auto yield = IsYield(item, block);
- const auto special = BinaryOperator::CreateOr(finsh, yield, "special", block);
-
- const auto fin = SelectInst::Create(finsh, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "fin", block);
- const auto save = SelectInst::Create(yield, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), fin, "save", block);
- new StoreInst(save, statusPtr, block);
-
- BranchInst::Create(done, good, special, block);
-
- block = good;
-
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto key = GetNodeValue(Nodes.KeyResultNode, ctx, block);
- codegenKeyArg->CreateSetValue(ctx, block, key);
-
- const auto keyParam = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
- new AllocaInst(key->getType(), 0U, "key_param", &main->back()) : key;
-
- if (NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget()) {
- new StoreInst(key, keyParam, block);
- }
-
- const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::At));
- const auto atType = FunctionType::get(ptrValueType, {stateArg->getType(), keyParam->getType()}, false);
- const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
- const auto place = CallInst::Create(atPtr, {stateArg, keyParam}, "place", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
-
- BranchInst::Create(init, next, IsInvalid(place, block), block);
-
- block = init;
- GetNodeValue(place, Nodes.InitResultNode, ctx, block);
- BranchInst::Create(test, block);
-
- block = next;
- codegenStateArg->CreateSetValue(ctx, block, place);
- GetNodeValue(place, Nodes.UpdateResultNode, ctx, block);
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
- BranchInst::Create(done, loop, check, block);
-
- block = done;
-
- const auto stat = ctx.GetStat();
- const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
- const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
- const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
- CallInst::Create(statPtr, {stateArg, stat}, "", block);
-
- BranchInst::Create(full, block);
- }
-
- {
- block = full;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
- const auto extractType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), onePtr->getType(), twoPtr->getType()}, false);
- const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
- const auto has = CallInst::Create(extractPtr, {stateArg, onePtr, twoPtr}, "has", block);
-
- BranchInst::Create(good, more, has, block);
-
- block = good;
-
- codegenKeyArg->CreateSetValue(ctx, block, onePtr);
- codegenStateArg->CreateSetValue(ctx, block, twoPtr);
-
- const auto value = GetNodeValue(Nodes.FinishResultNode, ctx, block);
- if constexpr (IsMultiRowState) {
- result->addIncoming(value, block);
- BranchInst::Create(over, block);
- } else if constexpr (StateContainerOpt) {
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- BranchInst::Create(more, exit, IsEmpty(value, block), block);
- block = exit;
-
- const auto strip = GetOptionalValue(context, value, block);
- result->addIncoming(strip, block);
- BranchInst::Create(over, block);
- } else {
- result->addIncoming(value, block);
- BranchInst::Create(more, over, IsEmpty(value, block), block);
- }
- }
-
- block = over;
- return result;
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, Value* currentPtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto statusType = Type::getInt32Ty(context);
- const auto valueType = Type::getInt128Ty(context);
- const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, StateContainerOpt ? 3U : 2U, "result", over);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto current = new LoadInst(currentPtr, "current", block);
- BranchInst::Create(pull, skip, HasValue(current, block), block);
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- block = pull;
-
- if constexpr (StateContainerOpt) {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
-
- result->addIncoming(GetYield(context), block);
- const auto choise = SwitchInst::Create(status, good, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
- } else {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
- BranchInst::Create(good, next, status, block);
- }
-
- block = good;
- const auto value = new LoadInst(valuePtr, "value", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
- result->addIncoming(value, block);
- BranchInst::Create(over, block);
-
- block = next;
- UnRefBoxed(current, ctx, block);
- new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
- BranchInst::Create(skip, block);
- }
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- block = skip;
-
- const auto list = DoGenerateGetValue(ctx, statePtr, block);
- result->addIncoming(list, block);
- BranchInst::Create(over, good, IsSpecial(list, block), block);
-
- block = good;
- if constexpr (StateContainerOpt) {
- new StoreInst(list, currentPtr, block);
- AddRefBoxed(list, ctx, block);
- } else {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
- CleanupBoxed(list, ctx, block);
- }
- BranchInst::Create(more, block);
- }
-
- block = over;
- return result;
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
-#ifdef MKQL_DISABLE_CODEGEN
- state = ctx.HolderFactory.Create<TState>(TValueHasher(KeyTypes, IsTuple), TValueEqual(KeyTypes, IsTuple));
-#else
- state = ctx.HolderFactory.Create<TState>(
- ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TValueHasher(KeyTypes, IsTuple)),
- ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TValueEqual(KeyTypes, IsTuple))
- );
-#endif
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- Nodes.RegisterDependencies(
- [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
- [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
- );
- }
- }
-
- IComputationNode* const Flow;
- const TCombineCoreNodes Nodes;
- const TKeyTypes KeyTypes;
- const bool IsTuple;
- const ui64 MemLimit;
-#ifndef MKQL_DISABLE_CODEGEN
- TEqualsPtr Equals = nullptr;
- THashPtr Hash = nullptr;
-
- Function* EqualsFunc = nullptr;
- Function* HashFunc = nullptr;
-
- template <bool EqualsOrHash>
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (EqualsFunc) {
- Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
- }
- if (HashFunc) {
- Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), IsTuple, KeyTypes));
- codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), IsTuple, KeyTypes));
- }
-#endif
-};
-
-template <bool IsMultiRowState, bool StateContainerOpt, bool TrackRss>
-class TCombineCoreWrapper: public TCustomValueCodegeneratorNode<TCombineCoreWrapper<IsMultiRowState, StateContainerOpt, TrackRss>> {
- typedef TCustomValueCodegeneratorNode<TCombineCoreWrapper<IsMultiRowState, StateContainerOpt, TrackRss>> TBaseComputation;
-#ifndef MKQL_DISABLE_CODEGEN
- using TCodegenValue = std::conditional_t<IsMultiRowState, TStreamCodegenSelfStatePlusValue<TState>, TStreamCodegenSelfStateValue<TState>>;
-#endif
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, NUdf::TUnboxedValue& current, TComputationContext& ctx) const {
+ while (true) {
+ if (current.HasValue()) {
+ if constexpr (StateContainerOpt) {
+ NUdf::TUnboxedValue result;
+ switch (const auto status = current.Fetch(result)) {
+ case NUdf::EFetchStatus::Ok: return result.Release();
+ case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
+ case NUdf::EFetchStatus::Finish: break;
+ }
+ } else if (NUdf::TUnboxedValue result; current.Next(result)) {
+ return result.Release();
+ }
+ current.Clear();
+ }
+
+ if (NUdf::TUnboxedValue output = DoCalculate(state, ctx); output.IsSpecial()) {
+ return output.Release();
+ } else {
+ current = StateContainerOpt ? std::move(output) : output.GetListIterator();
+ }
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.ItemNode);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.KeyNode);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.StateNode);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ statusType, // status
+ structPtrType // map
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto onePtr = new AllocaInst(valueType, 0U, "one_ptr", &ctx.Func->getEntryBlock().back());
+ const auto twoPtr = new AllocaInst(valueType, 0U, "two_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(ConstantInt::get(valueType, 0), onePtr, block);
+ new StoreInst(ConstantInt::get(valueType, 0), twoPtr, block);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+
+ BranchInst::Create(main, make, HasValue(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TCombineCoreFlowWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
+ const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
+ const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "cast", block);
+ const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(next, full, empty, block);
+
+ {
+ block = next;
+
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
+
+ const auto last = new LoadInst(statusPtr, "last", block);
+
+ result->addIncoming(GetFinish(context), block);
+ const auto choise = SwitchInst::Create(last, pull, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), over);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
+ result->addIncoming(GetYield(context), block);
+ BranchInst::Create(over, block);
+
+ block = pull;
+
+ const auto used = GetMemoryUsed(MemLimit, ctx, block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto finsh = IsFinish(item, block);
+ const auto yield = IsYield(item, block);
+ const auto special = BinaryOperator::CreateOr(finsh, yield, "special", block);
+
+ const auto fin = SelectInst::Create(finsh, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "fin", block);
+ const auto save = SelectInst::Create(yield, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), fin, "save", block);
+ new StoreInst(save, statusPtr, block);
+
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto key = GetNodeValue(Nodes.KeyResultNode, ctx, block);
+ codegenKeyArg->CreateSetValue(ctx, block, key);
+
+ const auto keyParam = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
+ new AllocaInst(key->getType(), 0U, "key_param", &main->back()) : key;
+
+ if (NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget()) {
+ new StoreInst(key, keyParam, block);
+ }
+
+ const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::At));
+ const auto atType = FunctionType::get(ptrValueType, {stateArg->getType(), keyParam->getType()}, false);
+ const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
+ const auto place = CallInst::Create(atPtr, {stateArg, keyParam}, "place", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+
+ BranchInst::Create(init, next, IsInvalid(place, block), block);
+
+ block = init;
+ GetNodeValue(place, Nodes.InitResultNode, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = next;
+ codegenStateArg->CreateSetValue(ctx, block, place);
+ GetNodeValue(place, Nodes.UpdateResultNode, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
+ BranchInst::Create(done, loop, check, block);
+
+ block = done;
+
+ const auto stat = ctx.GetStat();
+ const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
+ const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
+ const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
+ CallInst::Create(statPtr, {stateArg, stat}, "", block);
+
+ BranchInst::Create(full, block);
+ }
+
+ {
+ block = full;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
+ const auto extractType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), onePtr->getType(), twoPtr->getType()}, false);
+ const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
+ const auto has = CallInst::Create(extractPtr, {stateArg, onePtr, twoPtr}, "has", block);
+
+ BranchInst::Create(good, more, has, block);
+
+ block = good;
+
+ codegenKeyArg->CreateSetValue(ctx, block, onePtr);
+ codegenStateArg->CreateSetValue(ctx, block, twoPtr);
+
+ const auto value = GetNodeValue(Nodes.FinishResultNode, ctx, block);
+ if constexpr (IsMultiRowState) {
+ result->addIncoming(value, block);
+ BranchInst::Create(over, block);
+ } else if constexpr (StateContainerOpt) {
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ BranchInst::Create(more, exit, IsEmpty(value, block), block);
+ block = exit;
+
+ const auto strip = GetOptionalValue(context, value, block);
+ result->addIncoming(strip, block);
+ BranchInst::Create(over, block);
+ } else {
+ result->addIncoming(value, block);
+ BranchInst::Create(more, over, IsEmpty(value, block), block);
+ }
+ }
+
+ block = over;
+ return result;
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, Value* currentPtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto statusType = Type::getInt32Ty(context);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, StateContainerOpt ? 3U : 2U, "result", over);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto current = new LoadInst(currentPtr, "current", block);
+ BranchInst::Create(pull, skip, HasValue(current, block), block);
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ block = pull;
+
+ if constexpr (StateContainerOpt) {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
+
+ result->addIncoming(GetYield(context), block);
+ const auto choise = SwitchInst::Create(status, good, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
+ } else {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
+ BranchInst::Create(good, next, status, block);
+ }
+
+ block = good;
+ const auto value = new LoadInst(valuePtr, "value", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
+ result->addIncoming(value, block);
+ BranchInst::Create(over, block);
+
+ block = next;
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
+ BranchInst::Create(skip, block);
+ }
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ block = skip;
+
+ const auto list = DoGenerateGetValue(ctx, statePtr, block);
+ result->addIncoming(list, block);
+ BranchInst::Create(over, good, IsSpecial(list, block), block);
+
+ block = good;
+ if constexpr (StateContainerOpt) {
+ new StoreInst(list, currentPtr, block);
+ AddRefBoxed(list, ctx, block);
+ } else {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
+ CleanupBoxed(list, ctx, block);
+ }
+ BranchInst::Create(more, block);
+ }
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+#ifdef MKQL_DISABLE_CODEGEN
+ state = ctx.HolderFactory.Create<TState>(TValueHasher(KeyTypes, IsTuple), TValueEqual(KeyTypes, IsTuple));
+#else
+ state = ctx.HolderFactory.Create<TState>(
+ ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TValueHasher(KeyTypes, IsTuple)),
+ ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TValueEqual(KeyTypes, IsTuple))
+ );
+#endif
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ Nodes.RegisterDependencies(
+ [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
+ [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
+ );
+ }
+ }
+
+ IComputationNode* const Flow;
+ const TCombineCoreNodes Nodes;
+ const TKeyTypes KeyTypes;
+ const bool IsTuple;
+ const ui64 MemLimit;
+#ifndef MKQL_DISABLE_CODEGEN
+ TEqualsPtr Equals = nullptr;
+ THashPtr Hash = nullptr;
+
+ Function* EqualsFunc = nullptr;
+ Function* HashFunc = nullptr;
+
+ template <bool EqualsOrHash>
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (EqualsFunc) {
+ Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
+ }
+ if (HashFunc) {
+ Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), IsTuple, KeyTypes));
+ codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), IsTuple, KeyTypes));
+ }
+#endif
+};
+
+template <bool IsMultiRowState, bool StateContainerOpt, bool TrackRss>
+class TCombineCoreWrapper: public TCustomValueCodegeneratorNode<TCombineCoreWrapper<IsMultiRowState, StateContainerOpt, TrackRss>> {
+ typedef TCustomValueCodegeneratorNode<TCombineCoreWrapper<IsMultiRowState, StateContainerOpt, TrackRss>> TBaseComputation;
+#ifndef MKQL_DISABLE_CODEGEN
+ using TCodegenValue = std::conditional_t<IsMultiRowState, TStreamCodegenSelfStatePlusValue<TState>, TStreamCodegenSelfStateValue<TState>>;
+#endif
public:
- class TStreamValue : public TState {
+ class TStreamValue : public TState {
public:
- TStreamValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream, const TCombineCoreNodes& nodes, ui64 memLimit, TComputationContext& compCtx, const THashFunc& hash, const TEqualsFunc& equal)
- : TState(memInfo, hash, equal)
+ TStreamValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream, const TCombineCoreNodes& nodes, ui64 memLimit, TComputationContext& compCtx, const THashFunc& hash, const TEqualsFunc& equal)
+ : TState(memInfo, hash, equal)
, Stream(std::move(stream))
- , Nodes(nodes)
- , MemLimit(memLimit)
+ , Nodes(nodes)
+ , MemLimit(memLimit)
, CompCtx(compCtx)
- {}
+ {}
private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- for (;;) {
- if (IsMultiRowState && Iterator) {
- if constexpr (StateContainerOpt) {
- const auto status = Iterator.Fetch(result);
- if (status != NUdf::EFetchStatus::Finish) {
- return status;
- }
-
- Iterator.Clear();
- } else if (Iterator.Next(result)) {
- return NUdf::EFetchStatus::Ok;
- }
- Iterator.Clear();
+ for (;;) {
+ if (IsMultiRowState && Iterator) {
+ if constexpr (StateContainerOpt) {
+ const auto status = Iterator.Fetch(result);
+ if (status != NUdf::EFetchStatus::Finish) {
+ return status;
+ }
+
+ Iterator.Clear();
+ } else if (Iterator.Next(result)) {
+ return NUdf::EFetchStatus::Ok;
+ }
+ Iterator.Clear();
}
- if (IsEmpty()) {
- switch (InputStatus) {
- case NUdf::EFetchStatus::Ok: break;
- case NUdf::EFetchStatus::Finish:
- return NUdf::EFetchStatus::Finish;
- case NUdf::EFetchStatus::Yield:
- InputStatus = NUdf::EFetchStatus::Ok;
- return NUdf::EFetchStatus::Yield;
+ if (IsEmpty()) {
+ switch (InputStatus) {
+ case NUdf::EFetchStatus::Ok: break;
+ case NUdf::EFetchStatus::Finish:
+ return NUdf::EFetchStatus::Finish;
+ case NUdf::EFetchStatus::Yield:
+ InputStatus = NUdf::EFetchStatus::Ok;
+ return NUdf::EFetchStatus::Yield;
}
- const auto initUsage = MemLimit ? CompCtx.HolderFactory.GetMemoryUsed() : 0ULL;
-
- do {
- NUdf::TUnboxedValue item;
- InputStatus = Stream.Fetch(item);
- if (NUdf::EFetchStatus::Ok != InputStatus) {
- break;
- }
-
- const auto key = Nodes.ExtractKey(CompCtx, item);
- Nodes.ProcessItem(CompCtx, At(key));
- } while (!CompCtx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
-
- PushStat(CompCtx.Stats);
+ const auto initUsage = MemLimit ? CompCtx.HolderFactory.GetMemoryUsed() : 0ULL;
+
+ do {
+ NUdf::TUnboxedValue item;
+ InputStatus = Stream.Fetch(item);
+ if (NUdf::EFetchStatus::Ok != InputStatus) {
+ break;
+ }
+
+ const auto key = Nodes.ExtractKey(CompCtx, item);
+ Nodes.ProcessItem(CompCtx, At(key));
+ } while (!CompCtx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
+
+ PushStat(CompCtx.Stats);
}
- if (NUdf::TUnboxedValue key, state; Extract(key, state)) {
- NUdf::TUnboxedValue finishItem = Nodes.FinishItem(CompCtx, key, state);
-
- if constexpr (IsMultiRowState) {
- Iterator = StateContainerOpt ? std::move(finishItem) : finishItem.GetListIterator();
- } else {
- result = finishItem.Release().GetOptionalValueIf<StateContainerOpt>();
- return NUdf::EFetchStatus::Ok;
- }
+ if (NUdf::TUnboxedValue key, state; Extract(key, state)) {
+ NUdf::TUnboxedValue finishItem = Nodes.FinishItem(CompCtx, key, state);
+
+ if constexpr (IsMultiRowState) {
+ Iterator = StateContainerOpt ? std::move(finishItem) : finishItem.GetListIterator();
+ } else {
+ result = finishItem.Release().GetOptionalValueIf<StateContainerOpt>();
+ return NUdf::EFetchStatus::Ok;
+ }
}
}
}
- const NUdf::TUnboxedValue Stream;
- NUdf::TUnboxedValue Iterator;
- const TCombineCoreNodes Nodes;
- const ui64 MemLimit;
+ const NUdf::TUnboxedValue Stream;
+ NUdf::TUnboxedValue Iterator;
+ const TCombineCoreNodes Nodes;
+ const ui64 MemLimit;
TComputationContext& CompCtx;
};
- TCombineCoreWrapper(TComputationMutables& mutables, IComputationNode* stream, const TCombineCoreNodes& nodes, TKeyTypes&& keyTypes, bool isTuple, ui64 memLimit)
- : TBaseComputation(mutables)
- , Stream(stream)
- , Nodes(nodes)
- , KeyTypes(std::move(keyTypes))
- , IsTuple(isTuple)
- , MemLimit(memLimit)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Combine)
- return ctx.HolderFactory.Create<TCodegenValue>(Combine, &ctx, Stream->GetValue(ctx),
- ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TValueHasher(KeyTypes, IsTuple)),
- ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TValueEqual(KeyTypes, IsTuple))
- );
-#endif
- return ctx.HolderFactory.Create<TStreamValue>(Stream->GetValue(ctx), Nodes, MemLimit, ctx, TValueHasher(KeyTypes, IsTuple), TValueEqual(KeyTypes, IsTuple));
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Stream);
- Nodes.RegisterDependencies(
- [this](IComputationNode* node){ this->DependsOn(node); },
- [this](IComputationExternalNode* node){ this->Own(node); }
- );
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- template <bool EqualsOrHash>
- TString MakeFuncName() const {
- TStringStream out;
- out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- codegen->ExportSymbol(CombineFunc = GenerateCombine(codegen));
- codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeFuncName<true>(), IsTuple, KeyTypes));
- codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeFuncName<false>(), IsTuple, KeyTypes));
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (CombineFunc) {
- Combine = reinterpret_cast<TCombinePtr>(codegen->GetPointerToFunction(CombineFunc));
- }
- if (EqualsFunc) {
- Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
- }
- if (HashFunc) {
- Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
- }
- }
-
- Function* GenerateCombine(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.ItemNode);
- const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.KeyNode);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.StateNode);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto& name = this->MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(ptrValueType) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- statusType, // status
- structPtrType // map
- });
- const auto statePtrType = PointerType::getUnqual(stateType);
- const auto funcType = IsMultiRowState ?
- FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType, ptrValueType}, false):
- FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType}, false);
-
- TCodegenContext ctx(codegen);
+ TCombineCoreWrapper(TComputationMutables& mutables, IComputationNode* stream, const TCombineCoreNodes& nodes, TKeyTypes&& keyTypes, bool isTuple, ui64 memLimit)
+ : TBaseComputation(mutables)
+ , Stream(stream)
+ , Nodes(nodes)
+ , KeyTypes(std::move(keyTypes))
+ , IsTuple(isTuple)
+ , MemLimit(memLimit)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Combine)
+ return ctx.HolderFactory.Create<TCodegenValue>(Combine, &ctx, Stream->GetValue(ctx),
+ ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TValueHasher(KeyTypes, IsTuple)),
+ ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TValueEqual(KeyTypes, IsTuple))
+ );
+#endif
+ return ctx.HolderFactory.Create<TStreamValue>(Stream->GetValue(ctx), Nodes, MemLimit, ctx, TValueHasher(KeyTypes, IsTuple), TValueEqual(KeyTypes, IsTuple));
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Stream);
+ Nodes.RegisterDependencies(
+ [this](IComputationNode* node){ this->DependsOn(node); },
+ [this](IComputationExternalNode* node){ this->Own(node); }
+ );
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ template <bool EqualsOrHash>
+ TString MakeFuncName() const {
+ TStringStream out;
+ out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ codegen->ExportSymbol(CombineFunc = GenerateCombine(codegen));
+ codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeFuncName<true>(), IsTuple, KeyTypes));
+ codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeFuncName<false>(), IsTuple, KeyTypes));
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (CombineFunc) {
+ Combine = reinterpret_cast<TCombinePtr>(codegen->GetPointerToFunction(CombineFunc));
+ }
+ if (EqualsFunc) {
+ Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
+ }
+ if (HashFunc) {
+ Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
+ }
+ }
+
+ Function* GenerateCombine(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.ItemNode);
+ const auto codegenKeyArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.KeyNode);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(Nodes.StateNode);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenKeyArg, "Key arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto& name = this->MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(ptrValueType) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ statusType, // status
+ structPtrType // map
+ });
+ const auto statePtrType = PointerType::getUnqual(stateType);
+ const auto funcType = IsMultiRowState ?
+ FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType, ptrValueType}, false):
+ FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto stateArg = &*++args;
- const auto currArg = IsMultiRowState ? &*++args : nullptr;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- auto block = main;
-
- const auto onePtr = new AllocaInst(valueType, 0U, "one_ptr", block);
- const auto twoPtr = new AllocaInst(valueType, 0U, "two_ptr", block);
- new StoreInst(ConstantInt::get(valueType, 0), onePtr, block);
- new StoreInst(ConstantInt::get(valueType, 0), twoPtr, block);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- if constexpr (IsMultiRowState) {
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto current = new LoadInst(currArg, "current", block);
- BranchInst::Create(skip, pull, IsEmpty(current, block), block);
-
- block = pull;
-
- const auto status = StateContainerOpt ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, codegen, block, valuePtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, codegen, block, valuePtr);
-
- const auto icmp = StateContainerOpt ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block): status;
-
- BranchInst::Create(good, next, icmp, block);
-
- block = good;
- ReturnInst::Create(context, StateContainerOpt ? status : ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
-
- block = next;
- UnRefBoxed(current, ctx, block);
- new StoreInst(ConstantInt::get(current->getType(), 0), currArg, block);
- BranchInst::Create(skip, block);
-
- block = skip;
- }
-
- const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
- const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
- const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "cast", block);
- const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(next, full, empty, block);
-
- {
- block = next;
-
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
-
- const auto last = new LoadInst(statusPtr, "last", block);
-
- const auto choise = SwitchInst::Create(last, pull, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- ReturnInst::Create(context, last, block);
-
- block = pull;
-
- const auto used = GetMemoryUsed(MemLimit, ctx, block);
-
- const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto fetch = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, onePtr);
-
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, fetch, ConstantInt::get(fetch->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
- new StoreInst(fetch, statusPtr, block);
-
- BranchInst::Create(good, done, ok, block);
-
- block = good;
-
- codegenItemArg->CreateSetValue(ctx, block, onePtr);
- const auto key = GetNodeValue(Nodes.KeyResultNode, ctx, block);
- codegenKeyArg->CreateSetValue(ctx, block, key);
-
- const auto keyParam = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
- new AllocaInst(key->getType(), 0U, "key_param", &main->back()) : key;
-
- if (NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget()) {
- new StoreInst(key, keyParam, block);
- }
-
- const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::At));
- const auto atType = FunctionType::get(ptrValueType, {stateArg->getType(), keyParam->getType()}, false);
- const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
- const auto place = CallInst::Create(atPtr, {stateArg, keyParam}, "place", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
-
- BranchInst::Create(init, next, IsInvalid(place, block), block);
-
- block = init;
- GetNodeValue(place, Nodes.InitResultNode, ctx, block);
- BranchInst::Create(test, block);
-
- block = next;
- codegenStateArg->CreateSetValue(ctx, block, place);
- GetNodeValue(place, Nodes.UpdateResultNode, ctx, block);
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
- BranchInst::Create(done, loop, check, block);
-
- block = done;
-
- const auto stat = ctx.GetStat();
- const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
- const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
- const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
- CallInst::Create(statPtr, {stateArg, stat}, "", block);
-
- BranchInst::Create(full, block);
- }
-
- {
- block = full;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
- const auto extractType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), onePtr->getType(), twoPtr->getType()}, false);
- const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
- const auto has = CallInst::Create(extractPtr, {stateArg, onePtr, twoPtr}, "has", block);
-
- BranchInst::Create(good, more, has, block);
-
- block = good;
-
- codegenKeyArg->CreateSetValue(ctx, block, onePtr);
- codegenStateArg->CreateSetValue(ctx, block, twoPtr);
-
- if constexpr (IsMultiRowState) {
- if constexpr (StateContainerOpt) {
- GetNodeValue(currArg, Nodes.FinishResultNode, ctx, block);
- BranchInst::Create(more, block);
- } else {
- const auto list = GetNodeValue(Nodes.FinishResultNode, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currArg, list, codegen, block);
- if (Nodes.FinishResultNode->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- BranchInst::Create(more, block);
- }
- } else {
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, Nodes.FinishResultNode, ctx, block);
- const auto value = new LoadInst(valuePtr, "value", block);
-
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- BranchInst::Create(more, exit, IsEmpty(value, block), block);
-
- block = exit;
-
- if constexpr (StateContainerOpt) {
- const auto strip = GetOptionalValue(context, value, block);
- new StoreInst(strip, valuePtr, block);
- }
-
- ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
- }
- }
-
- return ctx.Func;
- }
-
- using TCombinePtr = typename TCodegenValue::TFetchPtr;
-
- Function* CombineFunc = nullptr;
- Function* EqualsFunc = nullptr;
- Function* HashFunc = nullptr;
-
- TCombinePtr Combine = nullptr;
- TEqualsPtr Equals = nullptr;
- THashPtr Hash = nullptr;
-#endif
- IComputationNode* const Stream;
- const TCombineCoreNodes Nodes;
- const TKeyTypes KeyTypes;
- const bool IsTuple;
- const ui64 MemLimit;
-};
-
-}
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto stateArg = &*++args;
+ const auto currArg = IsMultiRowState ? &*++args : nullptr;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ auto block = main;
+
+ const auto onePtr = new AllocaInst(valueType, 0U, "one_ptr", block);
+ const auto twoPtr = new AllocaInst(valueType, 0U, "two_ptr", block);
+ new StoreInst(ConstantInt::get(valueType, 0), onePtr, block);
+ new StoreInst(ConstantInt::get(valueType, 0), twoPtr, block);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ if constexpr (IsMultiRowState) {
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto current = new LoadInst(currArg, "current", block);
+ BranchInst::Create(skip, pull, IsEmpty(current, block), block);
+
+ block = pull;
+
+ const auto status = StateContainerOpt ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, codegen, block, valuePtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, codegen, block, valuePtr);
+
+ const auto icmp = StateContainerOpt ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block): status;
+
+ BranchInst::Create(good, next, icmp, block);
+
+ block = good;
+ ReturnInst::Create(context, StateContainerOpt ? status : ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+
+ block = next;
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(ConstantInt::get(current->getType(), 0), currArg, block);
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ }
+
+ const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
+ const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
+ const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "cast", block);
+ const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(next, full, empty, block);
+
+ {
+ block = next;
+
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
+
+ const auto last = new LoadInst(statusPtr, "last", block);
+
+ const auto choise = SwitchInst::Create(last, pull, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ ReturnInst::Create(context, last, block);
+
+ block = pull;
+
+ const auto used = GetMemoryUsed(MemLimit, ctx, block);
+
+ const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto fetch = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, onePtr);
+
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, fetch, ConstantInt::get(fetch->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
+ new StoreInst(fetch, statusPtr, block);
+
+ BranchInst::Create(good, done, ok, block);
+
+ block = good;
+
+ codegenItemArg->CreateSetValue(ctx, block, onePtr);
+ const auto key = GetNodeValue(Nodes.KeyResultNode, ctx, block);
+ codegenKeyArg->CreateSetValue(ctx, block, key);
+
+ const auto keyParam = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
+ new AllocaInst(key->getType(), 0U, "key_param", &main->back()) : key;
+
+ if (NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget()) {
+ new StoreInst(key, keyParam, block);
+ }
+
+ const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::At));
+ const auto atType = FunctionType::get(ptrValueType, {stateArg->getType(), keyParam->getType()}, false);
+ const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
+ const auto place = CallInst::Create(atPtr, {stateArg, keyParam}, "place", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+
+ BranchInst::Create(init, next, IsInvalid(place, block), block);
+
+ block = init;
+ GetNodeValue(place, Nodes.InitResultNode, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = next;
+ codegenStateArg->CreateSetValue(ctx, block, place);
+ GetNodeValue(place, Nodes.UpdateResultNode, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
+ BranchInst::Create(done, loop, check, block);
+
+ block = done;
+
+ const auto stat = ctx.GetStat();
+ const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
+ const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
+ const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
+ CallInst::Create(statPtr, {stateArg, stat}, "", block);
+
+ BranchInst::Create(full, block);
+ }
+
+ {
+ block = full;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
+ const auto extractType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), onePtr->getType(), twoPtr->getType()}, false);
+ const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
+ const auto has = CallInst::Create(extractPtr, {stateArg, onePtr, twoPtr}, "has", block);
+
+ BranchInst::Create(good, more, has, block);
+
+ block = good;
+
+ codegenKeyArg->CreateSetValue(ctx, block, onePtr);
+ codegenStateArg->CreateSetValue(ctx, block, twoPtr);
+
+ if constexpr (IsMultiRowState) {
+ if constexpr (StateContainerOpt) {
+ GetNodeValue(currArg, Nodes.FinishResultNode, ctx, block);
+ BranchInst::Create(more, block);
+ } else {
+ const auto list = GetNodeValue(Nodes.FinishResultNode, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currArg, list, codegen, block);
+ if (Nodes.FinishResultNode->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ BranchInst::Create(more, block);
+ }
+ } else {
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, Nodes.FinishResultNode, ctx, block);
+ const auto value = new LoadInst(valuePtr, "value", block);
+
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ BranchInst::Create(more, exit, IsEmpty(value, block), block);
+
+ block = exit;
+
+ if constexpr (StateContainerOpt) {
+ const auto strip = GetOptionalValue(context, value, block);
+ new StoreInst(strip, valuePtr, block);
+ }
+
+ ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+ }
+ }
+
+ return ctx.Func;
+ }
+
+ using TCombinePtr = typename TCodegenValue::TFetchPtr;
+
+ Function* CombineFunc = nullptr;
+ Function* EqualsFunc = nullptr;
+ Function* HashFunc = nullptr;
+
+ TCombinePtr Combine = nullptr;
+ TEqualsPtr Equals = nullptr;
+ THashPtr Hash = nullptr;
+#endif
+ IComputationNode* const Stream;
+ const TCombineCoreNodes Nodes;
+ const TKeyTypes KeyTypes;
+ const bool IsTuple;
+ const ui64 MemLimit;
+};
+
+}
+
IComputationNode* WrapCombineCore(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 9U, "Expected 9 args");
+ MKQL_ENSURE(callable.GetInputsCount() == 9U, "Expected 9 args");
- const auto type = callable.GetType()->GetReturnType();
- const auto finishResultType = callable.GetInput(7).GetStaticType();
+ const auto type = callable.GetType()->GetReturnType();
+ const auto finishResultType = callable.GetInput(7).GetStaticType();
MKQL_ENSURE(finishResultType->IsList() || finishResultType->IsOptional() || finishResultType->IsStream(), "Expected list, stream or optional");
- const auto keyType = callable.GetInput(2).GetStaticType();
+ const auto keyType = callable.GetInput(2).GetStaticType();
TKeyTypes keyTypes;
bool isTuple;
bool encoded;
GetDictionaryKeyTypes(keyType, keyTypes, isTuple, encoded);
Y_VERIFY(!encoded, "TODO");
- const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().Get<ui64>();
- const bool trackRss = EGraphPerProcess::Single == ctx.GraphPerProcess;
-
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto keyExtractorResultNode = LocateNode(ctx.NodeLocator, callable, 2);
- const auto initResultNode = LocateNode(ctx.NodeLocator, callable, 4);
- const auto updateResultNode = LocateNode(ctx.NodeLocator, callable, 6);
- const auto finishResultNode = LocateNode(ctx.NodeLocator, callable, 7);
-
- const auto itemNode = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto keyNode = LocateExternalNode(ctx.NodeLocator, callable, 3);
- const auto stateNode = LocateExternalNode(ctx.NodeLocator, callable, 5);
-
- const TCombineCoreNodes nodes = {
- itemNode,
- keyNode,
- stateNode,
- keyExtractorResultNode,
- initResultNode,
- updateResultNode,
- finishResultNode
- };
-
- if (type->IsFlow()) {
- const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
- if (finishResultType->IsStream()) {
- if (trackRss)
- return new TCombineCoreFlowWrapper<true, true, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreFlowWrapper<true, true, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else if (finishResultType->IsList()) {
- if (trackRss)
- return new TCombineCoreFlowWrapper<true, false, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreFlowWrapper<true, false, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else if (finishResultType->IsOptional()) {
- if (AS_TYPE(TOptionalType, finishResultType)->GetItemType()->IsOptional()) {
- if (trackRss)
- return new TCombineCoreFlowWrapper<false, true, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreFlowWrapper<false, true, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else {
- if (trackRss)
- return new TCombineCoreFlowWrapper<false, false, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreFlowWrapper<false, false, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- }
- }
- } else if (type->IsStream()) {
- if (finishResultType->IsStream()) {
- if (trackRss)
- return new TCombineCoreWrapper<true, true, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreWrapper<true, true, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else if (finishResultType->IsList()) {
- if (trackRss)
- return new TCombineCoreWrapper<true, false, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreWrapper<true, false, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else if (finishResultType->IsOptional()) {
- if (AS_TYPE(TOptionalType, finishResultType)->GetItemType()->IsOptional()) {
- if (trackRss)
- return new TCombineCoreWrapper<false, true, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreWrapper<false, true, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- } else {
- if (trackRss)
- return new TCombineCoreWrapper<false, false, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- else
- return new TCombineCoreWrapper<false, false, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
- }
- }
+ const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().Get<ui64>();
+ const bool trackRss = EGraphPerProcess::Single == ctx.GraphPerProcess;
+
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto keyExtractorResultNode = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto initResultNode = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto updateResultNode = LocateNode(ctx.NodeLocator, callable, 6);
+ const auto finishResultNode = LocateNode(ctx.NodeLocator, callable, 7);
+
+ const auto itemNode = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto keyNode = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto stateNode = LocateExternalNode(ctx.NodeLocator, callable, 5);
+
+ const TCombineCoreNodes nodes = {
+ itemNode,
+ keyNode,
+ stateNode,
+ keyExtractorResultNode,
+ initResultNode,
+ updateResultNode,
+ finishResultNode
+ };
+
+ if (type->IsFlow()) {
+ const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
+ if (finishResultType->IsStream()) {
+ if (trackRss)
+ return new TCombineCoreFlowWrapper<true, true, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreFlowWrapper<true, true, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else if (finishResultType->IsList()) {
+ if (trackRss)
+ return new TCombineCoreFlowWrapper<true, false, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreFlowWrapper<true, false, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else if (finishResultType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, finishResultType)->GetItemType()->IsOptional()) {
+ if (trackRss)
+ return new TCombineCoreFlowWrapper<false, true, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreFlowWrapper<false, true, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else {
+ if (trackRss)
+ return new TCombineCoreFlowWrapper<false, false, true>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreFlowWrapper<false, false, false>(ctx.Mutables, kind, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ }
+ }
+ } else if (type->IsStream()) {
+ if (finishResultType->IsStream()) {
+ if (trackRss)
+ return new TCombineCoreWrapper<true, true, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreWrapper<true, true, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else if (finishResultType->IsList()) {
+ if (trackRss)
+ return new TCombineCoreWrapper<true, false, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreWrapper<true, false, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else if (finishResultType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, finishResultType)->GetItemType()->IsOptional()) {
+ if (trackRss)
+ return new TCombineCoreWrapper<false, true, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreWrapper<false, true, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ } else {
+ if (trackRss)
+ return new TCombineCoreWrapper<false, false, true>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ else
+ return new TCombineCoreWrapper<false, false, false>(ctx.Mutables, stream, nodes, std::move(keyTypes), isTuple, memLimit);
+ }
+ }
}
-
- THROW yexception() << "Expected flow or stream.";
+
+ THROW yexception() << "Expected flow or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_condense.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_condense.cpp
index 5be078b6e6..c179abab49 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_condense.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_condense.cpp
@@ -1,5 +1,5 @@
-#include "mkql_condense.h"
-#include "mkql_squeeze_state.h"
+#include "mkql_condense.h"
+#include "mkql_squeeze_state.h"
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
@@ -9,167 +9,167 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool Interruptable>
-class TCondenseFlowWrapper : public TStatefulFlowCodegeneratorNode<TCondenseFlowWrapper<Interruptable>> {
- typedef TStatefulFlowCodegeneratorNode<TCondenseFlowWrapper<Interruptable>> TBaseComputation;
-public:
- TCondenseFlowWrapper(
- TComputationMutables& mutables,
- EValueRepresentation kind,
- IComputationNode* flow,
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* updateState)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
- Flow(flow), Item(item), State(state), Switch(outSwitch), InitState(initState), UpdateState(updateState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return static_cast<const NUdf::TUnboxedValuePod&>(state);
- }
-
- if (state.IsInvalid()) {
- state = NUdf::TUnboxedValuePod();
- State->SetValue(ctx, InitState->GetValue(ctx));
- }
-
- while (true) {
- auto item = Flow->GetValue(ctx);
- if (item.IsYield()) {
- return item.Release();
- }
-
- if (item.IsFinish()) {
- break;
- }
-
- Item->SetValue(ctx, std::move(item));
-
- if (Switch) {
- const auto& reset = Switch->GetValue(ctx);
- if (Interruptable && !reset) {
- break;
- }
-
- if (reset.template Get<bool>()) {
- auto result = State->GetValue(ctx);
- State->SetValue(ctx, InitState->GetValue(ctx));
- State->SetValue(ctx, UpdateState->GetValue(ctx));
- return result.Release();
- }
- }
-
- State->SetValue(ctx, UpdateState->GetValue(ctx));
- }
-
- state = NUdf::TUnboxedValue::MakeFinish();
- return State->GetValue(ctx).Release();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
- MKQL_ENSURE(codegenState, "State must be codegenerator node.");
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto result = PHINode::Create(state->getType(), Switch ? 4U : 3U, "result", exit);
- result->addIncoming(state, block);
-
- const auto select = SwitchInst::Create(state, work, 2U, block);
- select->addCase(GetFinish(context), exit);
- select->addCase(GetInvalid(context), init);
-
- block = init;
- new StoreInst(GetEmpty(context), statePtr, block);
- codegenState->CreateSetValue(ctx, block, GetNodeValue(InitState, ctx, block));
- BranchInst::Create(work, block);
-
- block = work;
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
-
- const auto action = SwitchInst::Create(item, good, 2U, block);
- action->addCase(GetFinish(context), stop);
- action->addCase(GetYield(context), exit);
-
- block = good;
-
- codegenItem->CreateSetValue(ctx, block, item);
-
- if (Switch) {
- const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto reset = GetNodeValue(Switch, ctx, block);
- if constexpr (Interruptable) {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- BranchInst::Create(stop, next, IsEmpty(reset, block), block);
- block = next;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(swap, skip, cast, block);
-
- block = swap;
-
- const auto output = codegenState->CreateSwapValue(ctx, block, GetNodeValue(InitState, ctx, block));
- codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
- result->addIncoming(output, block);
- BranchInst::Create(exit, block);
-
- block = skip;
- }
-
- codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
- BranchInst::Create(work, block);
-
- block = stop;
- new StoreInst(GetFinish(context), statePtr, block);
- const auto output = codegenState->CreateGetValue(ctx, block);
- result->addIncoming(output, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->Own(flow, Item);
- this->Own(flow, State);
- this->DependsOn(flow, InitState);
- this->DependsOn(flow, Switch);
- this->DependsOn(flow, UpdateState);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
- IComputationNode* const Switch;
- IComputationNode* const InitState;
- IComputationNode* const UpdateState;
-};
-
-template <bool Interruptable>
-class TCondenseWrapper : public TCustomValueCodegeneratorNode<TCondenseWrapper<Interruptable>> {
- typedef TCustomValueCodegeneratorNode<TCondenseWrapper<Interruptable>> TBaseComputation;
+namespace {
+
+template <bool Interruptable>
+class TCondenseFlowWrapper : public TStatefulFlowCodegeneratorNode<TCondenseFlowWrapper<Interruptable>> {
+ typedef TStatefulFlowCodegeneratorNode<TCondenseFlowWrapper<Interruptable>> TBaseComputation;
+public:
+ TCondenseFlowWrapper(
+ TComputationMutables& mutables,
+ EValueRepresentation kind,
+ IComputationNode* flow,
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* updateState)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
+ Flow(flow), Item(item), State(state), Switch(outSwitch), InitState(initState), UpdateState(updateState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return static_cast<const NUdf::TUnboxedValuePod&>(state);
+ }
+
+ if (state.IsInvalid()) {
+ state = NUdf::TUnboxedValuePod();
+ State->SetValue(ctx, InitState->GetValue(ctx));
+ }
+
+ while (true) {
+ auto item = Flow->GetValue(ctx);
+ if (item.IsYield()) {
+ return item.Release();
+ }
+
+ if (item.IsFinish()) {
+ break;
+ }
+
+ Item->SetValue(ctx, std::move(item));
+
+ if (Switch) {
+ const auto& reset = Switch->GetValue(ctx);
+ if (Interruptable && !reset) {
+ break;
+ }
+
+ if (reset.template Get<bool>()) {
+ auto result = State->GetValue(ctx);
+ State->SetValue(ctx, InitState->GetValue(ctx));
+ State->SetValue(ctx, UpdateState->GetValue(ctx));
+ return result.Release();
+ }
+ }
+
+ State->SetValue(ctx, UpdateState->GetValue(ctx));
+ }
+
+ state = NUdf::TUnboxedValue::MakeFinish();
+ return State->GetValue(ctx).Release();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+ const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
+ MKQL_ENSURE(codegenState, "State must be codegenerator node.");
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto result = PHINode::Create(state->getType(), Switch ? 4U : 3U, "result", exit);
+ result->addIncoming(state, block);
+
+ const auto select = SwitchInst::Create(state, work, 2U, block);
+ select->addCase(GetFinish(context), exit);
+ select->addCase(GetInvalid(context), init);
+
+ block = init;
+ new StoreInst(GetEmpty(context), statePtr, block);
+ codegenState->CreateSetValue(ctx, block, GetNodeValue(InitState, ctx, block));
+ BranchInst::Create(work, block);
+
+ block = work;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+
+ const auto action = SwitchInst::Create(item, good, 2U, block);
+ action->addCase(GetFinish(context), stop);
+ action->addCase(GetYield(context), exit);
+
+ block = good;
+
+ codegenItem->CreateSetValue(ctx, block, item);
+
+ if (Switch) {
+ const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto reset = GetNodeValue(Switch, ctx, block);
+ if constexpr (Interruptable) {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ BranchInst::Create(stop, next, IsEmpty(reset, block), block);
+ block = next;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(swap, skip, cast, block);
+
+ block = swap;
+
+ const auto output = codegenState->CreateSwapValue(ctx, block, GetNodeValue(InitState, ctx, block));
+ codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
+ result->addIncoming(output, block);
+ BranchInst::Create(exit, block);
+
+ block = skip;
+ }
+
+ codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
+ BranchInst::Create(work, block);
+
+ block = stop;
+ new StoreInst(GetFinish(context), statePtr, block);
+ const auto output = codegenState->CreateGetValue(ctx, block);
+ result->addIncoming(output, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->Own(flow, Item);
+ this->Own(flow, State);
+ this->DependsOn(flow, InitState);
+ this->DependsOn(flow, Switch);
+ this->DependsOn(flow, UpdateState);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
+ IComputationNode* const Switch;
+ IComputationNode* const InitState;
+ IComputationNode* const UpdateState;
+};
+
+template <bool Interruptable>
+class TCondenseWrapper : public TCustomValueCodegeneratorNode<TCondenseWrapper<Interruptable>> {
+ typedef TCustomValueCodegeneratorNode<TCondenseWrapper<Interruptable>> TBaseComputation;
public:
class TValue : public TComputationValue<TValue> {
public:
@@ -178,324 +178,324 @@ public:
TValue(
TMemoryUsageInfo* memInfo,
NUdf::TUnboxedValue&& stream,
- const TSqueezeState& state,
+ const TSqueezeState& state,
TComputationContext& ctx)
: TBase(memInfo)
, Stream(std::move(stream))
, Ctx(ctx)
- , State(state)
- {}
+ , State(state)
+ {}
private:
- ui32 GetTraverseCount() const final {
+ ui32 GetTraverseCount() const final {
return 1;
}
- NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
+ NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
Y_UNUSED(index);
return Stream;
}
- NUdf::TUnboxedValue Save() const final {
- return State.Save(Ctx);
+ NUdf::TUnboxedValue Save() const final {
+ return State.Save(Ctx);
}
- void Load(const NUdf::TStringRef& state) final {
- State.Load(Ctx, state);
+ void Load(const NUdf::TStringRef& state) final {
+ State.Load(Ctx, state);
}
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- if (ESqueezeState::Finished == State.Stage)
- return NUdf::EFetchStatus::Finish;
-
- if (ESqueezeState::Idle == State.Stage) {
- State.Stage = ESqueezeState::Work;
- State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
- }
-
- for (;;) {
- const auto status = Stream.Fetch(State.Item->RefValue(Ctx));
+ if (ESqueezeState::Finished == State.Stage)
+ return NUdf::EFetchStatus::Finish;
+
+ if (ESqueezeState::Idle == State.Stage) {
+ State.Stage = ESqueezeState::Work;
+ State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
+ }
+
+ for (;;) {
+ const auto status = Stream.Fetch(State.Item->RefValue(Ctx));
if (status == NUdf::EFetchStatus::Yield) {
return status;
}
if (status == NUdf::EFetchStatus::Finish) {
- break;
+ break;
}
- if (State.Switch) {
- const auto& reset = State.Switch->GetValue(Ctx);
- if (Interruptable && !reset) {
- break;
- }
-
- if (reset.template Get<bool>()) {
- result = State.State->GetValue(Ctx);
- State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
- State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
- return NUdf::EFetchStatus::Ok;
- }
- }
-
- State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
+ if (State.Switch) {
+ const auto& reset = State.Switch->GetValue(Ctx);
+ if (Interruptable && !reset) {
+ break;
+ }
+
+ if (reset.template Get<bool>()) {
+ result = State.State->GetValue(Ctx);
+ State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
+ State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+
+ State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
}
-
- State.Stage = ESqueezeState::Finished;
+
+ State.Stage = ESqueezeState::Finished;
result = State.State->GetValue(Ctx);
- return NUdf::EFetchStatus::Ok;
+ return NUdf::EFetchStatus::Ok;
}
- const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Stream;
TComputationContext& Ctx;
- TSqueezeState State;
+ TSqueezeState State;
};
- TCondenseWrapper(
+ TCondenseWrapper(
TComputationMutables& mutables,
IComputationNode* stream,
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* updateState,
- IComputationExternalNode* inSave = nullptr,
- IComputationNode* outSave = nullptr,
- IComputationExternalNode* inLoad = nullptr,
- IComputationNode* outLoad = nullptr,
- TType* stateType = nullptr)
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* updateState,
+ IComputationExternalNode* inSave = nullptr,
+ IComputationNode* outSave = nullptr,
+ IComputationExternalNode* inLoad = nullptr,
+ IComputationNode* outLoad = nullptr,
+ TType* stateType = nullptr)
: TBaseComputation(mutables)
, Stream(stream)
- , State(item, state, outSwitch, initState, updateState, inSave, outSave, inLoad, outLoad, stateType)
+ , State(item, state, outSwitch, initState, updateState, inSave, outSave, inLoad, outLoad, stateType)
{
- this->Stateless = false;
+ this->Stateless = false;
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Fetch)
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Fetch)
return ctx.HolderFactory.Create<TSqueezeCodegenValue>(State, Fetch, ctx, Stream->GetValue(ctx));
-#endif
+#endif
return ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx), State, ctx);
}
private:
- void RegisterDependencies() const final {
- this->DependsOn(Stream);
- this->Own(State.Item);
- this->Own(State.State);
- this->DependsOn(State.Switch);
- this->DependsOn(State.InitState);
- this->DependsOn(State.UpdateState);
-
- this->Own(State.InSave);
- this->DependsOn(State.OutSave);
- this->Own(State.InLoad);
- this->DependsOn(State.OutLoad);
+ void RegisterDependencies() const final {
+ this->DependsOn(Stream);
+ this->Own(State.Item);
+ this->Own(State.State);
+ this->DependsOn(State.Switch);
+ this->DependsOn(State.InitState);
+ this->DependsOn(State.UpdateState);
+
+ this->Own(State.InSave);
+ this->DependsOn(State.OutSave);
+ this->Own(State.InLoad);
+ this->DependsOn(State.OutLoad);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FetchFunc = GenerateFetch(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FetchFunc = GenerateFetch(codegen);
codegen->ExportSymbol(FetchFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FetchFunc) {
- Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
- }
- }
-
- Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(State.Item);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(State.State);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto stateType = Type::getInt8Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(stateType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FetchFunc) {
+ Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
+ }
+ }
+
+ Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(State.Item);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(State.State);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto stateType = Type::getInt8Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(stateType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
- const auto statePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto state = new LoadInst(statePtr, "state", block);
-
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Idle)), "one", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- BranchInst::Create(init, work, one, block);
- block = init;
-
- new StoreInst(ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Work)), statePtr, block);
-
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
- BranchInst::Create(work, block);
- block = work;
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
-
- const auto ychk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "ychk", block);
-
- const auto yies = BasicBlock::Create(context, "yies", ctx.Func);
- const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
- BranchInst::Create(yies, nope, ychk, block);
-
- block = yies;
- ReturnInst::Create(context, status, block);
-
- block = nope;
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- BranchInst::Create(stop, good, icmp, block);
- block = good;
-
- if (State.Switch) {
- const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto reset = GetNodeValue(State.Switch, ctx, block);
- if constexpr (Interruptable) {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, reset, ConstantInt::get(reset->getType(), 0), "done", block);
- BranchInst::Create(stop, next, done, block);
- block = next;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(swap, skip, cast, block);
-
- block = swap;
- SafeUnRefUnboxed(valuePtr, ctx, block);
- const auto state = codegenStateArg->CreateGetValue(ctx, block);
- new StoreInst(state, valuePtr, block);
- ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
-
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.UpdateState, ctx, block));
-
- ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
-
- block = skip;
- }
-
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.UpdateState, ctx, block));
- BranchInst::Create(loop, block);
-
- block = stop;
- new StoreInst(ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Finished)), statePtr, block);
- SafeUnRefUnboxed(valuePtr, ctx, block);
- const auto result = codegenStateArg->CreateGetValue(ctx, block);
- new StoreInst(result, valuePtr, block);
- ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
- ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
-
- return ctx.Func;
- }
-
- using TFetchPtr = TSqueezeCodegenValue::TFetchPtr;
-
- Function* FetchFunc = nullptr;
-
- TFetchPtr Fetch = nullptr;
-#endif
-
- IComputationNode* const Stream;
- TSqueezeState State;
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+ const auto statePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Idle)), "one", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ BranchInst::Create(init, work, one, block);
+ block = init;
+
+ new StoreInst(ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Work)), statePtr, block);
+
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
+ BranchInst::Create(work, block);
+ block = work;
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
+
+ const auto ychk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "ychk", block);
+
+ const auto yies = BasicBlock::Create(context, "yies", ctx.Func);
+ const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
+ BranchInst::Create(yies, nope, ychk, block);
+
+ block = yies;
+ ReturnInst::Create(context, status, block);
+
+ block = nope;
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ BranchInst::Create(stop, good, icmp, block);
+ block = good;
+
+ if (State.Switch) {
+ const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto reset = GetNodeValue(State.Switch, ctx, block);
+ if constexpr (Interruptable) {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, reset, ConstantInt::get(reset->getType(), 0), "done", block);
+ BranchInst::Create(stop, next, done, block);
+ block = next;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(swap, skip, cast, block);
+
+ block = swap;
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ const auto state = codegenStateArg->CreateGetValue(ctx, block);
+ new StoreInst(state, valuePtr, block);
+ ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
+
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.UpdateState, ctx, block));
+
+ ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+
+ block = skip;
+ }
+
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.UpdateState, ctx, block));
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ new StoreInst(ConstantInt::get(state->getType(), static_cast<ui8>(ESqueezeState::Finished)), statePtr, block);
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ const auto result = codegenStateArg->CreateGetValue(ctx, block);
+ new StoreInst(result, valuePtr, block);
+ ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
+ ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+
+ return ctx.Func;
+ }
+
+ using TFetchPtr = TSqueezeCodegenValue::TFetchPtr;
+
+ Function* FetchFunc = nullptr;
+
+ TFetchPtr Fetch = nullptr;
+#endif
+
+ IComputationNode* const Stream;
+ TSqueezeState State;
};
-}
-
-IComputationNode* WrapCondense(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
-
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initState = LocateNode(ctx.NodeLocator, callable, 1);
- const auto outSwitch = LocateNode(ctx.NodeLocator, callable, 4);
- const auto updateState = LocateNode(ctx.NodeLocator, callable, 5);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
-
- bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(4), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
-
- const auto type = callable.GetType()->GetReturnType();
- if (type->IsFlow()) {
- const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
- if (isOptional) {
- return new TCondenseFlowWrapper<true>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
- } else {
- return new TCondenseFlowWrapper<false>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
- }
- } else {
- if (isOptional) {
- return new TCondenseWrapper<true>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
- } else {
- return new TCondenseWrapper<false>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
- }
- }
-}
-
+}
+
+IComputationNode* WrapCondense(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
+
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initState = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto outSwitch = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto updateState = LocateNode(ctx.NodeLocator, callable, 5);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(callable.GetInput(4), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
+
+ const auto type = callable.GetType()->GetReturnType();
+ if (type->IsFlow()) {
+ const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
+ if (isOptional) {
+ return new TCondenseFlowWrapper<true>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
+ } else {
+ return new TCondenseFlowWrapper<false>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
+ }
+ } else {
+ if (isOptional) {
+ return new TCondenseWrapper<true>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
+ } else {
+ return new TCondenseWrapper<false>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
+ }
+ }
+}
+
IComputationNode* WrapSqueeze(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 9, "Expected 9 args");
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initState = LocateNode(ctx.NodeLocator, callable, 1);
- const auto updateState = LocateNode(ctx.NodeLocator, callable, 4);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initState = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto updateState = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
- IComputationExternalNode* inSave = nullptr;
+ IComputationExternalNode* inSave = nullptr;
IComputationNode* outSave = nullptr;
- IComputationExternalNode* inLoad = nullptr;
+ IComputationExternalNode* inLoad = nullptr;
IComputationNode* outLoad = nullptr;
- const auto hasSaveLoad = !callable.GetInput(6).GetStaticType()->IsVoid();
+ const auto hasSaveLoad = !callable.GetInput(6).GetStaticType()->IsVoid();
if (hasSaveLoad) {
outSave = LocateNode(ctx.NodeLocator, callable, 6);
outLoad = LocateNode(ctx.NodeLocator, callable, 8);
- inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
- inLoad = LocateExternalNode(ctx.NodeLocator, callable, 7);
+ inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
+ inLoad = LocateExternalNode(ctx.NodeLocator, callable, 7);
}
- const auto stateType = hasSaveLoad ? callable.GetInput(6).GetStaticType() : nullptr;
+ const auto stateType = hasSaveLoad ? callable.GetInput(6).GetStaticType() : nullptr;
- return new TCondenseWrapper<false>(ctx.Mutables, stream, item, state, nullptr, initState, updateState, inSave, outSave, inLoad, outLoad, stateType);
+ return new TCondenseWrapper<false>(ctx.Mutables, stream, item, state, nullptr, initState, updateState, inSave, outSave, inLoad, outLoad, stateType);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_condense.h b/ydb/library/yql/minikql/comp_nodes/mkql_condense.h
index 8df4aac9db..c8ea53056a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_condense.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_condense.h
@@ -4,7 +4,7 @@
namespace NKikimr {
namespace NMiniKQL {
-IComputationNode* WrapCondense(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapCondense(TCallable& callable, const TComputationNodeFactoryContext& ctx);
IComputationNode* WrapSqueeze(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_condense1.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_condense1.cpp
index 07775a92c5..2f5ac89432 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_condense1.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_condense1.cpp
@@ -1,5 +1,5 @@
-#include "mkql_condense1.h"
-#include "mkql_squeeze_state.h"
+#include "mkql_condense1.h"
+#include "mkql_squeeze_state.h"
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
@@ -9,180 +9,180 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool Interruptable>
-class TCondense1FlowWrapper : public TStatefulFlowCodegeneratorNode<TCondense1FlowWrapper<Interruptable>> {
- typedef TStatefulFlowCodegeneratorNode<TCondense1FlowWrapper<Interruptable>> TBaseComputation;
-public:
- TCondense1FlowWrapper(
- TComputationMutables& mutables,
- EValueRepresentation kind,
- IComputationNode* flow,
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* updateState)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
- Flow(flow), Item(item), State(state), Switch(outSwitch), InitState(initState), UpdateState(updateState)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return static_cast<const NUdf::TUnboxedValuePod&>(state);
- }
-
- while (true) {
- auto item = Flow->GetValue(ctx);
- if (item.IsYield()) {
- return item.Release();
- }
-
- if (item.IsFinish()) {
- break;
- }
-
- Item->SetValue(ctx, std::move(item));
-
- if (state.IsInvalid()) {
- state = NUdf::TUnboxedValuePod();
- State->SetValue(ctx, InitState->GetValue(ctx));
- } else {
- if (Switch) {
- const auto& reset = Switch->GetValue(ctx);
- if (Interruptable && !reset) {
- break;
- }
-
- if (reset.template Get<bool>()) {
- auto result = State->GetValue(ctx);
- State->SetValue(ctx, InitState->GetValue(ctx));
- return result.Release();
- }
- }
-
- State->SetValue(ctx, UpdateState->GetValue(ctx));
- }
- }
-
- const bool empty = state.IsInvalid();
- state = NUdf::TUnboxedValuePod::MakeFinish();
- return empty ? NUdf::TUnboxedValuePod::MakeFinish() : State->GetValue(ctx).Release();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
- MKQL_ENSURE(codegenState, "State must be codegenerator node.");
-
- const auto frst = BasicBlock::Create(context, "frst", ctx.Func);
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto result = PHINode::Create(state->getType(), Switch ? 4U : 3U, "result", exit);
- result->addIncoming(state, block);
-
- BranchInst::Create(exit, frst, IsFinish(state, block), block);
-
- block = frst;
-
- const auto invalid = IsInvalid(state, block);
- const auto empty = PHINode::Create(invalid->getType(), 3U, "empty", work);
- empty->addIncoming(invalid, block);
- BranchInst::Create(work, block);
-
- block = work;
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
-
- const auto action = SwitchInst::Create(item, good, 2U, block);
- action->addCase(GetFinish(context), stop);
- action->addCase(GetYield(context), exit);
-
- block = good;
-
- codegenItem->CreateSetValue(ctx, block, item);
- BranchInst::Create(init, next, empty, block);
-
- block = init;
-
- new StoreInst(GetEmpty(context), statePtr, block);
- codegenState->CreateSetValue(ctx, block, GetNodeValue(InitState, ctx, block));
- empty->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(work, block);
-
- block = next;
-
- if (Switch) {
- const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto reset = GetNodeValue(Switch, ctx, block);
- if constexpr (Interruptable) {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- BranchInst::Create(stop, next, IsEmpty(reset, block), block);
- block = next;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(swap, skip, cast, block);
-
- block = swap;
-
- const auto output = codegenState->CreateSwapValue(ctx, block, GetNodeValue(InitState, ctx, block));
- result->addIncoming(output, block);
- BranchInst::Create(exit, block);
-
- block = skip;
- }
-
- codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
- empty->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(work, block);
-
- block = stop;
- new StoreInst(GetFinish(context), statePtr, block);
- const auto output = codegenState->CreateGetValue(ctx, block);
- const auto select = SelectInst::Create(empty, GetFinish(context), output, "output", block);
- result->addIncoming(select, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->Own(flow, Item);
- this->Own(flow, State);
- this->DependsOn(flow, Switch);
- this->DependsOn(flow, InitState);
- this->DependsOn(flow, UpdateState);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
- IComputationNode* const Switch;
- IComputationNode* const InitState;
- IComputationNode* const UpdateState;
-};
-
-template <bool Interruptable>
-class TCondense1Wrapper : public TCustomValueCodegeneratorNode<TCondense1Wrapper<Interruptable>> {
- typedef TCustomValueCodegeneratorNode<TCondense1Wrapper<Interruptable>> TBaseComputation;
+namespace {
+
+template <bool Interruptable>
+class TCondense1FlowWrapper : public TStatefulFlowCodegeneratorNode<TCondense1FlowWrapper<Interruptable>> {
+ typedef TStatefulFlowCodegeneratorNode<TCondense1FlowWrapper<Interruptable>> TBaseComputation;
+public:
+ TCondense1FlowWrapper(
+ TComputationMutables& mutables,
+ EValueRepresentation kind,
+ IComputationNode* flow,
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* updateState)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded),
+ Flow(flow), Item(item), State(state), Switch(outSwitch), InitState(initState), UpdateState(updateState)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return static_cast<const NUdf::TUnboxedValuePod&>(state);
+ }
+
+ while (true) {
+ auto item = Flow->GetValue(ctx);
+ if (item.IsYield()) {
+ return item.Release();
+ }
+
+ if (item.IsFinish()) {
+ break;
+ }
+
+ Item->SetValue(ctx, std::move(item));
+
+ if (state.IsInvalid()) {
+ state = NUdf::TUnboxedValuePod();
+ State->SetValue(ctx, InitState->GetValue(ctx));
+ } else {
+ if (Switch) {
+ const auto& reset = Switch->GetValue(ctx);
+ if (Interruptable && !reset) {
+ break;
+ }
+
+ if (reset.template Get<bool>()) {
+ auto result = State->GetValue(ctx);
+ State->SetValue(ctx, InitState->GetValue(ctx));
+ return result.Release();
+ }
+ }
+
+ State->SetValue(ctx, UpdateState->GetValue(ctx));
+ }
+ }
+
+ const bool empty = state.IsInvalid();
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ return empty ? NUdf::TUnboxedValuePod::MakeFinish() : State->GetValue(ctx).Release();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+ const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
+ MKQL_ENSURE(codegenState, "State must be codegenerator node.");
+
+ const auto frst = BasicBlock::Create(context, "frst", ctx.Func);
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto result = PHINode::Create(state->getType(), Switch ? 4U : 3U, "result", exit);
+ result->addIncoming(state, block);
+
+ BranchInst::Create(exit, frst, IsFinish(state, block), block);
+
+ block = frst;
+
+ const auto invalid = IsInvalid(state, block);
+ const auto empty = PHINode::Create(invalid->getType(), 3U, "empty", work);
+ empty->addIncoming(invalid, block);
+ BranchInst::Create(work, block);
+
+ block = work;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+
+ const auto action = SwitchInst::Create(item, good, 2U, block);
+ action->addCase(GetFinish(context), stop);
+ action->addCase(GetYield(context), exit);
+
+ block = good;
+
+ codegenItem->CreateSetValue(ctx, block, item);
+ BranchInst::Create(init, next, empty, block);
+
+ block = init;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+ codegenState->CreateSetValue(ctx, block, GetNodeValue(InitState, ctx, block));
+ empty->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(work, block);
+
+ block = next;
+
+ if (Switch) {
+ const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto reset = GetNodeValue(Switch, ctx, block);
+ if constexpr (Interruptable) {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ BranchInst::Create(stop, next, IsEmpty(reset, block), block);
+ block = next;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(swap, skip, cast, block);
+
+ block = swap;
+
+ const auto output = codegenState->CreateSwapValue(ctx, block, GetNodeValue(InitState, ctx, block));
+ result->addIncoming(output, block);
+ BranchInst::Create(exit, block);
+
+ block = skip;
+ }
+
+ codegenState->CreateSetValue(ctx, block, GetNodeValue(UpdateState, ctx, block));
+ empty->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(work, block);
+
+ block = stop;
+ new StoreInst(GetFinish(context), statePtr, block);
+ const auto output = codegenState->CreateGetValue(ctx, block);
+ const auto select = SelectInst::Create(empty, GetFinish(context), output, "output", block);
+ result->addIncoming(select, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->Own(flow, Item);
+ this->Own(flow, State);
+ this->DependsOn(flow, Switch);
+ this->DependsOn(flow, InitState);
+ this->DependsOn(flow, UpdateState);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
+ IComputationNode* const Switch;
+ IComputationNode* const InitState;
+ IComputationNode* const UpdateState;
+};
+
+template <bool Interruptable>
+class TCondense1Wrapper : public TCustomValueCodegeneratorNode<TCondense1Wrapper<Interruptable>> {
+ typedef TCustomValueCodegeneratorNode<TCondense1Wrapper<Interruptable>> TBaseComputation;
public:
class TValue : public TComputationValue<TValue> {
public:
@@ -191,342 +191,342 @@ public:
TValue(
TMemoryUsageInfo* memInfo,
NUdf::TUnboxedValue&& stream,
- const TSqueezeState& state,
+ const TSqueezeState& state,
TComputationContext& ctx)
: TBase(memInfo)
, Stream(std::move(stream))
, Ctx(ctx)
- , State(state)
- {}
+ , State(state)
+ {}
private:
- ui32 GetTraverseCount() const final {
+ ui32 GetTraverseCount() const final {
return 1;
}
- NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
+ NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
Y_UNUSED(index);
return Stream;
}
- NUdf::TUnboxedValue Save() const final {
- return State.Save(Ctx);
+ NUdf::TUnboxedValue Save() const final {
+ return State.Save(Ctx);
}
- void Load(const NUdf::TStringRef& state) final {
- State.Load(Ctx, state);
+ void Load(const NUdf::TStringRef& state) final {
+ State.Load(Ctx, state);
}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- if (ESqueezeState::Finished == State.Stage)
- return NUdf::EFetchStatus::Finish;
-
- for (;;) {
- const auto status = Stream.Fetch(State.Item->RefValue(Ctx));
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ if (ESqueezeState::Finished == State.Stage)
+ return NUdf::EFetchStatus::Finish;
+
+ for (;;) {
+ const auto status = Stream.Fetch(State.Item->RefValue(Ctx));
if (status == NUdf::EFetchStatus::Yield) {
return status;
}
if (status == NUdf::EFetchStatus::Finish) {
- break;
+ break;
}
- if (ESqueezeState::Idle == State.Stage) {
- State.Stage = ESqueezeState::Work;
- State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
+ if (ESqueezeState::Idle == State.Stage) {
+ State.Stage = ESqueezeState::Work;
+ State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
} else {
- if (State.Switch) {
- const auto& reset = State.Switch->GetValue(Ctx);
- if (Interruptable && !reset) {
- break;
- }
-
- if (reset.template Get<bool>()) {
- result = State.State->GetValue(Ctx);
- State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
- return NUdf::EFetchStatus::Ok;
- }
- }
-
- State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
+ if (State.Switch) {
+ const auto& reset = State.Switch->GetValue(Ctx);
+ if (Interruptable && !reset) {
+ break;
+ }
+
+ if (reset.template Get<bool>()) {
+ result = State.State->GetValue(Ctx);
+ State.State->SetValue(Ctx, State.InitState->GetValue(Ctx));
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+
+ State.State->SetValue(Ctx, State.UpdateState->GetValue(Ctx));
}
}
-
- if (ESqueezeState::Idle == State.Stage) {
- State.Stage = ESqueezeState::Finished;
- return NUdf::EFetchStatus::Finish;
- }
-
+
+ if (ESqueezeState::Idle == State.Stage) {
+ State.Stage = ESqueezeState::Finished;
+ return NUdf::EFetchStatus::Finish;
+ }
+
result = State.State->GetValue(Ctx);
- State.Stage = ESqueezeState::Finished;
- return NUdf::EFetchStatus::Ok;
+ State.Stage = ESqueezeState::Finished;
+ return NUdf::EFetchStatus::Ok;
}
- const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Stream;
TComputationContext& Ctx;
- TSqueezeState State;
+ TSqueezeState State;
};
- TCondense1Wrapper(
+ TCondense1Wrapper(
TComputationMutables& mutables,
IComputationNode* stream,
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* updateState,
- IComputationExternalNode* inSave = nullptr,
- IComputationNode* outSave = nullptr,
- IComputationExternalNode* inLoad = nullptr,
- IComputationNode* outLoad = nullptr,
- TType* stateType = nullptr)
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* updateState,
+ IComputationExternalNode* inSave = nullptr,
+ IComputationNode* outSave = nullptr,
+ IComputationExternalNode* inLoad = nullptr,
+ IComputationNode* outLoad = nullptr,
+ TType* stateType = nullptr)
: TBaseComputation(mutables)
, Stream(stream)
- , State(item, state, outSwitch, initState, updateState, inSave, outSave, inLoad, outLoad, stateType)
+ , State(item, state, outSwitch, initState, updateState, inSave, outSave, inLoad, outLoad, stateType)
{
- this->Stateless = false;
+ this->Stateless = false;
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Fetch)
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Fetch)
return ctx.HolderFactory.Create<TSqueezeCodegenValue>(State, Fetch, ctx, Stream->GetValue(ctx));
-#endif
+#endif
return ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx), State, ctx);
}
private:
- void RegisterDependencies() const final {
- this->DependsOn(Stream);
- this->Own(State.Item);
- this->Own(State.State);
- this->DependsOn(State.Switch);
- this->DependsOn(State.InitState);
- this->DependsOn(State.UpdateState);
-
- this->Own(State.InSave);
- this->DependsOn(State.OutSave);
- this->Own(State.InLoad);
- this->DependsOn(State.OutLoad);
+ void RegisterDependencies() const final {
+ this->DependsOn(Stream);
+ this->Own(State.Item);
+ this->Own(State.State);
+ this->DependsOn(State.Switch);
+ this->DependsOn(State.InitState);
+ this->DependsOn(State.UpdateState);
+
+ this->Own(State.InSave);
+ this->DependsOn(State.OutSave);
+ this->Own(State.InLoad);
+ this->DependsOn(State.OutLoad);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FetchFunc = GenerateFetch(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FetchFunc = GenerateFetch(codegen);
codegen->ExportSymbol(FetchFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FetchFunc) {
- Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
- }
- }
-
- Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(State.Item);
- const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(State.State);
-
- MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
- MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto stateType = Type::getInt8Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(stateType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FetchFunc) {
+ Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
+ }
+ }
+
+ Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(State.Item);
+ const auto codegenStateArg = dynamic_cast<ICodegeneratorExternalNode*>(State.State);
+
+ MKQL_ENSURE(codegenItemArg, "Item arg must be codegenerator node.");
+ MKQL_ENSURE(codegenStateArg, "State arg must be codegenerator node.");
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto stateType = Type::getInt8Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(stateType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
- const auto statePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
-
- const auto ychk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "ychk", block);
-
- const auto yies = BasicBlock::Create(context, "yies", ctx.Func);
- const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
- BranchInst::Create(yies, nope, ychk, block);
-
- block = yies;
- ReturnInst::Create(context, status, block);
-
- block = nope;
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- BranchInst::Create(stop, good, icmp, block);
- block = good;
-
- const auto state1 = new LoadInst(statePtr, "state1", block);
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state1, ConstantInt::get(state1->getType(), static_cast<ui8>(ESqueezeState::Idle)), "one", block);
-
- const auto wait = BasicBlock::Create(context, "wait", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- const auto phi = PHINode::Create(valueType, 2, "phi", next);
-
- BranchInst::Create(wait, work, one, block);
- block = wait;
-
- new StoreInst(ConstantInt::get(state1->getType(), static_cast<ui8>(ESqueezeState::Work)), statePtr, block);
- const auto reset = GetNodeValue(State.InitState, ctx, block);
- phi->addIncoming(reset, block);
- BranchInst::Create(next, block);
-
- block = work;
-
- if (State.Switch) {
- const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto reset = GetNodeValue(State.Switch, ctx, block);
- if constexpr (Interruptable) {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, reset, ConstantInt::get(reset->getType(), 0), "done", block);
- BranchInst::Create(stop, next, done, block);
- block = next;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(swap, skip, cast, block);
-
- block = swap;
- SafeUnRefUnboxed(valuePtr, ctx, block);
- const auto state = codegenStateArg->CreateGetValue(ctx, block);
- new StoreInst(state, valuePtr, block);
- ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
- codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
- ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
-
- block = skip;
- }
-
- const auto state = GetNodeValue(State.UpdateState, ctx, block);
- phi->addIncoming(state, block);
- BranchInst::Create(next, block);
-
- block = next;
-
- codegenStateArg->CreateSetValue(ctx, block, phi);
- BranchInst::Create(loop, block);
-
- block = stop;
- const auto state2 = new LoadInst(statePtr, "state2", block);
-
- const auto full = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state2, ConstantInt::get(state2->getType(), static_cast<ui8>(ESqueezeState::Work)), "full", block);
- new StoreInst(ConstantInt::get(state2->getType(), static_cast<ui8>(ESqueezeState::Finished)), statePtr, block);
-
- const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
- BranchInst::Create(fill, yies, full, block);
-
- block = fill;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- const auto result = codegenStateArg->CreateGetValue(ctx, block);
- new StoreInst(result, valuePtr, block);
- ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
- ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
-
- return ctx.Func;
- }
-
- using TFetchPtr = TSqueezeCodegenValue::TFetchPtr;
-
- Function* FetchFunc = nullptr;
-
- TFetchPtr Fetch = nullptr;
-#endif
-
- IComputationNode* const Stream;
- TSqueezeState State;
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+ const auto statePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItemArg->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr);
+
+ const auto ychk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "ychk", block);
+
+ const auto yies = BasicBlock::Create(context, "yies", ctx.Func);
+ const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
+ BranchInst::Create(yies, nope, ychk, block);
+
+ block = yies;
+ ReturnInst::Create(context, status, block);
+
+ block = nope;
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Finish)), "cond", block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ BranchInst::Create(stop, good, icmp, block);
+ block = good;
+
+ const auto state1 = new LoadInst(statePtr, "state1", block);
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state1, ConstantInt::get(state1->getType(), static_cast<ui8>(ESqueezeState::Idle)), "one", block);
+
+ const auto wait = BasicBlock::Create(context, "wait", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ const auto phi = PHINode::Create(valueType, 2, "phi", next);
+
+ BranchInst::Create(wait, work, one, block);
+ block = wait;
+
+ new StoreInst(ConstantInt::get(state1->getType(), static_cast<ui8>(ESqueezeState::Work)), statePtr, block);
+ const auto reset = GetNodeValue(State.InitState, ctx, block);
+ phi->addIncoming(reset, block);
+ BranchInst::Create(next, block);
+
+ block = work;
+
+ if (State.Switch) {
+ const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto reset = GetNodeValue(State.Switch, ctx, block);
+ if constexpr (Interruptable) {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, reset, ConstantInt::get(reset->getType(), 0), "done", block);
+ BranchInst::Create(stop, next, done, block);
+ block = next;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(swap, skip, cast, block);
+
+ block = swap;
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ const auto state = codegenStateArg->CreateGetValue(ctx, block);
+ new StoreInst(state, valuePtr, block);
+ ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
+ codegenStateArg->CreateSetValue(ctx, block, GetNodeValue(State.InitState, ctx, block));
+ ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+
+ block = skip;
+ }
+
+ const auto state = GetNodeValue(State.UpdateState, ctx, block);
+ phi->addIncoming(state, block);
+ BranchInst::Create(next, block);
+
+ block = next;
+
+ codegenStateArg->CreateSetValue(ctx, block, phi);
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ const auto state2 = new LoadInst(statePtr, "state2", block);
+
+ const auto full = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state2, ConstantInt::get(state2->getType(), static_cast<ui8>(ESqueezeState::Work)), "full", block);
+ new StoreInst(ConstantInt::get(state2->getType(), static_cast<ui8>(ESqueezeState::Finished)), statePtr, block);
+
+ const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
+ BranchInst::Create(fill, yies, full, block);
+
+ block = fill;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ const auto result = codegenStateArg->CreateGetValue(ctx, block);
+ new StoreInst(result, valuePtr, block);
+ ValueAddRef(State.State->GetRepresentation(), valuePtr, ctx, block);
+ ReturnInst::Create(context, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+
+ return ctx.Func;
+ }
+
+ using TFetchPtr = TSqueezeCodegenValue::TFetchPtr;
+
+ Function* FetchFunc = nullptr;
+
+ TFetchPtr Fetch = nullptr;
+#endif
+
+ IComputationNode* const Stream;
+ TSqueezeState State;
};
-}
-
-IComputationNode* WrapCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
-
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initState = LocateNode(ctx.NodeLocator, callable, 2);
- const auto outSwitch = LocateNode(ctx.NodeLocator, callable, 4);
- const auto updateState = LocateNode(ctx.NodeLocator, callable, 5);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
-
- bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(4), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
-
- const auto type = callable.GetType()->GetReturnType();
- if (type->IsFlow()) {
- const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
- if (isOptional) {
- return new TCondense1FlowWrapper<true>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
- } else {
- return new TCondense1FlowWrapper<false>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
- }
- } else {
- if (isOptional) {
- return new TCondense1Wrapper<true>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
- } else {
- return new TCondense1Wrapper<false>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
- }
- }
-}
-
+}
+
+IComputationNode* WrapCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
+
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initState = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto outSwitch = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto updateState = LocateNode(ctx.NodeLocator, callable, 5);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(callable.GetInput(4), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
+
+ const auto type = callable.GetType()->GetReturnType();
+ if (type->IsFlow()) {
+ const auto kind = GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType());
+ if (isOptional) {
+ return new TCondense1FlowWrapper<true>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
+ } else {
+ return new TCondense1FlowWrapper<false>(ctx.Mutables, kind, stream, item, state, outSwitch, initState, updateState);
+ }
+ } else {
+ if (isOptional) {
+ return new TCondense1Wrapper<true>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
+ } else {
+ return new TCondense1Wrapper<false>(ctx.Mutables, stream, item, state, outSwitch, initState, updateState);
+ }
+ }
+}
+
IComputationNode* WrapSqueeze1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 9, "Expected 9 args");
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initState = LocateNode(ctx.NodeLocator, callable, 2);
- const auto updateState = LocateNode(ctx.NodeLocator, callable, 4);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initState = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto updateState = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
- IComputationExternalNode* inSave = nullptr;
+ IComputationExternalNode* inSave = nullptr;
IComputationNode* outSave = nullptr;
- IComputationExternalNode* inLoad = nullptr;
+ IComputationExternalNode* inLoad = nullptr;
IComputationNode* outLoad = nullptr;
- const auto hasSaveLoad = !callable.GetInput(6).GetStaticType()->IsVoid();
+ const auto hasSaveLoad = !callable.GetInput(6).GetStaticType()->IsVoid();
if (hasSaveLoad) {
outSave = LocateNode(ctx.NodeLocator, callable, 6);
outLoad = LocateNode(ctx.NodeLocator, callable, 8);
- inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
- inLoad = LocateExternalNode(ctx.NodeLocator, callable, 7);
+ inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
+ inLoad = LocateExternalNode(ctx.NodeLocator, callable, 7);
}
- const auto stateType = hasSaveLoad ? callable.GetInput(6).GetStaticType() : nullptr;
+ const auto stateType = hasSaveLoad ? callable.GetInput(6).GetStaticType() : nullptr;
- return new TCondense1Wrapper<false>(ctx.Mutables, stream, item, state, nullptr, initState, updateState, inSave, outSave, inLoad, outLoad, stateType);
+ return new TCondense1Wrapper<false>(ctx.Mutables, stream, item, state, nullptr, initState, updateState, inSave, outSave, inLoad, outLoad, stateType);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_condense1.h b/ydb/library/yql/minikql/comp_nodes/mkql_condense1.h
index 4a098e129a..3d7915f290 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_condense1.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_condense1.h
@@ -4,7 +4,7 @@
namespace NKikimr {
namespace NMiniKQL {
-IComputationNode* WrapCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx);
IComputationNode* WrapSqueeze1(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_contains.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_contains.cpp
index 736e356f10..54e2e0293d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_contains.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_contains.cpp
@@ -5,13 +5,13 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TContainsWrapper : public TMutableCodegeneratorNode<TContainsWrapper> {
- typedef TMutableCodegeneratorNode<TContainsWrapper> TBaseComputation;
+namespace {
+
+class TContainsWrapper : public TMutableCodegeneratorNode<TContainsWrapper> {
+ typedef TMutableCodegeneratorNode<TContainsWrapper> TBaseComputation;
public:
TContainsWrapper(TComputationMutables& mutables, IComputationNode* dict, IComputationNode* key)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
, Dict(dict)
, Key(key)
{
@@ -21,42 +21,42 @@ public:
return NUdf::TUnboxedValuePod(Dict->GetValue(compCtx).Contains(Key->GetValue(compCtx)));
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto dict = GetNodeValue(Dict, ctx, block);
-
- const auto keyp = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(valueType, 0U, "key", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(valueType, 0U, "key", block);
- GetNodeValue(keyp, Key, ctx, block);
- const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keyp);
-
- ValueUnRef(Key->GetRepresentation(), keyp, ctx, block);
- if (Dict->IsTemporaryValue())
- CleanupBoxed(dict, ctx, block);
- return MakeBoolean(cont, context, block);
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(Dict);
- DependsOn(Key);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto dict = GetNodeValue(Dict, ctx, block);
+
+ const auto keyp = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(valueType, 0U, "key", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(valueType, 0U, "key", block);
+ GetNodeValue(keyp, Key, ctx, block);
+ const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keyp);
+
+ ValueUnRef(Key->GetRepresentation(), keyp, ctx, block);
+ if (Dict->IsTemporaryValue())
+ CleanupBoxed(dict, ctx, block);
+ return MakeBoolean(cont, context, block);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Dict);
+ DependsOn(Key);
}
IComputationNode* const Dict;
IComputationNode* const Key;
};
-}
-
+}
+
IComputationNode* WrapContains(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto dict = LocateNode(ctx.NodeLocator, callable, 0);
- const auto key = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto dict = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto key = LocateNode(ctx.NodeLocator, callable, 1);
return new TContainsWrapper(ctx.Mutables, dict, key);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.cpp
index b31ef14e2c..8e1617b84d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.cpp
@@ -1,60 +1,60 @@
-#include "mkql_decimal_div.h"
+#include "mkql_decimal_div.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
-
-extern "C" NYql::NDecimal::TInt128 DecimalMulAndDivNormalMultiplier(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b, NYql::NDecimal::TInt128 c) {
- return NYql::NDecimal::MulAndDivNormalMultiplier(a, b, c);
-}
-
-extern "C" NYql::NDecimal::TInt128 DecimalDiv(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b) {
- return NYql::NDecimal::Div(a, b);
-}
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template<bool IsLeftOptional, bool IsRightOptional>
-class TDecimalDivWrapper : public TMutableCodegeneratorNode<TDecimalDivWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TMutableCodegeneratorNode<TDecimalDivWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
-public:
- TDecimalDivWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- , Bound(NYql::NDecimal::GetDivider(precision))
- , Divider(NYql::NDecimal::GetDivider(scale))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- const auto div = NYql::NDecimal::MulAndDivNormalMultiplier(left.GetInt128(), Divider, right.GetInt128());
- if (div > -Bound && div < +Bound)
- return NUdf::TUnboxedValuePod(div);
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(div) ? NYql::NDecimal::Nan() : (div > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
+
+extern "C" NYql::NDecimal::TInt128 DecimalMulAndDivNormalMultiplier(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b, NYql::NDecimal::TInt128 c) {
+ return NYql::NDecimal::MulAndDivNormalMultiplier(a, b, c);
+}
+
+extern "C" NYql::NDecimal::TInt128 DecimalDiv(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b) {
+ return NYql::NDecimal::Div(a, b);
+}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template<bool IsLeftOptional, bool IsRightOptional>
+class TDecimalDivWrapper : public TMutableCodegeneratorNode<TDecimalDivWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TMutableCodegeneratorNode<TDecimalDivWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+public:
+ TDecimalDivWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ , Bound(NYql::NDecimal::GetDivider(precision))
+ , Divider(NYql::NDecimal::GetDivider(scale))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ const auto div = NYql::NDecimal::MulAndDivNormalMultiplier(left.GetInt128(), Divider, right.GetInt128());
+ if (div > -Bound && div < +Bound)
+ return NUdf::TUnboxedValuePod(div);
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(div) ? NYql::NDecimal::Nan() : (div > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto name = "DecimalMulAndDivNormalMultiplier";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMulAndDivNormalMultiplier));
+
+ const auto name = "DecimalMulAndDivNormalMultiplier";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMulAndDivNormalMultiplier));
llvm::Value* func;
if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
const auto fnType = FunctionType::get(valType, { valType, valType, valType }, false);
@@ -63,247 +63,247 @@ public:
const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr, valTypePtr }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
}
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(test, block);
-
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(test, block);
+
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
Value* muldiv;
if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), NDecimal::GenConstant(Divider, context), GetterForInt128(right, block) }, "mul_and_div", block);
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), NDecimal::GenConstant(Divider, context), GetterForInt128(right, block) }, "mul_and_div", block);
} else {
const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(NDecimal::GenConstant(Divider, context), arg2Ptr, block);
+ new StoreInst(NDecimal::GenConstant(Divider, context), arg2Ptr, block);
new StoreInst(GetterForInt128(right, block), arg3Ptr, block);
CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
muldiv = new LoadInst(retPtr, "res", block);
}
-
- const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
-
- result->addIncoming(SetterForInt128(res, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
+
+ const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
+
+ result->addIncoming(SetterForInt128(res, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
Value* muldiv;
if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), NDecimal::GenConstant(Divider, context), GetterForInt128(right, block) }, "mul_and_div", block);
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), NDecimal::GenConstant(Divider, context), GetterForInt128(right, block) }, "mul_and_div", block);
} else {
const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(NDecimal::GenConstant(Divider, context), arg2Ptr, block);
+ new StoreInst(NDecimal::GenConstant(Divider, context), arg2Ptr, block);
new StoreInst(GetterForInt128(right, block), arg3Ptr, block);
CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
muldiv = new LoadInst(retPtr, "res", block);
}
-
- const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
-
- return SetterForInt128(res, block);
- }
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
- const NYql::NDecimal::TInt128 Bound;
- const NYql::NDecimal::TInt128 Divider;
-};
-
-template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
-class TDecimalDivIntegralWrapper : public TMutableCodegeneratorNode<TDecimalDivIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
- typedef TMutableCodegeneratorNode<TDecimalDivIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
-public:
- TDecimalDivIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::Div(left.GetInt128(), NYql::NDecimal::TInt128(right.Get<TRight>())));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto fnType = FunctionType::get(valType, {valType, valType}, false);
- const auto name = "DecimalDiv";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalDiv));
+
+ const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
+
+ return SetterForInt128(res, block);
+ }
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+ const NYql::NDecimal::TInt128 Bound;
+ const NYql::NDecimal::TInt128 Divider;
+};
+
+template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
+class TDecimalDivIntegralWrapper : public TMutableCodegeneratorNode<TDecimalDivIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
+ typedef TMutableCodegeneratorNode<TDecimalDivIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
+public:
+ TDecimalDivIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::Div(left.GetInt128(), NYql::NDecimal::TInt128(right.Get<TRight>())));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto fnType = FunctionType::get(valType, {valType, valType}, false);
+ const auto name = "DecimalDiv";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalDiv));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, valType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, valType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(test, block);
-
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
-
- Value* div;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- div = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(cast, arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- div = new LoadInst(retPtr, "res", block);
- }
-
- result->addIncoming(SetterForInt128(div, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
- Value* div;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- div = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(cast, arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- div = new LoadInst(retPtr, "res", block);
- }
- return SetterForInt128(div, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
-};
-
-}
-
-IComputationNode* WrapDecimalDiv(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
-
- bool isOptionalLeft, isOptionalRight;
-
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
- const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
-
- auto left = LocateNode(ctx.NodeLocator, callable, 0);
- auto right = LocateNode(ctx.NodeLocator, callable, 1);
-
- switch(rightType->GetSchemeType()) {
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
-
- if (isOptionalLeft && isOptionalRight)
- return new TDecimalDivWrapper<true, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else if (isOptionalLeft)
- return new TDecimalDivWrapper<true, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else if (isOptionalRight)
- return new TDecimalDivWrapper<false, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else
- return new TDecimalDivWrapper<false, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
-#define MAKE_PRIMITIVE_TYPE_DIV(type) \
- case NUdf::TDataType<type>::Id: \
- if (isOptionalLeft && isOptionalRight) \
- return new TDecimalDivIntegralWrapper<true, true, type>(ctx.Mutables, left, right); \
- else if (isOptionalLeft) \
- return new TDecimalDivIntegralWrapper<true, false, type>(ctx.Mutables, left, right); \
- else if (isOptionalRight) \
- return new TDecimalDivIntegralWrapper<false, true, type>(ctx.Mutables, left, right); \
- else \
- return new TDecimalDivIntegralWrapper<false, false, type>(ctx.Mutables, left, right);
- INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_DIV)
-#undef MAKE_PRIMITIVE_TYPE_DIV
- default:
- Y_FAIL("Unupported type.");
- }
-}
-
-}
-}
+ }
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(test, block);
+
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+
+ Value* div;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ div = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(cast, arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ div = new LoadInst(retPtr, "res", block);
+ }
+
+ result->addIncoming(SetterForInt128(div, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+ Value* div;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ div = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(cast, arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ div = new LoadInst(retPtr, "res", block);
+ }
+ return SetterForInt128(div, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+};
+
+}
+
+IComputationNode* WrapDecimalDiv(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
+
+ bool isOptionalLeft, isOptionalRight;
+
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
+ const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
+
+ auto left = LocateNode(ctx.NodeLocator, callable, 0);
+ auto right = LocateNode(ctx.NodeLocator, callable, 1);
+
+ switch(rightType->GetSchemeType()) {
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+
+ if (isOptionalLeft && isOptionalRight)
+ return new TDecimalDivWrapper<true, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else if (isOptionalLeft)
+ return new TDecimalDivWrapper<true, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else if (isOptionalRight)
+ return new TDecimalDivWrapper<false, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else
+ return new TDecimalDivWrapper<false, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+#define MAKE_PRIMITIVE_TYPE_DIV(type) \
+ case NUdf::TDataType<type>::Id: \
+ if (isOptionalLeft && isOptionalRight) \
+ return new TDecimalDivIntegralWrapper<true, true, type>(ctx.Mutables, left, right); \
+ else if (isOptionalLeft) \
+ return new TDecimalDivIntegralWrapper<true, false, type>(ctx.Mutables, left, right); \
+ else if (isOptionalRight) \
+ return new TDecimalDivIntegralWrapper<false, true, type>(ctx.Mutables, left, right); \
+ else \
+ return new TDecimalDivIntegralWrapper<false, false, type>(ctx.Mutables, left, right);
+ INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_DIV)
+#undef MAKE_PRIMITIVE_TYPE_DIV
+ default:
+ Y_FAIL("Unupported type.");
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.h b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.h
index b65f2db0bb..4041e32b0a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_div.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapDecimalDiv(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapDecimalDiv(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.cpp
index b205f70059..280eeb463a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.cpp
@@ -1,286 +1,286 @@
-#include "mkql_decimal_div.h"
+#include "mkql_decimal_div.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template<bool IsLeftOptional, bool IsRightOptional>
-class TDecimalModWrapper : public TMutableCodegeneratorNode<TDecimalModWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TMutableCodegeneratorNode<TDecimalModWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
-public:
- TDecimalModWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::Mod(left.GetInt128(), right.GetInt128()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto result = PHINode::Create(valType, IsLeftOptional || IsRightOptional ? 3 : 2, "result", done);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, test, zero, "check", block);
- result->addIncoming(zero, block);
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
- const auto lv = GetterForInt128(left, block);
- const auto rv = GetterForInt128(right, block);
-
- const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
- const auto rbad = NDecimal::GenIsAbnormal(rv, context, block);
- const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
- const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, zero, "check", block);
- const auto nan = BinaryOperator::CreateOr(bad, nul, "nan", block);
-
- const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
-
- result->addIncoming(SetterForInt128(GetDecimalNan(context), block), block);
- BranchInst::Create(done, norm, nan, block);
-
- block = norm;
- const auto srem = BinaryOperator::CreateSRem(lv, rv, "srem", block);
- result->addIncoming(SetterForInt128(srem, block), block);
- } else {
- const auto lv = GetterForInt128(left, block);
- const auto rv = GetterForInt128(right, block);
-
- const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
- const auto rbad = NDecimal::GenIsAbnormal(rv, context, block);
- const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
- const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, zero, "check", block);
- const auto nan = BinaryOperator::CreateOr(bad, nul, "nan", block);
-
- result->addIncoming(SetterForInt128(GetDecimalNan(context), block), block);
- BranchInst::Create(done, good, nan, block);
-
- block = good;
- const auto srem = BinaryOperator::CreateSRem(lv, rv, "srem", block);
- result->addIncoming(SetterForInt128(srem, block), block);
- }
-
- BranchInst::Create(done, block);
- block = done;
- return result;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
-};
-
-template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
-class TDecimalModIntegralWrapper : public TMutableCodegeneratorNode<TDecimalModIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
- typedef TMutableCodegeneratorNode<TDecimalModIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
-public:
- TDecimalModIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- , Bound(NYql::NDecimal::GetDivider(precision - scale))
- , Divider(NYql::NDecimal::GetDivider(scale))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- auto left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- const auto r = NYql::NDecimal::TInt128(right.Get<TRight>());
-
- if (std::is_signed<TRight>::value) {
- if (r >= +Bound || r <= -Bound)
- return left.Release();
- } else {
- if (r >= Bound)
- return left.Release();
- }
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::Mod(left.GetInt128(), NYql::NDecimal::Mul(Divider, r)));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto divider = NDecimal::GenConstant(Divider, context);
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto result = PHINode::Create(valType, IsLeftOptional || IsRightOptional ? 3 : 2, "result", done);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- result->addIncoming(zero, block);
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
- const auto lv = GetterForInt128(left, block);
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
-
- const auto out = std::is_signed<TRight>() ?
- NDecimal::GenOutOfBounds(cast, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block):
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, cast, NDecimal::GenConstant(Bound, context), "out", block);
-
- const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cast, zero, "check", block);
-
- const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
- const auto rbad = BinaryOperator::CreateOr(out, nul, "or", block);
- const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
-
- const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
-
- const auto spec = SelectInst::Create(out, left, SetterForInt128(GetDecimalNan(context), block), "spec", block);
- result->addIncoming(spec, block);
- BranchInst::Create(done, norm, bad, block);
-
- block = norm;
- const auto mul = BinaryOperator::CreateMul(divider, cast, "mul", block);
- const auto srem = BinaryOperator::CreateSRem(lv, mul, "srem", block);
- result->addIncoming(SetterForInt128(srem, block), block);
- } else {
- const auto lv = GetterForInt128(left, block);
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
-
- const auto out = std::is_signed<TRight>() ?
- NDecimal::GenOutOfBounds(cast, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block):
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, cast, NDecimal::GenConstant(Bound, context), "out", block);
-
- const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cast, zero, "check", block);
-
- const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
- const auto rbad = BinaryOperator::CreateOr(out, nul, "or", block);
- const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
-
- const auto spec = SelectInst::Create(out, left, SetterForInt128(GetDecimalNan(context), block), "spec", block);
-
- result->addIncoming(spec, block);
- BranchInst::Create(done, good, bad, block);
-
- block = good;
- const auto mul = BinaryOperator::CreateMul(divider, cast, "mul", block);
- const auto srem = BinaryOperator::CreateSRem(lv, mul, "srem", block);
- result->addIncoming(SetterForInt128(srem, block), block);
- }
-
- BranchInst::Create(done, block);
- block = done;
- return result;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
- const NYql::NDecimal::TInt128 Bound;
- const NYql::NDecimal::TInt128 Divider;
-};
-
-}
-
-IComputationNode* WrapDecimalMod(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
-
- bool isOptionalLeft, isOptionalRight;
-
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
- const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
-
- auto left = LocateNode(ctx.NodeLocator, callable, 0);
- auto right = LocateNode(ctx.NodeLocator, callable, 1);
-
- switch(rightType->GetSchemeType()) {
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
-
- if (isOptionalLeft && isOptionalRight)
- return new TDecimalModWrapper<true, true>(ctx.Mutables, left, right);
- else if (isOptionalLeft)
- return new TDecimalModWrapper<true, false>(ctx.Mutables, left, right);
- else if (isOptionalRight)
- return new TDecimalModWrapper<false, true>(ctx.Mutables, left, right);
- else
- return new TDecimalModWrapper<false, false>(ctx.Mutables, left, right);
-#define MAKE_PRIMITIVE_TYPE_MOD(type) \
- case NUdf::TDataType<type>::Id: \
- if (isOptionalLeft && isOptionalRight) \
- return new TDecimalModIntegralWrapper<true, true, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
- else if (isOptionalLeft) \
- return new TDecimalModIntegralWrapper<true, false, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
- else if (isOptionalRight) \
- return new TDecimalModIntegralWrapper<false, true, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
- else \
- return new TDecimalModIntegralWrapper<false, false, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_MOD)
-#undef MAKE_PRIMITIVE_TYPE_MOD
- default:
- Y_FAIL("Unupported type.");
- }
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template<bool IsLeftOptional, bool IsRightOptional>
+class TDecimalModWrapper : public TMutableCodegeneratorNode<TDecimalModWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TMutableCodegeneratorNode<TDecimalModWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+public:
+ TDecimalModWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::Mod(left.GetInt128(), right.GetInt128()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto result = PHINode::Create(valType, IsLeftOptional || IsRightOptional ? 3 : 2, "result", done);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, test, zero, "check", block);
+ result->addIncoming(zero, block);
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
+ const auto lv = GetterForInt128(left, block);
+ const auto rv = GetterForInt128(right, block);
+
+ const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
+ const auto rbad = NDecimal::GenIsAbnormal(rv, context, block);
+ const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
+ const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, zero, "check", block);
+ const auto nan = BinaryOperator::CreateOr(bad, nul, "nan", block);
+
+ const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
+
+ result->addIncoming(SetterForInt128(GetDecimalNan(context), block), block);
+ BranchInst::Create(done, norm, nan, block);
+
+ block = norm;
+ const auto srem = BinaryOperator::CreateSRem(lv, rv, "srem", block);
+ result->addIncoming(SetterForInt128(srem, block), block);
+ } else {
+ const auto lv = GetterForInt128(left, block);
+ const auto rv = GetterForInt128(right, block);
+
+ const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
+ const auto rbad = NDecimal::GenIsAbnormal(rv, context, block);
+ const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
+ const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, zero, "check", block);
+ const auto nan = BinaryOperator::CreateOr(bad, nul, "nan", block);
+
+ result->addIncoming(SetterForInt128(GetDecimalNan(context), block), block);
+ BranchInst::Create(done, good, nan, block);
+
+ block = good;
+ const auto srem = BinaryOperator::CreateSRem(lv, rv, "srem", block);
+ result->addIncoming(SetterForInt128(srem, block), block);
+ }
+
+ BranchInst::Create(done, block);
+ block = done;
+ return result;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+};
+
+template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
+class TDecimalModIntegralWrapper : public TMutableCodegeneratorNode<TDecimalModIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
+ typedef TMutableCodegeneratorNode<TDecimalModIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
+public:
+ TDecimalModIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ , Bound(NYql::NDecimal::GetDivider(precision - scale))
+ , Divider(NYql::NDecimal::GetDivider(scale))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ auto left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ const auto r = NYql::NDecimal::TInt128(right.Get<TRight>());
+
+ if (std::is_signed<TRight>::value) {
+ if (r >= +Bound || r <= -Bound)
+ return left.Release();
+ } else {
+ if (r >= Bound)
+ return left.Release();
+ }
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::Mod(left.GetInt128(), NYql::NDecimal::Mul(Divider, r)));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto divider = NDecimal::GenConstant(Divider, context);
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto result = PHINode::Create(valType, IsLeftOptional || IsRightOptional ? 3 : 2, "result", done);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ result->addIncoming(zero, block);
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
+ const auto lv = GetterForInt128(left, block);
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+
+ const auto out = std::is_signed<TRight>() ?
+ NDecimal::GenOutOfBounds(cast, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block):
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, cast, NDecimal::GenConstant(Bound, context), "out", block);
+
+ const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cast, zero, "check", block);
+
+ const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
+ const auto rbad = BinaryOperator::CreateOr(out, nul, "or", block);
+ const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
+
+ const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
+
+ const auto spec = SelectInst::Create(out, left, SetterForInt128(GetDecimalNan(context), block), "spec", block);
+ result->addIncoming(spec, block);
+ BranchInst::Create(done, norm, bad, block);
+
+ block = norm;
+ const auto mul = BinaryOperator::CreateMul(divider, cast, "mul", block);
+ const auto srem = BinaryOperator::CreateSRem(lv, mul, "srem", block);
+ result->addIncoming(SetterForInt128(srem, block), block);
+ } else {
+ const auto lv = GetterForInt128(left, block);
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+
+ const auto out = std::is_signed<TRight>() ?
+ NDecimal::GenOutOfBounds(cast, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block):
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, cast, NDecimal::GenConstant(Bound, context), "out", block);
+
+ const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cast, zero, "check", block);
+
+ const auto lbad = NDecimal::GenIsAbnormal(lv, context, block);
+ const auto rbad = BinaryOperator::CreateOr(out, nul, "or", block);
+ const auto bad = BinaryOperator::CreateOr(lbad, rbad, "bad", block);
+
+ const auto spec = SelectInst::Create(out, left, SetterForInt128(GetDecimalNan(context), block), "spec", block);
+
+ result->addIncoming(spec, block);
+ BranchInst::Create(done, good, bad, block);
+
+ block = good;
+ const auto mul = BinaryOperator::CreateMul(divider, cast, "mul", block);
+ const auto srem = BinaryOperator::CreateSRem(lv, mul, "srem", block);
+ result->addIncoming(SetterForInt128(srem, block), block);
+ }
+
+ BranchInst::Create(done, block);
+ block = done;
+ return result;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+ const NYql::NDecimal::TInt128 Bound;
+ const NYql::NDecimal::TInt128 Divider;
+};
+
+}
+
+IComputationNode* WrapDecimalMod(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
+
+ bool isOptionalLeft, isOptionalRight;
+
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
+ const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
+
+ auto left = LocateNode(ctx.NodeLocator, callable, 0);
+ auto right = LocateNode(ctx.NodeLocator, callable, 1);
+
+ switch(rightType->GetSchemeType()) {
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+
+ if (isOptionalLeft && isOptionalRight)
+ return new TDecimalModWrapper<true, true>(ctx.Mutables, left, right);
+ else if (isOptionalLeft)
+ return new TDecimalModWrapper<true, false>(ctx.Mutables, left, right);
+ else if (isOptionalRight)
+ return new TDecimalModWrapper<false, true>(ctx.Mutables, left, right);
+ else
+ return new TDecimalModWrapper<false, false>(ctx.Mutables, left, right);
+#define MAKE_PRIMITIVE_TYPE_MOD(type) \
+ case NUdf::TDataType<type>::Id: \
+ if (isOptionalLeft && isOptionalRight) \
+ return new TDecimalModIntegralWrapper<true, true, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
+ else if (isOptionalLeft) \
+ return new TDecimalModIntegralWrapper<true, false, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
+ else if (isOptionalRight) \
+ return new TDecimalModIntegralWrapper<false, true, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second); \
+ else \
+ return new TDecimalModIntegralWrapper<false, false, type>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_MOD)
+#undef MAKE_PRIMITIVE_TYPE_MOD
+ default:
+ Y_FAIL("Unupported type.");
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.h b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.h
index 034742afae..b097b257e0 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mod.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapDecimalMod(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapDecimalMod(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.cpp
index 4eb6000aed..746fef8173 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.cpp
@@ -1,378 +1,378 @@
-#include "mkql_decimal_mul.h"
+#include "mkql_decimal_mul.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
-
-extern "C" NYql::NDecimal::TInt128 DecimalMulAndDivNormalDivider(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b, NYql::NDecimal::TInt128 c) {
- return NYql::NDecimal::MulAndDivNormalDivider(a, b, c);
-}
-
-extern "C" NYql::NDecimal::TInt128 DecimalMul(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b) {
- return NYql::NDecimal::Mul(a, b);
-}
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template<bool IsLeftOptional, bool IsRightOptional>
-class TDecimalMulWrapper : public TMutableCodegeneratorNode<TDecimalMulWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TMutableCodegeneratorNode<TDecimalMulWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
-public:
- TDecimalMulWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- , Bound(NYql::NDecimal::GetDivider(precision))
- , Divider(NYql::NDecimal::GetDivider(scale))
- {
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- const auto mul = Divider > 1 ?
- NYql::NDecimal::MulAndDivNormalDivider(left.GetInt128(), right.GetInt128(), Divider):
- NYql::NDecimal::Mul(left.GetInt128(), right.GetInt128());
-
- if (mul > -Bound && mul < +Bound)
- return NUdf::TUnboxedValuePod(mul);
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(mul) ? NYql::NDecimal::Nan() : (mul > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
+
+extern "C" NYql::NDecimal::TInt128 DecimalMulAndDivNormalDivider(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b, NYql::NDecimal::TInt128 c) {
+ return NYql::NDecimal::MulAndDivNormalDivider(a, b, c);
+}
+
+extern "C" NYql::NDecimal::TInt128 DecimalMul(NYql::NDecimal::TInt128 a, NYql::NDecimal::TInt128 b) {
+ return NYql::NDecimal::Mul(a, b);
+}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template<bool IsLeftOptional, bool IsRightOptional>
+class TDecimalMulWrapper : public TMutableCodegeneratorNode<TDecimalMulWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TMutableCodegeneratorNode<TDecimalMulWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+public:
+ TDecimalMulWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision, ui8 scale)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ , Bound(NYql::NDecimal::GetDivider(precision))
+ , Divider(NYql::NDecimal::GetDivider(scale))
+ {
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ const auto mul = Divider > 1 ?
+ NYql::NDecimal::MulAndDivNormalDivider(left.GetInt128(), right.GetInt128(), Divider):
+ NYql::NDecimal::Mul(left.GetInt128(), right.GetInt128());
+
+ if (mul > -Bound && mul < +Bound)
+ return NUdf::TUnboxedValuePod(mul);
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(mul) ? NYql::NDecimal::Nan() : (mul > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
const auto valTypePtr = PointerType::getUnqual(valType);
-
+
llvm::Value* func;
- const bool useMulAddDiv = Divider > 1;
- if (useMulAddDiv) {
- const auto name = "DecimalMulAndDivNormalDivider";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMulAndDivNormalDivider));
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, valType, valType }, false);
+ const bool useMulAddDiv = Divider > 1;
+ if (useMulAddDiv) {
+ const auto name = "DecimalMulAndDivNormalDivider";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMulAndDivNormalDivider));
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, valType, valType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr, valTypePtr }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr, valTypePtr }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
+ }
} else {
- const auto name = "DecimalMul";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMul));
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, valType}, false);
+ const auto name = "DecimalMul";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMul));
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, valType}, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
+ }
}
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(test, block);
-
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(test, block);
+
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
Value* muldiv;
- if (useMulAddDiv) {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block), NDecimal::GenConstant(Divider, context) }, "mul_and_div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
- new StoreInst(NDecimal::GenConstant(Divider, context), arg3Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
- muldiv = new LoadInst(retPtr, "res", block);
- }
+ if (useMulAddDiv) {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block), NDecimal::GenConstant(Divider, context) }, "mul_and_div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
+ new StoreInst(NDecimal::GenConstant(Divider, context), arg3Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
+ muldiv = new LoadInst(retPtr, "res", block);
+ }
} else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block) }, "mul", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- muldiv = new LoadInst(retPtr, "res", block);
- }
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block) }, "mul", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ muldiv = new LoadInst(retPtr, "res", block);
+ }
}
-
- const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
-
- result->addIncoming(SetterForInt128(res, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
+
+ const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
+
+ result->addIncoming(SetterForInt128(res, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
Value* muldiv;
- if (useMulAddDiv) {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block), NDecimal::GenConstant(Divider, context) }, "mul_and_div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
- new StoreInst(NDecimal::GenConstant(Divider, context), arg3Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
- muldiv = new LoadInst(retPtr, "res", block);
- }
+ if (useMulAddDiv) {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block), NDecimal::GenConstant(Divider, context) }, "mul_and_div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ const auto arg3Ptr = new AllocaInst(valType, 0U, "arg3", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
+ new StoreInst(NDecimal::GenConstant(Divider, context), arg3Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr, arg3Ptr }, "", block);
+ muldiv = new LoadInst(retPtr, "res", block);
+ }
} else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block) }, "mul", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- muldiv = new LoadInst(retPtr, "res", block);
- }
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ muldiv = CallInst::Create(func, { GetterForInt128(left, block), GetterForInt128(right, block) }, "mul", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(GetterForInt128(right, block), arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ muldiv = new LoadInst(retPtr, "res", block);
+ }
}
-
- const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
-
- return SetterForInt128(res, block);
- }
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
- const NYql::NDecimal::TInt128 Bound;
- const NYql::NDecimal::TInt128 Divider;
-};
-
-template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
-class TDecimalMulIntegralWrapper : public TMutableCodegeneratorNode<TDecimalMulIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
- typedef TMutableCodegeneratorNode<TDecimalMulIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
-public:
- TDecimalMulIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Left(left)
- , Right(right)
- , Bound(NYql::NDecimal::GetDivider(precision))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& left = Left->GetValue(compCtx);
- const auto& right = Right->GetValue(compCtx);
-
- if (IsLeftOptional && !left)
- return NUdf::TUnboxedValuePod();
-
- if (IsRightOptional && !right)
- return NUdf::TUnboxedValuePod();
-
- const auto mul = NYql::NDecimal::Mul(left.GetInt128(), NYql::NDecimal::TInt128(right.Get<TRight>()));
-
- if (mul > -Bound && mul < +Bound)
- return NUdf::TUnboxedValuePod(mul);
-
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(mul) ? NYql::NDecimal::Nan() : (mul > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto fnType = FunctionType::get(valType, {valType, valType}, false);
- const auto name = "DecimalMul";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMul));
+
+ const auto ok = NDecimal::GenInBounds(muldiv, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(muldiv, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, muldiv, ConstantInt::get(muldiv->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, muldiv, bad, "res", block);
+
+ return SetterForInt128(res, block);
+ }
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+ const NYql::NDecimal::TInt128 Bound;
+ const NYql::NDecimal::TInt128 Divider;
+};
+
+template<bool IsLeftOptional, bool IsRightOptional, typename TRight>
+class TDecimalMulIntegralWrapper : public TMutableCodegeneratorNode<TDecimalMulIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> {
+ typedef TMutableCodegeneratorNode<TDecimalMulIntegralWrapper<IsLeftOptional, IsRightOptional, TRight>> TBaseComputation;
+public:
+ TDecimalMulIntegralWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right, ui8 precision)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Left(left)
+ , Right(right)
+ , Bound(NYql::NDecimal::GetDivider(precision))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& left = Left->GetValue(compCtx);
+ const auto& right = Right->GetValue(compCtx);
+
+ if (IsLeftOptional && !left)
+ return NUdf::TUnboxedValuePod();
+
+ if (IsRightOptional && !right)
+ return NUdf::TUnboxedValuePod();
+
+ const auto mul = NYql::NDecimal::Mul(left.GetInt128(), NYql::NDecimal::TInt128(right.Get<TRight>()));
+
+ if (mul > -Bound && mul < +Bound)
+ return NUdf::TUnboxedValuePod(mul);
+
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsNan(mul) ? NYql::NDecimal::Nan() : (mul > 0 ? +NYql::NDecimal::Inf() : -NYql::NDecimal::Inf()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto fnType = FunctionType::get(valType, {valType, valType}, false);
+ const auto name = "DecimalMul";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalMul));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, valType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, valType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, valTypePtr }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto test = IsLeftOptional && IsRightOptional ?
- BinaryOperator::CreateAnd(left, right, "test", block):
- IsLeftOptional ? left : right;
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(test, block);
-
- BranchInst::Create(done, good, IsEmpty(test, block), block);
-
- block = good;
-
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
- Value* mul;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- mul = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(cast, arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- mul = new LoadInst(retPtr, "res", block);
- }
-
- const auto ok = NDecimal::GenInBounds(mul, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(mul, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, mul, ConstantInt::get(mul->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, mul, bad, "res", block);
-
- result->addIncoming(SetterForInt128(res, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- const auto cast = std::is_signed<TRight>() ?
- static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
- static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
- Value* mul;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- mul = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
- const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
- new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
- new StoreInst(cast, arg2Ptr, block);
- CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
- mul = new LoadInst(retPtr, "res", block);
- }
-
- const auto ok = NDecimal::GenInBounds(mul, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
- const auto nan = NDecimal::GenIsNonComparable(mul, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, mul, ConstantInt::get(mul->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(ok, mul, bad, "res", block);
-
- return SetterForInt128(res, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
- }
-
- IComputationNode* const Left;
- IComputationNode* const Right;
- const NYql::NDecimal::TInt128 Bound;
-};
-
-
-}
-
-IComputationNode* WrapDecimalMul(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
-
- bool isOptionalLeft, isOptionalRight;
-
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
- const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
-
- auto left = LocateNode(ctx.NodeLocator, callable, 0);
- auto right = LocateNode(ctx.NodeLocator, callable, 1);
-
- switch(rightType->GetSchemeType()) {
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
-
- if (isOptionalLeft && isOptionalRight)
- return new TDecimalMulWrapper<true, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else if (isOptionalLeft)
- return new TDecimalMulWrapper<true, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else if (isOptionalRight)
- return new TDecimalMulWrapper<false, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
- else
- return new TDecimalMulWrapper<false, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
-#define MAKE_PRIMITIVE_TYPE_MUL(type) \
- case NUdf::TDataType<type>::Id: \
- if (isOptionalLeft && isOptionalRight) \
- return new TDecimalMulIntegralWrapper<true, true, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
- else if (isOptionalLeft) \
- return new TDecimalMulIntegralWrapper<true, false, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
- else if (isOptionalRight) \
- return new TDecimalMulIntegralWrapper<false, true, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
- else \
- return new TDecimalMulIntegralWrapper<false, false, type>(ctx.Mutables, left, right, leftType->GetParams().first);
- INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_MUL)
-#undef MAKE_PRIMITIVE_TYPE_MUL
- default:
- Y_FAIL("Unupported type.");
- }
-}
-
-}
-}
+ }
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto test = IsLeftOptional && IsRightOptional ?
+ BinaryOperator::CreateAnd(left, right, "test", block):
+ IsLeftOptional ? left : right;
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(test, block);
+
+ BranchInst::Create(done, good, IsEmpty(test, block), block);
+
+ block = good;
+
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+ Value* mul;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ mul = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(cast, arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ mul = new LoadInst(retPtr, "res", block);
+ }
+
+ const auto ok = NDecimal::GenInBounds(mul, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(mul, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, mul, ConstantInt::get(mul->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, mul, bad, "res", block);
+
+ result->addIncoming(SetterForInt128(res, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ const auto cast = std::is_signed<TRight>() ?
+ static_cast<CastInst*>(new SExtInst(GetterFor<TRight>(right, context, block), valType, "sext", block)):
+ static_cast<CastInst*>(new ZExtInst(GetterFor<TRight>(right, context, block), valType, "zext", block));
+ Value* mul;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ mul = CallInst::Create(func, {GetterForInt128(left, block), cast}, "div", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ const auto arg1Ptr = new AllocaInst(valType, 0U, "arg1", block);
+ const auto arg2Ptr = new AllocaInst(valType, 0U, "arg2", block);
+ new StoreInst(GetterForInt128(left, block), arg1Ptr, block);
+ new StoreInst(cast, arg2Ptr, block);
+ CallInst::Create(func, { retPtr, arg1Ptr, arg2Ptr }, "", block);
+ mul = new LoadInst(retPtr, "res", block);
+ }
+
+ const auto ok = NDecimal::GenInBounds(mul, NDecimal::GenConstant(-Bound, context), NDecimal::GenConstant(+Bound, context), block);
+ const auto nan = NDecimal::GenIsNonComparable(mul, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, mul, ConstantInt::get(mul->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(ok, mul, bad, "res", block);
+
+ return SetterForInt128(res, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
+ }
+
+ IComputationNode* const Left;
+ IComputationNode* const Right;
+ const NYql::NDecimal::TInt128 Bound;
+};
+
+
+}
+
+IComputationNode* WrapDecimalMul(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
+
+ bool isOptionalLeft, isOptionalRight;
+
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(callable.GetInput(0), isOptionalLeft));
+ const auto rightType = UnpackOptionalData(callable.GetInput(1), isOptionalRight);
+
+ auto left = LocateNode(ctx.NodeLocator, callable, 0);
+ auto right = LocateNode(ctx.NodeLocator, callable, 1);
+
+ switch(rightType->GetSchemeType()) {
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+
+ if (isOptionalLeft && isOptionalRight)
+ return new TDecimalMulWrapper<true, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else if (isOptionalLeft)
+ return new TDecimalMulWrapper<true, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else if (isOptionalRight)
+ return new TDecimalMulWrapper<false, true>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+ else
+ return new TDecimalMulWrapper<false, false>(ctx.Mutables, left, right, leftType->GetParams().first, leftType->GetParams().second);
+#define MAKE_PRIMITIVE_TYPE_MUL(type) \
+ case NUdf::TDataType<type>::Id: \
+ if (isOptionalLeft && isOptionalRight) \
+ return new TDecimalMulIntegralWrapper<true, true, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
+ else if (isOptionalLeft) \
+ return new TDecimalMulIntegralWrapper<true, false, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
+ else if (isOptionalRight) \
+ return new TDecimalMulIntegralWrapper<false, true, type>(ctx.Mutables, left, right, leftType->GetParams().first); \
+ else \
+ return new TDecimalMulIntegralWrapper<false, false, type>(ctx.Mutables, left, right, leftType->GetParams().first);
+ INTEGRAL_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_MUL)
+#undef MAKE_PRIMITIVE_TYPE_MUL
+ default:
+ Y_FAIL("Unupported type.");
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.h b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.h
index 3741239d57..916b393dcf 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_decimal_mul.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapDecimalMul(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapDecimalMul(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.cpp
index 4f681a5ffd..a20f016b57 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.cpp
@@ -7,282 +7,282 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TDictItemsWrapper : public TCustomValueCodegeneratorNode<TDictItemsWrapper> {
- typedef TCustomValueCodegeneratorNode<TDictItemsWrapper> TBaseComputation;
+namespace {
+
+class TDictItemsWrapper : public TCustomValueCodegeneratorNode<TDictItemsWrapper> {
+ typedef TCustomValueCodegeneratorNode<TDictItemsWrapper> TBaseComputation;
public:
- using TSelf = TDictItemsWrapper;
-
+ using TSelf = TDictItemsWrapper;
+
#ifndef MKQL_DISABLE_CODEGEN
- class TCodegenValue : public TComputationValue<TCodegenValue> {
+ class TCodegenValue : public TComputationValue<TCodegenValue> {
public:
- using TNextPtr = TCodegenIterator::TNextPtr;
-
- TCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& dict)
- : TComputationValue<TCodegenValue>(memInfo)
+ using TNextPtr = TCodegenIterator::TNextPtr;
+
+ TCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& dict)
+ : TComputationValue<TCodegenValue>(memInfo)
, NextFunc(next)
- , Ctx(ctx)
- , Dict(std::move(dict))
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return Ctx->HolderFactory.Create<TCodegenIterator>(NextFunc, Ctx, Dict.GetDictIterator());
- }
-
- ui64 GetListLength() const final {
- return Dict.GetDictLength();
- }
-
- bool HasListItems() const final {
- return Dict.HasDictItems();
- }
-
- bool HasFastListLength() const final {
- return true;
- }
-
- const TNextPtr NextFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Dict;
- };
+ , Ctx(ctx)
+ , Dict(std::move(dict))
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return Ctx->HolderFactory.Create<TCodegenIterator>(NextFunc, Ctx, Dict.GetDictIterator());
+ }
+
+ ui64 GetListLength() const final {
+ return Dict.GetDictLength();
+ }
+
+ bool HasListItems() const final {
+ return Dict.HasDictItems();
+ }
+
+ bool HasFastListLength() const final {
+ return true;
+ }
+
+ const TNextPtr NextFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Dict;
+ };
#endif
-
- class TValue : public TComputationValue<TValue> {
- public:
- class TIterator : public TComputationValue<TIterator> {
+
+ class TValue : public TComputationValue<TValue> {
+ public:
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& inner,
+ TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& inner,
TComputationContext& compCtx, const TSelf* self)
- : TComputationValue<TIterator>(memInfo)
- , Inner(std::move(inner))
+ : TComputationValue<TIterator>(memInfo)
+ , Inner(std::move(inner))
, CompCtx(compCtx)
, Self(self)
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- NUdf::TUnboxedValue key, payload;
- if (!Inner.NextPair(key, payload))
- return false;
-
- NUdf::TUnboxedValue* items = nullptr;
- value = Self->ResPair.NewArray(CompCtx, 2, items);
- items[0] = std::move(key);
- items[1] = std::move(payload);
- return true;
- }
-
- bool Skip() override {
- return Inner.Skip();
- }
-
- const NUdf::TUnboxedValue Inner;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ NUdf::TUnboxedValue key, payload;
+ if (!Inner.NextPair(key, payload))
+ return false;
+
+ NUdf::TUnboxedValue* items = nullptr;
+ value = Self->ResPair.NewArray(CompCtx, 2, items);
+ items[0] = std::move(key);
+ items[1] = std::move(payload);
+ return true;
+ }
+
+ bool Skip() override {
+ return Inner.Skip();
+ }
+
+ const NUdf::TUnboxedValue Inner;
TComputationContext& CompCtx;
- const TSelf* const Self;
+ const TSelf* const Self;
};
TValue(
TMemoryUsageInfo* memInfo,
const NUdf::TUnboxedValue&& dict,
TComputationContext& compCtx, const TSelf* self)
- : TComputationValue<TValue>(memInfo)
+ : TComputationValue<TValue>(memInfo)
, Dict(std::move(dict))
, CompCtx(compCtx)
, Self(self)
{
}
- private:
- ui64 GetListLength() const final {
- return Dict.GetDictLength();
- }
+ private:
+ ui64 GetListLength() const final {
+ return Dict.GetDictLength();
+ }
- bool HasListItems() const final {
- return Dict.HasDictItems();
+ bool HasListItems() const final {
+ return Dict.HasDictItems();
}
- bool HasFastListLength() const final {
- return true;
+ bool HasFastListLength() const final {
+ return true;
}
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(Dict.GetDictIterator(), CompCtx, Self);
- }
-
- const NUdf::TUnboxedValue Dict;
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(Dict.GetDictIterator(), CompCtx, Self);
+ }
+
+ const NUdf::TUnboxedValue Dict;
TComputationContext& CompCtx;
- const TSelf* const Self;
+ const TSelf* const Self;
};
TDictItemsWrapper(TComputationMutables& mutables, IComputationNode* dict)
: TBaseComputation(mutables)
, Dict(dict)
, ResPair(mutables)
- {}
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Next)
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Next)
return ctx.HolderFactory.Create<TCodegenValue>(Next, &ctx, Dict->GetValue(ctx));
-#endif
+#endif
return ctx.HolderFactory.Create<TValue>(Dict->GetValue(ctx), ctx, this);
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Dict);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Dict);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- NextFunc = GenerateNext(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ NextFunc = GenerateNext(codegen);
codegen->ExportSymbol(NextFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (NextFunc)
- Next = reinterpret_cast<TNextPtr>(codegen->GetPointerToFunction(NextFunc));
- }
-
- Function* GenerateNext(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Next");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt32Ty(context);
- const auto pairType = ArrayType::get(valueType, 2U);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (NextFunc)
+ Next = reinterpret_cast<TNextPtr>(codegen->GetPointerToFunction(NextFunc));
+ }
+
+ Function* GenerateNext(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Next");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+ const auto pairType = ArrayType::get(valueType, 2U);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto pairPtr = new AllocaInst(pairType, 0U, "pair_ptr", block);
- new StoreInst(ConstantAggregateZero::get(pairType), pairPtr, block);
-
- const auto keyPtr = GetElementPtrInst::CreateInBounds(pairPtr, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "key_ptr", block);
- const auto payPtr = GetElementPtrInst::CreateInBounds(pairPtr, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "pay_ptr", block);
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::NextPair>(statusType, container, codegen, block, keyPtr, payPtr);
-
- BranchInst::Create(good, done, status, block);
- block = good;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
-
- const auto itemsPtr = new AllocaInst(PointerType::getUnqual(pairType), 0U, "items_ptr", block);
- const auto output = ResPair.GenNewArray(2U, itemsPtr, ctx, block);
- AddRefBoxed(output, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto pair = new LoadInst(pairPtr, "pair", block);
- new StoreInst(pair, items, block);
- new StoreInst(output, valuePtr, block);
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TNextPtr = typename TCodegenIterator::TNextPtr;
-
- Function* NextFunc = nullptr;
-
- TNextPtr Next = nullptr;
-#endif
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto pairPtr = new AllocaInst(pairType, 0U, "pair_ptr", block);
+ new StoreInst(ConstantAggregateZero::get(pairType), pairPtr, block);
+
+ const auto keyPtr = GetElementPtrInst::CreateInBounds(pairPtr, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "key_ptr", block);
+ const auto payPtr = GetElementPtrInst::CreateInBounds(pairPtr, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "pay_ptr", block);
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::NextPair>(statusType, container, codegen, block, keyPtr, payPtr);
+
+ BranchInst::Create(good, done, status, block);
+ block = good;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+
+ const auto itemsPtr = new AllocaInst(PointerType::getUnqual(pairType), 0U, "items_ptr", block);
+ const auto output = ResPair.GenNewArray(2U, itemsPtr, ctx, block);
+ AddRefBoxed(output, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto pair = new LoadInst(pairPtr, "pair", block);
+ new StoreInst(pair, items, block);
+ new StoreInst(output, valuePtr, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TNextPtr = typename TCodegenIterator::TNextPtr;
+
+ Function* NextFunc = nullptr;
+
+ TNextPtr Next = nullptr;
+#endif
+
IComputationNode* const Dict;
- const TContainerCacheOnContext ResPair;
+ const TContainerCacheOnContext ResPair;
};
-template <bool KeysOrPayloads>
-class TDictHalfsWrapper : public TMutableComputationNode<TDictHalfsWrapper<KeysOrPayloads>> {
- typedef TMutableComputationNode<TDictHalfsWrapper<KeysOrPayloads>> TBaseComputation;
-public:
- using TSelf = TDictHalfsWrapper<KeysOrPayloads>;
-
- class TValue : public TComputationValue<TValue> {
- public:
- TValue(
- TMemoryUsageInfo* memInfo,
- const NUdf::TUnboxedValue&& dict,
+template <bool KeysOrPayloads>
+class TDictHalfsWrapper : public TMutableComputationNode<TDictHalfsWrapper<KeysOrPayloads>> {
+ typedef TMutableComputationNode<TDictHalfsWrapper<KeysOrPayloads>> TBaseComputation;
+public:
+ using TSelf = TDictHalfsWrapper<KeysOrPayloads>;
+
+ class TValue : public TComputationValue<TValue> {
+ public:
+ TValue(
+ TMemoryUsageInfo* memInfo,
+ const NUdf::TUnboxedValue&& dict,
TComputationContext&, const TSelf*)
- : TComputationValue<TValue>(memInfo)
- , Dict(std::move(dict))
- {}
-
- private:
- ui64 GetListLength() const final {
- return Dict.GetDictLength();
- }
-
- bool HasListItems() const final {
- return Dict.HasDictItems();
- }
-
- bool HasFastListLength() const final {
- return true;
- }
-
- NUdf::TUnboxedValue GetListIterator() const final {
- return KeysOrPayloads ? Dict.GetKeysIterator() : Dict.GetPayloadsIterator();
- }
-
- const NUdf::TUnboxedValue Dict;
- };
-
- TDictHalfsWrapper(TComputationMutables& mutables, IComputationNode* dict)
- : TBaseComputation(mutables), Dict(dict)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TValue>(Dict->GetValue(ctx), ctx, this);
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Dict);
- }
-
- IComputationNode* const Dict;
-};
-
-}
-
+ : TComputationValue<TValue>(memInfo)
+ , Dict(std::move(dict))
+ {}
+
+ private:
+ ui64 GetListLength() const final {
+ return Dict.GetDictLength();
+ }
+
+ bool HasListItems() const final {
+ return Dict.HasDictItems();
+ }
+
+ bool HasFastListLength() const final {
+ return true;
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return KeysOrPayloads ? Dict.GetKeysIterator() : Dict.GetPayloadsIterator();
+ }
+
+ const NUdf::TUnboxedValue Dict;
+ };
+
+ TDictHalfsWrapper(TComputationMutables& mutables, IComputationNode* dict)
+ : TBaseComputation(mutables), Dict(dict)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TValue>(Dict->GetValue(ctx), ctx, this);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Dict);
+ }
+
+ IComputationNode* const Dict;
+};
+
+}
+
IComputationNode* WrapDictItems(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1 || callable.GetInputsCount() == 2, "Expected one or two args");
- const auto node = LocateNode(ctx.NodeLocator, callable, 0);
-
- if (1U == callable.GetInputsCount()) {
- return new TDictItemsWrapper(ctx.Mutables, node);
- }
-
- const auto mode = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
- switch (static_cast<EDictItems>(mode)) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1 || callable.GetInputsCount() == 2, "Expected one or two args");
+ const auto node = LocateNode(ctx.NodeLocator, callable, 0);
+
+ if (1U == callable.GetInputsCount()) {
+ return new TDictItemsWrapper(ctx.Mutables, node);
+ }
+
+ const auto mode = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
+ switch (static_cast<EDictItems>(mode)) {
case EDictItems::Both:
return new TDictItemsWrapper(ctx.Mutables, node);
case EDictItems::Keys:
@@ -294,17 +294,17 @@ IComputationNode* WrapDictItems(TCallable& callable, const TComputationNodeFacto
}
}
-IComputationNode* WrapDictKeys(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected one arg");
- const auto node = LocateNode(ctx.NodeLocator, callable, 0);
- return new TDictHalfsWrapper<true>(ctx.Mutables, node);
+IComputationNode* WrapDictKeys(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected one arg");
+ const auto node = LocateNode(ctx.NodeLocator, callable, 0);
+ return new TDictHalfsWrapper<true>(ctx.Mutables, node);
+}
+
+IComputationNode* WrapDictPayloads(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected one arg");
+ const auto node = LocateNode(ctx.NodeLocator, callable, 0);
+ return new TDictHalfsWrapper<false>(ctx.Mutables, node);
+}
+
}
-
-IComputationNode* WrapDictPayloads(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected one arg");
- const auto node = LocateNode(ctx.NodeLocator, callable, 0);
- return new TDictHalfsWrapper<false>(ctx.Mutables, node);
}
-
-}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.h b/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.h
index 53231e8dc9..d9677266fe 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_dictitems.h
@@ -5,8 +5,8 @@ namespace NKikimr {
namespace NMiniKQL {
IComputationNode* WrapDictItems(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapDictKeys(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapDictPayloads(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapDictKeys(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapDictPayloads(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_discard.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_discard.cpp
index 6b27e50fe5..88a92bcd4e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_discard.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_discard.cpp
@@ -1,5 +1,5 @@
#include "mkql_discard.h"
-
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
@@ -7,104 +7,104 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TDiscardFlowWrapper : public TStatelessFlowCodegeneratorRootNode<TDiscardFlowWrapper> {
- typedef TStatelessFlowCodegeneratorRootNode<TDiscardFlowWrapper> TBaseComputation;
-public:
- TDiscardFlowWrapper(IComputationNode* flow)
- : TBaseComputation(flow, EValueRepresentation::Embedded), Flow(flow)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- while (true) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial())
- return item.Release();
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- BranchInst::Create(loop, block);
-
- block = loop;
- const auto item = GetNodeValue(Flow, ctx, block);
- BranchInst::Create(exit, skip, IsSpecial(item, block), block);
-
- block = skip;
- ValueCleanup(Flow->GetRepresentation(), item, ctx, block);
- BranchInst::Create(loop, block);
-
- block = exit;
- return item;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- FlowDependsOn(Flow);
- }
-
- IComputationNode* const Flow;
-};
-
-class TDiscardWideFlowWrapper : public TStatelessFlowCodegeneratorRootNode<TDiscardWideFlowWrapper> {
-using TBaseComputation = TStatelessFlowCodegeneratorRootNode<TDiscardWideFlowWrapper>;
-public:
- TDiscardWideFlowWrapper(IComputationWideFlowNode* flow, ui32 size)
- : TBaseComputation(flow, EValueRepresentation::Embedded), Flow(flow), Stub(size, nullptr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- while (true) {
- switch (Flow->FetchValues(ctx, Stub.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- default:
- continue;
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto result = GetNodeValues(Flow, ctx, block).first;
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, result, ConstantInt::get(result->getType(), 0), "good", block);
- BranchInst::Create(loop, exit, good, block);
-
- block = exit;
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, result, ConstantInt::get(result->getType(), 0), "yield", block);
- const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
- return outres;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- FlowDependsOn(Flow);
- }
-
- IComputationWideFlowNode* const Flow;
- mutable std::vector<NUdf::TUnboxedValue*> Stub;
-};
-
-class TDiscardWrapper : public TCustomValueCodegeneratorNode<TDiscardWrapper> {
- typedef TCustomValueCodegeneratorNode<TDiscardWrapper> TBaseComputation;
+namespace {
+
+class TDiscardFlowWrapper : public TStatelessFlowCodegeneratorRootNode<TDiscardFlowWrapper> {
+ typedef TStatelessFlowCodegeneratorRootNode<TDiscardFlowWrapper> TBaseComputation;
+public:
+ TDiscardFlowWrapper(IComputationNode* flow)
+ : TBaseComputation(flow, EValueRepresentation::Embedded), Flow(flow)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ while (true) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial())
+ return item.Release();
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ BranchInst::Create(exit, skip, IsSpecial(item, block), block);
+
+ block = skip;
+ ValueCleanup(Flow->GetRepresentation(), item, ctx, block);
+ BranchInst::Create(loop, block);
+
+ block = exit;
+ return item;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ FlowDependsOn(Flow);
+ }
+
+ IComputationNode* const Flow;
+};
+
+class TDiscardWideFlowWrapper : public TStatelessFlowCodegeneratorRootNode<TDiscardWideFlowWrapper> {
+using TBaseComputation = TStatelessFlowCodegeneratorRootNode<TDiscardWideFlowWrapper>;
+public:
+ TDiscardWideFlowWrapper(IComputationWideFlowNode* flow, ui32 size)
+ : TBaseComputation(flow, EValueRepresentation::Embedded), Flow(flow), Stub(size, nullptr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ while (true) {
+ switch (Flow->FetchValues(ctx, Stub.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ default:
+ continue;
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto result = GetNodeValues(Flow, ctx, block).first;
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, result, ConstantInt::get(result->getType(), 0), "good", block);
+ BranchInst::Create(loop, exit, good, block);
+
+ block = exit;
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, result, ConstantInt::get(result->getType(), 0), "yield", block);
+ const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
+ return outres;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ FlowDependsOn(Flow);
+ }
+
+ IComputationWideFlowNode* const Flow;
+ mutable std::vector<NUdf::TUnboxedValue*> Stub;
+};
+
+class TDiscardWrapper : public TCustomValueCodegeneratorNode<TDiscardWrapper> {
+ typedef TCustomValueCodegeneratorNode<TDiscardWrapper> TBaseComputation;
public:
class TValue : public TComputationValue<TValue> {
public:
@@ -114,9 +114,9 @@ public:
{
}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue&) override {
- for (NUdf::TUnboxedValue item;;) {
- const auto status = Stream.Fetch(item);
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue&) override {
+ for (NUdf::TUnboxedValue item;;) {
+ const auto status = Stream.Fetch(item);
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -124,7 +124,7 @@ public:
}
private:
- const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Stream;
};
TDiscardWrapper(TComputationMutables& mutables, IComputationNode* stream)
@@ -134,10 +134,10 @@ public:
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Fetch)
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Fetch)
return ctx.HolderFactory.Create<TStreamCodegenValueStateless>(Fetch, &ctx, Stream->GetValue(ctx));
-#endif
+#endif
return ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx));
}
@@ -146,95 +146,95 @@ private:
DependsOn(Stream);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FetchFunc = GenerateFetch(codegen);
- codegen->ExportSymbol(FetchFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FetchFunc)
- Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
- }
-
- Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FetchFunc = GenerateFetch(codegen);
+ codegen->ExportSymbol(FetchFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FetchFunc)
+ Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
+ }
+
+ Function* GenerateFetch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
-
- const auto stub = new AllocaInst(valueType, 0U, "stub", block);
- new StoreInst(ConstantInt::get(valueType, 0), stub, block);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, stub);
-
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- BranchInst::Create(done, loop, icmp, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+
+ const auto stub = new AllocaInst(valueType, 0U, "stub", block);
+ new StoreInst(ConstantInt::get(valueType, 0), stub, block);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, stub);
+
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ BranchInst::Create(done, loop, icmp, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
using TFetchPtr = TStreamCodegenValueStateless::TFetchPtr;
-
- Function* FetchFunc = nullptr;
-
- TFetchPtr Fetch = nullptr;
-#endif
-
+
+ Function* FetchFunc = nullptr;
+
+ TFetchPtr Fetch = nullptr;
+#endif
+
IComputationNode* const Stream;
};
-}
-
+}
+
IComputationNode* WrapDiscard(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- const auto type = callable.GetType()->GetReturnType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- if (type->IsFlow()) {
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
- if (const auto itemType = AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType(); itemType->IsTuple())
- return new TDiscardWideFlowWrapper(wide, AS_TYPE(TTupleType, itemType)->GetElementsCount());
- else
- return new TDiscardWideFlowWrapper(wide, 0U);
- else
- return new TDiscardFlowWrapper(flow);
- } else if (type->IsStream()) {
- return new TDiscardWrapper(ctx.Mutables, flow);
- }
-
- THROW yexception() << "Expected flow or stream.";
+ const auto type = callable.GetType()->GetReturnType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ if (type->IsFlow()) {
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
+ if (const auto itemType = AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType(); itemType->IsTuple())
+ return new TDiscardWideFlowWrapper(wide, AS_TYPE(TTupleType, itemType)->GetElementsCount());
+ else
+ return new TDiscardWideFlowWrapper(wide, 0U);
+ else
+ return new TDiscardFlowWrapper(flow);
+ } else if (type->IsStream()) {
+ return new TDiscardWrapper(ctx.Mutables, flow);
+ }
+
+ THROW yexception() << "Expected flow or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_element.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_element.cpp
index 61dc4635f5..c91edcb8be 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_element.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_element.cpp
@@ -1,239 +1,239 @@
-#include "mkql_element.h"
+#include "mkql_element.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <bool IsOptional>
-class TElementsWrapper : public TMutableCodegeneratorNode<TElementsWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TElementsWrapper<IsOptional>> TBaseComputation;
-public:
- TElementsWrapper(TComputationMutables& mutables, IComputationNode* array)
- : TBaseComputation(mutables, EValueRepresentation::Embedded), Array(array)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& array = Array->GetValue(compCtx);
- if constexpr (IsOptional) {
- return array ? NUdf::TUnboxedValuePod(reinterpret_cast<ui64>(array.GetElements())) : NUdf::TUnboxedValuePod();
- } else {
- return NUdf::TUnboxedValuePod(reinterpret_cast<ui64>(array.GetElements()));
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto array = GetNodeValue(Array, ctx, block);
- const auto elementsType = PointerType::getUnqual(array->getType());
-
- if constexpr (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(array->getType(), 2U, "result", done);
- result->addIncoming(ConstantInt::get(array->getType(), 0ULL), block);
- BranchInst::Create(done, good, IsEmpty(array, block), block);
-
- block = good;
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, array, ctx.Codegen, block);
- const auto cast = CastInst::Create(Instruction::PtrToInt, elements, Type::getInt64Ty(context), "cast", block);
- const auto wide = SetterFor<ui64>(cast, context, block);
- result->addIncoming(wide, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, array, ctx.Codegen, block);
- const auto cast = CastInst::Create(Instruction::PtrToInt, elements, Type::getInt64Ty(context), "cast", block);
- return SetterFor<ui64>(cast, context, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Array);
- }
-
- IComputationNode* const Array;
-};
-
-template <bool IsOptional>
-class TElementWrapper : public TMutableCodegeneratorPtrNode<TElementWrapper<IsOptional>> {
- typedef TMutableCodegeneratorPtrNode<TElementWrapper<IsOptional>> TBaseComputation;
-public:
- TElementWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* cache, IComputationNode* array, ui32 index)
- : TBaseComputation(mutables, kind), Cache(cache), Array(array), Index(index)
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- if (Cache->GetDependencesCount() > 1U) {
- const auto cache = Cache->GetValue(ctx);
- if (IsOptional && !cache) {
- return NUdf::TUnboxedValue();
- }
- if (const auto elements = cache.Get<ui64>()) {
- return reinterpret_cast<const NUdf::TUnboxedValuePod*>(elements)[Index];
- }
- }
-
- const auto& array = Array->GetValue(ctx);
- if constexpr (IsOptional) {
- return array ? array.GetElement(Index) : NUdf::TUnboxedValue();
- } else {
- return array.GetElement(Index);
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetElement(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto array = GetNodeValue(Array, ctx, block);
- const auto index = ConstantInt::get(Type::getInt32Ty(context), Index);
- if constexpr (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- BranchInst::Create(zero, good, IsEmpty(array, block), block);
-
- block = zero;
- new StoreInst(ConstantInt::get(array->getType(), 0ULL), pointer, block);
- BranchInst::Create(exit, block);
-
- block = good;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(pointer, array, ctx.Codegen, block, index);
- if (Array->IsTemporaryValue())
- CleanupBoxed(array, ctx, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- } else {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(pointer, array, ctx.Codegen, block, index);
- if (Array->IsTemporaryValue())
- CleanupBoxed(array, ctx, block);
- }
- }
-
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- if (Cache->GetDependencesCount() <= 1U) {
- return DoGenerateGetElement(ctx, pointer, block);
- }
-
- auto& context = ctx.Codegen->GetContext();
- const auto cache = GetNodeValue(Cache, ctx, block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- if (IsOptional) {
- const auto zero = ConstantInt::get(cache->getType(), 0ULL);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cache, zero, "check", block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
-
- BranchInst::Create(none, good, check, block);
-
- block = none;
- new StoreInst(zero, pointer, block);
- BranchInst::Create(done, block);
-
- block = good;
- }
-
- const auto trunc = CastInst::Create(Instruction::Trunc, cache, Type::getInt64Ty(context), "trunc", block);
- const auto type = PointerType::getUnqual(cache->getType());
- const auto elements = CastInst::Create(Instruction::IntToPtr, trunc, type, "elements", block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(type), "fill", block);
- BranchInst::Create(fast, slow, fill, block);
-
- block = fast;
- const auto index = ConstantInt::get(Type::getInt32Ty(context), this->Index);
- const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
- const auto item = new LoadInst(ptr, "item", block);
- ValueAddRef(this->GetRepresentation(), item, ctx, block);
- new StoreInst(item, pointer, block);
- BranchInst::Create(done, block);
-
- block = slow;
- DoGenerateGetElement(ctx, pointer, block);
- BranchInst::Create(done, block);
-
- block = done;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Array);
- this->DependsOn(Cache);
- }
-
- IComputationNode *const Cache;
- IComputationNode *const Array;
- const ui32 Index;
-};
-
-IComputationNode* WrapElements(IComputationNode* array, const TComputationNodeFactoryContext& ctx, bool isOptional) {
- if (isOptional) {
- return new TElementsWrapper<true>(ctx.Mutables, array);
- } else {
- return new TElementsWrapper<false>(ctx.Mutables, array);
- }
-}
-
-}
-
-IComputationNode* WrapNth(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2U, "Expected two args.");
- const auto input = callable.GetInput(0U);
- bool isOptional;
- const auto tupleType = AS_TYPE(TTupleType, UnpackOptional(input.GetStaticType(), isOptional));
- const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1U));
- const auto index = indexData->AsValue().Get<ui32>();
- MKQL_ENSURE(index < tupleType->GetElementsCount(), "Bad tuple index");
-
- const auto tuple = LocateNode(ctx.NodeLocator, callable, 0);
- const auto ins = ctx.ElementsCache.emplace(tuple, nullptr);
- if (ins.second) {
- ctx.NodePushBack(ins.first->second = WrapElements(tuple, ctx, isOptional));
- }
-
- if (isOptional) {
- return new TElementWrapper<true>(ctx.Mutables, GetValueRepresentation(tupleType->GetElementType(index)), ins.first->second, tuple, index);
- } else {
- return new TElementWrapper<false>(ctx.Mutables, GetValueRepresentation(tupleType->GetElementType(index)), ins.first->second, tuple, index);
- }
-}
-
-IComputationNode* WrapMember(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2U, "Expected two args.");
- const auto input = callable.GetInput(0U);
- bool isOptional;
- const auto structType = AS_TYPE(TStructType, UnpackOptional(input.GetStaticType(), isOptional));
- const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1U));
- const auto index = indexData->AsValue().Get<ui32>();
- MKQL_ENSURE(index < structType->GetMembersCount(), "Bad member index");
-
- const auto structObj = LocateNode(ctx.NodeLocator, callable, 0U);
- const auto ins = ctx.ElementsCache.emplace(structObj, nullptr);
- if (ins.second) {
- ctx.NodePushBack(ins.first->second = WrapElements(structObj, ctx, isOptional));
- }
- if (isOptional) {
- return new TElementWrapper<true>(ctx.Mutables, GetValueRepresentation(structType->GetMemberType(index)), ins.first->second, structObj, index);
- } else {
- return new TElementWrapper<false>(ctx.Mutables, GetValueRepresentation(structType->GetMemberType(index)), ins.first->second, structObj, index);
- }
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <bool IsOptional>
+class TElementsWrapper : public TMutableCodegeneratorNode<TElementsWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TElementsWrapper<IsOptional>> TBaseComputation;
+public:
+ TElementsWrapper(TComputationMutables& mutables, IComputationNode* array)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded), Array(array)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const auto& array = Array->GetValue(compCtx);
+ if constexpr (IsOptional) {
+ return array ? NUdf::TUnboxedValuePod(reinterpret_cast<ui64>(array.GetElements())) : NUdf::TUnboxedValuePod();
+ } else {
+ return NUdf::TUnboxedValuePod(reinterpret_cast<ui64>(array.GetElements()));
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto array = GetNodeValue(Array, ctx, block);
+ const auto elementsType = PointerType::getUnqual(array->getType());
+
+ if constexpr (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(array->getType(), 2U, "result", done);
+ result->addIncoming(ConstantInt::get(array->getType(), 0ULL), block);
+ BranchInst::Create(done, good, IsEmpty(array, block), block);
+
+ block = good;
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, array, ctx.Codegen, block);
+ const auto cast = CastInst::Create(Instruction::PtrToInt, elements, Type::getInt64Ty(context), "cast", block);
+ const auto wide = SetterFor<ui64>(cast, context, block);
+ result->addIncoming(wide, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, array, ctx.Codegen, block);
+ const auto cast = CastInst::Create(Instruction::PtrToInt, elements, Type::getInt64Ty(context), "cast", block);
+ return SetterFor<ui64>(cast, context, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Array);
+ }
+
+ IComputationNode* const Array;
+};
+
+template <bool IsOptional>
+class TElementWrapper : public TMutableCodegeneratorPtrNode<TElementWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorPtrNode<TElementWrapper<IsOptional>> TBaseComputation;
+public:
+ TElementWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* cache, IComputationNode* array, ui32 index)
+ : TBaseComputation(mutables, kind), Cache(cache), Array(array), Index(index)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ if (Cache->GetDependencesCount() > 1U) {
+ const auto cache = Cache->GetValue(ctx);
+ if (IsOptional && !cache) {
+ return NUdf::TUnboxedValue();
+ }
+ if (const auto elements = cache.Get<ui64>()) {
+ return reinterpret_cast<const NUdf::TUnboxedValuePod*>(elements)[Index];
+ }
+ }
+
+ const auto& array = Array->GetValue(ctx);
+ if constexpr (IsOptional) {
+ return array ? array.GetElement(Index) : NUdf::TUnboxedValue();
+ } else {
+ return array.GetElement(Index);
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetElement(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto array = GetNodeValue(Array, ctx, block);
+ const auto index = ConstantInt::get(Type::getInt32Ty(context), Index);
+ if constexpr (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ BranchInst::Create(zero, good, IsEmpty(array, block), block);
+
+ block = zero;
+ new StoreInst(ConstantInt::get(array->getType(), 0ULL), pointer, block);
+ BranchInst::Create(exit, block);
+
+ block = good;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(pointer, array, ctx.Codegen, block, index);
+ if (Array->IsTemporaryValue())
+ CleanupBoxed(array, ctx, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ } else {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(pointer, array, ctx.Codegen, block, index);
+ if (Array->IsTemporaryValue())
+ CleanupBoxed(array, ctx, block);
+ }
+ }
+
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ if (Cache->GetDependencesCount() <= 1U) {
+ return DoGenerateGetElement(ctx, pointer, block);
+ }
+
+ auto& context = ctx.Codegen->GetContext();
+ const auto cache = GetNodeValue(Cache, ctx, block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ if (IsOptional) {
+ const auto zero = ConstantInt::get(cache->getType(), 0ULL);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, cache, zero, "check", block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+
+ BranchInst::Create(none, good, check, block);
+
+ block = none;
+ new StoreInst(zero, pointer, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+ }
+
+ const auto trunc = CastInst::Create(Instruction::Trunc, cache, Type::getInt64Ty(context), "trunc", block);
+ const auto type = PointerType::getUnqual(cache->getType());
+ const auto elements = CastInst::Create(Instruction::IntToPtr, trunc, type, "elements", block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(type), "fill", block);
+ BranchInst::Create(fast, slow, fill, block);
+
+ block = fast;
+ const auto index = ConstantInt::get(Type::getInt32Ty(context), this->Index);
+ const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
+ const auto item = new LoadInst(ptr, "item", block);
+ ValueAddRef(this->GetRepresentation(), item, ctx, block);
+ new StoreInst(item, pointer, block);
+ BranchInst::Create(done, block);
+
+ block = slow;
+ DoGenerateGetElement(ctx, pointer, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Array);
+ this->DependsOn(Cache);
+ }
+
+ IComputationNode *const Cache;
+ IComputationNode *const Array;
+ const ui32 Index;
+};
+
+IComputationNode* WrapElements(IComputationNode* array, const TComputationNodeFactoryContext& ctx, bool isOptional) {
+ if (isOptional) {
+ return new TElementsWrapper<true>(ctx.Mutables, array);
+ } else {
+ return new TElementsWrapper<false>(ctx.Mutables, array);
+ }
+}
+
+}
+
+IComputationNode* WrapNth(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2U, "Expected two args.");
+ const auto input = callable.GetInput(0U);
+ bool isOptional;
+ const auto tupleType = AS_TYPE(TTupleType, UnpackOptional(input.GetStaticType(), isOptional));
+ const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1U));
+ const auto index = indexData->AsValue().Get<ui32>();
+ MKQL_ENSURE(index < tupleType->GetElementsCount(), "Bad tuple index");
+
+ const auto tuple = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto ins = ctx.ElementsCache.emplace(tuple, nullptr);
+ if (ins.second) {
+ ctx.NodePushBack(ins.first->second = WrapElements(tuple, ctx, isOptional));
+ }
+
+ if (isOptional) {
+ return new TElementWrapper<true>(ctx.Mutables, GetValueRepresentation(tupleType->GetElementType(index)), ins.first->second, tuple, index);
+ } else {
+ return new TElementWrapper<false>(ctx.Mutables, GetValueRepresentation(tupleType->GetElementType(index)), ins.first->second, tuple, index);
+ }
+}
+
+IComputationNode* WrapMember(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2U, "Expected two args.");
+ const auto input = callable.GetInput(0U);
+ bool isOptional;
+ const auto structType = AS_TYPE(TStructType, UnpackOptional(input.GetStaticType(), isOptional));
+ const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1U));
+ const auto index = indexData->AsValue().Get<ui32>();
+ MKQL_ENSURE(index < structType->GetMembersCount(), "Bad member index");
+
+ const auto structObj = LocateNode(ctx.NodeLocator, callable, 0U);
+ const auto ins = ctx.ElementsCache.emplace(structObj, nullptr);
+ if (ins.second) {
+ ctx.NodePushBack(ins.first->second = WrapElements(structObj, ctx, isOptional));
+ }
+ if (isOptional) {
+ return new TElementWrapper<true>(ctx.Mutables, GetValueRepresentation(structType->GetMemberType(index)), ins.first->second, structObj, index);
+ } else {
+ return new TElementWrapper<false>(ctx.Mutables, GetValueRepresentation(structType->GetMemberType(index)), ins.first->second, structObj, index);
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_element.h b/ydb/library/yql/minikql/comp_nodes/mkql_element.h
index d8d7f66d82..1233eb829f 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_element.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_element.h
@@ -1,11 +1,11 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapNth(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapMember(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapNth(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapMember(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_ensure.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_ensure.cpp
index b732b90fff..85c8371ec6 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_ensure.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_ensure.cpp
@@ -8,15 +8,15 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TEnsureWrapper : public TMutableCodegeneratorNode<TEnsureWrapper> {
- typedef TMutableCodegeneratorNode<TEnsureWrapper> TBaseComputation;
+namespace {
+
+class TEnsureWrapper : public TMutableCodegeneratorNode<TEnsureWrapper> {
+ typedef TMutableCodegeneratorNode<TEnsureWrapper> TBaseComputation;
public:
TEnsureWrapper(TComputationMutables& mutables, IComputationNode* value, IComputationNode* predicate,
IComputationNode* message, const NUdf::TSourcePosition& pos)
- : TBaseComputation(mutables, value->GetRepresentation())
- , Arg(value)
+ : TBaseComputation(mutables, value->GetRepresentation())
+ , Arg(value)
, Predicate(predicate)
, Message(message)
, Pos(pos)
@@ -26,40 +26,40 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& predicate = Predicate->GetValue(ctx);
if (predicate && predicate.Get<bool>()) {
- return Arg->GetValue(ctx).Release();
+ return Arg->GetValue(ctx).Release();
}
- Throw(this, &ctx);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto predicate = GetNodeValue(Predicate, ctx, block);
- const auto pass = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- BranchInst::Create(good, kill, pass, block);
-
- block = kill;
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TEnsureWrapper::Throw));
- const auto doFuncArg = ConstantInt::get(Type::getInt64Ty(context), (ui64)this);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), { Type::getInt64Ty(context), ctx.Ctx->getType() }, false)), "thrower", block);
- CallInst::Create(doFuncPtr, { doFuncArg, ctx.Ctx }, "", block)->setTailCall();
- new UnreachableInst(context, block);
-
- block = good;
- return GetNodeValue(Arg, ctx, block);;
- }
-#endif
-
-private:
+ Throw(this, &ctx);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+ const auto pass = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ BranchInst::Create(good, kill, pass, block);
+
+ block = kill;
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TEnsureWrapper::Throw));
+ const auto doFuncArg = ConstantInt::get(Type::getInt64Ty(context), (ui64)this);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), { Type::getInt64Ty(context), ctx.Ctx->getType() }, false)), "thrower", block);
+ CallInst::Create(doFuncPtr, { doFuncArg, ctx.Ctx }, "", block)->setTailCall();
+ new UnreachableInst(context, block);
+
+ block = good;
+ return GetNodeValue(Arg, ctx, block);;
+ }
+#endif
+
+private:
[[noreturn]] static void Throw(TEnsureWrapper const* thisPtr, TComputationContext* ctxPtr) {
- auto message = thisPtr->Message->GetValue(*ctxPtr);
+ auto message = thisPtr->Message->GetValue(*ctxPtr);
auto messageStr = message.AsStringRef();
TStringBuilder res;
res << thisPtr->Pos << " Condition violated";
@@ -71,18 +71,18 @@ private:
}
void RegisterDependencies() const final {
- DependsOn(Arg);
+ DependsOn(Arg);
DependsOn(Predicate);
}
- IComputationNode* const Arg;
+ IComputationNode* const Arg;
IComputationNode* const Predicate;
IComputationNode* const Message;
const NUdf::TSourcePosition Pos;
};
-}
-
+}
+
IComputationNode* WrapEnsure(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
bool isOptional;
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_enumerate.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_enumerate.cpp
index 1e8d938eb3..727aae0d0b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_enumerate.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_enumerate.cpp
@@ -7,24 +7,24 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TEnumerateWrapper : public TMutableCodegeneratorNode<TEnumerateWrapper> {
- typedef TMutableCodegeneratorNode<TEnumerateWrapper> TBaseComputation;
+namespace {
+
+class TEnumerateWrapper : public TMutableCodegeneratorNode<TEnumerateWrapper> {
+ typedef TMutableCodegeneratorNode<TEnumerateWrapper> TBaseComputation;
public:
using TSelf = TEnumerateWrapper;
class TValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
TIterator(
- TMemoryUsageInfo* memInfo,
- NUdf::TUnboxedValue&& inner,
+ TMemoryUsageInfo* memInfo,
+ NUdf::TUnboxedValue&& inner,
ui64 start, ui64 step,
TComputationContext& ctx, const TSelf* self)
- : TComputationValue(memInfo)
- , Inner(std::move(inner))
+ : TComputationValue(memInfo)
+ , Inner(std::move(inner))
, Step(step)
, Counter(start - step)
, Ctx(ctx)
@@ -32,35 +32,35 @@ public:
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- NUdf::TUnboxedValue item;
- if (Inner.Next(item)) {
- Counter += Step;
- NUdf::TUnboxedValue* items = nullptr;
- value = Self->ResPair.NewArray(Ctx, 2, items);
- items[0] = NUdf::TUnboxedValuePod(Counter);
- items[1] = std::move(item);
- return true;
- }
-
- return false;
- }
-
- bool Skip() override {
- if (Inner.Skip()) {
- Counter += Step;
- return true;
- }
-
- return false;
- }
-
- const NUdf::TUnboxedValue Inner;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ NUdf::TUnboxedValue item;
+ if (Inner.Next(item)) {
+ Counter += Step;
+ NUdf::TUnboxedValue* items = nullptr;
+ value = Self->ResPair.NewArray(Ctx, 2, items);
+ items[0] = NUdf::TUnboxedValuePod(Counter);
+ items[1] = std::move(item);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Skip() override {
+ if (Inner.Skip()) {
+ Counter += Step;
+ return true;
+ }
+
+ return false;
+ }
+
+ const NUdf::TUnboxedValue Inner;
const ui64 Step;
ui64 Counter;
TComputationContext& Ctx;
- const TSelf* const Self;
+ const TSelf* const Self;
};
TValue(
@@ -68,7 +68,7 @@ public:
const NUdf::TUnboxedValue& list,
ui64 start, ui64 step,
TComputationContext& ctx,
- const TSelf* self
+ const TSelf* self
)
: TCustomListValue(memInfo)
, List(list)
@@ -76,15 +76,15 @@ public:
, Step(step)
, Ctx(ctx)
, Self(self)
- {}
+ {}
- private:
+ private:
ui64 GetListLength() const override {
if (!Length) {
Length = List.GetListLength();
}
- return *Length;
+ return *Length;
}
bool HasListItems() const override {
@@ -95,79 +95,79 @@ public:
return *HasItems;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return Ctx.HolderFactory.Create<TIterator>(List.GetListIterator(), Start, Step, Ctx, Self);
- }
-
- const NUdf::TUnboxedValue List;
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return Ctx.HolderFactory.Create<TIterator>(List.GetListIterator(), Start, Step, Ctx, Self);
+ }
+
+ const NUdf::TUnboxedValue List;
const ui64 Start;
const ui64 Step;
TComputationContext& Ctx;
- const TSelf* const Self;
+ const TSelf* const Self;
};
TEnumerateWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* start, IComputationNode* step)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, List(list)
, Start(start)
, Step(step)
, ResPair(mutables)
- {}
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return WrapList(ctx, List->GetValue(ctx).Release(), Start->GetValue(ctx).Get<ui64>(), Step->GetValue(ctx).Get<ui64>());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return WrapList(ctx, List->GetValue(ctx).Release(), Start->GetValue(ctx).Get<ui64>(), Step->GetValue(ctx).Get<ui64>());
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto list = GetNodeValue(List, ctx, block);
+ const auto startv = GetNodeValue(Start, ctx, block);
+ const auto stepv = GetNodeValue(Step, ctx, block);
+
+ const auto start = GetterFor<ui64>(startv, context, block);
+ const auto step = GetterFor<ui64>(stepv, context, block);
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TEnumerateWrapper::WrapList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto signature = FunctionType::get(list->getType(), {self->getType(), ctx.Ctx->getType(), list->getType(), start->getType(), step->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ const auto output = CallInst::Create(creator, {self, ctx.Ctx, list, start, step}, "output", block);
+ return output;
+ } else {
+ const auto place = new AllocaInst(list->getType(), 0U, "place", block);
+ new StoreInst(list, place, block);
+ const auto signature = FunctionType::get(Type::getVoidTy(context), {self->getType(), place->getType(), ctx.Ctx->getType(), place->getType(), start->getType(), step->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ CallInst::Create(creator, {self, place, ctx.Ctx, place, start, step}, "", block);
+ const auto output = new LoadInst(place, "output", block);
+ return output;
+ }
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto list = GetNodeValue(List, ctx, block);
- const auto startv = GetNodeValue(Start, ctx, block);
- const auto stepv = GetNodeValue(Step, ctx, block);
-
- const auto start = GetterFor<ui64>(startv, context, block);
- const auto step = GetterFor<ui64>(stepv, context, block);
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TEnumerateWrapper::WrapList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto signature = FunctionType::get(list->getType(), {self->getType(), ctx.Ctx->getType(), list->getType(), start->getType(), step->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- const auto output = CallInst::Create(creator, {self, ctx.Ctx, list, start, step}, "output", block);
- return output;
- } else {
- const auto place = new AllocaInst(list->getType(), 0U, "place", block);
- new StoreInst(list, place, block);
- const auto signature = FunctionType::get(Type::getVoidTy(context), {self->getType(), place->getType(), ctx.Ctx->getType(), place->getType(), start->getType(), step->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- CallInst::Create(creator, {self, place, ctx.Ctx, place, start, step}, "", block);
- const auto output = new LoadInst(place, "output", block);
- return output;
- }
- }
-#endif
-private:
- NUdf::TUnboxedValuePod WrapList(TComputationContext& ctx, NUdf::TUnboxedValuePod list, ui64 start, ui64 step) const {
- return ctx.HolderFactory.Create<TValue>(list, start, step, ctx, this);
- }
-
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Start);
- DependsOn(Step);
+#endif
+private:
+ NUdf::TUnboxedValuePod WrapList(TComputationContext& ctx, NUdf::TUnboxedValuePod list, ui64 start, ui64 step) const {
+ return ctx.HolderFactory.Create<TValue>(list, start, step, ctx, this);
+ }
+
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Start);
+ DependsOn(Step);
}
IComputationNode* const List;
IComputationNode* const Start;
IComputationNode* const Step;
- const TContainerCacheOnContext ResPair;
+ const TContainerCacheOnContext ResPair;
};
-}
-
+}
+
IComputationNode* WrapEnumerate(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
AS_TYPE(TListType, callable.GetInput(0));
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_exists.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_exists.cpp
index daee788720..cf9d6c8b53 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_exists.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_exists.cpp
@@ -5,34 +5,34 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TExistsWrapper : public TDecoratorCodegeneratorNode<TExistsWrapper> {
- typedef TDecoratorCodegeneratorNode<TExistsWrapper> TBaseComputation;
+namespace {
+
+class TExistsWrapper : public TDecoratorCodegeneratorNode<TExistsWrapper> {
+ typedef TDecoratorCodegeneratorNode<TExistsWrapper> TBaseComputation;
public:
- TExistsWrapper(IComputationNode* optional)
- : TBaseComputation(optional)
- {}
+ TExistsWrapper(IComputationNode* optional)
+ : TBaseComputation(optional)
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
- return NUdf::TUnboxedValuePod(bool(value));
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
+ return NUdf::TUnboxedValuePod(bool(value));
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
- const auto check = IsExists(value, block);
- if (Node->IsTemporaryValue())
- ValueCleanup(Node->GetRepresentation(), value, ctx, block);
- return MakeBoolean(check, ctx.Codegen->GetContext(), block);
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
+ const auto check = IsExists(value, block);
+ if (Node->IsTemporaryValue())
+ ValueCleanup(Node->GetRepresentation(), value, ctx, block);
+ return MakeBoolean(check, ctx.Codegen->GetContext(), block);
+ }
+#endif
};
-}
-
+}
+
IComputationNode* WrapExists(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- return new TExistsWrapper(LocateNode(ctx.NodeLocator, callable, 0));
+ return new TExistsWrapper(LocateNode(ctx.NodeLocator, callable, 0));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_extend.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_extend.cpp
index 1e5fe8d1ac..36fd03b0a4 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_extend.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_extend.cpp
@@ -9,166 +9,166 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TExtendFlowWrapper : public TStatefulFlowCodegeneratorNode<TExtendFlowWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TExtendFlowWrapper> TBaseComputation;
-public:
- TExtendFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, TComputationNodePtrVector&& flows)
- : TBaseComputation(mutables, this, kind, EValueRepresentation::Embedded), Flows(flows)
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- for (ui64 index = state.IsInvalid() ? 0ULL : state.Get<ui64>(); index < Flows.size(); ++index) {
- const auto item = Flows[index]->GetValue(ctx);
-
- if (!item.IsFinish()) {
- state = NUdf::TUnboxedValuePod(index);
- return item;
- }
- }
-
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt64Ty(context);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = SelectInst::Create(IsInvalid(load, block), ConstantInt::get(indexType, 0ULL), GetterFor<ui64>(load, context, block), "index", block);
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, Flows.size() + 1U, "result", done);
-
- const auto index = PHINode::Create(indexType, 2U, "index", main);
- index->addIncoming(state, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto select = SwitchInst::Create(index, done, Flows.size(), block);
- result->addIncoming(GetFinish(context), block);
-
- for (auto i = 0U; i < Flows.size(); ++i) {
- const auto flow = BasicBlock::Create(context, "flow", ctx.Func);
- select->addCase(ConstantInt::get(indexType, i), flow);
-
- block = flow;
- const auto item = GetNodeValue(Flows[i], ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(next, done, IsFinish(item, block), block);
- }
-
- block = next;
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(indexType, 1ULL), "plus", block);
- index->addIncoming(plus, block);
- BranchInst::Create(main, block);
-
- block = done;
- new StoreInst(SetterFor<ui64>(index, context, block), statePtr, block);
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- std::for_each(Flows.cbegin(), Flows.cend(), std::bind(&TExtendFlowWrapper::FlowDependsOn, this, std::placeholders::_1));
- }
-
- const TComputationNodePtrVector Flows;
-};
-
+namespace {
+
+class TExtendFlowWrapper : public TStatefulFlowCodegeneratorNode<TExtendFlowWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TExtendFlowWrapper> TBaseComputation;
+public:
+ TExtendFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, TComputationNodePtrVector&& flows)
+ : TBaseComputation(mutables, this, kind, EValueRepresentation::Embedded), Flows(flows)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ for (ui64 index = state.IsInvalid() ? 0ULL : state.Get<ui64>(); index < Flows.size(); ++index) {
+ const auto item = Flows[index]->GetValue(ctx);
+
+ if (!item.IsFinish()) {
+ state = NUdf::TUnboxedValuePod(index);
+ return item;
+ }
+ }
+
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt64Ty(context);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = SelectInst::Create(IsInvalid(load, block), ConstantInt::get(indexType, 0ULL), GetterFor<ui64>(load, context, block), "index", block);
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, Flows.size() + 1U, "result", done);
+
+ const auto index = PHINode::Create(indexType, 2U, "index", main);
+ index->addIncoming(state, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto select = SwitchInst::Create(index, done, Flows.size(), block);
+ result->addIncoming(GetFinish(context), block);
+
+ for (auto i = 0U; i < Flows.size(); ++i) {
+ const auto flow = BasicBlock::Create(context, "flow", ctx.Func);
+ select->addCase(ConstantInt::get(indexType, i), flow);
+
+ block = flow;
+ const auto item = GetNodeValue(Flows[i], ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(next, done, IsFinish(item, block), block);
+ }
+
+ block = next;
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(indexType, 1ULL), "plus", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(main, block);
+
+ block = done;
+ new StoreInst(SetterFor<ui64>(index, context, block), statePtr, block);
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ std::for_each(Flows.cbegin(), Flows.cend(), std::bind(&TExtendFlowWrapper::FlowDependsOn, this, std::placeholders::_1));
+ }
+
+ const TComputationNodePtrVector Flows;
+};
+
template <bool IsStream>
-class TExtendWrapper : public TMutableCodegeneratorNode<TExtendWrapper<IsStream>> {
- typedef TMutableCodegeneratorNode<TExtendWrapper<IsStream>> TBaseComputation;
+class TExtendWrapper : public TMutableCodegeneratorNode<TExtendWrapper<IsStream>> {
+ typedef TMutableCodegeneratorNode<TExtendWrapper<IsStream>> TBaseComputation;
public:
TExtendWrapper(TComputationMutables& mutables, TComputationNodePtrVector&& lists)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, Lists(std::move(lists))
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- TUnboxedValueVector values;
- values.reserve(Lists.size());
- std::transform(Lists.cbegin(), Lists.cend(), std::back_inserter(values),
- std::bind(&IComputationNode::GetValue, std::placeholders::_1, std::ref(ctx))
- );
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ TUnboxedValueVector values;
+ values.reserve(Lists.size());
+ std::transform(Lists.cbegin(), Lists.cend(), std::back_inserter(values),
+ std::bind(&IComputationNode::GetValue, std::placeholders::_1, std::ref(ctx))
+ );
+
+ return IsStream ?
+ ctx.HolderFactory.ExtendStream(values.data(), values.size()):
+ ctx.HolderFactory.ExtendList<false>(values.data(), values.size());
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto sizeType = Type::getInt64Ty(context);
+ const auto size = ConstantInt::get(sizeType, Lists.size());
+
+ const auto arrayType = ArrayType::get(valueType, Lists.size());
+ const auto array = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(arrayType, 0U, "array", block);
+
+ for (size_t i = 0U; i < Lists.size(); ++i) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(array, {ConstantInt::get(sizeType, 0), ConstantInt::get(sizeType, i)}, (TString("ptr_") += ToString(i)).c_str(), block);
+ GetNodeValue(ptr, Lists[i], ctx, block);
+ }
+
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(IsStream ? &THolderFactory::ExtendStream : &THolderFactory::ExtendList<false>));
- return IsStream ?
- ctx.HolderFactory.ExtendStream(values.data(), values.size()):
- ctx.HolderFactory.ExtendList<false>(values.data(), values.size());
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {factory->getType(), array->getType(), size->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, array, size}, "res", block);
+ return res;
+ } else {
+ const auto retPtr = new AllocaInst(valueType, 0U, "ret_ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), array->getType(), size->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, array, size}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ return res;
+ }
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto sizeType = Type::getInt64Ty(context);
- const auto size = ConstantInt::get(sizeType, Lists.size());
-
- const auto arrayType = ArrayType::get(valueType, Lists.size());
- const auto array = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(arrayType, 0U, "array", block);
-
- for (size_t i = 0U; i < Lists.size(); ++i) {
- const auto ptr = GetElementPtrInst::CreateInBounds(array, {ConstantInt::get(sizeType, 0), ConstantInt::get(sizeType, i)}, (TString("ptr_") += ToString(i)).c_str(), block);
- GetNodeValue(ptr, Lists[i], ctx, block);
- }
-
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(IsStream ? &THolderFactory::ExtendStream : &THolderFactory::ExtendList<false>));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {factory->getType(), array->getType(), size->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, array, size}, "res", block);
- return res;
- } else {
- const auto retPtr = new AllocaInst(valueType, 0U, "ret_ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), array->getType(), size->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, array, size}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- return res;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- std::for_each(Lists.cbegin(), Lists.cend(), std::bind(&TExtendWrapper::DependsOn, this, std::placeholders::_1));
+#endif
+private:
+ void RegisterDependencies() const final {
+ std::for_each(Lists.cbegin(), Lists.cend(), std::bind(&TExtendWrapper::DependsOn, this, std::placeholders::_1));
}
- const TComputationNodePtrVector Lists;
+ const TComputationNodePtrVector Lists;
};
-}
-
+}
+
IComputationNode* WrapExtend(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() >= 1, "Expected at least 1 list");
- const auto type = callable.GetType()->GetReturnType();
-
- TComputationNodePtrVector flows;
- flows.reserve(callable.GetInputsCount());
+ const auto type = callable.GetType()->GetReturnType();
+
+ TComputationNodePtrVector flows;
+ flows.reserve(callable.GetInputsCount());
for (ui32 i = 0; i < callable.GetInputsCount(); ++i) {
- flows.emplace_back(LocateNode(ctx.NodeLocator, callable, i));
+ flows.emplace_back(LocateNode(ctx.NodeLocator, callable, i));
}
- if (type->IsFlow()) {
- return new TExtendFlowWrapper(ctx.Mutables, GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType()), std::move(flows));
- } else if (type->IsStream()) {
- return new TExtendWrapper<true>(ctx.Mutables, std::move(flows));
- } else if (type->IsList()) {
- return new TExtendWrapper<false>(ctx.Mutables, std::move(flows));
+ if (type->IsFlow()) {
+ return new TExtendFlowWrapper(ctx.Mutables, GetValueRepresentation(AS_TYPE(TFlowType, type)->GetItemType()), std::move(flows));
+ } else if (type->IsStream()) {
+ return new TExtendWrapper<true>(ctx.Mutables, std::move(flows));
+ } else if (type->IsList()) {
+ return new TExtendWrapper<false>(ctx.Mutables, std::move(flows));
}
-
- THROW yexception() << "Expected either flow, list or stream.";
+
+ THROW yexception() << "Expected either flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_factory.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_factory.cpp
index 6322ca3bf0..57599acb64 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_factory.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_factory.cpp
@@ -7,26 +7,26 @@
#include "mkql_block_add.h"
#include "mkql_blocks.h"
#include "mkql_callable.h"
-#include "mkql_chain_map.h"
-#include "mkql_chain1_map.h"
-#include "mkql_chopper.h"
+#include "mkql_chain_map.h"
+#include "mkql_chain1_map.h"
+#include "mkql_chopper.h"
#include "mkql_coalesce.h"
#include "mkql_collect.h"
#include "mkql_combine.h"
#include "mkql_contains.h"
-#include "mkql_decimal_div.h"
-#include "mkql_decimal_mod.h"
-#include "mkql_decimal_mul.h"
+#include "mkql_decimal_div.h"
+#include "mkql_decimal_mod.h"
+#include "mkql_decimal_mul.h"
#include "mkql_dictitems.h"
#include "mkql_discard.h"
-#include "mkql_element.h"
+#include "mkql_element.h"
#include "mkql_ensure.h"
#include "mkql_enumerate.h"
#include "mkql_exists.h"
#include "mkql_extend.h"
#include "mkql_filter.h"
#include "mkql_flatmap.h"
-#include "mkql_flow.h"
+#include "mkql_flow.h"
#include "mkql_fold.h"
#include "mkql_fold1.h"
#include "mkql_frombytes.h"
@@ -34,7 +34,7 @@
#include "mkql_fromyson.h"
#include "mkql_guess.h"
#include "mkql_group.h"
-#include "mkql_heap.h"
+#include "mkql_heap.h"
#include "mkql_hasitems.h"
#include "mkql_hopping.h"
#include "mkql_if.h"
@@ -43,16 +43,16 @@
#include "mkql_iterable.h"
#include "mkql_iterator.h"
#include "mkql_join.h"
-#include "mkql_join_dict.h"
-#include "mkql_lazy_list.h"
+#include "mkql_join_dict.h"
+#include "mkql_lazy_list.h"
#include "mkql_length.h"
#include "mkql_listfromrange.h"
#include "mkql_logical.h"
#include "mkql_lookup.h"
#include "mkql_map.h"
-#include "mkql_map_join.h"
+#include "mkql_map_join.h"
#include "mkql_multihopping.h"
-#include "mkql_multimap.h"
+#include "mkql_multimap.h"
#include "mkql_next_value.h"
#include "mkql_now.h"
#include "mkql_null.h"
@@ -70,10 +70,10 @@
#include "mkql_size.h"
#include "mkql_skip.h"
#include "mkql_sort.h"
-#include "mkql_condense.h"
-#include "mkql_condense1.h"
-#include "mkql_source.h"
-#include "mkql_squeeze_to_list.h"
+#include "mkql_condense.h"
+#include "mkql_condense1.h"
+#include "mkql_source.h"
+#include "mkql_squeeze_to_list.h"
#include "mkql_switch.h"
#include "mkql_take.h"
#include "mkql_timezone.h"
@@ -88,48 +88,48 @@
#include "mkql_visitall.h"
#include "mkql_way.h"
#include "mkql_weakmember.h"
-#include "mkql_while.h"
-#include "mkql_wide_chain_map.h"
-#include "mkql_wide_chopper.h"
-#include "mkql_wide_combine.h"
-#include "mkql_wide_condense.h"
-#include "mkql_wide_filter.h"
-#include "mkql_wide_map.h"
+#include "mkql_while.h"
+#include "mkql_wide_chain_map.h"
+#include "mkql_wide_chopper.h"
+#include "mkql_wide_combine.h"
+#include "mkql_wide_condense.h"
+#include "mkql_wide_filter.h"
+#include "mkql_wide_map.h"
#include "mkql_zip.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
-
-#include <string_view>
-#include <unordered_map>
-
+
+#include <string_view>
+#include <unordered_map>
+
namespace NKikimr {
namespace NMiniKQL {
IComputationNode* WrapArg(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected 0 args");
MKQL_ENSURE(callable.GetType()->IsMergeDisabled(), "Merge mode is not disabled");
- return new TExternalCodegeneratorNode(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()));
+ return new TExternalCodegeneratorNode(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()));
+}
+
+IComputationNode* WrapWideFlowArg(TCallable& callable, const TComputationNodeFactoryContext&) {
+ MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected 0 args");
+ MKQL_ENSURE(callable.GetType()->IsMergeDisabled(), "Merge mode is not disabled");
+ return new TWideFlowProxyCodegeneratorNode;
}
-IComputationNode* WrapWideFlowArg(TCallable& callable, const TComputationNodeFactoryContext&) {
- MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected 0 args");
- MKQL_ENSURE(callable.GetType()->IsMergeDisabled(), "Merge mode is not disabled");
- return new TWideFlowProxyCodegeneratorNode;
-}
-
-using TCallableComputationNodeBuilderPtr = IComputationNode* (*const)(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-using TCallableComputationNodeBuilderMap = std::unordered_map<std::string_view, TCallableComputationNodeBuilderPtr>;
+using TCallableComputationNodeBuilderPtr = IComputationNode* (*const)(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+using TCallableComputationNodeBuilderMap = std::unordered_map<std::string_view, TCallableComputationNodeBuilderPtr>;
namespace {
struct TCallableComputationNodeBuilderFuncMapFiller {
- const TCallableComputationNodeBuilderMap Map;
+ const TCallableComputationNodeBuilderMap Map;
TCallableComputationNodeBuilderFuncMapFiller()
- : Map(InitList)
- {}
+ : Map(InitList)
+ {}
- static constexpr std::initializer_list<TCallableComputationNodeBuilderMap::value_type> InitList = {
+ static constexpr std::initializer_list<TCallableComputationNodeBuilderMap::value_type> InitList = {
{"Append", &WrapAppend},
{"Prepend", &WrapPrepend},
{"Extend", &WrapExtend},
@@ -144,11 +144,11 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
{"Fold1", &WrapFold1},
{"Map", &WrapMap},
{"OrderedMap", &WrapMap},
- {"MultiMap", &WrapMultiMap},
+ {"MultiMap", &WrapMultiMap},
{"FlatMap", &WrapFlatMap},
{"OrderedFlatMap", &WrapFlatMap},
- {"ChainMap", &WrapChainMap},
- {"Chain1Map", &WrapChain1Map},
+ {"ChainMap", &WrapChainMap},
+ {"Chain1Map", &WrapChain1Map},
{"Filter", &WrapFilter},
{"OrderedFilter", &WrapFilter},
{"TakeWhile", &WrapTakeWhile},
@@ -163,15 +163,15 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
{"Lookup", &WrapLookup},
{"ToSortedDict", &WrapToSortedDict},
{"ToHashedDict", &WrapToHashedDict},
- {"SqueezeToList", &WrapSqueezeToList},
+ {"SqueezeToList", &WrapSqueezeToList},
{"SqueezeToSortedDict", &WrapSqueezeToSortedDict},
{"SqueezeToHashedDict", &WrapSqueezeToHashedDict},
- {"NarrowSqueezeToSortedDict", &WrapSqueezeToSortedDict},
- {"NarrowSqueezeToHashedDict", &WrapSqueezeToHashedDict},
+ {"NarrowSqueezeToSortedDict", &WrapSqueezeToSortedDict},
+ {"NarrowSqueezeToHashedDict", &WrapSqueezeToHashedDict},
{"Coalesce", &WrapCoalesce},
{"ToOptional", &WrapHead},
{"Head", &WrapHead},
- {"Last", &WrapLast},
+ {"Last", &WrapLast},
{"Unwrap", &WrapUnwrap},
{"Ensure", &WrapEnsure},
{"If", &WrapIf},
@@ -210,8 +210,8 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
{"Sort", &WrapSort},
{"UnstableSort", &WrapUnstableSort},
{"DictItems", &WrapDictItems},
- {"DictKeys", &WrapDictKeys},
- {"DictPayloads", &WrapDictPayloads},
+ {"DictKeys", &WrapDictKeys},
+ {"DictPayloads", &WrapDictPayloads},
{"Nth", &WrapNth},
{"ToIndexDict", &WrapToIndexDict},
{"JoinDict", &WrapJoinDict},
@@ -271,27 +271,27 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
{"PartialSort", &WrapPartialSort},
{"KeepTop", &WrapKeepTop},
{"Top", &WrapTop},
- {"TopSort", &WrapTopSort},
+ {"TopSort", &WrapTopSort},
{"SourceOf", &WrapSourceOf},
- {"LazyList", &WrapLazyList},
- {"Chopper", &WrapChopper},
- {"ExpandMap", &WrapExpandMap},
- {"WideMap", &WrapWideMap},
- {"WideChain1Map", &WrapWideChain1Map},
- {"NarrowMap", &WrapNarrowMap},
- {"NarrowFlatMap", &WrapNarrowFlatMap},
- {"NarrowMultiMap", &WrapNarrowMultiMap},
- {"WideFilter", &WrapWideFilter},
- {"WideTakeWhile", &WrapWideTakeWhile},
- {"WideSkipWhile", &WrapWideSkipWhile},
- {"WideTakeWhileInclusive", &WrapWideTakeWhileInclusive},
- {"WideSkipWhileInclusive", &WrapWideSkipWhileInclusive},
- {"WideCombiner", &WrapWideCombiner},
- {"WideLastCombiner", &WrapWideLastCombiner},
- {"WideCondense1", &WrapWideCondense1},
- {"WideChopper", &WrapWideChopper},
- {"WideFlowArg", &WrapWideFlowArg},
- {"Source", &WrapSource},
+ {"LazyList", &WrapLazyList},
+ {"Chopper", &WrapChopper},
+ {"ExpandMap", &WrapExpandMap},
+ {"WideMap", &WrapWideMap},
+ {"WideChain1Map", &WrapWideChain1Map},
+ {"NarrowMap", &WrapNarrowMap},
+ {"NarrowFlatMap", &WrapNarrowFlatMap},
+ {"NarrowMultiMap", &WrapNarrowMultiMap},
+ {"WideFilter", &WrapWideFilter},
+ {"WideTakeWhile", &WrapWideTakeWhile},
+ {"WideSkipWhile", &WrapWideSkipWhile},
+ {"WideTakeWhileInclusive", &WrapWideTakeWhileInclusive},
+ {"WideSkipWhileInclusive", &WrapWideSkipWhileInclusive},
+ {"WideCombiner", &WrapWideCombiner},
+ {"WideLastCombiner", &WrapWideLastCombiner},
+ {"WideCondense1", &WrapWideCondense1},
+ {"WideChopper", &WrapWideChopper},
+ {"WideFlowArg", &WrapWideFlowArg},
+ {"Source", &WrapSource},
{"RangeCreate", &WrapRangeCreate},
{"RangeUnion", &WrapRangeUnion},
{"RangeIntersect", &WrapRangeIntersect},
@@ -308,7 +308,7 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
TComputationNodeFactory GetBuiltinFactory() {
return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
const auto& map = Singleton<TCallableComputationNodeBuilderFuncMapFiller>()->Map;
- const auto it = map.find(callable.GetType()->GetName());
+ const auto it = map.find(callable.GetType()->GetName());
if (it == map.end())
return nullptr;
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_filter.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_filter.cpp
index 370c955509..7de0ebd830 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_filter.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_filter.cpp
@@ -6,192 +6,192 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TFilterFlowWrapper : public TStatelessFlowCodegeneratorNode<TFilterFlowWrapper> {
- typedef TStatelessFlowCodegeneratorNode<TFilterFlowWrapper> TBaseComputation;
-public:
- TFilterFlowWrapper(EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(flow, kind), Flow(flow), Item(item), Predicate(predicate)
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
- return item;
- else
- Item->SetValue(ctx, std::move(item));
- while (!Predicate->GetValue(ctx).template Get<bool>());
- return Item->GetValue(ctx);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- BranchInst::Create(loop, block);
-
- block = loop;
- const auto item = GetNodeValue(Flow, ctx, block);
- BranchInst::Create(exit, good, IsSpecial(item, block), block);
-
- block = good;
- codegenItem->CreateSetValue(ctx, block, item);
- const auto pred = GetNodeValue(Predicate, ctx, block);
- const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
-
- BranchInst::Create(exit, loop, bit, block);
-
- block = exit;
- return item;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Item);
- DependsOn(flow, Predicate);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
-};
-
-class TFilterWithLimitFlowWrapper : public TStatefulFlowCodegeneratorNode<TFilterWithLimitFlowWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TFilterWithLimitFlowWrapper> TBaseComputation;
-public:
- TFilterWithLimitFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Limit(limit), Item(item), Predicate(predicate)
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- state = Limit->GetValue(ctx);
- } else if (!state.Get<ui64>()) {
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
- do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
- return item;
- else
- Item->SetValue(ctx, std::move(item));
- while (!Predicate->GetValue(ctx).template Get<bool>());
-
- auto todo = state.Get<ui64>();
- state = NUdf::TUnboxedValuePod(--todo);
- return Item->GetValue(ctx);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 3U, "result", exit);
-
- BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Limit, ctx, block);
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetFalse(context), "done", block);
- result->addIncoming(GetFinish(context), block);
- BranchInst::Create(exit, loop, done, block);
-
- block = loop;
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(exit, step, IsSpecial(item, block), block);
-
- block = step;
- codegenItem->CreateSetValue(ctx, block, item);
- const auto pred = GetNodeValue(Predicate, ctx, block);
- const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
-
- BranchInst::Create(good, loop, bit, block);
-
- block = good;
- const auto decr = BinaryOperator::CreateSub(state, ConstantInt::get(state->getType(), 1ULL), "decr", block);
- new StoreInst(decr, statePtr, block);
-
- result->addIncoming(item, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- DependsOn(flow, Limit);
- Own(flow, Item);
- DependsOn(flow, Predicate);
- }
- }
-
- IComputationNode* const Flow;
- IComputationNode* const Limit;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
-};
-
-template <bool IsStream>
-class TBaseFilterWrapper {
-protected:
+namespace {
+
+class TFilterFlowWrapper : public TStatelessFlowCodegeneratorNode<TFilterFlowWrapper> {
+ typedef TStatelessFlowCodegeneratorNode<TFilterFlowWrapper> TBaseComputation;
+public:
+ TFilterFlowWrapper(EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(flow, kind), Flow(flow), Item(item), Predicate(predicate)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
+ return item;
+ else
+ Item->SetValue(ctx, std::move(item));
+ while (!Predicate->GetValue(ctx).template Get<bool>());
+ return Item->GetValue(ctx);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ BranchInst::Create(exit, good, IsSpecial(item, block), block);
+
+ block = good;
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto pred = GetNodeValue(Predicate, ctx, block);
+ const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
+
+ BranchInst::Create(exit, loop, bit, block);
+
+ block = exit;
+ return item;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Item);
+ DependsOn(flow, Predicate);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+};
+
+class TFilterWithLimitFlowWrapper : public TStatefulFlowCodegeneratorNode<TFilterWithLimitFlowWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TFilterWithLimitFlowWrapper> TBaseComputation;
+public:
+ TFilterWithLimitFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Limit(limit), Item(item), Predicate(predicate)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ state = Limit->GetValue(ctx);
+ } else if (!state.Get<ui64>()) {
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+ do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
+ return item;
+ else
+ Item->SetValue(ctx, std::move(item));
+ while (!Predicate->GetValue(ctx).template Get<bool>());
+
+ auto todo = state.Get<ui64>();
+ state = NUdf::TUnboxedValuePod(--todo);
+ return Item->GetValue(ctx);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 3U, "result", exit);
+
+ BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Limit, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetFalse(context), "done", block);
+ result->addIncoming(GetFinish(context), block);
+ BranchInst::Create(exit, loop, done, block);
+
+ block = loop;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(exit, step, IsSpecial(item, block), block);
+
+ block = step;
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto pred = GetNodeValue(Predicate, ctx, block);
+ const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
+
+ BranchInst::Create(good, loop, bit, block);
+
+ block = good;
+ const auto decr = BinaryOperator::CreateSub(state, ConstantInt::get(state->getType(), 1ULL), "decr", block);
+ new StoreInst(decr, statePtr, block);
+
+ result->addIncoming(item, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ DependsOn(flow, Limit);
+ Own(flow, Item);
+ DependsOn(flow, Predicate);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationNode* const Limit;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+};
+
+template <bool IsStream>
+class TBaseFilterWrapper {
+protected:
class TListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
- : TComputationValue<TIterator>(memInfo)
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
+ , Iter(std::move(iter))
, Item(item)
, Predicate(predicate)
{}
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- while (Iter.Next(Item->RefValue(CompCtx))) {
- if (Predicate->GetValue(CompCtx).template Get<bool>()) {
- value = Item->GetValue(CompCtx);
- return true;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ while (Iter.Next(Item->RefValue(CompCtx))) {
+ if (Predicate->GetValue(CompCtx).template Get<bool>()) {
+ value = Item->GetValue(CompCtx);
+ return true;
}
- }
+ }
+
+ return false;
+ }
- return false;
- }
-
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Iter;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, IComputationExternalNode* item, IComputationNode* predicate)
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, IComputationExternalNode* item, IComputationNode* predicate)
: TCustomListValue(memInfo)
, CompCtx(compCtx)
, List(list)
@@ -200,14 +200,14 @@ protected:
{
}
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, Predicate);
- }
-
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, Predicate);
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
@@ -215,7 +215,7 @@ protected:
public:
using TBase = TComputationValue<TStreamValue>;
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, IComputationExternalNode* item, IComputationNode* predicate)
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, IComputationExternalNode* item, IComputationNode* predicate)
: TBase(memInfo)
, CompCtx(compCtx)
, Stream(stream)
@@ -224,32 +224,32 @@ protected:
{
}
- private:
- ui32 GetTraverseCount() const final {
+ private:
+ ui32 GetTraverseCount() const final {
return 1;
}
- NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
+ NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
Y_UNUSED(index);
return Stream;
}
- NUdf::TUnboxedValue Save() const final {
+ NUdf::TUnboxedValue Save() const final {
return NUdf::TUnboxedValue::Zero();
}
- void Load(const NUdf::TStringRef&) final {}
+ void Load(const NUdf::TStringRef&) final {}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- for (;;) {
- const auto status = Stream.Fetch(Item->RefValue(CompCtx));
- if (NUdf::EFetchStatus::Ok != status) {
- return status;
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ for (;;) {
+ const auto status = Stream.Fetch(Item->RefValue(CompCtx));
+ if (NUdf::EFetchStatus::Ok != status) {
+ return status;
}
if (Predicate->GetValue(CompCtx).template Get<bool>()) {
result = Item->GetValue(CompCtx);
- return NUdf::EFetchStatus::Ok;
+ return NUdf::EFetchStatus::Ok;
}
}
@@ -257,1160 +257,1160 @@ protected:
}
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Stream;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
- TBaseFilterWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : List(list), Item(item), Predicate(predicate)
- {}
-
-#ifndef MKQL_DISABLE_CODEGEN
- Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ TBaseFilterWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : List(list), Item(item), Predicate(predicate)
+ {}
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
-
- BranchInst::Create(good, done, icmp, block);
- block = good;
-
- const auto item = new LoadInst(itemPtr, "item", block);
- const auto predicate = GetNodeValue(Predicate, ctx, block);
-
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(pass, loop, boolPred, block);
- block = pass;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- new StoreInst(item, valuePtr, block);
- ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TCodegenValue = std::conditional_t<IsStream, TStreamCodegenValueStateless, TCustomListCodegenValue>;
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
+
+ BranchInst::Create(good, done, icmp, block);
+ block = good;
+
+ const auto item = new LoadInst(itemPtr, "item", block);
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(pass, loop, boolPred, block);
+ block = pass;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ new StoreInst(item, valuePtr, block);
+ ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TCodegenValue = std::conditional_t<IsStream, TStreamCodegenValueStateless, TCustomListCodegenValue>;
using TFilterPtr = std::conditional_t<IsStream, TStreamCodegenValueStateless::TFetchPtr, TCustomListCodegenValue::TNextPtr>;
-
- Function* FilterFunc = nullptr;
-
- TFilterPtr Filter = nullptr;
-#endif
-
+
+ Function* FilterFunc = nullptr;
+
+ TFilterPtr Filter = nullptr;
+#endif
+
IComputationNode* const List;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
-template <bool IsStream>
-class TBaseFilterWithLimitWrapper {
-protected:
- class TListValue : public TCustomListValue {
- public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, ui64 limit, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
- : TComputationValue<TIterator>(memInfo)
- , CompCtx(compCtx)
- , Iter(std::move(iter))
- , Limit(limit)
- , Item(item)
- , Predicate(predicate)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- if (!Limit) {
- return false;
- }
- while (Iter.Next(Item->RefValue(CompCtx))) {
- if (Predicate->GetValue(CompCtx).template Get<bool>()) {
- value = Item->GetValue(CompCtx);
- --Limit;
- return true;
- }
- }
-
- return false;
- }
-
- TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- ui64 Limit;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
- };
-
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, ui64 limit, IComputationExternalNode* item, IComputationNode* predicate)
- : TCustomListValue(memInfo)
- , CompCtx(compCtx)
- , List(list)
- , Limit(limit)
- , Item(item)
- , Predicate(predicate)
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, Limit, List.GetListIterator(), Item, Predicate);
- }
-
- TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- const ui64 Limit;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
- };
-
- class TStreamValue : public TComputationValue<TStreamValue> {
- public:
- using TBase = TComputationValue<TStreamValue>;
-
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, ui64 limit, IComputationExternalNode* item, IComputationNode* predicate)
- : TBase(memInfo)
- , CompCtx(compCtx)
- , Stream(stream)
- , Limit(limit)
- , Item(item)
- , Predicate(predicate)
- {
- }
-
- private:
- ui32 GetTraverseCount() const final {
- return 1;
- }
-
- NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
- Y_UNUSED(index);
- return Stream;
- }
-
- NUdf::TUnboxedValue Save() const final {
- return NUdf::TUnboxedValue::Zero();
- }
-
- void Load(const NUdf::TStringRef&) final {}
-
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- if (!Limit) {
- return NUdf::EFetchStatus::Finish;
- }
-
- for (;;) {
- const auto status = Stream.Fetch(Item->RefValue(CompCtx));
- if (NUdf::EFetchStatus::Ok != status) {
- return status;
- }
-
- if (Predicate->GetValue(CompCtx).template Get<bool>()) {
- result = Item->GetValue(CompCtx);
- --Limit;
- return NUdf::EFetchStatus::Ok;
- }
- }
-
- return NUdf::EFetchStatus::Finish;
- }
-
- TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- ui64 Limit;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
- };
-
- TBaseFilterWithLimitWrapper(IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
- : List(list), Limit(limit), Item(item), Predicate(predicate)
- {}
-
-#ifndef MKQL_DISABLE_CODEGEN
- Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto limitType = Type::getInt64Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(limitType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+template <bool IsStream>
+class TBaseFilterWithLimitWrapper {
+protected:
+ class TListValue : public TCustomListValue {
+ public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, ui64 limit, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
+ : TComputationValue<TIterator>(memInfo)
+ , CompCtx(compCtx)
+ , Iter(std::move(iter))
+ , Limit(limit)
+ , Item(item)
+ , Predicate(predicate)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ if (!Limit) {
+ return false;
+ }
+ while (Iter.Next(Item->RefValue(CompCtx))) {
+ if (Predicate->GetValue(CompCtx).template Get<bool>()) {
+ value = Item->GetValue(CompCtx);
+ --Limit;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ TComputationContext& CompCtx;
+ const NUdf::TUnboxedValue Iter;
+ ui64 Limit;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+ };
+
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, ui64 limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : TCustomListValue(memInfo)
+ , CompCtx(compCtx)
+ , List(list)
+ , Limit(limit)
+ , Item(item)
+ , Predicate(predicate)
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, Limit, List.GetListIterator(), Item, Predicate);
+ }
+
+ TComputationContext& CompCtx;
+ const NUdf::TUnboxedValue List;
+ const ui64 Limit;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+ };
+
+ class TStreamValue : public TComputationValue<TStreamValue> {
+ public:
+ using TBase = TComputationValue<TStreamValue>;
+
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, ui64 limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBase(memInfo)
+ , CompCtx(compCtx)
+ , Stream(stream)
+ , Limit(limit)
+ , Item(item)
+ , Predicate(predicate)
+ {
+ }
+
+ private:
+ ui32 GetTraverseCount() const final {
+ return 1;
+ }
+
+ NUdf::TUnboxedValue GetTraverseItem(ui32 index) const final {
+ Y_UNUSED(index);
+ return Stream;
+ }
+
+ NUdf::TUnboxedValue Save() const final {
+ return NUdf::TUnboxedValue::Zero();
+ }
+
+ void Load(const NUdf::TStringRef&) final {}
+
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ if (!Limit) {
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ for (;;) {
+ const auto status = Stream.Fetch(Item->RefValue(CompCtx));
+ if (NUdf::EFetchStatus::Ok != status) {
+ return status;
+ }
+
+ if (Predicate->GetValue(CompCtx).template Get<bool>()) {
+ result = Item->GetValue(CompCtx);
+ --Limit;
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ TComputationContext& CompCtx;
+ const NUdf::TUnboxedValue Stream;
+ ui64 Limit;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+ };
+
+ TBaseFilterWithLimitWrapper(IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : List(list), Limit(limit), Item(item), Predicate(predicate)
+ {}
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto limitType = Type::getInt64Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(limitType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto limitArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto limit = new LoadInst(limitArg, "limit", false, block);
- const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, limit, ConstantInt::get(limit->getType(), 0), "zero", block);
- BranchInst::Create(nope, init, zero, block);
-
- block = nope;
- ReturnInst::Create(context, IsStream ? ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)) : ConstantInt::getFalse(context), block);
-
- block = init;
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
-
- BranchInst::Create(good, done, icmp, block);
- block = good;
-
- const auto item = new LoadInst(itemPtr, "item", block);
- const auto predicate = GetNodeValue(Predicate, ctx, block);
-
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(pass, loop, boolPred, block);
- block = pass;
-
- const auto decr = BinaryOperator::CreateSub(limit, ConstantInt::get(limit->getType(), 1ULL), "decr", block);
- new StoreInst(decr, limitArg, block);
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- new StoreInst(item, valuePtr, block);
- ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TCodegenValue = std::conditional_t<IsStream, TStreamCodegenStatefulValueT<ui64>, TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>>;
- using TFilterPtr = std::conditional_t<IsStream, TStreamCodegenStatefulValueT<ui64>::TFetchPtr, TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>::TNextPtr>;
-
- Function* FilterFunc = nullptr;
-
- TFilterPtr Filter = nullptr;
-#endif
-
- IComputationNode* const List;
- IComputationNode* const Limit;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
-};
-
-class TStreamFilterWrapper : public TCustomValueCodegeneratorNode<TStreamFilterWrapper>,
- private TBaseFilterWrapper<true> {
- typedef TBaseFilterWrapper<true> TBaseWrapper;
- typedef TCustomValueCodegeneratorNode<TStreamFilterWrapper> TBaseComputation;
-public:
- TStreamFilterWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Filter)
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, List->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, List->GetValue(ctx), Item, Predicate);
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- Own(Item);
- DependsOn(Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FilterFunc)
- Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
- }
-#endif
-};
-
-class TStreamFilterWithLimitWrapper : public TCustomValueCodegeneratorNode<TStreamFilterWithLimitWrapper>,
- private TBaseFilterWithLimitWrapper<true> {
- typedef TBaseFilterWithLimitWrapper<true> TBaseWrapper;
- typedef TCustomValueCodegeneratorNode<TStreamFilterWithLimitWrapper> TBaseComputation;
-public:
- TStreamFilterWithLimitWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, limit, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Filter)
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, List->GetValue(ctx), Limit->GetValue(ctx).Get<ui64>());
-#endif
- return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, List->GetValue(ctx), Limit->GetValue(ctx).Get<ui64>(), Item, Predicate);
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Limit);
- Own(Item);
- DependsOn(Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FilterFunc)
- Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
- }
-#endif
-};
-
-static constexpr size_t UseOnStack = 1ULL << 8ULL;
-ui64* MyAlloc(const ui64 size) { return TMKQLAllocator<ui64>::allocate(size); }
-void MyFree(const ui64 *const ptr, const ui64 size) noexcept { TMKQLAllocator<ui64>::deallocate(ptr, size); }
-
-class TListFilterWrapper : public TBothWaysCodegeneratorNode<TListFilterWrapper>,
- private TBaseFilterWrapper<false> {
- typedef TBaseFilterWrapper<false> TBaseWrapper;
- typedef TBothWaysCodegeneratorNode<TListFilterWrapper> TBaseComputation;
-public:
- TListFilterWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- const auto size = list.GetListLength();
-
- std::array<ui64, UseOnStack> stackBitSet;
- std::unique_ptr<ui64[]> heapBitSet;
-
- const auto maskSize = (size + 63ULL) >> 6ULL;
- const bool useHeap = maskSize > UseOnStack;
-
- if (useHeap) {
- heapBitSet = std::make_unique<ui64[]>(maskSize);
- }
-
- const auto mask = useHeap ? heapBitSet.get() : stackBitSet.data();
-
- ui64 count = 0ULL;
-
- for (ui64 i = 0ULL; i < size;) {
- auto& m = mask[i >> 6ULL];
- m = 0ULL;
- for (ui64 bit = 1ULL; bit && i < size; bit <<= 1ULL) {
- Item->SetValue(ctx, NUdf::TUnboxedValue(elements[i++]));
- if (Predicate->GetValue(ctx).Get<bool>()) {
- m |= bit;
- ++count;
- }
- }
- }
-
- if (count == size) {
- return list.Release();
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, items);
- for (auto p = mask; count; ++p) {
- const auto cb = count;
- auto e = elements;
- elements += 64ULL;
- for (auto bits = *p; bits; bits >>= 1ULL) {
- if (bits & 1ULL) {
- *items++ = *e;
- if (!--count)
- break;
- }
- ++e;
- }
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), Item, Predicate);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto out = PHINode::Create(list->getType(), 3U, "out", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
- const auto allBits = ConstantInt::get(size->getType(), 63);
- const auto add = BinaryOperator::CreateAdd(size, allBits, "add", block);
- const auto shr = BinaryOperator::CreateLShr(add, ConstantInt::get(add->getType(), 6), "shr", block);
-
- const auto maskType = Type::getInt64Ty(context);
- const auto zeroMask = ConstantInt::get(maskType, 0);
- const auto plusMask = ConstantInt::get(maskType, 1);
-
- const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
- const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto bits = PHINode::Create(PointerType::getUnqual(maskType), 2U, "bits", main);
-
- const auto zeroSize = ConstantInt::get(size->getType(), 0);
- const auto plusSize = ConstantInt::get(size->getType(), 1);
-
- const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, shr, ConstantInt::get(add->getType(), UseOnStack), "heap", block);
- BranchInst::Create(hmsk, smsk, heap, block);
-
- {
- block = smsk;
-
- const auto arrayType = ArrayType::get(Type::getInt64Ty(context), UseOnStack);
- const auto array = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(arrayType, 0U, "array", block);
- const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
-
- bits->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- {
- block = hmsk;
-
- const auto fnType = FunctionType::get(bits->getType(), {shr->getType()}, false);
- const auto name = "MyAlloc";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyAlloc));
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto limitArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto limit = new LoadInst(limitArg, "limit", false, block);
+ const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, limit, ConstantInt::get(limit->getType(), 0), "zero", block);
+ BranchInst::Create(nope, init, zero, block);
+
+ block = nope;
+ ReturnInst::Create(context, IsStream ? ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)) : ConstantInt::getFalse(context), block);
+
+ block = init;
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
+
+ BranchInst::Create(good, done, icmp, block);
+ block = good;
+
+ const auto item = new LoadInst(itemPtr, "item", block);
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(pass, loop, boolPred, block);
+ block = pass;
+
+ const auto decr = BinaryOperator::CreateSub(limit, ConstantInt::get(limit->getType(), 1ULL), "decr", block);
+ new StoreInst(decr, limitArg, block);
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ new StoreInst(item, valuePtr, block);
+ ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TCodegenValue = std::conditional_t<IsStream, TStreamCodegenStatefulValueT<ui64>, TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>>;
+ using TFilterPtr = std::conditional_t<IsStream, TStreamCodegenStatefulValueT<ui64>::TFetchPtr, TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>::TNextPtr>;
+
+ Function* FilterFunc = nullptr;
+
+ TFilterPtr Filter = nullptr;
+#endif
+
+ IComputationNode* const List;
+ IComputationNode* const Limit;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+};
+
+class TStreamFilterWrapper : public TCustomValueCodegeneratorNode<TStreamFilterWrapper>,
+ private TBaseFilterWrapper<true> {
+ typedef TBaseFilterWrapper<true> TBaseWrapper;
+ typedef TCustomValueCodegeneratorNode<TStreamFilterWrapper> TBaseComputation;
+public:
+ TStreamFilterWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Filter)
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, List->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, List->GetValue(ctx), Item, Predicate);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ Own(Item);
+ DependsOn(Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(FilterFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FilterFunc)
+ Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
+ }
+#endif
+};
+
+class TStreamFilterWithLimitWrapper : public TCustomValueCodegeneratorNode<TStreamFilterWithLimitWrapper>,
+ private TBaseFilterWithLimitWrapper<true> {
+ typedef TBaseFilterWithLimitWrapper<true> TBaseWrapper;
+ typedef TCustomValueCodegeneratorNode<TStreamFilterWithLimitWrapper> TBaseComputation;
+public:
+ TStreamFilterWithLimitWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, limit, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Filter)
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, List->GetValue(ctx), Limit->GetValue(ctx).Get<ui64>());
+#endif
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, List->GetValue(ctx), Limit->GetValue(ctx).Get<ui64>(), Item, Predicate);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Limit);
+ Own(Item);
+ DependsOn(Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(FilterFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FilterFunc)
+ Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
+ }
+#endif
+};
+
+static constexpr size_t UseOnStack = 1ULL << 8ULL;
+ui64* MyAlloc(const ui64 size) { return TMKQLAllocator<ui64>::allocate(size); }
+void MyFree(const ui64 *const ptr, const ui64 size) noexcept { TMKQLAllocator<ui64>::deallocate(ptr, size); }
+
+class TListFilterWrapper : public TBothWaysCodegeneratorNode<TListFilterWrapper>,
+ private TBaseFilterWrapper<false> {
+ typedef TBaseFilterWrapper<false> TBaseWrapper;
+ typedef TBothWaysCodegeneratorNode<TListFilterWrapper> TBaseComputation;
+public:
+ TListFilterWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ const auto size = list.GetListLength();
+
+ std::array<ui64, UseOnStack> stackBitSet;
+ std::unique_ptr<ui64[]> heapBitSet;
+
+ const auto maskSize = (size + 63ULL) >> 6ULL;
+ const bool useHeap = maskSize > UseOnStack;
+
+ if (useHeap) {
+ heapBitSet = std::make_unique<ui64[]>(maskSize);
+ }
+
+ const auto mask = useHeap ? heapBitSet.get() : stackBitSet.data();
+
+ ui64 count = 0ULL;
+
+ for (ui64 i = 0ULL; i < size;) {
+ auto& m = mask[i >> 6ULL];
+ m = 0ULL;
+ for (ui64 bit = 1ULL; bit && i < size; bit <<= 1ULL) {
+ Item->SetValue(ctx, NUdf::TUnboxedValue(elements[i++]));
+ if (Predicate->GetValue(ctx).Get<bool>()) {
+ m |= bit;
+ ++count;
+ }
+ }
+ }
+
+ if (count == size) {
+ return list.Release();
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, items);
+ for (auto p = mask; count; ++p) {
+ const auto cb = count;
+ auto e = elements;
+ elements += 64ULL;
+ for (auto bits = *p; bits; bits >>= 1ULL) {
+ if (bits & 1ULL) {
+ *items++ = *e;
+ if (!--count)
+ break;
+ }
+ ++e;
+ }
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), Item, Predicate);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto out = PHINode::Create(list->getType(), 3U, "out", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+ const auto allBits = ConstantInt::get(size->getType(), 63);
+ const auto add = BinaryOperator::CreateAdd(size, allBits, "add", block);
+ const auto shr = BinaryOperator::CreateLShr(add, ConstantInt::get(add->getType(), 6), "shr", block);
+
+ const auto maskType = Type::getInt64Ty(context);
+ const auto zeroMask = ConstantInt::get(maskType, 0);
+ const auto plusMask = ConstantInt::get(maskType, 1);
+
+ const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
+ const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto bits = PHINode::Create(PointerType::getUnqual(maskType), 2U, "bits", main);
+
+ const auto zeroSize = ConstantInt::get(size->getType(), 0);
+ const auto plusSize = ConstantInt::get(size->getType(), 1);
+
+ const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, shr, ConstantInt::get(add->getType(), UseOnStack), "heap", block);
+ BranchInst::Create(hmsk, smsk, heap, block);
+
+ {
+ block = smsk;
+
+ const auto arrayType = ArrayType::get(Type::getInt64Ty(context), UseOnStack);
+ const auto array = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(arrayType, 0U, "array", block);
+ const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
+
+ bits->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ {
+ block = hmsk;
+
+ const auto fnType = FunctionType::get(bits->getType(), {shr->getType()}, false);
+ const auto name = "MyAlloc";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyAlloc));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- const auto ptr = CallInst::Create(func, {shr}, "ptr", block);
- bits->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- block = main;
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto save = BasicBlock::Create(context, "save", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto last = BasicBlock::Create(context, "last", ctx.Func);
- const auto free = BasicBlock::Create(context, "free", ctx.Func);
-
- const auto output = PHINode::Create(out->getType(), 3U, "output", last);
- const auto index = PHINode::Create(size->getType(), 3U, "index", loop);
- const auto count = PHINode::Create(size->getType(), 3U, "count", loop);
- const auto bitset = PHINode::Create(maskType, 3U, "bitset", loop);
-
- count->addIncoming(zeroSize, block);
- index->addIncoming(zeroSize, block);
- bitset->addIncoming(zeroMask, block);
-
- BranchInst::Create(loop, block);
-
- {
- block = loop;
-
- const auto plus = BinaryOperator::CreateAdd(index, plusSize, "plus", block);
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, plus, size, "more", block);
- BranchInst::Create(test, stop, more, block);
-
- block = test;
-
- const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
- const auto item = new LoadInst(ptr, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto predicate = GetNodeValue(Predicate, ctx, block);
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- const auto inc = BinaryOperator::CreateAdd(count, plusSize, "inc", block);
- const auto mod = BinaryOperator::CreateAnd(index, allBits, "mod", block);
- const auto bit = BinaryOperator::CreateShl(plusMask, mod, "bit", block);
- const auto set = BinaryOperator::CreateOr(bitset, bit, "set", block);
-
- const auto newset = SelectInst::Create(boolPred, set, bitset, "newset", block);
- const auto newcount = SelectInst::Create(boolPred, inc, count, "newcount", block);
-
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, allBits, "next", block);
- const auto last = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, plus, size, "last", block);
- const auto step = BinaryOperator::CreateOr(next, last, "step", block);
-
- index->addIncoming(plus, block);
- count->addIncoming(newcount, block);
- bitset->addIncoming(newset, block);
- BranchInst::Create(save, loop, step, block);
-
- block = save;
- const auto div = BinaryOperator::CreateLShr(index, ConstantInt::get(index->getType(), 6), "div", block);
- const auto savePtr = GetElementPtrInst::CreateInBounds(bits, {div}, "save_ptr", block);
- new StoreInst(newset, savePtr, block);
-
- index->addIncoming(plus, block);
- count->addIncoming(newcount, block);
- bitset->addIncoming(zeroMask, block);
- BranchInst::Create(loop, block);
- }
-
- block = stop;
- const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, count, "asis", block);
-
- output->addIncoming(list, block);
- BranchInst::Create(last, make, asis, block);
-
- block = make;
-
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, count, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto move = BasicBlock::Create(context, "move", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto bulk = BasicBlock::Create(context, "bulk", ctx.Func);
- const auto copy = BasicBlock::Create(context, "copy", ctx.Func);
-
- const auto one = PHINode::Create(count->getType(), 2U, "one", move);
- const auto two = PHINode::Create(count->getType(), 2U, "two", move);
- const auto idx = PHINode::Create(count->getType(), 2U, "idx", move);
- one->addIncoming(zeroSize, block);
- two->addIncoming(zeroSize, block);
- idx->addIncoming(zeroSize, block);
-
- const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, zeroSize, count, "many", block);
- output->addIncoming(array, block);
- BranchInst::Create(move, last, many, block);
-
- block = move;
- const auto mptr = GetElementPtrInst::CreateInBounds(bits, {idx}, "mptr", block);
- const auto load = new LoadInst(mptr, "load", block);
-
- const auto six = BinaryOperator::CreateAdd(one, ConstantInt::get(one->getType(), 64), "six", block);
- const auto inc = BinaryOperator::CreateAdd(idx, plusSize, "inc", block);
-
- const auto mask = PHINode::Create(load->getType(), 3U, "mask", bulk);
- const auto one0 = PHINode::Create(one->getType(), 3U, "one0", bulk);
- const auto two0 = PHINode::Create(two->getType(), 3U, "two0", bulk);
-
- mask->addIncoming(load, block);
- one0->addIncoming(one, block);
- two0->addIncoming(two, block);
-
- BranchInst::Create(bulk, block);
-
- block = bulk;
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zeroMask, mask, "skip", block);
-
- one->addIncoming(six, block);
- two->addIncoming(two0, block);
- idx->addIncoming(inc, block);
- BranchInst::Create(move, work, skip, block);
-
- block = work;
-
- const auto plus = BinaryOperator::CreateAdd(one0, plusSize, "plus", block);
- const auto down = BinaryOperator::CreateLShr(mask, plusMask, "down", block);
- const auto bit = CastInst::Create(Instruction::Trunc, mask, Type::getInt1Ty(context), "bit", block);
-
- mask->addIncoming(down, block);
- one0->addIncoming(plus, block);
- two0->addIncoming(two0, block);
-
- BranchInst::Create(copy, bulk, bit, block);
-
- block = copy;
-
- const auto src = GetElementPtrInst::CreateInBounds(elements, {one0}, "src", block);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {two0}, "dst", block);
-
- const auto item = new LoadInst(src, "item", block);
- ValueAddRef(Item->GetRepresentation(), item, ctx, block);
- new StoreInst(item, dst, block);
-
- const auto next = BinaryOperator::CreateAdd(two0, plusSize, "next", block);
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, next, count, "more", block);
-
- one0->addIncoming(plus, block);
- two0->addIncoming(next, block);
- mask->addIncoming(down, block);
-
- output->addIncoming(array, block);
-
- BranchInst::Create(bulk, last, more, block);
- block = last;
-
- out->addIncoming(output, block);
- BranchInst::Create(free, done, heap, block);
-
- {
- block = free;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {bits->getType(), shr->getType()}, false);
- const auto name = "MyFree";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyFree));
+ const auto ptr = CallInst::Create(func, {shr}, "ptr", block);
+ bits->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ block = main;
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto save = BasicBlock::Create(context, "save", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto last = BasicBlock::Create(context, "last", ctx.Func);
+ const auto free = BasicBlock::Create(context, "free", ctx.Func);
+
+ const auto output = PHINode::Create(out->getType(), 3U, "output", last);
+ const auto index = PHINode::Create(size->getType(), 3U, "index", loop);
+ const auto count = PHINode::Create(size->getType(), 3U, "count", loop);
+ const auto bitset = PHINode::Create(maskType, 3U, "bitset", loop);
+
+ count->addIncoming(zeroSize, block);
+ index->addIncoming(zeroSize, block);
+ bitset->addIncoming(zeroMask, block);
+
+ BranchInst::Create(loop, block);
+
+ {
+ block = loop;
+
+ const auto plus = BinaryOperator::CreateAdd(index, plusSize, "plus", block);
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, plus, size, "more", block);
+ BranchInst::Create(test, stop, more, block);
+
+ block = test;
+
+ const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
+ const auto item = new LoadInst(ptr, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ const auto inc = BinaryOperator::CreateAdd(count, plusSize, "inc", block);
+ const auto mod = BinaryOperator::CreateAnd(index, allBits, "mod", block);
+ const auto bit = BinaryOperator::CreateShl(plusMask, mod, "bit", block);
+ const auto set = BinaryOperator::CreateOr(bitset, bit, "set", block);
+
+ const auto newset = SelectInst::Create(boolPred, set, bitset, "newset", block);
+ const auto newcount = SelectInst::Create(boolPred, inc, count, "newcount", block);
+
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, allBits, "next", block);
+ const auto last = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, plus, size, "last", block);
+ const auto step = BinaryOperator::CreateOr(next, last, "step", block);
+
+ index->addIncoming(plus, block);
+ count->addIncoming(newcount, block);
+ bitset->addIncoming(newset, block);
+ BranchInst::Create(save, loop, step, block);
+
+ block = save;
+ const auto div = BinaryOperator::CreateLShr(index, ConstantInt::get(index->getType(), 6), "div", block);
+ const auto savePtr = GetElementPtrInst::CreateInBounds(bits, {div}, "save_ptr", block);
+ new StoreInst(newset, savePtr, block);
+
+ index->addIncoming(plus, block);
+ count->addIncoming(newcount, block);
+ bitset->addIncoming(zeroMask, block);
+ BranchInst::Create(loop, block);
+ }
+
+ block = stop;
+ const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, count, "asis", block);
+
+ output->addIncoming(list, block);
+ BranchInst::Create(last, make, asis, block);
+
+ block = make;
+
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, count, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto move = BasicBlock::Create(context, "move", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto bulk = BasicBlock::Create(context, "bulk", ctx.Func);
+ const auto copy = BasicBlock::Create(context, "copy", ctx.Func);
+
+ const auto one = PHINode::Create(count->getType(), 2U, "one", move);
+ const auto two = PHINode::Create(count->getType(), 2U, "two", move);
+ const auto idx = PHINode::Create(count->getType(), 2U, "idx", move);
+ one->addIncoming(zeroSize, block);
+ two->addIncoming(zeroSize, block);
+ idx->addIncoming(zeroSize, block);
+
+ const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, zeroSize, count, "many", block);
+ output->addIncoming(array, block);
+ BranchInst::Create(move, last, many, block);
+
+ block = move;
+ const auto mptr = GetElementPtrInst::CreateInBounds(bits, {idx}, "mptr", block);
+ const auto load = new LoadInst(mptr, "load", block);
+
+ const auto six = BinaryOperator::CreateAdd(one, ConstantInt::get(one->getType(), 64), "six", block);
+ const auto inc = BinaryOperator::CreateAdd(idx, plusSize, "inc", block);
+
+ const auto mask = PHINode::Create(load->getType(), 3U, "mask", bulk);
+ const auto one0 = PHINode::Create(one->getType(), 3U, "one0", bulk);
+ const auto two0 = PHINode::Create(two->getType(), 3U, "two0", bulk);
+
+ mask->addIncoming(load, block);
+ one0->addIncoming(one, block);
+ two0->addIncoming(two, block);
+
+ BranchInst::Create(bulk, block);
+
+ block = bulk;
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zeroMask, mask, "skip", block);
+
+ one->addIncoming(six, block);
+ two->addIncoming(two0, block);
+ idx->addIncoming(inc, block);
+ BranchInst::Create(move, work, skip, block);
+
+ block = work;
+
+ const auto plus = BinaryOperator::CreateAdd(one0, plusSize, "plus", block);
+ const auto down = BinaryOperator::CreateLShr(mask, plusMask, "down", block);
+ const auto bit = CastInst::Create(Instruction::Trunc, mask, Type::getInt1Ty(context), "bit", block);
+
+ mask->addIncoming(down, block);
+ one0->addIncoming(plus, block);
+ two0->addIncoming(two0, block);
+
+ BranchInst::Create(copy, bulk, bit, block);
+
+ block = copy;
+
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {one0}, "src", block);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {two0}, "dst", block);
+
+ const auto item = new LoadInst(src, "item", block);
+ ValueAddRef(Item->GetRepresentation(), item, ctx, block);
+ new StoreInst(item, dst, block);
+
+ const auto next = BinaryOperator::CreateAdd(two0, plusSize, "next", block);
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, next, count, "more", block);
+
+ one0->addIncoming(plus, block);
+ two0->addIncoming(next, block);
+ mask->addIncoming(down, block);
+
+ output->addIncoming(array, block);
+
+ BranchInst::Create(bulk, last, more, block);
+ block = last;
+
+ out->addIncoming(output, block);
+ BranchInst::Create(free, done, heap, block);
+
+ {
+ block = free;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {bits->getType(), shr->getType()}, false);
+ const auto name = "MyFree";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyFree));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {bits, shr}, "", block);
-
- out->addIncoming(output, block);
- BranchInst::Create(done, block);
- }
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFilterWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- out->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- out->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return out;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- Own(Item);
- DependsOn(Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFilterWrapper>::GenerateFunctions(codegen);
- FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFilterWrapper>::FinalizeFunctions(codegen);
- if (FilterFunc)
- Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
- }
-#endif
-};
-
-class TListFilterWithLimitWrapper : public TBothWaysCodegeneratorNode<TListFilterWithLimitWrapper>,
- private TBaseFilterWithLimitWrapper<false> {
- typedef TBaseFilterWithLimitWrapper<false> TBaseWrapper;
- typedef TBothWaysCodegeneratorNode<TListFilterWithLimitWrapper> TBaseComputation;
-public:
- TListFilterWithLimitWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, limit, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto limit = Limit->GetValue(ctx).Get<ui64>();
-
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- const auto size = list.GetListLength();
-
- std::array<ui64, UseOnStack> stackBitSet;
- std::unique_ptr<ui64[]> heapBitSet;
-
- const auto maskSize = (size + 63ULL) >> 6ULL;
- const bool useHeap = maskSize > UseOnStack;
-
- if (useHeap) {
- heapBitSet = std::make_unique<ui64[]>(maskSize);
- }
-
- const auto mask = useHeap ? heapBitSet.get() : stackBitSet.data();
-
- ui64 count = 0ULL;
-
- for (ui64 i = 0ULL; i < size && count < limit;) {
- auto& m = mask[i >> 6ULL];
- m = 0ULL;
- for (ui64 bit = 1ULL; bit && i < size && count < limit; bit <<= 1ULL) {
- Item->SetValue(ctx, NUdf::TUnboxedValue(elements[i++]));
- if (Predicate->GetValue(ctx).Get<bool>()) {
- m |= bit;
- ++count;
- }
- }
- }
-
- if (count == size) {
- return list.Release();
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, items);
- for (auto p = mask; count; ++p) {
- const auto cb = count;
- auto e = elements;
- elements += 64ULL;
- for (auto bits = *p; bits; bits >>= 1ULL) {
- if (bits & 1ULL) {
- *items++ = *e;
- if (!--count)
- break;
- }
- ++e;
- }
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), limit, Item, Predicate);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value, ui64 limit) const {
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, value, std::move(limit));
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto limit = GetterFor<ui64>(GetNodeValue(Limit, ctx, block), context, block);
-
- const auto list = GetNodeValue(List, ctx, block);
- const auto out = PHINode::Create(list->getType(), 3U, "out", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
- const auto allBits = ConstantInt::get(size->getType(), 63);
- const auto add = BinaryOperator::CreateAdd(size, allBits, "add", block);
- const auto shr = BinaryOperator::CreateLShr(add, ConstantInt::get(add->getType(), 6), "shr", block);
-
- const auto maskType = Type::getInt64Ty(context);
- const auto zeroMask = ConstantInt::get(maskType, 0);
- const auto plusMask = ConstantInt::get(maskType, 1);
-
- const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
- const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto bits = PHINode::Create(PointerType::getUnqual(maskType), 2U, "bits", main);
-
- const auto zeroSize = ConstantInt::get(size->getType(), 0);
- const auto plusSize = ConstantInt::get(size->getType(), 1);
-
- const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, shr, ConstantInt::get(add->getType(), UseOnStack), "heap", block);
- BranchInst::Create(hmsk, smsk, heap, block);
-
- {
- block = smsk;
-
- const auto arrayType = ArrayType::get(Type::getInt64Ty(context), UseOnStack);
- const auto array = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(arrayType, 0U, "array", block);
- const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
-
- bits->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- {
- block = hmsk;
-
- const auto fnType = FunctionType::get(bits->getType(), {shr->getType()}, false);
- const auto name = "MyAlloc";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyAlloc));
+ CallInst::Create(func, {bits, shr}, "", block);
+
+ out->addIncoming(output, block);
+ BranchInst::Create(done, block);
+ }
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFilterWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ out->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ out->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return out;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ Own(Item);
+ DependsOn(Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFilterWrapper>::GenerateFunctions(codegen);
+ FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(FilterFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFilterWrapper>::FinalizeFunctions(codegen);
+ if (FilterFunc)
+ Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
+ }
+#endif
+};
+
+class TListFilterWithLimitWrapper : public TBothWaysCodegeneratorNode<TListFilterWithLimitWrapper>,
+ private TBaseFilterWithLimitWrapper<false> {
+ typedef TBaseFilterWithLimitWrapper<false> TBaseWrapper;
+ typedef TBothWaysCodegeneratorNode<TListFilterWithLimitWrapper> TBaseComputation;
+public:
+ TListFilterWithLimitWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* limit, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, limit, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto limit = Limit->GetValue(ctx).Get<ui64>();
+
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ const auto size = list.GetListLength();
+
+ std::array<ui64, UseOnStack> stackBitSet;
+ std::unique_ptr<ui64[]> heapBitSet;
+
+ const auto maskSize = (size + 63ULL) >> 6ULL;
+ const bool useHeap = maskSize > UseOnStack;
+
+ if (useHeap) {
+ heapBitSet = std::make_unique<ui64[]>(maskSize);
+ }
+
+ const auto mask = useHeap ? heapBitSet.get() : stackBitSet.data();
+
+ ui64 count = 0ULL;
+
+ for (ui64 i = 0ULL; i < size && count < limit;) {
+ auto& m = mask[i >> 6ULL];
+ m = 0ULL;
+ for (ui64 bit = 1ULL; bit && i < size && count < limit; bit <<= 1ULL) {
+ Item->SetValue(ctx, NUdf::TUnboxedValue(elements[i++]));
+ if (Predicate->GetValue(ctx).Get<bool>()) {
+ m |= bit;
+ ++count;
+ }
+ }
+ }
+
+ if (count == size) {
+ return list.Release();
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, items);
+ for (auto p = mask; count; ++p) {
+ const auto cb = count;
+ auto e = elements;
+ elements += 64ULL;
+ for (auto bits = *p; bits; bits >>= 1ULL) {
+ if (bits & 1ULL) {
+ *items++ = *e;
+ if (!--count)
+ break;
+ }
+ ++e;
+ }
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), limit, Item, Predicate);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value, ui64 limit) const {
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(Filter, &ctx, value, std::move(limit));
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto limit = GetterFor<ui64>(GetNodeValue(Limit, ctx, block), context, block);
+
+ const auto list = GetNodeValue(List, ctx, block);
+ const auto out = PHINode::Create(list->getType(), 3U, "out", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+ const auto allBits = ConstantInt::get(size->getType(), 63);
+ const auto add = BinaryOperator::CreateAdd(size, allBits, "add", block);
+ const auto shr = BinaryOperator::CreateLShr(add, ConstantInt::get(add->getType(), 6), "shr", block);
+
+ const auto maskType = Type::getInt64Ty(context);
+ const auto zeroMask = ConstantInt::get(maskType, 0);
+ const auto plusMask = ConstantInt::get(maskType, 1);
+
+ const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
+ const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto bits = PHINode::Create(PointerType::getUnqual(maskType), 2U, "bits", main);
+
+ const auto zeroSize = ConstantInt::get(size->getType(), 0);
+ const auto plusSize = ConstantInt::get(size->getType(), 1);
+
+ const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, shr, ConstantInt::get(add->getType(), UseOnStack), "heap", block);
+ BranchInst::Create(hmsk, smsk, heap, block);
+
+ {
+ block = smsk;
+
+ const auto arrayType = ArrayType::get(Type::getInt64Ty(context), UseOnStack);
+ const auto array = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(arrayType, 0U, "array", block);
+ const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
+
+ bits->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ {
+ block = hmsk;
+
+ const auto fnType = FunctionType::get(bits->getType(), {shr->getType()}, false);
+ const auto name = "MyAlloc";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyAlloc));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- const auto ptr = CallInst::Create(func, {shr}, "ptr", block);
- bits->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- block = main;
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto save = BasicBlock::Create(context, "save", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto last = BasicBlock::Create(context, "last", ctx.Func);
- const auto free = BasicBlock::Create(context, "free", ctx.Func);
-
- const auto output = PHINode::Create(out->getType(), 3U, "output", last);
- const auto index = PHINode::Create(size->getType(), 3U, "index", loop);
- const auto count = PHINode::Create(size->getType(), 3U, "count", loop);
- const auto bitset = PHINode::Create(maskType, 3U, "bitset", loop);
-
- count->addIncoming(zeroSize, block);
- index->addIncoming(zeroSize, block);
- bitset->addIncoming(zeroMask, block);
-
- BranchInst::Create(loop, block);
-
- {
- block = loop;
-
- const auto plus = BinaryOperator::CreateAdd(index, plusSize, "plus", block);
- const auto less_index = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, plus, size, "less_index", block);
- const auto less_count = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, count, limit, "less_count", block);
- const auto more = BinaryOperator::CreateAnd(less_index, less_count, "more", block);
- BranchInst::Create(test, stop, more, block);
-
- block = test;
-
- const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
- const auto item = new LoadInst(ptr, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto predicate = GetNodeValue(Predicate, ctx, block);
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- const auto inc = BinaryOperator::CreateAdd(count, plusSize, "inc", block);
- const auto mod = BinaryOperator::CreateAnd(index, allBits, "mod", block);
- const auto bit = BinaryOperator::CreateShl(plusMask, mod, "bit", block);
- const auto set = BinaryOperator::CreateOr(bitset, bit, "set", block);
-
- const auto newset = SelectInst::Create(boolPred, set, bitset, "newset", block);
- const auto newcount = SelectInst::Create(boolPred, inc, count, "newcount", block);
-
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, allBits, "next", block);
- const auto last = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, plus, size, "last", block);
- const auto full = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, newcount, limit, "full", block);
- const auto good = BinaryOperator::CreateOr(full, last, "good", block);
- const auto step = BinaryOperator::CreateOr(next, good, "step", block);
-
- index->addIncoming(plus, block);
- count->addIncoming(newcount, block);
- bitset->addIncoming(newset, block);
- BranchInst::Create(save, loop, step, block);
-
- block = save;
- const auto div = BinaryOperator::CreateLShr(index, ConstantInt::get(index->getType(), 6), "div", block);
- const auto savePtr = GetElementPtrInst::CreateInBounds(bits, {div}, "save_ptr", block);
- new StoreInst(newset, savePtr, block);
-
- index->addIncoming(plus, block);
- count->addIncoming(newcount, block);
- bitset->addIncoming(zeroMask, block);
- BranchInst::Create(loop, block);
- }
-
- block = stop;
- const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, count, "asis", block);
-
- output->addIncoming(list, block);
- BranchInst::Create(last, make, asis, block);
-
- block = make;
-
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, count, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto move = BasicBlock::Create(context, "move", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto bulk = BasicBlock::Create(context, "bulk", ctx.Func);
- const auto copy = BasicBlock::Create(context, "copy", ctx.Func);
-
- const auto one = PHINode::Create(count->getType(), 2U, "one", move);
- const auto two = PHINode::Create(count->getType(), 2U, "two", move);
- const auto idx = PHINode::Create(count->getType(), 2U, "idx", move);
- one->addIncoming(zeroSize, block);
- two->addIncoming(zeroSize, block);
- idx->addIncoming(zeroSize, block);
-
- const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, zeroSize, count, "many", block);
- output->addIncoming(array, block);
- BranchInst::Create(move, last, many, block);
-
- block = move;
- const auto mptr = GetElementPtrInst::CreateInBounds(bits, {idx}, "mptr", block);
- const auto load = new LoadInst(mptr, "load", block);
-
- const auto six = BinaryOperator::CreateAdd(one, ConstantInt::get(one->getType(), 64), "six", block);
- const auto inc = BinaryOperator::CreateAdd(idx, plusSize, "inc", block);
-
- const auto mask = PHINode::Create(load->getType(), 3U, "mask", bulk);
- const auto one0 = PHINode::Create(one->getType(), 3U, "one0", bulk);
- const auto two0 = PHINode::Create(two->getType(), 3U, "two0", bulk);
-
- mask->addIncoming(load, block);
- one0->addIncoming(one, block);
- two0->addIncoming(two, block);
-
- BranchInst::Create(bulk, block);
-
- block = bulk;
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zeroMask, mask, "skip", block);
-
- one->addIncoming(six, block);
- two->addIncoming(two0, block);
- idx->addIncoming(inc, block);
- BranchInst::Create(move, work, skip, block);
-
- block = work;
-
- const auto plus = BinaryOperator::CreateAdd(one0, plusSize, "plus", block);
- const auto down = BinaryOperator::CreateLShr(mask, plusMask, "down", block);
- const auto bit = CastInst::Create(Instruction::Trunc, mask, Type::getInt1Ty(context), "bit", block);
-
- mask->addIncoming(down, block);
- one0->addIncoming(plus, block);
- two0->addIncoming(two0, block);
-
- BranchInst::Create(copy, bulk, bit, block);
-
- block = copy;
-
- const auto src = GetElementPtrInst::CreateInBounds(elements, {one0}, "src", block);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {two0}, "dst", block);
-
- const auto item = new LoadInst(src, "item", block);
- ValueAddRef(Item->GetRepresentation(), item, ctx, block);
- new StoreInst(item, dst, block);
-
- const auto next = BinaryOperator::CreateAdd(two0, plusSize, "next", block);
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, next, count, "more", block);
-
- one0->addIncoming(plus, block);
- two0->addIncoming(next, block);
- mask->addIncoming(down, block);
-
- output->addIncoming(array, block);
-
- BranchInst::Create(bulk, last, more, block);
- block = last;
-
- out->addIncoming(output, block);
- BranchInst::Create(free, done, heap, block);
-
- {
- block = free;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {bits->getType(), shr->getType()}, false);
- const auto name = "MyFree";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyFree));
+ const auto ptr = CallInst::Create(func, {shr}, "ptr", block);
+ bits->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ block = main;
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto save = BasicBlock::Create(context, "save", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto last = BasicBlock::Create(context, "last", ctx.Func);
+ const auto free = BasicBlock::Create(context, "free", ctx.Func);
+
+ const auto output = PHINode::Create(out->getType(), 3U, "output", last);
+ const auto index = PHINode::Create(size->getType(), 3U, "index", loop);
+ const auto count = PHINode::Create(size->getType(), 3U, "count", loop);
+ const auto bitset = PHINode::Create(maskType, 3U, "bitset", loop);
+
+ count->addIncoming(zeroSize, block);
+ index->addIncoming(zeroSize, block);
+ bitset->addIncoming(zeroMask, block);
+
+ BranchInst::Create(loop, block);
+
+ {
+ block = loop;
+
+ const auto plus = BinaryOperator::CreateAdd(index, plusSize, "plus", block);
+ const auto less_index = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, plus, size, "less_index", block);
+ const auto less_count = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, count, limit, "less_count", block);
+ const auto more = BinaryOperator::CreateAnd(less_index, less_count, "more", block);
+ BranchInst::Create(test, stop, more, block);
+
+ block = test;
+
+ const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
+ const auto item = new LoadInst(ptr, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ const auto inc = BinaryOperator::CreateAdd(count, plusSize, "inc", block);
+ const auto mod = BinaryOperator::CreateAnd(index, allBits, "mod", block);
+ const auto bit = BinaryOperator::CreateShl(plusMask, mod, "bit", block);
+ const auto set = BinaryOperator::CreateOr(bitset, bit, "set", block);
+
+ const auto newset = SelectInst::Create(boolPred, set, bitset, "newset", block);
+ const auto newcount = SelectInst::Create(boolPred, inc, count, "newcount", block);
+
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, allBits, "next", block);
+ const auto last = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, plus, size, "last", block);
+ const auto full = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, newcount, limit, "full", block);
+ const auto good = BinaryOperator::CreateOr(full, last, "good", block);
+ const auto step = BinaryOperator::CreateOr(next, good, "step", block);
+
+ index->addIncoming(plus, block);
+ count->addIncoming(newcount, block);
+ bitset->addIncoming(newset, block);
+ BranchInst::Create(save, loop, step, block);
+
+ block = save;
+ const auto div = BinaryOperator::CreateLShr(index, ConstantInt::get(index->getType(), 6), "div", block);
+ const auto savePtr = GetElementPtrInst::CreateInBounds(bits, {div}, "save_ptr", block);
+ new StoreInst(newset, savePtr, block);
+
+ index->addIncoming(plus, block);
+ count->addIncoming(newcount, block);
+ bitset->addIncoming(zeroMask, block);
+ BranchInst::Create(loop, block);
+ }
+
+ block = stop;
+ const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, count, "asis", block);
+
+ output->addIncoming(list, block);
+ BranchInst::Create(last, make, asis, block);
+
+ block = make;
+
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, count, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto move = BasicBlock::Create(context, "move", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto bulk = BasicBlock::Create(context, "bulk", ctx.Func);
+ const auto copy = BasicBlock::Create(context, "copy", ctx.Func);
+
+ const auto one = PHINode::Create(count->getType(), 2U, "one", move);
+ const auto two = PHINode::Create(count->getType(), 2U, "two", move);
+ const auto idx = PHINode::Create(count->getType(), 2U, "idx", move);
+ one->addIncoming(zeroSize, block);
+ two->addIncoming(zeroSize, block);
+ idx->addIncoming(zeroSize, block);
+
+ const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, zeroSize, count, "many", block);
+ output->addIncoming(array, block);
+ BranchInst::Create(move, last, many, block);
+
+ block = move;
+ const auto mptr = GetElementPtrInst::CreateInBounds(bits, {idx}, "mptr", block);
+ const auto load = new LoadInst(mptr, "load", block);
+
+ const auto six = BinaryOperator::CreateAdd(one, ConstantInt::get(one->getType(), 64), "six", block);
+ const auto inc = BinaryOperator::CreateAdd(idx, plusSize, "inc", block);
+
+ const auto mask = PHINode::Create(load->getType(), 3U, "mask", bulk);
+ const auto one0 = PHINode::Create(one->getType(), 3U, "one0", bulk);
+ const auto two0 = PHINode::Create(two->getType(), 3U, "two0", bulk);
+
+ mask->addIncoming(load, block);
+ one0->addIncoming(one, block);
+ two0->addIncoming(two, block);
+
+ BranchInst::Create(bulk, block);
+
+ block = bulk;
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zeroMask, mask, "skip", block);
+
+ one->addIncoming(six, block);
+ two->addIncoming(two0, block);
+ idx->addIncoming(inc, block);
+ BranchInst::Create(move, work, skip, block);
+
+ block = work;
+
+ const auto plus = BinaryOperator::CreateAdd(one0, plusSize, "plus", block);
+ const auto down = BinaryOperator::CreateLShr(mask, plusMask, "down", block);
+ const auto bit = CastInst::Create(Instruction::Trunc, mask, Type::getInt1Ty(context), "bit", block);
+
+ mask->addIncoming(down, block);
+ one0->addIncoming(plus, block);
+ two0->addIncoming(two0, block);
+
+ BranchInst::Create(copy, bulk, bit, block);
+
+ block = copy;
+
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {one0}, "src", block);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {two0}, "dst", block);
+
+ const auto item = new LoadInst(src, "item", block);
+ ValueAddRef(Item->GetRepresentation(), item, ctx, block);
+ new StoreInst(item, dst, block);
+
+ const auto next = BinaryOperator::CreateAdd(two0, plusSize, "next", block);
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, next, count, "more", block);
+
+ one0->addIncoming(plus, block);
+ two0->addIncoming(next, block);
+ mask->addIncoming(down, block);
+
+ output->addIncoming(array, block);
+
+ BranchInst::Create(bulk, last, more, block);
+ block = last;
+
+ out->addIncoming(output, block);
+ BranchInst::Create(free, done, heap, block);
+
+ {
+ block = free;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {bits->getType(), shr->getType()}, false);
+ const auto name = "MyFree";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyFree));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {bits, shr}, "", block);
-
- out->addIncoming(output, block);
- BranchInst::Create(done, block);
- }
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFilterWithLimitWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType(), limit->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list, limit}, "value", block);
- out->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType(), limit->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr, limit}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- out->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return out;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Limit);
- Own(Item);
- DependsOn(Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFilterWithLimitWrapper>::GenerateFunctions(codegen);
- FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFilterWithLimitWrapper>::FinalizeFunctions(codegen);
- if (FilterFunc)
- Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
- }
-#endif
-};
-
-}
-
-IComputationNode* WrapFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 3 || callable.GetInputsCount() == 4, "Expected 3 or 4 args");
- const auto type = callable.GetType()->GetReturnType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
-
- if (callable.GetInputsCount() == 3) {
- const auto predicate = LocateNode(ctx.NodeLocator, callable, 2);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
-
- if (type->IsFlow()) {
- return new TFilterFlowWrapper(GetValueRepresentation(type), flow, itemArg, predicate);
- } else if (type->IsStream()) {
- return new TStreamFilterWrapper(ctx.Mutables, flow, itemArg, predicate);
- } else if (type->IsList()) {
- return new TListFilterWrapper(ctx.Mutables, flow, itemArg, predicate);
- }
- } else {
- const auto limit = LocateNode(ctx.NodeLocator, callable, 1);
- const auto predicate = LocateNode(ctx.NodeLocator, callable, 3);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
-
- if (type->IsFlow()) {
- return new TFilterWithLimitFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, limit, itemArg, predicate);
- } else if (type->IsStream()) {
- return new TStreamFilterWithLimitWrapper(ctx.Mutables, flow, limit, itemArg, predicate);
- } else if (type->IsList()) {
- return new TListFilterWithLimitWrapper(ctx.Mutables, flow, limit, itemArg, predicate);
- }
+ CallInst::Create(func, {bits, shr}, "", block);
+
+ out->addIncoming(output, block);
+ BranchInst::Create(done, block);
+ }
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFilterWithLimitWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType(), limit->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list, limit}, "value", block);
+ out->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType(), limit->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr, limit}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ out->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return out;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Limit);
+ Own(Item);
+ DependsOn(Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFilterWithLimitWrapper>::GenerateFunctions(codegen);
+ FilterFunc = GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(FilterFunc);
}
-
- THROW yexception() << "Expected flow, list or stream.";
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFilterWithLimitWrapper>::FinalizeFunctions(codegen);
+ if (FilterFunc)
+ Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(FilterFunc));
+ }
+#endif
+};
+
+}
+
+IComputationNode* WrapFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 3 || callable.GetInputsCount() == 4, "Expected 3 or 4 args");
+ const auto type = callable.GetType()->GetReturnType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+
+ if (callable.GetInputsCount() == 3) {
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+
+ if (type->IsFlow()) {
+ return new TFilterFlowWrapper(GetValueRepresentation(type), flow, itemArg, predicate);
+ } else if (type->IsStream()) {
+ return new TStreamFilterWrapper(ctx.Mutables, flow, itemArg, predicate);
+ } else if (type->IsList()) {
+ return new TListFilterWrapper(ctx.Mutables, flow, itemArg, predicate);
+ }
+ } else {
+ const auto limit = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
+
+ if (type->IsFlow()) {
+ return new TFilterWithLimitFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, limit, itemArg, predicate);
+ } else if (type->IsStream()) {
+ return new TStreamFilterWithLimitWrapper(ctx.Mutables, flow, limit, itemArg, predicate);
+ } else if (type->IsList()) {
+ return new TListFilterWithLimitWrapper(ctx.Mutables, flow, limit, itemArg, predicate);
+ }
+ }
+
+ THROW yexception() << "Expected flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.cpp
index fe1907ee33..a9d49e109d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.cpp
@@ -9,953 +9,953 @@ namespace NMiniKQL {
using NYql::EnsureDynamicCast;
-namespace {
-
-class TFlowFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFlowFlatMapFlowWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowFlatMapFlowWrapper>;
-public:
- TFlowFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* input, IComputationNode* output)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Input(input), Output(output)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.Release();
- } else {
- state = NUdf::TUnboxedValuePod();
- Input->SetValue(ctx, std::move(item));
- }
- }
-
- while (true) {
- if (auto output = Output->GetValue(ctx); output.IsFinish()) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- state = NUdf::TUnboxedValuePod::Invalid();
- return item.Release();
- } else {
- state = NUdf::TUnboxedValuePod();
- Input->SetValue(ctx, std::move(item));
- }
- } else {
- return output.Release();
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+namespace {
+
+class TFlowFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TFlowFlatMapFlowWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowFlatMapFlowWrapper>;
+public:
+ TFlowFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* input, IComputationNode* output)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Input(input), Output(output)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.Release();
+ } else {
+ state = NUdf::TUnboxedValuePod();
+ Input->SetValue(ctx, std::move(item));
+ }
+ }
+
+ while (true) {
+ if (auto output = Output->GetValue(ctx); output.IsFinish()) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ state = NUdf::TUnboxedValuePod::Invalid();
+ return item.Release();
+ } else {
+ state = NUdf::TUnboxedValuePod();
+ Input->SetValue(ctx, std::move(item));
+ }
+ } else {
+ return output.Release();
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
MKQL_ENSURE(codegenInput, "Input must be codegenerator node.");
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", exit);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
-
- BranchInst::Create(init, work, reset, block);
-
- block = init;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(exit, next, IsSpecial(item, block), block);
-
- block = next;
-
- new StoreInst(GetEmpty(context), statePtr, block);
- codegenInput->CreateSetValue(ctx, block, item);
-
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto output = GetNodeValue(Output, ctx, block);
-
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, output, GetFinish(context), "finish", block);
- result->addIncoming(output, block);
- BranchInst::Create(step, exit, finish, block);
-
- block = step;
-
- new StoreInst(GetInvalid(context), statePtr, block);
- BranchInst::Create(init, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Input);
- DependsOn(flow, Output);
- }
- Input->AddDependence(Output->GetSource());
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Input;
- IComputationNode* const Output;
-};
-
-class TFlowFlatMapWideWrapper : public TStatefulWideFlowCodegeneratorNode<TFlowFlatMapWideWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TFlowFlatMapWideWrapper>;
-public:
- TFlowFlatMapWideWrapper(TComputationMutables& mutables, IComputationNode* flow, IComputationExternalNode* input, IComputationWideFlowNode* output)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Input(input), Output(output)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.IsFinish() ? EFetchResult::Finish : EFetchResult::Yield;
- } else {
- state = NUdf::TUnboxedValuePod();
- Input->SetValue(ctx, std::move(item));
- }
- }
-
- while (true) {
- if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish != result)
- return result;
- else if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- state = NUdf::TUnboxedValuePod::Invalid();
- return item.IsFinish() ? EFetchResult::Finish : EFetchResult::Yield;
- } else {
- state = NUdf::TUnboxedValuePod();
- Input->SetValue(ctx, std::move(item));
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", exit);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
+
+ BranchInst::Create(init, work, reset, block);
+
+ block = init;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(exit, next, IsSpecial(item, block), block);
+
+ block = next;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+ codegenInput->CreateSetValue(ctx, block, item);
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto output = GetNodeValue(Output, ctx, block);
+
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, output, GetFinish(context), "finish", block);
+ result->addIncoming(output, block);
+ BranchInst::Create(step, exit, finish, block);
+
+ block = step;
+
+ new StoreInst(GetInvalid(context), statePtr, block);
+ BranchInst::Create(init, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Input);
+ DependsOn(flow, Output);
+ }
+ Input->AddDependence(Output->GetSource());
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Input;
+ IComputationNode* const Output;
+};
+
+class TFlowFlatMapWideWrapper : public TStatefulWideFlowCodegeneratorNode<TFlowFlatMapWideWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TFlowFlatMapWideWrapper>;
+public:
+ TFlowFlatMapWideWrapper(TComputationMutables& mutables, IComputationNode* flow, IComputationExternalNode* input, IComputationWideFlowNode* output)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Input(input), Output(output)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.IsFinish() ? EFetchResult::Finish : EFetchResult::Yield;
+ } else {
+ state = NUdf::TUnboxedValuePod();
+ Input->SetValue(ctx, std::move(item));
+ }
+ }
+
+ while (true) {
+ if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish != result)
+ return result;
+ else if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ state = NUdf::TUnboxedValuePod::Invalid();
+ return item.IsFinish() ? EFetchResult::Finish : EFetchResult::Yield;
+ } else {
+ state = NUdf::TUnboxedValuePod();
+ Input->SetValue(ctx, std::move(item));
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
MKQL_ENSURE(codegenInput, "Input must be codegenerator node.");
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 2U, "result", exit);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
-
- BranchInst::Create(init, work, reset, block);
-
- block = init;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- const auto outres = SelectInst::Create(IsFinish(item, block), ConstantInt::get(resultType, i32(EFetchResult::Finish)), ConstantInt::get(resultType, i32(EFetchResult::Yield)), "outres", block);
- result->addIncoming(outres, block);
- BranchInst::Create(exit, next, IsSpecial(item, block), block);
-
- block = next;
-
- new StoreInst(GetEmpty(context), statePtr, block);
- codegenInput->CreateSetValue(ctx, block, item);
-
- BranchInst::Create(work, block);
-
- block = work;
-
- auto output = GetNodeValues(Output, ctx, block);
-
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, output.first, ConstantInt::get(resultType, 0), "finish", block);
- result->addIncoming(output.first, block);
- BranchInst::Create(step, exit, finish, block);
-
- block = step;
-
- new StoreInst(GetInvalid(context), statePtr, block);
- BranchInst::Create(init, block);
-
- block = exit;
- return {result, std::move(output.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Input);
- DependsOn(flow, Output);
- }
- Input->AddDependence(Output->GetSource());
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Input;
- IComputationWideFlowNode* const Output;
-};
-
-class TListFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TListFlatMapFlowWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TListFlatMapFlowWrapper>;
-public:
- TListFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* input, IComputationNode* output)
- : TBaseComputation(mutables, output, kind, EValueRepresentation::Boxed), List(list), Input(input), Output(output)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- state = List->GetValue(ctx).GetListIterator();
-
- if (!state.Next(Input->RefValue(ctx))) {
- state = NUdf::TUnboxedValuePod::MakeFinish();
- }
- }
-
- if (state.IsFinish()) {
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
- while (true) {
- if (auto output = Output->GetValue(ctx); output.IsFinish()) {
- if (state.Next(Input->RefValue(ctx))) {
- continue;
- }
-
- return state = NUdf::TUnboxedValuePod::MakeFinish();
- } else {
- return output.Release();
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 2U, "result", exit);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
+
+ BranchInst::Create(init, work, reset, block);
+
+ block = init;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ const auto outres = SelectInst::Create(IsFinish(item, block), ConstantInt::get(resultType, i32(EFetchResult::Finish)), ConstantInt::get(resultType, i32(EFetchResult::Yield)), "outres", block);
+ result->addIncoming(outres, block);
+ BranchInst::Create(exit, next, IsSpecial(item, block), block);
+
+ block = next;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+ codegenInput->CreateSetValue(ctx, block, item);
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ auto output = GetNodeValues(Output, ctx, block);
+
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, output.first, ConstantInt::get(resultType, 0), "finish", block);
+ result->addIncoming(output.first, block);
+ BranchInst::Create(step, exit, finish, block);
+
+ block = step;
+
+ new StoreInst(GetInvalid(context), statePtr, block);
+ BranchInst::Create(init, block);
+
+ block = exit;
+ return {result, std::move(output.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Input);
+ DependsOn(flow, Output);
+ }
+ Input->AddDependence(Output->GetSource());
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Input;
+ IComputationWideFlowNode* const Output;
+};
+
+class TListFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TListFlatMapFlowWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TListFlatMapFlowWrapper>;
+public:
+ TListFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* input, IComputationNode* output)
+ : TBaseComputation(mutables, output, kind, EValueRepresentation::Boxed), List(list), Input(input), Output(output)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ state = List->GetValue(ctx).GetListIterator();
+
+ if (!state.Next(Input->RefValue(ctx))) {
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ }
+ }
+
+ if (state.IsFinish()) {
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+ while (true) {
+ if (auto output = Output->GetValue(ctx); output.IsFinish()) {
+ if (state.Next(Input->RefValue(ctx))) {
+ continue;
+ }
+
+ return state = NUdf::TUnboxedValuePod::MakeFinish();
+ } else {
+ return output.Release();
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
MKQL_ENSURE(codegenInput, "Input must be codegenerator node.");
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 3U, "result", exit);
- result->addIncoming(GetFinish(context), block);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto choise = SwitchInst::Create(state, work, 2U, block);
- choise->addCase(GetInvalid(context), init);
- choise->addCase(GetFinish(context), exit);
-
- block = init;
-
- const auto list = GetNodeValue(List, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
-
- BranchInst::Create(next, block);
-
- block = next;
-
- const auto iterator = new LoadInst(statePtr, "iterator", block);
- const auto itemPtr = codegenInput->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iterator, ctx.Codegen, block, itemPtr);
- BranchInst::Create(work, done, status, block);
-
- block = work;
-
- const auto output = GetNodeValue(Output, ctx, block);
- result->addIncoming(output, block);
- BranchInst::Create(next, exit, IsFinish(output, block), block);
-
- block = done;
-
- UnRefBoxed(iterator, ctx, block);
- new StoreInst(GetFinish(context), statePtr, block);
- result->addIncoming(GetFinish(context), block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(List)) {
- Own(flow, Input);
- DependsOn(flow, Output);
- }
- Input->AddDependence(Output->GetSource());
- }
-
- IComputationNode* const List;
- IComputationExternalNode* const Input;
- IComputationNode* const Output;
-};
-
-class TListFlatMapWideWrapper : public TStatefulWideFlowCodegeneratorNode<TListFlatMapWideWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TListFlatMapWideWrapper>;
-public:
- TListFlatMapWideWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* input, IComputationWideFlowNode* output)
- : TBaseComputation(mutables, output, EValueRepresentation::Boxed), List(list), Input(input), Output(output)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = List->GetValue(ctx).GetListIterator();
-
- if (!state.Next(Input->RefValue(ctx))) {
- state = NUdf::TUnboxedValuePod::MakeFinish();
- }
- }
-
- if (state.IsFinish()) {
- return EFetchResult::Finish;
- }
-
- while (true) {
- if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish != result)
- return result;
- else if (state.Next(Input->RefValue(ctx)))
- continue;
-
- state = NUdf::TUnboxedValuePod::MakeFinish();
- return EFetchResult::Finish;
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 3U, "result", exit);
+ result->addIncoming(GetFinish(context), block);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto choise = SwitchInst::Create(state, work, 2U, block);
+ choise->addCase(GetInvalid(context), init);
+ choise->addCase(GetFinish(context), exit);
+
+ block = init;
+
+ const auto list = GetNodeValue(List, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+
+ BranchInst::Create(next, block);
+
+ block = next;
+
+ const auto iterator = new LoadInst(statePtr, "iterator", block);
+ const auto itemPtr = codegenInput->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iterator, ctx.Codegen, block, itemPtr);
+ BranchInst::Create(work, done, status, block);
+
+ block = work;
+
+ const auto output = GetNodeValue(Output, ctx, block);
+ result->addIncoming(output, block);
+ BranchInst::Create(next, exit, IsFinish(output, block), block);
+
+ block = done;
+
+ UnRefBoxed(iterator, ctx, block);
+ new StoreInst(GetFinish(context), statePtr, block);
+ result->addIncoming(GetFinish(context), block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(List)) {
+ Own(flow, Input);
+ DependsOn(flow, Output);
+ }
+ Input->AddDependence(Output->GetSource());
+ }
+
+ IComputationNode* const List;
+ IComputationExternalNode* const Input;
+ IComputationNode* const Output;
+};
+
+class TListFlatMapWideWrapper : public TStatefulWideFlowCodegeneratorNode<TListFlatMapWideWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TListFlatMapWideWrapper>;
+public:
+ TListFlatMapWideWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* input, IComputationWideFlowNode* output)
+ : TBaseComputation(mutables, output, EValueRepresentation::Boxed), List(list), Input(input), Output(output)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = List->GetValue(ctx).GetListIterator();
+
+ if (!state.Next(Input->RefValue(ctx))) {
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ }
+ }
+
+ if (state.IsFinish()) {
+ return EFetchResult::Finish;
+ }
+
+ while (true) {
+ if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish != result)
+ return result;
+ else if (state.Next(Input->RefValue(ctx)))
+ continue;
+
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ return EFetchResult::Finish;
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ const auto codegenInput = dynamic_cast<ICodegeneratorExternalNode*>(Input);
MKQL_ENSURE(codegenInput, "Input must be codegenerator node.");
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 3U, "result", exit);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto choise = SwitchInst::Create(state, work, 2U, block);
- choise->addCase(GetInvalid(context), init);
- choise->addCase(GetFinish(context), exit);
-
- block = init;
-
- const auto list = GetNodeValue(List, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
-
- BranchInst::Create(next, block);
-
- block = next;
-
- const auto iterator = new LoadInst(statePtr, "iterator", block);
- const auto itemPtr = codegenInput->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iterator, ctx.Codegen, block, itemPtr);
- BranchInst::Create(work, done, status, block);
-
- block = work;
-
- auto output = GetNodeValues(Output, ctx, block);
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, output.first, ConstantInt::get(resultType, 0), "finish", block);
- result->addIncoming(output.first, block);
- BranchInst::Create(next, exit, finish, block);
-
- block = done;
-
- UnRefBoxed(iterator, ctx, block);
- new StoreInst(GetFinish(context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return {result, std::move(output.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(List)) {
- Own(flow, Input);
- DependsOn(flow, Output);
- }
- Input->AddDependence(Output->GetSource());
- }
-
- IComputationNode* const List;
- IComputationExternalNode* const Input;
- IComputationWideFlowNode* const Output;
-};
-
-class TNarrowFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TNarrowFlatMapFlowWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TNarrowFlatMapFlowWrapper>;
-public:
- TNarrowFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* output)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Items(std::move(items)), Output(output), Fields(Items.size(), nullptr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- default:
- state = NUdf::TUnboxedValuePod();
- }
- }
-
- while (true) {
- if (auto output = Output->GetValue(ctx); output.IsFinish()) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- default:
- state = NUdf::TUnboxedValuePod();
- }
- } else {
- return output.Release();
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", exit);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
-
- BranchInst::Create(init, work, reset, block);
-
- block = init;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
-
- const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
-
- result->addIncoming(outres, block);
- BranchInst::Create(next, exit, good, block);
-
- block = next;
-
- new StoreInst(GetEmpty(context), statePtr, block);
-
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 3U, "result", exit);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto choise = SwitchInst::Create(state, work, 2U, block);
+ choise->addCase(GetInvalid(context), init);
+ choise->addCase(GetFinish(context), exit);
+
+ block = init;
+
+ const auto list = GetNodeValue(List, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+
+ BranchInst::Create(next, block);
+
+ block = next;
+
+ const auto iterator = new LoadInst(statePtr, "iterator", block);
+ const auto itemPtr = codegenInput->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iterator, ctx.Codegen, block, itemPtr);
+ BranchInst::Create(work, done, status, block);
+
+ block = work;
+
+ auto output = GetNodeValues(Output, ctx, block);
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, output.first, ConstantInt::get(resultType, 0), "finish", block);
+ result->addIncoming(output.first, block);
+ BranchInst::Create(next, exit, finish, block);
+
+ block = done;
+
+ UnRefBoxed(iterator, ctx, block);
+ new StoreInst(GetFinish(context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return {result, std::move(output.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(List)) {
+ Own(flow, Input);
+ DependsOn(flow, Output);
+ }
+ Input->AddDependence(Output->GetSource());
+ }
+
+ IComputationNode* const List;
+ IComputationExternalNode* const Input;
+ IComputationWideFlowNode* const Output;
+};
+
+class TNarrowFlatMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TNarrowFlatMapFlowWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TNarrowFlatMapFlowWrapper>;
+public:
+ TNarrowFlatMapFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* output)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Items(std::move(items)), Output(output), Fields(Items.size(), nullptr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ default:
+ state = NUdf::TUnboxedValuePod();
+ }
+ }
+
+ while (true) {
+ if (auto output = Output->GetValue(ctx); output.IsFinish()) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ default:
+ state = NUdf::TUnboxedValuePod();
+ }
+ } else {
+ return output.Release();
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", exit);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto reset = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetInvalid(context), "reset", block);
+
+ BranchInst::Create(init, work, reset, block);
+
+ block = init;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
+
+ const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
+
+ result->addIncoming(outres, block);
+ BranchInst::Create(next, exit, good, block);
+
+ block = next;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
-
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto output = GetNodeValue(Output, ctx, block);
-
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, output, GetFinish(context), "finish", block);
- result->addIncoming(output, block);
- BranchInst::Create(step, exit, finish, block);
-
- block = step;
-
- new StoreInst(GetInvalid(context), statePtr, block);
- BranchInst::Create(init, block);
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowFlatMapFlowWrapper::Own, flow, std::placeholders::_1));
- DependsOn(flow, Output);
- }
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&IComputationNode::AddDependence, std::placeholders::_1, Output->GetSource()));
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const Output;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-template <bool IsMultiRowPerItem, bool ResultContainerOpt>
-class TFlowFlatMapWrapper : public std::conditional_t<IsMultiRowPerItem,
- TStatefulFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- TStatelessFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>> {
-using TBaseComputation = std::conditional_t<IsMultiRowPerItem,
- TStatefulFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- TStatelessFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>>;
-public:
- TFlowFlatMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(mutables, flow, kind), Flow(flow), Item(item), NewItem(newItem)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- while (true) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.Release();
- } else {
- Item->SetValue(ctx, std::move(item));
- }
-
- if (auto newItem = NewItem->GetValue(ctx)) {
- return newItem.Release().GetOptionalValueIf<!IsMultiRowPerItem && ResultContainerOpt>();
- }
- }
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- while (!state.IsFinish()) {
- if (state.HasValue()) {
- if constexpr (ResultContainerOpt) {
- switch (NUdf::TUnboxedValue result; state.Fetch(result)) {
- case NUdf::EFetchStatus::Finish: break;
- case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
- case NUdf::EFetchStatus::Ok: return result.Release();
- }
- } else if (NUdf::TUnboxedValue result; state.Next(result)) {
- return result.Release();
- }
- state.Clear();
- }
-
- NUdf::TUnboxedValue item = DoCalculate(ctx);
- if (item.IsSpecial()) {
- return item.Release();
- } else {
- state = ResultContainerOpt ? std::move(item) : item.GetListIterator();
- }
- }
-
- return state;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(item->getType(), 2, "result", exit);
-
- result->addIncoming(item, block);
- BranchInst::Create(exit, work, IsSpecial(item, block), block);
-
- block = work;
- codegenItem->CreateSetValue(ctx, block, item);
- const auto value = GetNodeValue(NewItem, ctx, block);
- result->addIncoming(!IsMultiRowPerItem && ResultContainerOpt ? GetOptionalValue(context, value, block) : value, block);
- BranchInst::Create(loop, exit, IsEmpty(value, block), block);
-
- block = exit;
- return result;
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto statusType = Type::getInt32Ty(context);
- const auto valueType = Type::getInt128Ty(context);
- const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, ResultContainerOpt ? 3U : 2U, "result", over);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto current = new LoadInst(currentPtr, "current", block);
- BranchInst::Create(pull, skip, HasValue(current, block), block);
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- block = pull;
-
- if constexpr (ResultContainerOpt) {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
-
- result->addIncoming(GetYield(context), block);
- const auto choise = SwitchInst::Create(status, good, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
- } else {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
- BranchInst::Create(good, next, status, block);
- }
-
- block = good;
- const auto value = new LoadInst(valuePtr, "value", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
- result->addIncoming(value, block);
- BranchInst::Create(over, block);
-
- block = next;
- UnRefBoxed(current, ctx, block);
- new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
- BranchInst::Create(skip, block);
- }
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- block = skip;
-
- const auto list = DoGenerateGetValue(ctx, block);
- result->addIncoming(list, block);
- BranchInst::Create(over, good, IsSpecial(list, block), block);
-
- block = good;
- if constexpr (ResultContainerOpt) {
- new StoreInst(list, currentPtr, block);
- AddRefBoxed(list, ctx, block);
- } else {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
- if (NewItem->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- }
- BranchInst::Create(more, block);
- }
-
- block = over;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(this->Flow)) {
- this->Own(flow, this->Item);
- this->DependsOn(flow, this->NewItem);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-};
-
-template <bool IsMultiRowPerItem, bool ResultContainerOpt>
-class TNarrowFlatMapWrapper : public std::conditional_t<IsMultiRowPerItem,
- TStatefulFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- TStatelessFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>> {
-using TBaseComputation = std::conditional_t<IsMultiRowPerItem,
- TStatefulFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- TStatelessFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>>;
-public:
- TNarrowFlatMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, const TComputationExternalNodePtrVector&& items, IComputationNode* newItem)
- : TBaseComputation(mutables, flow, kind), Flow(flow), Items(std::move(items)), NewItem(newItem)
- , PasstroughItem(GetPasstroughtMap({NewItem}, Items).front()), Fields(Items.size(), nullptr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- while (true) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (NewItem == Items[i] || Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- case EFetchResult::One:
- break;
- }
-
- if (auto newItem = NewItem->GetValue(ctx)) {
- return newItem.Release().GetOptionalValueIf<!IsMultiRowPerItem && ResultContainerOpt>();
- }
- }
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- while (!state.IsFinish()) {
- if (state.HasValue()) {
- if constexpr (ResultContainerOpt) {
- switch (NUdf::TUnboxedValue result; state.Fetch(result)) {
- case NUdf::EFetchStatus::Finish: break;
- case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
- case NUdf::EFetchStatus::Ok: return result.Release();
- }
- } else if (NUdf::TUnboxedValue result; state.Next(result)) {
- return result.Release();
- }
- state.Clear();
- }
-
- NUdf::TUnboxedValue item = DoCalculate(ctx);
- if (item.IsSpecial()) {
- return item.Release();
- } else {
- state = ResultContainerOpt ? std::move(item) : item.GetListIterator();
- }
- }
-
- return state;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(Type::getInt128Ty(context), 2, "result", exit);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
-
- const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
-
-
- result->addIncoming(outres, block);
- BranchInst::Create(work, exit, good, block);
-
- block = work;
-
- Value* value = nullptr;
- if (const auto passtrough = PasstroughItem) {
- value = getres.second[*passtrough](ctx, block);
- } else {
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto output = GetNodeValue(Output, ctx, block);
+
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, output, GetFinish(context), "finish", block);
+ result->addIncoming(output, block);
+ BranchInst::Create(step, exit, finish, block);
+
+ block = step;
+
+ new StoreInst(GetInvalid(context), statePtr, block);
+ BranchInst::Create(init, block);
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowFlatMapFlowWrapper::Own, flow, std::placeholders::_1));
+ DependsOn(flow, Output);
+ }
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&IComputationNode::AddDependence, std::placeholders::_1, Output->GetSource()));
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const Output;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+template <bool IsMultiRowPerItem, bool ResultContainerOpt>
+class TFlowFlatMapWrapper : public std::conditional_t<IsMultiRowPerItem,
+ TStatefulFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ TStatelessFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>> {
+using TBaseComputation = std::conditional_t<IsMultiRowPerItem,
+ TStatefulFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ TStatelessFlowCodegeneratorNode<TFlowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>>;
+public:
+ TFlowFlatMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(mutables, flow, kind), Flow(flow), Item(item), NewItem(newItem)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ while (true) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.Release();
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ }
+
+ if (auto newItem = NewItem->GetValue(ctx)) {
+ return newItem.Release().GetOptionalValueIf<!IsMultiRowPerItem && ResultContainerOpt>();
+ }
+ }
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ while (!state.IsFinish()) {
+ if (state.HasValue()) {
+ if constexpr (ResultContainerOpt) {
+ switch (NUdf::TUnboxedValue result; state.Fetch(result)) {
+ case NUdf::EFetchStatus::Finish: break;
+ case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
+ case NUdf::EFetchStatus::Ok: return result.Release();
+ }
+ } else if (NUdf::TUnboxedValue result; state.Next(result)) {
+ return result.Release();
+ }
+ state.Clear();
+ }
+
+ NUdf::TUnboxedValue item = DoCalculate(ctx);
+ if (item.IsSpecial()) {
+ return item.Release();
+ } else {
+ state = ResultContainerOpt ? std::move(item) : item.GetListIterator();
+ }
+ }
+
+ return state;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(item->getType(), 2, "result", exit);
+
+ result->addIncoming(item, block);
+ BranchInst::Create(exit, work, IsSpecial(item, block), block);
+
+ block = work;
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto value = GetNodeValue(NewItem, ctx, block);
+ result->addIncoming(!IsMultiRowPerItem && ResultContainerOpt ? GetOptionalValue(context, value, block) : value, block);
+ BranchInst::Create(loop, exit, IsEmpty(value, block), block);
+
+ block = exit;
+ return result;
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto statusType = Type::getInt32Ty(context);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, ResultContainerOpt ? 3U : 2U, "result", over);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto current = new LoadInst(currentPtr, "current", block);
+ BranchInst::Create(pull, skip, HasValue(current, block), block);
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ block = pull;
+
+ if constexpr (ResultContainerOpt) {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
+
+ result->addIncoming(GetYield(context), block);
+ const auto choise = SwitchInst::Create(status, good, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
+ } else {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
+ BranchInst::Create(good, next, status, block);
+ }
+
+ block = good;
+ const auto value = new LoadInst(valuePtr, "value", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
+ result->addIncoming(value, block);
+ BranchInst::Create(over, block);
+
+ block = next;
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
+ BranchInst::Create(skip, block);
+ }
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ block = skip;
+
+ const auto list = DoGenerateGetValue(ctx, block);
+ result->addIncoming(list, block);
+ BranchInst::Create(over, good, IsSpecial(list, block), block);
+
+ block = good;
+ if constexpr (ResultContainerOpt) {
+ new StoreInst(list, currentPtr, block);
+ AddRefBoxed(list, ctx, block);
+ } else {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
+ if (NewItem->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ }
+ BranchInst::Create(more, block);
+ }
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(this->Flow)) {
+ this->Own(flow, this->Item);
+ this->DependsOn(flow, this->NewItem);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+};
+
+template <bool IsMultiRowPerItem, bool ResultContainerOpt>
+class TNarrowFlatMapWrapper : public std::conditional_t<IsMultiRowPerItem,
+ TStatefulFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ TStatelessFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>> {
+using TBaseComputation = std::conditional_t<IsMultiRowPerItem,
+ TStatefulFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ TStatelessFlowCodegeneratorNode<TNarrowFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>>;
+public:
+ TNarrowFlatMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, const TComputationExternalNodePtrVector&& items, IComputationNode* newItem)
+ : TBaseComputation(mutables, flow, kind), Flow(flow), Items(std::move(items)), NewItem(newItem)
+ , PasstroughItem(GetPasstroughtMap({NewItem}, Items).front()), Fields(Items.size(), nullptr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ while (true) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (NewItem == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ case EFetchResult::One:
+ break;
+ }
+
+ if (auto newItem = NewItem->GetValue(ctx)) {
+ return newItem.Release().GetOptionalValueIf<!IsMultiRowPerItem && ResultContainerOpt>();
+ }
+ }
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ while (!state.IsFinish()) {
+ if (state.HasValue()) {
+ if constexpr (ResultContainerOpt) {
+ switch (NUdf::TUnboxedValue result; state.Fetch(result)) {
+ case NUdf::EFetchStatus::Finish: break;
+ case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
+ case NUdf::EFetchStatus::Ok: return result.Release();
+ }
+ } else if (NUdf::TUnboxedValue result; state.Next(result)) {
+ return result.Release();
+ }
+ state.Clear();
+ }
+
+ NUdf::TUnboxedValue item = DoCalculate(ctx);
+ if (item.IsSpecial()) {
+ return item.Release();
+ } else {
+ state = ResultContainerOpt ? std::move(item) : item.GetListIterator();
+ }
+ }
+
+ return state;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 2, "result", exit);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
+
+ const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
+
+
+ result->addIncoming(outres, block);
+ BranchInst::Create(work, exit, good, block);
+
+ block = work;
+
+ Value* value = nullptr;
+ if (const auto passtrough = PasstroughItem) {
+ value = getres.second[*passtrough](ctx, block);
+ } else {
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
-
- value = GetNodeValue(NewItem, ctx, block);
- }
-
- result->addIncoming(!IsMultiRowPerItem && ResultContainerOpt ? GetOptionalValue(context, value, block) : value, block);
- BranchInst::Create(loop, exit, IsEmpty(value, block), block);
-
- block = exit;
- return result;
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto statusType = Type::getInt32Ty(context);
- const auto valueType = Type::getInt128Ty(context);
- const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, ResultContainerOpt ? 3U : 2U, "result", over);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto current = new LoadInst(currentPtr, "current", block);
- BranchInst::Create(pull, skip, HasValue(current, block), block);
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- block = pull;
-
- if constexpr (ResultContainerOpt) {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
-
- result->addIncoming(GetYield(context), block);
- const auto choise = SwitchInst::Create(status, good, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
- } else {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
- BranchInst::Create(good, next, status, block);
- }
-
- block = good;
- const auto value = new LoadInst(valuePtr, "value", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
- result->addIncoming(value, block);
- BranchInst::Create(over, block);
-
- block = next;
- UnRefBoxed(current, ctx, block);
- new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
- BranchInst::Create(skip, block);
- }
-
- {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- block = skip;
-
- const auto list = DoGenerateGetValue(ctx, block);
- result->addIncoming(list, block);
- BranchInst::Create(over, good, IsSpecial(list, block), block);
-
- block = good;
- if constexpr (ResultContainerOpt) {
- new StoreInst(list, currentPtr, block);
- AddRefBoxed(list, ctx, block);
- } else {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
- if (NewItem->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- }
- BranchInst::Create(more, block);
- }
-
- block = over;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- for (const auto& item : this->Items)
- this->Own(flow, item);
- this->DependsOn(flow, this->NewItem);
- }
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const NewItem;
-
- const std::optional<size_t> PasstroughItem;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-template <bool MultiOptional>
-class TSimpleListValue : public TCustomListValue {
+
+ value = GetNodeValue(NewItem, ctx, block);
+ }
+
+ result->addIncoming(!IsMultiRowPerItem && ResultContainerOpt ? GetOptionalValue(context, value, block) : value, block);
+ BranchInst::Create(loop, exit, IsEmpty(value, block), block);
+
+ block = exit;
+ return result;
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto statusType = Type::getInt32Ty(context);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, ResultContainerOpt ? 3U : 2U, "result", over);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto current = new LoadInst(currentPtr, "current", block);
+ BranchInst::Create(pull, skip, HasValue(current, block), block);
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ block = pull;
+
+ if constexpr (ResultContainerOpt) {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, current, ctx.Codegen, block, valuePtr);
+
+ result->addIncoming(GetYield(context), block);
+ const auto choise = SwitchInst::Create(status, good, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), over);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), next);
+ } else {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), current, ctx.Codegen, block, valuePtr);
+ BranchInst::Create(good, next, status, block);
+ }
+
+ block = good;
+ const auto value = new LoadInst(valuePtr, "value", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
+ result->addIncoming(value, block);
+ BranchInst::Create(over, block);
+
+ block = next;
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(ConstantInt::get(current->getType(), 0), currentPtr, block);
+ BranchInst::Create(skip, block);
+ }
+
+ {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ block = skip;
+
+ const auto list = DoGenerateGetValue(ctx, block);
+ result->addIncoming(list, block);
+ BranchInst::Create(over, good, IsSpecial(list, block), block);
+
+ block = good;
+ if constexpr (ResultContainerOpt) {
+ new StoreInst(list, currentPtr, block);
+ AddRefBoxed(list, ctx, block);
+ } else {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentPtr, list, ctx.Codegen, block);
+ if (NewItem->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ }
+ BranchInst::Create(more, block);
+ }
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ for (const auto& item : this->Items)
+ this->Own(flow, item);
+ this->DependsOn(flow, this->NewItem);
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const NewItem;
+
+ const std::optional<size_t> PasstroughItem;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+template <bool MultiOptional>
+class TSimpleListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
- : TComputationValue<TIterator>(memInfo)
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
- , Item(item)
- , NewItem(newItem)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- for (;;) {
- if (!Iter.Next(Item->RefValue(CompCtx))) {
- return false;
- }
-
+ , Iter(std::move(iter))
+ , Item(item)
+ , NewItem(newItem)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ for (;;) {
+ if (!Iter.Next(Item->RefValue(CompCtx))) {
+ return false;
+ }
+
if (auto newItem = NewItem->GetValue(CompCtx)) {
- value = newItem.Release().template GetOptionalValueIf<MultiOptional>();
- return true;
- }
- }
- }
-
+ value = newItem.Release().template GetOptionalValueIf<MultiOptional>();
+ return true;
+ }
+ }
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
-
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
- };
-
- TSimpleListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
- : TCustomListValue(memInfo)
+ const NUdf::TUnboxedValue Iter;
+
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+ };
+
+ TSimpleListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TCustomListValue(memInfo)
, CompCtx(compCtx)
- , List(std::move(list))
- , Item(item)
- , NewItem(newItem)
- {
- }
-
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
- }
-
+ , List(std::move(list))
+ , Item(item)
+ , NewItem(newItem)
+ {
+ }
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-};
-
-template <bool MultiOptional>
-class TSimpleStreamValue : public TComputationValue<TSimpleStreamValue<MultiOptional>> {
-public:
- using TBase = TComputationValue<TSimpleStreamValue>;
-
- TSimpleStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
- : TBase(memInfo)
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+};
+
+template <bool MultiOptional>
+class TSimpleStreamValue : public TComputationValue<TSimpleStreamValue<MultiOptional>> {
+public:
+ using TBase = TComputationValue<TSimpleStreamValue>;
+
+ TSimpleStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBase(memInfo)
, CompCtx(compCtx)
- , Stream(std::move(stream))
- , Item(item)
- , NewItem(newItem)
- {}
-
-private:
+ , Stream(std::move(stream))
+ , Item(item)
+ , NewItem(newItem)
+ {}
+
+private:
ui32 GetTraverseCount() const override {
return 1;
}
@@ -973,110 +973,110 @@ private:
Y_UNUSED(state);
}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- for (;;) {
- const auto status = Stream.Fetch(Item->RefValue(CompCtx));
- if (NUdf::EFetchStatus::Ok != status) {
- return status;
- }
-
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ for (;;) {
+ const auto status = Stream.Fetch(Item->RefValue(CompCtx));
+ if (NUdf::EFetchStatus::Ok != status) {
+ return status;
+ }
+
if (auto newItem = NewItem->GetValue(CompCtx)) {
- result = newItem.Release().template GetOptionalValueIf<MultiOptional>();
- return NUdf::EFetchStatus::Ok;
- }
- }
- }
-
-private:
+ result = newItem.Release().template GetOptionalValueIf<MultiOptional>();
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+ }
+
+private:
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-};
-
-template <bool IsNewStream>
-class TListValue : public TCustomListValue {
-public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
- : TComputationValue<TIterator>(memInfo)
+ const NUdf::TUnboxedValue Stream;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+};
+
+template <bool IsNewStream>
+class TListValue : public TCustomListValue {
+public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
+ , Iter(std::move(iter))
, Item(item)
, NewItem(newItem)
- {}
+ {}
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- for (NUdf::TUnboxedValue current = std::move(Current);; current.Clear()) {
- if (!current) {
- if (Iter.Next(Item->RefValue(CompCtx))) {
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ for (NUdf::TUnboxedValue current = std::move(Current);; current.Clear()) {
+ if (!current) {
+ if (Iter.Next(Item->RefValue(CompCtx))) {
current = IsNewStream ? NewItem->GetValue(CompCtx) : NewItem->GetValue(CompCtx).GetListIterator();
- } else {
- return false;
- }
- }
-
- if constexpr (IsNewStream) {
- const auto status = current.Fetch(value);
- MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status");
- if (NUdf::EFetchStatus::Finish == status) {
- continue;
- }
- } else {
- if (!current.Next(value)) {
- continue;
- }
- }
-
- Current = std::move(current);
- return true;
- }
- }
-
+ } else {
+ return false;
+ }
+ }
+
+ if constexpr (IsNewStream) {
+ const auto status = current.Fetch(value);
+ MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status");
+ if (NUdf::EFetchStatus::Finish == status) {
+ continue;
+ }
+ } else {
+ if (!current.Next(value)) {
+ continue;
+ }
+ }
+
+ Current = std::move(current);
+ return true;
+ }
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
-
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Iter;
+
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
-
- NUdf::TUnboxedValue Current;
+
+ NUdf::TUnboxedValue Current;
};
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
- : TCustomListValue(memInfo)
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TCustomListValue(memInfo)
, CompCtx(compCtx)
- , List(std::move(list))
- , Item(item)
- , NewItem(newItem)
- {}
+ , List(std::move(list))
+ , Item(item)
+ , NewItem(newItem)
+ {}
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
- }
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
+ }
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-};
-
-template <bool IsNewStream>
-class TStreamValue : public TComputationValue<TStreamValue<IsNewStream>> {
-public:
- using TBase = TComputationValue<TStreamValue<IsNewStream>>;
-
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
- : TBase(memInfo)
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+};
+
+template <bool IsNewStream>
+class TStreamValue : public TComputationValue<TStreamValue<IsNewStream>> {
+public:
+ using TBase = TComputationValue<TStreamValue<IsNewStream>>;
+
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBase(memInfo)
, CompCtx(compCtx)
- , Stream(std::move(stream))
- , Item(item)
- , NewItem(newItem)
- {}
-
-private:
+ , Stream(std::move(stream))
+ , Item(item)
+ , NewItem(newItem)
+ {}
+
+private:
ui32 GetTraverseCount() const override {
return 1;
}
@@ -1094,646 +1094,646 @@ private:
Y_UNUSED(state);
}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- for (NUdf::TUnboxedValue current = std::move(Current);; current.Clear()) {
- if (!current) {
- const auto status = Stream.Fetch(Item->RefValue(CompCtx));
- if (NUdf::EFetchStatus::Ok != status) {
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ for (NUdf::TUnboxedValue current = std::move(Current);; current.Clear()) {
+ if (!current) {
+ const auto status = Stream.Fetch(Item->RefValue(CompCtx));
+ if (NUdf::EFetchStatus::Ok != status) {
return status;
}
current = IsNewStream ? NewItem->GetValue(CompCtx) : NewItem->GetValue(CompCtx).GetListIterator();
}
auto status = NUdf::EFetchStatus::Ok;
- if constexpr (IsNewStream) {
+ if constexpr (IsNewStream) {
status = current.Fetch(result);
- if (NUdf::EFetchStatus::Finish == status) {
- continue;
+ if (NUdf::EFetchStatus::Finish == status) {
+ continue;
}
- } else {
- if (!current.Next(result)) {
- continue;
+ } else {
+ if (!current.Next(result)) {
+ continue;
}
- }
+ }
- Current = std::move(current);
+ Current = std::move(current);
return status;
}
- }
+ }
-private:
+private:
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-
- NUdf::TUnboxedValue Current;
-};
-
-template <bool IsInputStream, bool IsMultiRowPerItem, bool ResultContainerOpt>
-class TBaseFlatMapWrapper {
-protected:
- TBaseFlatMapWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : List(list), Item(item), NewItem(newItem)
- {}
-
-#ifndef MKQL_DISABLE_CODEGEN
- using TCodegenValue = std::conditional_t<IsInputStream,
- typename std::conditional_t<IsMultiRowPerItem, TStreamCodegenStatefulValue, TStreamCodegenValueStateless>,
- typename std::conditional_t<IsMultiRowPerItem, TCustomListCodegenStatefulValue, TCustomListCodegenValue>>;
-
- Function* GenerateSimpleMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsInputStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ const NUdf::TUnboxedValue Stream;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+
+ NUdf::TUnboxedValue Current;
+};
+
+template <bool IsInputStream, bool IsMultiRowPerItem, bool ResultContainerOpt>
+class TBaseFlatMapWrapper {
+protected:
+ TBaseFlatMapWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : List(list), Item(item), NewItem(newItem)
+ {}
+
+#ifndef MKQL_DISABLE_CODEGEN
+ using TCodegenValue = std::conditional_t<IsInputStream,
+ typename std::conditional_t<IsMultiRowPerItem, TStreamCodegenStatefulValue, TStreamCodegenValueStateless>,
+ typename std::conditional_t<IsMultiRowPerItem, TCustomListCodegenStatefulValue, TCustomListCodegenValue>>;
+
+ Function* GenerateSimpleMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsInputStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = IsInputStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsInputStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
- status;
-
- BranchInst::Create(good, done, icmp, block);
- block = good;
-
- const auto resItem = GetNodeValue(NewItem, ctx, block);
-
- BranchInst::Create(loop, pass, IsEmpty(resItem, block), block);
-
- block = pass;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- const auto getOpt = GetOptionalValue(context, resItem, block);
- new StoreInst(getOpt, valuePtr, block);
- ValueAddRef(NewItem->GetRepresentation(), valuePtr, ctx, block);
-
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsInputStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto stateType = ResultContainerOpt ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = IsInputStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsInputStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
+ status;
+
+ BranchInst::Create(good, done, icmp, block);
+ block = good;
+
+ const auto resItem = GetNodeValue(NewItem, ctx, block);
+
+ BranchInst::Create(loop, pass, IsEmpty(resItem, block), block);
+
+ block = pass;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ const auto getOpt = GetOptionalValue(context, resItem, block);
+ new StoreInst(getOpt, valuePtr, block);
+ ValueAddRef(NewItem->GetRepresentation(), valuePtr, ctx, block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsInputStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto stateType = ResultContainerOpt ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto currentArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto init = new LoadInst(currentArg, "init", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto cont = BasicBlock::Create(context, "cont", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto current = PHINode::Create(valueType, 2, "result", pass);
- current->addIncoming(init, block);
-
- const auto step = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, init, zero, "step", block);
- BranchInst::Create(next, pass, step, block);
-
- block = next;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = IsInputStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsInputStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
- status;
-
- BranchInst::Create(good, done, icmp, block);
- block = good;
-
- if constexpr (ResultContainerOpt) {
- GetNodeValue(currentArg, NewItem, ctx, block);
- } else {
- const auto list = GetNodeValue(NewItem, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentArg, list, codegen, block);
- if (NewItem->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- }
-
- const auto iter = new LoadInst(currentArg, "iter", block);
- current->addIncoming(iter, block);
-
- BranchInst::Create(pass, block);
- block = pass;
-
- const auto state = ResultContainerOpt ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(stateType, current, codegen, block, valuePtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(stateType, current, codegen, block, valuePtr);
-
- const auto scmp = ResultContainerOpt ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, state, ConstantInt::get(stateType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), "scmp", block):
- state;
-
- BranchInst::Create(exit, cont, scmp, block);
-
- block = cont;
- UnRefBoxed(current, ctx, block);
- BranchInst::Create(next, block);
-
- block = exit;
- ReturnInst::Create(context, IsInputStream ? (ResultContainerOpt ? state : ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok))) : ConstantInt::getTrue(context), block);
-
- block = done;
- new StoreInst(zero, currentArg, block);
- ReturnInst::Create(context, status, block);
-
- return ctx.Func;
- }
-
- using TFlatMapPtr = std::conditional_t<IsInputStream,
- typename std::conditional_t<IsMultiRowPerItem, TStreamCodegenStatefulValue, TStreamCodegenValueStateless>::TFetchPtr,
- typename std::conditional_t<IsMultiRowPerItem, TCustomListCodegenStatefulValue, TCustomListCodegenValue>::TNextPtr
- >;
-
- Function* FlatMapFunc = nullptr;
-
- TFlatMapPtr FlatMap = nullptr;
-#endif
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto currentArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto init = new LoadInst(currentArg, "init", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto cont = BasicBlock::Create(context, "cont", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto current = PHINode::Create(valueType, 2, "result", pass);
+ current->addIncoming(init, block);
+
+ const auto step = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, init, zero, "step", block);
+ BranchInst::Create(next, pass, step, block);
+
+ block = next;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = IsInputStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsInputStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
+ status;
+
+ BranchInst::Create(good, done, icmp, block);
+ block = good;
+
+ if constexpr (ResultContainerOpt) {
+ GetNodeValue(currentArg, NewItem, ctx, block);
+ } else {
+ const auto list = GetNodeValue(NewItem, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(currentArg, list, codegen, block);
+ if (NewItem->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ }
+
+ const auto iter = new LoadInst(currentArg, "iter", block);
+ current->addIncoming(iter, block);
+
+ BranchInst::Create(pass, block);
+ block = pass;
+
+ const auto state = ResultContainerOpt ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(stateType, current, codegen, block, valuePtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(stateType, current, codegen, block, valuePtr);
+
+ const auto scmp = ResultContainerOpt ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, state, ConstantInt::get(stateType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), "scmp", block):
+ state;
+
+ BranchInst::Create(exit, cont, scmp, block);
+
+ block = cont;
+ UnRefBoxed(current, ctx, block);
+ BranchInst::Create(next, block);
+
+ block = exit;
+ ReturnInst::Create(context, IsInputStream ? (ResultContainerOpt ? state : ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok))) : ConstantInt::getTrue(context), block);
+
+ block = done;
+ new StoreInst(zero, currentArg, block);
+ ReturnInst::Create(context, status, block);
+
+ return ctx.Func;
+ }
+
+ using TFlatMapPtr = std::conditional_t<IsInputStream,
+ typename std::conditional_t<IsMultiRowPerItem, TStreamCodegenStatefulValue, TStreamCodegenValueStateless>::TFetchPtr,
+ typename std::conditional_t<IsMultiRowPerItem, TCustomListCodegenStatefulValue, TCustomListCodegenValue>::TNextPtr
+ >;
+
+ Function* FlatMapFunc = nullptr;
+
+ TFlatMapPtr FlatMap = nullptr;
+#endif
+
IComputationNode* const List;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
};
-template <bool IsMultiRowPerItem, bool ResultContainerOpt>
-class TStreamFlatMapWrapper : public TCustomValueCodegeneratorNode<TStreamFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- private TBaseFlatMapWrapper<true, IsMultiRowPerItem, ResultContainerOpt> {
- typedef TBaseFlatMapWrapper<true, IsMultiRowPerItem, ResultContainerOpt> TBaseWrapper;
- typedef TCustomValueCodegeneratorNode<TStreamFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>> TBaseComputation;
-public:
- TStreamFlatMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && this->FlatMap)
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(this->FlatMap, &ctx, this->List->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<std::conditional_t<IsMultiRowPerItem, TStreamValue<ResultContainerOpt>, TSimpleStreamValue<ResultContainerOpt>>>(ctx, this->List->GetValue(ctx), this->Item, this->NewItem);
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(this->List);
- this->Own(this->Item);
- this->DependsOn(this->NewItem);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- this->FlatMapFunc = IsMultiRowPerItem ?
- this->GenerateMapper(codegen, TBaseComputation::MakeName("Fetch")):
- this->GenerateSimpleMapper(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(this->FlatMapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (this->FlatMapFunc)
- this->FlatMap = reinterpret_cast<typename TBaseWrapper::TFlatMapPtr>(codegen->GetPointerToFunction(this->FlatMapFunc));
- }
-#endif
-};
-
-NUdf::TUnboxedValuePod* MyArrayAlloc(const ui64 size) {
- return TMKQLAllocator<NUdf::TUnboxedValuePod>::allocate(size);
-}
-
-void MyArrayFree(const NUdf::TUnboxedValuePod *const ptr, const ui64 size) noexcept {
- TMKQLAllocator<NUdf::TUnboxedValuePod>::deallocate(ptr, size);
-}
-
-template <bool IsMultiRowPerItem, bool ResultContainerOpt>
-class TListFlatMapWrapper : public TBothWaysCodegeneratorNode<TListFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
- private TBaseFlatMapWrapper<false, IsMultiRowPerItem, ResultContainerOpt> {
- typedef TBaseFlatMapWrapper<false, IsMultiRowPerItem, ResultContainerOpt> TBaseWrapper;
- typedef TBothWaysCodegeneratorNode<TListFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>> TBaseComputation;
- static constexpr size_t UseOnStack = 1ULL << 8ULL;
-public:
- TListFlatMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = this->List->GetValue(ctx);
-
- if (!ResultContainerOpt) { // TODO temporary disable for list of streams.
- if (const auto elements = list.GetElements()) {
- const auto size = list.GetListLength();
- TUnboxedValueVector values(size);
-
- auto it = values.begin();
- std::for_each(elements, elements + size, [&] (NUdf::TUnboxedValue item) {
- this->Item->SetValue(ctx, std::move(item));
- *it = this->NewItem->GetValue(ctx);
- if (IsMultiRowPerItem || *it) {
+template <bool IsMultiRowPerItem, bool ResultContainerOpt>
+class TStreamFlatMapWrapper : public TCustomValueCodegeneratorNode<TStreamFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ private TBaseFlatMapWrapper<true, IsMultiRowPerItem, ResultContainerOpt> {
+ typedef TBaseFlatMapWrapper<true, IsMultiRowPerItem, ResultContainerOpt> TBaseWrapper;
+ typedef TCustomValueCodegeneratorNode<TStreamFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>> TBaseComputation;
+public:
+ TStreamFlatMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && this->FlatMap)
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(this->FlatMap, &ctx, this->List->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<std::conditional_t<IsMultiRowPerItem, TStreamValue<ResultContainerOpt>, TSimpleStreamValue<ResultContainerOpt>>>(ctx, this->List->GetValue(ctx), this->Item, this->NewItem);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(this->List);
+ this->Own(this->Item);
+ this->DependsOn(this->NewItem);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ this->FlatMapFunc = IsMultiRowPerItem ?
+ this->GenerateMapper(codegen, TBaseComputation::MakeName("Fetch")):
+ this->GenerateSimpleMapper(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(this->FlatMapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (this->FlatMapFunc)
+ this->FlatMap = reinterpret_cast<typename TBaseWrapper::TFlatMapPtr>(codegen->GetPointerToFunction(this->FlatMapFunc));
+ }
+#endif
+};
+
+NUdf::TUnboxedValuePod* MyArrayAlloc(const ui64 size) {
+ return TMKQLAllocator<NUdf::TUnboxedValuePod>::allocate(size);
+}
+
+void MyArrayFree(const NUdf::TUnboxedValuePod *const ptr, const ui64 size) noexcept {
+ TMKQLAllocator<NUdf::TUnboxedValuePod>::deallocate(ptr, size);
+}
+
+template <bool IsMultiRowPerItem, bool ResultContainerOpt>
+class TListFlatMapWrapper : public TBothWaysCodegeneratorNode<TListFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>>,
+ private TBaseFlatMapWrapper<false, IsMultiRowPerItem, ResultContainerOpt> {
+ typedef TBaseFlatMapWrapper<false, IsMultiRowPerItem, ResultContainerOpt> TBaseWrapper;
+ typedef TBothWaysCodegeneratorNode<TListFlatMapWrapper<IsMultiRowPerItem, ResultContainerOpt>> TBaseComputation;
+ static constexpr size_t UseOnStack = 1ULL << 8ULL;
+public:
+ TListFlatMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = this->List->GetValue(ctx);
+
+ if (!ResultContainerOpt) { // TODO temporary disable for list of streams.
+ if (const auto elements = list.GetElements()) {
+ const auto size = list.GetListLength();
+ TUnboxedValueVector values(size);
+
+ auto it = values.begin();
+ std::for_each(elements, elements + size, [&] (NUdf::TUnboxedValue item) {
+ this->Item->SetValue(ctx, std::move(item));
+ *it = this->NewItem->GetValue(ctx);
+ if (IsMultiRowPerItem || *it) {
auto value = it->GetOptionalValueIf<!IsMultiRowPerItem && ResultContainerOpt>();
*it++ = value;
- }
- });
-
- if constexpr (IsMultiRowPerItem) {
- return ctx.HolderFactory.ExtendList<ResultContainerOpt>(values.data(), values.size());
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(std::distance(values.begin(), it), items);
- std::move(values.begin(), it, items);
- return result;
- }
- }
-
- return ctx.HolderFactory.Create<std::conditional_t<IsMultiRowPerItem, TListValue<ResultContainerOpt>, TSimpleListValue<ResultContainerOpt>>>(ctx, std::move(list), this->Item, this->NewItem);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(this->FlatMap, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(this->Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto list = GetNodeValue(this->List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto map = PHINode::Create(list->getType(), 3U, "map", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = ResultContainerOpt ? static_cast<Value*>(ConstantInt::getFalse(context)): // TODO temporary disable for list of streams.
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
- const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto free = BasicBlock::Create(context, "free", ctx.Func);
-
- const auto vector = PHINode::Create(PointerType::getUnqual(list->getType()), 2U, "vector", main);
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto zeroSize = ConstantInt::get(size->getType(), 0);
- const auto plusSize = ConstantInt::get(size->getType(), 1);
-
- const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), UseOnStack), "heap", block);
- BranchInst::Create(hmsk, smsk, heap, block);
-
- {
- block = smsk;
-
- const auto arrayType = ArrayType::get(list->getType(), UseOnStack);
- const auto array = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(arrayType, 0U, "array", block);
- const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
-
- vector->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- {
- block = hmsk;
-
- const auto fnType = FunctionType::get(vector->getType(), {size->getType()}, false);
- const auto name = "MyArrayAlloc";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyArrayAlloc));
+ }
+ });
+
+ if constexpr (IsMultiRowPerItem) {
+ return ctx.HolderFactory.ExtendList<ResultContainerOpt>(values.data(), values.size());
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(std::distance(values.begin(), it), items);
+ std::move(values.begin(), it, items);
+ return result;
+ }
+ }
+
+ return ctx.HolderFactory.Create<std::conditional_t<IsMultiRowPerItem, TListValue<ResultContainerOpt>, TSimpleListValue<ResultContainerOpt>>>(ctx, std::move(list), this->Item, this->NewItem);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCodegenValue>(this->FlatMap, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(this->Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto list = GetNodeValue(this->List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto map = PHINode::Create(list->getType(), 3U, "map", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = ResultContainerOpt ? static_cast<Value*>(ConstantInt::getFalse(context)): // TODO temporary disable for list of streams.
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto smsk = BasicBlock::Create(context, "smsk", ctx.Func);
+ const auto hmsk = BasicBlock::Create(context, "hmsk", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto free = BasicBlock::Create(context, "free", ctx.Func);
+
+ const auto vector = PHINode::Create(PointerType::getUnqual(list->getType()), 2U, "vector", main);
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto zeroSize = ConstantInt::get(size->getType(), 0);
+ const auto plusSize = ConstantInt::get(size->getType(), 1);
+
+ const auto heap = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), UseOnStack), "heap", block);
+ BranchInst::Create(hmsk, smsk, heap, block);
+
+ {
+ block = smsk;
+
+ const auto arrayType = ArrayType::get(list->getType(), UseOnStack);
+ const auto array = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(arrayType, 0U, "array", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(arrayType, 0U, "array", block);
+ const auto ptr = GetElementPtrInst::CreateInBounds(array, {zeroSize, zeroSize}, "ptr", block);
+
+ vector->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ {
+ block = hmsk;
+
+ const auto fnType = FunctionType::get(vector->getType(), {size->getType()}, false);
+ const auto name = "MyArrayAlloc";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyArrayAlloc));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- const auto ptr = CallInst::Create(func, {size}, "ptr", block);
- vector->addIncoming(ptr, block);
- BranchInst::Create(main, block);
- }
-
- block = main;
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- index->addIncoming(zeroSize, block);
-
- const auto idx = IsMultiRowPerItem ? index : PHINode::Create(size->getType(), 2U, "idx", loop);
- if constexpr (!IsMultiRowPerItem) {
- idx->addIncoming(zeroSize, block);
- }
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
-
- BranchInst::Create(next, stop, more, block);
-
- block = next;
- const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto item = new LoadInst(src, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto dst = GetElementPtrInst::CreateInBounds(vector, {idx}, "dst", block);
- GetNodeValue(dst, this->NewItem, ctx, block);
-
- const auto inc = BinaryOperator::CreateAdd(index, plusSize, "inc", block);
- index->addIncoming(inc, block);
-
- if constexpr (!IsMultiRowPerItem) {
- const auto plus = BinaryOperator::CreateAdd(idx, plusSize, "plus", block);
- const auto load = new LoadInst(dst, "load", block);
- new StoreInst(GetOptionalValue(context, load, block), dst, block);
- const auto move = SelectInst::Create(IsExists(load, block), plus, idx, "move", block);
- idx->addIncoming(move, block);
- }
-
- BranchInst::Create(loop, block);
-
- block = stop;
-
- if (this->List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
-
- Value* res;
- if constexpr (!IsMultiRowPerItem) {
- const auto newPtr = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "new_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "new_ptr", block);
- res = GenNewArray(ctx, idx, newPtr, block);
- const auto target = new LoadInst(newPtr, "target", block);
-
- const auto pType = PointerType::getUnqual(Type::getInt8Ty(context));
- const auto pdst = CastInst::Create(Instruction::BitCast, target, pType, "pdst", block);
- const auto psrc = CastInst::Create(Instruction::BitCast, vector, pType, "psrc", block);
- const auto bytes = BinaryOperator::CreateShl(idx, ConstantInt::get(idx->getType(), 4), "bytes", block);
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {pType, pType, bytes->getType(), Type::getInt1Ty(context)}, false);
+ const auto ptr = CallInst::Create(func, {size}, "ptr", block);
+ vector->addIncoming(ptr, block);
+ BranchInst::Create(main, block);
+ }
+
+ block = main;
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ index->addIncoming(zeroSize, block);
+
+ const auto idx = IsMultiRowPerItem ? index : PHINode::Create(size->getType(), 2U, "idx", loop);
+ if constexpr (!IsMultiRowPerItem) {
+ idx->addIncoming(zeroSize, block);
+ }
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
+
+ BranchInst::Create(next, stop, more, block);
+
+ block = next;
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto item = new LoadInst(src, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto dst = GetElementPtrInst::CreateInBounds(vector, {idx}, "dst", block);
+ GetNodeValue(dst, this->NewItem, ctx, block);
+
+ const auto inc = BinaryOperator::CreateAdd(index, plusSize, "inc", block);
+ index->addIncoming(inc, block);
+
+ if constexpr (!IsMultiRowPerItem) {
+ const auto plus = BinaryOperator::CreateAdd(idx, plusSize, "plus", block);
+ const auto load = new LoadInst(dst, "load", block);
+ new StoreInst(GetOptionalValue(context, load, block), dst, block);
+ const auto move = SelectInst::Create(IsExists(load, block), plus, idx, "move", block);
+ idx->addIncoming(move, block);
+ }
+
+ BranchInst::Create(loop, block);
+
+ block = stop;
+
+ if (this->List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+
+ Value* res;
+ if constexpr (!IsMultiRowPerItem) {
+ const auto newPtr = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "new_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "new_ptr", block);
+ res = GenNewArray(ctx, idx, newPtr, block);
+ const auto target = new LoadInst(newPtr, "target", block);
+
+ const auto pType = PointerType::getUnqual(Type::getInt8Ty(context));
+ const auto pdst = CastInst::Create(Instruction::BitCast, target, pType, "pdst", block);
+ const auto psrc = CastInst::Create(Instruction::BitCast, vector, pType, "psrc", block);
+ const auto bytes = BinaryOperator::CreateShl(idx, ConstantInt::get(idx->getType(), 4), "bytes", block);
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {pType, pType, bytes->getType(), Type::getInt1Ty(context)}, false);
const auto func = ctx.Codegen->GetModule().getOrInsertFunction("llvm.memcpy.p0i8.p0i8.i64", fnType).getCallee();
- CallInst::Create(func, {pdst, psrc, bytes, ConstantInt::getFalse(context)}, "", block);
- } else {
- const auto factory = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ExtendList<ResultContainerOpt>));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), vector->getType(), index->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- res = CallInst::Create(funcPtr, {factory, vector, index}, "res", block);
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), vector->getType(), index->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, vector, index}, "", block);
- res = new LoadInst(retPtr, "res", block);
- }
- }
- map->addIncoming(res, block);
- BranchInst::Create(free, done, heap, block);
-
- {
- block = free;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {vector->getType(), size->getType()}, false);
- const auto name = "MyArrayFree";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyArrayFree));
+ CallInst::Create(func, {pdst, psrc, bytes, ConstantInt::getFalse(context)}, "", block);
+ } else {
+ const auto factory = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ExtendList<ResultContainerOpt>));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), vector->getType(), index->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ res = CallInst::Create(funcPtr, {factory, vector, index}, "res", block);
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), vector->getType(), index->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, vector, index}, "", block);
+ res = new LoadInst(retPtr, "res", block);
+ }
+ }
+ map->addIncoming(res, block);
+ BranchInst::Create(free, done, heap, block);
+
+ {
+ block = free;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {vector->getType(), size->getType()}, false);
+ const auto name = "MyArrayFree";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&MyArrayFree));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {vector, size}, "", block);
-
- map->addIncoming(res, block);
- BranchInst::Create(done, block);
- }
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFlatMapWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- map->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- map->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return map;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(this->List);
- this->Own(this->Item);
- this->DependsOn(this->NewItem);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFlatMapWrapper>::GenerateFunctions(codegen);
- this->FlatMapFunc = IsMultiRowPerItem ?
- this->GenerateMapper(codegen, TBaseComputation::MakeName("Next")):
- this->GenerateSimpleMapper(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(this->FlatMapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListFlatMapWrapper>::FinalizeFunctions(codegen);
- if (this->FlatMapFunc)
- this->FlatMap = reinterpret_cast<typename TBaseWrapper::TFlatMapPtr>(codegen->GetPointerToFunction(this->FlatMapFunc));
- }
-#endif
-};
-
-}
-
-IComputationNode* WrapFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
-
- const auto listType = callable.GetInput(0).GetStaticType();;
- const auto newListType = callable.GetInput(2).GetStaticType();
-
- const auto type = callable.GetType()->GetReturnType();
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto newItem = LocateNode(ctx.NodeLocator, callable, 2);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto kind = GetValueRepresentation(type);
- if (listType->IsFlow()) {
- if (newListType->IsFlow()) {
- if (const auto wideOut = dynamic_cast<IComputationWideFlowNode*>(newItem))
- return new TFlowFlatMapWideWrapper(ctx.Mutables, list, itemArg, wideOut);
- else
- return new TFlowFlatMapFlowWrapper(ctx.Mutables, kind, list, itemArg, newItem);
- } else if (newListType->IsList()) {
- return new TFlowFlatMapWrapper<true, false>(ctx.Mutables, kind, list, itemArg, newItem);
- } else if (newListType->IsStream()) {
- return new TFlowFlatMapWrapper<true, true>(ctx.Mutables, kind, list, itemArg, newItem);
- } else if (newListType->IsOptional()) {
- if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
- return new TFlowFlatMapWrapper<false, true>(ctx.Mutables, kind, list, itemArg, newItem);
- } else {
- return new TFlowFlatMapWrapper<false, false>(ctx.Mutables, kind, list, itemArg, newItem);
- }
- }
- } else if (listType->IsStream()) {
- if (newListType->IsList()) {
- return new TStreamFlatMapWrapper<true, false>(ctx.Mutables, list, itemArg, newItem);
- } else if (newListType->IsStream()) {
- return new TStreamFlatMapWrapper<true, true>(ctx.Mutables, list, itemArg, newItem);
- } else if (newListType->IsOptional()) {
- if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
- return new TStreamFlatMapWrapper<false, true>(ctx.Mutables, list, itemArg, newItem);
- } else {
- return new TStreamFlatMapWrapper<false, false>(ctx.Mutables, list, itemArg, newItem);
- }
+ CallInst::Create(func, {vector, size}, "", block);
+
+ map->addIncoming(res, block);
+ BranchInst::Create(done, block);
+ }
}
- } else if (listType->IsList()) {
- if (newListType->IsFlow()) {
- if (const auto wideOut = dynamic_cast<IComputationWideFlowNode*>(newItem))
- return new TListFlatMapWideWrapper(ctx.Mutables, list, itemArg, wideOut);
- else
- return new TListFlatMapFlowWrapper(ctx.Mutables, kind, list, itemArg, newItem);
- } else if (newListType->IsList()) {
- return new TListFlatMapWrapper<true, false>(ctx.Mutables, list, itemArg, newItem);
- } else if (newListType->IsStream()) {
- return new TListFlatMapWrapper<true, true>(ctx.Mutables, list, itemArg, newItem);
- } else if (newListType->IsOptional()) {
- if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
- return new TListFlatMapWrapper<false, true>(ctx.Mutables, list, itemArg, newItem);
- } else {
- return new TListFlatMapWrapper<false, false>(ctx.Mutables, list, itemArg, newItem);
- }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFlatMapWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ map->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ map->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
}
+
+ block = done;
+ return map;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(this->List);
+ this->Own(this->Item);
+ this->DependsOn(this->NewItem);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFlatMapWrapper>::GenerateFunctions(codegen);
+ this->FlatMapFunc = IsMultiRowPerItem ?
+ this->GenerateMapper(codegen, TBaseComputation::MakeName("Next")):
+ this->GenerateSimpleMapper(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(this->FlatMapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListFlatMapWrapper>::FinalizeFunctions(codegen);
+ if (this->FlatMapFunc)
+ this->FlatMap = reinterpret_cast<typename TBaseWrapper::TFlatMapPtr>(codegen->GetPointerToFunction(this->FlatMapFunc));
}
-
- THROW yexception() << "Expected flow, list or stream of lists, streams or optionals.";
+#endif
+};
+
+}
+
+IComputationNode* WrapFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
+
+ const auto listType = callable.GetInput(0).GetStaticType();;
+ const auto newListType = callable.GetInput(2).GetStaticType();
+
+ const auto type = callable.GetType()->GetReturnType();
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto newItem = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto kind = GetValueRepresentation(type);
+ if (listType->IsFlow()) {
+ if (newListType->IsFlow()) {
+ if (const auto wideOut = dynamic_cast<IComputationWideFlowNode*>(newItem))
+ return new TFlowFlatMapWideWrapper(ctx.Mutables, list, itemArg, wideOut);
+ else
+ return new TFlowFlatMapFlowWrapper(ctx.Mutables, kind, list, itemArg, newItem);
+ } else if (newListType->IsList()) {
+ return new TFlowFlatMapWrapper<true, false>(ctx.Mutables, kind, list, itemArg, newItem);
+ } else if (newListType->IsStream()) {
+ return new TFlowFlatMapWrapper<true, true>(ctx.Mutables, kind, list, itemArg, newItem);
+ } else if (newListType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
+ return new TFlowFlatMapWrapper<false, true>(ctx.Mutables, kind, list, itemArg, newItem);
+ } else {
+ return new TFlowFlatMapWrapper<false, false>(ctx.Mutables, kind, list, itemArg, newItem);
+ }
+ }
+ } else if (listType->IsStream()) {
+ if (newListType->IsList()) {
+ return new TStreamFlatMapWrapper<true, false>(ctx.Mutables, list, itemArg, newItem);
+ } else if (newListType->IsStream()) {
+ return new TStreamFlatMapWrapper<true, true>(ctx.Mutables, list, itemArg, newItem);
+ } else if (newListType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
+ return new TStreamFlatMapWrapper<false, true>(ctx.Mutables, list, itemArg, newItem);
+ } else {
+ return new TStreamFlatMapWrapper<false, false>(ctx.Mutables, list, itemArg, newItem);
+ }
+ }
+ } else if (listType->IsList()) {
+ if (newListType->IsFlow()) {
+ if (const auto wideOut = dynamic_cast<IComputationWideFlowNode*>(newItem))
+ return new TListFlatMapWideWrapper(ctx.Mutables, list, itemArg, wideOut);
+ else
+ return new TListFlatMapFlowWrapper(ctx.Mutables, kind, list, itemArg, newItem);
+ } else if (newListType->IsList()) {
+ return new TListFlatMapWrapper<true, false>(ctx.Mutables, list, itemArg, newItem);
+ } else if (newListType->IsStream()) {
+ return new TListFlatMapWrapper<true, true>(ctx.Mutables, list, itemArg, newItem);
+ } else if (newListType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
+ return new TListFlatMapWrapper<false, true>(ctx.Mutables, list, itemArg, newItem);
+ } else {
+ return new TListFlatMapWrapper<false, false>(ctx.Mutables, list, itemArg, newItem);
+ }
+ }
+ }
+
+ THROW yexception() << "Expected flow, list or stream of lists, streams or optionals.";
+}
+
+IComputationNode* WrapNarrowFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 1U, "Expected at least two args.");
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature.");
+
+ const auto last = callable.GetInputsCount() - 1U;
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ const auto newItem = LocateNode(ctx.NodeLocator, callable, last);
+
+ TComputationExternalNodePtrVector args(width, nullptr);
+ ui32 index = 0U;
+ std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ const auto newListType = callable.GetInput(last).GetStaticType();
+ const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ if (newListType->IsFlow()) {
+ return new TNarrowFlatMapFlowWrapper(ctx.Mutables, kind, wide, std::move(args), newItem);
+ } else if (newListType->IsList()) {
+ return new TNarrowFlatMapWrapper<true, false>(ctx.Mutables, kind, wide, std::move(args), newItem);
+ } else if (newListType->IsStream()) {
+ return new TNarrowFlatMapWrapper<true, true>(ctx.Mutables, kind, wide, std::move(args), newItem);
+ } else if (newListType->IsOptional()) {
+ if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
+ return new TNarrowFlatMapWrapper<false, true>(ctx.Mutables, kind, wide, std::move(args), newItem);
+ } else {
+ return new TNarrowFlatMapWrapper<false, false>(ctx.Mutables, kind, wide, std::move(args), newItem);
+ }
+ }
+ }
+
+ THROW yexception() << "Expected wide flow.";
}
-IComputationNode* WrapNarrowFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 1U, "Expected at least two args.");
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature.");
-
- const auto last = callable.GetInputsCount() - 1U;
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- const auto newItem = LocateNode(ctx.NodeLocator, callable, last);
-
- TComputationExternalNodePtrVector args(width, nullptr);
- ui32 index = 0U;
- std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- const auto newListType = callable.GetInput(last).GetStaticType();
- const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- if (newListType->IsFlow()) {
- return new TNarrowFlatMapFlowWrapper(ctx.Mutables, kind, wide, std::move(args), newItem);
- } else if (newListType->IsList()) {
- return new TNarrowFlatMapWrapper<true, false>(ctx.Mutables, kind, wide, std::move(args), newItem);
- } else if (newListType->IsStream()) {
- return new TNarrowFlatMapWrapper<true, true>(ctx.Mutables, kind, wide, std::move(args), newItem);
- } else if (newListType->IsOptional()) {
- if (AS_TYPE(TOptionalType, newListType)->GetItemType()->IsOptional()) {
- return new TNarrowFlatMapWrapper<false, true>(ctx.Mutables, kind, wide, std::move(args), newItem);
- } else {
- return new TNarrowFlatMapWrapper<false, false>(ctx.Mutables, kind, wide, std::move(args), newItem);
- }
- }
- }
-
- THROW yexception() << "Expected wide flow.";
}
-
}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.h b/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.h
index c791cf8e37..5ba32aecfd 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_flatmap.h
@@ -6,8 +6,8 @@ namespace NMiniKQL {
IComputationNode* WrapFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapNarrowFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-
+IComputationNode* WrapNarrowFlatMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_flow.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_flow.cpp
index e7d6e2e1a1..16ccf3a51d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_flow.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_flow.cpp
@@ -1,313 +1,313 @@
-#include "mkql_flow.h"
+#include "mkql_flow.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <bool IsStream>
-class TToFlowWrapper : public TFlowSourceCodegeneratorNode<TToFlowWrapper<IsStream>> {
- typedef TFlowSourceCodegeneratorNode<TToFlowWrapper<IsStream>> TBaseComputation;
-public:
- TToFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind,IComputationNode* stream)
- : TBaseComputation(mutables, kind, EValueRepresentation::Any), Stream(stream)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& stream, TComputationContext& ctx) const {
- if (stream.IsInvalid()) {
- stream = IsStream ? Stream->GetValue(ctx) : Stream->GetValue(ctx).GetListIterator();
- }
-
- NUdf::TUnboxedValue next;
- if constexpr (IsStream) {
- switch (const auto state = stream.Fetch(next)) {
- case NUdf::EFetchStatus::Ok: return next.Release();
- case NUdf::EFetchStatus::Finish: return NUdf::TUnboxedValuePod::MakeFinish();
- case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
- }
- } else {
- return stream.Next(next) ? next.Release() : NUdf::TUnboxedValuePod::MakeFinish();
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = PHINode::Create(load->getType(), 2U, "state", main);
- state->addIncoming(load, block);
-
- BranchInst::Create(init, main, IsInvalid(load, block), block);
-
- block = init;
-
- if constexpr (IsStream) {
- GetNodeValue(statePtr, Stream, ctx, block);
- } else {
- const auto list = GetNodeValue(Stream, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
- if (Stream->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- }
-
- const auto save = new LoadInst(statePtr, "save", block);
- state->addIncoming(save, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
-
- if constexpr (IsStream) {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(Type::getInt32Ty(context), state, ctx.Codegen, block, valuePtr);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
-
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
- BranchInst::Create(good, none, ok, block);
-
- block = none;
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "yield", block);
- const auto special = SelectInst::Create(yield, GetYield(context), GetFinish(context), "special", block);
- result->addIncoming(special, block);
- BranchInst::Create(done, block);
- } else {
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), state, ctx.Codegen, block, valuePtr);
- result->addIncoming(GetFinish(context), block);
- BranchInst::Create(good, done, status, block);
- }
-
- block = good;
- const auto value = new LoadInst(valuePtr, "value", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
- result->addIncoming(value, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Stream);
- }
-
- IComputationNode* const Stream;
-};
-
-template <bool IsItemOptional = true>
-class TOptToFlowWrapper : public TFlowSourceCodegeneratorNode<TOptToFlowWrapper<IsItemOptional>> {
- typedef TFlowSourceCodegeneratorNode<TOptToFlowWrapper<IsItemOptional>> TBaseComputation;
-public:
- TOptToFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* optional)
- : TBaseComputation(mutables, kind, EValueRepresentation::Embedded), Optional(optional)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return state;
- }
-
- state = NUdf::TUnboxedValue::MakeFinish();
- if (auto value = Optional->GetValue(ctx)) {
- return value.Release().GetOptionalValueIf<IsItemOptional>();
- }
-
- return state;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto result = PHINode::Create(load->getType(), 2U, "state", done);
-
- result->addIncoming(load, block);
- BranchInst::Create(done, main, IsFinish(load, block), block);
-
- block = main;
-
- const auto finish = GetFinish(context);
- new StoreInst(finish, statePtr, block);
-
- const auto optional = GetNodeValue(Optional, ctx, block);
- const auto value = IsItemOptional ? GetOptionalValue(context, optional, block) : optional;
- const auto output = SelectInst::Create(IsEmpty(optional, block), finish, value, "output", block);
-
- result->addIncoming(output, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Optional);
- }
-
- IComputationNode* const Optional;
-};
-
-class TFromFlowWrapper : public TCustomValueCodegeneratorNode<TFromFlowWrapper> {
- typedef TCustomValueCodegeneratorNode<TFromFlowWrapper> TBaseComputation;
-public:
-
- class TStreamValue : public TComputationValue<TStreamValue> {
- public:
- using TBase = TComputationValue<TStreamValue>;
-
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, IComputationNode* flow)
- : TBase(memInfo), CompCtx(compCtx), Flow(flow)
- {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- result = Flow->GetValue(CompCtx);
- if (result.IsFinish())
- return NUdf::EFetchStatus::Finish;
- if (result.IsYield())
- return NUdf::EFetchStatus::Yield;
- return NUdf::EFetchStatus::Ok;
- }
-
- TComputationContext& CompCtx;
- IComputationNode* const Flow;
- };
-
- class TStreamCodegenValue : public TComputationValue<TStreamCodegenValue> {
- public:
- using TBase = TComputationValue<TStreamCodegenValue>;
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod&);
-
- TStreamCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx)
- : TBase(memInfo), FetchFunc(fetch), Ctx(ctx)
- {}
-
- protected:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- };
-
- TFromFlowWrapper(TComputationMutables& mutables, IComputationNode* flow)
- : TBaseComputation(mutables), Flow(flow)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Fetch)
- return ctx.HolderFactory.Create<TStreamCodegenValue>(Fetch, &ctx);
-#endif
- return ctx.HolderFactory.Create<TStreamValue>(ctx, Flow);
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Flow);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- FetchFunc = GenerateFetcher(codegen);
- codegen->ExportSymbol(FetchFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FetchFunc)
- Fetch = reinterpret_cast<TStreamCodegenValue::TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
- }
-
- Function* GenerateFetcher(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <bool IsStream>
+class TToFlowWrapper : public TFlowSourceCodegeneratorNode<TToFlowWrapper<IsStream>> {
+ typedef TFlowSourceCodegeneratorNode<TToFlowWrapper<IsStream>> TBaseComputation;
+public:
+ TToFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind,IComputationNode* stream)
+ : TBaseComputation(mutables, kind, EValueRepresentation::Any), Stream(stream)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& stream, TComputationContext& ctx) const {
+ if (stream.IsInvalid()) {
+ stream = IsStream ? Stream->GetValue(ctx) : Stream->GetValue(ctx).GetListIterator();
+ }
+
+ NUdf::TUnboxedValue next;
+ if constexpr (IsStream) {
+ switch (const auto state = stream.Fetch(next)) {
+ case NUdf::EFetchStatus::Ok: return next.Release();
+ case NUdf::EFetchStatus::Finish: return NUdf::TUnboxedValuePod::MakeFinish();
+ case NUdf::EFetchStatus::Yield: return NUdf::TUnboxedValuePod::MakeYield();
+ }
+ } else {
+ return stream.Next(next) ? next.Release() : NUdf::TUnboxedValuePod::MakeFinish();
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = PHINode::Create(load->getType(), 2U, "state", main);
+ state->addIncoming(load, block);
+
+ BranchInst::Create(init, main, IsInvalid(load, block), block);
+
+ block = init;
+
+ if constexpr (IsStream) {
+ GetNodeValue(statePtr, Stream, ctx, block);
+ } else {
+ const auto list = GetNodeValue(Stream, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(statePtr, list, ctx.Codegen, block);
+ if (Stream->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ }
+
+ const auto save = new LoadInst(statePtr, "save", block);
+ state->addIncoming(save, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto valuePtr = new AllocaInst(valueType, 0U, "value_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(ConstantInt::get(valueType, 0), valuePtr, block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+
+ if constexpr (IsStream) {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(Type::getInt32Ty(context), state, ctx.Codegen, block, valuePtr);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
+
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+ BranchInst::Create(good, none, ok, block);
+
+ block = none;
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Yield)), "yield", block);
+ const auto special = SelectInst::Create(yield, GetYield(context), GetFinish(context), "special", block);
+ result->addIncoming(special, block);
+ BranchInst::Create(done, block);
+ } else {
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), state, ctx.Codegen, block, valuePtr);
+ result->addIncoming(GetFinish(context), block);
+ BranchInst::Create(good, done, status, block);
+ }
+
+ block = good;
+ const auto value = new LoadInst(valuePtr, "value", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
+ result->addIncoming(value, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Stream);
+ }
+
+ IComputationNode* const Stream;
+};
+
+template <bool IsItemOptional = true>
+class TOptToFlowWrapper : public TFlowSourceCodegeneratorNode<TOptToFlowWrapper<IsItemOptional>> {
+ typedef TFlowSourceCodegeneratorNode<TOptToFlowWrapper<IsItemOptional>> TBaseComputation;
+public:
+ TOptToFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* optional)
+ : TBaseComputation(mutables, kind, EValueRepresentation::Embedded), Optional(optional)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return state;
+ }
+
+ state = NUdf::TUnboxedValue::MakeFinish();
+ if (auto value = Optional->GetValue(ctx)) {
+ return value.Release().GetOptionalValueIf<IsItemOptional>();
+ }
+
+ return state;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto result = PHINode::Create(load->getType(), 2U, "state", done);
+
+ result->addIncoming(load, block);
+ BranchInst::Create(done, main, IsFinish(load, block), block);
+
+ block = main;
+
+ const auto finish = GetFinish(context);
+ new StoreInst(finish, statePtr, block);
+
+ const auto optional = GetNodeValue(Optional, ctx, block);
+ const auto value = IsItemOptional ? GetOptionalValue(context, optional, block) : optional;
+ const auto output = SelectInst::Create(IsEmpty(optional, block), finish, value, "output", block);
+
+ result->addIncoming(output, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Optional);
+ }
+
+ IComputationNode* const Optional;
+};
+
+class TFromFlowWrapper : public TCustomValueCodegeneratorNode<TFromFlowWrapper> {
+ typedef TCustomValueCodegeneratorNode<TFromFlowWrapper> TBaseComputation;
+public:
+
+ class TStreamValue : public TComputationValue<TStreamValue> {
+ public:
+ using TBase = TComputationValue<TStreamValue>;
+
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, IComputationNode* flow)
+ : TBase(memInfo), CompCtx(compCtx), Flow(flow)
+ {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ result = Flow->GetValue(CompCtx);
+ if (result.IsFinish())
+ return NUdf::EFetchStatus::Finish;
+ if (result.IsYield())
+ return NUdf::EFetchStatus::Yield;
+ return NUdf::EFetchStatus::Ok;
+ }
+
+ TComputationContext& CompCtx;
+ IComputationNode* const Flow;
+ };
+
+ class TStreamCodegenValue : public TComputationValue<TStreamCodegenValue> {
+ public:
+ using TBase = TComputationValue<TStreamCodegenValue>;
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod&);
+
+ TStreamCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx)
+ : TBase(memInfo), FetchFunc(fetch), Ctx(ctx)
+ {}
+
+ protected:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ };
+
+ TFromFlowWrapper(TComputationMutables& mutables, IComputationNode* flow)
+ : TBaseComputation(mutables), Flow(flow)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Fetch)
+ return ctx.HolderFactory.Create<TStreamCodegenValue>(Fetch, &ctx);
+#endif
+ return ctx.HolderFactory.Create<TStreamValue>(ctx, Flow);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Flow);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ FetchFunc = GenerateFetcher(codegen);
+ codegen->ExportSymbol(FetchFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FetchFunc)
+ Fetch = reinterpret_cast<TStreamCodegenValue::TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
+ }
+
+ Function* GenerateFetcher(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, Flow, ctx, block);
-
- const auto value = new LoadInst(valuePtr, "value", block);
-
- const auto second = SelectInst::Create(IsYield(value, block), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "second", block);
- const auto first = SelectInst::Create(IsFinish(value, block), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), second, "second", block);
-
- ReturnInst::Create(context, first, block);
- return ctx.Func;
- }
-
- Function* FetchFunc = nullptr;
-
- TStreamCodegenValue::TFetchPtr Fetch = nullptr;
-#endif
- IComputationNode* const Flow;
-};
-
-}
-
-IComputationNode* WrapToFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args, got " << callable.GetInputsCount());
- const auto type = callable.GetInput(0).GetStaticType();
- const auto outType = AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType();
- const auto kind = GetValueRepresentation(outType);
- if (type->IsStream()) {
- return new TToFlowWrapper<true>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
- } else if (type->IsList()) {
- return new TToFlowWrapper<false>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
- } else if (type->IsOptional()) {
- if (outType->IsOptional()) {
- return new TOptToFlowWrapper<true>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
- } else {
- return new TOptToFlowWrapper<false>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
- }
- }
-
- THROW yexception() << "Expected optional, list or stream.";
-}
-
-IComputationNode* WrapFromFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args, got " << callable.GetInputsCount());
- return new TFromFlowWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
-}
-
-}
-}
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, Flow, ctx, block);
+
+ const auto value = new LoadInst(valuePtr, "value", block);
+
+ const auto second = SelectInst::Create(IsYield(value, block), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "second", block);
+ const auto first = SelectInst::Create(IsFinish(value, block), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), second, "second", block);
+
+ ReturnInst::Create(context, first, block);
+ return ctx.Func;
+ }
+
+ Function* FetchFunc = nullptr;
+
+ TStreamCodegenValue::TFetchPtr Fetch = nullptr;
+#endif
+ IComputationNode* const Flow;
+};
+
+}
+
+IComputationNode* WrapToFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args, got " << callable.GetInputsCount());
+ const auto type = callable.GetInput(0).GetStaticType();
+ const auto outType = AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType();
+ const auto kind = GetValueRepresentation(outType);
+ if (type->IsStream()) {
+ return new TToFlowWrapper<true>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
+ } else if (type->IsList()) {
+ return new TToFlowWrapper<false>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
+ } else if (type->IsOptional()) {
+ if (outType->IsOptional()) {
+ return new TOptToFlowWrapper<true>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
+ } else {
+ return new TOptToFlowWrapper<false>(ctx.Mutables, kind, LocateNode(ctx.NodeLocator, callable, 0));
+ }
+ }
+
+ THROW yexception() << "Expected optional, list or stream.";
+}
+
+IComputationNode* WrapFromFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args, got " << callable.GetInputsCount());
+ return new TFromFlowWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_flow.h b/ydb/library/yql/minikql/comp_nodes/mkql_flow.h
index a6585f4cee..515fe4cad7 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_flow.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_flow.h
@@ -1,12 +1,12 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapToFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapFromFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapToFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapFromFlow(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_fold.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_fold.cpp
index 2d30615b76..15d912e49d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_fold.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_fold.cpp
@@ -5,14 +5,14 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TFoldWrapper : public TMutableCodegeneratorRootNode<TFoldWrapper> {
typedef TMutableCodegeneratorRootNode<TFoldWrapper> TBaseComputation;
public:
- TFoldWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state,
+ TFoldWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state,
IComputationNode* newState, IComputationNode* initialState)
- : TBaseComputation(mutables, kind)
+ : TBaseComputation(mutables, kind)
, List(list)
, Item(item)
, State(state)
@@ -23,149 +23,149 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
State->SetValue(compCtx, InitialState->GetValue(compCtx));
-
+
TThresher<false>::DoForEachItem(List->GetValue(compCtx),
[this, &compCtx] (NUdf::TUnboxedValue&& item) {
Item->SetValue(compCtx, std::move(item));
State->SetValue(compCtx, NewState->GetValue(compCtx));
}
- );
-
+ );
+
return State->GetValue(compCtx).Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- llvm::Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto &context = ctx.Codegen->GetContext();
-
- const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenState, "State must be codegenerator node.");
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
-
- const auto init = GetNodeValue(InitialState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, init);
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
-
- {
- block = fast;
- const auto sizeType = Type::getInt64Ty(context);
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(sizeType, list, ctx.Codegen, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto index = PHINode::Create(sizeType, 2U, "index", loop);
- index->addIncoming(ConstantInt::get(sizeType, 0), block);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "more", block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- BranchInst::Create(good, done, more, block);
-
- block = good;
- const auto itemPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "item_ptr", block);
- const auto item = new LoadInst(itemPtr, "item", block);
-
- codegenItem->CreateSetValue(ctx, block, item);
-
- const auto newState = GetNodeValue(NewState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, newState);
-
- const auto next = BinaryOperator::CreateAdd(index, ConstantInt::get(sizeType, 1), "next", block);
- index->addIncoming(next, block);
-
- BranchInst::Create(loop, block);
- }
-
- {
- block = slow;
-
- const auto iterPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(valueType, 0U, "iter_ptr", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
- const auto iter = new LoadInst(iterPtr, "iter", block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
-
- BranchInst::Create(good, stop, status, block);
- block = good;
-
- const auto newState = GetNodeValue(NewState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, newState);
-
- BranchInst::Create(loop, block);
-
- block = stop;
- UnRefBoxed(iter, ctx, block);
- BranchInst::Create(done, block);
- }
-
+#ifndef MKQL_DISABLE_CODEGEN
+ llvm::Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto &context = ctx.Codegen->GetContext();
+
+ const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenState, "State must be codegenerator node.");
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+
+ const auto init = GetNodeValue(InitialState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, init);
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+
+ {
+ block = fast;
+ const auto sizeType = Type::getInt64Ty(context);
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(sizeType, list, ctx.Codegen, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto index = PHINode::Create(sizeType, 2U, "index", loop);
+ index->addIncoming(ConstantInt::get(sizeType, 0), block);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "more", block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ BranchInst::Create(good, done, more, block);
+
+ block = good;
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "item_ptr", block);
+ const auto item = new LoadInst(itemPtr, "item", block);
+
+ codegenItem->CreateSetValue(ctx, block, item);
+
+ const auto newState = GetNodeValue(NewState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, newState);
+
+ const auto next = BinaryOperator::CreateAdd(index, ConstantInt::get(sizeType, 1), "next", block);
+ index->addIncoming(next, block);
+
+ BranchInst::Create(loop, block);
+ }
+
+ {
+ block = slow;
+
+ const auto iterPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(valueType, 0U, "iter_ptr", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
+ const auto iter = new LoadInst(iterPtr, "iter", block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
+
+ BranchInst::Create(good, stop, status, block);
+ block = good;
+
+ const auto newState = GetNodeValue(NewState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, newState);
+
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ UnRefBoxed(iter, ctx, block);
+ BranchInst::Create(done, block);
+ }
+
block = done;
- if (List->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- return codegenState->CreateGetValue(ctx, block);
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
+ if (List->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ return codegenState->CreateGetValue(ctx, block);
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
this->DependsOn(InitialState);
this->Own(Item);
this->Own(State);
- this->DependsOn(NewState);
+ this->DependsOn(NewState);
}
IComputationNode* const List;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
IComputationNode* const NewState;
IComputationNode* const InitialState;
};
-}
-
+}
+
IComputationNode* WrapFold(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
MKQL_ENSURE(callable.GetInput(0).GetStaticType()->IsList(), "Expected List");
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initialState = LocateNode(ctx.NodeLocator, callable, 1);
- const auto newState = LocateNode(ctx.NodeLocator, callable, 4);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
-
- const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
-
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initialState = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto newState = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+
+ const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
+
return new TFoldWrapper(ctx.Mutables, kind, list, item, state, newState, initialState);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_fold1.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_fold1.cpp
index 01f5baca9b..e6fab3f0a3 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_fold1.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_fold1.cpp
@@ -4,14 +4,14 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TFold1Wrapper : public TMutableCodegeneratorRootNode<TFold1Wrapper> {
typedef TMutableCodegeneratorRootNode<TFold1Wrapper> TBaseComputation;
public:
- TFold1Wrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state,
+ TFold1Wrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state,
IComputationNode* newState, IComputationNode* initialState)
- : TBaseComputation(mutables, kind)
+ : TBaseComputation(mutables, kind)
, List(list)
, Item(item)
, State(state)
@@ -21,200 +21,200 @@ public:
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- ui64 length = 0ULL;
+ ui64 length = 0ULL;
TThresher<false>::DoForEachItem(List->GetValue(compCtx),
[this, &length, &compCtx] (NUdf::TUnboxedValue&& item) {
Item->SetValue(compCtx, std::move(item));
State->SetValue(compCtx, (length++ ? NewState : InitialState)->GetValue(compCtx));
- }
- );
-
+ }
+ );
+
return length ? State->GetValue(compCtx).Release().MakeOptional() : NUdf::TUnboxedValuePod();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto &context = ctx.Codegen->GetContext();
-
- const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenState, "State must be codegenerator node.");
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(valueType, 3, "result", exit);
-
- BranchInst::Create(slow, fast, null, block);
-
- {
- block = fast;
- const auto sizeType = Type::getInt64Ty(context);
- const auto nil = ConstantInt::get(sizeType, 0);
- const auto one = ConstantInt::get(sizeType, 1);
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(sizeType, list, ctx.Codegen, block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto index = PHINode::Create(sizeType, 2, "index", loop);
-
- const auto more1 = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, nil, size, "more1", block);
- result->addIncoming(ConstantInt::get(valueType, 0), block);
-
- BranchInst::Create(next, exit, more1, block);
-
- block = next;
-
- const auto item1Ptr = GetElementPtrInst::CreateInBounds(elements, {nil}, "item1_ptr", block);
- const auto item1 = new LoadInst(item1Ptr, "item1", block);
- codegenItem->CreateSetValue(ctx, block, item1);
-
- const auto init = GetNodeValue(InitialState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, init);
-
- index->addIncoming(one, block);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "more", block);
-
- BranchInst::Create(good, done, more, block);
-
- block = good;
-
- const auto itemPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "item_ptr", block);
- const auto item = new LoadInst(itemPtr, "item", block);
-
- codegenItem->CreateSetValue(ctx, block, item);
-
- const auto newState = GetNodeValue(NewState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, newState);
-
- const auto plus = BinaryOperator::CreateAdd(index, one, "plus", block);
- index->addIncoming(plus, block);
-
- BranchInst::Create(loop, block);
-
- block = done;
-
- const auto res = codegenState->CreateGetValue(ctx, block);
- const auto opt = MakeOptional(context, res, block);
- result->addIncoming(opt, block);
- BranchInst::Create(exit, block);
- }
-
- {
- block = slow;
-
- const auto iterPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(valueType, 0U, "iter_ptr", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
- const auto iter = new LoadInst(iterPtr, "iter", block);
-
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto step = PHINode::Create(valueType, 2, "step", stop);
-
- const auto item1Ptr = codegenItem->CreateRefValue(ctx, block);
- const auto status1 = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, item1Ptr);
-
- step->addIncoming(ConstantInt::get(valueType, 0), block);
- BranchInst::Create(next, stop, status1, block);
-
- block = next;
-
- const auto init = GetNodeValue(InitialState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, init);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
-
- BranchInst::Create(good, done, status, block);
- block = good;
-
- const auto newState = GetNodeValue(NewState, ctx, block);
-
- codegenState->CreateSetValue(ctx, block, newState);
-
- BranchInst::Create(loop, block);
-
- block = done;
-
- const auto res = codegenState->CreateGetValue(ctx, block);
- const auto opt = MakeOptional(context, res, block);
- step->addIncoming(opt, block);
- BranchInst::Create(stop, block);
-
- block = stop;
-
- UnRefBoxed(iter, ctx, block);
- result->addIncoming(step, block);
- BranchInst::Create(exit, block);
- }
-
- block = exit;
- if (List->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- return result;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto &context = ctx.Codegen->GetContext();
+
+ const auto codegenState = dynamic_cast<ICodegeneratorExternalNode*>(State);
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenState, "State must be codegenerator node.");
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(valueType, 3, "result", exit);
+
+ BranchInst::Create(slow, fast, null, block);
+
+ {
+ block = fast;
+ const auto sizeType = Type::getInt64Ty(context);
+ const auto nil = ConstantInt::get(sizeType, 0);
+ const auto one = ConstantInt::get(sizeType, 1);
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(sizeType, list, ctx.Codegen, block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto index = PHINode::Create(sizeType, 2, "index", loop);
+
+ const auto more1 = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, nil, size, "more1", block);
+ result->addIncoming(ConstantInt::get(valueType, 0), block);
+
+ BranchInst::Create(next, exit, more1, block);
+
+ block = next;
+
+ const auto item1Ptr = GetElementPtrInst::CreateInBounds(elements, {nil}, "item1_ptr", block);
+ const auto item1 = new LoadInst(item1Ptr, "item1", block);
+ codegenItem->CreateSetValue(ctx, block, item1);
+
+ const auto init = GetNodeValue(InitialState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, init);
+
+ index->addIncoming(one, block);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "more", block);
+
+ BranchInst::Create(good, done, more, block);
+
+ block = good;
+
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "item_ptr", block);
+ const auto item = new LoadInst(itemPtr, "item", block);
+
+ codegenItem->CreateSetValue(ctx, block, item);
+
+ const auto newState = GetNodeValue(NewState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, newState);
+
+ const auto plus = BinaryOperator::CreateAdd(index, one, "plus", block);
+ index->addIncoming(plus, block);
+
+ BranchInst::Create(loop, block);
+
+ block = done;
+
+ const auto res = codegenState->CreateGetValue(ctx, block);
+ const auto opt = MakeOptional(context, res, block);
+ result->addIncoming(opt, block);
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = slow;
+
+ const auto iterPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(valueType, 0U, "iter_ptr", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
+ const auto iter = new LoadInst(iterPtr, "iter", block);
+
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto step = PHINode::Create(valueType, 2, "step", stop);
+
+ const auto item1Ptr = codegenItem->CreateRefValue(ctx, block);
+ const auto status1 = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, item1Ptr);
+
+ step->addIncoming(ConstantInt::get(valueType, 0), block);
+ BranchInst::Create(next, stop, status1, block);
+
+ block = next;
+
+ const auto init = GetNodeValue(InitialState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, init);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
+
+ BranchInst::Create(good, done, status, block);
+ block = good;
+
+ const auto newState = GetNodeValue(NewState, ctx, block);
+
+ codegenState->CreateSetValue(ctx, block, newState);
+
+ BranchInst::Create(loop, block);
+
+ block = done;
+
+ const auto res = codegenState->CreateGetValue(ctx, block);
+ const auto opt = MakeOptional(context, res, block);
+ step->addIncoming(opt, block);
+ BranchInst::Create(stop, block);
+
+ block = stop;
+
+ UnRefBoxed(iter, ctx, block);
+ result->addIncoming(step, block);
+ BranchInst::Create(exit, block);
+ }
+
+ block = exit;
+ if (List->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ return result;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
this->DependsOn(InitialState);
this->Own(Item);
this->Own(State);
- this->DependsOn(NewState);
+ this->DependsOn(NewState);
}
IComputationNode* const List;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
IComputationNode* const NewState;
IComputationNode* const InitialState;
};
-}
-
+}
+
IComputationNode* WrapFold1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
MKQL_ENSURE(callable.GetInput(0).GetStaticType()->IsList(), "Expected List");
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto initialState = LocateNode(ctx.NodeLocator, callable, 2);
- const auto newState = LocateNode(ctx.NodeLocator, callable, 4);
- const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
-
- const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
-
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto initialState = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto newState = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto state = LocateExternalNode(ctx.NodeLocator, callable, 3);
+
+ const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
+
return new TFold1Wrapper(ctx.Mutables, kind, list, item, state, newState, initialState);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_frombytes.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_frombytes.cpp
index aeb51580b7..16f9109b70 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_frombytes.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_frombytes.cpp
@@ -13,8 +13,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
using NYql::SwapBytes;
template <bool IsOptional>
@@ -53,7 +53,7 @@ public:
return ret;
}
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
case NUdf::EDataSlot::TzDatetime: {
@@ -114,28 +114,28 @@ public:
}
}
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
}
IComputationNode* const Data;
const NUdf::EDataSlot SchemeType;
};
-}
-
+}
+
IComputationNode* WrapFromBytes(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected String");
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected String");
- const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
+ const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
if (isOptional) {
return new TFromBytesWrapper<true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
} else {
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_fromstring.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_fromstring.cpp
index 0183dd72f3..7090aff8cd 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_fromstring.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_fromstring.cpp
@@ -5,331 +5,331 @@
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h>
-
+
#include <ydb/library/yql/public/udf/udf_terminator.h>
#ifndef MKQL_DISABLE_CODEGEN
-extern "C" NKikimr::NUdf::TUnboxedValuePod DataFromString(const NKikimr::NUdf::TUnboxedValuePod data, NKikimr::NUdf::EDataSlot slot) {
- return NKikimr::NMiniKQL::ValueFromString(slot, data.AsStringRef());
-}
-
-extern "C" NYql::NDecimal::TInt128 DecimalFromString(const NKikimr::NUdf::TUnboxedValuePod decimal, ui8 precision, ui8 scale) {
- return NYql::NDecimal::FromStringEx(decimal.AsStringRef(), precision, scale);
-}
+extern "C" NKikimr::NUdf::TUnboxedValuePod DataFromString(const NKikimr::NUdf::TUnboxedValuePod data, NKikimr::NUdf::EDataSlot slot) {
+ return NKikimr::NMiniKQL::ValueFromString(slot, data.AsStringRef());
+}
+
+extern "C" NYql::NDecimal::TInt128 DecimalFromString(const NKikimr::NUdf::TUnboxedValuePod decimal, ui8 precision, ui8 scale) {
+ return NYql::NDecimal::FromStringEx(decimal.AsStringRef(), precision, scale);
+}
#endif
-
+
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool IsStrict, bool IsOptional>
-class TDecimalFromStringWrapper : public TMutableCodegeneratorNode<TDecimalFromStringWrapper<IsStrict, IsOptional>> {
- typedef TMutableCodegeneratorNode<TDecimalFromStringWrapper<IsStrict, IsOptional>> TBaseComputation;
+class TDecimalFromStringWrapper : public TMutableCodegeneratorNode<TDecimalFromStringWrapper<IsStrict, IsOptional>> {
+ typedef TMutableCodegeneratorNode<TDecimalFromStringWrapper<IsStrict, IsOptional>> TBaseComputation;
public:
- TDecimalFromStringWrapper(TComputationMutables& mutables, IComputationNode* data, ui8 precision, ui8 scale)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ TDecimalFromStringWrapper(TComputationMutables& mutables, IComputationNode* data, ui8 precision, ui8 scale)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
, Data(data)
- , Precision(precision)
- , Scale(scale)
+ , Precision(precision)
+ , Scale(scale)
{
- MKQL_ENSURE(precision > 0 && precision <= NYql::NDecimal::MaxPrecision, "Wrong precision.");
- MKQL_ENSURE(scale <= precision, "Wrong scale.");
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& data = Data->GetValue(ctx);
- if (IsOptional && !data) {
- return NUdf::TUnboxedValuePod();
- }
-
- if (const auto v = NYql::NDecimal::FromStringEx(data.AsStringRef(), Precision, Scale); !NYql::NDecimal::IsError(v)) {
- return NUdf::TUnboxedValuePod(v);
- }
-
- if (IsStrict) {
- Throw(data, Precision, Scale);
- } else {
- return NUdf::TUnboxedValuePod();
- }
+ MKQL_ENSURE(precision > 0 && precision <= NYql::NDecimal::MaxPrecision, "Wrong precision.");
+ MKQL_ENSURE(scale <= precision, "Wrong scale.");
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto& data = Data->GetValue(ctx);
+ if (IsOptional && !data) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ if (const auto v = NYql::NDecimal::FromStringEx(data.AsStringRef(), Precision, Scale); !NYql::NDecimal::IsError(v)) {
+ return NUdf::TUnboxedValuePod(v);
+ }
+
+ if (IsStrict) {
+ Throw(data, Precision, Scale);
+ } else {
+ return NUdf::TUnboxedValuePod();
+ }
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto psType = Type::getInt8Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto name = "DecimalFromString";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalFromString));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto psType = Type::getInt8Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto name = "DecimalFromString";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalFromString));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, psType, psType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, psType, psType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, psType, psType }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, psType, psType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto precision = ConstantInt::get(psType, Precision);
- const auto scale = ConstantInt::get(psType, Scale);
- const auto value = GetNodeValue(Data, ctx, block);
-
- const auto fail = BasicBlock::Create(context, "fail", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto ways = (IsOptional ? 1U : 0U) + (IsStrict ? 0U : 1U);
- const auto last = ways > 0U ? BasicBlock::Create(context, "last", ctx.Func) : nullptr;
- const auto phi = last ? PHINode::Create(valType, ways + 1U, "result", last) : nullptr;
-
- if (IsOptional) {
- phi->addIncoming(zero, block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
-
- const auto call = BasicBlock::Create(context, "call", ctx.Func);
- BranchInst::Create(last, call, check, block);
- block = call;
- }
-
- Value* decimal;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- decimal = CallInst::Create(func, { value, precision, scale }, "from_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(value, retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
- decimal = new LoadInst(retPtr, "res", block);
- }
-
- if (Data->IsTemporaryValue())
- ValueCleanup(Data->GetRepresentation(), value, ctx, block);
-
- const auto test = NDecimal::GenIsError(decimal, context, block);
- BranchInst::Create(fail, good, test, block);
-
- {
- block = fail;
- if (IsStrict) {
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDecimalFromStringWrapper::Throw));
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {valType, psType, psType}, false)), "thrower", block);
- CallInst::Create(doFuncPtr, { value, precision, scale }, "", block);
- new UnreachableInst(context, block);
- } else {
- phi->addIncoming(zero, block);
- BranchInst::Create(last, block);
- }
- }
-
- block = good;
-
+ }
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto precision = ConstantInt::get(psType, Precision);
+ const auto scale = ConstantInt::get(psType, Scale);
+ const auto value = GetNodeValue(Data, ctx, block);
+
+ const auto fail = BasicBlock::Create(context, "fail", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto ways = (IsOptional ? 1U : 0U) + (IsStrict ? 0U : 1U);
+ const auto last = ways > 0U ? BasicBlock::Create(context, "last", ctx.Func) : nullptr;
+ const auto phi = last ? PHINode::Create(valType, ways + 1U, "result", last) : nullptr;
+
+ if (IsOptional) {
+ phi->addIncoming(zero, block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
+
+ const auto call = BasicBlock::Create(context, "call", ctx.Func);
+ BranchInst::Create(last, call, check, block);
+ block = call;
+ }
+
+ Value* decimal;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ decimal = CallInst::Create(func, { value, precision, scale }, "from_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(value, retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
+ decimal = new LoadInst(retPtr, "res", block);
+ }
+
+ if (Data->IsTemporaryValue())
+ ValueCleanup(Data->GetRepresentation(), value, ctx, block);
+
+ const auto test = NDecimal::GenIsError(decimal, context, block);
+ BranchInst::Create(fail, good, test, block);
+
+ {
+ block = fail;
+ if (IsStrict) {
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDecimalFromStringWrapper::Throw));
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {valType, psType, psType}, false)), "thrower", block);
+ CallInst::Create(doFuncPtr, { value, precision, scale }, "", block);
+ new UnreachableInst(context, block);
+ } else {
+ phi->addIncoming(zero, block);
+ BranchInst::Create(last, block);
+ }
+ }
+
+ block = good;
+
if (IsOptional || !IsStrict) {
- phi->addIncoming(SetterForInt128(decimal, block), block);
- BranchInst::Create(last, block);
-
- block = last;
- return phi;
- } else {
- return SetterForInt128(decimal, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
- }
-
- [[noreturn]] static void Throw(const NUdf::TUnboxedValuePod data, ui8 precision, ui8 scale) {
- const auto& ref = data.AsStringRef();
- UdfTerminate((TStringBuilder() << "could not convert "
- << TString(ref.Data(), ref.Size()).Quote()
- << " to Decimal(" << unsigned(precision) << "," << unsigned(scale) << ")").data());
- }
-
- IComputationNode* const Data;
- const ui8 Precision, Scale;
-};
-
-template <bool IsStrict, bool IsOptional>
-class TFromStringWrapper : public TMutableCodegeneratorNode<TFromStringWrapper<IsStrict, IsOptional>> {
- typedef TMutableCodegeneratorNode<TFromStringWrapper<IsStrict, IsOptional>> TBaseComputation;
-public:
- TFromStringWrapper(TComputationMutables& mutables, IComputationNode* data, NUdf::TDataTypeId schemeType)
- : TBaseComputation(mutables, GetValueRepresentation(schemeType))
- , Data(data)
- , SchemeType(NUdf::GetDataSlot(schemeType))
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ phi->addIncoming(SetterForInt128(decimal, block), block);
+ BranchInst::Create(last, block);
+
+ block = last;
+ return phi;
+ } else {
+ return SetterForInt128(decimal, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
+ }
+
+ [[noreturn]] static void Throw(const NUdf::TUnboxedValuePod data, ui8 precision, ui8 scale) {
+ const auto& ref = data.AsStringRef();
+ UdfTerminate((TStringBuilder() << "could not convert "
+ << TString(ref.Data(), ref.Size()).Quote()
+ << " to Decimal(" << unsigned(precision) << "," << unsigned(scale) << ")").data());
+ }
+
+ IComputationNode* const Data;
+ const ui8 Precision, Scale;
+};
+
+template <bool IsStrict, bool IsOptional>
+class TFromStringWrapper : public TMutableCodegeneratorNode<TFromStringWrapper<IsStrict, IsOptional>> {
+ typedef TMutableCodegeneratorNode<TFromStringWrapper<IsStrict, IsOptional>> TBaseComputation;
+public:
+ TFromStringWrapper(TComputationMutables& mutables, IComputationNode* data, NUdf::TDataTypeId schemeType)
+ : TBaseComputation(mutables, GetValueRepresentation(schemeType))
+ , Data(data)
+ , SchemeType(NUdf::GetDataSlot(schemeType))
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
const auto& data = Data->GetValue(ctx);
- if (IsOptional && !data) {
- return NUdf::TUnboxedValuePod();
+ if (IsOptional && !data) {
+ return NUdf::TUnboxedValuePod();
}
-
- if (const auto out = ValueFromString(SchemeType, data.AsStringRef())) {
- return out;
+
+ if (const auto out = ValueFromString(SchemeType, data.AsStringRef())) {
+ return out;
}
-
+
if (IsStrict) {
- Throw(data, SchemeType);
+ Throw(data, SchemeType);
} else {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto slotType = Type::getInt32Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto name = "DataFromString";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DataFromString));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto slotType = Type::getInt32Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto name = "DataFromString";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DataFromString));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, slotType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, slotType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, slotType }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, slotType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto slot = ConstantInt::get(slotType, static_cast<ui32>(SchemeType));
- const auto value = GetNodeValue(Data, ctx, block);
-
- const auto fail = IsStrict ? BasicBlock::Create(context, "fail", ctx.Func) : nullptr;
- const auto last = IsOptional || fail ? BasicBlock::Create(context, "last", ctx.Func) : nullptr;
- const auto phi = IsOptional ? PHINode::Create(valType, 2U, "result", last) : nullptr;
-
- if (IsOptional) {
- phi->addIncoming(zero, block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
-
- const auto call = BasicBlock::Create(context, "call", ctx.Func);
- BranchInst::Create(last, call, check, block);
- block = call;
- }
-
- Value* data;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- data = CallInst::Create(func, { value, slot }, "from_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(value, retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, slot }, "", block);
- data = new LoadInst(retPtr, "res", block);
- }
-
- if (Data->IsTemporaryValue())
- ValueCleanup(Data->GetRepresentation(), value, ctx, block);
-
+ }
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto slot = ConstantInt::get(slotType, static_cast<ui32>(SchemeType));
+ const auto value = GetNodeValue(Data, ctx, block);
+
+ const auto fail = IsStrict ? BasicBlock::Create(context, "fail", ctx.Func) : nullptr;
+ const auto last = IsOptional || fail ? BasicBlock::Create(context, "last", ctx.Func) : nullptr;
+ const auto phi = IsOptional ? PHINode::Create(valType, 2U, "result", last) : nullptr;
+
if (IsOptional) {
- phi->addIncoming(data, block);
- }
-
- if (IsStrict) {
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, data, zero, "test", block);
- BranchInst::Create(fail, last, test, block);
-
- block = fail;
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFromStringWrapper::Throw));
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {valType, slotType}, false)), "thrower", block);
- CallInst::Create(doFuncPtr, { value, slot }, "", block);
- new UnreachableInst(context, block);
+ phi->addIncoming(zero, block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
+
+ const auto call = BasicBlock::Create(context, "call", ctx.Func);
+ BranchInst::Create(last, call, check, block);
+ block = call;
+ }
+
+ Value* data;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ data = CallInst::Create(func, { value, slot }, "from_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(value, retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, slot }, "", block);
+ data = new LoadInst(retPtr, "res", block);
+ }
+
+ if (Data->IsTemporaryValue())
+ ValueCleanup(Data->GetRepresentation(), value, ctx, block);
+
+ if (IsOptional) {
+ phi->addIncoming(data, block);
+ }
+
+ if (IsStrict) {
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, data, zero, "test", block);
+ BranchInst::Create(fail, last, test, block);
+
+ block = fail;
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFromStringWrapper::Throw));
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {valType, slotType}, false)), "thrower", block);
+ CallInst::Create(doFuncPtr, { value, slot }, "", block);
+ new UnreachableInst(context, block);
} else if (IsOptional) {
- BranchInst::Create(last, block);
- }
-
+ BranchInst::Create(last, block);
+ }
+
if (IsOptional || IsStrict) {
- block = last;
- }
-
+ block = last;
+ }
+
return IsOptional ? phi : data;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
+ }
+
+ [[noreturn]] static void Throw(const NUdf::TUnboxedValuePod data, NUdf::EDataSlot slot) {
+ const auto& ref = data.AsStringRef();
+ UdfTerminate((TStringBuilder() << "could not convert "
+ << TString(ref.Data(), ref.Size()).Quote()
+ << " to " << NUdf::GetDataTypeInfo(slot).Name).data());
}
- [[noreturn]] static void Throw(const NUdf::TUnboxedValuePod data, NUdf::EDataSlot slot) {
- const auto& ref = data.AsStringRef();
- UdfTerminate((TStringBuilder() << "could not convert "
- << TString(ref.Data(), ref.Size()).Quote()
- << " to " << NUdf::GetDataTypeInfo(slot).Name).data());
- }
-
IComputationNode* const Data;
const NUdf::EDataSlot SchemeType;
};
-}
-
+}
+
IComputationNode* WrapFromString(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 2, "Expected 2 args");
+ MKQL_ENSURE(callable.GetInputsCount() >= 2, "Expected 2 args");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id || dataType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
-
- const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
-
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
- if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
- const auto precision = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().Get<ui8>();
- const auto scale = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui8>();
-
- if (isOptional) {
- return new TDecimalFromStringWrapper<false, true>(ctx.Mutables, data, precision, scale);
- } else {
- return new TDecimalFromStringWrapper<false, false>(ctx.Mutables, data, precision, scale);
- }
- } else {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- if (isOptional) {
- return new TFromStringWrapper<false, true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- } else {
- return new TFromStringWrapper<false, false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- }
- }
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id || dataType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
+
+ const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
+
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
+ MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
+ const auto precision = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().Get<ui8>();
+ const auto scale = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui8>();
+
+ if (isOptional) {
+ return new TDecimalFromStringWrapper<false, true>(ctx.Mutables, data, precision, scale);
+ } else {
+ return new TDecimalFromStringWrapper<false, false>(ctx.Mutables, data, precision, scale);
+ }
+ } else {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
+ if (isOptional) {
+ return new TFromStringWrapper<false, true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ } else {
+ return new TFromStringWrapper<false, false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ }
+ }
}
IComputationNode* WrapStrictFromString(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 2, "Expected 2 args");
+ MKQL_ENSURE(callable.GetInputsCount() >= 2, "Expected 2 args");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id || dataType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
-
- const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
-
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
- if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
- const auto precision = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().Get<ui8>();
- const auto scale = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui8>();
-
- if (isOptional) {
- return new TDecimalFromStringWrapper<true, true>(ctx.Mutables, data, precision, scale);
- } else {
- return new TDecimalFromStringWrapper<true, false>(ctx.Mutables, data, precision, scale);
- }
- } else {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
-
- if (isOptional) {
- return new TFromStringWrapper<true, true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- } else {
- return new TFromStringWrapper<true, false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- }
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id || dataType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
+
+ const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
+
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
+ MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
+ const auto precision = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().Get<ui8>();
+ const auto scale = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui8>();
+
+ if (isOptional) {
+ return new TDecimalFromStringWrapper<true, true>(ctx.Mutables, data, precision, scale);
+ } else {
+ return new TDecimalFromStringWrapper<true, false>(ctx.Mutables, data, precision, scale);
+ }
+ } else {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
+
+ if (isOptional) {
+ return new TFromStringWrapper<true, true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ } else {
+ return new TFromStringWrapper<true, false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_fromyson.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_fromyson.cpp
index 2de7f042b7..98aa7d9c3e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_fromyson.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_fromyson.cpp
@@ -6,56 +6,56 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsOptional>
-class TFromYsonSimpleTypeWrapper : public TMutableComputationNode<TFromYsonSimpleTypeWrapper<IsOptional>> {
- typedef TMutableComputationNode<TFromYsonSimpleTypeWrapper<IsOptional>> TBaseComputation;
+namespace {
+
+template<bool IsOptional>
+class TFromYsonSimpleTypeWrapper : public TMutableComputationNode<TFromYsonSimpleTypeWrapper<IsOptional>> {
+ typedef TMutableComputationNode<TFromYsonSimpleTypeWrapper<IsOptional>> TBaseComputation;
public:
TFromYsonSimpleTypeWrapper(TComputationMutables& mutables, IComputationNode* data, NUdf::TDataTypeId schemeType)
: TBaseComputation(mutables)
, Data(data)
, SchemeType(NUdf::GetDataSlot(schemeType))
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& data = Data->GetValue(ctx);
- if (IsOptional && !data) {
- return NUdf::TUnboxedValuePod();
+ if (IsOptional && !data) {
+ return NUdf::TUnboxedValuePod();
}
- return SimpleValueFromYson(SchemeType, data.AsStringRef());
+ return SimpleValueFromYson(SchemeType, data.AsStringRef());
}
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
}
IComputationNode* const Data;
const NUdf::EDataSlot SchemeType;
};
-}
-
+}
+
IComputationNode* WrapFromYsonSimpleType(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- const auto dataSchemeType = dataType->GetSchemeType();
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ const auto dataSchemeType = dataType->GetSchemeType();
MKQL_ENSURE(dataSchemeType == NUdf::TDataType<char*>::Id || dataSchemeType == NUdf::TDataType<NUdf::TYson>::Id,
"Expected String or Yson");
- const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
+ const auto schemeTypeData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const auto schemeType = schemeTypeData->AsValue().Get<ui32>();
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
- if (isOptional) {
- return new TFromYsonSimpleTypeWrapper<true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- } else {
- return new TFromYsonSimpleTypeWrapper<false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
- }
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ if (isOptional) {
+ return new TFromYsonSimpleTypeWrapper<true>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ } else {
+ return new TFromYsonSimpleTypeWrapper<false>(ctx.Mutables, data, static_cast<NUdf::TDataTypeId>(schemeType));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_group.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_group.cpp
index 20c28776b7..0d0ff62fae 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_group.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_group.cpp
@@ -11,8 +11,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool WithHandler>
class TGroupingCoreWrapper: public TMutableComputationNode<TGroupingCoreWrapper<WithHandler>> {
using TSelf = TGroupingCoreWrapper;
@@ -151,10 +151,10 @@ public:
TGroupingCoreWrapper(TComputationMutables& mutables,
IComputationNode* stream,
- IComputationExternalNode* keyExtractorItem,
+ IComputationExternalNode* keyExtractorItem,
IComputationNode* keyExtractorResult,
- IComputationExternalNode* groupSwitchKey,
- IComputationExternalNode* groupSwitchItem,
+ IComputationExternalNode* groupSwitchKey,
+ IComputationExternalNode* groupSwitchItem,
IComputationNode* groupSwitchResult,
IComputationExternalNode* handlerItem,
IComputationNode* handlerResult)
@@ -189,28 +189,28 @@ private:
private:
IComputationNode* const Stream;
- IComputationExternalNode* const KeyExtractorItemNode;
+ IComputationExternalNode* const KeyExtractorItemNode;
IComputationNode* const KeyExtractorResultNode;
- IComputationExternalNode* const GroupSwitchKeyNode;
- IComputationExternalNode* const GroupSwitchItemNode;
+ IComputationExternalNode* const GroupSwitchKeyNode;
+ IComputationExternalNode* const GroupSwitchItemNode;
IComputationNode* const GroupSwitchResultNode;
IComputationExternalNode* const HandlerItemNode;
IComputationNode* const HandlerResultNode;
};
-}
-
+}
+
IComputationNode* WrapGroupingCore(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 6 || callable.GetInputsCount() == 8, "Expected 6 or 8 args");
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto keyExtractorResult = LocateNode(ctx.NodeLocator, callable, 1);
- const auto groupSwitchResult = LocateNode(ctx.NodeLocator, callable, 2);
- const auto keyExtractorItem = LocateExternalNode(ctx.NodeLocator, callable, 3);
- const auto groupSwitchKey = LocateExternalNode(ctx.NodeLocator, callable, 4);
- const auto groupSwitchItem = LocateExternalNode(ctx.NodeLocator, callable, 5);
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto keyExtractorResult = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto groupSwitchResult = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto keyExtractorItem = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto groupSwitchKey = LocateExternalNode(ctx.NodeLocator, callable, 4);
+ const auto groupSwitchItem = LocateExternalNode(ctx.NodeLocator, callable, 5);
if (callable.GetInputsCount() == 8) {
auto handlerResult = LocateNode(ctx.NodeLocator, callable, 6);
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_guess.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_guess.cpp
index b9cfdae43b..0e0c734a5e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_guess.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_guess.cpp
@@ -6,14 +6,14 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool IsOptional>
-class TGuessWrapper: public TMutableCodegeneratorPtrNode<TGuessWrapper<IsOptional>> {
- typedef TMutableCodegeneratorPtrNode<TGuessWrapper<IsOptional>> TBaseComputation;
+class TGuessWrapper: public TMutableCodegeneratorPtrNode<TGuessWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorPtrNode<TGuessWrapper<IsOptional>> TBaseComputation;
public:
- TGuessWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, ui32 index)
- : TBaseComputation(mutables, kind)
+ TGuessWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, ui32 index)
+ : TBaseComputation(mutables, kind)
, VarNode(varNode)
, Index(index)
{
@@ -22,130 +22,130 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
auto var = VarNode->GetValue(compCtx);
- if (IsOptional && !var) {
- return NUdf::TUnboxedValuePod();
+ if (IsOptional && !var) {
+ return NUdf::TUnboxedValuePod();
}
- const auto currentIndex = var.GetVariantIndex();
+ const auto currentIndex = var.GetVariantIndex();
if (Index == currentIndex) {
- return var.Release().GetVariantItem().MakeOptional();
+ return var.Release().GetVariantItem().MakeOptional();
} else {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt32Ty(context);
-
- const auto var = GetNodeValue(VarNode, ctx, block);
-
- const auto ind = ConstantInt::get(indexType, Index);
- const auto zero = ConstantInt::get(valueType, 0ULL);
-
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
-
- if (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- BranchInst::Create(none, good, IsEmpty(var, block), block);
-
- block = good;
- }
-
- const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
-
- const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
- const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
-
- const auto index = PHINode::Create(indexType, 2, "index", step);
-
- BranchInst::Create(embed, boxed, check, block);
-
- block = embed;
-
- const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(indexType, 1), "dec", block);
- index->addIncoming(dec, block);
- BranchInst::Create(step, block);
-
- block = boxed;
-
- const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(indexType, var, ctx.Codegen, block);
- index->addIncoming(idx, block);
- BranchInst::Create(step, block);
-
- block = step;
-
- const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ind, "equal", block);
-
- const auto same = BasicBlock::Create(context, "same", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(same, none, equal, block);
-
- block = none;
- new StoreInst(zero, pointer, block);
- BranchInst::Create(done, block);
-
- block = same;
-
- const auto box = BasicBlock::Create(context, "box", ctx.Func);
- const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
- BranchInst::Create(emb, box, check, block);
-
- block = emb;
-
- const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
- const auto mask = ConstantInt::get(valueType, APInt(128, 2, init));
- const auto clean = BinaryOperator::CreateAnd(var, mask, "clean", block);
- new StoreInst(MakeOptional(context, clean, block), pointer, block);
- ValueAddRef(this->RepresentationKind, pointer, ctx, block);
-
- BranchInst::Create(done, block);
-
- block = box;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(pointer, var, ctx.Codegen, block);
-
- const auto load = new LoadInst(pointer, "load", block);
- new StoreInst(MakeOptional(context, load, block), pointer, block);
-
- BranchInst::Create(done, block);
-
- block = done;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(VarNode);
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+
+ const auto var = GetNodeValue(VarNode, ctx, block);
+
+ const auto ind = ConstantInt::get(indexType, Index);
+ const auto zero = ConstantInt::get(valueType, 0ULL);
+
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+
+ if (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ BranchInst::Create(none, good, IsEmpty(var, block), block);
+
+ block = good;
+ }
+
+ const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
+
+ const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
+ const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+
+ const auto index = PHINode::Create(indexType, 2, "index", step);
+
+ BranchInst::Create(embed, boxed, check, block);
+
+ block = embed;
+
+ const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(indexType, 1), "dec", block);
+ index->addIncoming(dec, block);
+ BranchInst::Create(step, block);
+
+ block = boxed;
+
+ const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(indexType, var, ctx.Codegen, block);
+ index->addIncoming(idx, block);
+ BranchInst::Create(step, block);
+
+ block = step;
+
+ const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ind, "equal", block);
+
+ const auto same = BasicBlock::Create(context, "same", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(same, none, equal, block);
+
+ block = none;
+ new StoreInst(zero, pointer, block);
+ BranchInst::Create(done, block);
+
+ block = same;
+
+ const auto box = BasicBlock::Create(context, "box", ctx.Func);
+ const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
+ BranchInst::Create(emb, box, check, block);
+
+ block = emb;
+
+ const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
+ const auto mask = ConstantInt::get(valueType, APInt(128, 2, init));
+ const auto clean = BinaryOperator::CreateAnd(var, mask, "clean", block);
+ new StoreInst(MakeOptional(context, clean, block), pointer, block);
+ ValueAddRef(this->RepresentationKind, pointer, ctx, block);
+
+ BranchInst::Create(done, block);
+
+ block = box;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(pointer, var, ctx.Codegen, block);
+
+ const auto load = new LoadInst(pointer, "load", block);
+ new StoreInst(MakeOptional(context, load, block), pointer, block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(VarNode);
}
- IComputationNode *const VarNode;
+ IComputationNode *const VarNode;
const ui32 Index;
};
-}
-
+}
+
IComputationNode* WrapGuess(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 arguments");
bool isOptional;
- const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
- const auto varType = AS_TYPE(TVariantType, unpacked);
+ const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
+ const auto varType = AS_TYPE(TVariantType, unpacked);
- const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const ui32 index = indexData->AsValue().Get<ui32>();
+ const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const ui32 index = indexData->AsValue().Get<ui32>();
MKQL_ENSURE(index < varType->GetAlternativesCount(), "Bad alternative index");
- const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
if (isOptional) {
- return new TGuessWrapper<true>(ctx.Mutables, GetValueRepresentation(varType->GetAlternativeType(index)), variant, index);
+ return new TGuessWrapper<true>(ctx.Mutables, GetValueRepresentation(varType->GetAlternativeType(index)), variant, index);
} else {
- return new TGuessWrapper<false>(ctx.Mutables, GetValueRepresentation(varType->GetAlternativeType(index)), variant, index);
+ return new TGuessWrapper<false>(ctx.Mutables, GetValueRepresentation(varType->GetAlternativeType(index)), variant, index);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_hasitems.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_hasitems.cpp
index b8a2038587..3fb5f02ae8 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_hasitems.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_hasitems.cpp
@@ -6,85 +6,85 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool IsDict, bool IsOptional>
-class THasItemsWrapper : public TMutableCodegeneratorNode<THasItemsWrapper<IsDict, IsOptional>> {
- typedef TMutableCodegeneratorNode<THasItemsWrapper<IsDict, IsOptional>> TBaseComputation;
+namespace {
+
+template <bool IsDict, bool IsOptional>
+class THasItemsWrapper : public TMutableCodegeneratorNode<THasItemsWrapper<IsDict, IsOptional>> {
+ typedef TMutableCodegeneratorNode<THasItemsWrapper<IsDict, IsOptional>> TBaseComputation;
public:
THasItemsWrapper(TComputationMutables& mutables, IComputationNode* collection)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
, Collection(collection)
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& collection = Collection->GetValue(compCtx);
- if (IsOptional && !collection) {
- return NUdf::TUnboxedValuePod();
- }
+ const auto& collection = Collection->GetValue(compCtx);
+ if (IsOptional && !collection) {
+ return NUdf::TUnboxedValuePod();
+ }
const bool hasItems = IsDict ? collection.HasDictItems() : collection.HasListItems();
- return NUdf::TUnboxedValuePod(hasItems);
+ return NUdf::TUnboxedValuePod(hasItems);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto collection = GetNodeValue(Collection, ctx, block);
-
- if constexpr (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(collection->getType(), 2U, "result", done);
-
- result->addIncoming(collection, block);
- BranchInst::Create(done, good, IsEmpty(collection, block), block);
-
- block = good;
-
- const auto has = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::HasDictItems : NUdf::TBoxedValueAccessor::EMethod::HasListItems>(Type::getInt1Ty(context), collection, ctx.Codegen, block);
- if (Collection->IsTemporaryValue())
- CleanupBoxed(collection, ctx, block);
- result->addIncoming(MakeBoolean(has, context, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- const auto has = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::HasDictItems : NUdf::TBoxedValueAccessor::EMethod::HasListItems>(Type::getInt1Ty(context), collection, ctx.Codegen, block);
- if (Collection->IsTemporaryValue())
- CleanupBoxed(collection, ctx, block);
- return MakeBoolean(has, context, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Collection);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto collection = GetNodeValue(Collection, ctx, block);
+
+ if constexpr (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(collection->getType(), 2U, "result", done);
+
+ result->addIncoming(collection, block);
+ BranchInst::Create(done, good, IsEmpty(collection, block), block);
+
+ block = good;
+
+ const auto has = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::HasDictItems : NUdf::TBoxedValueAccessor::EMethod::HasListItems>(Type::getInt1Ty(context), collection, ctx.Codegen, block);
+ if (Collection->IsTemporaryValue())
+ CleanupBoxed(collection, ctx, block);
+ result->addIncoming(MakeBoolean(has, context, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ const auto has = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::HasDictItems : NUdf::TBoxedValueAccessor::EMethod::HasListItems>(Type::getInt1Ty(context), collection, ctx.Codegen, block);
+ if (Collection->IsTemporaryValue())
+ CleanupBoxed(collection, ctx, block);
+ return MakeBoolean(has, context, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Collection);
}
IComputationNode* const Collection;
};
-}
-
+}
+
IComputationNode* WrapHasItems(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- bool isOptional;
- const auto type = UnpackOptional(callable.GetInput(0).GetStaticType(), isOptional);
+ bool isOptional;
+ const auto type = UnpackOptional(callable.GetInput(0).GetStaticType(), isOptional);
if (type->IsDict()) {
- if (isOptional)
- return new THasItemsWrapper<true, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- else
- return new THasItemsWrapper<true, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ if (isOptional)
+ return new THasItemsWrapper<true, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ else
+ return new THasItemsWrapper<true, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
} else {
- if (isOptional)
- return new THasItemsWrapper<false, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- else
- return new THasItemsWrapper<false, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ if (isOptional)
+ return new THasItemsWrapper<false, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ else
+ return new THasItemsWrapper<false, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
}
-
- THROW yexception() << "Expected list or dict.";
+
+ THROW yexception() << "Expected list or dict.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_heap.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_heap.cpp
index 63d96b0ec2..c4b5c291db 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_heap.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_heap.cpp
@@ -1,405 +1,405 @@
-#include "mkql_heap.h"
-
+#include "mkql_heap.h"
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-using TComparator = std::function<bool(const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r)>;
-using TAlgorithm = void(*)(NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, TComparator);
-using TArgsPlace = std::array<NUdf::TUnboxedValuePod, 2U>;
-using TComparePtr = bool (*)(TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r);
-
-class THeapWrapper : public TMutableCodegeneratorNode<THeapWrapper>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
- typedef TMutableCodegeneratorNode<THeapWrapper> TBaseComputation;
-public:
- THeapWrapper(TAlgorithm algorithm, TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
- , Algorithm(algorithm)
- , List(list)
- , Left(left)
- , Right(right)
- , Compare(compare)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- const auto size = list.GetListLength();
-
- if (size < 2U)
- return list.Release();
-
- NUdf::TUnboxedValue *items = nullptr;
- const auto next = ctx.HolderFactory.CloneArray(list.Release(), items);
-
- NUdf::TUnboxedValuePod *const begin = items, *const end = items + size;
-
- Do(ctx, begin, end);
-
- return next;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto fact = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CloneArray));// TODO: Generate code instead of call CloneArray.
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 1ULL), "test", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
- result->addIncoming(list, block);
-
- BranchInst::Create(work, done, test, block);
-
- block = work;
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", block);
-
- const auto idxType = Type::getInt32Ty(context);
-
- Value* array = nullptr;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {fact->getType(), list->getType(), itemsPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- array = CallInst::Create(funcPtr, {fact, list, itemsPtr}, "array", block);
- } else {
- const auto arrayPtr = new AllocaInst(valueType, 0U, "array_ptr", block);
- new StoreInst(list, arrayPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), arrayPtr->getType(), arrayPtr->getType(), itemsPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {fact, arrayPtr, arrayPtr, itemsPtr}, "", block);
- array = new LoadInst(arrayPtr, "array", block);
- }
-
- result->addIncoming(array, block);
-
- const auto algo = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THeapWrapper::Do));
- const auto self = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(this));
-
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto zero = ConstantInt::get(idxType, 0);
- const auto begin = GetElementPtrInst::CreateInBounds(items, {zero}, "begin", block);
- const auto end = GetElementPtrInst::CreateInBounds(items, {size}, "end", block);
-
- const auto selfPtr = CastInst::Create(Instruction::IntToPtr, self, PointerType::getUnqual(StructType::get(context)), "comp", block);
- const auto doType = FunctionType::get(Type::getVoidTy(context), {selfPtr->getType(), ctx.Ctx->getType(), begin->getType(), end->getType()}, false);
- const auto doPtr = CastInst::Create(Instruction::IntToPtr, algo, PointerType::getUnqual(doType), "do", block);
-
- CallInst::Create(doPtr, {selfPtr, ctx.Ctx, begin, end}, "", block);
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void Do(TComputationContext& ctx, NUdf::TUnboxedValuePod* begin, NUdf::TUnboxedValuePod* end) const {
- if (Comparator) {
- return Algorithm(begin, end, std::bind(Comparator, std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
- }
-
- TArgsPlace args;
- Left->SetGetter([&](TComputationContext&) { return args.front(); });
- Right->SetGetter([&](TComputationContext&) { return args.back(); });
- Algorithm(begin, end, std::bind(&THeapWrapper::Comp, this, std::ref(args), std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
- }
-
- bool Comp(TArgsPlace& args, TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r) const {
- args = {{l, r}};
- Left->InvalidateValue(ctx);
- Right->InvalidateValue(ctx);
- return Compare->GetValue(ctx).Get<bool>();
- }
-
- void RegisterDependencies() const final {
- this->DependsOn(List);
- this->Own(Left);
- this->Own(Right);
- this->DependsOn(Compare);
- }
-
- const TAlgorithm Algorithm;
-
- IComputationNode* const List;
- IComputationExternalNode* const Left;
- IComputationExternalNode* const Right;
- IComputationNode* const Compare;
-
- TComparePtr Comparator = nullptr;
-
-#ifndef MKQL_DISABLE_CODEGEN
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::compare_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (CompareFunc) {
- Comparator = reinterpret_cast<TComparePtr>(codegen->GetPointerToFunction(CompareFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- CompareFunc = GenerateCompareFunction(codegen, MakeName(), Left, Right, Compare);
- codegen->ExportSymbol(CompareFunc);
- }
-
- Function* CompareFunc = nullptr;
-#endif
-};
-
-IComputationNode* WrapHeap(TAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
-
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto compare = LocateNode(ctx.NodeLocator, callable, 3);
- const auto left = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const auto right = LocateExternalNode(ctx.NodeLocator, callable, 2);
-
- return new THeapWrapper(algorithm, ctx.Mutables, list, left, right, compare);
-}
-
-using TNthAlgorithm = void(*)(NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, TComparator);
-
-class TNthWrapper : public TMutableCodegeneratorNode<TNthWrapper>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
- typedef TMutableCodegeneratorNode<TNthWrapper> TBaseComputation;
-public:
- TNthWrapper(TNthAlgorithm algorithm, TComputationMutables& mutables, IComputationNode* list, IComputationNode* middle, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
- , Algorithm(algorithm)
- , List(list)
- , Middle(middle)
- , Left(left)
- , Right(right)
- , Compare(compare)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- auto middle = Middle->GetValue(ctx).Get<ui64>();
- const auto size = list.GetListLength();
-
- middle = std::min(middle, size);
-
- if (middle == 0U || size < 2U)
- return list.Release();
-
- NUdf::TUnboxedValue *items = nullptr;
- const auto next = ctx.HolderFactory.CloneArray(list.Release(), items);
-
- NUdf::TUnboxedValuePod *const begin = items, *const mid = items + middle, *const end = items + size;
-
- Do(ctx, begin, mid, end);
-
- return next;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto fact = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CloneArray));// TODO: Generate code instead of call CloneArray.
-
- const auto list = GetNodeValue(List, ctx, block);
- const auto midv = GetNodeValue(Middle, ctx, block);
- const auto middle = GetterFor<ui64>(midv, context, block);
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto greater = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, middle, size, "greater", block);
-
- const auto min = SelectInst::Create(greater, size, middle, "min", block);
-
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, min, ConstantInt::get(size->getType(), 0ULL), "one", block);
- const auto two = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 1ULL), "two", block);
- const auto test = BinaryOperator::CreateAnd(one, two, "and", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
- result->addIncoming(list, block);
-
- BranchInst::Create(work, done, test, block);
-
- block = work;
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", block);
-
- const auto idxType = Type::getInt32Ty(context);
-
- Value* array = nullptr;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {fact->getType(), list->getType(), itemsPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- array = CallInst::Create(funcPtr, {fact, list, itemsPtr}, "array", block);
- } else {
- const auto arrayPtr = new AllocaInst(valueType, 0U, "array_ptr", block);
- new StoreInst(list, arrayPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), arrayPtr->getType(), arrayPtr->getType(), itemsPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {fact, arrayPtr, arrayPtr, itemsPtr}, "", block);
- array = new LoadInst(arrayPtr, "array", block);
- }
-
- result->addIncoming(array, block);
-
- const auto algo = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TNthWrapper::Do));
- const auto self = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(this));
-
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto zero = ConstantInt::get(idxType, 0);
- const auto begin = GetElementPtrInst::CreateInBounds(items, {zero}, "begin", block);
- const auto mid = GetElementPtrInst::CreateInBounds(items, {min}, "middle", block);
- const auto end = GetElementPtrInst::CreateInBounds(items, {size}, "end", block);
-
- const auto selfPtr = CastInst::Create(Instruction::IntToPtr, self, PointerType::getUnqual(StructType::get(context)), "comp", block);
- const auto doType = FunctionType::get(Type::getVoidTy(context), {selfPtr->getType(), ctx.Ctx->getType(), begin->getType(), mid->getType(), end->getType()}, false);
- const auto doPtr = CastInst::Create(Instruction::IntToPtr, algo, PointerType::getUnqual(doType), "do", block);
-
- CallInst::Create(doPtr, {selfPtr, ctx.Ctx, begin, mid, end}, "", block);
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void Do(TComputationContext& ctx, NUdf::TUnboxedValuePod* begin, NUdf::TUnboxedValuePod* nth, NUdf::TUnboxedValuePod* end) const {
- if (Comparator) {
- return Algorithm(begin, nth, end, std::bind(Comparator, std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
- }
-
- TArgsPlace args;
- Left->SetGetter([&](TComputationContext&) { return args.front(); });
- Right->SetGetter([&](TComputationContext&) { return args.back(); });
- Algorithm(begin, nth, end, std::bind(&TNthWrapper::Comp, this, std::ref(args), std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
- }
-
- bool Comp(TArgsPlace& args, TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r) const {
- args = {{l, r}};
- Left->InvalidateValue(ctx);
- Right->InvalidateValue(ctx);
- return Compare->GetValue(ctx).Get<bool>();
- }
-
- void RegisterDependencies() const final {
- this->DependsOn(List);
- this->DependsOn(Middle);
- this->Own(Left);
- this->Own(Right);
- this->DependsOn(Compare);
- }
-
- const TNthAlgorithm Algorithm;
-
- IComputationNode* const List;
- IComputationNode* const Middle;
- IComputationExternalNode* const Left;
- IComputationExternalNode* const Right;
- IComputationNode* const Compare;
-
- TComparePtr Comparator = nullptr;
-
-#ifndef MKQL_DISABLE_CODEGEN
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::compare_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (CompareFunc) {
- Comparator = reinterpret_cast<TComparePtr>(codegen->GetPointerToFunction(CompareFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- CompareFunc = GenerateCompareFunction(codegen, MakeName(), Left, Right, Compare);
- codegen->ExportSymbol(CompareFunc);
- }
-
- Function* CompareFunc = nullptr;
-#endif
-};
-
-IComputationNode* WrapNth(TNthAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
-
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto middle = LocateNode(ctx.NodeLocator, callable, 1);
- const auto compare = LocateNode(ctx.NodeLocator, callable, 4);
- const auto left = LocateExternalNode(ctx.NodeLocator, callable, 2);
- const auto right = LocateExternalNode(ctx.NodeLocator, callable, 3);
-
- return new TNthWrapper(algorithm, ctx.Mutables, list, middle, left, right, compare);
-}
-
-}
-
-IComputationNode* WrapMakeHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapHeap(&std::make_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapPushHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapHeap(&std::push_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapPopHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapHeap(&std::pop_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapSortHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapHeap(&std::sort_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapStableSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapHeap(&std::stable_sort<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapNthElement(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapNth(&std::nth_element<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapPartialSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapNth(&std::partial_sort<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
-}
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+using TComparator = std::function<bool(const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r)>;
+using TAlgorithm = void(*)(NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, TComparator);
+using TArgsPlace = std::array<NUdf::TUnboxedValuePod, 2U>;
+using TComparePtr = bool (*)(TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r);
+
+class THeapWrapper : public TMutableCodegeneratorNode<THeapWrapper>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+ typedef TMutableCodegeneratorNode<THeapWrapper> TBaseComputation;
+public:
+ THeapWrapper(TAlgorithm algorithm, TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ , Algorithm(algorithm)
+ , List(list)
+ , Left(left)
+ , Right(right)
+ , Compare(compare)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ const auto size = list.GetListLength();
+
+ if (size < 2U)
+ return list.Release();
+
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto next = ctx.HolderFactory.CloneArray(list.Release(), items);
+
+ NUdf::TUnboxedValuePod *const begin = items, *const end = items + size;
+
+ Do(ctx, begin, end);
+
+ return next;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto fact = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CloneArray));// TODO: Generate code instead of call CloneArray.
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 1ULL), "test", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+ result->addIncoming(list, block);
+
+ BranchInst::Create(work, done, test, block);
+
+ block = work;
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", block);
+
+ const auto idxType = Type::getInt32Ty(context);
+
+ Value* array = nullptr;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {fact->getType(), list->getType(), itemsPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ array = CallInst::Create(funcPtr, {fact, list, itemsPtr}, "array", block);
+ } else {
+ const auto arrayPtr = new AllocaInst(valueType, 0U, "array_ptr", block);
+ new StoreInst(list, arrayPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), arrayPtr->getType(), arrayPtr->getType(), itemsPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {fact, arrayPtr, arrayPtr, itemsPtr}, "", block);
+ array = new LoadInst(arrayPtr, "array", block);
+ }
+
+ result->addIncoming(array, block);
+
+ const auto algo = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THeapWrapper::Do));
+ const auto self = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(this));
+
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto zero = ConstantInt::get(idxType, 0);
+ const auto begin = GetElementPtrInst::CreateInBounds(items, {zero}, "begin", block);
+ const auto end = GetElementPtrInst::CreateInBounds(items, {size}, "end", block);
+
+ const auto selfPtr = CastInst::Create(Instruction::IntToPtr, self, PointerType::getUnqual(StructType::get(context)), "comp", block);
+ const auto doType = FunctionType::get(Type::getVoidTy(context), {selfPtr->getType(), ctx.Ctx->getType(), begin->getType(), end->getType()}, false);
+ const auto doPtr = CastInst::Create(Instruction::IntToPtr, algo, PointerType::getUnqual(doType), "do", block);
+
+ CallInst::Create(doPtr, {selfPtr, ctx.Ctx, begin, end}, "", block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void Do(TComputationContext& ctx, NUdf::TUnboxedValuePod* begin, NUdf::TUnboxedValuePod* end) const {
+ if (Comparator) {
+ return Algorithm(begin, end, std::bind(Comparator, std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
+ }
+
+ TArgsPlace args;
+ Left->SetGetter([&](TComputationContext&) { return args.front(); });
+ Right->SetGetter([&](TComputationContext&) { return args.back(); });
+ Algorithm(begin, end, std::bind(&THeapWrapper::Comp, this, std::ref(args), std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
+ }
+
+ bool Comp(TArgsPlace& args, TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r) const {
+ args = {{l, r}};
+ Left->InvalidateValue(ctx);
+ Right->InvalidateValue(ctx);
+ return Compare->GetValue(ctx).Get<bool>();
+ }
+
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
+ this->Own(Left);
+ this->Own(Right);
+ this->DependsOn(Compare);
+ }
+
+ const TAlgorithm Algorithm;
+
+ IComputationNode* const List;
+ IComputationExternalNode* const Left;
+ IComputationExternalNode* const Right;
+ IComputationNode* const Compare;
+
+ TComparePtr Comparator = nullptr;
+
+#ifndef MKQL_DISABLE_CODEGEN
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::compare_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (CompareFunc) {
+ Comparator = reinterpret_cast<TComparePtr>(codegen->GetPointerToFunction(CompareFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ CompareFunc = GenerateCompareFunction(codegen, MakeName(), Left, Right, Compare);
+ codegen->ExportSymbol(CompareFunc);
+ }
+
+ Function* CompareFunc = nullptr;
+#endif
+};
+
+IComputationNode* WrapHeap(TAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
+
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto compare = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto left = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto right = LocateExternalNode(ctx.NodeLocator, callable, 2);
+
+ return new THeapWrapper(algorithm, ctx.Mutables, list, left, right, compare);
+}
+
+using TNthAlgorithm = void(*)(NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, NUdf::TUnboxedValuePod*, TComparator);
+
+class TNthWrapper : public TMutableCodegeneratorNode<TNthWrapper>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+ typedef TMutableCodegeneratorNode<TNthWrapper> TBaseComputation;
+public:
+ TNthWrapper(TNthAlgorithm algorithm, TComputationMutables& mutables, IComputationNode* list, IComputationNode* middle, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ , Algorithm(algorithm)
+ , List(list)
+ , Middle(middle)
+ , Left(left)
+ , Right(right)
+ , Compare(compare)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ auto middle = Middle->GetValue(ctx).Get<ui64>();
+ const auto size = list.GetListLength();
+
+ middle = std::min(middle, size);
+
+ if (middle == 0U || size < 2U)
+ return list.Release();
+
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto next = ctx.HolderFactory.CloneArray(list.Release(), items);
+
+ NUdf::TUnboxedValuePod *const begin = items, *const mid = items + middle, *const end = items + size;
+
+ Do(ctx, begin, mid, end);
+
+ return next;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto fact = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CloneArray));// TODO: Generate code instead of call CloneArray.
+
+ const auto list = GetNodeValue(List, ctx, block);
+ const auto midv = GetNodeValue(Middle, ctx, block);
+ const auto middle = GetterFor<ui64>(midv, context, block);
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto greater = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, middle, size, "greater", block);
+
+ const auto min = SelectInst::Create(greater, size, middle, "min", block);
+
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, min, ConstantInt::get(size->getType(), 0ULL), "one", block);
+ const auto two = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 1ULL), "two", block);
+ const auto test = BinaryOperator::CreateAnd(one, two, "and", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+ result->addIncoming(list, block);
+
+ BranchInst::Create(work, done, test, block);
+
+ block = work;
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(valueType), 0U, "items_ptr", block);
+
+ const auto idxType = Type::getInt32Ty(context);
+
+ Value* array = nullptr;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {fact->getType(), list->getType(), itemsPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ array = CallInst::Create(funcPtr, {fact, list, itemsPtr}, "array", block);
+ } else {
+ const auto arrayPtr = new AllocaInst(valueType, 0U, "array_ptr", block);
+ new StoreInst(list, arrayPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), arrayPtr->getType(), arrayPtr->getType(), itemsPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {fact, arrayPtr, arrayPtr, itemsPtr}, "", block);
+ array = new LoadInst(arrayPtr, "array", block);
+ }
+
+ result->addIncoming(array, block);
+
+ const auto algo = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TNthWrapper::Do));
+ const auto self = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(this));
+
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto zero = ConstantInt::get(idxType, 0);
+ const auto begin = GetElementPtrInst::CreateInBounds(items, {zero}, "begin", block);
+ const auto mid = GetElementPtrInst::CreateInBounds(items, {min}, "middle", block);
+ const auto end = GetElementPtrInst::CreateInBounds(items, {size}, "end", block);
+
+ const auto selfPtr = CastInst::Create(Instruction::IntToPtr, self, PointerType::getUnqual(StructType::get(context)), "comp", block);
+ const auto doType = FunctionType::get(Type::getVoidTy(context), {selfPtr->getType(), ctx.Ctx->getType(), begin->getType(), mid->getType(), end->getType()}, false);
+ const auto doPtr = CastInst::Create(Instruction::IntToPtr, algo, PointerType::getUnqual(doType), "do", block);
+
+ CallInst::Create(doPtr, {selfPtr, ctx.Ctx, begin, mid, end}, "", block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void Do(TComputationContext& ctx, NUdf::TUnboxedValuePod* begin, NUdf::TUnboxedValuePod* nth, NUdf::TUnboxedValuePod* end) const {
+ if (Comparator) {
+ return Algorithm(begin, nth, end, std::bind(Comparator, std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
+ }
+
+ TArgsPlace args;
+ Left->SetGetter([&](TComputationContext&) { return args.front(); });
+ Right->SetGetter([&](TComputationContext&) { return args.back(); });
+ Algorithm(begin, nth, end, std::bind(&TNthWrapper::Comp, this, std::ref(args), std::ref(ctx), std::placeholders::_1, std::placeholders::_2));
+ }
+
+ bool Comp(TArgsPlace& args, TComputationContext& ctx, const NUdf::TUnboxedValuePod l, const NUdf::TUnboxedValuePod r) const {
+ args = {{l, r}};
+ Left->InvalidateValue(ctx);
+ Right->InvalidateValue(ctx);
+ return Compare->GetValue(ctx).Get<bool>();
+ }
+
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
+ this->DependsOn(Middle);
+ this->Own(Left);
+ this->Own(Right);
+ this->DependsOn(Compare);
+ }
+
+ const TNthAlgorithm Algorithm;
+
+ IComputationNode* const List;
+ IComputationNode* const Middle;
+ IComputationExternalNode* const Left;
+ IComputationExternalNode* const Right;
+ IComputationNode* const Compare;
+
+ TComparePtr Comparator = nullptr;
+
+#ifndef MKQL_DISABLE_CODEGEN
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::compare_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (CompareFunc) {
+ Comparator = reinterpret_cast<TComparePtr>(codegen->GetPointerToFunction(CompareFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ CompareFunc = GenerateCompareFunction(codegen, MakeName(), Left, Right, Compare);
+ codegen->ExportSymbol(CompareFunc);
+ }
+
+ Function* CompareFunc = nullptr;
+#endif
+};
+
+IComputationNode* WrapNth(TNthAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
+
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto middle = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto compare = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto left = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ const auto right = LocateExternalNode(ctx.NodeLocator, callable, 3);
+
+ return new TNthWrapper(algorithm, ctx.Mutables, list, middle, left, right, compare);
+}
+
+}
+
+IComputationNode* WrapMakeHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapHeap(&std::make_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapPushHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapHeap(&std::push_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapPopHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapHeap(&std::pop_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapSortHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapHeap(&std::sort_heap<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapStableSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapHeap(&std::stable_sort<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapNthElement(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapNth(&std::nth_element<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapPartialSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapNth(&std::partial_sort<NUdf::TUnboxedValuePod*, TComparator>, callable, ctx);
+}
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_heap.h b/ydb/library/yql/minikql/comp_nodes/mkql_heap.h
index 02ad462f9d..f2457f81c2 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_heap.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_heap.h
@@ -1,17 +1,17 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapMakeHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapPushHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapPopHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapSortHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapStableSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapNthElement(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapPartialSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapMakeHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapPushHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapPopHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapSortHeap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapStableSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapNthElement(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapPartialSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_hopping.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_hopping.cpp
index dd92f42999..27d1e000ac 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_hopping.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_hopping.cpp
@@ -11,8 +11,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
const TStatKey Hop_NewHopsCount("Hop_NewHopsCount", true);
const TStatKey Hop_ThrownEventsCount("Hop_ThrownEventsCount", true);
@@ -28,18 +28,18 @@ public:
TStreamValue(
TMemoryUsageInfo* memInfo,
NUdf::TUnboxedValue&& stream,
- const TSelf* self,
- ui64 hopTime,
- ui64 intervalHopCount,
+ const TSelf* self,
+ ui64 hopTime,
+ ui64 intervalHopCount,
ui64 delayHopCount,
TComputationContext& ctx)
: TBase(memInfo)
, Stream(std::move(stream))
, Self(self)
- , HopTime(hopTime)
- , IntervalHopCount(intervalHopCount)
- , DelayHopCount(delayHopCount)
- , Buckets(IntervalHopCount + DelayHopCount)
+ , HopTime(hopTime)
+ , IntervalHopCount(intervalHopCount)
+ , DelayHopCount(delayHopCount)
+ , Buckets(IntervalHopCount + DelayHopCount)
, Ctx(ctx)
{}
@@ -73,7 +73,7 @@ public:
WriteBool(out, Finished);
auto strRef = NUdf::TStringRef(out.data(), out.size());
- return MakeString(strRef);
+ return MakeString(strRef);
}
void Load(const NUdf::TStringRef& state) override {
@@ -97,12 +97,12 @@ public:
}
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- if (!Ready.empty()) {
- result = std::move(Ready.front());
- Ready.pop_front();
+ if (!Ready.empty()) {
+ result = std::move(Ready.front());
+ Ready.pop_front();
return NUdf::EFetchStatus::Ok;
}
- if (Finished) {
+ if (Finished) {
return NUdf::EFetchStatus::Finish;
}
@@ -127,7 +127,7 @@ public:
const auto status = Stream.Fetch(item);
if (status != NUdf::EFetchStatus::Ok) {
if (status == NUdf::EFetchStatus::Finish) {
- Finished = true;
+ Finished = true;
}
return status;
}
@@ -140,13 +140,13 @@ public:
auto hopIndex = time.Get<ui64>() / HopTime;
- if (!Started) {
- HopIndex = hopIndex + 1;
- Started = true;
+ if (!Started) {
+ HopIndex = hopIndex + 1;
+ Started = true;
}
- while (hopIndex >= HopIndex) {
- auto firstBucketIndex = HopIndex % Buckets.size();
+ while (hopIndex >= HopIndex) {
+ auto firstBucketIndex = HopIndex % Buckets.size();
auto bucketIndex = firstBucketIndex;
TMaybe<NUdf::TUnboxedValue> aggregated;
@@ -164,12 +164,12 @@ public:
aggregated = Self->OutMerge->GetValue(Ctx);
}
}
- if (++bucketIndex == Buckets.size()) {
+ if (++bucketIndex == Buckets.size()) {
bucketIndex = 0;
}
}
- auto& clearBucket = Buckets[firstBucketIndex];
+ auto& clearBucket = Buckets[firstBucketIndex];
clearBucket.Value = NUdf::TUnboxedValue();
clearBucket.HasValue = false;
@@ -180,11 +180,11 @@ public:
}
++newHops;
- ++HopIndex;
+ ++HopIndex;
}
if (hopIndex + DelayHopCount + 1 >= HopIndex) {
- auto& bucket = Buckets[hopIndex % Buckets.size()];
+ auto& bucket = Buckets[hopIndex % Buckets.size()];
if (!bucket.HasValue) {
bucket.Value = Self->OutInit->GetValue(Ctx);
bucket.HasValue = true;
@@ -198,24 +198,24 @@ public:
}
}
-
- const NUdf::TUnboxedValue Stream;
- const TSelf *const Self;
-
+
+ const NUdf::TUnboxedValue Stream;
+ const TSelf *const Self;
+
const ui64 HopTime;
const ui64 IntervalHopCount;
const ui64 DelayHopCount;
- struct TBucket {
- NUdf::TUnboxedValue Value;
- bool HasValue = false;
- };
-
- std::vector<TBucket> Buckets; // circular buffer
- std::deque<NUdf::TUnboxedValue> Ready; // buffer for fetching results
+ struct TBucket {
+ NUdf::TUnboxedValue Value;
+ bool HasValue = false;
+ };
+
+ std::vector<TBucket> Buckets; // circular buffer
+ std::deque<NUdf::TUnboxedValue> Ready; // buffer for fetching results
ui64 HopIndex = 0;
- bool Started = false;
- bool Finished = false;
+ bool Started = false;
+ bool Finished = false;
TComputationContext& Ctx;
};
@@ -223,12 +223,12 @@ public:
THoppingCoreWrapper(
TComputationMutables& mutables,
IComputationNode* stream,
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationExternalNode* state2,
- IComputationExternalNode* time,
- IComputationExternalNode* inSave,
- IComputationExternalNode* inLoad,
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationExternalNode* state2,
+ IComputationExternalNode* time,
+ IComputationExternalNode* inSave,
+ IComputationExternalNode* inLoad,
IComputationNode* outTime,
IComputationNode* outInit,
IComputationNode* outUpdate,
@@ -264,28 +264,28 @@ public:
Stateless = false;
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto hopTime = Hop->GetValue(ctx).Get<i64>();
const auto interval = Interval->GetValue(ctx).Get<i64>();
const auto delay = Delay->GetValue(ctx).Get<i64>();
// TODO: move checks from here
MKQL_ENSURE(hopTime > 0, "hop must be positive");
- MKQL_ENSURE(interval >= hopTime, "interval should be greater or equal to hop");
- MKQL_ENSURE(delay >= hopTime, "delay should be greater or equal to hop");
+ MKQL_ENSURE(interval >= hopTime, "interval should be greater or equal to hop");
+ MKQL_ENSURE(delay >= hopTime, "delay should be greater or equal to hop");
- const auto intervalHopCount = interval / hopTime;
- const auto delayHopCount = delay / hopTime;
+ const auto intervalHopCount = interval / hopTime;
+ const auto delayHopCount = delay / hopTime;
- MKQL_ENSURE(intervalHopCount <= 100000, "too many hops in interval");
- MKQL_ENSURE(delayHopCount <= 100000, "too many hops in delay");
+ MKQL_ENSURE(intervalHopCount <= 100000, "too many hops in interval");
+ MKQL_ENSURE(delayHopCount <= 100000, "too many hops in delay");
return ctx.HolderFactory.Create<TStreamValue>(Stream->GetValue(ctx), this, (ui64)hopTime, (ui64)intervalHopCount, (ui64)delayHopCount, ctx);
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Stream);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Stream);
Own(Item);
Own(State);
Own(State2);
@@ -299,19 +299,19 @@ private:
DependsOn(OutLoad);
DependsOn(OutMerge);
DependsOn(OutFinish);
- DependsOn(Hop);
- DependsOn(Interval);
- DependsOn(Delay);
+ DependsOn(Hop);
+ DependsOn(Interval);
+ DependsOn(Delay);
}
IComputationNode* const Stream;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
- IComputationExternalNode* const State2;
- IComputationExternalNode* const Time;
- IComputationExternalNode* const InSave;
- IComputationExternalNode* const InLoad;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
+ IComputationExternalNode* const State2;
+ IComputationExternalNode* const Time;
+ IComputationExternalNode* const InSave;
+ IComputationExternalNode* const InLoad;
IComputationNode* const OutTime;
IComputationNode* const OutInit;
@@ -329,16 +329,16 @@ private:
TMutableObjectOverBoxedValue<TValuePackerBoxed> Packer;
};
-}
-
+}
+
IComputationNode* WrapHoppingCore(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 17, "Expected 17 args");
auto hasSaveLoad = !callable.GetInput(10).GetStaticType()->IsVoid();
- IComputationExternalNode* inSave = nullptr;
+ IComputationExternalNode* inSave = nullptr;
IComputationNode* outSave = nullptr;
- IComputationExternalNode* inLoad = nullptr;
+ IComputationExternalNode* inLoad = nullptr;
IComputationNode* outLoad = nullptr;
auto streamType = callable.GetInput(0).GetStaticType();
@@ -360,13 +360,13 @@ IComputationNode* WrapHoppingCore(TCallable& callable, const TComputationNodeFac
auto interval = LocateNode(ctx.NodeLocator, callable, 15);
auto delay = LocateNode(ctx.NodeLocator, callable, 16);
- auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
- auto state = LocateExternalNode(ctx.NodeLocator, callable, 2);
- auto state2 = LocateExternalNode(ctx.NodeLocator, callable, 3);
- auto time = LocateExternalNode(ctx.NodeLocator, callable, 4);
+ auto item = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ auto state = LocateExternalNode(ctx.NodeLocator, callable, 2);
+ auto state2 = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ auto time = LocateExternalNode(ctx.NodeLocator, callable, 4);
if (hasSaveLoad) {
- inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
- inLoad = LocateExternalNode(ctx.NodeLocator, callable, 6);
+ inSave = LocateExternalNode(ctx.NodeLocator, callable, 5);
+ inLoad = LocateExternalNode(ctx.NodeLocator, callable, 6);
}
auto stateType = hasSaveLoad ? callable.GetInput(10).GetStaticType() : nullptr;
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_if.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_if.cpp
index 01d0935595..ac25b71031 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_if.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_if.cpp
@@ -6,159 +6,159 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsOptional>
-class TIfWrapper : public TMutableCodegeneratorNode<TIfWrapper<IsOptional>> {
-using TBaseComputation = TMutableCodegeneratorNode<TIfWrapper<IsOptional>>;
+namespace {
+
+template<bool IsOptional>
+class TIfWrapper : public TMutableCodegeneratorNode<TIfWrapper<IsOptional>> {
+using TBaseComputation = TMutableCodegeneratorNode<TIfWrapper<IsOptional>>;
public:
- TIfWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* predicate, IComputationNode* thenBranch, IComputationNode* elseBranch)
- : TBaseComputation(mutables, kind)
+ TIfWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* predicate, IComputationNode* thenBranch, IComputationNode* elseBranch)
+ : TBaseComputation(mutables, kind)
, Predicate(predicate)
, ThenBranch(thenBranch)
, ElseBranch(elseBranch)
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& predicate = Predicate->GetValue(ctx);
- if (IsOptional && !predicate) {
- return NUdf::TUnboxedValuePod();
- }
-
- return (predicate.Get<bool>() ? ThenBranch : ElseBranch)->GetValue(ctx).Release();
+ const auto& predicate = Predicate->GetValue(ctx);
+ if (IsOptional && !predicate) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return (predicate.Get<bool>() ? ThenBranch : ElseBranch)->GetValue(ctx).Release();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto then = BasicBlock::Create(context, "then", ctx.Func);
+ const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto value = GetNodeValue(Predicate, ctx, block);
+ const auto result = PHINode::Create(value->getType(), IsOptional ? 3U : 2U, "result", done);
+
+ if (IsOptional) {
+ result->addIncoming(value, block);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ BranchInst::Create(done, good, IsEmpty(value, block), block);
+
+ block = good;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, value, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(then, elsb, cast, block);
+
+ {
+ block = then;
+ const auto left = GetNodeValue(ThenBranch, ctx, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = elsb;
+ const auto right = GetNodeValue(ElseBranch, ctx, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Predicate);
+ this->DependsOn(ThenBranch);
+ this->DependsOn(ElseBranch);
+ }
+
+ IComputationNode* const Predicate;
+ IComputationNode* const ThenBranch;
+ IComputationNode* const ElseBranch;
+};
+
+template<bool IsOptional>
+class TFlowIfWrapper : public TStatefulFlowCodegeneratorNode<TFlowIfWrapper<IsOptional>> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowIfWrapper<IsOptional>>;
+public:
+ TFlowIfWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* predicate, IComputationNode* thenBranch, IComputationNode* elseBranch)
+ : TBaseComputation(mutables, nullptr, kind)
+ , Predicate(predicate)
+ , ThenBranch(thenBranch)
+ , ElseBranch(elseBranch)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ state = Predicate->GetValue(ctx);
+ }
+
+ if (IsOptional && !state) {
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+ return (state.Get<bool>() ? ThenBranch : ElseBranch)->GetValue(ctx).Release();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto then = BasicBlock::Create(context, "then", ctx.Func);
+ const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Predicate, ctx, block);
+
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto result = PHINode::Create(state->getType(), IsOptional ? 3U : 2U, "result", done);
+
+ if (IsOptional) {
+ result->addIncoming(state, block);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ BranchInst::Create(done, good, IsEmpty(state, block), block);
+
+ block = good;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(then, elsb, cast, block);
+
+ {
+ block = then;
+ const auto left = GetNodeValue(ThenBranch, ctx, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = elsb;
+ const auto right = GetNodeValue(ElseBranch, ctx, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto then = BasicBlock::Create(context, "then", ctx.Func);
- const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto value = GetNodeValue(Predicate, ctx, block);
- const auto result = PHINode::Create(value->getType(), IsOptional ? 3U : 2U, "result", done);
-
- if (IsOptional) {
- result->addIncoming(value, block);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- BranchInst::Create(done, good, IsEmpty(value, block), block);
-
- block = good;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, value, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(then, elsb, cast, block);
-
- {
- block = then;
- const auto left = GetNodeValue(ThenBranch, ctx, block);
- result->addIncoming(left, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = elsb;
- const auto right = GetNodeValue(ElseBranch, ctx, block);
- result->addIncoming(right, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Predicate);
- this->DependsOn(ThenBranch);
- this->DependsOn(ElseBranch);
- }
-
- IComputationNode* const Predicate;
- IComputationNode* const ThenBranch;
- IComputationNode* const ElseBranch;
-};
-
-template<bool IsOptional>
-class TFlowIfWrapper : public TStatefulFlowCodegeneratorNode<TFlowIfWrapper<IsOptional>> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowIfWrapper<IsOptional>>;
-public:
- TFlowIfWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* predicate, IComputationNode* thenBranch, IComputationNode* elseBranch)
- : TBaseComputation(mutables, nullptr, kind)
- , Predicate(predicate)
- , ThenBranch(thenBranch)
- , ElseBranch(elseBranch)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- state = Predicate->GetValue(ctx);
- }
-
- if (IsOptional && !state) {
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
- return (state.Get<bool>() ? ThenBranch : ElseBranch)->GetValue(ctx).Release();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto then = BasicBlock::Create(context, "then", ctx.Func);
- const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Predicate, ctx, block);
-
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto result = PHINode::Create(state->getType(), IsOptional ? 3U : 2U, "result", done);
-
- if (IsOptional) {
- result->addIncoming(state, block);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- BranchInst::Create(done, good, IsEmpty(state, block), block);
-
- block = good;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(then, elsb, cast, block);
-
- {
- block = then;
- const auto left = GetNodeValue(ThenBranch, ctx, block);
- result->addIncoming(left, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = elsb;
- const auto right = GetNodeValue(ElseBranch, ctx, block);
- result->addIncoming(right, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOnBoth(ThenBranch, ElseBranch))
- this->DependsOn(flow, Predicate);
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOnBoth(ThenBranch, ElseBranch))
+ this->DependsOn(flow, Predicate);
}
IComputationNode* const Predicate;
@@ -166,145 +166,145 @@ private:
IComputationNode* const ElseBranch;
};
-class TWideIfWrapper : public TStatefulWideFlowCodegeneratorNode<TWideIfWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideIfWrapper>;
-public:
- TWideIfWrapper(TComputationMutables& mutables, IComputationNode* predicate, IComputationWideFlowNode* thenBranch, IComputationWideFlowNode* elseBranch)
- : TBaseComputation(mutables, nullptr, EValueRepresentation::Embedded)
- , Predicate(predicate)
- , ThenBranch(thenBranch)
- , ElseBranch(elseBranch)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = Predicate->GetValue(ctx);
- }
-
- return (state.Get<bool>() ? ThenBranch : ElseBranch)->FetchValues(ctx, output);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto then = BasicBlock::Create(context, "then", ctx.Func);
- const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Predicate, ctx, block);
-
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto result = PHINode::Create(Type::getInt32Ty(context), 2, "result", done);
-
- const auto cast = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(then, elsb, cast, block);
-
- block = then;
-
- const auto left = GetNodeValues(ThenBranch, ctx, block);
- result->addIncoming(left.first, block);
- BranchInst::Create(done, block);
-
- block = elsb;
-
- const auto right = GetNodeValues(ElseBranch, ctx, block);
- result->addIncoming(right.first, block);
- BranchInst::Create(done, block);
-
- block = done;
-
- MKQL_ENSURE(left.second.size() == right.second.size(), "Expected same width of flows.");
- TGettersList getters;
- getters.reserve(left.second.size());
- const auto index = static_cast<const IComputationNode*>(this)->GetIndex();
- size_t idx = 0U;
- std::generate_n(std::back_inserter(getters), right.second.size(), [&]() {
- const auto i = idx++;
- return [index, lget = left.second[i], rget = right.second[i]](const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto then = BasicBlock::Create(context, "then", ctx.Func);
- const auto elsb = BasicBlock::Create(context, "elsb", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(Type::getInt128Ty(context), 2, "result", done);
-
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), index)}, "state_ptr", block);
- const auto state = new LoadInst(statePtr, "state", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "trunc", block);
-
- BranchInst::Create(then, elsb, trunc, block);
-
- block = then;
- result->addIncoming(lget(ctx, block), block);
- BranchInst::Create(done, block);
-
- block = elsb;
- result->addIncoming(rget(ctx, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOnBoth(ThenBranch, ElseBranch))
- DependsOn(flow, Predicate);
- }
-
- IComputationNode* const Predicate;
- IComputationWideFlowNode* const ThenBranch;
- IComputationWideFlowNode* const ElseBranch;
-};
-
-}
-
+class TWideIfWrapper : public TStatefulWideFlowCodegeneratorNode<TWideIfWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideIfWrapper>;
+public:
+ TWideIfWrapper(TComputationMutables& mutables, IComputationNode* predicate, IComputationWideFlowNode* thenBranch, IComputationWideFlowNode* elseBranch)
+ : TBaseComputation(mutables, nullptr, EValueRepresentation::Embedded)
+ , Predicate(predicate)
+ , ThenBranch(thenBranch)
+ , ElseBranch(elseBranch)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = Predicate->GetValue(ctx);
+ }
+
+ return (state.Get<bool>() ? ThenBranch : ElseBranch)->FetchValues(ctx, output);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto then = BasicBlock::Create(context, "then", ctx.Func);
+ const auto elsb = BasicBlock::Create(context, "else", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(init, test, IsInvalid(statePtr, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Predicate, ctx, block);
+
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto result = PHINode::Create(Type::getInt32Ty(context), 2, "result", done);
+
+ const auto cast = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(then, elsb, cast, block);
+
+ block = then;
+
+ const auto left = GetNodeValues(ThenBranch, ctx, block);
+ result->addIncoming(left.first, block);
+ BranchInst::Create(done, block);
+
+ block = elsb;
+
+ const auto right = GetNodeValues(ElseBranch, ctx, block);
+ result->addIncoming(right.first, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ MKQL_ENSURE(left.second.size() == right.second.size(), "Expected same width of flows.");
+ TGettersList getters;
+ getters.reserve(left.second.size());
+ const auto index = static_cast<const IComputationNode*>(this)->GetIndex();
+ size_t idx = 0U;
+ std::generate_n(std::back_inserter(getters), right.second.size(), [&]() {
+ const auto i = idx++;
+ return [index, lget = left.second[i], rget = right.second[i]](const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto then = BasicBlock::Create(context, "then", ctx.Func);
+ const auto elsb = BasicBlock::Create(context, "elsb", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 2, "result", done);
+
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), index)}, "state_ptr", block);
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "trunc", block);
+
+ BranchInst::Create(then, elsb, trunc, block);
+
+ block = then;
+ result->addIncoming(lget(ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = elsb;
+ result->addIncoming(rget(ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOnBoth(ThenBranch, ElseBranch))
+ DependsOn(flow, Predicate);
+ }
+
+ IComputationNode* const Predicate;
+ IComputationWideFlowNode* const ThenBranch;
+ IComputationWideFlowNode* const ElseBranch;
+};
+
+}
+
IComputationNode* WrapIf(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
- bool isOptional;
- const auto predicateType = UnpackOptionalData(callable.GetInput(0), isOptional);
- MKQL_ENSURE(predicateType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool or optional of bool.");
-
- const auto predicate = LocateNode(ctx.NodeLocator, callable, 0);
- const auto thenBranch = LocateNode(ctx.NodeLocator, callable, 1);
- const auto elseBranch = LocateNode(ctx.NodeLocator, callable, 2);
- const auto type = callable.GetType()->GetReturnType();
-
- if (type->IsFlow()) {
- const auto thenWide = dynamic_cast<IComputationWideFlowNode*>(thenBranch);
- const auto elseWide = dynamic_cast<IComputationWideFlowNode*>(elseBranch);
- if (thenWide && elseWide && !isOptional)
- return new TWideIfWrapper(ctx.Mutables, predicate, thenWide, elseWide);
- else if (!thenWide && !elseWide) {
- if (isOptional)
- return new TFlowIfWrapper<true>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
- else
- return new TFlowIfWrapper<false>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
- }
- } else {
- if (isOptional) {
- return new TIfWrapper<true>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
- } else {
- return new TIfWrapper<false>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
- }
- }
-
- THROW yexception() << "Wrong signature.";
+ bool isOptional;
+ const auto predicateType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ MKQL_ENSURE(predicateType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool or optional of bool.");
+
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto thenBranch = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto elseBranch = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto type = callable.GetType()->GetReturnType();
+
+ if (type->IsFlow()) {
+ const auto thenWide = dynamic_cast<IComputationWideFlowNode*>(thenBranch);
+ const auto elseWide = dynamic_cast<IComputationWideFlowNode*>(elseBranch);
+ if (thenWide && elseWide && !isOptional)
+ return new TWideIfWrapper(ctx.Mutables, predicate, thenWide, elseWide);
+ else if (!thenWide && !elseWide) {
+ if (isOptional)
+ return new TFlowIfWrapper<true>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
+ else
+ return new TFlowIfWrapper<false>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
+ }
+ } else {
+ if (isOptional) {
+ return new TIfWrapper<true>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
+ } else {
+ return new TIfWrapper<false>(ctx.Mutables, GetValueRepresentation(type), predicate, thenBranch, elseBranch);
+ }
+ }
+
+ THROW yexception() << "Wrong signature.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_ifpresent.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_ifpresent.cpp
index 0a1a905a09..e017c7ea88 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_ifpresent.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_ifpresent.cpp
@@ -5,321 +5,321 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsMultiOptional>
-class TIfPresentWrapper : public TMutableCodegeneratorNode<TIfPresentWrapper<IsMultiOptional>> {
-using TBaseComputation = TMutableCodegeneratorNode<TIfPresentWrapper<IsMultiOptional>>;
+namespace {
+
+template<bool IsMultiOptional>
+class TIfPresentWrapper : public TMutableCodegeneratorNode<TIfPresentWrapper<IsMultiOptional>> {
+using TBaseComputation = TMutableCodegeneratorNode<TIfPresentWrapper<IsMultiOptional>>;
public:
- TIfPresentWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* optional, IComputationExternalNode* item, IComputationNode* presentBranch,
+ TIfPresentWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* optional, IComputationExternalNode* item, IComputationNode* presentBranch,
IComputationNode* missingBranch)
- : TBaseComputation(mutables, kind)
+ : TBaseComputation(mutables, kind)
, Optional(optional)
, Item(item)
, PresentBranch(presentBranch)
, MissingBranch(missingBranch)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
- const auto optional = Optional->GetValue(ctx);
- if (optional)
- Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
-
- return (optional ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
- } else {
- return (previous ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
+ const auto optional = Optional->GetValue(ctx);
+ if (optional)
+ Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
+
+ return (optional ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
+ } else {
+ return (previous ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- const auto previous = codegenItem->CreateGetValue(ctx, block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
- const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(previous->getType(), 2, "result", done);
-
- const auto choise = SwitchInst::Create(previous, fast, 2U, block);
- choise->addCase(GetEmpty(context), miss);
- choise->addCase(GetInvalid(context), slow);
-
- block = slow;
-
- const auto value = GetNodeValue(Optional, ctx, block);
- BranchInst::Create(pres, miss, IsExists(value, block), block);
-
- block = pres;
- codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
- BranchInst::Create(fast, block);
-
- block = fast;
- const auto left = GetNodeValue(PresentBranch, ctx, block);
- result->addIncoming(left, block);
- BranchInst::Create(done, block);
-
- block = miss;
- const auto right = GetNodeValue(MissingBranch, ctx, block);
- result->addIncoming(right, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Optional);
- this->DependsOn(MissingBranch);
- Optional->AddDependence(Item);
- this->Own(Item);
- this->DependsOn(PresentBranch);
- }
-
- IComputationNode* const Optional;
- IComputationExternalNode* const Item;
- IComputationNode* const PresentBranch;
- IComputationNode* const MissingBranch;
-};
-
-template<bool IsMultiOptional>
-class TFlowIfPresentWrapper : public TStatelessFlowCodegeneratorNode<TFlowIfPresentWrapper<IsMultiOptional>> {
-using TBaseComputation = TStatelessFlowCodegeneratorNode<TFlowIfPresentWrapper<IsMultiOptional>>;
-public:
- TFlowIfPresentWrapper(EValueRepresentation kind, IComputationNode* optional, IComputationExternalNode* item, IComputationNode* presentBranch,
- IComputationNode* missingBranch)
- : TBaseComputation(nullptr, kind)
- , Optional(optional)
- , Item(item)
- , PresentBranch(presentBranch)
- , MissingBranch(missingBranch)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
- const auto optional = Optional->GetValue(ctx);
- if (optional)
- Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
-
- return (optional ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
- } else {
- return (previous ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ const auto previous = codegenItem->CreateGetValue(ctx, block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
+ const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(previous->getType(), 2, "result", done);
+
+ const auto choise = SwitchInst::Create(previous, fast, 2U, block);
+ choise->addCase(GetEmpty(context), miss);
+ choise->addCase(GetInvalid(context), slow);
+
+ block = slow;
+
+ const auto value = GetNodeValue(Optional, ctx, block);
+ BranchInst::Create(pres, miss, IsExists(value, block), block);
+
+ block = pres;
+ codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
+ BranchInst::Create(fast, block);
+
+ block = fast;
+ const auto left = GetNodeValue(PresentBranch, ctx, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(done, block);
+
+ block = miss;
+ const auto right = GetNodeValue(MissingBranch, ctx, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Optional);
+ this->DependsOn(MissingBranch);
+ Optional->AddDependence(Item);
+ this->Own(Item);
+ this->DependsOn(PresentBranch);
+ }
+
+ IComputationNode* const Optional;
+ IComputationExternalNode* const Item;
+ IComputationNode* const PresentBranch;
+ IComputationNode* const MissingBranch;
+};
+
+template<bool IsMultiOptional>
+class TFlowIfPresentWrapper : public TStatelessFlowCodegeneratorNode<TFlowIfPresentWrapper<IsMultiOptional>> {
+using TBaseComputation = TStatelessFlowCodegeneratorNode<TFlowIfPresentWrapper<IsMultiOptional>>;
+public:
+ TFlowIfPresentWrapper(EValueRepresentation kind, IComputationNode* optional, IComputationExternalNode* item, IComputationNode* presentBranch,
+ IComputationNode* missingBranch)
+ : TBaseComputation(nullptr, kind)
+ , Optional(optional)
+ , Item(item)
+ , PresentBranch(presentBranch)
+ , MissingBranch(missingBranch)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
+ const auto optional = Optional->GetValue(ctx);
+ if (optional)
+ Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
+
+ return (optional ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
+ } else {
+ return (previous ? PresentBranch : MissingBranch)->GetValue(ctx).Release();
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- const auto previous = codegenItem->CreateGetValue(ctx, block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
- const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(previous->getType(), 2, "result", done);
-
- const auto choise = SwitchInst::Create(previous, fast, 2U, block);
- choise->addCase(GetEmpty(context), miss);
- choise->addCase(GetInvalid(context), slow);
-
- block = slow;
-
- const auto value = GetNodeValue(Optional, ctx, block);
- BranchInst::Create(pres, miss, IsExists(value, block), block);
-
- block = pres;
- codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
- BranchInst::Create(fast, block);
-
- block = fast;
- const auto left = GetNodeValue(PresentBranch, ctx, block);
- result->addIncoming(left, block);
- BranchInst::Create(done, block);
-
- block = miss;
- const auto right = GetNodeValue(MissingBranch, ctx, block);
- result->addIncoming(right, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOnBoth(PresentBranch, MissingBranch)) {
- this->DependsOn(flow, Optional);
- this->Own(flow, Item);
- }
- Optional->AddDependence(Item);
+ const auto previous = codegenItem->CreateGetValue(ctx, block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
+ const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(previous->getType(), 2, "result", done);
+
+ const auto choise = SwitchInst::Create(previous, fast, 2U, block);
+ choise->addCase(GetEmpty(context), miss);
+ choise->addCase(GetInvalid(context), slow);
+
+ block = slow;
+
+ const auto value = GetNodeValue(Optional, ctx, block);
+ BranchInst::Create(pres, miss, IsExists(value, block), block);
+
+ block = pres;
+ codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
+ BranchInst::Create(fast, block);
+
+ block = fast;
+ const auto left = GetNodeValue(PresentBranch, ctx, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(done, block);
+
+ block = miss;
+ const auto right = GetNodeValue(MissingBranch, ctx, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOnBoth(PresentBranch, MissingBranch)) {
+ this->DependsOn(flow, Optional);
+ this->Own(flow, Item);
+ }
+ Optional->AddDependence(Item);
}
IComputationNode* const Optional;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const PresentBranch;
IComputationNode* const MissingBranch;
};
-template<bool IsMultiOptional>
-class TWideIfPresentWrapper : public TStatelessWideFlowCodegeneratorNode<TWideIfPresentWrapper<IsMultiOptional>> {
-using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideIfPresentWrapper<IsMultiOptional>>;
-public:
- TWideIfPresentWrapper(IComputationNode* optional, IComputationExternalNode* item, IComputationWideFlowNode* presentBranch,
- IComputationWideFlowNode* missingBranch)
- : TBaseComputation(nullptr)
- , Optional(optional)
- , Item(item)
- , PresentBranch(presentBranch)
- , MissingBranch(missingBranch)
- {}
-
- EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
- const auto optional = Optional->GetValue(ctx);
- if (optional)
- Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
-
- return (optional ? PresentBranch : MissingBranch)->FetchValues(ctx, output);
- } else {
- return (previous ? PresentBranch : MissingBranch)->FetchValues(ctx, output);
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+template<bool IsMultiOptional>
+class TWideIfPresentWrapper : public TStatelessWideFlowCodegeneratorNode<TWideIfPresentWrapper<IsMultiOptional>> {
+using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideIfPresentWrapper<IsMultiOptional>>;
+public:
+ TWideIfPresentWrapper(IComputationNode* optional, IComputationExternalNode* item, IComputationWideFlowNode* presentBranch,
+ IComputationWideFlowNode* missingBranch)
+ : TBaseComputation(nullptr)
+ , Optional(optional)
+ , Item(item)
+ , PresentBranch(presentBranch)
+ , MissingBranch(missingBranch)
+ {}
+
+ EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (const auto& previous = Item->GetValue(ctx); previous.IsInvalid()) {
+ const auto optional = Optional->GetValue(ctx);
+ if (optional)
+ Item->SetValue(ctx, optional.GetOptionalValueIf<IsMultiOptional>());
+
+ return (optional ? PresentBranch : MissingBranch)->FetchValues(ctx, output);
+ } else {
+ return (previous ? PresentBranch : MissingBranch)->FetchValues(ctx, output);
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- const auto previous = codegenItem->CreateGetValue(ctx, block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
- const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt32Ty(context), 2, "result", done);
-
- const auto choise = SwitchInst::Create(previous, pres, 2U, block);
- choise->addCase(GetEmpty(context), miss);
- choise->addCase(GetInvalid(context), init);
-
- block = init;
-
- const auto value = GetNodeValue(Optional, ctx, block);
- BranchInst::Create(good, miss, IsExists(value, block), block);
-
- block = good;
-
- codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
-
- BranchInst::Create(pres, block);
-
- block = pres;
- const auto left = GetNodeValues(PresentBranch, ctx, block);
- result->addIncoming(left.first, block);
- BranchInst::Create(done, block);
-
- block = miss;
- const auto right = GetNodeValues(MissingBranch, ctx, block);
- result->addIncoming(right.first, block);
- BranchInst::Create(done, block);
-
- block = done;
-
- MKQL_ENSURE(left.second.size() == right.second.size(), "Expected same width of flows.");
- ICodegeneratorInlineWideNode::TGettersList getters;
- getters.reserve(left.second.size());
- size_t idx = 0U;
- std::generate_n(std::back_inserter(getters), right.second.size(), [&]() {
- const auto i = idx++;
- return [codegenItem, lget = left.second[i], rget = right.second[i]](const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
- const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto current = codegenItem->CreateGetValue(ctx, block);
- const auto result = PHINode::Create(current->getType(), 2, "result", done);
-
- const auto choise = SwitchInst::Create(current, pres, 2U, block);
- choise->addCase(GetEmpty(context), miss);
- choise->addCase(GetInvalid(context), miss);
-
- block = pres;
- result->addIncoming(lget(ctx, block), block);
- BranchInst::Create(done, block);
-
- block = miss;
- result->addIncoming(rget(ctx, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOnBoth(PresentBranch, MissingBranch)) {
- this->DependsOn(flow, Optional);
- this->Own(flow, Item);
- }
- Optional->AddDependence(Item);
- }
-
- IComputationNode* const Optional;
- IComputationExternalNode* const Item;
- IComputationWideFlowNode* const PresentBranch;
- IComputationWideFlowNode* const MissingBranch;
-};
-
-}
-
+ const auto previous = codegenItem->CreateGetValue(ctx, block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
+ const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt32Ty(context), 2, "result", done);
+
+ const auto choise = SwitchInst::Create(previous, pres, 2U, block);
+ choise->addCase(GetEmpty(context), miss);
+ choise->addCase(GetInvalid(context), init);
+
+ block = init;
+
+ const auto value = GetNodeValue(Optional, ctx, block);
+ BranchInst::Create(good, miss, IsExists(value, block), block);
+
+ block = good;
+
+ codegenItem->CreateSetValue(ctx, block, IsMultiOptional ? GetOptionalValue(context, value, block) : value);
+
+ BranchInst::Create(pres, block);
+
+ block = pres;
+ const auto left = GetNodeValues(PresentBranch, ctx, block);
+ result->addIncoming(left.first, block);
+ BranchInst::Create(done, block);
+
+ block = miss;
+ const auto right = GetNodeValues(MissingBranch, ctx, block);
+ result->addIncoming(right.first, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ MKQL_ENSURE(left.second.size() == right.second.size(), "Expected same width of flows.");
+ ICodegeneratorInlineWideNode::TGettersList getters;
+ getters.reserve(left.second.size());
+ size_t idx = 0U;
+ std::generate_n(std::back_inserter(getters), right.second.size(), [&]() {
+ const auto i = idx++;
+ return [codegenItem, lget = left.second[i], rget = right.second[i]](const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto pres = BasicBlock::Create(context, "pres", ctx.Func);
+ const auto miss = BasicBlock::Create(context, "miss", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto current = codegenItem->CreateGetValue(ctx, block);
+ const auto result = PHINode::Create(current->getType(), 2, "result", done);
+
+ const auto choise = SwitchInst::Create(current, pres, 2U, block);
+ choise->addCase(GetEmpty(context), miss);
+ choise->addCase(GetInvalid(context), miss);
+
+ block = pres;
+ result->addIncoming(lget(ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = miss;
+ result->addIncoming(rget(ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOnBoth(PresentBranch, MissingBranch)) {
+ this->DependsOn(flow, Optional);
+ this->Own(flow, Item);
+ }
+ Optional->AddDependence(Item);
+ }
+
+ IComputationNode* const Optional;
+ IComputationExternalNode* const Item;
+ IComputationWideFlowNode* const PresentBranch;
+ IComputationWideFlowNode* const MissingBranch;
+};
+
+}
+
IComputationNode* WrapIfPresent(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
- const auto optional = LocateNode(ctx.NodeLocator, callable, 0);
- const auto presentBranch = LocateNode(ctx.NodeLocator, callable, 2);
- const auto missingBranch = LocateNode(ctx.NodeLocator, callable, 3);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- const bool multiOptional = AS_TYPE(TOptionalType, callable.GetInput(0U).GetStaticType())->GetItemType()->IsOptional();
- if (const auto type = callable.GetType()->GetReturnType(); type->IsFlow()) {
- const auto presWide = dynamic_cast<IComputationWideFlowNode*>(presentBranch);
- const auto missWide = dynamic_cast<IComputationWideFlowNode*>(missingBranch);
-
- if (presWide && missWide) {
- if (multiOptional)
- return new TWideIfPresentWrapper<true>(optional, itemArg, presWide, missWide);
- else
- return new TWideIfPresentWrapper<false>(optional, itemArg, presWide, missWide);
- } else if (!presWide && !missWide) {
- if (multiOptional)
- return new TFlowIfPresentWrapper<true>(GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
- else
- return new TFlowIfPresentWrapper<false>(GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
- }
- } else if (multiOptional) {
- return new TIfPresentWrapper<true>(ctx.Mutables, GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
- } else {
- return new TIfPresentWrapper<false>(ctx.Mutables, GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
- }
-
- THROW yexception() << "Wrong signature.";
+ const auto optional = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto presentBranch = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto missingBranch = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const bool multiOptional = AS_TYPE(TOptionalType, callable.GetInput(0U).GetStaticType())->GetItemType()->IsOptional();
+ if (const auto type = callable.GetType()->GetReturnType(); type->IsFlow()) {
+ const auto presWide = dynamic_cast<IComputationWideFlowNode*>(presentBranch);
+ const auto missWide = dynamic_cast<IComputationWideFlowNode*>(missingBranch);
+
+ if (presWide && missWide) {
+ if (multiOptional)
+ return new TWideIfPresentWrapper<true>(optional, itemArg, presWide, missWide);
+ else
+ return new TWideIfPresentWrapper<false>(optional, itemArg, presWide, missWide);
+ } else if (!presWide && !missWide) {
+ if (multiOptional)
+ return new TFlowIfPresentWrapper<true>(GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
+ else
+ return new TFlowIfPresentWrapper<false>(GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
+ }
+ } else if (multiOptional) {
+ return new TIfPresentWrapper<true>(ctx.Mutables, GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
+ } else {
+ return new TIfPresentWrapper<false>(ctx.Mutables, GetValueRepresentation(type), optional, itemArg, presentBranch, missingBranch);
+ }
+
+ THROW yexception() << "Wrong signature.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_invoke.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_invoke.cpp
index 2c17bd285a..50e60d9296 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_invoke.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_invoke.cpp
@@ -8,215 +8,215 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsOptional>
-class TUnaryArgInvokeBase {
-protected:
- TUnaryArgInvokeBase(TStringBuf name, const TFunctionDescriptor& descr)
- : Name(name), Descriptor(descr)
- {}
-
- NUdf::TUnboxedValuePod DoCalc(const NUdf::TUnboxedValuePod& arg) const {
- if (IsOptional && !arg) {
- return {};
- }
- return Descriptor.Function(&arg);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
- if (IsOptional) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(arg->getType(), 2U, "result", done);
-
- result->addIncoming(arg, block);
- BranchInst::Create(good, done, IsExists(arg, block), block);
-
- block = good;
- const auto out = reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(&arg, ctx, block);
-
- result->addIncoming(out, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(&arg, ctx, block);
- }
- }
-#endif
- const TStringBuf Name;
- const TFunctionDescriptor Descriptor;
-};
-
-template<bool IsOptional>
-class TSimpleUnaryArgInvokeWrapper : public TDecoratorCodegeneratorNode<TSimpleUnaryArgInvokeWrapper<IsOptional>>, private TUnaryArgInvokeBase<IsOptional> {
- typedef TDecoratorCodegeneratorNode<TSimpleUnaryArgInvokeWrapper<IsOptional>> TBaseComputation;
-public:
- TSimpleUnaryArgInvokeWrapper(TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* arg)
- : TBaseComputation(arg), TUnaryArgInvokeBase<IsOptional>(name, descr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& arg) const {
- return this->DoCalc(arg);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
- return this->DoGenGetValue(ctx, arg, block);
- }
-#endif
-
-private:
- TString DebugString() const final {
- return TBaseComputation::DebugString() + "(" + this->Name + ")" ;
- }
-};
-
-template<bool IsOptional>
-class TDefaultUnaryArgInvokeWrapper : public TMutableCodegeneratorNode<TDefaultUnaryArgInvokeWrapper<IsOptional>>, private TUnaryArgInvokeBase<IsOptional> {
- typedef TMutableCodegeneratorNode<TDefaultUnaryArgInvokeWrapper<IsOptional>> TBaseComputation;
-public:
- TDefaultUnaryArgInvokeWrapper(TComputationMutables& mutables, EValueRepresentation kind, TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* arg)
- : TBaseComputation(mutables, kind), TUnaryArgInvokeBase<IsOptional>(name, descr), Arg(arg)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return this->DoCalc(Arg->GetValue(ctx));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- const auto arg = GetNodeValue(Arg, ctx, block);
- return this->DoGenGetValue(ctx, arg, block);
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Arg);
- }
-
- TString DebugString() const final {
- return TBaseComputation::DebugString() + "(" + this->Name + ")" ;
- }
-
- IComputationNode *const Arg;
-};
-
-class TBinaryInvokeWrapper : public TBinaryCodegeneratorNode<TBinaryInvokeWrapper> {
- typedef TBinaryCodegeneratorNode<TBinaryInvokeWrapper> TBaseComputation;
-public:
- TBinaryInvokeWrapper(TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* left, IComputationNode* right, EValueRepresentation kind = EValueRepresentation::Embedded)
- : TBaseComputation(left, right, kind), Name(name), Descriptor(descr)
- {
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const std::array<NUdf::TUnboxedValue, 2U> args {{Left->GetValue(compCtx), Right->GetValue(compCtx)}};
- return Descriptor.Function(args.data());
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- const std::array<Value*, 2U> args {{GetNodeValue(Left, ctx, block), GetNodeValue(Right, ctx, block)}};
- return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(args.data(), ctx, block);
- }
-#endif
-
-private:
- TString DebugString() const final {
- return TBaseComputation::DebugString() + "(" + Name + ")" ;
- }
-
- const TStringBuf Name;
- const TFunctionDescriptor Descriptor;
-};
-
-template<size_t Size>
-class TInvokeWrapper : public TMutableCodegeneratorNode<TInvokeWrapper<Size>> {
- typedef TMutableCodegeneratorNode<TInvokeWrapper<Size>> TBaseComputation;
+namespace {
+
+template<bool IsOptional>
+class TUnaryArgInvokeBase {
+protected:
+ TUnaryArgInvokeBase(TStringBuf name, const TFunctionDescriptor& descr)
+ : Name(name), Descriptor(descr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalc(const NUdf::TUnboxedValuePod& arg) const {
+ if (IsOptional && !arg) {
+ return {};
+ }
+ return Descriptor.Function(&arg);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
+ if (IsOptional) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(arg->getType(), 2U, "result", done);
+
+ result->addIncoming(arg, block);
+ BranchInst::Create(good, done, IsExists(arg, block), block);
+
+ block = good;
+ const auto out = reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(&arg, ctx, block);
+
+ result->addIncoming(out, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(&arg, ctx, block);
+ }
+ }
+#endif
+ const TStringBuf Name;
+ const TFunctionDescriptor Descriptor;
+};
+
+template<bool IsOptional>
+class TSimpleUnaryArgInvokeWrapper : public TDecoratorCodegeneratorNode<TSimpleUnaryArgInvokeWrapper<IsOptional>>, private TUnaryArgInvokeBase<IsOptional> {
+ typedef TDecoratorCodegeneratorNode<TSimpleUnaryArgInvokeWrapper<IsOptional>> TBaseComputation;
+public:
+ TSimpleUnaryArgInvokeWrapper(TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* arg)
+ : TBaseComputation(arg), TUnaryArgInvokeBase<IsOptional>(name, descr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& arg) const {
+ return this->DoCalc(arg);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
+ return this->DoGenGetValue(ctx, arg, block);
+ }
+#endif
+
+private:
+ TString DebugString() const final {
+ return TBaseComputation::DebugString() + "(" + this->Name + ")" ;
+ }
+};
+
+template<bool IsOptional>
+class TDefaultUnaryArgInvokeWrapper : public TMutableCodegeneratorNode<TDefaultUnaryArgInvokeWrapper<IsOptional>>, private TUnaryArgInvokeBase<IsOptional> {
+ typedef TMutableCodegeneratorNode<TDefaultUnaryArgInvokeWrapper<IsOptional>> TBaseComputation;
+public:
+ TDefaultUnaryArgInvokeWrapper(TComputationMutables& mutables, EValueRepresentation kind, TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* arg)
+ : TBaseComputation(mutables, kind), TUnaryArgInvokeBase<IsOptional>(name, descr), Arg(arg)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return this->DoCalc(Arg->GetValue(ctx));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ const auto arg = GetNodeValue(Arg, ctx, block);
+ return this->DoGenGetValue(ctx, arg, block);
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Arg);
+ }
+
+ TString DebugString() const final {
+ return TBaseComputation::DebugString() + "(" + this->Name + ")" ;
+ }
+
+ IComputationNode *const Arg;
+};
+
+class TBinaryInvokeWrapper : public TBinaryCodegeneratorNode<TBinaryInvokeWrapper> {
+ typedef TBinaryCodegeneratorNode<TBinaryInvokeWrapper> TBaseComputation;
public:
- TInvokeWrapper(TComputationMutables& mutables, EValueRepresentation kind, TStringBuf name, const TFunctionDescriptor& descr, TComputationNodePtrVector&& argNodes)
- : TBaseComputation(mutables, kind)
- , Name(name), Descriptor(descr)
+ TBinaryInvokeWrapper(TStringBuf name, const TFunctionDescriptor& descr, IComputationNode* left, IComputationNode* right, EValueRepresentation kind = EValueRepresentation::Embedded)
+ : TBaseComputation(left, right, kind), Name(name), Descriptor(descr)
+ {
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
+ const std::array<NUdf::TUnboxedValue, 2U> args {{Left->GetValue(compCtx), Right->GetValue(compCtx)}};
+ return Descriptor.Function(args.data());
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ const std::array<Value*, 2U> args {{GetNodeValue(Left, ctx, block), GetNodeValue(Right, ctx, block)}};
+ return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(args.data(), ctx, block);
+ }
+#endif
+
+private:
+ TString DebugString() const final {
+ return TBaseComputation::DebugString() + "(" + Name + ")" ;
+ }
+
+ const TStringBuf Name;
+ const TFunctionDescriptor Descriptor;
+};
+
+template<size_t Size>
+class TInvokeWrapper : public TMutableCodegeneratorNode<TInvokeWrapper<Size>> {
+ typedef TMutableCodegeneratorNode<TInvokeWrapper<Size>> TBaseComputation;
+public:
+ TInvokeWrapper(TComputationMutables& mutables, EValueRepresentation kind, TStringBuf name, const TFunctionDescriptor& descr, TComputationNodePtrVector&& argNodes)
+ : TBaseComputation(mutables, kind)
+ , Name(name), Descriptor(descr)
, ArgNodes(std::move(argNodes))
{
}
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- std::array<NUdf::TUnboxedValue, Size> values;
- std::transform(ArgNodes.cbegin(), ArgNodes.cend(), values.begin(),
- std::bind(&IComputationNode::GetValue, std::placeholders::_1, std::ref(ctx))
- );
- return Descriptor.Function(values.data());
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ std::array<NUdf::TUnboxedValue, Size> values;
+ std::transform(ArgNodes.cbegin(), ArgNodes.cend(), values.begin(),
+ std::bind(&IComputationNode::GetValue, std::placeholders::_1, std::ref(ctx))
+ );
+ return Descriptor.Function(values.data());
}
#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- std::array<Value*, Size> values;
- std::transform(ArgNodes.cbegin(), ArgNodes.cend(), values.begin(),
- [&](IComputationNode* node) { return GetNodeValue(node, ctx, block); }
- );
- return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(values.data(), ctx, block);
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- std::for_each(ArgNodes.cbegin(), ArgNodes.cend(), std::bind(&TInvokeWrapper::DependsOn, this, std::placeholders::_1));
- }
-
- TString DebugString() const final {
- return TBaseComputation::DebugString() + "(" + Name + ")" ;
- }
-
- const TStringBuf Name;
- const TFunctionDescriptor Descriptor;
- const TComputationNodePtrVector ArgNodes;
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ std::array<Value*, Size> values;
+ std::transform(ArgNodes.cbegin(), ArgNodes.cend(), values.begin(),
+ [&](IComputationNode* node) { return GetNodeValue(node, ctx, block); }
+ );
+ return reinterpret_cast<TGeneratorPtr>(Descriptor.Generator)(values.data(), ctx, block);
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ std::for_each(ArgNodes.cbegin(), ArgNodes.cend(), std::bind(&TInvokeWrapper::DependsOn, this, std::placeholders::_1));
+ }
+
+ TString DebugString() const final {
+ return TBaseComputation::DebugString() + "(" + Name + ")" ;
+ }
+
+ const TStringBuf Name;
+ const TFunctionDescriptor Descriptor;
+ const TComputationNodePtrVector ArgNodes;
};
-}
-
+}
+
IComputationNode* WrapInvoke(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 2U && callable.GetInputsCount() <= 4U, "Expected from one to three arguments.");
- const auto returnType = callable.GetType()->GetReturnType();
-
- const auto inputsCount = callable.GetInputsCount();
- std::array<TArgType, 4U> argsTypes;
- TComputationNodePtrVector argNodes;
- argNodes.reserve(inputsCount - 1U);
- argsTypes.front().first = UnpackOptionalData(returnType, argsTypes.front().second)->GetSchemeType();
- for (ui32 i = 1U; i < inputsCount; ++i) {
- argsTypes[i].first = UnpackOptionalData(callable.GetInput(i), argsTypes[i].second)->GetSchemeType();
- argNodes.emplace_back(LocateNode(ctx.NodeLocator, callable, i));
- }
-
- const auto funcName = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef();
- const auto funcDesc = ctx.FunctionRegistry.GetBuiltins()->GetBuiltin(funcName, argsTypes.data(), inputsCount);
-
- const auto returnKind = GetValueRepresentation(returnType);
- switch (argNodes.size()) {
- case 1U:
- if (EValueRepresentation::Embedded == returnKind) {
- return new TSimpleUnaryArgInvokeWrapper<false>(funcName, funcDesc, argNodes.front());
- } else {
- return new TDefaultUnaryArgInvokeWrapper<false>(ctx.Mutables, returnKind, funcName, funcDesc, argNodes.front());
- }
- case 2U:
- if (EValueRepresentation::Embedded == returnKind) {
- return new TBinaryInvokeWrapper(funcName, funcDesc, argNodes.front(), argNodes.back());
- }
- return new TInvokeWrapper<2U>(ctx.Mutables, returnKind, funcName, funcDesc, std::move(argNodes));
- case 3U:
- return new TInvokeWrapper<3U>(ctx.Mutables, returnKind, funcName, funcDesc, std::move(argNodes));
- default:
- Y_FAIL("Too wide invoke.");
- }
+ MKQL_ENSURE(callable.GetInputsCount() >= 2U && callable.GetInputsCount() <= 4U, "Expected from one to three arguments.");
+ const auto returnType = callable.GetType()->GetReturnType();
+
+ const auto inputsCount = callable.GetInputsCount();
+ std::array<TArgType, 4U> argsTypes;
+ TComputationNodePtrVector argNodes;
+ argNodes.reserve(inputsCount - 1U);
+ argsTypes.front().first = UnpackOptionalData(returnType, argsTypes.front().second)->GetSchemeType();
+ for (ui32 i = 1U; i < inputsCount; ++i) {
+ argsTypes[i].first = UnpackOptionalData(callable.GetInput(i), argsTypes[i].second)->GetSchemeType();
+ argNodes.emplace_back(LocateNode(ctx.NodeLocator, callable, i));
+ }
+
+ const auto funcName = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef();
+ const auto funcDesc = ctx.FunctionRegistry.GetBuiltins()->GetBuiltin(funcName, argsTypes.data(), inputsCount);
+
+ const auto returnKind = GetValueRepresentation(returnType);
+ switch (argNodes.size()) {
+ case 1U:
+ if (EValueRepresentation::Embedded == returnKind) {
+ return new TSimpleUnaryArgInvokeWrapper<false>(funcName, funcDesc, argNodes.front());
+ } else {
+ return new TDefaultUnaryArgInvokeWrapper<false>(ctx.Mutables, returnKind, funcName, funcDesc, argNodes.front());
+ }
+ case 2U:
+ if (EValueRepresentation::Embedded == returnKind) {
+ return new TBinaryInvokeWrapper(funcName, funcDesc, argNodes.front(), argNodes.back());
+ }
+ return new TInvokeWrapper<2U>(ctx.Mutables, returnKind, funcName, funcDesc, std::move(argNodes));
+ case 3U:
+ return new TInvokeWrapper<3U>(ctx.Mutables, returnKind, funcName, funcDesc, std::move(argNodes));
+ default:
+ Y_FAIL("Too wide invoke.");
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_iterator.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_iterator.cpp
index be4c6a0591..8eccbb27b5 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_iterator.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_iterator.cpp
@@ -1,5 +1,5 @@
-#include "mkql_iterator.h"
-
+#include "mkql_iterator.h"
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
@@ -7,260 +7,260 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TIteratorWrapper : public TMutableCodegeneratorNode<TIteratorWrapper> {
- typedef TMutableCodegeneratorNode<TIteratorWrapper> TBaseComputation;
+namespace {
+
+class TIteratorWrapper : public TMutableCodegeneratorNode<TIteratorWrapper> {
+ typedef TMutableCodegeneratorNode<TIteratorWrapper> TBaseComputation;
public:
TIteratorWrapper(TComputationMutables& mutables, IComputationNode* list, TComputationNodePtrVector&& dependentNodes)
- : TBaseComputation(mutables, EValueRepresentation::Boxed), List(list), DependentNodes(std::move(dependentNodes))
- {}
+ : TBaseComputation(mutables, EValueRepresentation::Boxed), List(list), DependentNodes(std::move(dependentNodes))
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.CreateIteratorOverList(List->GetValue(ctx).Release());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.CreateIteratorOverList(List->GetValue(ctx).Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto value = GetNodeValue(List, ctx, block);
-
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateIteratorOverList));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto signature = FunctionType::get(value->getType(), {factory->getType(), value->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- const auto output = CallInst::Create(creator, {factory, value}, "output", block);
- return output;
- } else {
- const auto place = new AllocaInst(value->getType(), 0U, "place", block);
- new StoreInst(value, place, block);
- const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- CallInst::Create(creator, {factory, place, place}, "", block);
- const auto output = new LoadInst(place, "output", block);
- return output;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- std::for_each(DependentNodes.cbegin(), DependentNodes.cend(),std::bind(&TIteratorWrapper::DependsOn, this, std::placeholders::_1));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto value = GetNodeValue(List, ctx, block);
+
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateIteratorOverList));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto signature = FunctionType::get(value->getType(), {factory->getType(), value->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ const auto output = CallInst::Create(creator, {factory, value}, "output", block);
+ return output;
+ } else {
+ const auto place = new AllocaInst(value->getType(), 0U, "place", block);
+ new StoreInst(value, place, block);
+ const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ CallInst::Create(creator, {factory, place, place}, "", block);
+ const auto output = new LoadInst(place, "output", block);
+ return output;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ std::for_each(DependentNodes.cbegin(), DependentNodes.cend(),std::bind(&TIteratorWrapper::DependsOn, this, std::placeholders::_1));
}
- IComputationNode *const List;
- const TComputationNodePtrVector DependentNodes;
+ IComputationNode *const List;
+ const TComputationNodePtrVector DependentNodes;
};
-class TForwardListWrapper : public TMutableCodegeneratorNode<TForwardListWrapper> {
- typedef TMutableCodegeneratorNode<TForwardListWrapper> TBaseComputation;
+class TForwardListWrapper : public TMutableCodegeneratorNode<TForwardListWrapper> {
+ typedef TMutableCodegeneratorNode<TForwardListWrapper> TBaseComputation;
public:
TForwardListWrapper(TComputationMutables& mutables, IComputationNode* stream)
- : TBaseComputation(mutables, EValueRepresentation::Boxed), Stream(stream)
- {}
+ : TBaseComputation(mutables, EValueRepresentation::Boxed), Stream(stream)
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.CreateForwardList(Stream->GetValue(ctx).Release());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.CreateForwardList(Stream->GetValue(ctx).Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto value = GetNodeValue(Stream, ctx, block);
-
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateForwardList));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto signature = FunctionType::get(value->getType(), {factory->getType(), value->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- const auto output = CallInst::Create(creator, {factory, value}, "output", block);
- return output;
- } else {
- const auto place = new AllocaInst(value->getType(), 0U, "place", block);
- new StoreInst(value, place, block);
- const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- CallInst::Create(creator, {factory, place, place}, "", block);
- const auto output = new LoadInst(place, "output", block);
- return output;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(Stream);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto value = GetNodeValue(Stream, ctx, block);
+
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateForwardList));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto signature = FunctionType::get(value->getType(), {factory->getType(), value->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ const auto output = CallInst::Create(creator, {factory, value}, "output", block);
+ return output;
+ } else {
+ const auto place = new AllocaInst(value->getType(), 0U, "place", block);
+ new StoreInst(value, place, block);
+ const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ CallInst::Create(creator, {factory, place, place}, "", block);
+ const auto output = new LoadInst(place, "output", block);
+ return output;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Stream);
}
- IComputationNode *const Stream;
+ IComputationNode *const Stream;
};
-class TFlowForwardListWrapper : public TCustomValueCodegeneratorNode<TFlowForwardListWrapper> {
- typedef TCustomValueCodegeneratorNode<TFlowForwardListWrapper> TBaseComputation;
-public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- using TPtr = IComputationNode*;
-
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, TPtr flow)
- : TComputationValue<TIterator>(memInfo), CompCtx(compCtx), Flow(flow)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- value = Flow->GetValue(CompCtx);
- if (value.IsYield()) {
- Throw();
- }
- return !value.IsFinish();
- }
-
- TComputationContext& CompCtx;
- const TPtr Flow;
- };
-
- class TCodegenIterator : public TComputationValue<TCodegenIterator> {
- public:
- using TPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod&);
-
- TCodegenIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, TPtr func)
- : TComputationValue<TCodegenIterator>(memInfo), CompCtx(compCtx), Func(func)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- return Func(&CompCtx, value);
- }
-
- TComputationContext& CompCtx;
- const TPtr Func;
- };
-
- template <class TIterator>
- class TForwardListValue : public TCustomListValue {
- public:
- TForwardListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, typename TIterator::TPtr ptr)
- : TCustomListValue(memInfo), CompCtx(compCtx), Ptr(ptr)
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- if (const auto ptr = Ptr) {
- Ptr = nullptr;
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, ptr);
- }
-
- THROW yexception() << "Second pass on forward list.";
- }
-
- TComputationContext& CompCtx;
- mutable typename TIterator::TPtr Ptr;
- };
-
- TFlowForwardListWrapper(TComputationMutables& mutables, IComputationNode* flow)
- : TBaseComputation(mutables), Flow(flow)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Next)
- return ctx.HolderFactory.Create<TForwardListValue<TCodegenIterator>>(ctx, Next);
-#endif
- return ctx.HolderFactory.Create<TForwardListValue<TIterator>>(ctx, Flow);
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Flow);
- }
-
- [[noinline]] [[noreturn]] static void Throw() {
- UdfTerminate("Unexpected flow status.");
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- NextFunc = GenerateNext(codegen);
- codegen->ExportSymbol(NextFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (NextFunc)
- Next = reinterpret_cast<TCodegenIterator::TPtr>(codegen->GetPointerToFunction(NextFunc));
- }
-
- Function* GenerateNext(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Next");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto contextType = GetCompContextType(context);
- const auto funcType = FunctionType::get(Type::getInt1Ty(context), {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+class TFlowForwardListWrapper : public TCustomValueCodegeneratorNode<TFlowForwardListWrapper> {
+ typedef TCustomValueCodegeneratorNode<TFlowForwardListWrapper> TBaseComputation;
+public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ using TPtr = IComputationNode*;
+
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, TPtr flow)
+ : TComputationValue<TIterator>(memInfo), CompCtx(compCtx), Flow(flow)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ value = Flow->GetValue(CompCtx);
+ if (value.IsYield()) {
+ Throw();
+ }
+ return !value.IsFinish();
+ }
+
+ TComputationContext& CompCtx;
+ const TPtr Flow;
+ };
+
+ class TCodegenIterator : public TComputationValue<TCodegenIterator> {
+ public:
+ using TPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod&);
+
+ TCodegenIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, TPtr func)
+ : TComputationValue<TCodegenIterator>(memInfo), CompCtx(compCtx), Func(func)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ return Func(&CompCtx, value);
+ }
+
+ TComputationContext& CompCtx;
+ const TPtr Func;
+ };
+
+ template <class TIterator>
+ class TForwardListValue : public TCustomListValue {
+ public:
+ TForwardListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, typename TIterator::TPtr ptr)
+ : TCustomListValue(memInfo), CompCtx(compCtx), Ptr(ptr)
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ if (const auto ptr = Ptr) {
+ Ptr = nullptr;
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, ptr);
+ }
+
+ THROW yexception() << "Second pass on forward list.";
+ }
+
+ TComputationContext& CompCtx;
+ mutable typename TIterator::TPtr Ptr;
+ };
+
+ TFlowForwardListWrapper(TComputationMutables& mutables, IComputationNode* flow)
+ : TBaseComputation(mutables), Flow(flow)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Next)
+ return ctx.HolderFactory.Create<TForwardListValue<TCodegenIterator>>(ctx, Next);
+#endif
+ return ctx.HolderFactory.Create<TForwardListValue<TIterator>>(ctx, Flow);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Flow);
+ }
+
+ [[noinline]] [[noreturn]] static void Throw() {
+ UdfTerminate("Unexpected flow status.");
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ NextFunc = GenerateNext(codegen);
+ codegen->ExportSymbol(NextFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (NextFunc)
+ Next = reinterpret_cast<TCodegenIterator::TPtr>(codegen->GetPointerToFunction(NextFunc));
+ }
+
+ Function* GenerateNext(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Next");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto contextType = GetCompContextType(context);
+ const auto funcType = FunctionType::get(Type::getInt1Ty(context), {PointerType::getUnqual(contextType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, Flow, ctx, block);
-
- const auto value = new LoadInst(valuePtr, "value", block);
-
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- BranchInst::Create(kill, good, IsYield(value, block), block);
-
- block = kill;
- const auto doThrow = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowForwardListWrapper::Throw));
- const auto doThrowPtr = CastInst::Create(Instruction::IntToPtr, doThrow, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
- CallInst::Create(doThrowPtr, {}, "", block)->setTailCall();
- new UnreachableInst(context, block);
-
- block = good;
- const auto result = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, value, GetFinish(context), "result", block);
- ReturnInst::Create(context, result, block);
- return ctx.Func;
- }
-
- Function* NextFunc = nullptr;
-
- TCodegenIterator::TPtr Next = nullptr;
-#endif
- IComputationNode* const Flow;
-};
-
-}
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, Flow, ctx, block);
+
+ const auto value = new LoadInst(valuePtr, "value", block);
+
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ BranchInst::Create(kill, good, IsYield(value, block), block);
+
+ block = kill;
+ const auto doThrow = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowForwardListWrapper::Throw));
+ const auto doThrowPtr = CastInst::Create(Instruction::IntToPtr, doThrow, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
+ CallInst::Create(doThrowPtr, {}, "", block)->setTailCall();
+ new UnreachableInst(context, block);
+
+ block = good;
+ const auto result = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, value, GetFinish(context), "result", block);
+ ReturnInst::Create(context, result, block);
+ return ctx.Func;
+ }
+
+ Function* NextFunc = nullptr;
+
+ TCodegenIterator::TPtr Next = nullptr;
+#endif
+ IComputationNode* const Flow;
+};
+
+}
+
IComputationNode* WrapEmptyIterator(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected 0 arg");
- const auto type = callable.GetType()->GetReturnType();
- if (type->IsFlow()) {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod::MakeFinish());
- } else if (type->IsStream()) {
- return ctx.NodeFactory.CreateEmptyNode();
- }
- THROW yexception() << "Expected flow or stream.";
+ const auto type = callable.GetType()->GetReturnType();
+ if (type->IsFlow()) {
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod::MakeFinish());
+ } else if (type->IsStream()) {
+ return ctx.NodeFactory.CreateEmptyNode();
+ }
+ THROW yexception() << "Expected flow or stream.";
}
IComputationNode* WrapIterator(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() >= 1, "Expected at least 1 arg");
- const auto type = callable.GetInput(0).GetStaticType();
+ const auto type = callable.GetInput(0).GetStaticType();
MKQL_ENSURE(type->IsList(), "Requires list");
TComputationNodePtrVector dependentNodes(callable.GetInputsCount() - 1);
@@ -273,13 +273,13 @@ IComputationNode* WrapIterator(TCallable& callable, const TComputationNodeFactor
IComputationNode* WrapForwardList(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- const auto type = callable.GetInput(0).GetStaticType();
- if (type->IsFlow()) {
- return new TFlowForwardListWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- } else if (type->IsStream()) {
- return new TForwardListWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- }
- THROW yexception() << "Expected flow or stream.";
+ const auto type = callable.GetInput(0).GetStaticType();
+ if (type->IsFlow()) {
+ return new TFlowForwardListWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ } else if (type->IsStream()) {
+ return new TForwardListWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ }
+ THROW yexception() << "Expected flow or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_join.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_join.cpp
index fe8bb158b5..d2182bbc23 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_join.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_join.cpp
@@ -14,1358 +14,1358 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
const ui64 DEFAULT_STACK_ITEMS = 16;
static const TStatKey Join_Spill_Count("Join_Spill_Count", true);
static const TStatKey Join_Spill_MaxFileSize("Join_Spill_MaxFileSize", false);
static const TStatKey Join_Spill_MaxRowsCount("Join_Spill_MaxRowsCount", false);
-enum class EOutputMode {
- Unknown,
- LeftNull,
- RightNull,
- BothNull,
- Cross,
- CrossSwap,
- None
-};
-
-std::vector<bool> FillRequiredStructColumn(const ui32 inputWidth, const std::vector<ui32>& requiredColumns) {
- std::vector<bool> result(inputWidth, false);
- for (const auto i : requiredColumns) {
- result[i] = true;
- }
- return result;
-}
-
-enum ETableIndex : ui32 {
- LeftIndex = 0U,
- RightIndex = 1U
-};
-
-namespace NFlow {
-
-using TFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*const*)>;
-using TLiveFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*)>;
-
+enum class EOutputMode {
+ Unknown,
+ LeftNull,
+ RightNull,
+ BothNull,
+ Cross,
+ CrossSwap,
+ None
+};
+
+std::vector<bool> FillRequiredStructColumn(const ui32 inputWidth, const std::vector<ui32>& requiredColumns) {
+ std::vector<bool> result(inputWidth, false);
+ for (const auto i : requiredColumns) {
+ result[i] = true;
+ }
+ return result;
+}
+
+enum ETableIndex : ui32 {
+ LeftIndex = 0U,
+ RightIndex = 1U
+};
+
+namespace NFlow {
+
+using TFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*const*)>;
+using TLiveFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*)>;
+
class TSpillList {
public:
- TSpillList(TValuePacker& itemPacker, bool singleShot, size_t width = 0ULL)
- : Width(width)
- , ItemPacker(itemPacker)
- , Count(0)
-#ifndef NDEBUG
- , IsSealed(false)
-#endif
- , Index(ui64(-1))
+ TSpillList(TValuePacker& itemPacker, bool singleShot, size_t width = 0ULL)
+ : Width(width)
+ , ItemPacker(itemPacker)
+ , Count(0)
+#ifndef NDEBUG
+ , IsSealed(false)
+#endif
+ , Index(ui64(-1))
, SingleShot(singleShot)
- {}
-
- TSpillList(TSpillList&& rhs) = delete;
- TSpillList(const TSpillList& rhs) = delete;
- void operator=(const TSpillList& rhs) = delete;
-
- void Init() {
- Count = 0;
-#ifndef NDEBUG
- IsSealed = false;
-#endif
- Index = ui64(-1);
- FileState = nullptr;
- Heap.clear();
- LiveFlow = nullptr;
- LiveValue = NUdf::TUnboxedValue();
- }
-
- bool Spill() {
- if (FileState) {
- return false;
- }
-
- FileState.reset(new TFileState);
- OpenWrite();
- for (ui32 i = 0; i < Count; ++i) {
- Write(std::move(InMemory(i)));
- }
-
- Heap.clear();
- return true;
- }
-
- void Live(IComputationNode* flow, NUdf::TUnboxedValue&& liveValue) {
- Y_VERIFY_DEBUG(!IsLive());
- Y_VERIFY_DEBUG(Count == 0);
- LiveFlow = flow;
- LiveValue = std::move(liveValue);
- }
-
- void Live(TLiveFetcher&& fetcher, NUdf::TUnboxedValue* liveValues) {
- Y_VERIFY_DEBUG(!IsLive());
- Y_VERIFY_DEBUG(Count == 0);
- Fetcher = std::move(fetcher);
- LiveValues = liveValues;
- }
-
- void Add(NUdf::TUnboxedValue&& value) {
-#ifndef NDEBUG
- Y_VERIFY_DEBUG(!IsSealed);
-#endif
+ {}
+
+ TSpillList(TSpillList&& rhs) = delete;
+ TSpillList(const TSpillList& rhs) = delete;
+ void operator=(const TSpillList& rhs) = delete;
+
+ void Init() {
+ Count = 0;
+#ifndef NDEBUG
+ IsSealed = false;
+#endif
+ Index = ui64(-1);
+ FileState = nullptr;
+ Heap.clear();
+ LiveFlow = nullptr;
+ LiveValue = NUdf::TUnboxedValue();
+ }
+
+ bool Spill() {
+ if (FileState) {
+ return false;
+ }
+
+ FileState.reset(new TFileState);
+ OpenWrite();
+ for (ui32 i = 0; i < Count; ++i) {
+ Write(std::move(InMemory(i)));
+ }
+
+ Heap.clear();
+ return true;
+ }
+
+ void Live(IComputationNode* flow, NUdf::TUnboxedValue&& liveValue) {
+ Y_VERIFY_DEBUG(!IsLive());
+ Y_VERIFY_DEBUG(Count == 0);
+ LiveFlow = flow;
+ LiveValue = std::move(liveValue);
+ }
+
+ void Live(TLiveFetcher&& fetcher, NUdf::TUnboxedValue* liveValues) {
+ Y_VERIFY_DEBUG(!IsLive());
+ Y_VERIFY_DEBUG(Count == 0);
+ Fetcher = std::move(fetcher);
+ LiveValues = liveValues;
+ }
+
+ void Add(NUdf::TUnboxedValue&& value) {
+#ifndef NDEBUG
+ Y_VERIFY_DEBUG(!IsSealed);
+#endif
if (SingleShot && Count > 0) {
MKQL_ENSURE(Count == 1, "Counter inconsistent");
return;
}
- if (FileState) {
- Write(std::move(value));
- } else {
- if (Count < DEFAULT_STACK_ITEMS) {
- Stack[Count] = std::move(value);
- }
- else {
- if (Count == DEFAULT_STACK_ITEMS) {
- Y_VERIFY_DEBUG(Heap.empty());
- Heap.assign(Stack, Stack + DEFAULT_STACK_ITEMS);
- }
-
- Heap.push_back(std::move(value));
- }
- }
-
- ++Count;
- }
-
- void Seal(TComputationContext& ctx) {
-#ifndef NDEBUG
- IsSealed = true;
-#endif
- if (FileState) {
- FileState->Output->Finish();
- Cerr << "Spill finished at " << Count << " items" << Endl;
- FileState->Output.reset();
- Cerr << "File size: " << GetFileLength(FileState->File.GetName()) << ", expected: " << FileState->TotalSize << Endl;
-
- MKQL_INC_STAT(ctx.Stats, Join_Spill_Count);
- MKQL_SET_MAX_STAT(ctx.Stats, Join_Spill_MaxFileSize, static_cast<i64>(FileState->TotalSize));
- MKQL_SET_MAX_STAT(ctx.Stats, Join_Spill_MaxRowsCount, static_cast<i64>(Count));
- }
- }
-
- bool IsLive() const {
- return bool(LiveFlow) || bool(Fetcher);
- }
-
- ui64 GetCount() const {
- Y_VERIFY_DEBUG(!IsLive());
- return Count;
- }
-
- bool Empty() const {
- return !IsLive() && (Count == 0);
- }
-
- NUdf::TUnboxedValue Next(TComputationContext& ctx) {
-#ifndef NDEBUG
- Y_VERIFY_DEBUG(IsSealed);
-#endif
- if (IsLive()) {
- if ((Index + 1) == 0) {
- ++Index;
- return std::move(LiveValue);
- }
-
+ if (FileState) {
+ Write(std::move(value));
+ } else {
+ if (Count < DEFAULT_STACK_ITEMS) {
+ Stack[Count] = std::move(value);
+ }
+ else {
+ if (Count == DEFAULT_STACK_ITEMS) {
+ Y_VERIFY_DEBUG(Heap.empty());
+ Heap.assign(Stack, Stack + DEFAULT_STACK_ITEMS);
+ }
+
+ Heap.push_back(std::move(value));
+ }
+ }
+
+ ++Count;
+ }
+
+ void Seal(TComputationContext& ctx) {
+#ifndef NDEBUG
+ IsSealed = true;
+#endif
+ if (FileState) {
+ FileState->Output->Finish();
+ Cerr << "Spill finished at " << Count << " items" << Endl;
+ FileState->Output.reset();
+ Cerr << "File size: " << GetFileLength(FileState->File.GetName()) << ", expected: " << FileState->TotalSize << Endl;
+
+ MKQL_INC_STAT(ctx.Stats, Join_Spill_Count);
+ MKQL_SET_MAX_STAT(ctx.Stats, Join_Spill_MaxFileSize, static_cast<i64>(FileState->TotalSize));
+ MKQL_SET_MAX_STAT(ctx.Stats, Join_Spill_MaxRowsCount, static_cast<i64>(Count));
+ }
+ }
+
+ bool IsLive() const {
+ return bool(LiveFlow) || bool(Fetcher);
+ }
+
+ ui64 GetCount() const {
+ Y_VERIFY_DEBUG(!IsLive());
+ return Count;
+ }
+
+ bool Empty() const {
+ return !IsLive() && (Count == 0);
+ }
+
+ NUdf::TUnboxedValue Next(TComputationContext& ctx) {
+#ifndef NDEBUG
+ Y_VERIFY_DEBUG(IsSealed);
+#endif
+ if (IsLive()) {
+ if ((Index + 1) == 0) {
+ ++Index;
+ return std::move(LiveValue);
+ }
+
auto value = LiveFlow->GetValue(ctx);
while (SingleShot && !value.IsSpecial()) {
// skip all remaining values
value = LiveFlow->GetValue(ctx);
}
- if (!value.IsSpecial()) {
- ++Index;
- }
- return value;
- }
-
- if ((Index + 1) == Count) {
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
- ++Index;
- if (FileState) {
- if (Index == 0) {
- OpenRead();
- }
-
- return Read(ctx);
- }
-
- return InMemory(Index);
- }
-
- EFetchResult Next(TComputationContext& ctx, NUdf::TUnboxedValue* values) {
- if (IsLive()) {
- if ((Index + 1) == 0) {
- ++Index;
-
- if (values != LiveValues)
- for (auto i = 0U; i < Width; ++i)
- *values++ = std::move(*LiveValues++);
-
- LiveValues = nullptr;
- return EFetchResult::One;
- }
-
- auto result = Fetcher(ctx, values);
- while (SingleShot && EFetchResult::One == result) {
- // skip all remaining values
- result = Fetcher(ctx, values);
- }
-
- if (EFetchResult::One == result) {
- ++Index;
- }
- return result;
- }
-
- if ((Index + 1) == Count) {
- return EFetchResult::Finish;
- }
-
- ++Index;
- if (FileState) {
- if (Index == 0) {
- OpenRead();
- }
-
- std::copy_n(Read(ctx).GetElements(), Width, values);
- return EFetchResult::One;
- }
-
- std::copy_n(InMemory(Index).GetElements(), Width, values);
- return EFetchResult::One;
- }
-
- void Rewind() {
+ if (!value.IsSpecial()) {
+ ++Index;
+ }
+ return value;
+ }
+
+ if ((Index + 1) == Count) {
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+ ++Index;
+ if (FileState) {
+ if (Index == 0) {
+ OpenRead();
+ }
+
+ return Read(ctx);
+ }
+
+ return InMemory(Index);
+ }
+
+ EFetchResult Next(TComputationContext& ctx, NUdf::TUnboxedValue* values) {
+ if (IsLive()) {
+ if ((Index + 1) == 0) {
+ ++Index;
+
+ if (values != LiveValues)
+ for (auto i = 0U; i < Width; ++i)
+ *values++ = std::move(*LiveValues++);
+
+ LiveValues = nullptr;
+ return EFetchResult::One;
+ }
+
+ auto result = Fetcher(ctx, values);
+ while (SingleShot && EFetchResult::One == result) {
+ // skip all remaining values
+ result = Fetcher(ctx, values);
+ }
+
+ if (EFetchResult::One == result) {
+ ++Index;
+ }
+ return result;
+ }
+
+ if ((Index + 1) == Count) {
+ return EFetchResult::Finish;
+ }
+
+ ++Index;
+ if (FileState) {
+ if (Index == 0) {
+ OpenRead();
+ }
+
+ std::copy_n(Read(ctx).GetElements(), Width, values);
+ return EFetchResult::One;
+ }
+
+ std::copy_n(InMemory(Index).GetElements(), Width, values);
+ return EFetchResult::One;
+ }
+
+ void Rewind() {
Y_VERIFY_DEBUG(!IsLive());
-#ifndef NDEBUG
- Y_VERIFY_DEBUG(IsSealed);
-#endif
- Index = ui64(-1);
- if (FileState) {
- OpenRead();
- }
- }
-
-private:
- NUdf::TUnboxedValue& InMemory(ui32 index) {
- return !Heap.empty() ? Heap[index] : Stack[index];
- }
-
- const NUdf::TUnboxedValue& InMemory(ui32 index) const {
- return !Heap.empty() ? Heap[index] : Stack[index];
- }
-
- void OpenWrite() {
- Cerr << "Spill started at " << Count << " items to " << FileState->File.GetName() << Endl;
- FileState->Output.reset(new TFixedBufferFileOutput(FileState->File.GetName()));
- FileState->Output->SetFlushPropagateMode(false);
- FileState->Output->SetFinishPropagateMode(false);
- }
-
- void Write(NUdf::TUnboxedValue&& value) {
- Y_VERIFY_DEBUG(FileState->Output);
- TStringBuf serialized = ItemPacker.Pack(value);
+#ifndef NDEBUG
+ Y_VERIFY_DEBUG(IsSealed);
+#endif
+ Index = ui64(-1);
+ if (FileState) {
+ OpenRead();
+ }
+ }
+
+private:
+ NUdf::TUnboxedValue& InMemory(ui32 index) {
+ return !Heap.empty() ? Heap[index] : Stack[index];
+ }
+
+ const NUdf::TUnboxedValue& InMemory(ui32 index) const {
+ return !Heap.empty() ? Heap[index] : Stack[index];
+ }
+
+ void OpenWrite() {
+ Cerr << "Spill started at " << Count << " items to " << FileState->File.GetName() << Endl;
+ FileState->Output.reset(new TFixedBufferFileOutput(FileState->File.GetName()));
+ FileState->Output->SetFlushPropagateMode(false);
+ FileState->Output->SetFinishPropagateMode(false);
+ }
+
+ void Write(NUdf::TUnboxedValue&& value) {
+ Y_VERIFY_DEBUG(FileState->Output);
+ TStringBuf serialized = ItemPacker.Pack(value);
ui32 length = serialized.size();
- FileState->Output->Write(&length, sizeof(length));
+ FileState->Output->Write(&length, sizeof(length));
FileState->Output->Write(serialized.data(), length);
- FileState->TotalSize += sizeof(length);
- FileState->TotalSize += length;
- }
-
- void OpenRead() {
- FileState->Input.reset();
- FileState->Input.reset(new TFileInput(FileState->File.GetName()));
- }
-
- NUdf::TUnboxedValue Read(TComputationContext& ctx) {
- ui32 length = 0;
- auto wasRead = FileState->Input->Load(&length, sizeof(length));
- Y_VERIFY(wasRead == sizeof(length));
- FileState->Buffer.Reserve(length);
- wasRead = FileState->Input->Load((void*)FileState->Buffer.Data(), length);
- Y_VERIFY(wasRead == length);
- return ReadValue = ItemPacker.Unpack(TStringBuf(FileState->Buffer.Data(), length), ctx.HolderFactory);
- }
-
-private:
- const size_t Width;
- TValuePacker& ItemPacker;
- ui64 Count;
- NUdf::TUnboxedValue ReadValue;
- NUdf::TUnboxedValue Stack[DEFAULT_STACK_ITEMS];
- TUnboxedValueVector Heap;
-#ifndef NDEBUG
- bool IsSealed;
-#endif
- ui64 Index;
+ FileState->TotalSize += sizeof(length);
+ FileState->TotalSize += length;
+ }
+
+ void OpenRead() {
+ FileState->Input.reset();
+ FileState->Input.reset(new TFileInput(FileState->File.GetName()));
+ }
+
+ NUdf::TUnboxedValue Read(TComputationContext& ctx) {
+ ui32 length = 0;
+ auto wasRead = FileState->Input->Load(&length, sizeof(length));
+ Y_VERIFY(wasRead == sizeof(length));
+ FileState->Buffer.Reserve(length);
+ wasRead = FileState->Input->Load((void*)FileState->Buffer.Data(), length);
+ Y_VERIFY(wasRead == length);
+ return ReadValue = ItemPacker.Unpack(TStringBuf(FileState->Buffer.Data(), length), ctx.HolderFactory);
+ }
+
+private:
+ const size_t Width;
+ TValuePacker& ItemPacker;
+ ui64 Count;
+ NUdf::TUnboxedValue ReadValue;
+ NUdf::TUnboxedValue Stack[DEFAULT_STACK_ITEMS];
+ TUnboxedValueVector Heap;
+#ifndef NDEBUG
+ bool IsSealed;
+#endif
+ ui64 Index;
const bool SingleShot;
- struct TFileState {
- TFileState()
+ struct TFileState {
+ TFileState()
: File(TTempFileHandle::InCurrentDir())
- , TotalSize(0)
- {}
-
- TTempFileHandle File;
- ui64 TotalSize;
- std::unique_ptr<TFileInput> Input;
- std::unique_ptr<TFixedBufferFileOutput> Output;
- TBuffer Buffer;
- };
-
- std::unique_ptr<TFileState> FileState;
+ , TotalSize(0)
+ {}
+
+ TTempFileHandle File;
+ ui64 TotalSize;
+ std::unique_ptr<TFileInput> Input;
+ std::unique_ptr<TFixedBufferFileOutput> Output;
+ TBuffer Buffer;
+ };
+
+ std::unique_ptr<TFileState> FileState;
IComputationNode* LiveFlow = nullptr;
- TLiveFetcher Fetcher;
- NUdf::TUnboxedValue LiveValue;
- NUdf::TUnboxedValue* LiveValues = nullptr;
-};
-
-template <EJoinKind Kind, bool TTrackRss>
-class TCommonJoinCoreWrapper : public TStatefulFlowComputationNode<TCommonJoinCoreWrapper<Kind, TTrackRss>> {
- using TSelf = TCommonJoinCoreWrapper<Kind, TTrackRss>;
- using TBase = TStatefulFlowComputationNode<TSelf>;
- typedef TBase TBaseComputation;
-public:
- class TValue : public TComputationValue<TValue> {
- friend TSelf;
- public:
- using TBase = TComputationValue<TValue>;
-
- TValue(TMemoryUsageInfo* memInfo, TComputationContext& ctx, const TSelf* self)
- : TBase(memInfo)
- , Self(self)
+ TLiveFetcher Fetcher;
+ NUdf::TUnboxedValue LiveValue;
+ NUdf::TUnboxedValue* LiveValues = nullptr;
+};
+
+template <EJoinKind Kind, bool TTrackRss>
+class TCommonJoinCoreWrapper : public TStatefulFlowComputationNode<TCommonJoinCoreWrapper<Kind, TTrackRss>> {
+ using TSelf = TCommonJoinCoreWrapper<Kind, TTrackRss>;
+ using TBase = TStatefulFlowComputationNode<TSelf>;
+ typedef TBase TBaseComputation;
+public:
+ class TValue : public TComputationValue<TValue> {
+ friend TSelf;
+ public:
+ using TBase = TComputationValue<TValue>;
+
+ TValue(TMemoryUsageInfo* memInfo, TComputationContext& ctx, const TSelf* self)
+ : TBase(memInfo)
+ , Self(self)
, List1(Self->Packer.RefMutableObject(ctx, false, Self->InputStructType), IsAnyJoinLeft(Self->AnyJoinSettings))
, List2(Self->Packer.RefMutableObject(ctx, false, Self->InputStructType), IsAnyJoinRight(Self->AnyJoinSettings))
- {
- Init();
- }
-
- void Init() {
- List1.Init();
- List2.Init();
- CrossMove1 = true;
- EatInput = true;
- KeyHasNulls = false;
- OutputMode = EOutputMode::Unknown;
- InitialUsage = std::nullopt;
- }
-
- private:
+ {
+ Init();
+ }
+
+ void Init() {
+ List1.Init();
+ List2.Init();
+ CrossMove1 = true;
+ EatInput = true;
+ KeyHasNulls = false;
+ OutputMode = EOutputMode::Unknown;
+ InitialUsage = std::nullopt;
+ }
+
+ private:
// copypaste to resolve -Woverloaded-virtual
bool Next(NUdf::TUnboxedValue&) override {
- this->ThrowNotSupported(__func__);
+ this->ThrowNotSupported(__func__);
return false;
}
- NUdf::TUnboxedValue Next(IComputationNode* flow, TComputationContext& ctx) {
- while (EatInput) {
- if (!InitialUsage) {
- InitialUsage = ctx.HolderFactory.GetPagePool().GetUsed();
- }
-
- if (auto value = flow->GetValue(ctx); value.IsYield()) {
- return value;
- } else if (value.IsFinish()) {
- EatInput = false;
- } else {
- if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
- for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
- if (!value.GetElement(Self->KeyColumns[i])) {
- KeyHasNulls = true;
- break;
- }
- }
- }
-
- switch (const auto tableIndex = value.GetElement(Self->TableIndexPos).template Get<ui32>()) {
- case LeftIndex:
- if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
- }
-
- if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
- List1.Live(flow, std::move(value));
- EatInput = false;
- } else {
- List1.Add(std::move(value));
- if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List1.Spill();
- }
- }
- break;
- case RightIndex:
- if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
- }
-
- if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
- List2.Live(flow, std::move(value));
- EatInput = false;
- } else {
- List2.Add(std::move(value));
- if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List2.Spill();
- }
- }
- break;
- default: THROW yexception() << "Bad table index: " << tableIndex;
- }
- }
- }
-
- while (true) {
- switch (OutputMode) {
- case EOutputMode::Unknown: {
- List1.Seal(ctx);
- List2.Seal(ctx);
- switch (Kind) {
- case EJoinKind::Cross:
- case EJoinKind::Inner:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- }
-
- break;
- case EJoinKind::Left:
- if (List1.Empty()) {
- OutputMode = EOutputMode::None;
- }
- break;
-
- case EJoinKind::LeftOnly:
- if (List1.Empty() || !List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
- }
- break;
-
- case EJoinKind::Right:
- if (List2.Empty()) {
- OutputMode = EOutputMode::None;
- }
- break;
-
- case EJoinKind::RightOnly:
- if (List2.Empty() || !List1.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
- }
- break;
-
- case EJoinKind::Exclusion:
- if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
- OutputMode = EOutputMode::None;
- } else if (List1.Empty()) {
- OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
- OutputMode = EOutputMode::RightNull;
- } else {
- OutputMode = EOutputMode::BothNull;
- }
- break;
-
- case EJoinKind::Full:
- break;
-
- case EJoinKind::LeftSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
- }
- break;
-
- case EJoinKind::RightSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
- }
- break;
-
- default:
- Y_FAIL("Unknown kind");
- }
-
- if (OutputMode == EOutputMode::Unknown) {
- if (List1.Empty()) {
- OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
- OutputMode = EOutputMode::RightNull;
- } else if (List1.IsLive()) {
- OutputMode = EOutputMode::Cross;
- } else if (List2.IsLive()) {
- OutputMode = EOutputMode::CrossSwap;
- } else {
- OutputMode = List1.GetCount() >= List2.GetCount() ?
- EOutputMode::Cross : EOutputMode::CrossSwap;
- }
- }
- }
- continue;
- case EOutputMode::LeftNull:
- if (const auto item = List2.Next(ctx); item.IsSpecial()) {
- return item;
- } else {
- return PrepareNullItem<true>(ctx, item);
- }
- case EOutputMode::RightNull:
- if (const auto item = List1.Next(ctx); item.IsSpecial()) {
- return item;
- } else {
- return PrepareNullItem<false>(ctx, item);
- }
- case EOutputMode::BothNull:
- if (CrossMove1) {
- if (const auto item = List1.Next(ctx); item.IsFinish()) {
- CrossMove1 = false;
- } else if (item.IsYield()) {
- return item;
- } else {
- return PrepareNullItem<false>(ctx, item);
- }
- }
-
- if (const auto item = List2.Next(ctx); item.IsSpecial()) {
- return item;
- } else {
- return PrepareNullItem<true>(ctx, item);
- }
- case EOutputMode::Cross:
- return PrepareCrossItem<false>(ctx);
- case EOutputMode::CrossSwap:
- return PrepareCrossItem<true>(ctx);
- case EOutputMode::None:
- return NUdf::TUnboxedValuePod::MakeFinish();
- default:
- Y_FAIL("Unknown output mode");
- }
- }
- }
-
- template <bool IsLeftNull>
- NUdf::TUnboxedValue PrepareNullItem(TComputationContext& ctx, const NUdf::TUnboxedValue& value) {
- const auto structObj = Self->ResStruct.NewArray(ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
-
- for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
- ui32 inIndex = Self->LeftInputColumns[i];
- ui32 outIndex = Self->LeftOutputColumns[i];
- if constexpr (IsLeftNull) {
- ResItems[outIndex] = NUdf::TUnboxedValuePod();
- continue;
- }
-
- auto member = value.GetElement(inIndex);
- if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
- } else {
- ResItems[outIndex] = std::move(member);
- }
- }
-
- for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
- ui32 inIndex = Self->RightInputColumns[i];
- ui32 outIndex = Self->RightOutputColumns[i];
- if constexpr (!IsLeftNull) {
- ResItems[outIndex] = NUdf::TUnboxedValuePod();
- continue;
- }
-
- auto member = value.GetElement(inIndex);
- if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
- }
- else {
- ResItems[outIndex] = std::move(member);
- }
- }
-
- return structObj;
- }
-
- template <bool SwapLists>
- NUdf::TUnboxedValue PrepareCrossItem(TComputationContext& ctx) {
- if (KeyHasNulls) {
- for (;;) {
- const auto& value = (CrossMove1 == SwapLists ? List2 : List1).Next(ctx);
- if (value.IsFinish() && CrossMove1) {
- CrossMove1 = false;
- continue;
- }
-
- if (value.IsSpecial()) {
- return value;
- }
-
- return (CrossMove1 == SwapLists) ? PrepareNullItem<true>(ctx, value) : PrepareNullItem<false>(ctx, value);
- }
- }
-
- for (;;) {
- if (CrossMove1) {
- CrossValue1 = (SwapLists ? List2 : List1).Next(ctx);
- if (CrossValue1.IsSpecial()) {
- return CrossValue1;
- }
-
- CrossMove1 = false;
- (SwapLists ? List1 : List2).Rewind();
- }
-
- CrossValue2 = (SwapLists ? List1 : List2).Next(ctx);
- if (CrossValue2.IsFinish()) {
- CrossMove1 = true;
- continue;
- }
-
- auto structObj = Self->ResStruct.NewArray(ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
-
- for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
- ui32 inIndex = Self->LeftInputColumns[i];
- ui32 outIndex = Self->LeftOutputColumns[i];
- auto member = (SwapLists ? CrossValue2 : CrossValue1).GetElement(inIndex);
- if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
- } else {
- ResItems[outIndex] = std::move(member);
- }
- }
-
- for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
- ui32 inIndex = Self->RightInputColumns[i];
- ui32 outIndex = Self->RightOutputColumns[i];
- auto member = (SwapLists ? CrossValue1 : CrossValue2).GetElement(inIndex);
- if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
- } else {
- ResItems[outIndex] = std::move(member);
- }
- }
-
- return std::move(structObj);
- }
- }
-
-
- private:
- const TSelf* const Self;
- bool EatInput;
- bool KeyHasNulls;
- std::optional<ui64> InitialUsage;
- EOutputMode OutputMode;
-
- bool CrossMove1;
- NUdf::TUnboxedValue CrossValue1;
- NUdf::TUnboxedValue CrossValue2;
-
- TSpillList List1;
- TSpillList List2;
-
- NUdf::TUnboxedValue* ResItems = nullptr;
- };
-
- TCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationNode* flow, const TType* inputStructType, ui32 inputWidth, ui32 tableIndexPos,
- std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
- std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
+ NUdf::TUnboxedValue Next(IComputationNode* flow, TComputationContext& ctx) {
+ while (EatInput) {
+ if (!InitialUsage) {
+ InitialUsage = ctx.HolderFactory.GetPagePool().GetUsed();
+ }
+
+ if (auto value = flow->GetValue(ctx); value.IsYield()) {
+ return value;
+ } else if (value.IsFinish()) {
+ EatInput = false;
+ } else {
+ if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
+ for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
+ if (!value.GetElement(Self->KeyColumns[i])) {
+ KeyHasNulls = true;
+ break;
+ }
+ }
+ }
+
+ switch (const auto tableIndex = value.GetElement(Self->TableIndexPos).template Get<ui32>()) {
+ case LeftIndex:
+ if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
+ }
+
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
+ List1.Live(flow, std::move(value));
+ EatInput = false;
+ } else {
+ List1.Add(std::move(value));
+ if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List1.Spill();
+ }
+ }
+ break;
+ case RightIndex:
+ if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
+ }
+
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
+ List2.Live(flow, std::move(value));
+ EatInput = false;
+ } else {
+ List2.Add(std::move(value));
+ if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List2.Spill();
+ }
+ }
+ break;
+ default: THROW yexception() << "Bad table index: " << tableIndex;
+ }
+ }
+ }
+
+ while (true) {
+ switch (OutputMode) {
+ case EOutputMode::Unknown: {
+ List1.Seal(ctx);
+ List2.Seal(ctx);
+ switch (Kind) {
+ case EJoinKind::Cross:
+ case EJoinKind::Inner:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+
+ break;
+ case EJoinKind::Left:
+ if (List1.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+ break;
+
+ case EJoinKind::LeftOnly:
+ if (List1.Empty() || !List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
+ }
+ break;
+
+ case EJoinKind::Right:
+ if (List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+ break;
+
+ case EJoinKind::RightOnly:
+ if (List2.Empty() || !List1.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
+ }
+ break;
+
+ case EJoinKind::Exclusion:
+ if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
+ OutputMode = EOutputMode::None;
+ } else if (List1.Empty()) {
+ OutputMode = EOutputMode::LeftNull;
+ } else if (List2.Empty()) {
+ OutputMode = EOutputMode::RightNull;
+ } else {
+ OutputMode = EOutputMode::BothNull;
+ }
+ break;
+
+ case EJoinKind::Full:
+ break;
+
+ case EJoinKind::LeftSemi:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
+ }
+ break;
+
+ case EJoinKind::RightSemi:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
+ }
+ break;
+
+ default:
+ Y_FAIL("Unknown kind");
+ }
+
+ if (OutputMode == EOutputMode::Unknown) {
+ if (List1.Empty()) {
+ OutputMode = EOutputMode::LeftNull;
+ } else if (List2.Empty()) {
+ OutputMode = EOutputMode::RightNull;
+ } else if (List1.IsLive()) {
+ OutputMode = EOutputMode::Cross;
+ } else if (List2.IsLive()) {
+ OutputMode = EOutputMode::CrossSwap;
+ } else {
+ OutputMode = List1.GetCount() >= List2.GetCount() ?
+ EOutputMode::Cross : EOutputMode::CrossSwap;
+ }
+ }
+ }
+ continue;
+ case EOutputMode::LeftNull:
+ if (const auto item = List2.Next(ctx); item.IsSpecial()) {
+ return item;
+ } else {
+ return PrepareNullItem<true>(ctx, item);
+ }
+ case EOutputMode::RightNull:
+ if (const auto item = List1.Next(ctx); item.IsSpecial()) {
+ return item;
+ } else {
+ return PrepareNullItem<false>(ctx, item);
+ }
+ case EOutputMode::BothNull:
+ if (CrossMove1) {
+ if (const auto item = List1.Next(ctx); item.IsFinish()) {
+ CrossMove1 = false;
+ } else if (item.IsYield()) {
+ return item;
+ } else {
+ return PrepareNullItem<false>(ctx, item);
+ }
+ }
+
+ if (const auto item = List2.Next(ctx); item.IsSpecial()) {
+ return item;
+ } else {
+ return PrepareNullItem<true>(ctx, item);
+ }
+ case EOutputMode::Cross:
+ return PrepareCrossItem<false>(ctx);
+ case EOutputMode::CrossSwap:
+ return PrepareCrossItem<true>(ctx);
+ case EOutputMode::None:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ default:
+ Y_FAIL("Unknown output mode");
+ }
+ }
+ }
+
+ template <bool IsLeftNull>
+ NUdf::TUnboxedValue PrepareNullItem(TComputationContext& ctx, const NUdf::TUnboxedValue& value) {
+ const auto structObj = Self->ResStruct.NewArray(ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
+
+ for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
+ ui32 inIndex = Self->LeftInputColumns[i];
+ ui32 outIndex = Self->LeftOutputColumns[i];
+ if constexpr (IsLeftNull) {
+ ResItems[outIndex] = NUdf::TUnboxedValuePod();
+ continue;
+ }
+
+ auto member = value.GetElement(inIndex);
+ if (Self->IsRequiredColumn[inIndex]) {
+ ResItems[outIndex] = member.Release().GetOptionalValue();
+ } else {
+ ResItems[outIndex] = std::move(member);
+ }
+ }
+
+ for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
+ ui32 inIndex = Self->RightInputColumns[i];
+ ui32 outIndex = Self->RightOutputColumns[i];
+ if constexpr (!IsLeftNull) {
+ ResItems[outIndex] = NUdf::TUnboxedValuePod();
+ continue;
+ }
+
+ auto member = value.GetElement(inIndex);
+ if (Self->IsRequiredColumn[inIndex]) {
+ ResItems[outIndex] = member.Release().GetOptionalValue();
+ }
+ else {
+ ResItems[outIndex] = std::move(member);
+ }
+ }
+
+ return structObj;
+ }
+
+ template <bool SwapLists>
+ NUdf::TUnboxedValue PrepareCrossItem(TComputationContext& ctx) {
+ if (KeyHasNulls) {
+ for (;;) {
+ const auto& value = (CrossMove1 == SwapLists ? List2 : List1).Next(ctx);
+ if (value.IsFinish() && CrossMove1) {
+ CrossMove1 = false;
+ continue;
+ }
+
+ if (value.IsSpecial()) {
+ return value;
+ }
+
+ return (CrossMove1 == SwapLists) ? PrepareNullItem<true>(ctx, value) : PrepareNullItem<false>(ctx, value);
+ }
+ }
+
+ for (;;) {
+ if (CrossMove1) {
+ CrossValue1 = (SwapLists ? List2 : List1).Next(ctx);
+ if (CrossValue1.IsSpecial()) {
+ return CrossValue1;
+ }
+
+ CrossMove1 = false;
+ (SwapLists ? List1 : List2).Rewind();
+ }
+
+ CrossValue2 = (SwapLists ? List1 : List2).Next(ctx);
+ if (CrossValue2.IsFinish()) {
+ CrossMove1 = true;
+ continue;
+ }
+
+ auto structObj = Self->ResStruct.NewArray(ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
+
+ for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
+ ui32 inIndex = Self->LeftInputColumns[i];
+ ui32 outIndex = Self->LeftOutputColumns[i];
+ auto member = (SwapLists ? CrossValue2 : CrossValue1).GetElement(inIndex);
+ if (Self->IsRequiredColumn[inIndex]) {
+ ResItems[outIndex] = member.Release().GetOptionalValue();
+ } else {
+ ResItems[outIndex] = std::move(member);
+ }
+ }
+
+ for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
+ ui32 inIndex = Self->RightInputColumns[i];
+ ui32 outIndex = Self->RightOutputColumns[i];
+ auto member = (SwapLists ? CrossValue1 : CrossValue2).GetElement(inIndex);
+ if (Self->IsRequiredColumn[inIndex]) {
+ ResItems[outIndex] = member.Release().GetOptionalValue();
+ } else {
+ ResItems[outIndex] = std::move(member);
+ }
+ }
+
+ return std::move(structObj);
+ }
+ }
+
+
+ private:
+ const TSelf* const Self;
+ bool EatInput;
+ bool KeyHasNulls;
+ std::optional<ui64> InitialUsage;
+ EOutputMode OutputMode;
+
+ bool CrossMove1;
+ NUdf::TUnboxedValue CrossValue1;
+ NUdf::TUnboxedValue CrossValue2;
+
+ TSpillList List1;
+ TSpillList List2;
+
+ NUdf::TUnboxedValue* ResItems = nullptr;
+ };
+
+ TCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationNode* flow, const TType* inputStructType, ui32 inputWidth, ui32 tableIndexPos,
+ std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
+ std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
std::optional<ui32> sortedTableOrder, std::vector<ui32>&& keyColumns, EAnyJoinSettings anyJoinSettings)
- : TBaseComputation(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
- , Flow(flow)
- , InputStructType(inputStructType)
- , Packer(mutables)
- , TableIndexPos(tableIndexPos)
- , LeftInputColumns(std::move(leftInputColumns))
- , RightInputColumns(std::move(rightInputColumns))
- , RequiredColumns(std::move(requiredColumns))
- , LeftOutputColumns(std::move(leftOutputColumns))
- , RightOutputColumns(std::move(rightOutputColumns))
- , MemLimit(memLimit)
- , SortedTableOrder(sortedTableOrder)
- , KeyColumns(std::move(keyColumns))
- , IsRequiredColumn(FillRequiredStructColumn(inputWidth, RequiredColumns))
- , ResStruct(mutables)
- , ResStreamIndex(mutables.CurValueIndex++)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ , Flow(flow)
+ , InputStructType(inputStructType)
+ , Packer(mutables)
+ , TableIndexPos(tableIndexPos)
+ , LeftInputColumns(std::move(leftInputColumns))
+ , RightInputColumns(std::move(rightInputColumns))
+ , RequiredColumns(std::move(requiredColumns))
+ , LeftOutputColumns(std::move(leftOutputColumns))
+ , RightOutputColumns(std::move(rightOutputColumns))
+ , MemLimit(memLimit)
+ , SortedTableOrder(sortedTableOrder)
+ , KeyColumns(std::move(keyColumns))
+ , IsRequiredColumn(FillRequiredStructColumn(inputWidth, RequiredColumns))
+ , ResStruct(mutables)
+ , ResStreamIndex(mutables.CurValueIndex++)
, AnyJoinSettings(anyJoinSettings)
- {
- }
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (!state.HasValue()) {
- state = ctx.HolderFactory.Create<TValue>(ctx, this);
- }
-
- return static_cast<TValue*>(state.AsBoxed().Get())->Next(Flow, ctx);
- }
-
-private:
- void RegisterDependencies() const final {
- this->FlowDependsOn(Flow);
- }
-
- IComputationNode* const Flow;
- const TType* const InputStructType;
- const TMutableObjectOverBoxedValue<TValuePackerBoxed> Packer;
- const ui32 TableIndexPos;
- const std::vector<ui32> LeftInputColumns;
- const std::vector<ui32> RightInputColumns;
- const std::vector<ui32> RequiredColumns;
- const std::vector<ui32> LeftOutputColumns;
- const std::vector<ui32> RightOutputColumns;
- const ui64 MemLimit;
- const std::optional<ui32> SortedTableOrder;
- const std::vector<ui32> KeyColumns;
- const std::vector<bool> IsRequiredColumn;
-
- const TContainerCacheOnContext ResStruct;
- const ui32 ResStreamIndex;
+ {
+ }
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (!state.HasValue()) {
+ state = ctx.HolderFactory.Create<TValue>(ctx, this);
+ }
+
+ return static_cast<TValue*>(state.AsBoxed().Get())->Next(Flow, ctx);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->FlowDependsOn(Flow);
+ }
+
+ IComputationNode* const Flow;
+ const TType* const InputStructType;
+ const TMutableObjectOverBoxedValue<TValuePackerBoxed> Packer;
+ const ui32 TableIndexPos;
+ const std::vector<ui32> LeftInputColumns;
+ const std::vector<ui32> RightInputColumns;
+ const std::vector<ui32> RequiredColumns;
+ const std::vector<ui32> LeftOutputColumns;
+ const std::vector<ui32> RightOutputColumns;
+ const ui64 MemLimit;
+ const std::optional<ui32> SortedTableOrder;
+ const std::vector<ui32> KeyColumns;
+ const std::vector<bool> IsRequiredColumn;
+
+ const TContainerCacheOnContext ResStruct;
+ const ui32 ResStreamIndex;
const EAnyJoinSettings AnyJoinSettings;
-};
-
-template <EJoinKind Kind, bool TTrackRss>
-class TWideCommonJoinCoreWrapper : public TStatefulWideFlowCodegeneratorNode<TWideCommonJoinCoreWrapper<Kind, TTrackRss>>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
- using TSelf = TWideCommonJoinCoreWrapper<Kind, TTrackRss>;
- using TBase = TStatefulWideFlowCodegeneratorNode<TSelf>;
- typedef TBase TBaseComputation;
-public:
- class TValue : public TComputationValue<TValue> {
- friend TSelf;
- public:
- using TBase = TComputationValue<TValue>;
-
- TValue(TMemoryUsageInfo* memInfo, TComputationContext& ctx, const TSelf* self, TFetcher&& fetcher)
- : TBase(memInfo)
- , Self(self)
- , Fetcher(std::move(fetcher))
- , Values(Self->InputRepresentations.size(), NUdf::TUnboxedValuePod())
- , CrossValues1(std::max(Self->LeftInputColumns.size(), Self->RightInputColumns.size()), NUdf::TUnboxedValuePod())
- , CrossValues2(std::max(Self->LeftInputColumns.size(), Self->RightInputColumns.size()), NUdf::TUnboxedValuePod())
- , List1(Self->PackerLeft.RefMutableObject(ctx, false, Self->InputLeftType), IsAnyJoinLeft(Self->AnyJoinSettings), Self->InputLeftType->GetElementsCount())
- , List2(Self->PackerRight.RefMutableObject(ctx, false, Self->InputRightType), IsAnyJoinRight(Self->AnyJoinSettings), Self->InputRightType->GetElementsCount())
- , Fields(GetPointers(Values))
- {
- Init();
- }
-
- void Init() {
- List1.Init();
- List2.Init();
- CrossMove1 = true;
- EatInput = true;
- KeyHasNulls = false;
- OutputMode = EOutputMode::Unknown;
- InitialUsage = std::nullopt;
- }
-
- private:
- // copypaste to resolve -Woverloaded-virtual
- bool Next(NUdf::TUnboxedValue&) override {
- this->ThrowNotSupported(__func__);
- return false;
- }
-
- EFetchResult FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
- while (EatInput) {
- if (!InitialUsage) {
- InitialUsage = ctx.HolderFactory.GetPagePool().GetUsed();
- }
-
- switch (Fetcher(ctx, Fields.data())) {
- case EFetchResult::Yield:
- return EFetchResult::Yield;
- case EFetchResult::Finish:
- EatInput = false;
- continue;
- default:
- break;
- }
-
- if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
- for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
- if (!*Fields[Self->KeyColumns[i]]) {
- KeyHasNulls = true;
- break;
- }
- }
- }
-
- switch (const auto tableIndex = Fields[Self->TableIndexPos]->template Get<ui32>()) {
- case LeftIndex:
- if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
- }
-
- if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
- TLiveFetcher fetcher = [this] (TComputationContext& ctx, NUdf::TUnboxedValue* output) {
- if (const auto status = Fetcher(ctx, Fields.data()); EFetchResult::One != status)
- return status;
- std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), output, [this] (ui32 index) { return std::move(this->Values[index]); });
- return EFetchResult::One;
- };
- std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), Values.data(), [this] (ui32 index) { return std::move(this->Values[index]); });
- List1.Live(std::move(fetcher), Values.data());
- EatInput = false;
- } else {
- NUdf::TUnboxedValue* items = nullptr;
- auto value = ctx.HolderFactory.CreateDirectArrayHolder(Self->LeftInputColumns.size(), items);
- std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), items, [this] (ui32 index) { return std::move(this->Values[index]); });
- List1.Add(std::move(value));
- if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List1.Spill();
- }
- }
- break;
- case RightIndex:
- if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
- }
-
- if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
- TLiveFetcher fetcher = [this] (TComputationContext& ctx, NUdf::TUnboxedValue* output) {
- if (const auto status = Fetcher(ctx, Fields.data()); EFetchResult::One != status)
- return status;
- std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), output, [this] (ui32 index) { return std::move(this->Values[index]); });
- return EFetchResult::One;
- };
- std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), Values.data(), [this] (ui32 index) { return std::move(this->Values[index]); });
- List2.Live(std::move(fetcher), Values.data());
- EatInput = false;
- } else {
- NUdf::TUnboxedValue* items = nullptr;
- auto value = ctx.HolderFactory.CreateDirectArrayHolder(Self->RightInputColumns.size(), items);
- std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), items, [this] (ui32 index) { return std::move(this->Values[index]); });
- List2.Add(std::move(value));
- if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List2.Spill();
- }
- }
- break;
- default: THROW yexception() << "Bad table index: " << tableIndex;
- }
- }
-
- while (true) {
- switch (OutputMode) {
- case EOutputMode::Unknown: {
- List1.Seal(ctx);
- List2.Seal(ctx);
- switch (Kind) {
- case EJoinKind::Cross:
- case EJoinKind::Inner:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- }
-
- break;
- case EJoinKind::Left:
- if (List1.Empty()) {
- OutputMode = EOutputMode::None;
- }
- break;
-
- case EJoinKind::LeftOnly:
- if (List1.Empty() || !List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
- }
- break;
-
- case EJoinKind::Right:
- if (List2.Empty()) {
- OutputMode = EOutputMode::None;
- }
- break;
-
- case EJoinKind::RightOnly:
- if (List2.Empty() || !List1.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
- }
- break;
-
- case EJoinKind::Exclusion:
- if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
- OutputMode = EOutputMode::None;
- } else if (List1.Empty()) {
- OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
- OutputMode = EOutputMode::RightNull;
- } else {
- OutputMode = EOutputMode::BothNull;
- }
- break;
-
- case EJoinKind::Full:
- break;
-
- case EJoinKind::LeftSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
- }
- break;
-
- case EJoinKind::RightSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
- }
- break;
-
- default:
- Y_FAIL("Unknown kind");
- }
-
- if (OutputMode == EOutputMode::Unknown) {
- if (List1.Empty()) {
- OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
- OutputMode = EOutputMode::RightNull;
- } else if (List1.IsLive()) {
- OutputMode = EOutputMode::Cross;
- } else if (List2.IsLive()) {
- OutputMode = EOutputMode::CrossSwap;
- } else {
- OutputMode = List1.GetCount() >= List2.GetCount() ?
- EOutputMode::Cross : EOutputMode::CrossSwap;
- }
- }
- }
- continue;
- case EOutputMode::LeftNull:
- if (const auto res = List2.Next(ctx, Values.data()); EFetchResult::One != res) {
- return res;
- }
-
- PrepareNullItem<true>(ctx, output);
- return EFetchResult::One;
-
- case EOutputMode::RightNull:
- if (const auto res = List1.Next(ctx, Values.data()); EFetchResult::One != res) {
- return res;
- }
-
- PrepareNullItem<false>(ctx, output);
- return EFetchResult::One;
- case EOutputMode::BothNull:
- if (CrossMove1) {
- switch (List1.Next(ctx, Values.data())) {
- case EFetchResult::Finish: CrossMove1 = false; break;
- case EFetchResult::Yield: return EFetchResult::Yield;
- case EFetchResult::One:
- PrepareNullItem<false>(ctx, output);
- return EFetchResult::One;
- }
- }
-
- if (const auto res = List2.Next(ctx, Values.data()); EFetchResult::One != res) {
- return res;
- }
-
- PrepareNullItem<true>(ctx, output);
- return EFetchResult::One;
- case EOutputMode::Cross:
- return PrepareCrossItem<false>(ctx, output);
- case EOutputMode::CrossSwap:
- return PrepareCrossItem<true>(ctx, output);
- case EOutputMode::None:
- return EFetchResult::Finish;
- default:
- Y_FAIL("Unknown output mode");
- }
- }
- }
-
- template <bool IsLeftNull>
- void PrepareNullItem(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
- for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
- if (const auto out = output[Self->LeftOutputColumns[i]]) {
- if constexpr (IsLeftNull) {
- *out = NUdf::TUnboxedValuePod();
- } else if (Self->IsRequiredColumn[Self->LeftInputColumns[i]]) {
- *out = Values[i].Release().GetOptionalValue();
- } else {
- *out = std::move(Values[i]);
- }
- }
- }
-
- for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
- if (const auto out = output[Self->RightOutputColumns[i]]) {
- if constexpr (!IsLeftNull) {
- *out = NUdf::TUnboxedValuePod();
- } else if (Self->IsRequiredColumn[Self->RightInputColumns[i]]) {
- *out = Values[i].Release().GetOptionalValue();
- } else {
- *out = std::move(Values[i]);
- }
- }
- }
- }
-
- template <bool SwapLists>
- EFetchResult PrepareCrossItem(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
- if (KeyHasNulls) {
- for (;;) {
- if (const auto res = (CrossMove1 == SwapLists ? List2 : List1).Next(ctx, Values.data()); EFetchResult::Finish == res && CrossMove1) {
- CrossMove1 = false;
- continue;
- } else if (EFetchResult::One != res) {
- return res;
- }
-
- if (CrossMove1 == SwapLists)
- PrepareNullItem<true>(ctx, output);
- else
- PrepareNullItem<false>(ctx, output);
-
- return EFetchResult::One;
- }
- }
-
- for (;;) {
- if (CrossMove1) {
- if (const auto res = (SwapLists ? List2 : List1).Next(ctx, CrossValues1.data()); EFetchResult::One != res) {
- return res;
- }
-
- CrossMove1 = false;
- (SwapLists ? List1 : List2).Rewind();
- }
-
- if (const auto res = (SwapLists ? List1 : List2).Next(ctx, CrossValues2.data()); EFetchResult::Finish == res) {
- CrossMove1 = true;
- continue;
- } else if (EFetchResult::Yield == res) {
- return EFetchResult::Yield;
- }
-
- const auto& lValues = SwapLists ? CrossValues2 : CrossValues1;
- const auto& rValues = SwapLists ? CrossValues1 : CrossValues2;
-
- for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
- if (const auto out = output[Self->LeftOutputColumns[i]]) {
- if (Self->IsRequiredColumn[Self->LeftInputColumns[i]]) {
- *out = NUdf::TUnboxedValue(lValues[i]).Release().GetOptionalValue();
- } else {
- *out = lValues[i];
- }
- }
- }
-
- for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
- if (const auto out = output[Self->RightOutputColumns[i]]) {
- if (Self->IsRequiredColumn[Self->RightInputColumns[i]]) {
- *out = NUdf::TUnboxedValue(rValues[i]).Release().GetOptionalValue();
- } else {
- *out = rValues[i];
- }
- }
- }
-
- return EFetchResult::One;
- }
- }
-
- private:
- static std::vector<NUdf::TUnboxedValue*> GetPointers(std::vector<NUdf::TUnboxedValue>& array) {
- std::vector<NUdf::TUnboxedValue*> pointers;
- pointers.reserve(array.size());
- std::transform(array.begin(), array.end(), std::back_inserter(pointers), [](NUdf::TUnboxedValue& v) { return std::addressof(v); });
- return pointers;
- }
-
-
- const TSelf* const Self;
- TFetcher Fetcher;
- bool EatInput;
- bool KeyHasNulls;
- std::optional<ui64> InitialUsage;
- EOutputMode OutputMode;
-
- bool CrossMove1;
-
- std::vector<NUdf::TUnboxedValue> Values, CrossValues1, CrossValues2;
-
- TSpillList List1, List2;
-
- NUdf::TUnboxedValue* ResItems = nullptr;
- const std::vector<NUdf::TUnboxedValue*> Fields;
- };
-
- TWideCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, const TTupleType* inputLeftType, const TTupleType* inputRightType,
- std::vector<EValueRepresentation>&& inputRepresentations, std::vector<EValueRepresentation>&& outputRepresentations, ui32 tableIndexPos,
- std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
- std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
- std::optional<ui32> sortedTableOrder, std::vector<ui32>&& keyColumns, EAnyJoinSettings anyJoinSettings)
- : TBaseComputation(mutables, flow, EValueRepresentation::Any)
- , Flow(flow), InputRepresentations(std::move(inputRepresentations)), OutputRepresentations(std::move(outputRepresentations))
- , InputLeftType(inputLeftType), InputRightType(inputRightType)
- , PackerLeft(mutables), PackerRight(mutables)
- , TableIndexPos(tableIndexPos)
- , LeftInputColumns(std::move(leftInputColumns))
- , RightInputColumns(std::move(rightInputColumns))
- , RequiredColumns(std::move(requiredColumns))
- , LeftOutputColumns(std::move(leftOutputColumns))
- , RightOutputColumns(std::move(rightOutputColumns))
- , MemLimit(memLimit)
- , SortedTableOrder(sortedTableOrder)
- , KeyColumns(std::move(keyColumns))
- , IsRequiredColumn(FillRequiredStructColumn(InputRepresentations.size(), RequiredColumns))
- , AnyJoinSettings(anyJoinSettings)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- return static_cast<TValue*>(state.AsBoxed().Get())->FetchValues(ctx, output);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt32Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto size = LeftOutputColumns.size() + RightOutputColumns.size();
- const auto arrayType = ArrayType::get(valueType, size);
- const auto fieldsType = ArrayType::get(PointerType::getUnqual(valueType), size);
-
- const auto atTop = &ctx.Func->getEntryBlock().back();
-
- const auto values = new AllocaInst(arrayType, 0U, "values", atTop);
- const auto fields = new AllocaInst(fieldsType, 0U, "fields", atTop);
-
- ICodegeneratorInlineWideNode::TGettersList getters(size);
-
- Value* initV = UndefValue::get(arrayType);
- Value* initF = UndefValue::get(fieldsType);
- std::vector<Value*> pointers;
- pointers.reserve(size);
- for (auto i = 0U; i < size; ++i) {
- pointers.emplace_back(GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, i)}, (TString("ptr_") += ToString(i)).c_str(), atTop));
- initV = InsertValueInst::Create(initV, ConstantInt::get(valueType, 0), {i}, (TString("zero_") += ToString(i)).c_str(), atTop);
- initF = InsertValueInst::Create(initF, pointers.back(), {i}, (TString("insert_") += ToString(i)).c_str(), atTop);
-
- getters[i] = [i, values](const TCodegenContext& ctx, BasicBlock*& block) {
- const auto indexType = Type::getInt32Ty(ctx.Codegen->GetContext());
- const auto pointer = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, i)}, (TString("ptr_") += ToString(i)).c_str(), block);
- return new LoadInst(pointer, (TString("load_") += ToString(i)).c_str(), block);
- };
- }
-
- new StoreInst(initV, values, atTop);
- new StoreInst(initF, fields, atTop);
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(main, make, HasValue(statePtr, block), block);
-
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideCommonJoinCoreWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- for (ui32 i = 0U; i < OutputRepresentations.size(); ++i) {
- ValueCleanup(OutputRepresentations[i], pointers[i], ctx, block);
- }
-
- new StoreInst(initV, values, block);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValue::FetchValues));
- const auto funcType = FunctionType::get(Type::getInt32Ty(context), { statePtrType, ctx.Ctx->getType(), fields->getType() }, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funcType), "fetch_func", block);
- const auto result = CallInst::Create(funcPtr, { stateArg, ctx.Ctx, fields }, "fetch", block);
-
- for (ui32 i = 0U; i < OutputRepresentations.size(); ++i) {
- ValueRelease(OutputRepresentations[i], pointers[i], ctx, block);
- }
-
- return {result, std::move(getters)};
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
-#ifdef MKQL_DISABLE_CODEGEN
- state = ctx.HolderFactory.Create<TValue>(ctx, this, std::bind(&IComputationWideFlowNode::FetchValues, Flow, std::placeholders::_1, std::placeholders::_2));
-#else
- state = Fetch && ctx.ExecuteLLVM ?
- ctx.HolderFactory.Create<TValue>(ctx, this, Fetch):
- ctx.HolderFactory.Create<TValue>(ctx, this, std::bind(&IComputationWideFlowNode::FetchValues, Flow, std::placeholders::_1, std::placeholders::_2));
-#endif
- }
-
- void RegisterDependencies() const final {
- this->FlowDependsOn(Flow);
- }
-
- IComputationWideFlowNode* const Flow;
- const std::vector<EValueRepresentation> InputRepresentations;
- const std::vector<EValueRepresentation> OutputRepresentations;
- const TTupleType* const InputLeftType;
- const TTupleType* const InputRightType;
- const TMutableObjectOverBoxedValue<TValuePackerBoxed> PackerLeft, PackerRight;
- const ui32 TableIndexPos;
- const std::vector<ui32> LeftInputColumns;
- const std::vector<ui32> RightInputColumns;
- const std::vector<ui32> RequiredColumns;
- const std::vector<ui32> LeftOutputColumns;
- const std::vector<ui32> RightOutputColumns;
- const ui64 MemLimit;
- const std::optional<ui32> SortedTableOrder;
- const std::vector<ui32> KeyColumns;
- const std::vector<bool> IsRequiredColumn;
- const EAnyJoinSettings AnyJoinSettings;
-#ifndef MKQL_DISABLE_CODEGEN
- typedef EFetchResult (*TFetchPtr)(TComputationContext&, NUdf::TUnboxedValue*const*);
-
- TFetchPtr Fetch = nullptr;
-
- Function* FetchFunc = nullptr;
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (FetchFunc) {
- Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- codegen->ExportSymbol(FetchFunc = GenerateFetchFunction(codegen));
- }
-
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::Fetch_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- Function* GenerateFetchFunction(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = MakeName();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto pointerType = PointerType::getUnqual(valueType);
- const auto arrayType = ArrayType::get(pointerType, InputRepresentations.size());
- const auto contextType = GetCompContextType(context);
- const auto resultType = Type::getInt32Ty(context);
- const auto funcType = FunctionType::get(resultType, {PointerType::getUnqual(contextType), PointerType::getUnqual(arrayType)}, false);
- const auto indexType = Type::getInt32Ty(context);
-
- TCodegenContext ctx(codegen);
+};
+
+template <EJoinKind Kind, bool TTrackRss>
+class TWideCommonJoinCoreWrapper : public TStatefulWideFlowCodegeneratorNode<TWideCommonJoinCoreWrapper<Kind, TTrackRss>>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+ using TSelf = TWideCommonJoinCoreWrapper<Kind, TTrackRss>;
+ using TBase = TStatefulWideFlowCodegeneratorNode<TSelf>;
+ typedef TBase TBaseComputation;
+public:
+ class TValue : public TComputationValue<TValue> {
+ friend TSelf;
+ public:
+ using TBase = TComputationValue<TValue>;
+
+ TValue(TMemoryUsageInfo* memInfo, TComputationContext& ctx, const TSelf* self, TFetcher&& fetcher)
+ : TBase(memInfo)
+ , Self(self)
+ , Fetcher(std::move(fetcher))
+ , Values(Self->InputRepresentations.size(), NUdf::TUnboxedValuePod())
+ , CrossValues1(std::max(Self->LeftInputColumns.size(), Self->RightInputColumns.size()), NUdf::TUnboxedValuePod())
+ , CrossValues2(std::max(Self->LeftInputColumns.size(), Self->RightInputColumns.size()), NUdf::TUnboxedValuePod())
+ , List1(Self->PackerLeft.RefMutableObject(ctx, false, Self->InputLeftType), IsAnyJoinLeft(Self->AnyJoinSettings), Self->InputLeftType->GetElementsCount())
+ , List2(Self->PackerRight.RefMutableObject(ctx, false, Self->InputRightType), IsAnyJoinRight(Self->AnyJoinSettings), Self->InputRightType->GetElementsCount())
+ , Fields(GetPointers(Values))
+ {
+ Init();
+ }
+
+ void Init() {
+ List1.Init();
+ List2.Init();
+ CrossMove1 = true;
+ EatInput = true;
+ KeyHasNulls = false;
+ OutputMode = EOutputMode::Unknown;
+ InitialUsage = std::nullopt;
+ }
+
+ private:
+ // copypaste to resolve -Woverloaded-virtual
+ bool Next(NUdf::TUnboxedValue&) override {
+ this->ThrowNotSupported(__func__);
+ return false;
+ }
+
+ EFetchResult FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
+ while (EatInput) {
+ if (!InitialUsage) {
+ InitialUsage = ctx.HolderFactory.GetPagePool().GetUsed();
+ }
+
+ switch (Fetcher(ctx, Fields.data())) {
+ case EFetchResult::Yield:
+ return EFetchResult::Yield;
+ case EFetchResult::Finish:
+ EatInput = false;
+ continue;
+ default:
+ break;
+ }
+
+ if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
+ for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
+ if (!*Fields[Self->KeyColumns[i]]) {
+ KeyHasNulls = true;
+ break;
+ }
+ }
+ }
+
+ switch (const auto tableIndex = Fields[Self->TableIndexPos]->template Get<ui32>()) {
+ case LeftIndex:
+ if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
+ }
+
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
+ TLiveFetcher fetcher = [this] (TComputationContext& ctx, NUdf::TUnboxedValue* output) {
+ if (const auto status = Fetcher(ctx, Fields.data()); EFetchResult::One != status)
+ return status;
+ std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), output, [this] (ui32 index) { return std::move(this->Values[index]); });
+ return EFetchResult::One;
+ };
+ std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), Values.data(), [this] (ui32 index) { return std::move(this->Values[index]); });
+ List1.Live(std::move(fetcher), Values.data());
+ EatInput = false;
+ } else {
+ NUdf::TUnboxedValue* items = nullptr;
+ auto value = ctx.HolderFactory.CreateDirectArrayHolder(Self->LeftInputColumns.size(), items);
+ std::transform(Self->LeftInputColumns.cbegin(), Self->LeftInputColumns.cend(), items, [this] (ui32 index) { return std::move(this->Values[index]); });
+ List1.Add(std::move(value));
+ if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List1.Spill();
+ }
+ }
+ break;
+ case RightIndex:
+ if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
+ }
+
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
+ TLiveFetcher fetcher = [this] (TComputationContext& ctx, NUdf::TUnboxedValue* output) {
+ if (const auto status = Fetcher(ctx, Fields.data()); EFetchResult::One != status)
+ return status;
+ std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), output, [this] (ui32 index) { return std::move(this->Values[index]); });
+ return EFetchResult::One;
+ };
+ std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), Values.data(), [this] (ui32 index) { return std::move(this->Values[index]); });
+ List2.Live(std::move(fetcher), Values.data());
+ EatInput = false;
+ } else {
+ NUdf::TUnboxedValue* items = nullptr;
+ auto value = ctx.HolderFactory.CreateDirectArrayHolder(Self->RightInputColumns.size(), items);
+ std::transform(Self->RightInputColumns.cbegin(), Self->RightInputColumns.cend(), items, [this] (ui32 index) { return std::move(this->Values[index]); });
+ List2.Add(std::move(value));
+ if (ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List2.Spill();
+ }
+ }
+ break;
+ default: THROW yexception() << "Bad table index: " << tableIndex;
+ }
+ }
+
+ while (true) {
+ switch (OutputMode) {
+ case EOutputMode::Unknown: {
+ List1.Seal(ctx);
+ List2.Seal(ctx);
+ switch (Kind) {
+ case EJoinKind::Cross:
+ case EJoinKind::Inner:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+
+ break;
+ case EJoinKind::Left:
+ if (List1.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+ break;
+
+ case EJoinKind::LeftOnly:
+ if (List1.Empty() || !List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
+ }
+ break;
+
+ case EJoinKind::Right:
+ if (List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ }
+ break;
+
+ case EJoinKind::RightOnly:
+ if (List2.Empty() || !List1.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
+ }
+ break;
+
+ case EJoinKind::Exclusion:
+ if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
+ OutputMode = EOutputMode::None;
+ } else if (List1.Empty()) {
+ OutputMode = EOutputMode::LeftNull;
+ } else if (List2.Empty()) {
+ OutputMode = EOutputMode::RightNull;
+ } else {
+ OutputMode = EOutputMode::BothNull;
+ }
+ break;
+
+ case EJoinKind::Full:
+ break;
+
+ case EJoinKind::LeftSemi:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
+ }
+ break;
+
+ case EJoinKind::RightSemi:
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
+ }
+ break;
+
+ default:
+ Y_FAIL("Unknown kind");
+ }
+
+ if (OutputMode == EOutputMode::Unknown) {
+ if (List1.Empty()) {
+ OutputMode = EOutputMode::LeftNull;
+ } else if (List2.Empty()) {
+ OutputMode = EOutputMode::RightNull;
+ } else if (List1.IsLive()) {
+ OutputMode = EOutputMode::Cross;
+ } else if (List2.IsLive()) {
+ OutputMode = EOutputMode::CrossSwap;
+ } else {
+ OutputMode = List1.GetCount() >= List2.GetCount() ?
+ EOutputMode::Cross : EOutputMode::CrossSwap;
+ }
+ }
+ }
+ continue;
+ case EOutputMode::LeftNull:
+ if (const auto res = List2.Next(ctx, Values.data()); EFetchResult::One != res) {
+ return res;
+ }
+
+ PrepareNullItem<true>(ctx, output);
+ return EFetchResult::One;
+
+ case EOutputMode::RightNull:
+ if (const auto res = List1.Next(ctx, Values.data()); EFetchResult::One != res) {
+ return res;
+ }
+
+ PrepareNullItem<false>(ctx, output);
+ return EFetchResult::One;
+ case EOutputMode::BothNull:
+ if (CrossMove1) {
+ switch (List1.Next(ctx, Values.data())) {
+ case EFetchResult::Finish: CrossMove1 = false; break;
+ case EFetchResult::Yield: return EFetchResult::Yield;
+ case EFetchResult::One:
+ PrepareNullItem<false>(ctx, output);
+ return EFetchResult::One;
+ }
+ }
+
+ if (const auto res = List2.Next(ctx, Values.data()); EFetchResult::One != res) {
+ return res;
+ }
+
+ PrepareNullItem<true>(ctx, output);
+ return EFetchResult::One;
+ case EOutputMode::Cross:
+ return PrepareCrossItem<false>(ctx, output);
+ case EOutputMode::CrossSwap:
+ return PrepareCrossItem<true>(ctx, output);
+ case EOutputMode::None:
+ return EFetchResult::Finish;
+ default:
+ Y_FAIL("Unknown output mode");
+ }
+ }
+ }
+
+ template <bool IsLeftNull>
+ void PrepareNullItem(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
+ for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
+ if (const auto out = output[Self->LeftOutputColumns[i]]) {
+ if constexpr (IsLeftNull) {
+ *out = NUdf::TUnboxedValuePod();
+ } else if (Self->IsRequiredColumn[Self->LeftInputColumns[i]]) {
+ *out = Values[i].Release().GetOptionalValue();
+ } else {
+ *out = std::move(Values[i]);
+ }
+ }
+ }
+
+ for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
+ if (const auto out = output[Self->RightOutputColumns[i]]) {
+ if constexpr (!IsLeftNull) {
+ *out = NUdf::TUnboxedValuePod();
+ } else if (Self->IsRequiredColumn[Self->RightInputColumns[i]]) {
+ *out = Values[i].Release().GetOptionalValue();
+ } else {
+ *out = std::move(Values[i]);
+ }
+ }
+ }
+ }
+
+ template <bool SwapLists>
+ EFetchResult PrepareCrossItem(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) {
+ if (KeyHasNulls) {
+ for (;;) {
+ if (const auto res = (CrossMove1 == SwapLists ? List2 : List1).Next(ctx, Values.data()); EFetchResult::Finish == res && CrossMove1) {
+ CrossMove1 = false;
+ continue;
+ } else if (EFetchResult::One != res) {
+ return res;
+ }
+
+ if (CrossMove1 == SwapLists)
+ PrepareNullItem<true>(ctx, output);
+ else
+ PrepareNullItem<false>(ctx, output);
+
+ return EFetchResult::One;
+ }
+ }
+
+ for (;;) {
+ if (CrossMove1) {
+ if (const auto res = (SwapLists ? List2 : List1).Next(ctx, CrossValues1.data()); EFetchResult::One != res) {
+ return res;
+ }
+
+ CrossMove1 = false;
+ (SwapLists ? List1 : List2).Rewind();
+ }
+
+ if (const auto res = (SwapLists ? List1 : List2).Next(ctx, CrossValues2.data()); EFetchResult::Finish == res) {
+ CrossMove1 = true;
+ continue;
+ } else if (EFetchResult::Yield == res) {
+ return EFetchResult::Yield;
+ }
+
+ const auto& lValues = SwapLists ? CrossValues2 : CrossValues1;
+ const auto& rValues = SwapLists ? CrossValues1 : CrossValues2;
+
+ for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
+ if (const auto out = output[Self->LeftOutputColumns[i]]) {
+ if (Self->IsRequiredColumn[Self->LeftInputColumns[i]]) {
+ *out = NUdf::TUnboxedValue(lValues[i]).Release().GetOptionalValue();
+ } else {
+ *out = lValues[i];
+ }
+ }
+ }
+
+ for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
+ if (const auto out = output[Self->RightOutputColumns[i]]) {
+ if (Self->IsRequiredColumn[Self->RightInputColumns[i]]) {
+ *out = NUdf::TUnboxedValue(rValues[i]).Release().GetOptionalValue();
+ } else {
+ *out = rValues[i];
+ }
+ }
+ }
+
+ return EFetchResult::One;
+ }
+ }
+
+ private:
+ static std::vector<NUdf::TUnboxedValue*> GetPointers(std::vector<NUdf::TUnboxedValue>& array) {
+ std::vector<NUdf::TUnboxedValue*> pointers;
+ pointers.reserve(array.size());
+ std::transform(array.begin(), array.end(), std::back_inserter(pointers), [](NUdf::TUnboxedValue& v) { return std::addressof(v); });
+ return pointers;
+ }
+
+
+ const TSelf* const Self;
+ TFetcher Fetcher;
+ bool EatInput;
+ bool KeyHasNulls;
+ std::optional<ui64> InitialUsage;
+ EOutputMode OutputMode;
+
+ bool CrossMove1;
+
+ std::vector<NUdf::TUnboxedValue> Values, CrossValues1, CrossValues2;
+
+ TSpillList List1, List2;
+
+ NUdf::TUnboxedValue* ResItems = nullptr;
+ const std::vector<NUdf::TUnboxedValue*> Fields;
+ };
+
+ TWideCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, const TTupleType* inputLeftType, const TTupleType* inputRightType,
+ std::vector<EValueRepresentation>&& inputRepresentations, std::vector<EValueRepresentation>&& outputRepresentations, ui32 tableIndexPos,
+ std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
+ std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
+ std::optional<ui32> sortedTableOrder, std::vector<ui32>&& keyColumns, EAnyJoinSettings anyJoinSettings)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Any)
+ , Flow(flow), InputRepresentations(std::move(inputRepresentations)), OutputRepresentations(std::move(outputRepresentations))
+ , InputLeftType(inputLeftType), InputRightType(inputRightType)
+ , PackerLeft(mutables), PackerRight(mutables)
+ , TableIndexPos(tableIndexPos)
+ , LeftInputColumns(std::move(leftInputColumns))
+ , RightInputColumns(std::move(rightInputColumns))
+ , RequiredColumns(std::move(requiredColumns))
+ , LeftOutputColumns(std::move(leftOutputColumns))
+ , RightOutputColumns(std::move(rightOutputColumns))
+ , MemLimit(memLimit)
+ , SortedTableOrder(sortedTableOrder)
+ , KeyColumns(std::move(keyColumns))
+ , IsRequiredColumn(FillRequiredStructColumn(InputRepresentations.size(), RequiredColumns))
+ , AnyJoinSettings(anyJoinSettings)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ return static_cast<TValue*>(state.AsBoxed().Get())->FetchValues(ctx, output);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto size = LeftOutputColumns.size() + RightOutputColumns.size();
+ const auto arrayType = ArrayType::get(valueType, size);
+ const auto fieldsType = ArrayType::get(PointerType::getUnqual(valueType), size);
+
+ const auto atTop = &ctx.Func->getEntryBlock().back();
+
+ const auto values = new AllocaInst(arrayType, 0U, "values", atTop);
+ const auto fields = new AllocaInst(fieldsType, 0U, "fields", atTop);
+
+ ICodegeneratorInlineWideNode::TGettersList getters(size);
+
+ Value* initV = UndefValue::get(arrayType);
+ Value* initF = UndefValue::get(fieldsType);
+ std::vector<Value*> pointers;
+ pointers.reserve(size);
+ for (auto i = 0U; i < size; ++i) {
+ pointers.emplace_back(GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, i)}, (TString("ptr_") += ToString(i)).c_str(), atTop));
+ initV = InsertValueInst::Create(initV, ConstantInt::get(valueType, 0), {i}, (TString("zero_") += ToString(i)).c_str(), atTop);
+ initF = InsertValueInst::Create(initF, pointers.back(), {i}, (TString("insert_") += ToString(i)).c_str(), atTop);
+
+ getters[i] = [i, values](const TCodegenContext& ctx, BasicBlock*& block) {
+ const auto indexType = Type::getInt32Ty(ctx.Codegen->GetContext());
+ const auto pointer = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, i)}, (TString("ptr_") += ToString(i)).c_str(), block);
+ return new LoadInst(pointer, (TString("load_") += ToString(i)).c_str(), block);
+ };
+ }
+
+ new StoreInst(initV, values, atTop);
+ new StoreInst(initF, fields, atTop);
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(main, make, HasValue(statePtr, block), block);
+
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideCommonJoinCoreWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ for (ui32 i = 0U; i < OutputRepresentations.size(); ++i) {
+ ValueCleanup(OutputRepresentations[i], pointers[i], ctx, block);
+ }
+
+ new StoreInst(initV, values, block);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValue::FetchValues));
+ const auto funcType = FunctionType::get(Type::getInt32Ty(context), { statePtrType, ctx.Ctx->getType(), fields->getType() }, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funcType), "fetch_func", block);
+ const auto result = CallInst::Create(funcPtr, { stateArg, ctx.Ctx, fields }, "fetch", block);
+
+ for (ui32 i = 0U; i < OutputRepresentations.size(); ++i) {
+ ValueRelease(OutputRepresentations[i], pointers[i], ctx, block);
+ }
+
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+#ifdef MKQL_DISABLE_CODEGEN
+ state = ctx.HolderFactory.Create<TValue>(ctx, this, std::bind(&IComputationWideFlowNode::FetchValues, Flow, std::placeholders::_1, std::placeholders::_2));
+#else
+ state = Fetch && ctx.ExecuteLLVM ?
+ ctx.HolderFactory.Create<TValue>(ctx, this, Fetch):
+ ctx.HolderFactory.Create<TValue>(ctx, this, std::bind(&IComputationWideFlowNode::FetchValues, Flow, std::placeholders::_1, std::placeholders::_2));
+#endif
+ }
+
+ void RegisterDependencies() const final {
+ this->FlowDependsOn(Flow);
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const std::vector<EValueRepresentation> InputRepresentations;
+ const std::vector<EValueRepresentation> OutputRepresentations;
+ const TTupleType* const InputLeftType;
+ const TTupleType* const InputRightType;
+ const TMutableObjectOverBoxedValue<TValuePackerBoxed> PackerLeft, PackerRight;
+ const ui32 TableIndexPos;
+ const std::vector<ui32> LeftInputColumns;
+ const std::vector<ui32> RightInputColumns;
+ const std::vector<ui32> RequiredColumns;
+ const std::vector<ui32> LeftOutputColumns;
+ const std::vector<ui32> RightOutputColumns;
+ const ui64 MemLimit;
+ const std::optional<ui32> SortedTableOrder;
+ const std::vector<ui32> KeyColumns;
+ const std::vector<bool> IsRequiredColumn;
+ const EAnyJoinSettings AnyJoinSettings;
+#ifndef MKQL_DISABLE_CODEGEN
+ typedef EFetchResult (*TFetchPtr)(TComputationContext&, NUdf::TUnboxedValue*const*);
+
+ TFetchPtr Fetch = nullptr;
+
+ Function* FetchFunc = nullptr;
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (FetchFunc) {
+ Fetch = reinterpret_cast<TFetchPtr>(codegen->GetPointerToFunction(FetchFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ codegen->ExportSymbol(FetchFunc = GenerateFetchFunction(codegen));
+ }
+
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::Fetch_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ Function* GenerateFetchFunction(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = MakeName();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto pointerType = PointerType::getUnqual(valueType);
+ const auto arrayType = ArrayType::get(pointerType, InputRepresentations.size());
+ const auto contextType = GetCompContextType(context);
+ const auto resultType = Type::getInt32Ty(context);
+ const auto funcType = FunctionType::get(resultType, {PointerType::getUnqual(contextType), PointerType::getUnqual(arrayType)}, false);
+ const auto indexType = Type::getInt32Ty(context);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto outputArg = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- auto block = main;
-
- const auto result = GetNodeValues(Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, result.first, ConstantInt::get(result.first->getType(), 0), "special", block);
-
- BranchInst::Create(exit, good, special, block);
-
- block = good;
-
- const auto fields = new LoadInst(outputArg, "fields", block);
-
- for (ui32 i = 0U; i < InputRepresentations.size(); ++i) {
- const auto save = BasicBlock::Create(context, (TString("save_") += ToString(i)).c_str(), ctx.Func);
- const auto skip = BasicBlock::Create(context, (TString("skip_") += ToString(i)).c_str(), ctx.Func);
-
- const auto pointer = ExtractValueInst::Create(fields, i, (TString("pointer_") += ToString(i)).c_str(), block);
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, pointer, ConstantPointerNull::get(pointerType), (TString("null_") += ToString(i)).c_str(), block);
-
- BranchInst::Create(skip, save, null, block);
-
- block = save;
-
- const auto value = result.second[i](ctx, block);
- ValueUnRef(InputRepresentations[i], pointer, ctx, block);
- new StoreInst(value, pointer, block);
- ValueAddRef(InputRepresentations[i], value, ctx, block);
-
- BranchInst::Create(skip, block);
-
- block = skip;
- }
- BranchInst::Create(exit, block);
-
- block = exit;
- ReturnInst::Create(context, result.first, block);
- return ctx.Func;
- }
-#endif
-};
-
-}
-
-namespace NStream {
-
-class TSpillList {
-public:
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto outputArg = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ auto block = main;
+
+ const auto result = GetNodeValues(Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, result.first, ConstantInt::get(result.first->getType(), 0), "special", block);
+
+ BranchInst::Create(exit, good, special, block);
+
+ block = good;
+
+ const auto fields = new LoadInst(outputArg, "fields", block);
+
+ for (ui32 i = 0U; i < InputRepresentations.size(); ++i) {
+ const auto save = BasicBlock::Create(context, (TString("save_") += ToString(i)).c_str(), ctx.Func);
+ const auto skip = BasicBlock::Create(context, (TString("skip_") += ToString(i)).c_str(), ctx.Func);
+
+ const auto pointer = ExtractValueInst::Create(fields, i, (TString("pointer_") += ToString(i)).c_str(), block);
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, pointer, ConstantPointerNull::get(pointerType), (TString("null_") += ToString(i)).c_str(), block);
+
+ BranchInst::Create(skip, save, null, block);
+
+ block = save;
+
+ const auto value = result.second[i](ctx, block);
+ ValueUnRef(InputRepresentations[i], pointer, ctx, block);
+ new StoreInst(value, pointer, block);
+ ValueAddRef(InputRepresentations[i], value, ctx, block);
+
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ }
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ ReturnInst::Create(context, result.first, block);
+ return ctx.Func;
+ }
+#endif
+};
+
+}
+
+namespace NStream {
+
+class TSpillList {
+public:
TSpillList(TValuePacker& itemPacker, bool singleShot)
- : ItemPacker(itemPacker)
+ : ItemPacker(itemPacker)
, Ctx(nullptr)
, Count(0)
#ifndef NDEBUG
@@ -1401,7 +1401,7 @@ public:
return false;
}
- FileState.reset(new TFileState);
+ FileState.reset(new TFileState);
OpenWrite();
for (ui32 i = 0; i < Count; ++i) {
Write(std::move(InMemory(i)));
@@ -1453,7 +1453,7 @@ public:
if (FileState) {
FileState->Output->Finish();
Cerr << "Spill finished at " << Count << " items" << Endl;
- FileState->Output.reset();
+ FileState->Output.reset();
Cerr << "File size: " << GetFileLength(FileState->File.GetName()) << ", expected: " << FileState->TotalSize << Endl;
MKQL_INC_STAT(Ctx->Stats, Join_Spill_Count);
@@ -1463,7 +1463,7 @@ public:
}
bool IsLive() const {
- return bool(LiveStream);
+ return bool(LiveStream);
}
ui64 GetCount() const {
@@ -1539,7 +1539,7 @@ private:
void OpenWrite() {
Cerr << "Spill started at " << Count << " items to " << FileState->File.GetName() << Endl;
- FileState->Output.reset(new TFixedBufferFileOutput(FileState->File.GetName()));
+ FileState->Output.reset(new TFixedBufferFileOutput(FileState->File.GetName()));
FileState->Output->SetFlushPropagateMode(false);
FileState->Output->SetFinishPropagateMode(false);
}
@@ -1555,8 +1555,8 @@ private:
}
void OpenRead() {
- FileState->Input.reset();
- FileState->Input.reset(new TFileInput(FileState->File.GetName()));
+ FileState->Input.reset();
+ FileState->Input.reset(new TFileInput(FileState->File.GetName()));
}
NUdf::TUnboxedValue Read() {
@@ -1588,12 +1588,12 @@ private:
TTempFileHandle File;
ui64 TotalSize;
- std::unique_ptr<TFileInput> Input;
- std::unique_ptr<TFixedBufferFileOutput> Output;
+ std::unique_ptr<TFileInput> Input;
+ std::unique_ptr<TFixedBufferFileOutput> Output;
TBuffer Buffer;
};
- std::unique_ptr<TFileState> FileState;
+ std::unique_ptr<TFileState> FileState;
NUdf::TUnboxedValue LiveStream;
NUdf::TUnboxedValue LiveValue;
};
@@ -1609,7 +1609,7 @@ public:
using TBase = TComputationValue<TValue>;
TValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
- TComputationContext& ctx, const TSelf* self)
+ TComputationContext& ctx, const TSelf* self)
: TBase(memInfo)
, Stream(std::move(stream))
, Ctx(ctx)
@@ -1626,130 +1626,130 @@ public:
}
void Init() {
- List1.Init(Ctx);
- List2.Init(Ctx);
+ List1.Init(Ctx);
+ List2.Init(Ctx);
CrossMove1 = true;
EatInput = true;
KeyHasNulls = false;
OutputMode = EOutputMode::Unknown;
- InitialUsage = std::nullopt;
+ InitialUsage = std::nullopt;
}
- private:
+ private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- while (EatInput) {
- if (!InitialUsage) {
- InitialUsage = Ctx.HolderFactory.GetPagePool().GetUsed();
+ while (EatInput) {
+ if (!InitialUsage) {
+ InitialUsage = Ctx.HolderFactory.GetPagePool().GetUsed();
}
- NUdf::TUnboxedValue value;
- const auto status = Stream.Fetch(value);
- if (status == NUdf::EFetchStatus::Yield) {
- return status;
- }
-
- if (status == NUdf::EFetchStatus::Finish) {
- EatInput = false;
- } else {
- if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
- for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
- if (!value.GetElement(Self->KeyColumns[i])) {
- KeyHasNulls = true;
- break;
- }
- }
+ NUdf::TUnboxedValue value;
+ const auto status = Stream.Fetch(value);
+ if (status == NUdf::EFetchStatus::Yield) {
+ return status;
+ }
+
+ if (status == NUdf::EFetchStatus::Finish) {
+ EatInput = false;
+ } else {
+ if (!KeyHasNulls && (Kind == EJoinKind::Exclusion || Kind == EJoinKind::Full)) {
+ for (ui32 i = 0U; i < Self->KeyColumns.size(); ++i) {
+ if (!value.GetElement(Self->KeyColumns[i])) {
+ KeyHasNulls = true;
+ break;
+ }
+ }
}
- switch (const auto tableIndex = value.GetElement(Self->TableIndexPos).template Get<ui32>()) {
- case LeftIndex:
- if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
+ switch (const auto tableIndex = value.GetElement(Self->TableIndexPos).template Get<ui32>()) {
+ case LeftIndex:
+ if (Kind == EJoinKind::RightOnly || (Kind == EJoinKind::Exclusion && !List2.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
}
- if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
- List1.Live(Stream, std::move(value));
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == RightIndex) {
+ List1.Live(Stream, std::move(value));
EatInput = false;
} else {
- List1.Add(std::move(value));
- if (Ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List1.Spill();
+ List1.Add(std::move(value));
+ if (Ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List1.Spill();
}
}
- break;
- case RightIndex:
- if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
- EatInput = false;
- OutputMode = EOutputMode::None;
- break;
+ break;
+ case RightIndex:
+ if (Kind == EJoinKind::LeftOnly || (Kind == EJoinKind::Exclusion && !List1.Empty() && !KeyHasNulls)) {
+ EatInput = false;
+ OutputMode = EOutputMode::None;
+ break;
}
- if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
- List2.Live(Stream, std::move(value));
+ if (Self->SortedTableOrder && *Self->SortedTableOrder == LeftIndex) {
+ List2.Live(Stream, std::move(value));
EatInput = false;
} else {
- List2.Add(std::move(value));
- if (Ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
- List2.Spill();
+ List2.Add(std::move(value));
+ if (Ctx.CheckAdjustedMemLimit<TTrackRss>(Self->MemLimit, *InitialUsage)) {
+ List2.Spill();
}
}
- break;
- default: THROW yexception() << "Bad table index: " << tableIndex;
+ break;
+ default: THROW yexception() << "Bad table index: " << tableIndex;
}
}
- }
+ }
- while (true) {
+ while (true) {
switch (OutputMode) {
case EOutputMode::Unknown: {
- List1.Seal();
- List2.Seal();
+ List1.Seal();
+ List2.Seal();
switch (Kind) {
case EJoinKind::Cross:
case EJoinKind::Inner:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
}
break;
case EJoinKind::Left:
- if (List1.Empty()) {
- OutputMode = EOutputMode::None;
+ if (List1.Empty()) {
+ OutputMode = EOutputMode::None;
}
break;
case EJoinKind::LeftOnly:
- if (List1.Empty() || !List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
+ if (List1.Empty() || !List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
}
break;
case EJoinKind::Right:
- if (List2.Empty()) {
- OutputMode = EOutputMode::None;
+ if (List2.Empty()) {
+ OutputMode = EOutputMode::None;
}
break;
case EJoinKind::RightOnly:
- if (List2.Empty() || !List1.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
+ if (List2.Empty() || !List1.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
}
break;
case EJoinKind::Exclusion:
- if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
- OutputMode = EOutputMode::None;
- } else if (List1.Empty()) {
- OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
- OutputMode = EOutputMode::RightNull;
- } else {
- OutputMode = EOutputMode::BothNull;
+ if (!List1.Empty() && !List2.Empty() && !KeyHasNulls) {
+ OutputMode = EOutputMode::None;
+ } else if (List1.Empty()) {
+ OutputMode = EOutputMode::LeftNull;
+ } else if (List2.Empty()) {
+ OutputMode = EOutputMode::RightNull;
+ } else {
+ OutputMode = EOutputMode::BothNull;
}
break;
@@ -1757,18 +1757,18 @@ public:
break;
case EJoinKind::LeftSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::RightNull;
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::RightNull;
}
break;
case EJoinKind::RightSemi:
- if (List1.Empty() || List2.Empty()) {
- OutputMode = EOutputMode::None;
- } else {
- OutputMode = EOutputMode::LeftNull;
+ if (List1.Empty() || List2.Empty()) {
+ OutputMode = EOutputMode::None;
+ } else {
+ OutputMode = EOutputMode::LeftNull;
}
break;
@@ -1777,16 +1777,16 @@ public:
}
if (OutputMode == EOutputMode::Unknown) {
- if (List1.Empty()) {
+ if (List1.Empty()) {
OutputMode = EOutputMode::LeftNull;
- } else if (List2.Empty()) {
+ } else if (List2.Empty()) {
OutputMode = EOutputMode::RightNull;
- } else if (List1.IsLive()) {
+ } else if (List1.IsLive()) {
OutputMode = EOutputMode::Cross;
- } else if (List2.IsLive()) {
+ } else if (List2.IsLive()) {
OutputMode = EOutputMode::CrossSwap;
} else {
- OutputMode = List1.GetCount() >= List2.GetCount() ?
+ OutputMode = List1.GetCount() >= List2.GetCount() ?
EOutputMode::Cross : EOutputMode::CrossSwap;
}
}
@@ -1794,7 +1794,7 @@ public:
continue;
case EOutputMode::LeftNull: {
NUdf::TUnboxedValue value;
- auto status = List2.Next(value);
+ auto status = List2.Next(value);
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -1805,7 +1805,7 @@ public:
break;
case EOutputMode::RightNull: {
NUdf::TUnboxedValue value;
- auto status = List1.Next(value);
+ auto status = List1.Next(value);
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -1814,57 +1814,57 @@ public:
return NUdf::EFetchStatus::Ok;
}
break;
- case EOutputMode::BothNull: {
- NUdf::TUnboxedValue value;
-
- if (CrossMove1) {
- switch (const auto status = List1.Next(value)) {
- case NUdf::EFetchStatus::Finish: CrossMove1 = false; break;
- case NUdf::EFetchStatus::Yield: return status;
- case NUdf::EFetchStatus::Ok:
- result = PrepareNullItem<false>(value);
- return NUdf::EFetchStatus::Ok;
- }
- }
-
- switch (const auto status = List2.Next(value)) {
- case NUdf::EFetchStatus::Yield:
- case NUdf::EFetchStatus::Finish: return status;
- case NUdf::EFetchStatus::Ok:
- result = PrepareNullItem<true>(value);
- return NUdf::EFetchStatus::Ok;
- }
- }
- break;
+ case EOutputMode::BothNull: {
+ NUdf::TUnboxedValue value;
+
+ if (CrossMove1) {
+ switch (const auto status = List1.Next(value)) {
+ case NUdf::EFetchStatus::Finish: CrossMove1 = false; break;
+ case NUdf::EFetchStatus::Yield: return status;
+ case NUdf::EFetchStatus::Ok:
+ result = PrepareNullItem<false>(value);
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+
+ switch (const auto status = List2.Next(value)) {
+ case NUdf::EFetchStatus::Yield:
+ case NUdf::EFetchStatus::Finish: return status;
+ case NUdf::EFetchStatus::Ok:
+ result = PrepareNullItem<true>(value);
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
+ break;
case EOutputMode::Cross:
return PrepareCrossItem<false>(result);
case EOutputMode::CrossSwap:
return PrepareCrossItem<true>(result);
- case EOutputMode::None:
- return NUdf::EFetchStatus::Finish;
+ case EOutputMode::None:
+ return NUdf::EFetchStatus::Finish;
default:
- Y_FAIL("Unknown output mode");
+ Y_FAIL("Unknown output mode");
}
}
}
template <bool IsLeftNull>
- NUdf::TUnboxedValue PrepareNullItem(const NUdf::TUnboxedValue& value) {
- const auto structObj = Self->ResStruct.NewArray(Ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
+ NUdf::TUnboxedValue PrepareNullItem(const NUdf::TUnboxedValue& value) {
+ const auto structObj = Self->ResStruct.NewArray(Ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
ui32 inIndex = Self->LeftInputColumns[i];
ui32 outIndex = Self->LeftOutputColumns[i];
if (IsLeftNull) {
- ResItems[outIndex] = NUdf::TUnboxedValuePod();
+ ResItems[outIndex] = NUdf::TUnboxedValuePod();
continue;
}
- auto member = value.GetElement(inIndex);
+ auto member = value.GetElement(inIndex);
if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
+ ResItems[outIndex] = member.Release().GetOptionalValue();
} else {
- ResItems[outIndex] = std::move(member);
+ ResItems[outIndex] = std::move(member);
}
}
@@ -1872,16 +1872,16 @@ public:
ui32 inIndex = Self->RightInputColumns[i];
ui32 outIndex = Self->RightOutputColumns[i];
if (!IsLeftNull) {
- ResItems[outIndex] = NUdf::TUnboxedValuePod();
+ ResItems[outIndex] = NUdf::TUnboxedValuePod();
continue;
}
- auto member = value.GetElement(inIndex);
+ auto member = value.GetElement(inIndex);
if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
+ ResItems[outIndex] = member.Release().GetOptionalValue();
}
else {
- ResItems[outIndex] = std::move(member);
+ ResItems[outIndex] = std::move(member);
}
}
@@ -1893,7 +1893,7 @@ public:
if (KeyHasNulls) {
for (;;) {
NUdf::TUnboxedValue value;
- auto status = (CrossMove1 == SwapLists ? List2 : List1).Next(value);
+ auto status = (CrossMove1 == SwapLists ? List2 : List1).Next(value);
if (status == NUdf::EFetchStatus::Finish && CrossMove1) {
CrossMove1 = false;
continue;
@@ -1910,43 +1910,43 @@ public:
for (;;) {
if (CrossMove1) {
- auto status = (SwapLists ? List2 : List1).Next(CrossValue1);
+ auto status = (SwapLists ? List2 : List1).Next(CrossValue1);
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
CrossMove1 = false;
- (SwapLists ? List1 : List2).Rewind();
+ (SwapLists ? List1 : List2).Rewind();
}
- auto status = (SwapLists ? List1 : List2).Next(CrossValue2);
+ auto status = (SwapLists ? List1 : List2).Next(CrossValue2);
MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status");
if (status == NUdf::EFetchStatus::Finish) {
CrossMove1 = true;
continue;
}
- auto structObj = Self->ResStruct.NewArray(Ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
+ auto structObj = Self->ResStruct.NewArray(Ctx, Self->LeftInputColumns.size() + Self->RightInputColumns.size(), ResItems);
for (ui32 i = 0; i < Self->LeftInputColumns.size(); ++i) {
ui32 inIndex = Self->LeftInputColumns[i];
ui32 outIndex = Self->LeftOutputColumns[i];
- auto member = (SwapLists ? CrossValue2 : CrossValue1).GetElement(inIndex);
+ auto member = (SwapLists ? CrossValue2 : CrossValue1).GetElement(inIndex);
if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
+ ResItems[outIndex] = member.Release().GetOptionalValue();
} else {
- ResItems[outIndex] = std::move(member);
+ ResItems[outIndex] = std::move(member);
}
}
for (ui32 i = 0; i < Self->RightInputColumns.size(); ++i) {
ui32 inIndex = Self->RightInputColumns[i];
ui32 outIndex = Self->RightOutputColumns[i];
- auto member = (SwapLists ? CrossValue1 : CrossValue2).GetElement(inIndex);
+ auto member = (SwapLists ? CrossValue1 : CrossValue2).GetElement(inIndex);
if (Self->IsRequiredColumn[inIndex]) {
- ResItems[outIndex] = member.Release().GetOptionalValue();
+ ResItems[outIndex] = member.Release().GetOptionalValue();
} else {
- ResItems[outIndex] = std::move(member);
+ ResItems[outIndex] = std::move(member);
}
}
@@ -1959,25 +1959,25 @@ public:
private:
NUdf::TUnboxedValue Stream;
TComputationContext& Ctx;
- const TSelf* const Self;
+ const TSelf* const Self;
bool EatInput;
bool KeyHasNulls;
- std::optional<ui64> InitialUsage;
+ std::optional<ui64> InitialUsage;
EOutputMode OutputMode;
bool CrossMove1;
NUdf::TUnboxedValue CrossValue1;
NUdf::TUnboxedValue CrossValue2;
-
- TSpillList List1;
- TSpillList List2;
-
- NUdf::TUnboxedValue* ResItems = nullptr;
+
+ TSpillList List1;
+ TSpillList List2;
+
+ NUdf::TUnboxedValue* ResItems = nullptr;
};
- TCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationNode* stream, const TType* inputStructType, ui32 inputWidth, ui32 tableIndexPos,
- std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
- std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
+ TCommonJoinCoreWrapper(TComputationMutables& mutables, IComputationNode* stream, const TType* inputStructType, ui32 inputWidth, ui32 tableIndexPos,
+ std::vector<ui32>&& leftInputColumns, std::vector<ui32>&& rightInputColumns, std::vector<ui32>&& requiredColumns,
+ std::vector<ui32>&& leftOutputColumns, std::vector<ui32>&& rightOutputColumns, ui64 memLimit,
std::optional<ui32> sortedTableOrder, std::vector<ui32>&& keyColumns, EAnyJoinSettings anyJoinSettings)
: TBaseComputation(mutables)
, Stream(stream)
@@ -1992,14 +1992,14 @@ public:
, MemLimit(memLimit)
, SortedTableOrder(sortedTableOrder)
, KeyColumns(std::move(keyColumns))
- , IsRequiredColumn(FillRequiredStructColumn(inputWidth, RequiredColumns))
+ , IsRequiredColumn(FillRequiredStructColumn(inputWidth, RequiredColumns))
, ResStruct(mutables)
, ResStreamIndex(mutables.CurValueIndex++)
, AnyJoinSettings(anyJoinSettings)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto& resStream = ctx.MutableValues[ResStreamIndex];
if (!resStream || resStream.IsInvalid() || !resStream.UniqueBoxed()) {
resStream = ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx), ctx, this);
@@ -2010,124 +2010,124 @@ public:
return static_cast<const NUdf::TUnboxedValuePod&>(resStream);
}
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Stream);
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Stream);
}
IComputationNode* const Stream;
- const TType* const InputStructType;
- const TMutableObjectOverBoxedValue<TValuePackerBoxed> Packer;
+ const TType* const InputStructType;
+ const TMutableObjectOverBoxedValue<TValuePackerBoxed> Packer;
const ui32 TableIndexPos;
- const std::vector<ui32> LeftInputColumns;
- const std::vector<ui32> RightInputColumns;
- const std::vector<ui32> RequiredColumns;
- const std::vector<ui32> LeftOutputColumns;
- const std::vector<ui32> RightOutputColumns;
+ const std::vector<ui32> LeftInputColumns;
+ const std::vector<ui32> RightInputColumns;
+ const std::vector<ui32> RequiredColumns;
+ const std::vector<ui32> LeftOutputColumns;
+ const std::vector<ui32> RightOutputColumns;
const ui64 MemLimit;
- const std::optional<ui32> SortedTableOrder;
- const std::vector<ui32> KeyColumns;
- const std::vector<bool> IsRequiredColumn;
+ const std::optional<ui32> SortedTableOrder;
+ const std::vector<ui32> KeyColumns;
+ const std::vector<bool> IsRequiredColumn;
- const TContainerCacheOnContext ResStruct;
+ const TContainerCacheOnContext ResStruct;
const ui32 ResStreamIndex;
const EAnyJoinSettings AnyJoinSettings;
};
}
-}
-
+}
+
IComputationNode* WrapCommonJoinCore(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 11U || callable.GetInputsCount() == 12U, "Expected 12 args");
- const auto type = callable.GetType()->GetReturnType();
-
- const auto inputRowType = type->IsFlow() ?
- AS_TYPE(TFlowType, callable.GetInput(0))->GetItemType():
- AS_TYPE(TStreamType, callable.GetInput(0))->GetItemType();
-
- std::vector<EValueRepresentation> inputRepresentations;
- std::vector<TType*> fieldTypes;
- if (inputRowType->IsTuple()) {
- const auto tupleType = AS_TYPE(TTupleType, inputRowType);
- inputRepresentations.reserve(tupleType->GetElementsCount());
- fieldTypes.reserve(tupleType->GetElementsCount());
- for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i) {
- fieldTypes.emplace_back(tupleType->GetElementType(i));
- inputRepresentations.emplace_back(GetValueRepresentation(fieldTypes.back()));
- }
- } else if (inputRowType->IsStruct()) {
- const auto structType = AS_TYPE(TStructType, inputRowType);
- inputRepresentations.reserve(structType->GetMembersCount());
- fieldTypes.reserve(structType->GetMembersCount());
- for (ui32 i = 0U; i < structType->GetMembersCount(); ++i) {
- fieldTypes.emplace_back(structType->GetMemberType(i));
- inputRepresentations.emplace_back(GetValueRepresentation(fieldTypes.back()));
- }
- }
-
- const auto outputRowType = type->IsFlow() ?
- AS_TYPE(TFlowType, type)->GetItemType():
- AS_TYPE(TStreamType, type)->GetItemType();
-
- std::vector<EValueRepresentation> outputRepresentations;
- if (outputRowType->IsTuple()) {
- const auto tupleType = AS_TYPE(TTupleType, outputRowType);
- outputRepresentations.reserve(tupleType->GetElementsCount());
- for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i)
- outputRepresentations.emplace_back(GetValueRepresentation(tupleType->GetElementType(i)));
- } else if (outputRowType->IsStruct()) {
- const auto structType = AS_TYPE(TStructType, outputRowType);
- outputRepresentations.reserve(structType->GetMembersCount());
- for (ui32 i = 0U; i < structType->GetMembersCount(); ++i)
- outputRepresentations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
- }
-
- const auto rawKind = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
- const auto kind = GetJoinKind(rawKind);
-
- std::vector<ui32> leftInputColumns;
- std::vector<ui32> rightInputColumns;
- std::vector<ui32> requiredColumns;
- std::vector<ui32> leftOutputColumns;
- std::vector<ui32> rightOutputColumns;
- std::vector<ui32> keyColumns;
- const auto leftInputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(2));
- const auto rightInputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(3));
- const auto requiredColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(4));
- const auto leftOutputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
- const auto rightOutputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(6));
- const auto keyColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(7));
-
- std::vector<TType*> leftTypes;
- leftTypes.reserve(leftInputColumnsNode->GetValuesCount());
+ MKQL_ENSURE(callable.GetInputsCount() == 11U || callable.GetInputsCount() == 12U, "Expected 12 args");
+ const auto type = callable.GetType()->GetReturnType();
+
+ const auto inputRowType = type->IsFlow() ?
+ AS_TYPE(TFlowType, callable.GetInput(0))->GetItemType():
+ AS_TYPE(TStreamType, callable.GetInput(0))->GetItemType();
+
+ std::vector<EValueRepresentation> inputRepresentations;
+ std::vector<TType*> fieldTypes;
+ if (inputRowType->IsTuple()) {
+ const auto tupleType = AS_TYPE(TTupleType, inputRowType);
+ inputRepresentations.reserve(tupleType->GetElementsCount());
+ fieldTypes.reserve(tupleType->GetElementsCount());
+ for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i) {
+ fieldTypes.emplace_back(tupleType->GetElementType(i));
+ inputRepresentations.emplace_back(GetValueRepresentation(fieldTypes.back()));
+ }
+ } else if (inputRowType->IsStruct()) {
+ const auto structType = AS_TYPE(TStructType, inputRowType);
+ inputRepresentations.reserve(structType->GetMembersCount());
+ fieldTypes.reserve(structType->GetMembersCount());
+ for (ui32 i = 0U; i < structType->GetMembersCount(); ++i) {
+ fieldTypes.emplace_back(structType->GetMemberType(i));
+ inputRepresentations.emplace_back(GetValueRepresentation(fieldTypes.back()));
+ }
+ }
+
+ const auto outputRowType = type->IsFlow() ?
+ AS_TYPE(TFlowType, type)->GetItemType():
+ AS_TYPE(TStreamType, type)->GetItemType();
+
+ std::vector<EValueRepresentation> outputRepresentations;
+ if (outputRowType->IsTuple()) {
+ const auto tupleType = AS_TYPE(TTupleType, outputRowType);
+ outputRepresentations.reserve(tupleType->GetElementsCount());
+ for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i)
+ outputRepresentations.emplace_back(GetValueRepresentation(tupleType->GetElementType(i)));
+ } else if (outputRowType->IsStruct()) {
+ const auto structType = AS_TYPE(TStructType, outputRowType);
+ outputRepresentations.reserve(structType->GetMembersCount());
+ for (ui32 i = 0U; i < structType->GetMembersCount(); ++i)
+ outputRepresentations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
+ }
+
+ const auto rawKind = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
+ const auto kind = GetJoinKind(rawKind);
+
+ std::vector<ui32> leftInputColumns;
+ std::vector<ui32> rightInputColumns;
+ std::vector<ui32> requiredColumns;
+ std::vector<ui32> leftOutputColumns;
+ std::vector<ui32> rightOutputColumns;
+ std::vector<ui32> keyColumns;
+ const auto leftInputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(2));
+ const auto rightInputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(3));
+ const auto requiredColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(4));
+ const auto leftOutputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
+ const auto rightOutputColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(6));
+ const auto keyColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(7));
+
+ std::vector<TType*> leftTypes;
+ leftTypes.reserve(leftInputColumnsNode->GetValuesCount());
leftInputColumns.reserve(leftInputColumnsNode->GetValuesCount());
for (ui32 i = 0; i < leftInputColumnsNode->GetValuesCount(); ++i) {
- leftInputColumns.push_back(AS_VALUE(TDataLiteral, leftInputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
- leftTypes.emplace_back(fieldTypes[leftInputColumns.back()]);
+ leftInputColumns.push_back(AS_VALUE(TDataLiteral, leftInputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ leftTypes.emplace_back(fieldTypes[leftInputColumns.back()]);
}
- std::vector<TType*> rightTypes;
- rightTypes.reserve(rightInputColumnsNode->GetValuesCount());
+ std::vector<TType*> rightTypes;
+ rightTypes.reserve(rightInputColumnsNode->GetValuesCount());
rightInputColumns.reserve(rightInputColumnsNode->GetValuesCount());
for (ui32 i = 0; i < rightInputColumnsNode->GetValuesCount(); ++i) {
- rightInputColumns.push_back(AS_VALUE(TDataLiteral, rightInputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
- rightTypes.emplace_back(fieldTypes[rightInputColumns.back()]);
+ rightInputColumns.push_back(AS_VALUE(TDataLiteral, rightInputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ rightTypes.emplace_back(fieldTypes[rightInputColumns.back()]);
}
requiredColumns.reserve(requiredColumnsNode->GetValuesCount());
for (ui32 i = 0; i < requiredColumnsNode->GetValuesCount(); ++i) {
- requiredColumns.push_back(AS_VALUE(TDataLiteral, requiredColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ requiredColumns.push_back(AS_VALUE(TDataLiteral, requiredColumnsNode->GetValue(i))->AsValue().Get<ui32>());
}
leftOutputColumns.reserve(leftOutputColumnsNode->GetValuesCount());
for (ui32 i = 0; i < leftOutputColumnsNode->GetValuesCount(); ++i) {
- leftOutputColumns.push_back(AS_VALUE(TDataLiteral, leftOutputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ leftOutputColumns.push_back(AS_VALUE(TDataLiteral, leftOutputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
}
rightOutputColumns.reserve(rightOutputColumnsNode->GetValuesCount());
for (ui32 i = 0; i < rightOutputColumnsNode->GetValuesCount(); ++i) {
- rightOutputColumns.push_back(AS_VALUE(TDataLiteral, rightOutputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ rightOutputColumns.push_back(AS_VALUE(TDataLiteral, rightOutputColumnsNode->GetValue(i))->AsValue().Get<ui32>());
}
keyColumns.reserve(keyColumnsNode->GetValuesCount());
@@ -2135,9 +2135,9 @@ IComputationNode* WrapCommonJoinCore(TCallable& callable, const TComputationNode
keyColumns.push_back(AS_VALUE(TDataLiteral, keyColumnsNode->GetValue(i))->AsValue().Get<ui32>());
}
- const ui64 memLimit = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().Get<ui64>();
+ const ui64 memLimit = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().Get<ui64>();
- std::optional<ui32> sortedTableOrder;
+ std::optional<ui32> sortedTableOrder;
if (!callable.GetInput(9).GetStaticType()->IsVoid()) {
sortedTableOrder = AS_VALUE(TDataLiteral, callable.GetInput(9))->AsValue().Get<ui32>();
MKQL_ENSURE(*sortedTableOrder < 2, "Bad sorted table order");
@@ -2145,63 +2145,63 @@ IComputationNode* WrapCommonJoinCore(TCallable& callable, const TComputationNode
const EAnyJoinSettings anyJoinSettings = GetAnyJoinSettings(AS_VALUE(TDataLiteral, callable.GetInput(10))->AsValue().Get<ui32>());
- const auto tableIndexPos = 12U == callable.GetInputsCount() ?
- AS_VALUE(TDataLiteral, callable.GetInput(11U))->AsValue().Get<ui32>():
- AS_TYPE(TStructType, inputRowType)->GetMemberIndex("_yql_table_index");
-
+ const auto tableIndexPos = 12U == callable.GetInputsCount() ?
+ AS_VALUE(TDataLiteral, callable.GetInput(11U))->AsValue().Get<ui32>():
+ AS_TYPE(TStructType, inputRowType)->GetMemberIndex("_yql_table_index");
+
const bool trackRss = EGraphPerProcess::Single == ctx.GraphPerProcess;
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
-
- const auto leftInputType = TTupleType::Create(leftTypes.size(), leftTypes.data(), ctx.Env);
- const auto rightInputType = TTupleType::Create(rightTypes.size(), rightTypes.data(), ctx.Env);
-
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+
+ const auto leftInputType = TTupleType::Create(leftTypes.size(), leftTypes.data(), ctx.Env);
+ const auto rightInputType = TTupleType::Create(rightTypes.size(), rightTypes.data(), ctx.Env);
+
#define MAKE_COMMON_JOIN_CORE_WRAPPER(KIND)\
case EJoinKind::KIND: \
- if (type->IsFlow()) { \
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) \
- if (trackRss) \
- return new NFlow::TWideCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, wide, leftInputType, rightInputType, std::move(inputRepresentations), std::move(outputRepresentations), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
- std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- else \
- return new NFlow::TWideCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, wide, leftInputType, rightInputType, std::move(inputRepresentations), std::move(outputRepresentations), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
- std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- else \
- if (trackRss) \
- return new NFlow::TCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
- std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- else \
- return new NFlow::TCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
- std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- } else { \
- if (trackRss) \
- return new NStream::TCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ if (type->IsFlow()) { \
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) \
+ if (trackRss) \
+ return new NFlow::TWideCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, wide, leftInputType, rightInputType, std::move(inputRepresentations), std::move(outputRepresentations), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
+ else \
+ return new NFlow::TWideCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, wide, leftInputType, rightInputType, std::move(inputRepresentations), std::move(outputRepresentations), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
+ else \
+ if (trackRss) \
+ return new NFlow::TCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
+ else \
+ return new NFlow::TCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
+ } else { \
+ if (trackRss) \
+ return new NStream::TCommonJoinCoreWrapper<EJoinKind::KIND, true>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- else \
- return new NStream::TCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
- std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
+ else \
+ return new NStream::TCommonJoinCoreWrapper<EJoinKind::KIND, false>(ctx.Mutables, flow, inputRowType, inputRepresentations.size(), tableIndexPos, \
+ std::move(leftInputColumns), std::move(rightInputColumns), std::move(requiredColumns), \
std::move(leftOutputColumns), std::move(rightOutputColumns), memLimit, sortedTableOrder, std::move(keyColumns), anyJoinSettings); \
- }
+ }
switch (kind) {
- MAKE_COMMON_JOIN_CORE_WRAPPER(Inner)
- MAKE_COMMON_JOIN_CORE_WRAPPER(Left)
- MAKE_COMMON_JOIN_CORE_WRAPPER(Right)
- MAKE_COMMON_JOIN_CORE_WRAPPER(Full)
- MAKE_COMMON_JOIN_CORE_WRAPPER(LeftOnly)
- MAKE_COMMON_JOIN_CORE_WRAPPER(RightOnly)
- MAKE_COMMON_JOIN_CORE_WRAPPER(Exclusion)
- MAKE_COMMON_JOIN_CORE_WRAPPER(LeftSemi)
- MAKE_COMMON_JOIN_CORE_WRAPPER(RightSemi)
- MAKE_COMMON_JOIN_CORE_WRAPPER(Cross)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Inner)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Left)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Right)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Full)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(LeftOnly)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(RightOnly)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Exclusion)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(LeftSemi)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(RightSemi)
+ MAKE_COMMON_JOIN_CORE_WRAPPER(Cross)
default:
Y_FAIL("Unknown kind");
}
-#undef MAKE_COMMON_JOIN_CORE_WRAPPER
+#undef MAKE_COMMON_JOIN_CORE_WRAPPER
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_join_dict.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_join_dict.cpp
index f1e8edd678..194a4cb15e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_join_dict.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_join_dict.cpp
@@ -1,4 +1,4 @@
-#include "mkql_join_dict.h"
+#include "mkql_join_dict.h"
#include <ydb/library/yql/minikql/computation/mkql_custom_list.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
@@ -9,7 +9,7 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
+namespace {
template <EJoinKind Kind>
struct TWrapTraits {
@@ -17,73 +17,73 @@ struct TWrapTraits {
static constexpr bool Wrap2 = IsRightOptional(Kind);
};
-template <bool KeyTuple>
-class TJoinDictWrapper : public TMutableCodegeneratorPtrNode<TJoinDictWrapper<KeyTuple>> {
- typedef TMutableCodegeneratorPtrNode<TJoinDictWrapper<KeyTuple>> TBaseComputation;
+template <bool KeyTuple>
+class TJoinDictWrapper : public TMutableCodegeneratorPtrNode<TJoinDictWrapper<KeyTuple>> {
+ typedef TMutableCodegeneratorPtrNode<TJoinDictWrapper<KeyTuple>> TBaseComputation;
public:
TJoinDictWrapper(TComputationMutables& mutables, IComputationNode* dict1, IComputationNode* dict2,
- bool isMulti1, bool isMulti2, EJoinKind joinKind, std::vector<ui32>&& indexes = std::vector<ui32>())
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ bool isMulti1, bool isMulti2, EJoinKind joinKind, std::vector<ui32>&& indexes = std::vector<ui32>())
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, Dict1(dict1)
, Dict2(dict2)
, IsMulti1(isMulti1)
, IsMulti2(isMulti2)
, JoinKind(joinKind)
- , OptIndicies(std::move(indexes))
+ , OptIndicies(std::move(indexes))
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& dict1 = Dict1->GetValue(ctx);
- const auto& dict2 = Dict2->GetValue(ctx);
- return JoinDicts(ctx, dict1, dict2);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto joinFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TJoinDictWrapper::JoinDicts));
- const auto joinFuncArg = ConstantInt::get(Type::getInt64Ty(context), (ui64)this);
-
- const auto one = GetNodeValue(Dict1, ctx, block);
- const auto two = GetNodeValue(Dict2, ctx, block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto joinFuncType = FunctionType::get(Type::getInt128Ty(context),
- { joinFuncArg->getType(), ctx.Ctx->getType(), one->getType(), two->getType() }, false);
- const auto joinFuncPtr = CastInst::Create(Instruction::IntToPtr, joinFunc, PointerType::getUnqual(joinFuncType), "cast", block);
- const auto join = CallInst::Create(joinFuncPtr, { joinFuncArg, ctx.Ctx, one, two }, "join", block);
- AddRefBoxed(join, ctx, block);
- new StoreInst(join, pointer, block);
- } else {
- const auto onePtr = new AllocaInst(one->getType(), 0U, "one_ptr", block);
- const auto twoPtr = new AllocaInst(two->getType(), 0U, "two_ptr", block);
- new StoreInst(one, onePtr, block);
- new StoreInst(two, twoPtr, block);
-
- const auto joinFuncType = FunctionType::get(Type::getVoidTy(context),
- { joinFuncArg->getType(), pointer->getType(), ctx.Ctx->getType(), onePtr->getType(), twoPtr->getType() }, false);
-
- const auto joinFuncPtr = CastInst::Create(Instruction::IntToPtr, joinFunc, PointerType::getUnqual(joinFuncType), "cast", block);
- CallInst::Create(joinFuncPtr, { joinFuncArg, pointer, ctx.Ctx, onePtr, twoPtr }, "", block);
- const auto join = new LoadInst(pointer, "join", block);
- AddRefBoxed(join, ctx, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Dict1);
- this->DependsOn(Dict2);
- }
-
- bool HasNullInKey(const NUdf::TUnboxedValue& key) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto& dict1 = Dict1->GetValue(ctx);
+ const auto& dict2 = Dict2->GetValue(ctx);
+ return JoinDicts(ctx, dict1, dict2);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto joinFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TJoinDictWrapper::JoinDicts));
+ const auto joinFuncArg = ConstantInt::get(Type::getInt64Ty(context), (ui64)this);
+
+ const auto one = GetNodeValue(Dict1, ctx, block);
+ const auto two = GetNodeValue(Dict2, ctx, block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto joinFuncType = FunctionType::get(Type::getInt128Ty(context),
+ { joinFuncArg->getType(), ctx.Ctx->getType(), one->getType(), two->getType() }, false);
+ const auto joinFuncPtr = CastInst::Create(Instruction::IntToPtr, joinFunc, PointerType::getUnqual(joinFuncType), "cast", block);
+ const auto join = CallInst::Create(joinFuncPtr, { joinFuncArg, ctx.Ctx, one, two }, "join", block);
+ AddRefBoxed(join, ctx, block);
+ new StoreInst(join, pointer, block);
+ } else {
+ const auto onePtr = new AllocaInst(one->getType(), 0U, "one_ptr", block);
+ const auto twoPtr = new AllocaInst(two->getType(), 0U, "two_ptr", block);
+ new StoreInst(one, onePtr, block);
+ new StoreInst(two, twoPtr, block);
+
+ const auto joinFuncType = FunctionType::get(Type::getVoidTy(context),
+ { joinFuncArg->getType(), pointer->getType(), ctx.Ctx->getType(), onePtr->getType(), twoPtr->getType() }, false);
+
+ const auto joinFuncPtr = CastInst::Create(Instruction::IntToPtr, joinFunc, PointerType::getUnqual(joinFuncType), "cast", block);
+ CallInst::Create(joinFuncPtr, { joinFuncArg, pointer, ctx.Ctx, onePtr, twoPtr }, "", block);
+ const auto join = new LoadInst(pointer, "join", block);
+ AddRefBoxed(join, ctx, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Dict1);
+ this->DependsOn(Dict2);
+ }
+
+ bool HasNullInKey(const NUdf::TUnboxedValue& key) const {
if (!key) {
return true;
}
- if (KeyTuple) {
+ if (KeyTuple) {
for (ui32 index : OptIndicies) {
if (!key.GetElement(index)) {
return true;
@@ -94,208 +94,208 @@ private:
return false;
}
- template <EJoinKind Kind>
- void WriteValuesImpl(const NUdf::TUnboxedValuePod& payload1, const NUdf::TUnboxedValuePod& payload2,
- TDefaultListRepresentation& resList, TComputationContext& ctx) const {
- WriteValues<TWrapTraits<Kind>::Wrap1, TWrapTraits<Kind>::Wrap2>(payload1, payload2, resList, ctx);
- }
-
- template <bool WrapAsOptional1, bool WrapAsOptional2>
- void WriteValues(const NUdf::TUnboxedValuePod& payload1, const NUdf::TUnboxedValuePod& payload2,
- TDefaultListRepresentation& resList, TComputationContext& ctx) const {
- const bool isMulti1 = IsMulti1 && bool(payload1);
- const bool isMulti2 = IsMulti2 && bool(payload2);
- if (!isMulti1 && !isMulti2) {
- WriteTuple<WrapAsOptional1, WrapAsOptional2>(payload1, payload2, resList, ctx);
- } else if (isMulti1 && !isMulti2) {
- const auto it = payload1.GetListIterator();
- for (NUdf::TUnboxedValue item1; it.Next(item1);) {
- WriteTuple<WrapAsOptional1, WrapAsOptional2>(item1, payload2, resList, ctx);
- }
- } else if (!isMulti1 && isMulti2) {
- const auto it = payload2.GetListIterator();
- for (NUdf::TUnboxedValue item2; it.Next(item2);) {
- WriteTuple<WrapAsOptional1, WrapAsOptional2>(payload1, item2, resList, ctx);
- }
- } else {
- const auto it1 = payload1.GetListIterator();
- for (NUdf::TUnboxedValue item1; it1.Next(item1);) {
- const auto it2 = payload2.GetListIterator();
- for (NUdf::TUnboxedValue item2; it2.Next(item2);) {
- WriteTuple<WrapAsOptional1, WrapAsOptional2>(item1, item2, resList, ctx);
- }
- }
- }
- }
-
- template <bool WrapAsOptional1, bool WrapAsOptional2>
- void WriteTuple(const NUdf::TUnboxedValuePod& val1, const NUdf::TUnboxedValuePod& val2,
- TDefaultListRepresentation& resList, TComputationContext& ctx) const {
- NUdf::TUnboxedValue* itemsPtr = nullptr;
- auto tuple = ctx.HolderFactory.CreateDirectArrayHolder(2, itemsPtr);
- itemsPtr[0] = val1 ? val1.MakeOptionalIf<WrapAsOptional1>() : NUdf::TUnboxedValuePod(val1);
- itemsPtr[1] = val2 ? val2.MakeOptionalIf<WrapAsOptional2>() : NUdf::TUnboxedValuePod(val2);
- resList = resList.Append(std::move(tuple));
- }
-
- NUdf::TUnboxedValuePod JoinDicts(TComputationContext& ctx, const NUdf::TUnboxedValuePod dict1, const NUdf::TUnboxedValuePod dict2) const {
+ template <EJoinKind Kind>
+ void WriteValuesImpl(const NUdf::TUnboxedValuePod& payload1, const NUdf::TUnboxedValuePod& payload2,
+ TDefaultListRepresentation& resList, TComputationContext& ctx) const {
+ WriteValues<TWrapTraits<Kind>::Wrap1, TWrapTraits<Kind>::Wrap2>(payload1, payload2, resList, ctx);
+ }
+
+ template <bool WrapAsOptional1, bool WrapAsOptional2>
+ void WriteValues(const NUdf::TUnboxedValuePod& payload1, const NUdf::TUnboxedValuePod& payload2,
+ TDefaultListRepresentation& resList, TComputationContext& ctx) const {
+ const bool isMulti1 = IsMulti1 && bool(payload1);
+ const bool isMulti2 = IsMulti2 && bool(payload2);
+ if (!isMulti1 && !isMulti2) {
+ WriteTuple<WrapAsOptional1, WrapAsOptional2>(payload1, payload2, resList, ctx);
+ } else if (isMulti1 && !isMulti2) {
+ const auto it = payload1.GetListIterator();
+ for (NUdf::TUnboxedValue item1; it.Next(item1);) {
+ WriteTuple<WrapAsOptional1, WrapAsOptional2>(item1, payload2, resList, ctx);
+ }
+ } else if (!isMulti1 && isMulti2) {
+ const auto it = payload2.GetListIterator();
+ for (NUdf::TUnboxedValue item2; it.Next(item2);) {
+ WriteTuple<WrapAsOptional1, WrapAsOptional2>(payload1, item2, resList, ctx);
+ }
+ } else {
+ const auto it1 = payload1.GetListIterator();
+ for (NUdf::TUnboxedValue item1; it1.Next(item1);) {
+ const auto it2 = payload2.GetListIterator();
+ for (NUdf::TUnboxedValue item2; it2.Next(item2);) {
+ WriteTuple<WrapAsOptional1, WrapAsOptional2>(item1, item2, resList, ctx);
+ }
+ }
+ }
+ }
+
+ template <bool WrapAsOptional1, bool WrapAsOptional2>
+ void WriteTuple(const NUdf::TUnboxedValuePod& val1, const NUdf::TUnboxedValuePod& val2,
+ TDefaultListRepresentation& resList, TComputationContext& ctx) const {
+ NUdf::TUnboxedValue* itemsPtr = nullptr;
+ auto tuple = ctx.HolderFactory.CreateDirectArrayHolder(2, itemsPtr);
+ itemsPtr[0] = val1 ? val1.MakeOptionalIf<WrapAsOptional1>() : NUdf::TUnboxedValuePod(val1);
+ itemsPtr[1] = val2 ? val2.MakeOptionalIf<WrapAsOptional2>() : NUdf::TUnboxedValuePod(val2);
+ resList = resList.Append(std::move(tuple));
+ }
+
+ NUdf::TUnboxedValuePod JoinDicts(TComputationContext& ctx, const NUdf::TUnboxedValuePod dict1, const NUdf::TUnboxedValuePod dict2) const {
TDefaultListRepresentation resList;
switch (JoinKind) {
case EJoinKind::Inner:
if (dict1.GetDictLength() < dict2.GetDictLength()) {
// traverse dict1, lookup dict2
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
Y_VERIFY_DEBUG(!HasNullInKey(key1));
- if (const auto lookup2 = dict2.Lookup(key1)) {
+ if (const auto lookup2 = dict2.Lookup(key1)) {
WriteValuesImpl<EJoinKind::Inner>(payload1, lookup2, resList, ctx);
}
}
} else {
// traverse dict2, lookup dict1
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
Y_VERIFY_DEBUG(!HasNullInKey(key2));
- if (const auto lookup1 = dict1.Lookup(key2)) {
+ if (const auto lookup1 = dict1.Lookup(key2)) {
WriteValuesImpl<EJoinKind::Inner>(lookup1, payload2, resList, ctx);
}
}
}
- break;
+ break;
- case EJoinKind::Left: {
+ case EJoinKind::Left: {
// traverse dict1, lookup dict2
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
auto lookup2 = HasNullInKey(key1) ? NUdf::TUnboxedValue() : dict2.Lookup(key1);
- lookup2 = lookup2 ? lookup2.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
- WriteValuesImpl<EJoinKind::Left>(payload1, lookup2, resList, ctx);
- }
+ lookup2 = lookup2 ? lookup2.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
+ WriteValuesImpl<EJoinKind::Left>(payload1, lookup2, resList, ctx);
+ }
}
break;
- case EJoinKind::Right: {
+ case EJoinKind::Right: {
// traverse dict2, lookup dict1
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
auto lookup1 = HasNullInKey(key2) ? NUdf::TUnboxedValue() : dict1.Lookup(key2);
- lookup1 = lookup1 ? lookup1.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
- WriteValuesImpl<EJoinKind::Right>(lookup1, payload2, resList, ctx);
- }
+ lookup1 = lookup1 ? lookup1.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
+ WriteValuesImpl<EJoinKind::Right>(lookup1, payload2, resList, ctx);
+ }
}
break;
- case EJoinKind::Full: {
+ case EJoinKind::Full: {
// traverse dict1, lookup dict2 - as Left
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
auto lookup2 = HasNullInKey(key1) ? NUdf::TUnboxedValue() : dict2.Lookup(key1);
- lookup2 = lookup2 ? lookup2.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
- WriteValuesImpl<EJoinKind::Full>(payload1, lookup2, resList, ctx);
- }
+ lookup2 = lookup2 ? lookup2.Release().GetOptionalValue() : NUdf::TUnboxedValuePod();
+ WriteValuesImpl<EJoinKind::Full>(payload1, lookup2, resList, ctx);
+ }
}
- {
+ {
// traverse dict2, lookup dict1 - avoid Inner
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
if (HasNullInKey(key2) || !dict1.Contains(key2)) {
- WriteValuesImpl<EJoinKind::Full>(NUdf::TUnboxedValuePod(), payload2, resList, ctx);
- }
+ WriteValuesImpl<EJoinKind::Full>(NUdf::TUnboxedValuePod(), payload2, resList, ctx);
+ }
}
}
break;
- case EJoinKind::LeftOnly: {
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ case EJoinKind::LeftOnly: {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
if (HasNullInKey(key1) || !dict2.Contains(key1)) {
- if (IsMulti1) {
- TThresher<false>::DoForEachItem(payload1,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- } else {
- resList = resList.Append(std::move(payload1));
- }
+ if (IsMulti1) {
+ TThresher<false>::DoForEachItem(payload1,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ } else {
+ resList = resList.Append(std::move(payload1));
+ }
}
- }
+ }
}
break;
- case EJoinKind::RightOnly: {
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ case EJoinKind::RightOnly: {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
if (HasNullInKey(key2) || !dict1.Contains(key2)) {
- if (IsMulti2) {
- TThresher<false>::DoForEachItem(payload2,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- } else {
- resList = resList.Append(std::move(payload2));
- }
+ if (IsMulti2) {
+ TThresher<false>::DoForEachItem(payload2,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ } else {
+ resList = resList.Append(std::move(payload2));
+ }
}
- }
+ }
}
break;
- case EJoinKind::Exclusion: {
+ case EJoinKind::Exclusion: {
// traverse dict1, lookup dict2 - avoid Inner
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
if (HasNullInKey(key1) || !dict2.Contains(key1)) {
- WriteValuesImpl<EJoinKind::Exclusion>(payload1, NUdf::TUnboxedValuePod(), resList, ctx);
- }
+ WriteValuesImpl<EJoinKind::Exclusion>(payload1, NUdf::TUnboxedValuePod(), resList, ctx);
+ }
}
- }
- {
+ }
+ {
// traverse dict2, lookup dict1 - avoid Inner
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
if (HasNullInKey(key2) || !dict1.Contains(key2)) {
- WriteValuesImpl<EJoinKind::Exclusion>(NUdf::TUnboxedValuePod(), payload2, resList, ctx);
- }
+ WriteValuesImpl<EJoinKind::Exclusion>(NUdf::TUnboxedValuePod(), payload2, resList, ctx);
+ }
}
}
break;
- case EJoinKind::LeftSemi: {
- const auto it = dict1.GetDictIterator();
- for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
+ case EJoinKind::LeftSemi: {
+ const auto it = dict1.GetDictIterator();
+ for (NUdf::TUnboxedValue key1, payload1; it.NextPair(key1, payload1);) {
Y_VERIFY_DEBUG(!HasNullInKey(key1));
- if (dict2.Contains(key1)) {
- if (IsMulti1) {
- TThresher<false>::DoForEachItem(payload1,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- } else {
- resList = resList.Append(std::move(payload1));
- }
+ if (dict2.Contains(key1)) {
+ if (IsMulti1) {
+ TThresher<false>::DoForEachItem(payload1,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ } else {
+ resList = resList.Append(std::move(payload1));
+ }
}
- }
+ }
}
break;
- case EJoinKind::RightSemi: {
- const auto it = dict2.GetDictIterator();
- for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
+ case EJoinKind::RightSemi: {
+ const auto it = dict2.GetDictIterator();
+ for (NUdf::TUnboxedValue key2, payload2; it.NextPair(key2, payload2);) {
Y_VERIFY_DEBUG(!HasNullInKey(key2));
- if (dict1.Contains(key2)) {
- if (IsMulti2) {
- TThresher<false>::DoForEachItem(payload2,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- } else {
- resList = resList.Append(std::move(payload2));
- }
+ if (dict1.Contains(key2)) {
+ if (IsMulti2) {
+ TThresher<false>::DoForEachItem(payload2,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ } else {
+ resList = resList.Append(std::move(payload2));
+ }
}
- }
+ }
}
break;
@@ -303,7 +303,7 @@ private:
Y_FAIL("Unknown kind");
}
- return ctx.HolderFactory.CreateDirectListHolder(std::move(resList));
+ return ctx.HolderFactory.CreateDirectListHolder(std::move(resList));
}
IComputationNode* const Dict1;
@@ -311,45 +311,45 @@ private:
const bool IsMulti1;
const bool IsMulti2;
const EJoinKind JoinKind;
- const std::vector<ui32> OptIndicies;
+ const std::vector<ui32> OptIndicies;
};
-}
+}
IComputationNode* WrapJoinDict(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
- const auto dict1node = callable.GetInput(0);
- const auto dict2node = callable.GetInput(1);
- const auto isMulti1Node = callable.GetInput(2);
- const auto isMulti2Node = callable.GetInput(3);
- const auto joinKindNode = callable.GetInput(4);
-
- const auto dict1type = AS_TYPE(TDictType, dict1node);
- const auto dict2type = AS_TYPE(TDictType, dict2node);
- const auto keyType = dict1type->GetKeyType();
- MKQL_ENSURE(keyType->IsSameType(*dict2type->GetKeyType()), "Dict key types must be the same");
-
- const bool multi1 = AS_VALUE(TDataLiteral, isMulti1Node)->AsValue().Get<bool>();
- const bool multi2 = AS_VALUE(TDataLiteral, isMulti2Node)->AsValue().Get<bool>();
- const ui32 rawKind = AS_VALUE(TDataLiteral, joinKindNode)->AsValue().Get<ui32>();
-
- const auto dict1 = LocateNode(ctx.NodeLocator, callable, 0);
- const auto dict2 = LocateNode(ctx.NodeLocator, callable, 1);
-
- if (keyType->IsTuple()) {
- const auto tupleType = AS_TYPE(TTupleType, keyType);
- std::vector<ui32> indicies;
- indicies.reserve(tupleType->GetElementsCount());
- for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i) {
- if (tupleType->GetElementType(i)->IsOptional()) {
- indicies.emplace_back(i);
- }
- }
-
- return new TJoinDictWrapper<true>(ctx.Mutables, dict1, dict2, multi1, multi2, GetJoinKind(rawKind), std::move(indicies));
- } else {
- return new TJoinDictWrapper<false>(ctx.Mutables, dict1, dict2, multi1, multi2, GetJoinKind(rawKind));
+ const auto dict1node = callable.GetInput(0);
+ const auto dict2node = callable.GetInput(1);
+ const auto isMulti1Node = callable.GetInput(2);
+ const auto isMulti2Node = callable.GetInput(3);
+ const auto joinKindNode = callable.GetInput(4);
+
+ const auto dict1type = AS_TYPE(TDictType, dict1node);
+ const auto dict2type = AS_TYPE(TDictType, dict2node);
+ const auto keyType = dict1type->GetKeyType();
+ MKQL_ENSURE(keyType->IsSameType(*dict2type->GetKeyType()), "Dict key types must be the same");
+
+ const bool multi1 = AS_VALUE(TDataLiteral, isMulti1Node)->AsValue().Get<bool>();
+ const bool multi2 = AS_VALUE(TDataLiteral, isMulti2Node)->AsValue().Get<bool>();
+ const ui32 rawKind = AS_VALUE(TDataLiteral, joinKindNode)->AsValue().Get<ui32>();
+
+ const auto dict1 = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto dict2 = LocateNode(ctx.NodeLocator, callable, 1);
+
+ if (keyType->IsTuple()) {
+ const auto tupleType = AS_TYPE(TTupleType, keyType);
+ std::vector<ui32> indicies;
+ indicies.reserve(tupleType->GetElementsCount());
+ for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i) {
+ if (tupleType->GetElementType(i)->IsOptional()) {
+ indicies.emplace_back(i);
+ }
+ }
+
+ return new TJoinDictWrapper<true>(ctx.Mutables, dict1, dict2, multi1, multi2, GetJoinKind(rawKind), std::move(indicies));
+ } else {
+ return new TJoinDictWrapper<false>(ctx.Mutables, dict1, dict2, multi1, multi2, GetJoinKind(rawKind));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.cpp
index ca9d85efe7..eb4524f347 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.cpp
@@ -1,106 +1,106 @@
-#include "mkql_lazy_list.h"
+#include "mkql_lazy_list.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <bool IsOptional>
-class TLazyListWrapper : public TMutableCodegeneratorNode<TLazyListWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TLazyListWrapper<IsOptional>> TBaseComputation;
-public:
-
- TLazyListWrapper(TComputationMutables& mutables, IComputationNode* list)
- : TBaseComputation(mutables, EValueRepresentation::Boxed), List(list)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- if (IsOptional && !list) {
- return NUdf::TUnboxedValuePod();
- }
-
- if (list.GetElements()) {
- return ctx.HolderFactory.LazyList(list.Release());
- }
-
- return list.Release();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::LazyList));
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto wrap = BasicBlock::Create(context, "wrap", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto lazy = PHINode::Create(list->getType(), IsOptional ? 3U : 2U, "lazy", done);
- lazy->addIncoming(list, block);
-
- if (IsOptional) {
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- BranchInst::Create(done, test, IsEmpty(list, block), block);
-
- block = test;
- lazy->addIncoming(list, block);
- }
-
- const auto ptrType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- BranchInst::Create(done, wrap, null, block);
-
- block = wrap;
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), list->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, list}, "res", block);
- lazy->addIncoming(res, block);
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- new StoreInst(list, retPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, retPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- lazy->addIncoming(res, block);
- }
-
- BranchInst::Create(done, block);
-
- block = done;
- return lazy;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
- }
-
- IComputationNode* const List;
-};
-
-}
-
-IComputationNode* WrapLazyList(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1U, "Expected single arg, got " << callable.GetInputsCount());
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
-
- if (callable.GetInput(0).GetStaticType()->IsOptional()) {
- return new TLazyListWrapper<true>(ctx.Mutables, list);
- } else {
- return new TLazyListWrapper<false>(ctx.Mutables, list);
- }
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <bool IsOptional>
+class TLazyListWrapper : public TMutableCodegeneratorNode<TLazyListWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TLazyListWrapper<IsOptional>> TBaseComputation;
+public:
+
+ TLazyListWrapper(TComputationMutables& mutables, IComputationNode* list)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed), List(list)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ if (IsOptional && !list) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ if (list.GetElements()) {
+ return ctx.HolderFactory.LazyList(list.Release());
+ }
+
+ return list.Release();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::LazyList));
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto wrap = BasicBlock::Create(context, "wrap", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto lazy = PHINode::Create(list->getType(), IsOptional ? 3U : 2U, "lazy", done);
+ lazy->addIncoming(list, block);
+
+ if (IsOptional) {
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ BranchInst::Create(done, test, IsEmpty(list, block), block);
+
+ block = test;
+ lazy->addIncoming(list, block);
+ }
+
+ const auto ptrType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ BranchInst::Create(done, wrap, null, block);
+
+ block = wrap;
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), list->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, list}, "res", block);
+ lazy->addIncoming(res, block);
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ new StoreInst(list, retPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, retPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ lazy->addIncoming(res, block);
+ }
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return lazy;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
+ }
+
+ IComputationNode* const List;
+};
+
+}
+
+IComputationNode* WrapLazyList(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1U, "Expected single arg, got " << callable.GetInputsCount());
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+
+ if (callable.GetInput(0).GetStaticType()->IsOptional()) {
+ return new TLazyListWrapper<true>(ctx.Mutables, list);
+ } else {
+ return new TLazyListWrapper<false>(ctx.Mutables, list);
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.h b/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.h
index 83b5a2e8df..d93432b743 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_lazy_list.h
@@ -1,11 +1,11 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapLazyList(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapLazyList(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_length.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_length.cpp
index ff8b5848d1..db5266928c 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_length.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_length.cpp
@@ -7,83 +7,83 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool IsDict, bool IsOptional>
-class TLengthWrapper : public TMutableCodegeneratorNode<TLengthWrapper<IsDict, IsOptional>> {
- typedef TMutableCodegeneratorNode<TLengthWrapper<IsDict, IsOptional>> TBaseComputation;
+namespace {
+
+template <bool IsDict, bool IsOptional>
+class TLengthWrapper : public TMutableCodegeneratorNode<TLengthWrapper<IsDict, IsOptional>> {
+ typedef TMutableCodegeneratorNode<TLengthWrapper<IsDict, IsOptional>> TBaseComputation;
public:
TLengthWrapper(TComputationMutables& mutables, IComputationNode* collection)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
, Collection(collection)
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
- const auto& collection = Collection->GetValue(compCtx);
- if (IsOptional && !collection) {
- return NUdf::TUnboxedValuePod();
- }
- const auto length = IsDict ? collection.GetDictLength() : collection.GetListLength();
- return NUdf::TUnboxedValuePod(length);
+ const auto& collection = Collection->GetValue(compCtx);
+ if (IsOptional && !collection) {
+ return NUdf::TUnboxedValuePod();
+ }
+ const auto length = IsDict ? collection.GetDictLength() : collection.GetListLength();
+ return NUdf::TUnboxedValuePod(length);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto collection = GetNodeValue(Collection, ctx, block);
-
- if constexpr (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(collection->getType(), 2U, "result", done);
-
- result->addIncoming(collection, block);
- BranchInst::Create(done, good, IsEmpty(collection, block), block);
- block = good;
-
- const auto length = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::GetDictLength : NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), collection, ctx.Codegen, block);
- if (Collection->IsTemporaryValue())
- CleanupBoxed(collection, ctx, block);
- result->addIncoming(SetterFor<ui64>(length, context, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- const auto length = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::GetDictLength : NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), collection, ctx.Codegen, block);
- if (Collection->IsTemporaryValue())
- CleanupBoxed(collection, ctx, block);
- return SetterFor<ui64>(length, context, block);
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Collection);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto collection = GetNodeValue(Collection, ctx, block);
+
+ if constexpr (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(collection->getType(), 2U, "result", done);
+
+ result->addIncoming(collection, block);
+ BranchInst::Create(done, good, IsEmpty(collection, block), block);
+ block = good;
+
+ const auto length = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::GetDictLength : NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), collection, ctx.Codegen, block);
+ if (Collection->IsTemporaryValue())
+ CleanupBoxed(collection, ctx, block);
+ result->addIncoming(SetterFor<ui64>(length, context, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ const auto length = CallBoxedValueVirtualMethod<IsDict ? NUdf::TBoxedValueAccessor::EMethod::GetDictLength : NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), collection, ctx.Codegen, block);
+ if (Collection->IsTemporaryValue())
+ CleanupBoxed(collection, ctx, block);
+ return SetterFor<ui64>(length, context, block);
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Collection);
}
IComputationNode* const Collection;
};
-}
-
+}
+
IComputationNode* WrapLength(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- bool isOptional;
- const auto type = UnpackOptional(callable.GetInput(0).GetStaticType(), isOptional);
+ bool isOptional;
+ const auto type = UnpackOptional(callable.GetInput(0).GetStaticType(), isOptional);
if (type->IsDict() || type->IsEmptyDict()) {
- if (isOptional)
- return new TLengthWrapper<true, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- else
- return new TLengthWrapper<true, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ if (isOptional)
+ return new TLengthWrapper<true, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ else
+ return new TLengthWrapper<true, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
} else if (type->IsList() || type->IsEmptyList()) {
- if (isOptional)
- return new TLengthWrapper<false, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
- else
- return new TLengthWrapper<false, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ if (isOptional)
+ return new TLengthWrapper<false, true>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
+ else
+ return new TLengthWrapper<false, false>(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
}
-
- THROW yexception() << "Expected list or dict.";
+
+ THROW yexception() << "Expected list or dict.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_listfromrange.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_listfromrange.cpp
index 0d5bbb77a8..5eeac1ea86 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_listfromrange.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_listfromrange.cpp
@@ -31,7 +31,7 @@ ui64 GetElementsCount(ui64 start, ui64 end, ui64 step) {
return rem ? (div + 1) : div;
}
-template<typename T, typename TStep>
+template<typename T, typename TStep>
ui64 GetElementsCount(T start, T end, TStep step) {
ui64 newStart = ShiftByMaxNegative(start);
ui64 newEnd = ShiftByMaxNegative(end);
@@ -47,12 +47,12 @@ ui64 GetElementsCount(T start, T end, TStep step) {
return GetElementsCount(newStart, newEnd, newStep);
}
-template <typename T, typename TStep = std::make_signed_t<T>, std::conditional_t<std::is_floating_point_v<TStep>, i8, TStep> TConstFactor = 1, ui64 TConstLimit = std::numeric_limits<ui64>::max(), bool TzDate = false>
+template <typename T, typename TStep = std::make_signed_t<T>, std::conditional_t<std::is_floating_point_v<TStep>, i8, TStep> TConstFactor = 1, ui64 TConstLimit = std::numeric_limits<ui64>::max(), bool TzDate = false>
class TListFromRangeWrapper : public TMutableCodegeneratorNode<TListFromRangeWrapper<T, TStep, TConstFactor, TConstLimit, TzDate>> {
-private:
- using TBaseComputation = TMutableCodegeneratorNode<TListFromRangeWrapper<T, TStep, TConstFactor, TConstLimit, TzDate>>;
+private:
+ using TBaseComputation = TMutableCodegeneratorNode<TListFromRangeWrapper<T, TStep, TConstFactor, TConstLimit, TzDate>>;
- class TValue : public TComputationValue<TValue> {
+ class TValue : public TComputationValue<TValue> {
public:
template <bool Asc, bool Float>
class TIterator;
@@ -68,7 +68,7 @@ private:
{}
protected:
- bool Skip() final {
+ bool Skip() final {
if (!Count) {
return false;
}
@@ -79,15 +79,15 @@ private:
bool Next(NUdf::TUnboxedValue& value) override {
if (!Count) {
- return false;
- }
-
- value = NUdf::TUnboxedValuePod(Current);
+ return false;
+ }
+
+ value = NUdf::TUnboxedValuePod(Current);
Current += Step;
--Count;
- return true;
- }
-
+ return true;
+ }
+
T Current;
const TStep Step;
ui64 Count;
@@ -99,38 +99,38 @@ private:
TIterator(TMemoryUsageInfo* memInfo, T start, T end, TStep step)
: TComputationValue<TIterator>(memInfo)
, Start(start)
- , Index(-T(1))
- , Limit(end - start)
+ , Index(-T(1))
+ , Limit(end - start)
, Step(step)
{}
private:
- bool Skip() final {
- const auto next = Index + T(1);
- if (Asc ? next * Step < Limit : next * Step > Limit) {
- Index = next;
- return true;
+ bool Skip() final {
+ const auto next = Index + T(1);
+ if (Asc ? next * Step < Limit : next * Step > Limit) {
+ Index = next;
+ return true;
}
return false;
}
- bool Next(NUdf::TUnboxedValue& value) final {
- if (!Skip()) {
- return false;
- }
-
- value = NUdf::TUnboxedValuePod(Start + Index * Step);
- return true;
- }
-
+ bool Next(NUdf::TUnboxedValue& value) final {
+ if (!Skip()) {
+ return false;
+ }
+
+ value = NUdf::TUnboxedValuePod(Start + Index * Step);
+ return true;
+ }
+
const T Start;
T Index;
- const T Limit;
+ const T Limit;
const TStep Step;
};
TValue(TMemoryUsageInfo* memInfo, TComputationContext& ctx, T start, T end, TStep step)
- : TComputationValue<TValue>(memInfo)
+ : TComputationValue<TValue>(memInfo)
, Ctx(ctx)
, Start(start)
, End(end)
@@ -141,50 +141,50 @@ private:
protected:
NUdf::TUnboxedValue GetListIterator() const override {
if (Step > TStep(0)) {
- return Ctx.HolderFactory.template Create<TIterator<true, std::is_floating_point<T>::value>>(Start, End, Step);
+ return Ctx.HolderFactory.template Create<TIterator<true, std::is_floating_point<T>::value>>(Start, End, Step);
} else if (Step < TStep(0)) {
- return Ctx.HolderFactory.template Create<TIterator<false, std::is_floating_point<T>::value>>(Start, End, Step);
+ return Ctx.HolderFactory.template Create<TIterator<false, std::is_floating_point<T>::value>>(Start, End, Step);
} else {
return Ctx.HolderFactory.GetEmptyContainer();
}
}
- ui64 GetListLength() const final {
+ ui64 GetListLength() const final {
if (std::is_integral<T>()) {
return GetElementsCount<T, TStep>(Start, End, Step);
}
- if (Step > T(0) && Start < End) {
- ui64 len = 0ULL;
- for (T i = 0; i * Step < End - Start; i += T(1)) {
- ++len;
- }
- return len;
- } else if (Step < T(0) && Start > End) {
- ui64 len = 0ULL;
- for (T i = 0; i * Step > End - Start; i += T(1)) {
- ++len;
- }
- return len;
- } else {
- return 0ULL;
- }
- }
-
- bool HasListItems() const final {
+ if (Step > T(0) && Start < End) {
+ ui64 len = 0ULL;
+ for (T i = 0; i * Step < End - Start; i += T(1)) {
+ ++len;
+ }
+ return len;
+ } else if (Step < T(0) && Start > End) {
+ ui64 len = 0ULL;
+ for (T i = 0; i * Step > End - Start; i += T(1)) {
+ ++len;
+ }
+ return len;
+ } else {
+ return 0ULL;
+ }
+ }
+
+ bool HasListItems() const final {
if (Step > TStep(0)) {
- return Start < End;
+ return Start < End;
} else if (Step < TStep(0)) {
- return Start > End;
- } else {
- return false;
- }
- }
-
- bool HasFastListLength() const final {
- return std::is_integral<T>();
- }
-
+ return Start > End;
+ } else {
+ return false;
+ }
+ }
+
+ bool HasFastListLength() const final {
+ return std::is_integral<T>();
+ }
+
TComputationContext& Ctx;
const T Start;
const T End;
@@ -209,7 +209,7 @@ private:
return false;
}
private:
- const ui16 TimezoneId;
+ const ui16 TimezoneId;
};
NUdf::TUnboxedValue GetListIterator() const final {
if (TValue::Step > TStep(0)) {
@@ -226,80 +226,80 @@ private:
{
}
private:
- const ui16 TimezoneId;
+ const ui16 TimezoneId;
};
-public:
+public:
TListFromRangeWrapper(TComputationMutables& mutables, IComputationNode* start, IComputationNode* end, IComputationNode* step)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, Start(start)
, End(end)
, Step(step)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto start = Start->GetValue(ctx);
- const auto end = End->GetValue(ctx);
- auto step = Step->GetValue(ctx).Get<TStep>();
- if constexpr (TConstFactor > 1) {
- if (step % TConstFactor)
- step = 0;
- else
- step /= TConstFactor;
- }
-
- if constexpr (TzDate) {
- return MakeList(ctx, start.Get<T>(), end.Get<T>(), step, start.GetTimezoneId());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto start = Start->GetValue(ctx);
+ const auto end = End->GetValue(ctx);
+ auto step = Step->GetValue(ctx).Get<TStep>();
+ if constexpr (TConstFactor > 1) {
+ if (step % TConstFactor)
+ step = 0;
+ else
+ step /= TConstFactor;
+ }
+
+ if constexpr (TzDate) {
+ return MakeList(ctx, start.Get<T>(), end.Get<T>(), step, start.GetTimezoneId());
+ } else {
+ return MakeList(ctx, start.Get<T>(), end.Get<T>(), step, 0U);
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto startv = GetNodeValue(Start, ctx, block);
+ const auto endv = GetNodeValue(End, ctx, block);
+ const auto stepv = GetNodeValue(Step, ctx, block);
+
+ const auto start = GetterFor<T>(startv, context, block);
+ const auto end = GetterFor<T>(endv, context, block);
+
+ auto step = GetterFor<TStep>(stepv, context, block);
+ if constexpr (TConstFactor > 1) {
+ const auto zero = ConstantInt::get(GetTypeFor<TStep>(context), 0);
+ const auto fact = ConstantInt::get(GetTypeFor<TStep>(context), TConstFactor);
+ const auto div = BinaryOperator::CreateSDiv(step, fact, "div", block);
+ const auto rem = BinaryOperator::CreateSRem(step, fact, "rem", block);
+ const auto bad = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, rem, zero, "bad", block);
+ step = SelectInst::Create(bad, zero, div, "step", block);
+ }
+
+ const auto timezone = TzDate ? GetterForTimezone(context, startv, block) : ConstantInt::get(Type::getInt16Ty(context), 0);
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFromRangeWrapper::MakeList));
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto signature = FunctionType::get(Type::getInt128Ty(context), {ctx.Ctx->getType(), start->getType(), end->getType(), step->getType(), timezone->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ const auto output = CallInst::Create(creator, {ctx.Ctx, start, end, step, timezone}, "output", block);
+ return output;
} else {
- return MakeList(ctx, start.Get<T>(), end.Get<T>(), step, 0U);
+ const auto place = new AllocaInst(Type::getInt128Ty(context), 0U, "place", block);
+ const auto signature = FunctionType::get(Type::getVoidTy(context), {place->getType(), ctx.Ctx->getType(), start->getType(), end->getType(), step->getType(), timezone->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ CallInst::Create(creator, {place, ctx.Ctx, start, end, step, timezone}, "", block);
+ const auto output = new LoadInst(place, "output", block);
+ return output;
}
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto startv = GetNodeValue(Start, ctx, block);
- const auto endv = GetNodeValue(End, ctx, block);
- const auto stepv = GetNodeValue(Step, ctx, block);
-
- const auto start = GetterFor<T>(startv, context, block);
- const auto end = GetterFor<T>(endv, context, block);
-
- auto step = GetterFor<TStep>(stepv, context, block);
- if constexpr (TConstFactor > 1) {
- const auto zero = ConstantInt::get(GetTypeFor<TStep>(context), 0);
- const auto fact = ConstantInt::get(GetTypeFor<TStep>(context), TConstFactor);
- const auto div = BinaryOperator::CreateSDiv(step, fact, "div", block);
- const auto rem = BinaryOperator::CreateSRem(step, fact, "rem", block);
- const auto bad = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, rem, zero, "bad", block);
- step = SelectInst::Create(bad, zero, div, "step", block);
- }
-
- const auto timezone = TzDate ? GetterForTimezone(context, startv, block) : ConstantInt::get(Type::getInt16Ty(context), 0);
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListFromRangeWrapper::MakeList));
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto signature = FunctionType::get(Type::getInt128Ty(context), {ctx.Ctx->getType(), start->getType(), end->getType(), step->getType(), timezone->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- const auto output = CallInst::Create(creator, {ctx.Ctx, start, end, step, timezone}, "output", block);
- return output;
- } else {
- const auto place = new AllocaInst(Type::getInt128Ty(context), 0U, "place", block);
- const auto signature = FunctionType::get(Type::getVoidTy(context), {place->getType(), ctx.Ctx->getType(), start->getType(), end->getType(), step->getType(), timezone->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- CallInst::Create(creator, {place, ctx.Ctx, start, end, step, timezone}, "", block);
- const auto output = new LoadInst(place, "output", block);
- return output;
- }
- }
-#endif
+#endif
private:
- static NUdf::TUnboxedValuePod MakeList(TComputationContext& ctx, T start, T end, TStep step, ui16 timezoneId) {
- if (timezoneId)
- return ctx.HolderFactory.Create<TTzValue>(ctx, start, end, step, timezoneId);
- else
- return ctx.HolderFactory.Create<TValue>(ctx, start, end, step);
- }
-
+ static NUdf::TUnboxedValuePod MakeList(TComputationContext& ctx, T start, T end, TStep step, ui16 timezoneId) {
+ if (timezoneId)
+ return ctx.HolderFactory.Create<TTzValue>(ctx, start, end, step, timezoneId);
+ else
+ return ctx.HolderFactory.Create<TValue>(ctx, start, end, step);
+ }
+
void RegisterDependencies() const final {
this->DependsOn(Start);
this->DependsOn(End);
@@ -316,9 +316,9 @@ private:
IComputationNode* WrapListFromRange(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
- const auto start = LocateNode(ctx.NodeLocator, callable, 0);
- const auto end = LocateNode(ctx.NodeLocator, callable, 1);
- const auto step = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto start = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto end = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto step = LocateNode(ctx.NodeLocator, callable, 2);
switch (*AS_TYPE(TDataType, callable.GetInput(0).GetStaticType())->GetDataSlot()) {
case NUdf::EDataSlot::Uint8:
return new TListFromRangeWrapper<ui8>(ctx.Mutables, start, end, step);
@@ -337,9 +337,9 @@ IComputationNode* WrapListFromRange(TCallable& callable, const TComputationNodeF
case NUdf::EDataSlot::Int64:
return new TListFromRangeWrapper<i64>(ctx.Mutables, start, end, step);
case NUdf::EDataSlot::Float:
- return new TListFromRangeWrapper<float, float>(ctx.Mutables, start, end, step);
+ return new TListFromRangeWrapper<float, float>(ctx.Mutables, start, end, step);
case NUdf::EDataSlot::Double:
- return new TListFromRangeWrapper<double, double>(ctx.Mutables, start, end, step);
+ return new TListFromRangeWrapper<double, double>(ctx.Mutables, start, end, step);
case NUdf::EDataSlot::Date:
return new TListFromRangeWrapper<ui16, i64, 86400000000ll, NYql::NUdf::MAX_DATE>(ctx.Mutables, start, end, step);
case NUdf::EDataSlot::TzDate:
@@ -352,8 +352,8 @@ IComputationNode* WrapListFromRange(TCallable& callable, const TComputationNodeF
return new TListFromRangeWrapper<ui64, i64, 1, NYql::NUdf::MAX_TIMESTAMP>(ctx.Mutables, start, end, step);
case NUdf::EDataSlot::TzTimestamp:
return new TListFromRangeWrapper<ui64, i64, 1, NYql::NUdf::MAX_TIMESTAMP, true>(ctx.Mutables, start, end, step);
- case NUdf::EDataSlot::Interval:
- return new TListFromRangeWrapper<i64, i64, 1, NYql::NUdf::MAX_TIMESTAMP>(ctx.Mutables, start, end, step);
+ case NUdf::EDataSlot::Interval:
+ return new TListFromRangeWrapper<i64, i64, 1, NYql::NUdf::MAX_TIMESTAMP>(ctx.Mutables, start, end, step);
default:
MKQL_ENSURE(false, "unexpected");
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_logical.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_logical.cpp
index b3310bd3a4..7a0f69777e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_logical.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_logical.cpp
@@ -7,281 +7,281 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool IsLeftOptional, bool IsRightOptional>
-class TAndWrapper : public TBinaryCodegeneratorNode<TAndWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TBinaryCodegeneratorNode<TAndWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+class TAndWrapper : public TBinaryCodegeneratorNode<TAndWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TBinaryCodegeneratorNode<TAndWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
public:
TAndWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(left, right, EValueRepresentation::Embedded)
+ : TBaseComputation(left, right, EValueRepresentation::Embedded)
{
Y_UNUSED(mutables);
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& left = this->Left->GetValue(ctx);
- if (!IsLeftOptional || left) {
- if (!left.template Get<bool>()) {
- return NUdf::TUnboxedValuePod(false);
+ const auto& left = this->Left->GetValue(ctx);
+ if (!IsLeftOptional || left) {
+ if (!left.template Get<bool>()) {
+ return NUdf::TUnboxedValuePod(false);
}
}
- const auto& right = this->Right->GetValue(ctx);
- if (!IsRightOptional || right) {
- if (!right.template Get<bool>()) {
- return NUdf::TUnboxedValuePod(false);
+ const auto& right = this->Right->GetValue(ctx);
+ if (!IsRightOptional || right) {
+ if (!right.template Get<bool>()) {
+ return NUdf::TUnboxedValuePod(false);
}
}
// both either true (just true) or nothing
- if (IsLeftOptional && !left || IsRightOptional && !right) {
- return NUdf::TUnboxedValuePod();
+ if (IsLeftOptional && !left || IsRightOptional && !right) {
+ return NUdf::TUnboxedValuePod();
}
- return NUdf::TUnboxedValuePod(true);
+ return NUdf::TUnboxedValuePod(true);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto left = GetNodeValue(this->Left, ctx, block);
-
- const auto uvFalse = GetFalse(context);
-
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, uvFalse, "skip", block);
-
- const auto both = BasicBlock::Create(context, "both", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2, "result", done);
-
- result->addIncoming(uvFalse, block);
- BranchInst::Create(done, both, skip, block);
-
- block = both;
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- if (IsLeftOptional) {
- const auto andr = BinaryOperator::CreateAnd(left, right, "and", block);
- const auto over = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, uvFalse, "over", block);
- const auto full = SelectInst::Create(over, uvFalse, andr, "full", block);
- result->addIncoming(full, block);
- } else {
- result->addIncoming(right, block);
- }
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto left = GetNodeValue(this->Left, ctx, block);
+
+ const auto uvFalse = GetFalse(context);
+
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, uvFalse, "skip", block);
+
+ const auto both = BasicBlock::Create(context, "both", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2, "result", done);
+
+ result->addIncoming(uvFalse, block);
+ BranchInst::Create(done, both, skip, block);
+
+ block = both;
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ if (IsLeftOptional) {
+ const auto andr = BinaryOperator::CreateAnd(left, right, "and", block);
+ const auto over = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, uvFalse, "over", block);
+ const auto full = SelectInst::Create(over, uvFalse, andr, "full", block);
+ result->addIncoming(full, block);
+ } else {
+ result->addIncoming(right, block);
+ }
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
};
template <bool IsLeftOptional, bool IsRightOptional>
-class TOrWrapper : public TBinaryCodegeneratorNode<TOrWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TBinaryCodegeneratorNode<TOrWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+class TOrWrapper : public TBinaryCodegeneratorNode<TOrWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TBinaryCodegeneratorNode<TOrWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
public:
TOrWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(left, right, EValueRepresentation::Embedded)
+ : TBaseComputation(left, right, EValueRepresentation::Embedded)
{
Y_UNUSED(mutables);
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& left = this->Left->GetValue(ctx);
- if (!IsLeftOptional || left) {
- if (left.template Get<bool>()) {
- return NUdf::TUnboxedValuePod(true);
+ const auto& left = this->Left->GetValue(ctx);
+ if (!IsLeftOptional || left) {
+ if (left.template Get<bool>()) {
+ return NUdf::TUnboxedValuePod(true);
}
}
- const auto& right = this->Right->GetValue(ctx);
- if (!IsRightOptional || right) {
- if (right.template Get<bool>()) {
- return NUdf::TUnboxedValuePod(true);
+ const auto& right = this->Right->GetValue(ctx);
+ if (!IsRightOptional || right) {
+ if (right.template Get<bool>()) {
+ return NUdf::TUnboxedValuePod(true);
}
}
// both either false (just false) or nothing
- if (IsLeftOptional && !left || IsRightOptional && !right) {
- return NUdf::TUnboxedValuePod();
+ if (IsLeftOptional && !left || IsRightOptional && !right) {
+ return NUdf::TUnboxedValuePod();
}
- return NUdf::TUnboxedValuePod(false);
+ return NUdf::TUnboxedValuePod(false);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto left = GetNodeValue(this->Left, ctx, block);
-
- const auto uvTrue = GetTrue(context);
-
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, uvTrue, "skip", block);
-
- const auto both = BasicBlock::Create(context, "both", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2, "result", done);
-
- result->addIncoming(uvTrue, block);
- BranchInst::Create(done, both, skip, block);
-
- block = both;
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- if (IsLeftOptional) {
- const auto andr = BinaryOperator::CreateAnd(left, right, "and", block);
- const auto over = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, uvTrue, "over", block);
- const auto full = SelectInst::Create(over, uvTrue, andr, "full", block);
- result->addIncoming(full, block);
- } else {
- result->addIncoming(right, block);
- }
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto left = GetNodeValue(this->Left, ctx, block);
+
+ const auto uvTrue = GetTrue(context);
+
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, uvTrue, "skip", block);
+
+ const auto both = BasicBlock::Create(context, "both", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2, "result", done);
+
+ result->addIncoming(uvTrue, block);
+ BranchInst::Create(done, both, skip, block);
+
+ block = both;
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ if (IsLeftOptional) {
+ const auto andr = BinaryOperator::CreateAnd(left, right, "and", block);
+ const auto over = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, uvTrue, "over", block);
+ const auto full = SelectInst::Create(over, uvTrue, andr, "full", block);
+ result->addIncoming(full, block);
+ } else {
+ result->addIncoming(right, block);
+ }
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
};
template <bool IsLeftOptional, bool IsRightOptional>
-class TXorWrapper : public TBinaryCodegeneratorNode<TXorWrapper<IsLeftOptional, IsRightOptional>> {
- typedef TBinaryCodegeneratorNode<TXorWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
+class TXorWrapper : public TBinaryCodegeneratorNode<TXorWrapper<IsLeftOptional, IsRightOptional>> {
+ typedef TBinaryCodegeneratorNode<TXorWrapper<IsLeftOptional, IsRightOptional>> TBaseComputation;
public:
TXorWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(left, right, EValueRepresentation::Embedded)
+ : TBaseComputation(left, right, EValueRepresentation::Embedded)
{
Y_UNUSED(mutables);
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& left = this->Left->GetValue(ctx);
- if (IsLeftOptional && !left) {
- return NUdf::TUnboxedValuePod();
- }
-
- const auto& right = this->Right->GetValue(ctx);
- if (IsRightOptional && !right) {
- return NUdf::TUnboxedValuePod();
+ const auto& left = this->Left->GetValue(ctx);
+ if (IsLeftOptional && !left) {
+ return NUdf::TUnboxedValuePod();
}
- const bool res = left.template Get<bool>() != right.template Get<bool>();
- return NUdf::TUnboxedValuePod(res);
+ const auto& right = this->Right->GetValue(ctx);
+ if (IsRightOptional && !right) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ const bool res = left.template Get<bool>() != right.template Get<bool>();
+ return NUdf::TUnboxedValuePod(res);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- if (IsLeftOptional || IsRightOptional) {
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto both = BasicBlock::Create(context, "both", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2, "result", done);
-
- if (IsLeftOptional) {
- const auto left = GetNodeValue(this->Left, ctx, block);
-
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "skip", block);
- result->addIncoming(zero, block);
- BranchInst::Create(done, both, skip, block);
-
- block = both;
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- if (IsRightOptional) {
- const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
- const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "null", block);
- const auto last = SelectInst::Create(null, zero, full, "last", block);
- result->addIncoming(last, block);
- } else {
- const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
- const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
- result->addIncoming(full, block);
- }
- } else if (IsRightOptional) {
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "skip", block);
- result->addIncoming(zero, block);
- BranchInst::Create(done, both, skip, block);
-
- block = both;
- const auto left = GetNodeValue(this->Left, ctx, block);
-
- const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
- const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
- result->addIncoming(full, block);
- }
-
- BranchInst::Create(done, block);
- block = done;
-
- return result;
- } else {
- const auto left = GetNodeValue(this->Left, ctx, block);
- const auto right = GetNodeValue(this->Right, ctx, block);
-
- const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
- const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
- return full;
- }
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ if (IsLeftOptional || IsRightOptional) {
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto both = BasicBlock::Create(context, "both", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2, "result", done);
+
+ if (IsLeftOptional) {
+ const auto left = GetNodeValue(this->Left, ctx, block);
+
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "skip", block);
+ result->addIncoming(zero, block);
+ BranchInst::Create(done, both, skip, block);
+
+ block = both;
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ if (IsRightOptional) {
+ const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
+ const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "null", block);
+ const auto last = SelectInst::Create(null, zero, full, "last", block);
+ result->addIncoming(last, block);
+ } else {
+ const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
+ const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
+ result->addIncoming(full, block);
+ }
+ } else if (IsRightOptional) {
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ const auto skip = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "skip", block);
+ result->addIncoming(zero, block);
+ BranchInst::Create(done, both, skip, block);
+
+ block = both;
+ const auto left = GetNodeValue(this->Left, ctx, block);
+
+ const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
+ const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
+ result->addIncoming(full, block);
+ }
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ return result;
+ } else {
+ const auto left = GetNodeValue(this->Left, ctx, block);
+ const auto right = GetNodeValue(this->Right, ctx, block);
+
+ const auto xorr = BinaryOperator::CreateXor(left, right, "xor", block);
+ const auto full = BinaryOperator::CreateOr(xorr, GetFalse(context), "full", block);
+ return full;
+ }
+ }
+#endif
};
template <bool IsOptional>
-class TNotWrapper : public TDecoratorCodegeneratorNode<TNotWrapper<IsOptional>> {
- typedef TDecoratorCodegeneratorNode<TNotWrapper<IsOptional>> TBaseComputation;
+class TNotWrapper : public TDecoratorCodegeneratorNode<TNotWrapper<IsOptional>> {
+ typedef TDecoratorCodegeneratorNode<TNotWrapper<IsOptional>> TBaseComputation;
public:
- TNotWrapper(IComputationNode* arg)
- : TBaseComputation(arg)
- {}
+ TNotWrapper(IComputationNode* arg)
+ : TBaseComputation(arg)
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& arg) const {
- if (IsOptional && !arg) {
- return NUdf::TUnboxedValuePod();
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& arg) const {
+ if (IsOptional && !arg) {
+ return NUdf::TUnboxedValuePod();
}
- const bool res = !arg.template Get<bool>();
- return NUdf::TUnboxedValuePod(res);
+ const bool res = !arg.template Get<bool>();
+ return NUdf::TUnboxedValuePod(res);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
- const auto xorr = BinaryOperator::CreateXor(arg, ConstantInt::get(arg->getType(), 1), "xor", block);
- const auto result = IsOptional ? SelectInst::Create(IsExists(arg, block), xorr, arg, "sel", block) : static_cast<Value*>(xorr);
- return result;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
+ const auto xorr = BinaryOperator::CreateXor(arg, ConstantInt::get(arg->getType(), 1), "xor", block);
+ const auto result = IsOptional ? SelectInst::Create(IsExists(arg, block), xorr, arg, "sel", block) : static_cast<Value*>(xorr);
+ return result;
+ }
+#endif
};
template <template <bool, bool> class TWrapper>
IComputationNode* WrapLogicalFunction(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- const auto nodeLocator = ctx.NodeLocator;
+ const auto nodeLocator = ctx.NodeLocator;
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto leftType = callable.GetInput(0).GetStaticType();
- const auto rightType = callable.GetInput(1).GetStaticType();
+ const auto leftType = callable.GetInput(0).GetStaticType();
+ const auto rightType = callable.GetInput(1).GetStaticType();
CheckBinaryFunctionArgs(leftType, rightType, true, true);
- const bool isLeftOptional = leftType->IsOptional();
- const bool isRightOptional = rightType->IsOptional();
- const auto left = LocateNode(nodeLocator, callable, 0);
- const auto right = LocateNode(nodeLocator, callable, 1);
+ const bool isLeftOptional = leftType->IsOptional();
+ const bool isRightOptional = rightType->IsOptional();
+ const auto left = LocateNode(nodeLocator, callable, 0);
+ const auto right = LocateNode(nodeLocator, callable, 1);
if (isLeftOptional) {
if (isRightOptional) {
return new TWrapper<true, true>(ctx.Mutables, left, right);
@@ -298,8 +298,8 @@ IComputationNode* WrapLogicalFunction(TCallable& callable, const TComputationNod
}
}
-}
-
+}
+
IComputationNode* WrapAnd(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
return WrapLogicalFunction<TAndWrapper>(callable, ctx);
}
@@ -320,13 +320,13 @@ IComputationNode* WrapNot(TCallable& callable, const TComputationNodeFactoryCont
const auto schemeType = dataType->GetSchemeType();
MKQL_ENSURE(schemeType == NUdf::TDataType<bool>::Id, "Expected bool");
- const auto node = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto node = LocateNode(ctx.NodeLocator, callable, 0);
if (isOptional) {
- return new TNotWrapper<true>(node);
+ return new TNotWrapper<true>(node);
}
else {
- return new TNotWrapper<false>(node);
+ return new TNotWrapper<false>(node);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_lookup.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_lookup.cpp
index 89df552921..732fe3d5fa 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_lookup.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_lookup.cpp
@@ -5,13 +5,13 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TLookupWrapper : public TMutableCodegeneratorPtrNode<TLookupWrapper> {
- typedef TMutableCodegeneratorPtrNode<TLookupWrapper> TBaseComputation;
+namespace {
+
+class TLookupWrapper : public TMutableCodegeneratorPtrNode<TLookupWrapper> {
+ typedef TMutableCodegeneratorPtrNode<TLookupWrapper> TBaseComputation;
public:
- TLookupWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* dict, IComputationNode* key)
- : TBaseComputation(mutables, kind)
+ TLookupWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* dict, IComputationNode* key)
+ : TBaseComputation(mutables, kind)
, Dict(dict)
, Key(key)
{
@@ -21,37 +21,37 @@ public:
return Dict->GetValue(ctx).Lookup(Key->GetValue(ctx));
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- const auto dict = GetNodeValue(Dict, ctx, block);
-
- GetNodeValue(pointer, Key, ctx, block);
- const auto keyp = new LoadInst(pointer, "key", block);
-
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(pointer, dict, ctx.Codegen, block, pointer);
- ValueUnRef(Key->GetRepresentation(), keyp, ctx, block);
- if (Dict->IsTemporaryValue())
- CleanupBoxed(dict, ctx, block);
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(Dict);
- DependsOn(Key);
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ const auto dict = GetNodeValue(Dict, ctx, block);
+
+ GetNodeValue(pointer, Key, ctx, block);
+ const auto keyp = new LoadInst(pointer, "key", block);
+
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(pointer, dict, ctx.Codegen, block, pointer);
+ ValueUnRef(Key->GetRepresentation(), keyp, ctx, block);
+ if (Dict->IsTemporaryValue())
+ CleanupBoxed(dict, ctx, block);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Dict);
+ DependsOn(Key);
}
IComputationNode* const Dict;
IComputationNode* const Key;
};
-}
-
+}
+
IComputationNode* WrapLookup(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto dict = LocateNode(ctx.NodeLocator, callable, 0);
- const auto key = LocateNode(ctx.NodeLocator, callable, 1);
- return new TLookupWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), dict, key);
+ const auto dict = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto key = LocateNode(ctx.NodeLocator, callable, 1);
+ return new TLookupWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), dict, key);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_map.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_map.cpp
index f0524a8e36..04997bd1f1 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_map.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_map.cpp
@@ -6,119 +6,119 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TFlowMapWrapper : public TStatelessFlowCodegeneratorNode<TFlowMapWrapper> {
- typedef TStatelessFlowCodegeneratorNode<TFlowMapWrapper> TBaseComputation;
-public:
- TFlowMapWrapper(EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(flow, kind)
- , Flow(flow)
- , Item(item)
- , NewItem(newItem)
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+namespace {
+
+class TFlowMapWrapper : public TStatelessFlowCodegeneratorNode<TFlowMapWrapper> {
+ typedef TStatelessFlowCodegeneratorNode<TFlowMapWrapper> TBaseComputation;
+public:
+ TFlowMapWrapper(EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(flow, kind)
+ , Flow(flow)
+ , Item(item)
+ , NewItem(newItem)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
return item;
- } else {
- Item->SetValue(ctx, std::move(item));
- }
- return NewItem->GetValue(ctx);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto result = PHINode::Create(item->getType(), 2, "result", pass);
- result->addIncoming(item, block);
-
- BranchInst::Create(pass, work, IsSpecial(item, block), block);
-
- block = work;
- codegenItem->CreateSetValue(ctx, block, item);
- const auto out = GetNodeValue(NewItem, ctx, block);
- result->addIncoming(out, block);
- BranchInst::Create(pass, block);
-
- block = pass;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Item);
- DependsOn(flow, NewItem);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationNode* const NewItem;
-};
-
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ }
+ return NewItem->GetValue(ctx);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto result = PHINode::Create(item->getType(), 2, "result", pass);
+ result->addIncoming(item, block);
+
+ BranchInst::Create(pass, work, IsSpecial(item, block), block);
+
+ block = work;
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto out = GetNodeValue(NewItem, ctx, block);
+ result->addIncoming(out, block);
+ BranchInst::Create(pass, block);
+
+ block = pass;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Item);
+ DependsOn(flow, NewItem);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationNode* const NewItem;
+};
+
template <bool IsStream>
-class TBaseMapWrapper {
-protected:
+class TBaseMapWrapper {
+protected:
class TListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
- : TComputationValue<TIterator>(memInfo)
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* newItem)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
+ , Iter(std::move(iter))
, Item(item)
, NewItem(newItem)
{}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Iter.Next(Item->RefValue(CompCtx))) {
- return false;
- }
-
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Iter.Next(Item->RefValue(CompCtx))) {
+ return false;
+ }
+
value = NewItem->GetValue(CompCtx);
- return true;
- }
-
+ return true;
+ }
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Iter;
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
};
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, IComputationNode* newItem)
: TCustomListValue(memInfo)
, CompCtx(compCtx)
- , List(std::move(list))
+ , List(std::move(list))
, Item(item)
, NewItem(newItem)
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
- }
-
- ui64 GetListLength() const final {
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItem);
+ }
+
+ ui64 GetListLength() const final {
if (!Length) {
Length = List.GetListLength();
}
- return *Length;
+ return *Length;
}
- bool HasListItems() const final {
+ bool HasListItems() const final {
if (!HasItems) {
HasItems = List.HasListItems();
}
@@ -126,13 +126,13 @@ protected:
return *HasItems;
}
- bool HasFastListLength() const final {
+ bool HasFastListLength() const final {
return List.HasFastListLength();
}
-
+
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
};
@@ -140,32 +140,32 @@ protected:
public:
using TBase = TComputationValue<TStreamValue>;
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& stream, IComputationExternalNode* item, IComputationNode* newItem)
: TBase(memInfo)
, CompCtx(compCtx)
- , Stream(std::move(stream))
+ , Stream(std::move(stream))
, Item(item)
, NewItem(newItem)
{
}
- private:
- ui32 GetTraverseCount() const final {
- return 1U;
+ private:
+ ui32 GetTraverseCount() const final {
+ return 1U;
}
- NUdf::TUnboxedValue GetTraverseItem(ui32) const final {
+ NUdf::TUnboxedValue GetTraverseItem(ui32) const final {
return Stream;
}
- NUdf::TUnboxedValue Save() const final {
- return NUdf::TUnboxedValuePod::Zero();
+ NUdf::TUnboxedValue Save() const final {
+ return NUdf::TUnboxedValuePod::Zero();
}
- void Load(const NUdf::TStringRef&) final {}
+ void Load(const NUdf::TStringRef&) final {}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- const auto status = Stream.Fetch(Item->RefValue(CompCtx));
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ const auto status = Stream.Fetch(Item->RefValue(CompCtx));
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -175,281 +175,281 @@ protected:
}
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Stream;
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
};
- TBaseMapWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : List(list), Item(item), NewItem(newItem)
- {}
-
-#ifndef MKQL_DISABLE_CODEGEN
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ TBaseMapWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : List(list), Item(item), NewItem(newItem)
+ {}
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
-
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
-
- BranchInst::Create(done, good, icmp, block);
- block = good;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, NewItem, ctx, block);
-
- BranchInst::Create(done, block);
- block = done;
-
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block):
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
+
+ BranchInst::Create(done, good, icmp, block);
+ block = good;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, NewItem, ctx, block);
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
using TMapPtr = std::conditional_t<IsStream, TStreamCodegenValueStateless::TFetchPtr, TListCodegenValue::TNextPtr>;
-
- Function* MapFunc = nullptr;
-
- TMapPtr Map = nullptr;
-#endif
-
+
+ Function* MapFunc = nullptr;
+
+ TMapPtr Map = nullptr;
+#endif
+
IComputationNode* const List;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const NewItem;
};
-class TStreamMapWrapper : public TCustomValueCodegeneratorNode<TStreamMapWrapper>, private TBaseMapWrapper<true> {
- typedef TCustomValueCodegeneratorNode<TStreamMapWrapper> TBaseComputation;
- typedef TBaseMapWrapper<true> TBaseWrapper;
-public:
- TStreamMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Map)
- return ctx.HolderFactory.Create<TStreamCodegenValueStateless>(Map, &ctx, List->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), Item, NewItem);
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- Own(Item);
- DependsOn(NewItem);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(MapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (MapFunc)
- Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
- }
-#endif
-};
-
-class TListMapWrapper : public TBothWaysCodegeneratorNode<TListMapWrapper>, private TBaseMapWrapper<false> {
- typedef TBothWaysCodegeneratorNode<TListMapWrapper> TBaseComputation;
- typedef TBaseMapWrapper<false> TBaseWrapper;
-public:
- TListMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
- : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- auto size = list.GetListLength();
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
- while (size--) {
- Item->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
- *items++ = NewItem->GetValue(ctx);
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), Item, NewItem);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<TListCodegenValue>(Map, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto map = PHINode::Create(list->getType(), 2U, "map", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, size, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- index->addIncoming(ConstantInt::get(size->getType(), 0), block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
-
- BranchInst::Create(next, stop, more, block);
-
- block = next;
- const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto item = new LoadInst(src, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
- GetNodeValue(dst, NewItem, ctx, block);
-
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
- index->addIncoming(plus, block);
- BranchInst::Create(loop, block);
-
- block = stop;
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- map->addIncoming(array, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListMapWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- map->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- map->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return map;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- Own(Item);
- DependsOn(NewItem);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListMapWrapper>::GenerateFunctions(codegen);
- MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(MapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListMapWrapper>::FinalizeFunctions(codegen);
- if (MapFunc)
- Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
- }
-#endif
-};
-
-}
-
+class TStreamMapWrapper : public TCustomValueCodegeneratorNode<TStreamMapWrapper>, private TBaseMapWrapper<true> {
+ typedef TCustomValueCodegeneratorNode<TStreamMapWrapper> TBaseComputation;
+ typedef TBaseMapWrapper<true> TBaseWrapper;
+public:
+ TStreamMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Map)
+ return ctx.HolderFactory.Create<TStreamCodegenValueStateless>(Map, &ctx, List->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<TStreamValue>(ctx, List->GetValue(ctx), Item, NewItem);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ Own(Item);
+ DependsOn(NewItem);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(MapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (MapFunc)
+ Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
+ }
+#endif
+};
+
+class TListMapWrapper : public TBothWaysCodegeneratorNode<TListMapWrapper>, private TBaseMapWrapper<false> {
+ typedef TBothWaysCodegeneratorNode<TListMapWrapper> TBaseComputation;
+ typedef TBaseMapWrapper<false> TBaseWrapper;
+public:
+ TListMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* newItem)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, newItem)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ auto size = list.GetListLength();
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
+ while (size--) {
+ Item->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
+ *items++ = NewItem->GetValue(ctx);
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), Item, NewItem);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<TListCodegenValue>(Map, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto map = PHINode::Create(list->getType(), 2U, "map", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, size, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ index->addIncoming(ConstantInt::get(size->getType(), 0), block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
+
+ BranchInst::Create(next, stop, more, block);
+
+ block = next;
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto item = new LoadInst(src, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {index}, "dst", block);
+ GetNodeValue(dst, NewItem, ctx, block);
+
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ map->addIncoming(array, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListMapWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ map->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ map->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return map;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ Own(Item);
+ DependsOn(NewItem);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListMapWrapper>::GenerateFunctions(codegen);
+ MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(MapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListMapWrapper>::FinalizeFunctions(codegen);
+ if (MapFunc)
+ Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
+ }
+#endif
+};
+
+}
+
IComputationNode* WrapMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args, got " << callable.GetInputsCount());
- const auto type = callable.GetType()->GetReturnType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto newItem = LocateNode(ctx.NodeLocator, callable, 2);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- if (type->IsFlow()) {
- return new TFlowMapWrapper(GetValueRepresentation(type), flow, itemArg, newItem);
- } else if (type->IsStream()) {
- return new TStreamMapWrapper(ctx.Mutables, flow, itemArg, newItem);
- } else if (type->IsList()) {
- return new TListMapWrapper(ctx.Mutables, flow, itemArg, newItem);
+ const auto type = callable.GetType()->GetReturnType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto newItem = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ if (type->IsFlow()) {
+ return new TFlowMapWrapper(GetValueRepresentation(type), flow, itemArg, newItem);
+ } else if (type->IsStream()) {
+ return new TStreamMapWrapper(ctx.Mutables, flow, itemArg, newItem);
+ } else if (type->IsList()) {
+ return new TListMapWrapper(ctx.Mutables, flow, itemArg, newItem);
}
-
- THROW yexception() << "Expected flow, list or stream.";
+
+ THROW yexception() << "Expected flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_map_join.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_map_join.cpp
index 203f54ce22..613958f74b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_map_join.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_map_join.cpp
@@ -1,4 +1,4 @@
-#include "mkql_map_join.h"
+#include "mkql_map_join.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
@@ -11,164 +11,164 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsTuple>
-class TWideMapJoinBase {
-protected:
- TWideMapJoinBase(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
- IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
- : LeftKeyConverters(std::move(leftKeyConverters))
- , DictType(dictType)
- , OutputRepresentations(std::move(outputRepresentations))
- , LeftKeyColumns(std::move(leftKeyColumns))
- , LeftRenames(std::move(leftRenames))
- , RightRenames(std::move(rightRenames))
- , UsedInputs(GetUsedInputs())
- , Flow(flow)
- , Dict(dict)
- , KeyTuple(mutables)
- , Inputs(UsedInputs.size())
- , Fields(MakeFields(inputWidth))
- {}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* GenMakeKeysTuple(Value* keysPtr, const ICodegeneratorInlineWideNode::TGettersList& getters, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
- const auto keys = getters[LeftKeyColumns.front()](ctx, block);
- new StoreInst(keys, keysPtr, block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, keys, zero, "check", block);
- return check;
- }
-
- Value* GenMakeKeysTuple(Value* keysPtr, const ICodegeneratorInlineWideNode::TGettersList& getters, Value* itemsPtr, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto idxType = Type::getInt32Ty(context);
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
-
- const auto keys = KeyTuple.GenNewArray(LeftKeyColumns.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(Type::getInt1Ty(context), (LeftKeyColumns.size() + 1U) << 1U , "result", done);
-
- const auto keyType = AS_TYPE(TTupleType, DictType->GetKeyType());
- for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
- const auto index = ConstantInt::get(idxType, i);
- const auto ptr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), index}, (TString("ptr_") += ToString(i)).c_str(), block);
- const auto elem = getters[LeftKeyColumns[i]](ctx, block);
- const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator);
- const auto conv = converter ? converter(reinterpret_cast<Value *const *>(&elem), ctx, block) : elem;
-
- result->addIncoming(ConstantInt::getTrue(context), block);
- const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
- BranchInst::Create(done, next, check, block);
-
- block = next;
-
- new StoreInst(conv, ptr, block);
- ValueAddRef(GetValueRepresentation(keyType->GetElementType(i)), conv, ctx, block);
- }
-
- result->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(done, block);
-
- block = done;
- new StoreInst(keys, keysPtr, block);
- return result;
- }
-
- void GenFillLeftStruct(const ICodegeneratorInlineWideNode::TGettersList& input, ICodegeneratorInlineWideNode::TGettersList& output) const {
- for (auto i = 0U; i < LeftRenames.size(); ++i) {
- const auto& src = input[LeftRenames[i]];
- output[LeftRenames[++i]] = src;
- }
- }
-
- std::array<Value*, 2U> GenFillOutput(ui32 idx, const TCodegenContext& ctx, const ICodegeneratorInlineWideNode::TGettersList& input, ICodegeneratorInlineWideNode::TGettersList& output) const {
- GenFillLeftStruct(input, output);
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valueType, 0);
-
- auto width = 0U;
- for (auto i = 0U; i < RightRenames.size(); ++++i) {
- width = std::max(width, RightRenames[i]);
- }
-
- const auto arrayType = ArrayType::get(valueType, ++width);
- const auto atTop = &ctx.Func->getEntryBlock().back();
-
- const auto stub = new AllocaInst(arrayType, 0U, "stub", atTop);
-
- Value* zeros = UndefValue::get(arrayType);
- for (auto i = 0U; i < width; ++i) {
- zeros = InsertValueInst::Create(zeros, zero, {i}, (TString("zero_") += ToString(i)).c_str(), atTop);
- }
-
- new StoreInst(zeros, stub, atTop);
-
- const auto item = new AllocaInst(valueType, 0U, "item", atTop);
- const auto placeholder = new AllocaInst(stub->getType(), 0U, "placeholder", atTop);
- const auto pointer = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "pointer", atTop);
-
- for (auto i = 0U; i < RightRenames.size(); ++i) {
- const auto from = RightRenames[i];
- const auto to = RightRenames[++i];
- const auto kind = OutputRepresentations[to];
- output[to] = [from, kind, item, pointer, placeholder, arrayType](const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto index = ConstantInt::get(Type::getInt32Ty(context), from);
- const auto elements = new LoadInst(placeholder, "elements", block);
-
- const auto pointerType = PointerType::getUnqual(arrayType);
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(pointerType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto out = PHINode::Create(pointer->getType(), 2U, "out", done);
-
- BranchInst::Create(slow, fast, null, block);
-
- block = fast;
-
- const auto ptr = GetElementPtrInst::CreateInBounds(elements, {ConstantInt::get(Type::getInt32Ty(context), 0), index}, "ptr", block);
- out->addIncoming(ptr, block);
-
- BranchInst::Create(done, block);
-
- block = slow;
-
- const auto value = new LoadInst(pointer, "value", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, value, ctx.Codegen, block, index);
- ValueRelease(kind, item, ctx, block);
- out->addIncoming(item, block);
-
- BranchInst::Create(done, block);
-
- block = done;
-
- const auto load = new LoadInst(out, "load", block);
- return load;
- };
- }
-
- return {{placeholder, stub}};
- }
-#endif
- NUdf::TUnboxedValue MakeKeysTuple(TComputationContext& ctx) const {
- if constexpr (IsTuple) {
- NUdf::TUnboxedValue* items = nullptr;
- const auto keys = KeyTuple.NewArray(ctx, LeftKeyColumns.size(), items);
+namespace {
+
+template<bool IsTuple>
+class TWideMapJoinBase {
+protected:
+ TWideMapJoinBase(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
+ IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
+ : LeftKeyConverters(std::move(leftKeyConverters))
+ , DictType(dictType)
+ , OutputRepresentations(std::move(outputRepresentations))
+ , LeftKeyColumns(std::move(leftKeyColumns))
+ , LeftRenames(std::move(leftRenames))
+ , RightRenames(std::move(rightRenames))
+ , UsedInputs(GetUsedInputs())
+ , Flow(flow)
+ , Dict(dict)
+ , KeyTuple(mutables)
+ , Inputs(UsedInputs.size())
+ , Fields(MakeFields(inputWidth))
+ {}
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* GenMakeKeysTuple(Value* keysPtr, const ICodegeneratorInlineWideNode::TGettersList& getters, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+ const auto keys = getters[LeftKeyColumns.front()](ctx, block);
+ new StoreInst(keys, keysPtr, block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, keys, zero, "check", block);
+ return check;
+ }
+
+ Value* GenMakeKeysTuple(Value* keysPtr, const ICodegeneratorInlineWideNode::TGettersList& getters, Value* itemsPtr, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto idxType = Type::getInt32Ty(context);
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+
+ const auto keys = KeyTuple.GenNewArray(LeftKeyColumns.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt1Ty(context), (LeftKeyColumns.size() + 1U) << 1U , "result", done);
+
+ const auto keyType = AS_TYPE(TTupleType, DictType->GetKeyType());
+ for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
+ const auto index = ConstantInt::get(idxType, i);
+ const auto ptr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), index}, (TString("ptr_") += ToString(i)).c_str(), block);
+ const auto elem = getters[LeftKeyColumns[i]](ctx, block);
+ const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator);
+ const auto conv = converter ? converter(reinterpret_cast<Value *const *>(&elem), ctx, block) : elem;
+
+ result->addIncoming(ConstantInt::getTrue(context), block);
+ const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
+ BranchInst::Create(done, next, check, block);
+
+ block = next;
+
+ new StoreInst(conv, ptr, block);
+ ValueAddRef(GetValueRepresentation(keyType->GetElementType(i)), conv, ctx, block);
+ }
+
+ result->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ new StoreInst(keys, keysPtr, block);
+ return result;
+ }
+
+ void GenFillLeftStruct(const ICodegeneratorInlineWideNode::TGettersList& input, ICodegeneratorInlineWideNode::TGettersList& output) const {
+ for (auto i = 0U; i < LeftRenames.size(); ++i) {
+ const auto& src = input[LeftRenames[i]];
+ output[LeftRenames[++i]] = src;
+ }
+ }
+
+ std::array<Value*, 2U> GenFillOutput(ui32 idx, const TCodegenContext& ctx, const ICodegeneratorInlineWideNode::TGettersList& input, ICodegeneratorInlineWideNode::TGettersList& output) const {
+ GenFillLeftStruct(input, output);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ auto width = 0U;
+ for (auto i = 0U; i < RightRenames.size(); ++++i) {
+ width = std::max(width, RightRenames[i]);
+ }
+
+ const auto arrayType = ArrayType::get(valueType, ++width);
+ const auto atTop = &ctx.Func->getEntryBlock().back();
+
+ const auto stub = new AllocaInst(arrayType, 0U, "stub", atTop);
+
+ Value* zeros = UndefValue::get(arrayType);
+ for (auto i = 0U; i < width; ++i) {
+ zeros = InsertValueInst::Create(zeros, zero, {i}, (TString("zero_") += ToString(i)).c_str(), atTop);
+ }
+
+ new StoreInst(zeros, stub, atTop);
+
+ const auto item = new AllocaInst(valueType, 0U, "item", atTop);
+ const auto placeholder = new AllocaInst(stub->getType(), 0U, "placeholder", atTop);
+ const auto pointer = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "pointer", atTop);
+
+ for (auto i = 0U; i < RightRenames.size(); ++i) {
+ const auto from = RightRenames[i];
+ const auto to = RightRenames[++i];
+ const auto kind = OutputRepresentations[to];
+ output[to] = [from, kind, item, pointer, placeholder, arrayType](const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto index = ConstantInt::get(Type::getInt32Ty(context), from);
+ const auto elements = new LoadInst(placeholder, "elements", block);
+
+ const auto pointerType = PointerType::getUnqual(arrayType);
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(pointerType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto out = PHINode::Create(pointer->getType(), 2U, "out", done);
+
+ BranchInst::Create(slow, fast, null, block);
+
+ block = fast;
+
+ const auto ptr = GetElementPtrInst::CreateInBounds(elements, {ConstantInt::get(Type::getInt32Ty(context), 0), index}, "ptr", block);
+ out->addIncoming(ptr, block);
+
+ BranchInst::Create(done, block);
+
+ block = slow;
+
+ const auto value = new LoadInst(pointer, "value", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, value, ctx.Codegen, block, index);
+ ValueRelease(kind, item, ctx, block);
+ out->addIncoming(item, block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ const auto load = new LoadInst(out, "load", block);
+ return load;
+ };
+ }
+
+ return {{placeholder, stub}};
+ }
+#endif
+ NUdf::TUnboxedValue MakeKeysTuple(TComputationContext& ctx) const {
+ if constexpr (IsTuple) {
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto keys = KeyTuple.NewArray(ctx, LeftKeyColumns.size(), items);
if (!LeftKeyColumns.empty()) {
Y_VERIFY(items);
for (auto i = 0U; i < LeftKeyColumns.size(); ++i) {
@@ -177,462 +177,462 @@ protected:
if (!(*items++ = converter ? converter(value) : *value))
return NUdf::TUnboxedValuePod();
}
- }
-
- return keys;
- } else {
- const auto value = Fields[LeftKeyColumns.front()];
- const auto converter = LeftKeyConverters.front().Function;
- return converter ? converter(value) : *value;
- }
- }
-
- void FillLeftStruct(NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < LeftRenames.size(); ++i) {
- const auto prevIndex = LeftRenames[i];
- const auto newIndex = LeftRenames[++i];
- if (const auto out = output[newIndex])
- *out = *Fields[prevIndex];
- }
- }
-
- void FillRightStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue*const* output) const {
- if (const auto ptr = structObj.GetElements()) {
- for (auto i = 0U; i < RightRenames.size(); ++i) {
- const auto prevIndex = RightRenames[i];
- const auto newIndex = RightRenames[++i];
- if (const auto out = output[newIndex])
- *out = ptr[prevIndex];
- }
- } else {
- for (auto i = 0U; i < RightRenames.size(); ++i) {
- const auto prevIndex = RightRenames[i];
- const auto newIndex = RightRenames[++i];
- if (const auto out = output[newIndex])
- *out = structObj.GetElement(prevIndex);
- }
- }
- }
-
- void NullRightStruct(NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < RightRenames.size(); ++i) {
- const auto newIndex = RightRenames[++i];
- if (const auto out = output[newIndex])
- *out = NUdf::TUnboxedValuePod();
- }
- }
-
- std::set<ui32> GetUsedInputs() const {
- std::set<ui32> unique(LeftKeyColumns.cbegin(), LeftKeyColumns.cend());
- for (auto i = 0U; i < LeftRenames.size(); i += 2U)
- unique.emplace(LeftRenames[i]);
- return unique;
- }
-
- std::vector<NUdf::TUnboxedValue*> MakeFields(ui32 width) const {
- std::vector<NUdf::TUnboxedValue*> fields(width, nullptr);
- auto it = Inputs.begin();
- for (const auto idx : UsedInputs)
- fields[idx] = &*it++;
- return fields;
- }
-
- const std::vector<TFunctionDescriptor> LeftKeyConverters;
- TDictType* const DictType;
- const std::vector<EValueRepresentation> OutputRepresentations;
- const std::vector<ui32> LeftKeyColumns;
- const std::vector<ui32> LeftRenames;
- const std::vector<ui32> RightRenames;
- const std::set<ui32> UsedInputs;
- IComputationWideFlowNode* const Flow;
- IComputationNode* const Dict;
-
- const TContainerCacheOnContext KeyTuple;
-
- mutable std::vector<NUdf::TUnboxedValue> Inputs;
- const std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-template<bool WithoutRight, bool RightRequired, bool IsTuple>
-class TWideMapJoinWrapper : public TWideMapJoinBase<IsTuple>, public TStatefulWideFlowCodegeneratorNode<TWideMapJoinWrapper<WithoutRight, RightRequired, IsTuple>> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideMapJoinWrapper<WithoutRight, RightRequired, IsTuple>>;
-public:
- TWideMapJoinWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
- IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
- : TWideMapJoinBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations)
- , std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict, inputWidth)
- , TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& lookup, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- const auto dict = this->Dict->GetValue(ctx);
- do {
- if (const auto res = this->Flow->FetchValues(ctx, this->Fields.data()); EFetchResult::One != res)
- return res;
-
- const auto keys = this->MakeKeysTuple(ctx);
-
- if constexpr (WithoutRight) {
- if ((keys && dict.Contains(keys)) == RightRequired)
- break;
- else
- continue;
- } else if (keys) {
- if (lookup = dict.Lookup(keys)) {
- this->FillLeftStruct(output);
- this->FillRightStruct(lookup, output);
- return EFetchResult::One;
- }
- }
- } while (RightRequired || WithoutRight);
-
- this->FillLeftStruct(output);
- this->NullRightStruct(output);
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* lookupPtr, BasicBlock*& block) const {
- MKQL_ENSURE(!this->Dict->IsTemporaryValue(), "Dict can't be temporary");
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto resultType = Type::getInt32Ty(context);
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(zero, keysPtr, block);
-
- const auto dict = GetNodeValue(this->Dict, ctx, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto result = PHINode::Create(resultType, RightRequired ? 2U : 3U, "result", stop);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto current = GetNodeValues(this->Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, current.first, ConstantInt::get(resultType, 0), "special", block);
-
- result->addIncoming(current.first, block);
-
- BranchInst::Create(stop, next, special, block);
-
- block = next;
-
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current.second, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current.second, ctx, block);
-
- ICodegeneratorInlineWideNode::TGettersList getters(this->OutputRepresentations.size());
- if constexpr (WithoutRight) {
- this->GenFillLeftStruct(current.second, getters);
-
- if (RightRequired) {
- BranchInst::Create(loop, step, none, block);
- } else {
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
- BranchInst::Create(stop, step, none, block);
- }
-
- block = step;
-
- const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keysPtr);
-
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- if constexpr (RightRequired) {
- BranchInst::Create(stop, loop, cont, block);
- } else {
- BranchInst::Create(loop, stop, cont, block);
- }
- } else {
- const auto output = this->GenFillOutput(static_cast<const IComputationNode*>(this)->GetIndex(), ctx, current.second, getters);
-
- const auto left = RightRequired ? nullptr : BasicBlock::Create(context, "left", ctx.Func);
-
- if constexpr (RightRequired)
- BranchInst::Create(loop, step, none, block);
- else
- BranchInst::Create(left, step, none, block);
-
- block = step;
-
- ValueUnRef(EValueRepresentation::Boxed, lookupPtr, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(lookupPtr, dict, ctx.Codegen, block, keysPtr);
-
- const auto lookup = new LoadInst(lookupPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- if constexpr (RightRequired)
- BranchInst::Create(full, loop, ok, block);
- else {
- BranchInst::Create(full, left, ok, block);
-
- block = left;
-
- new StoreInst(std::get<1U>(output), std::get<0U>(output), block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- BranchInst::Create(stop, block);
- }
-
- {
- block = full;
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(std::get<1U>(output)->getType(), lookup, ctx.Codegen, block);
- new StoreInst(elements, std::get<0U>(output), block);
-
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- BranchInst::Create(stop, block);
- }
- }
-
- block = stop;
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(this->Flow))
- this->DependsOn(flow, this->Dict);
- }
-};
-
-template<bool RightRequired, bool IsTuple>
-class TWideMultiMapJoinWrapper : public TWideMapJoinBase<IsTuple>, public TPairStateWideFlowCodegeneratorNode<TWideMultiMapJoinWrapper<RightRequired, IsTuple>> {
-using TBaseComputation = TPairStateWideFlowCodegeneratorNode<TWideMultiMapJoinWrapper<RightRequired, IsTuple>>;
-public:
- TWideMultiMapJoinWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
- IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
- : TWideMapJoinBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations)
- , std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict, inputWidth)
- , TBaseComputation(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Boxed)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& iter, NUdf::TUnboxedValue& item, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto iterator = std::move(iter);;) {
- if (iterator.HasValue()) {
- if (iterator.Next(item)) {
- this->FillLeftStruct(output);
- this->FillRightStruct(item, output);
- iter = std::move(iterator);
- return EFetchResult::One;
- }
- }
-
- for (const auto& dict = this->Dict->GetValue(ctx);;) {
- if (const auto res = this->Flow->FetchValues(ctx, this->Fields.data()); EFetchResult::One != res)
- return res;
-
- if (const auto keys = this->MakeKeysTuple(ctx)) {
- if (const auto lookup = dict.Lookup(keys)) {
- iterator = lookup.GetListIterator();
- break;
- }
- }
-
- if constexpr (!RightRequired) {
- this->FillLeftStruct(output);
- this->NullRightStruct(output);
- return EFetchResult::One;
- }
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* iteraratorPtr, Value* itemPtr, BasicBlock*& block) const {
- MKQL_ENSURE(!this->Dict->IsTemporaryValue(), "Dict can't be temporary");
- auto& context = ctx.Codegen->GetContext();
-
- const auto resultType = Type::getInt32Ty(context);
- const auto valueType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
-
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto subiter = new LoadInst(iteraratorPtr, "subiter", block);
-
- const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
- const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
- const auto part = BasicBlock::Create(context, "part", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
- const auto left = RightRequired ? nullptr : BasicBlock::Create(context, "left", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto result = PHINode::Create(resultType, RightRequired ? 2U : 3U, "result", exit);
-
- ICodegeneratorInlineWideNode::TGettersList getters(this->OutputRepresentations.size());
-
- BranchInst::Create(hasi, part, HasValue(subiter, block), block);
-
- block = part;
- const auto dict = GetNodeValue(this->Dict, ctx, block);
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto current = GetNodeValues(this->Flow, ctx, block);
-
- const auto output = this->GenFillOutput(static_cast<const IComputationNode*>(this)->GetIndex() + 1U, ctx, current.second, getters);
-
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, current.first, ConstantInt::get(resultType, 0), "special", block);
-
- result->addIncoming(current.first, block);
-
- BranchInst::Create(exit, next, special, block);
-
- block = hasi;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, ctx.Codegen, block, itemPtr);
- BranchInst::Create(full, skip, status, block);
-
- {
- block = full;
-
- const auto item = new LoadInst(itemPtr, "item", block);
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(std::get<1U>(output)->getType(), item, ctx.Codegen, block);
- new StoreInst(elements, std::get<0U>(output), block);
-
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- BranchInst::Create(exit, block);
- }
-
- {
- block = skip;
- UnRefBoxed(subiter, ctx, block);
- new StoreInst(zero, iteraratorPtr, block);
- BranchInst::Create(part, block);
- }
-
- block = next;
-
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current.second, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current.second, ctx, block);
-
- if constexpr (RightRequired)
- BranchInst::Create(loop, step, none, block);
- else
- BranchInst::Create(left, step, none, block);
-
- block = step;
-
- ValueUnRef(EValueRepresentation::Boxed, itemPtr, ctx, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
-
- const auto lookup = new LoadInst(itemPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- if constexpr (RightRequired)
- BranchInst::Create(fill, loop, ok, block);
- else {
- BranchInst::Create(fill, left, ok, block);
-
- block = left;
-
- new StoreInst(std::get<1U>(output), std::get<0U>(output), block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- BranchInst::Create(exit, block);
- }
-
- {
- block = fill;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteraratorPtr, lookup, ctx.Codegen, block);
- BranchInst::Create(work, block);
- }
-
- block = exit;
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(this->Flow))
- this->DependsOn(flow, this->Dict);
- }
-};
-
-template<bool IsTuple>
-class TMapJoinCoreWrapperBase {
-protected:
- TMapJoinCoreWrapperBase(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames, IComputationNode* stream, IComputationNode* dict)
- : LeftKeyConverters(std::move(leftKeyConverters))
- , DictType(dictType)
- , OutputRepresentations(std::move(outputRepresentations))
- , LeftKeyColumns(std::move(leftKeyColumns))
- , LeftRenames(std::move(leftRenames))
- , RightRenames(std::move(rightRenames))
- , Stream(stream)
- , Dict(dict)
- , ResStruct(mutables)
- , KeyTuple(mutables)
- {}
-
- static void FillStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items, const std::vector<ui32>& renames) {
+ }
+
+ return keys;
+ } else {
+ const auto value = Fields[LeftKeyColumns.front()];
+ const auto converter = LeftKeyConverters.front().Function;
+ return converter ? converter(value) : *value;
+ }
+ }
+
+ void FillLeftStruct(NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < LeftRenames.size(); ++i) {
+ const auto prevIndex = LeftRenames[i];
+ const auto newIndex = LeftRenames[++i];
+ if (const auto out = output[newIndex])
+ *out = *Fields[prevIndex];
+ }
+ }
+
+ void FillRightStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue*const* output) const {
+ if (const auto ptr = structObj.GetElements()) {
+ for (auto i = 0U; i < RightRenames.size(); ++i) {
+ const auto prevIndex = RightRenames[i];
+ const auto newIndex = RightRenames[++i];
+ if (const auto out = output[newIndex])
+ *out = ptr[prevIndex];
+ }
+ } else {
+ for (auto i = 0U; i < RightRenames.size(); ++i) {
+ const auto prevIndex = RightRenames[i];
+ const auto newIndex = RightRenames[++i];
+ if (const auto out = output[newIndex])
+ *out = structObj.GetElement(prevIndex);
+ }
+ }
+ }
+
+ void NullRightStruct(NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < RightRenames.size(); ++i) {
+ const auto newIndex = RightRenames[++i];
+ if (const auto out = output[newIndex])
+ *out = NUdf::TUnboxedValuePod();
+ }
+ }
+
+ std::set<ui32> GetUsedInputs() const {
+ std::set<ui32> unique(LeftKeyColumns.cbegin(), LeftKeyColumns.cend());
+ for (auto i = 0U; i < LeftRenames.size(); i += 2U)
+ unique.emplace(LeftRenames[i]);
+ return unique;
+ }
+
+ std::vector<NUdf::TUnboxedValue*> MakeFields(ui32 width) const {
+ std::vector<NUdf::TUnboxedValue*> fields(width, nullptr);
+ auto it = Inputs.begin();
+ for (const auto idx : UsedInputs)
+ fields[idx] = &*it++;
+ return fields;
+ }
+
+ const std::vector<TFunctionDescriptor> LeftKeyConverters;
+ TDictType* const DictType;
+ const std::vector<EValueRepresentation> OutputRepresentations;
+ const std::vector<ui32> LeftKeyColumns;
+ const std::vector<ui32> LeftRenames;
+ const std::vector<ui32> RightRenames;
+ const std::set<ui32> UsedInputs;
+ IComputationWideFlowNode* const Flow;
+ IComputationNode* const Dict;
+
+ const TContainerCacheOnContext KeyTuple;
+
+ mutable std::vector<NUdf::TUnboxedValue> Inputs;
+ const std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+template<bool WithoutRight, bool RightRequired, bool IsTuple>
+class TWideMapJoinWrapper : public TWideMapJoinBase<IsTuple>, public TStatefulWideFlowCodegeneratorNode<TWideMapJoinWrapper<WithoutRight, RightRequired, IsTuple>> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideMapJoinWrapper<WithoutRight, RightRequired, IsTuple>>;
+public:
+ TWideMapJoinWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
+ IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
+ : TWideMapJoinBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations)
+ , std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict, inputWidth)
+ , TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& lookup, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ const auto dict = this->Dict->GetValue(ctx);
+ do {
+ if (const auto res = this->Flow->FetchValues(ctx, this->Fields.data()); EFetchResult::One != res)
+ return res;
+
+ const auto keys = this->MakeKeysTuple(ctx);
+
+ if constexpr (WithoutRight) {
+ if ((keys && dict.Contains(keys)) == RightRequired)
+ break;
+ else
+ continue;
+ } else if (keys) {
+ if (lookup = dict.Lookup(keys)) {
+ this->FillLeftStruct(output);
+ this->FillRightStruct(lookup, output);
+ return EFetchResult::One;
+ }
+ }
+ } while (RightRequired || WithoutRight);
+
+ this->FillLeftStruct(output);
+ this->NullRightStruct(output);
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* lookupPtr, BasicBlock*& block) const {
+ MKQL_ENSURE(!this->Dict->IsTemporaryValue(), "Dict can't be temporary");
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto resultType = Type::getInt32Ty(context);
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(zero, keysPtr, block);
+
+ const auto dict = GetNodeValue(this->Dict, ctx, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto result = PHINode::Create(resultType, RightRequired ? 2U : 3U, "result", stop);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto current = GetNodeValues(this->Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, current.first, ConstantInt::get(resultType, 0), "special", block);
+
+ result->addIncoming(current.first, block);
+
+ BranchInst::Create(stop, next, special, block);
+
+ block = next;
+
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current.second, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current.second, ctx, block);
+
+ ICodegeneratorInlineWideNode::TGettersList getters(this->OutputRepresentations.size());
+ if constexpr (WithoutRight) {
+ this->GenFillLeftStruct(current.second, getters);
+
+ if (RightRequired) {
+ BranchInst::Create(loop, step, none, block);
+ } else {
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+ BranchInst::Create(stop, step, none, block);
+ }
+
+ block = step;
+
+ const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keysPtr);
+
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ if constexpr (RightRequired) {
+ BranchInst::Create(stop, loop, cont, block);
+ } else {
+ BranchInst::Create(loop, stop, cont, block);
+ }
+ } else {
+ const auto output = this->GenFillOutput(static_cast<const IComputationNode*>(this)->GetIndex(), ctx, current.second, getters);
+
+ const auto left = RightRequired ? nullptr : BasicBlock::Create(context, "left", ctx.Func);
+
+ if constexpr (RightRequired)
+ BranchInst::Create(loop, step, none, block);
+ else
+ BranchInst::Create(left, step, none, block);
+
+ block = step;
+
+ ValueUnRef(EValueRepresentation::Boxed, lookupPtr, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(lookupPtr, dict, ctx.Codegen, block, keysPtr);
+
+ const auto lookup = new LoadInst(lookupPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ if constexpr (RightRequired)
+ BranchInst::Create(full, loop, ok, block);
+ else {
+ BranchInst::Create(full, left, ok, block);
+
+ block = left;
+
+ new StoreInst(std::get<1U>(output), std::get<0U>(output), block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ BranchInst::Create(stop, block);
+ }
+
+ {
+ block = full;
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(std::get<1U>(output)->getType(), lookup, ctx.Codegen, block);
+ new StoreInst(elements, std::get<0U>(output), block);
+
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ BranchInst::Create(stop, block);
+ }
+ }
+
+ block = stop;
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(this->Flow))
+ this->DependsOn(flow, this->Dict);
+ }
+};
+
+template<bool RightRequired, bool IsTuple>
+class TWideMultiMapJoinWrapper : public TWideMapJoinBase<IsTuple>, public TPairStateWideFlowCodegeneratorNode<TWideMultiMapJoinWrapper<RightRequired, IsTuple>> {
+using TBaseComputation = TPairStateWideFlowCodegeneratorNode<TWideMultiMapJoinWrapper<RightRequired, IsTuple>>;
+public:
+ TWideMultiMapJoinWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
+ IComputationWideFlowNode* flow, IComputationNode* dict, ui32 inputWidth)
+ : TWideMapJoinBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations)
+ , std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict, inputWidth)
+ , TBaseComputation(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Boxed)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& iter, NUdf::TUnboxedValue& item, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto iterator = std::move(iter);;) {
+ if (iterator.HasValue()) {
+ if (iterator.Next(item)) {
+ this->FillLeftStruct(output);
+ this->FillRightStruct(item, output);
+ iter = std::move(iterator);
+ return EFetchResult::One;
+ }
+ }
+
+ for (const auto& dict = this->Dict->GetValue(ctx);;) {
+ if (const auto res = this->Flow->FetchValues(ctx, this->Fields.data()); EFetchResult::One != res)
+ return res;
+
+ if (const auto keys = this->MakeKeysTuple(ctx)) {
+ if (const auto lookup = dict.Lookup(keys)) {
+ iterator = lookup.GetListIterator();
+ break;
+ }
+ }
+
+ if constexpr (!RightRequired) {
+ this->FillLeftStruct(output);
+ this->NullRightStruct(output);
+ return EFetchResult::One;
+ }
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* iteraratorPtr, Value* itemPtr, BasicBlock*& block) const {
+ MKQL_ENSURE(!this->Dict->IsTemporaryValue(), "Dict can't be temporary");
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto subiter = new LoadInst(iteraratorPtr, "subiter", block);
+
+ const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto part = BasicBlock::Create(context, "part", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
+ const auto left = RightRequired ? nullptr : BasicBlock::Create(context, "left", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto result = PHINode::Create(resultType, RightRequired ? 2U : 3U, "result", exit);
+
+ ICodegeneratorInlineWideNode::TGettersList getters(this->OutputRepresentations.size());
+
+ BranchInst::Create(hasi, part, HasValue(subiter, block), block);
+
+ block = part;
+ const auto dict = GetNodeValue(this->Dict, ctx, block);
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto current = GetNodeValues(this->Flow, ctx, block);
+
+ const auto output = this->GenFillOutput(static_cast<const IComputationNode*>(this)->GetIndex() + 1U, ctx, current.second, getters);
+
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, current.first, ConstantInt::get(resultType, 0), "special", block);
+
+ result->addIncoming(current.first, block);
+
+ BranchInst::Create(exit, next, special, block);
+
+ block = hasi;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, ctx.Codegen, block, itemPtr);
+ BranchInst::Create(full, skip, status, block);
+
+ {
+ block = full;
+
+ const auto item = new LoadInst(itemPtr, "item", block);
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(std::get<1U>(output)->getType(), item, ctx.Codegen, block);
+ new StoreInst(elements, std::get<0U>(output), block);
+
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = skip;
+ UnRefBoxed(subiter, ctx, block);
+ new StoreInst(zero, iteraratorPtr, block);
+ BranchInst::Create(part, block);
+ }
+
+ block = next;
+
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current.second, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current.second, ctx, block);
+
+ if constexpr (RightRequired)
+ BranchInst::Create(loop, step, none, block);
+ else
+ BranchInst::Create(left, step, none, block);
+
+ block = step;
+
+ ValueUnRef(EValueRepresentation::Boxed, itemPtr, ctx, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
+
+ const auto lookup = new LoadInst(itemPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ if constexpr (RightRequired)
+ BranchInst::Create(fill, loop, ok, block);
+ else {
+ BranchInst::Create(fill, left, ok, block);
+
+ block = left;
+
+ new StoreInst(std::get<1U>(output), std::get<0U>(output), block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = fill;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteraratorPtr, lookup, ctx.Codegen, block);
+ BranchInst::Create(work, block);
+ }
+
+ block = exit;
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(this->Flow))
+ this->DependsOn(flow, this->Dict);
+ }
+};
+
+template<bool IsTuple>
+class TMapJoinCoreWrapperBase {
+protected:
+ TMapJoinCoreWrapperBase(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames, IComputationNode* stream, IComputationNode* dict)
+ : LeftKeyConverters(std::move(leftKeyConverters))
+ , DictType(dictType)
+ , OutputRepresentations(std::move(outputRepresentations))
+ , LeftKeyColumns(std::move(leftKeyColumns))
+ , LeftRenames(std::move(leftRenames))
+ , RightRenames(std::move(rightRenames))
+ , Stream(stream)
+ , Dict(dict)
+ , ResStruct(mutables)
+ , KeyTuple(mutables)
+ {}
+
+ static void FillStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items, const std::vector<ui32>& renames) {
if (renames.empty()) {
return;
}
Y_VERIFY(items);
- if (const auto ptr = structObj.GetElements()) {
- for (auto i = 0U; i < renames.size();) {
- const auto prevIndex = renames[i++];
- const auto newIndex = renames[i++];
- items[newIndex] = ptr[prevIndex];
- }
- } else {
- for (auto i = 0U; i < renames.size();) {
- const auto prevIndex = renames[i++];
- const auto newIndex = renames[i++];
- items[newIndex] = structObj.GetElement(prevIndex);
- }
- }
- }
-
- void FillLeftStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items) const {
- FillStruct(structObj, items, LeftRenames);
- }
-
- void FillRightStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items) const {
- FillStruct(structObj, items, RightRenames);
- }
-
- NUdf::TUnboxedValue MakeKeysTuple(TComputationContext& ctx, const NUdf::TUnboxedValuePod& structObj) const {
- if (IsTuple) {
- NUdf::TUnboxedValue* items = nullptr;
- const auto keys = KeyTuple.NewArray(ctx, LeftKeyColumns.size(), items);
+ if (const auto ptr = structObj.GetElements()) {
+ for (auto i = 0U; i < renames.size();) {
+ const auto prevIndex = renames[i++];
+ const auto newIndex = renames[i++];
+ items[newIndex] = ptr[prevIndex];
+ }
+ } else {
+ for (auto i = 0U; i < renames.size();) {
+ const auto prevIndex = renames[i++];
+ const auto newIndex = renames[i++];
+ items[newIndex] = structObj.GetElement(prevIndex);
+ }
+ }
+ }
+
+ void FillLeftStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items) const {
+ FillStruct(structObj, items, LeftRenames);
+ }
+
+ void FillRightStruct(const NUdf::TUnboxedValue& structObj, NUdf::TUnboxedValue* items) const {
+ FillStruct(structObj, items, RightRenames);
+ }
+
+ NUdf::TUnboxedValue MakeKeysTuple(TComputationContext& ctx, const NUdf::TUnboxedValuePod& structObj) const {
+ if (IsTuple) {
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto keys = KeyTuple.NewArray(ctx, LeftKeyColumns.size(), items);
if (!LeftKeyColumns.empty()) {
Y_VERIFY(items);
const auto ptr = structObj.GetElements();
@@ -642,772 +642,772 @@ protected:
if (!(*items++ = converter ? NUdf::TUnboxedValue(converter(&value)) : std::move(value)))
return NUdf::TUnboxedValuePod();
}
- }
-
- return keys;
- } else {
- const auto value = structObj.GetElement(LeftKeyColumns.front());
- const auto converter = LeftKeyConverters.front().Function;
- return converter ? NUdf::TUnboxedValue(converter(&value)) : value;
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenFillLeftStruct(Value* left, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto idxType = Type::getInt32Ty(context);
- const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, left, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- for (auto i = 0U; i < LeftRenames.size();) {
- const auto oldI = LeftRenames[i++];
- const auto newI = LeftRenames[i++];
- const auto oldIndex = ConstantInt::get(idxType, oldI);
- const auto newIndex = ConstantInt::get(idxType, newI);
- const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
- const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
- const auto item = new LoadInst(oldPtr, "item", block);
- new StoreInst(item, newPtr, block);
- ValueAddRef(OutputRepresentations[newI], newPtr, ctx, block);
- }
- BranchInst::Create(done, block);
- }
- {
- block = slow;
- for (auto i = 0U; i < LeftRenames.size();) {
- const auto oldI = LeftRenames[i++];
- const auto newI = LeftRenames[i++];
- const auto oldIndex = ConstantInt::get(idxType, oldI);
- const auto newIndex = ConstantInt::get(idxType, newI);
- const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, left, ctx.Codegen, block, oldIndex);
- }
- BranchInst::Create(done, block);
- }
- block = done;
- }
-
- void GenFillRightStruct(Value* right, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto idxType = Type::getInt32Ty(context);
- const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, right, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- for (auto i = 0U; i < RightRenames.size();) {
- const auto oldI = RightRenames[i++];
- const auto newI = RightRenames[i++];
- const auto oldIndex = ConstantInt::get(idxType, oldI);
- const auto newIndex = ConstantInt::get(idxType, newI);
- const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
- const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
- const auto elem = new LoadInst(oldPtr, "elem", block);
- new StoreInst(elem, newPtr, block);
- ValueAddRef(OutputRepresentations[newI], newPtr, ctx, block);
- }
- BranchInst::Create(done, block);
- }
- {
- block = slow;
- for (auto i = 0U; i < RightRenames.size();) {
- const auto oldI = RightRenames[i++];
- const auto newI = RightRenames[i++];
- const auto oldIndex = ConstantInt::get(idxType, oldI);
- const auto newIndex = ConstantInt::get(idxType, newI);
- const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, right, ctx.Codegen, block, oldIndex);
- }
- BranchInst::Create(done, block);
- }
- block = done;
- }
-
- Value* GenMakeKeysTuple(Value* keysPtr, Value* current, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto idxType = Type::getInt32Ty(context);
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
-
- const auto index = ConstantInt::get(idxType, LeftKeyColumns.front());
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(keysPtr, current, ctx.Codegen, block, index);
- if (const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters.front().Generator)) {
- Value *const elem = new LoadInst(keysPtr, "elem", block);
- const auto conv = converter(&elem, ctx, block);
- new StoreInst(conv, keysPtr, block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
- return check;
- } else {
- const auto keys = new LoadInst(keysPtr, "keys", block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, keys, zero, "check", block);
- return check;
- }
- }
-
- Value* GenMakeKeysTuple(Value* keysPtr, Value* current, Value* itemsPtr, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto idxType = Type::getInt32Ty(context);
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
-
- const auto keys = KeyTuple.GenNewArray(LeftKeyColumns.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, current, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(Type::getInt1Ty(context), (LeftKeyColumns.size() + 1U) << 1U , "result", done);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
-
- const auto keyType = AS_TYPE(TTupleType, DictType->GetKeyType());
- for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
- const auto oldIndex = ConstantInt::get(idxType, LeftKeyColumns[i]);
- const auto newIndex = ConstantInt::get(idxType, i);
- const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
- const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
- const auto elem = new LoadInst(oldPtr, "elem", block);
- const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator);
- const auto conv = converter ? converter(reinterpret_cast<Value *const *>(&elem), ctx, block) : elem;
-
- result->addIncoming(ConstantInt::getTrue(context), block);
- const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
- BranchInst::Create(done, next, check, block);
-
- block = next;
-
- new StoreInst(conv, newPtr, block);
- ValueAddRef(GetValueRepresentation(keyType->GetElementType(i)), newPtr, ctx, block);
- }
-
- result->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(done, block);
- }
- {
- block = slow;
-
- for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
- const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i)}, "item", block);
- const auto index = ConstantInt::get(idxType, LeftKeyColumns[i]);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, current, ctx.Codegen, block, index);
-
- const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
- const auto elem = new LoadInst(item, "elem", block);
-
- if (const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator)) {
- const auto conv = converter(reinterpret_cast<Value *const *>(&elem), ctx, block);
- new StoreInst(conv, item, block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
- result->addIncoming(ConstantInt::getTrue(context), block);
- BranchInst::Create(done, next, check, block);
- } else {
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elem, zero, "check", block);
- result->addIncoming(ConstantInt::getTrue(context), block);
- BranchInst::Create(done, next, check, block);
- }
-
- block = next;
- }
-
- result->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- new StoreInst(keys, keysPtr, block);
- return result;
- }
-#endif
-
- const std::vector<TFunctionDescriptor> LeftKeyConverters;
- TDictType* const DictType;
- const std::vector<EValueRepresentation> OutputRepresentations;
- const std::vector<ui32> LeftKeyColumns;
- const std::vector<ui32> LeftRenames;
- const std::vector<ui32> RightRenames;
- IComputationNode* const Stream;
- IComputationNode* const Dict;
-
- const TContainerCacheOnContext ResStruct;
- const TContainerCacheOnContext KeyTuple;
-};
-
-enum class ERightKind {
- None = 0,
- Once,
- Many
-};
-
-template<ERightKind RightKind, bool RightRequired, bool IsTuple>
-class TMapJoinCoreFlowWrapper : public TMapJoinCoreWrapperBase<IsTuple>, public std::conditional_t<ERightKind::Many != RightKind,
- TStatelessFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>,
- TPairStateFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>> {
- typedef std::conditional_t<ERightKind::Many != RightKind,
- TStatelessFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>,
- TPairStateFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>> TBaseComputation;
-public:
- TMapJoinCoreFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
- IComputationNode* flow, IComputationNode* dict)
- : TMapJoinCoreWrapperBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations),
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict), TBaseComputation(mutables, flow, kind)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- for (const auto dict = this->Dict->GetValue(ctx);;) {
- auto item = this->Stream->GetValue(ctx);
- if (item.IsSpecial()) {
- return item.Release();
- }
-
- const auto keys = this->MakeKeysTuple(ctx, item);
-
- switch (RightKind) {
- case ERightKind::Once:
- if (keys) {
- if (const auto lookup = dict.Lookup(keys)) {
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
- this->FillLeftStruct(item, items);
- this->FillRightStruct(lookup, items);
- return result;
- }
- }
-
- if constexpr (RightRequired)
- continue;
- else
- break;
-
- case ERightKind::None:
- if constexpr (RightRequired) {
- if (keys && dict.Contains(keys))
- break;
- else
- continue;
- } else {
- if (keys && dict.Contains(keys))
- continue;
- else
- break;
- }
- default:
- Y_FAIL("Unreachable");
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
- this->FillLeftStruct(item, items);
- return result;
- }
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& curr, NUdf::TUnboxedValue& iter, TComputationContext& ctx) const {
- for (auto iterator = std::move(iter);;) {
- if (iterator.HasValue() && curr.HasValue()) {
- if (NUdf::TUnboxedValue item; iterator.Next(item)) {
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
- this->FillLeftStruct(curr, items);
- this->FillRightStruct(item, items);
- iter = std::move(iterator);
- return result;
- }
- }
-
- const auto& dict = this->Dict->GetValue(ctx);
- for (auto current = std::move(curr);;) {
- current = this->Stream->GetValue(ctx);
- if (current.IsSpecial()) {
- return current.Release();
- }
-
- if (const auto keys = this->MakeKeysTuple(ctx, current)) {
- if (const auto lookup = dict.Lookup(keys)) {
- iterator = lookup.GetListIterator();
- curr = std::move(current);
- break;
- }
- }
-
- if constexpr (!RightRequired) {
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
- this->FillLeftStruct(current, items);
- return result;
- }
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
-
- const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back());
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(zero, keysPtr, block);
- const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(zero, itemPtr, block);
-
- const auto dict = GetNodeValue(this->Dict, ctx, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto result = PHINode::Create(valueType, 3U, "result", stop);
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto current = GetNodeValue(this->Stream, ctx, block);
- result->addIncoming(current, block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- BranchInst::Create(stop, next, IsSpecial(current, block), block);
- block = next;
-
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current, ctx, block);
-
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto half = BasicBlock::Create(context, "half", ctx.Func);
-
- BranchInst::Create(RightRequired ? skip : half, step, none, block);
-
- block = step;
-
- switch (RightKind) {
- case ERightKind::None: {
- const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- if constexpr (RightRequired) {
- BranchInst::Create(half, skip, cont, block);
- } else {
- BranchInst::Create(skip, half, cont, block);
- }
- break;
- }
- case ERightKind::Once: {
- new StoreInst(zero, itemPtr, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- const auto lookup = new LoadInst(itemPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(full, RightRequired ? skip : half, ok, block);
-
- {
- block = full;
-
- const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
- this->GenFillRightStruct(lookup, items, ctx, block);
-
- UnRefBoxed(lookup, ctx, block);
- ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
-
- result->addIncoming(out, block);
- BranchInst::Create(stop, block);
- }
- break;
- }
- case ERightKind::Many:
- Y_FAIL("Wrong case");
- }
-
- {
- block = half;
-
- const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
-
- ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
-
- result->addIncoming(out, block);
- BranchInst::Create(stop, block);
- }
-
- {
- block = skip;
- ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
- BranchInst::Create(loop, block);
- }
-
- block = stop;
- if (this->Dict->IsTemporaryValue())
- CleanupBoxed(dict, ctx, block);
- return result;
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, Value* iteraratorPtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valueType, 0);
-
- const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
-
- const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back());
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
- const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back());
- new StoreInst(zero, itemPtr, block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto subiter = new LoadInst(iteraratorPtr, "subiter", block);
-
- const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
- const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
- const auto part = BasicBlock::Create(context, "part", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(valueType, 3U, "result", exit);
-
- BranchInst::Create(hasi, part, HasValue(subiter, block), block);
-
- block = hasi;
- const auto curr = new LoadInst(currentPtr, "curr", block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, ctx.Codegen, block, itemPtr);
- BranchInst::Create(full, skip, status, block);
-
- {
- block = full;
-
- const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto item = new LoadInst(itemPtr, "item", block);
-
- this->GenFillLeftStruct(curr, items, ctx, block);
- this->GenFillRightStruct(item, items, ctx, block);
-
- UnRefBoxed(item, ctx, block);
-
- result->addIncoming(out, block);
- BranchInst::Create(exit, block);
- }
-
- {
- block = skip;
- UnRefBoxed(curr, ctx, block);
- UnRefBoxed(subiter, ctx, block);
- new StoreInst(zero, currentPtr, block);
- new StoreInst(zero, iteraratorPtr, block);
- BranchInst::Create(part, block);
- }
-
- block = part;
- const auto dict = GetNodeValue(this->Dict, ctx, block);
- BranchInst::Create(loop, block);
-
- block = loop;
- GetNodeValue(currentPtr, this->Stream, ctx, block);
- const auto current = new LoadInst(currentPtr, "current", block);
- BranchInst::Create(stop, next, IsSpecial(current, block), block);
-
- block = stop;
-
- if (this->Dict->IsTemporaryValue())
- CleanupBoxed(dict, ctx, block);
- result->addIncoming(current, block);
-
- BranchInst::Create(exit, block);
-
- block = next;
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current, ctx, block);
-
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto hsnt = BasicBlock::Create(context, "half", ctx.Func);
-
- BranchInst::Create(hsnt, step, none, block);
-
- block = step;
-
- new StoreInst(zero, itemPtr, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- const auto lookup = new LoadInst(itemPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
-
- BranchInst::Create(fill, hsnt, ok, block);
-
-
- block = hsnt;
-
- if constexpr (RightRequired) {
- UnRefBoxed(current, ctx, block);
- new StoreInst(zero, currentPtr, block);
- BranchInst::Create(loop, block);
- } else {
- const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
- UnRefBoxed(current, ctx, block);
- new StoreInst(zero, currentPtr, block);
-
- if (this->Dict->IsTemporaryValue())
- CleanupBoxed(dict, ctx, block);
-
- result->addIncoming(out, block);
- BranchInst::Create(exit, block);
- }
-
- {
- block = fill;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteraratorPtr, lookup, ctx.Codegen, block);
- CleanupBoxed(lookup, ctx, block);
- BranchInst::Create(work, block);
- }
-
- block = exit;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(this->Stream))
- this->DependsOn(flow, this->Dict);
- }
-};
-
-template<ERightKind RightKind, bool RightRequired, bool IsTuple>
-class TMapJoinCoreWrapper : public TMapJoinCoreWrapperBase<IsTuple>, public TCustomValueCodegeneratorNode<TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>> {
-private:
- typedef TCustomValueCodegeneratorNode<TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>> TBaseComputation;
-
- class TCodegenValue : public TComputationValue<TCodegenValue> {
- public:
- using TBase = TComputationValue<TCodegenValue>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
- TCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, NUdf::TUnboxedValue&& dict)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- , Dict(std::move(dict))
- {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), static_cast<const NUdf::TUnboxedValuePod&>(Dict), result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
- const NUdf::TUnboxedValue Dict;
- };
-
- class TCodegenStatefulValue : public TComputationValue<TCodegenStatefulValue> {
- public:
- using TBase = TComputationValue<TCodegenStatefulValue>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&);
-
- TCodegenStatefulValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, NUdf::TUnboxedValue&& dict)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- , Dict(std::move(dict))
- {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), static_cast<const NUdf::TUnboxedValuePod&>(Dict), Current, Iterator, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
- const NUdf::TUnboxedValue Dict;
-
- NUdf::TUnboxedValue Current;
- NUdf::TUnboxedValue Iterator;
- };
-
- using TSelf = TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>;
- using TBase = TCustomValueCodegeneratorNode<TSelf>;
-
+ }
+
+ return keys;
+ } else {
+ const auto value = structObj.GetElement(LeftKeyColumns.front());
+ const auto converter = LeftKeyConverters.front().Function;
+ return converter ? NUdf::TUnboxedValue(converter(&value)) : value;
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenFillLeftStruct(Value* left, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto idxType = Type::getInt32Ty(context);
+ const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, left, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ for (auto i = 0U; i < LeftRenames.size();) {
+ const auto oldI = LeftRenames[i++];
+ const auto newI = LeftRenames[i++];
+ const auto oldIndex = ConstantInt::get(idxType, oldI);
+ const auto newIndex = ConstantInt::get(idxType, newI);
+ const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
+ const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
+ const auto item = new LoadInst(oldPtr, "item", block);
+ new StoreInst(item, newPtr, block);
+ ValueAddRef(OutputRepresentations[newI], newPtr, ctx, block);
+ }
+ BranchInst::Create(done, block);
+ }
+ {
+ block = slow;
+ for (auto i = 0U; i < LeftRenames.size();) {
+ const auto oldI = LeftRenames[i++];
+ const auto newI = LeftRenames[i++];
+ const auto oldIndex = ConstantInt::get(idxType, oldI);
+ const auto newIndex = ConstantInt::get(idxType, newI);
+ const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, left, ctx.Codegen, block, oldIndex);
+ }
+ BranchInst::Create(done, block);
+ }
+ block = done;
+ }
+
+ void GenFillRightStruct(Value* right, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto idxType = Type::getInt32Ty(context);
+ const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, right, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ for (auto i = 0U; i < RightRenames.size();) {
+ const auto oldI = RightRenames[i++];
+ const auto newI = RightRenames[i++];
+ const auto oldIndex = ConstantInt::get(idxType, oldI);
+ const auto newIndex = ConstantInt::get(idxType, newI);
+ const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
+ const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
+ const auto elem = new LoadInst(oldPtr, "elem", block);
+ new StoreInst(elem, newPtr, block);
+ ValueAddRef(OutputRepresentations[newI], newPtr, ctx, block);
+ }
+ BranchInst::Create(done, block);
+ }
+ {
+ block = slow;
+ for (auto i = 0U; i < RightRenames.size();) {
+ const auto oldI = RightRenames[i++];
+ const auto newI = RightRenames[i++];
+ const auto oldIndex = ConstantInt::get(idxType, oldI);
+ const auto newIndex = ConstantInt::get(idxType, newI);
+ const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, right, ctx.Codegen, block, oldIndex);
+ }
+ BranchInst::Create(done, block);
+ }
+ block = done;
+ }
+
+ Value* GenMakeKeysTuple(Value* keysPtr, Value* current, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto idxType = Type::getInt32Ty(context);
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+
+ const auto index = ConstantInt::get(idxType, LeftKeyColumns.front());
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(keysPtr, current, ctx.Codegen, block, index);
+ if (const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters.front().Generator)) {
+ Value *const elem = new LoadInst(keysPtr, "elem", block);
+ const auto conv = converter(&elem, ctx, block);
+ new StoreInst(conv, keysPtr, block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
+ return check;
+ } else {
+ const auto keys = new LoadInst(keysPtr, "keys", block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, keys, zero, "check", block);
+ return check;
+ }
+ }
+
+ Value* GenMakeKeysTuple(Value* keysPtr, Value* current, Value* itemsPtr, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto idxType = Type::getInt32Ty(context);
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+
+ const auto keys = KeyTuple.GenNewArray(LeftKeyColumns.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto ptrType = PointerType::getUnqual(Type::getInt128Ty(context));
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, current, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt1Ty(context), (LeftKeyColumns.size() + 1U) << 1U , "result", done);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+
+ const auto keyType = AS_TYPE(TTupleType, DictType->GetKeyType());
+ for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
+ const auto oldIndex = ConstantInt::get(idxType, LeftKeyColumns[i]);
+ const auto newIndex = ConstantInt::get(idxType, i);
+ const auto oldPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "old", block);
+ const auto newPtr = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), newIndex}, "new", block);
+ const auto elem = new LoadInst(oldPtr, "elem", block);
+ const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator);
+ const auto conv = converter ? converter(reinterpret_cast<Value *const *>(&elem), ctx, block) : elem;
+
+ result->addIncoming(ConstantInt::getTrue(context), block);
+ const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
+ BranchInst::Create(done, next, check, block);
+
+ block = next;
+
+ new StoreInst(conv, newPtr, block);
+ ValueAddRef(GetValueRepresentation(keyType->GetElementType(i)), newPtr, ctx, block);
+ }
+
+ result->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(done, block);
+ }
+ {
+ block = slow;
+
+ for (ui32 i = 0; i < LeftKeyColumns.size(); ++i) {
+ const auto item = GetElementPtrInst::CreateInBounds(items, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i)}, "item", block);
+ const auto index = ConstantInt::get(idxType, LeftKeyColumns[i]);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(item, current, ctx.Codegen, block, index);
+
+ const auto next = BasicBlock::Create(context, (TString("next_") += ToString(i)).c_str(), ctx.Func);
+ const auto elem = new LoadInst(item, "elem", block);
+
+ if (const auto converter = reinterpret_cast<TGeneratorPtr>(LeftKeyConverters[i].Generator)) {
+ const auto conv = converter(reinterpret_cast<Value *const *>(&elem), ctx, block);
+ new StoreInst(conv, item, block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, conv, zero, "check", block);
+ result->addIncoming(ConstantInt::getTrue(context), block);
+ BranchInst::Create(done, next, check, block);
+ } else {
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elem, zero, "check", block);
+ result->addIncoming(ConstantInt::getTrue(context), block);
+ BranchInst::Create(done, next, check, block);
+ }
+
+ block = next;
+ }
+
+ result->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ new StoreInst(keys, keysPtr, block);
+ return result;
+ }
+#endif
+
+ const std::vector<TFunctionDescriptor> LeftKeyConverters;
+ TDictType* const DictType;
+ const std::vector<EValueRepresentation> OutputRepresentations;
+ const std::vector<ui32> LeftKeyColumns;
+ const std::vector<ui32> LeftRenames;
+ const std::vector<ui32> RightRenames;
+ IComputationNode* const Stream;
+ IComputationNode* const Dict;
+
+ const TContainerCacheOnContext ResStruct;
+ const TContainerCacheOnContext KeyTuple;
+};
+
+enum class ERightKind {
+ None = 0,
+ Once,
+ Many
+};
+
+template<ERightKind RightKind, bool RightRequired, bool IsTuple>
+class TMapJoinCoreFlowWrapper : public TMapJoinCoreWrapperBase<IsTuple>, public std::conditional_t<ERightKind::Many != RightKind,
+ TStatelessFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>,
+ TPairStateFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>> {
+ typedef std::conditional_t<ERightKind::Many != RightKind,
+ TStatelessFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>,
+ TPairStateFlowCodegeneratorNode<TMapJoinCoreFlowWrapper<RightKind, RightRequired, IsTuple>>> TBaseComputation;
+public:
+ TMapJoinCoreFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
+ IComputationNode* flow, IComputationNode* dict)
+ : TMapJoinCoreWrapperBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations),
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict), TBaseComputation(mutables, flow, kind)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ for (const auto dict = this->Dict->GetValue(ctx);;) {
+ auto item = this->Stream->GetValue(ctx);
+ if (item.IsSpecial()) {
+ return item.Release();
+ }
+
+ const auto keys = this->MakeKeysTuple(ctx, item);
+
+ switch (RightKind) {
+ case ERightKind::Once:
+ if (keys) {
+ if (const auto lookup = dict.Lookup(keys)) {
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
+ this->FillLeftStruct(item, items);
+ this->FillRightStruct(lookup, items);
+ return result;
+ }
+ }
+
+ if constexpr (RightRequired)
+ continue;
+ else
+ break;
+
+ case ERightKind::None:
+ if constexpr (RightRequired) {
+ if (keys && dict.Contains(keys))
+ break;
+ else
+ continue;
+ } else {
+ if (keys && dict.Contains(keys))
+ continue;
+ else
+ break;
+ }
+ default:
+ Y_FAIL("Unreachable");
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
+ this->FillLeftStruct(item, items);
+ return result;
+ }
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& curr, NUdf::TUnboxedValue& iter, TComputationContext& ctx) const {
+ for (auto iterator = std::move(iter);;) {
+ if (iterator.HasValue() && curr.HasValue()) {
+ if (NUdf::TUnboxedValue item; iterator.Next(item)) {
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
+ this->FillLeftStruct(curr, items);
+ this->FillRightStruct(item, items);
+ iter = std::move(iterator);
+ return result;
+ }
+ }
+
+ const auto& dict = this->Dict->GetValue(ctx);
+ for (auto current = std::move(curr);;) {
+ current = this->Stream->GetValue(ctx);
+ if (current.IsSpecial()) {
+ return current.Release();
+ }
+
+ if (const auto keys = this->MakeKeysTuple(ctx, current)) {
+ if (const auto lookup = dict.Lookup(keys)) {
+ iterator = lookup.GetListIterator();
+ curr = std::move(current);
+ break;
+ }
+ }
+
+ if constexpr (!RightRequired) {
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = this->ResStruct.NewArray(ctx, this->OutputRepresentations.size(), items);
+ this->FillLeftStruct(current, items);
+ return result;
+ }
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+
+ const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back());
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(zero, keysPtr, block);
+ const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(zero, itemPtr, block);
+
+ const auto dict = GetNodeValue(this->Dict, ctx, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto result = PHINode::Create(valueType, 3U, "result", stop);
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto current = GetNodeValue(this->Stream, ctx, block);
+ result->addIncoming(current, block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ BranchInst::Create(stop, next, IsSpecial(current, block), block);
+ block = next;
+
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current, ctx, block);
+
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto half = BasicBlock::Create(context, "half", ctx.Func);
+
+ BranchInst::Create(RightRequired ? skip : half, step, none, block);
+
+ block = step;
+
+ switch (RightKind) {
+ case ERightKind::None: {
+ const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, ctx.Codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ if constexpr (RightRequired) {
+ BranchInst::Create(half, skip, cont, block);
+ } else {
+ BranchInst::Create(skip, half, cont, block);
+ }
+ break;
+ }
+ case ERightKind::Once: {
+ new StoreInst(zero, itemPtr, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ const auto lookup = new LoadInst(itemPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(full, RightRequired ? skip : half, ok, block);
+
+ {
+ block = full;
+
+ const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+ this->GenFillRightStruct(lookup, items, ctx, block);
+
+ UnRefBoxed(lookup, ctx, block);
+ ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
+
+ result->addIncoming(out, block);
+ BranchInst::Create(stop, block);
+ }
+ break;
+ }
+ case ERightKind::Many:
+ Y_FAIL("Wrong case");
+ }
+
+ {
+ block = half;
+
+ const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+
+ ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
+
+ result->addIncoming(out, block);
+ BranchInst::Create(stop, block);
+ }
+
+ {
+ block = skip;
+ ValueCleanup(static_cast<const IComputationNode*>(this)->GetRepresentation(), current, ctx, block);
+ BranchInst::Create(loop, block);
+ }
+
+ block = stop;
+ if (this->Dict->IsTemporaryValue())
+ CleanupBoxed(dict, ctx, block);
+ return result;
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* currentPtr, Value* iteraratorPtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valueType, 0);
+
+ const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+
+ const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", &ctx.Func->getEntryBlock().back());
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", &ctx.Func->getEntryBlock().back()) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", &ctx.Func->getEntryBlock().back());
+ const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back());
+ new StoreInst(zero, itemPtr, block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto subiter = new LoadInst(iteraratorPtr, "subiter", block);
+
+ const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto part = BasicBlock::Create(context, "part", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(valueType, 3U, "result", exit);
+
+ BranchInst::Create(hasi, part, HasValue(subiter, block), block);
+
+ block = hasi;
+ const auto curr = new LoadInst(currentPtr, "curr", block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, ctx.Codegen, block, itemPtr);
+ BranchInst::Create(full, skip, status, block);
+
+ {
+ block = full;
+
+ const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto item = new LoadInst(itemPtr, "item", block);
+
+ this->GenFillLeftStruct(curr, items, ctx, block);
+ this->GenFillRightStruct(item, items, ctx, block);
+
+ UnRefBoxed(item, ctx, block);
+
+ result->addIncoming(out, block);
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = skip;
+ UnRefBoxed(curr, ctx, block);
+ UnRefBoxed(subiter, ctx, block);
+ new StoreInst(zero, currentPtr, block);
+ new StoreInst(zero, iteraratorPtr, block);
+ BranchInst::Create(part, block);
+ }
+
+ block = part;
+ const auto dict = GetNodeValue(this->Dict, ctx, block);
+ BranchInst::Create(loop, block);
+
+ block = loop;
+ GetNodeValue(currentPtr, this->Stream, ctx, block);
+ const auto current = new LoadInst(currentPtr, "current", block);
+ BranchInst::Create(stop, next, IsSpecial(current, block), block);
+
+ block = stop;
+
+ if (this->Dict->IsTemporaryValue())
+ CleanupBoxed(dict, ctx, block);
+ result->addIncoming(current, block);
+
+ BranchInst::Create(exit, block);
+
+ block = next;
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current, ctx, block);
+
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto hsnt = BasicBlock::Create(context, "half", ctx.Func);
+
+ BranchInst::Create(hsnt, step, none, block);
+
+ block = step;
+
+ new StoreInst(zero, itemPtr, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ const auto lookup = new LoadInst(itemPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
+
+ BranchInst::Create(fill, hsnt, ok, block);
+
+
+ block = hsnt;
+
+ if constexpr (RightRequired) {
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(zero, currentPtr, block);
+ BranchInst::Create(loop, block);
+ } else {
+ const auto out = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(zero, currentPtr, block);
+
+ if (this->Dict->IsTemporaryValue())
+ CleanupBoxed(dict, ctx, block);
+
+ result->addIncoming(out, block);
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = fill;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteraratorPtr, lookup, ctx.Codegen, block);
+ CleanupBoxed(lookup, ctx, block);
+ BranchInst::Create(work, block);
+ }
+
+ block = exit;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(this->Stream))
+ this->DependsOn(flow, this->Dict);
+ }
+};
+
+template<ERightKind RightKind, bool RightRequired, bool IsTuple>
+class TMapJoinCoreWrapper : public TMapJoinCoreWrapperBase<IsTuple>, public TCustomValueCodegeneratorNode<TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>> {
+private:
+ typedef TCustomValueCodegeneratorNode<TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>> TBaseComputation;
+
+ class TCodegenValue : public TComputationValue<TCodegenValue> {
+ public:
+ using TBase = TComputationValue<TCodegenValue>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
+ TCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, NUdf::TUnboxedValue&& dict)
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ , Dict(std::move(dict))
+ {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), static_cast<const NUdf::TUnboxedValuePod&>(Dict), result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Dict;
+ };
+
+ class TCodegenStatefulValue : public TComputationValue<TCodegenStatefulValue> {
+ public:
+ using TBase = TComputationValue<TCodegenStatefulValue>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&);
+
+ TCodegenStatefulValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, NUdf::TUnboxedValue&& dict)
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ , Dict(std::move(dict))
+ {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), static_cast<const NUdf::TUnboxedValuePod&>(Dict), Current, Iterator, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Dict;
+
+ NUdf::TUnboxedValue Current;
+ NUdf::TUnboxedValue Iterator;
+ };
+
+ using TSelf = TMapJoinCoreWrapper<RightKind, RightRequired, IsTuple>;
+ using TBase = TCustomValueCodegeneratorNode<TSelf>;
+
class TValue : public TComputationValue<TValue> {
public:
using TBase = TComputationValue<TValue>;
TValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
- NUdf::TUnboxedValue&& dict, TComputationContext& ctx, const TSelf* self)
+ NUdf::TUnboxedValue&& dict, TComputationContext& ctx, const TSelf* self)
: TBase(memInfo)
, Stream(std::move(stream))
, Dict(std::move(dict))
, Ctx(ctx)
, Self(self)
- {}
- private:
+ {}
+ private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- for (NUdf::TUnboxedValue current;;) {
- if (const auto status = Stream.Fetch(current); status != NUdf::EFetchStatus::Ok) {
+ for (NUdf::TUnboxedValue current;;) {
+ if (const auto status = Stream.Fetch(current); status != NUdf::EFetchStatus::Ok) {
return status;
}
- const auto keys = Self->MakeKeysTuple(Ctx, current);
-
- switch (RightKind) {
- case ERightKind::Once:
- if (keys) {
- if (const auto lookup = Dict.Lookup(keys)) {
- NUdf::TUnboxedValue* items = nullptr;
- result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
- Self->FillLeftStruct(current, items);
- Self->FillRightStruct(lookup, items);
- return NUdf::EFetchStatus::Ok;
- }
+ const auto keys = Self->MakeKeysTuple(Ctx, current);
+
+ switch (RightKind) {
+ case ERightKind::Once:
+ if (keys) {
+ if (const auto lookup = Dict.Lookup(keys)) {
+ NUdf::TUnboxedValue* items = nullptr;
+ result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
+ Self->FillLeftStruct(current, items);
+ Self->FillRightStruct(lookup, items);
+ return NUdf::EFetchStatus::Ok;
+ }
}
- if constexpr (RightRequired)
- continue;
- else
- break;
-
- case ERightKind::None:
- if constexpr (RightRequired) {
- if (keys && Dict.Contains(keys))
- break;
- else
- continue;
- } else {
- if (keys && Dict.Contains(keys))
- continue;
- else
- break;
- }
- default:
- Y_FAIL("Unreachable");
+ if constexpr (RightRequired)
+ continue;
+ else
+ break;
+
+ case ERightKind::None:
+ if constexpr (RightRequired) {
+ if (keys && Dict.Contains(keys))
+ break;
+ else
+ continue;
+ } else {
+ if (keys && Dict.Contains(keys))
+ continue;
+ else
+ break;
+ }
+ default:
+ Y_FAIL("Unreachable");
}
- NUdf::TUnboxedValue* items = nullptr;
- result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
- Self->FillLeftStruct(current, items);
- return NUdf::EFetchStatus::Ok;
- }
- }
+ NUdf::TUnboxedValue* items = nullptr;
+ result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
+ Self->FillLeftStruct(current, items);
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
- private:
+ private:
NUdf::TUnboxedValue Stream;
NUdf::TUnboxedValue Dict;
- TComputationContext& Ctx;
- const TSelf* const Self;
- };
-
- class TMultiRowValue : public TComputationValue<TMultiRowValue> {
- public:
- using TBase = TComputationValue<TMultiRowValue>;
-
- TMultiRowValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
- NUdf::TUnboxedValue&& dict, TComputationContext& ctx, const TSelf* self)
- : TBase(memInfo)
- , Stream(std::move(stream))
- , Dict(std::move(dict))
- , Ctx(ctx)
- , Self(self)
- {}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- for (auto iterator = std::move(Iterator);;) {
- if (iterator && Current) {
- if (NUdf::TUnboxedValue item; iterator.Next(item)) {
- NUdf::TUnboxedValue* items = nullptr;
- result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
- Self->FillLeftStruct(Current, items);
- Self->FillRightStruct(item, items);
- Iterator = std::move(iterator);
- return NUdf::EFetchStatus::Ok;
- }
+ TComputationContext& Ctx;
+ const TSelf* const Self;
+ };
+
+ class TMultiRowValue : public TComputationValue<TMultiRowValue> {
+ public:
+ using TBase = TComputationValue<TMultiRowValue>;
+
+ TMultiRowValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
+ NUdf::TUnboxedValue&& dict, TComputationContext& ctx, const TSelf* self)
+ : TBase(memInfo)
+ , Stream(std::move(stream))
+ , Dict(std::move(dict))
+ , Ctx(ctx)
+ , Self(self)
+ {}
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ for (auto iterator = std::move(Iterator);;) {
+ if (iterator && Current) {
+ if (NUdf::TUnboxedValue item; iterator.Next(item)) {
+ NUdf::TUnboxedValue* items = nullptr;
+ result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
+ Self->FillLeftStruct(Current, items);
+ Self->FillRightStruct(item, items);
+ Iterator = std::move(iterator);
+ return NUdf::EFetchStatus::Ok;
+ }
}
- for (auto current = std::move(Current);;) {
- if (const auto status = Stream.Fetch(current); NUdf::EFetchStatus::Ok != status) {
- return status;
- }
-
- if (const auto keys = Self->MakeKeysTuple(Ctx, current)) {
- if (const auto lookup = Dict.Lookup(keys)) {
- iterator = lookup.GetListIterator();
- Current = std::move(current);
- break;
- }
- }
-
- if (!RightRequired) {
- NUdf::TUnboxedValue* items = nullptr;
- result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
- Self->FillLeftStruct(current, items);
- return NUdf::EFetchStatus::Ok;
- }
- }
+ for (auto current = std::move(Current);;) {
+ if (const auto status = Stream.Fetch(current); NUdf::EFetchStatus::Ok != status) {
+ return status;
+ }
+
+ if (const auto keys = Self->MakeKeysTuple(Ctx, current)) {
+ if (const auto lookup = Dict.Lookup(keys)) {
+ iterator = lookup.GetListIterator();
+ Current = std::move(current);
+ break;
+ }
+ }
+
+ if (!RightRequired) {
+ NUdf::TUnboxedValue* items = nullptr;
+ result = Self->ResStruct.NewArray(Ctx, Self->OutputRepresentations.size(), items);
+ Self->FillLeftStruct(current, items);
+ return NUdf::EFetchStatus::Ok;
+ }
+ }
}
}
@@ -1415,503 +1415,503 @@ private:
NUdf::TUnboxedValue Stream;
NUdf::TUnboxedValue Dict;
TComputationContext& Ctx;
- const TSelf* const Self;
+ const TSelf* const Self;
- NUdf::TUnboxedValue Current;
- NUdf::TUnboxedValue Iterator;
+ NUdf::TUnboxedValue Current;
+ NUdf::TUnboxedValue Iterator;
};
- using TMyCodegenValue = std::conditional_t<ERightKind::Many == RightKind, TCodegenStatefulValue, TCodegenValue>;
-
-public:
- TMapJoinCoreWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
- TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
- std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
+ using TMyCodegenValue = std::conditional_t<ERightKind::Many == RightKind, TCodegenStatefulValue, TCodegenValue>;
+
+public:
+ TMapJoinCoreWrapper(TComputationMutables& mutables, std::vector<TFunctionDescriptor>&& leftKeyConverters,
+ TDictType* dictType, std::vector<EValueRepresentation>&& outputRepresentations, std::vector<ui32>&& leftKeyColumns,
+ std::vector<ui32>&& leftRenames, std::vector<ui32>&& rightRenames,
IComputationNode* stream, IComputationNode* dict)
- : TMapJoinCoreWrapperBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations),
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), stream, dict), TBaseComputation(mutables)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && MapJoin)
- return ctx.HolderFactory.Create<TMyCodegenValue>(MapJoin, &ctx, this->Stream->GetValue(ctx), this->Dict->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<std::conditional_t<ERightKind::Many == RightKind, TMultiRowValue, TValue>>(this->Stream->GetValue(ctx), this->Dict->GetValue(ctx), ctx, this);
+ : TMapJoinCoreWrapperBase<IsTuple>(mutables, std::move(leftKeyConverters), dictType, std::move(outputRepresentations),
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), stream, dict), TBaseComputation(mutables)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && MapJoin)
+ return ctx.HolderFactory.Create<TMyCodegenValue>(MapJoin, &ctx, this->Stream->GetValue(ctx), this->Dict->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<std::conditional_t<ERightKind::Many == RightKind, TMultiRowValue, TValue>>(this->Stream->GetValue(ctx), this->Dict->GetValue(ctx), ctx, this);
}
-private:
- void RegisterDependencies() const final {
- this->DependsOn(this->Stream);
- this->DependsOn(this->Dict);
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(this->Stream);
+ this->DependsOn(this->Dict);
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- MapJoinFunc = RightKind == ERightKind::Many ? GenerateStatefulMapper(codegen) : GenerateMapper(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ MapJoinFunc = RightKind == ERightKind::Many ? GenerateStatefulMapper(codegen) : GenerateMapper(codegen);
codegen->ExportSymbol(MapJoinFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (MapJoinFunc)
- MapJoin = reinterpret_cast<TMapJoinPtr>(codegen->GetPointerToFunction(MapJoinFunc));
- }
-
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto idxType = Type::getInt32Ty(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, containerType, PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (MapJoinFunc)
+ MapJoin = reinterpret_cast<TMapJoinPtr>(codegen->GetPointerToFunction(MapJoinFunc));
+ }
+
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto idxType = Type::getInt32Ty(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, containerType, PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto streamArg = &*++args;
- const auto dictArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(streamArg, "load_stream", false, block) : static_cast<Value*>(streamArg);
-
- const auto dict = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(dictArg, "load_dict", false, block) : static_cast<Value*>(dictArg);
-
- const auto zero = ConstantInt::get(valueType, 0);
- const auto fsok = ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok));
-
- const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", block);
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", block) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", block);
- new StoreInst(zero, keysPtr, block);
- const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
- new StoreInst(zero, itemPtr, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- BranchInst::Create(loop, block);
-
- block = loop;
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, itemPtr);
- ReturnInst::Create(context, status, stop);
-
- const auto stat = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, fsok, "stat", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- BranchInst::Create(stop, next, stat, block);
- block = next;
-
- const auto current = new LoadInst(itemPtr, "current", block);
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current, ctx, block);
-
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto half = BasicBlock::Create(context, "half", ctx.Func);
-
- BranchInst::Create(RightRequired ? skip : half, step, none, block);
-
- block = step;
- switch (RightKind) {
- case ERightKind::None: {
- const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- if constexpr (RightRequired) {
- BranchInst::Create(half, skip, cont, block);
- } else {
- BranchInst::Create(skip, half, cont, block);
- }
- break;
- }
-
- case ERightKind::Once: {
- new StoreInst(zero, itemPtr, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- const auto lookup = new LoadInst(itemPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(full, RightRequired ? skip : half, ok, block);
-
- {
- block = full;
-
- const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
- this->GenFillRightStruct(lookup, items, ctx, block);
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- AddRefBoxed(result, ctx, block);
- new StoreInst(result, valuePtr, block);
-
- UnRefBoxed(current, ctx, block);
- UnRefBoxed(lookup, ctx, block);
-
- ReturnInst::Create(context, fsok, block);
- }
- break;
- }
- case ERightKind::Many:
- Y_FAIL("Wrong case");
- }
-
- {
- block = half;
-
- const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- AddRefBoxed(result, ctx, block);
- new StoreInst(result, valuePtr, block);
-
- UnRefBoxed(current, ctx, block);
-
- ReturnInst::Create(context, fsok, block);
- }
-
- {
- block = skip;
- UnRefBoxed(current, ctx, block);
- new StoreInst(zero, itemPtr, block);
- BranchInst::Create(loop, block);
- }
-
- return ctx.Func;
- }
-
- Function* GenerateStatefulMapper(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = TBaseComputation::MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
- const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto idxType = Type::getInt32Ty(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto streamArg = &*++args;
+ const auto dictArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(streamArg, "load_stream", false, block) : static_cast<Value*>(streamArg);
+
+ const auto dict = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(dictArg, "load_dict", false, block) : static_cast<Value*>(dictArg);
+
+ const auto zero = ConstantInt::get(valueType, 0);
+ const auto fsok = ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok));
+
+ const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", block);
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", block) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", block);
+ new StoreInst(zero, keysPtr, block);
+ const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
+ new StoreInst(zero, itemPtr, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ BranchInst::Create(loop, block);
+
+ block = loop;
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, itemPtr);
+ ReturnInst::Create(context, status, stop);
+
+ const auto stat = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, fsok, "stat", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ BranchInst::Create(stop, next, stat, block);
+ block = next;
+
+ const auto current = new LoadInst(itemPtr, "current", block);
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current, ctx, block);
+
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto half = BasicBlock::Create(context, "half", ctx.Func);
+
+ BranchInst::Create(RightRequired ? skip : half, step, none, block);
+
+ block = step;
+ switch (RightKind) {
+ case ERightKind::None: {
+ const auto cont = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Contains>(Type::getInt1Ty(context), dict, codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ if constexpr (RightRequired) {
+ BranchInst::Create(half, skip, cont, block);
+ } else {
+ BranchInst::Create(skip, half, cont, block);
+ }
+ break;
+ }
+
+ case ERightKind::Once: {
+ new StoreInst(zero, itemPtr, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ const auto lookup = new LoadInst(itemPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(full, RightRequired ? skip : half, ok, block);
+
+ {
+ block = full;
+
+ const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+ this->GenFillRightStruct(lookup, items, ctx, block);
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ AddRefBoxed(result, ctx, block);
+ new StoreInst(result, valuePtr, block);
+
+ UnRefBoxed(current, ctx, block);
+ UnRefBoxed(lookup, ctx, block);
+
+ ReturnInst::Create(context, fsok, block);
+ }
+ break;
+ }
+ case ERightKind::Many:
+ Y_FAIL("Wrong case");
+ }
+
+ {
+ block = half;
+
+ const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ AddRefBoxed(result, ctx, block);
+ new StoreInst(result, valuePtr, block);
+
+ UnRefBoxed(current, ctx, block);
+
+ ReturnInst::Create(context, fsok, block);
+ }
+
+ {
+ block = skip;
+ UnRefBoxed(current, ctx, block);
+ new StoreInst(zero, itemPtr, block);
+ BranchInst::Create(loop, block);
+ }
+
+ return ctx.Func;
+ }
+
+ Function* GenerateStatefulMapper(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = TBaseComputation::MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto itemsType = ArrayType::get(valueType, this->OutputRepresentations.size());
+ const auto keysType = IsTuple ? ArrayType::get(valueType, this->LeftKeyColumns.size()) : nullptr;
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto idxType = Type::getInt32Ty(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto streamArg = &*++args;
- const auto dictArg = &*++args;
- const auto currentArg = &*++args;
- const auto iteratorArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(streamArg, "load_stream", false, block) : static_cast<Value*>(streamArg);
-
- const auto dict = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(dictArg, "load_dict", false, block) : static_cast<Value*>(dictArg);
-
- const auto zero = ConstantInt::get(valueType, 0);
- const auto fsok = ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok));
-
- const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", block);
- const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", block) : nullptr;
-
- const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", block);
- const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
- new StoreInst(zero, itemPtr, block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto subiter = new LoadInst(iteratorArg, "subiter", block);
-
- const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
- const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
-
- const auto ichk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, subiter, zero, "ichk", block);
- BranchInst::Create(hasi, loop, ichk, block);
-
- {
- block = hasi;
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, codegen, block, itemPtr);
- BranchInst::Create(full, skip, status, block);
- }
-
- {
- block = skip;
- UnRefBoxed(subiter, ctx, block);
- new StoreInst(zero, iteratorArg, block);
- BranchInst::Create(loop, block);
- }
-
- {
- block = full;
-
- const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto curr = new LoadInst(currentArg, "curr", block);
- const auto item = new LoadInst(itemPtr, "item", block);
-
- this->GenFillLeftStruct(curr, items, ctx, block);
- this->GenFillRightStruct(item, items, ctx, block);
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- AddRefBoxed(result, ctx, block);
- new StoreInst(result, valuePtr, block);
-
- UnRefBoxed(item, ctx, block);
-
- ReturnInst::Create(context, fsok, block);
- }
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- {
- block = loop;
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, currentArg);
- ReturnInst::Create(context, status, stop);
-
- const auto stat = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, fsok, "stat", block);
- BranchInst::Create(stop, next, stat, block);
- }
-
- {
- block = next;
- const auto current = new LoadInst(currentArg, "current", block);
-
- const auto none = IsTuple ?
- this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
- this->GenMakeKeysTuple(keysPtr, current, ctx, block);
-
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto hsnt = RightRequired ? loop : BasicBlock::Create(context, "half", ctx.Func);
-
- BranchInst::Create(hsnt, step, none, block);
-
- block = step;
-
- new StoreInst(zero, itemPtr, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
-
- if constexpr (!IsTuple) {
- ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
- }
-
- const auto lookup = new LoadInst(itemPtr, "lookup", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
-
- const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
-
- BranchInst::Create(fill, hsnt, ok, block);
-
- if constexpr (!RightRequired) {
- block = hsnt;
-
- const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- this->GenFillLeftStruct(current, items, ctx, block);
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- AddRefBoxed(result, ctx, block);
- new StoreInst(result, valuePtr, block);
-
- ReturnInst::Create(context, fsok, block);
- }
-
- {
- block = fill;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteratorArg, lookup, codegen, block);
- CleanupBoxed(lookup, ctx, block);
- BranchInst::Create(work, block);
- }
- }
-
- return ctx.Func;
- }
-
- using TMapJoinPtr = typename TMyCodegenValue::TFetchPtr;
-
- Function* MapJoinFunc = nullptr;
-
- TMapJoinPtr MapJoin = nullptr;
-#endif
-};
-
-}
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto streamArg = &*++args;
+ const auto dictArg = &*++args;
+ const auto currentArg = &*++args;
+ const auto iteratorArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(streamArg, "load_stream", false, block) : static_cast<Value*>(streamArg);
+
+ const auto dict = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(dictArg, "load_dict", false, block) : static_cast<Value*>(dictArg);
+
+ const auto zero = ConstantInt::get(valueType, 0);
+ const auto fsok = ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok));
+
+ const auto itemsPtr = new AllocaInst(PointerType::getUnqual(itemsType), 0U, "items_ptr", block);
+ const auto kitmsPtr = IsTuple ? new AllocaInst(PointerType::getUnqual(keysType), 0U, "kitms_ptr", block) : nullptr;
+
+ const auto keysPtr = new AllocaInst(valueType, 0U, "keys_ptr", block);
+ const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
+ new StoreInst(zero, itemPtr, block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto subiter = new LoadInst(iteratorArg, "subiter", block);
+
+ const auto hasi = BasicBlock::Create(context, "hasi", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "loop", ctx.Func);
+
+ const auto ichk = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, subiter, zero, "ichk", block);
+ BranchInst::Create(hasi, loop, ichk, block);
+
+ {
+ block = hasi;
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), subiter, codegen, block, itemPtr);
+ BranchInst::Create(full, skip, status, block);
+ }
+
+ {
+ block = skip;
+ UnRefBoxed(subiter, ctx, block);
+ new StoreInst(zero, iteratorArg, block);
+ BranchInst::Create(loop, block);
+ }
+
+ {
+ block = full;
+
+ const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto curr = new LoadInst(currentArg, "curr", block);
+ const auto item = new LoadInst(itemPtr, "item", block);
+
+ this->GenFillLeftStruct(curr, items, ctx, block);
+ this->GenFillRightStruct(item, items, ctx, block);
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ AddRefBoxed(result, ctx, block);
+ new StoreInst(result, valuePtr, block);
+
+ UnRefBoxed(item, ctx, block);
+
+ ReturnInst::Create(context, fsok, block);
+ }
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ {
+ block = loop;
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, currentArg);
+ ReturnInst::Create(context, status, stop);
+
+ const auto stat = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, fsok, "stat", block);
+ BranchInst::Create(stop, next, stat, block);
+ }
+
+ {
+ block = next;
+ const auto current = new LoadInst(currentArg, "current", block);
+
+ const auto none = IsTuple ?
+ this->GenMakeKeysTuple(keysPtr, current, kitmsPtr, ctx, block):
+ this->GenMakeKeysTuple(keysPtr, current, ctx, block);
+
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto hsnt = RightRequired ? loop : BasicBlock::Create(context, "half", ctx.Func);
+
+ BranchInst::Create(hsnt, step, none, block);
+
+ block = step;
+
+ new StoreInst(zero, itemPtr, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Lookup>(itemPtr, dict, ctx.Codegen, block, keysPtr);
+
+ if constexpr (!IsTuple) {
+ ValueUnRef(GetValueRepresentation(this->DictType->GetKeyType()), keysPtr, ctx, block);
+ }
+
+ const auto lookup = new LoadInst(itemPtr, "lookup", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lookup, zero, "ok", block);
+
+ const auto fill = BasicBlock::Create(context, "fill", ctx.Func);
+
+ BranchInst::Create(fill, hsnt, ok, block);
+
+ if constexpr (!RightRequired) {
+ block = hsnt;
+
+ const auto result = this->ResStruct.GenNewArray(this->OutputRepresentations.size(), itemsPtr, ctx, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ this->GenFillLeftStruct(current, items, ctx, block);
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ AddRefBoxed(result, ctx, block);
+ new StoreInst(result, valuePtr, block);
+
+ ReturnInst::Create(context, fsok, block);
+ }
+
+ {
+ block = fill;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iteratorArg, lookup, codegen, block);
+ CleanupBoxed(lookup, ctx, block);
+ BranchInst::Create(work, block);
+ }
+ }
+
+ return ctx.Func;
+ }
+
+ using TMapJoinPtr = typename TMyCodegenValue::TFetchPtr;
+
+ Function* MapJoinFunc = nullptr;
+
+ TMapJoinPtr MapJoin = nullptr;
+#endif
+};
+
+}
IComputationNode* WrapMapJoinCore(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 6, "Expected 6 args");
- const auto type = callable.GetType()->GetReturnType();
- const auto leftStreamNode = callable.GetInput(0);
- const auto leftItemType = leftStreamNode.GetStaticType()->IsFlow() ?
- AS_TYPE(TFlowType, leftStreamNode)->GetItemType():
- AS_TYPE(TStreamType, leftStreamNode)->GetItemType();
- const auto dictNode = callable.GetInput(1);
- const auto dictType = AS_TYPE(TDictType, dictNode);
- const auto dictKeyType = dictType->GetKeyType();
- const bool isTupleKey = dictKeyType->IsTuple();
- const auto joinKindNode = callable.GetInput(2);
- const auto rawKind = AS_VALUE(TDataLiteral, joinKindNode)->AsValue().Get<ui32>();
- const auto kind = GetJoinKind(rawKind);
- const bool isMany = dictType->GetPayloadType()->IsList();
- const bool boolWithoutRight = EJoinKind::LeftOnly == kind || EJoinKind::LeftSemi == kind;
- const auto returnItemType = type->IsFlow() ?
- AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType():
- AS_TYPE(TStreamType, callable.GetType()->GetReturnType())->GetItemType();
- const auto leftKeyColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(3));
- const auto leftRenamesNode = AS_VALUE(TTupleLiteral, callable.GetInput(4));
- const auto rightRenamesNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
-
- std::vector<ui32> leftKeyColumns, leftRenames, rightRenames;
-
+ const auto type = callable.GetType()->GetReturnType();
+ const auto leftStreamNode = callable.GetInput(0);
+ const auto leftItemType = leftStreamNode.GetStaticType()->IsFlow() ?
+ AS_TYPE(TFlowType, leftStreamNode)->GetItemType():
+ AS_TYPE(TStreamType, leftStreamNode)->GetItemType();
+ const auto dictNode = callable.GetInput(1);
+ const auto dictType = AS_TYPE(TDictType, dictNode);
+ const auto dictKeyType = dictType->GetKeyType();
+ const bool isTupleKey = dictKeyType->IsTuple();
+ const auto joinKindNode = callable.GetInput(2);
+ const auto rawKind = AS_VALUE(TDataLiteral, joinKindNode)->AsValue().Get<ui32>();
+ const auto kind = GetJoinKind(rawKind);
+ const bool isMany = dictType->GetPayloadType()->IsList();
+ const bool boolWithoutRight = EJoinKind::LeftOnly == kind || EJoinKind::LeftSemi == kind;
+ const auto returnItemType = type->IsFlow() ?
+ AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType():
+ AS_TYPE(TStreamType, callable.GetType()->GetReturnType())->GetItemType();
+ const auto leftKeyColumnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(3));
+ const auto leftRenamesNode = AS_VALUE(TTupleLiteral, callable.GetInput(4));
+ const auto rightRenamesNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
+
+ std::vector<ui32> leftKeyColumns, leftRenames, rightRenames;
+
leftKeyColumns.reserve(leftKeyColumnsNode->GetValuesCount());
for (ui32 i = 0; i < leftKeyColumnsNode->GetValuesCount(); ++i) {
- leftKeyColumns.emplace_back(AS_VALUE(TDataLiteral, leftKeyColumnsNode->GetValue(i))->AsValue().Get<ui32>());
+ leftKeyColumns.emplace_back(AS_VALUE(TDataLiteral, leftKeyColumnsNode->GetValue(i))->AsValue().Get<ui32>());
}
leftRenames.reserve(leftRenamesNode->GetValuesCount());
for (ui32 i = 0; i < leftRenamesNode->GetValuesCount(); ++i) {
- leftRenames.emplace_back(AS_VALUE(TDataLiteral, leftRenamesNode->GetValue(i))->AsValue().Get<ui32>());
+ leftRenames.emplace_back(AS_VALUE(TDataLiteral, leftRenamesNode->GetValue(i))->AsValue().Get<ui32>());
}
rightRenames.reserve(rightRenamesNode->GetValuesCount());
for (ui32 i = 0; i < rightRenamesNode->GetValuesCount(); ++i) {
- rightRenames.emplace_back(AS_VALUE(TDataLiteral, rightRenamesNode->GetValue(i))->AsValue().Get<ui32>());
+ rightRenames.emplace_back(AS_VALUE(TDataLiteral, rightRenamesNode->GetValue(i))->AsValue().Get<ui32>());
}
- std::vector<TFunctionDescriptor> leftKeyConverters;
+ std::vector<TFunctionDescriptor> leftKeyConverters;
leftKeyConverters.resize(leftKeyColumns.size());
for (ui32 i = 0; i < leftKeyColumns.size(); ++i) {
- const auto leftColumnType = leftItemType->IsTuple() ?
- AS_TYPE(TTupleType, leftItemType)->GetElementType(leftKeyColumns[i]):
- AS_TYPE(TStructType, leftItemType)->GetMemberType(leftKeyColumns[i]);
+ const auto leftColumnType = leftItemType->IsTuple() ?
+ AS_TYPE(TTupleType, leftItemType)->GetElementType(leftKeyColumns[i]):
+ AS_TYPE(TStructType, leftItemType)->GetMemberType(leftKeyColumns[i]);
bool isLeftOptional;
- const auto leftDataType = UnpackOptionalData(leftColumnType, isLeftOptional);
+ const auto leftDataType = UnpackOptionalData(leftColumnType, isLeftOptional);
bool isRightOptional;
- const auto rightDataType = UnpackOptionalData(isTupleKey ? AS_TYPE(TTupleType, dictKeyType)->GetElementType(i) : dictKeyType, isRightOptional);
+ const auto rightDataType = UnpackOptionalData(isTupleKey ? AS_TYPE(TTupleType, dictKeyType)->GetElementType(i) : dictKeyType, isRightOptional);
if (leftDataType->GetSchemeType() != rightDataType->GetSchemeType()) {
// find a converter
- const std::array<TArgType, 2U> argsTypes = {{{rightDataType->GetSchemeType(), isLeftOptional}, {leftDataType->GetSchemeType(), isLeftOptional}}};
- leftKeyConverters[i] = ctx.FunctionRegistry.GetBuiltins()->GetBuiltin("Convert", argsTypes.data(), 2U);
+ const std::array<TArgType, 2U> argsTypes = {{{rightDataType->GetSchemeType(), isLeftOptional}, {leftDataType->GetSchemeType(), isLeftOptional}}};
+ leftKeyConverters[i] = ctx.FunctionRegistry.GetBuiltins()->GetBuiltin("Convert", argsTypes.data(), 2U);
}
}
- std::vector<EValueRepresentation> outputRepresentations;
- if (returnItemType->IsTuple()) {
- const auto tupleType = AS_TYPE(TTupleType, returnItemType);
- outputRepresentations.reserve(tupleType->GetElementsCount());
- for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i)
- outputRepresentations.emplace_back(GetValueRepresentation(tupleType->GetElementType(i)));
- } else if (returnItemType->IsStruct()) {
- const auto structType = AS_TYPE(TStructType, returnItemType);
- outputRepresentations.reserve(structType->GetMembersCount());
- for (ui32 i = 0U; i < structType->GetMembersCount(); ++i)
- outputRepresentations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
- }
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto dict = LocateNode(ctx.NodeLocator, callable, 1);
-
-#define NEW_WRAPPER(KIND, RIGHT_REQ, IS_TUPLE) \
- if (type->IsFlow()) { \
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) { \
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount(); \
- if (boolWithoutRight) \
- return new TWideMapJoinWrapper<true, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
- std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
- else if (isMany) \
- return new TWideMultiMapJoinWrapper<RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
- std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
- else \
- return new TWideMapJoinWrapper<false, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
- std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
- } else \
- return new TMapJoinCoreFlowWrapper<KIND, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, GetValueRepresentation(type), \
- std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict); \
- } else { \
- return new TMapJoinCoreWrapper<KIND, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
- std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
- std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict); \
- } \
-
-#define MAKE_WRAPPER(IS_TUPLE) \
+ std::vector<EValueRepresentation> outputRepresentations;
+ if (returnItemType->IsTuple()) {
+ const auto tupleType = AS_TYPE(TTupleType, returnItemType);
+ outputRepresentations.reserve(tupleType->GetElementsCount());
+ for (ui32 i = 0U; i < tupleType->GetElementsCount(); ++i)
+ outputRepresentations.emplace_back(GetValueRepresentation(tupleType->GetElementType(i)));
+ } else if (returnItemType->IsStruct()) {
+ const auto structType = AS_TYPE(TStructType, returnItemType);
+ outputRepresentations.reserve(structType->GetMembersCount());
+ for (ui32 i = 0U; i < structType->GetMembersCount(); ++i)
+ outputRepresentations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
+ }
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto dict = LocateNode(ctx.NodeLocator, callable, 1);
+
+#define NEW_WRAPPER(KIND, RIGHT_REQ, IS_TUPLE) \
+ if (type->IsFlow()) { \
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) { \
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount(); \
+ if (boolWithoutRight) \
+ return new TWideMapJoinWrapper<true, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
+ std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
+ else if (isMany) \
+ return new TWideMultiMapJoinWrapper<RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
+ std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
+ else \
+ return new TWideMapJoinWrapper<false, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
+ std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), wide, dict, width); \
+ } else \
+ return new TMapJoinCoreFlowWrapper<KIND, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, GetValueRepresentation(type), \
+ std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict); \
+ } else { \
+ return new TMapJoinCoreWrapper<KIND, RIGHT_REQ, IS_TUPLE>(ctx.Mutables, \
+ std::move(leftKeyConverters), dictType, std::move(outputRepresentations), \
+ std::move(leftKeyColumns), std::move(leftRenames), std::move(rightRenames), flow, dict); \
+ } \
+
+#define MAKE_WRAPPER(IS_TUPLE) \
switch (kind) { \
- case EJoinKind::Inner: \
- if (isMany) { \
- NEW_WRAPPER(ERightKind::Many, true, IS_TUPLE); \
- } else { \
- NEW_WRAPPER(ERightKind::Once, true, IS_TUPLE); \
- } \
- case EJoinKind::Left: \
- if (isMany) { \
- NEW_WRAPPER(ERightKind::Many, false, IS_TUPLE); \
- } else { \
- NEW_WRAPPER(ERightKind::Once, false, IS_TUPLE); \
- } \
- case EJoinKind::LeftOnly: \
- NEW_WRAPPER(ERightKind::None, false, IS_TUPLE); \
- case EJoinKind::LeftSemi: \
- NEW_WRAPPER(ERightKind::None, true, IS_TUPLE); \
- default: \
- ythrow yexception() << "Unsupported join kind"; \
- } \
-
-
+ case EJoinKind::Inner: \
+ if (isMany) { \
+ NEW_WRAPPER(ERightKind::Many, true, IS_TUPLE); \
+ } else { \
+ NEW_WRAPPER(ERightKind::Once, true, IS_TUPLE); \
+ } \
+ case EJoinKind::Left: \
+ if (isMany) { \
+ NEW_WRAPPER(ERightKind::Many, false, IS_TUPLE); \
+ } else { \
+ NEW_WRAPPER(ERightKind::Once, false, IS_TUPLE); \
+ } \
+ case EJoinKind::LeftOnly: \
+ NEW_WRAPPER(ERightKind::None, false, IS_TUPLE); \
+ case EJoinKind::LeftSemi: \
+ NEW_WRAPPER(ERightKind::None, true, IS_TUPLE); \
+ default: \
+ ythrow yexception() << "Unsupported join kind"; \
+ } \
+
+
if (isTupleKey) {
- MAKE_WRAPPER(true)
+ MAKE_WRAPPER(true)
} else {
- MAKE_WRAPPER(false)
+ MAKE_WRAPPER(false)
}
#undef MAKE_WRAPPER
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_multimap.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_multimap.cpp
index 6fce297d46..e9e93aca67 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_multimap.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_multimap.cpp
@@ -1,566 +1,566 @@
-#include "mkql_multimap.h"
+#include "mkql_multimap.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/utils/cast.h>
-
+
#include <util/string/cast.h>
-namespace NKikimr {
-namespace NMiniKQL {
-
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-class TFlowMultiMapWrapper : public TStatefulFlowCodegeneratorNode<TFlowMultiMapWrapper> {
- typedef TStatefulFlowCodegeneratorNode<TFlowMultiMapWrapper> TBaseComputation;
-public:
- TFlowMultiMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
- : TBaseComputation(mutables, flow, kind), Flow(flow), Item(item), NewItems(std::move(newItems))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish())
- return NUdf::TUnboxedValuePod::MakeFinish();
-
- const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
- if (!pos) {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.Release();
- } else {
- Item->SetValue(ctx, std::move(item));
- }
- }
-
- const auto next = pos + 1ULL;
- state = NewItems.size() == next ? NUdf::TUnboxedValuePod::Invalid() : NUdf::TUnboxedValuePod(ui64(next));
- return NewItems[pos]->GetValue(ctx).Release();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto state = new LoadInst(statePtr, "state", block);
-
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- const auto result = PHINode::Create(state->getType(), NewItems.size() + 1U, "result", pass);
-
- const auto choise = SwitchInst::Create(state, zero, NewItems.size() - 1U, block);
-
- for (ui32 i = 1U; i < NewItems.size();) {
- const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(GetConstant(i, context), part);
-
- block = part;
-
- const auto out = GetNodeValue(NewItems[i], ctx, block);
- result->addIncoming(out, block);
- const auto next = ++i;
- new StoreInst(NewItems.size() <= next ? GetInvalid(context) : GetConstant(next, context), statePtr, block);
- BranchInst::Create(pass, block);
- }
-
- {
- block = zero;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
-
- BranchInst::Create(pass, work, IsSpecial(item, block), block);
-
- block = work;
-
- codegenItem->CreateSetValue(ctx, block, item);
- const auto out = GetNodeValue(NewItems.front(), ctx, block);
- result->addIncoming(out, block);
- new StoreInst(GetConstant(1ULL, context), statePtr, block);
- BranchInst::Create(pass, block);
- }
-
- block = pass;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Item);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- const TComputationNodePtrVector NewItems;
-};
-
-class TListMultiMapWrapper : public TBothWaysCodegeneratorNode<TListMultiMapWrapper> {
-private:
- typedef TBothWaysCodegeneratorNode<TListMultiMapWrapper> TBaseComputation;
-
- class TListValue : public TCustomListValue {
- public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, const TComputationNodePtrVector& newItems)
- : TComputationValue<TIterator>(memInfo)
- , CompCtx(compCtx)
- , Iter(std::move(iter))
- , Item(item)
- , NewItems(newItems)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Position) {
- if (!Iter.Next(Item->RefValue(CompCtx))) {
- return false;
- }
- }
-
- value = NewItems[Position]->GetValue(CompCtx);
- if (++Position == NewItems.size())
- Position = 0U;
- return true;
- }
-
- TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- IComputationExternalNode* const Item;
- const TComputationNodePtrVector NewItems;
- size_t Position = 0U;
- };
-
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, const TComputationNodePtrVector& newItems)
- : TCustomListValue(memInfo)
- , CompCtx(compCtx)
- , List(std::move(list))
- , Item(item)
- , NewItems(newItems)
- {}
-
- private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItems);
- }
-
- ui64 GetListLength() const final {
- if (!Length) {
- Length = List.GetListLength() * NewItems.size();
- }
-
- return *Length;
- }
-
- bool HasListItems() const final {
- if (!HasItems) {
- HasItems = List.HasListItems();
- }
-
- return *HasItems;
- }
-
- bool HasFastListLength() const final {
- return List.HasFastListLength();
- }
-
- TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
- const TComputationNodePtrVector NewItems;
- };
-
-public:
- TListMultiMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
- : TBaseComputation(mutables), List(list), Item(item), NewItems(std::move(newItems))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = List->GetValue(ctx);
-
- if (auto elements = list.GetElements()) {
- auto size = list.GetListLength();
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size * NewItems.size(), items);
- while (size--) {
- Item->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
- for (const auto newItem : NewItems)
- *items++ = newItem->GetValue(ctx);
- }
- return result;
- }
-
- return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), Item, NewItems);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- using TCodegenValue = TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>;
-
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<TCodegenValue>(Map, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto map = PHINode::Create(list->getType(), 2U, "map", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
- const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto full = BinaryOperator::CreateMul(size, ConstantInt::get(size->getType(), NewItems.size()), "full", block);
- const auto array = GenNewArray(ctx, full, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- index->addIncoming(ConstantInt::get(size->getType(), 0), block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
-
- BranchInst::Create(next, stop, more, block);
-
- block = next;
- const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto item = new LoadInst(src, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto from = BinaryOperator::CreateMul(index, ConstantInt::get(index->getType(), NewItems.size()), "from", block);
-
- for (ui32 i = 0U; i < NewItems.size(); ++i) {
- const auto pos = BinaryOperator::CreateAdd(from, ConstantInt::get(from->getType(), i), (TString("pos_") += ToString(i)).c_str(), block);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {pos}, (TString("dst_") += ToString(i)).c_str(), block);
- GetNodeValue(dst, NewItems[i], ctx, block);
- }
-
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
- index->addIncoming(plus, block);
- BranchInst::Create(loop, block);
-
- block = stop;
- if (List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- map->addIncoming(array, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListMultiMapWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- map->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- map->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return map;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- Own(Item);
- std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TListMultiMapWrapper::DependsOn, this, std::placeholders::_1));
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListMultiMapWrapper>::GenerateFunctions(codegen);
- MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(MapFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListMultiMapWrapper>::FinalizeFunctions(codegen);
- if (MapFunc)
- Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
- }
-
- Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto positionType = Type::getInt64Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(positionType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+namespace {
+
+class TFlowMultiMapWrapper : public TStatefulFlowCodegeneratorNode<TFlowMultiMapWrapper> {
+ typedef TStatefulFlowCodegeneratorNode<TFlowMultiMapWrapper> TBaseComputation;
+public:
+ TFlowMultiMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
+ : TBaseComputation(mutables, flow, kind), Flow(flow), Item(item), NewItems(std::move(newItems))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish())
+ return NUdf::TUnboxedValuePod::MakeFinish();
+
+ const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
+ if (!pos) {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.Release();
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ }
+ }
+
+ const auto next = pos + 1ULL;
+ state = NewItems.size() == next ? NUdf::TUnboxedValuePod::Invalid() : NUdf::TUnboxedValuePod(ui64(next));
+ return NewItems[pos]->GetValue(ctx).Release();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto state = new LoadInst(statePtr, "state", block);
+
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ const auto result = PHINode::Create(state->getType(), NewItems.size() + 1U, "result", pass);
+
+ const auto choise = SwitchInst::Create(state, zero, NewItems.size() - 1U, block);
+
+ for (ui32 i = 1U; i < NewItems.size();) {
+ const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(GetConstant(i, context), part);
+
+ block = part;
+
+ const auto out = GetNodeValue(NewItems[i], ctx, block);
+ result->addIncoming(out, block);
+ const auto next = ++i;
+ new StoreInst(NewItems.size() <= next ? GetInvalid(context) : GetConstant(next, context), statePtr, block);
+ BranchInst::Create(pass, block);
+ }
+
+ {
+ block = zero;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+
+ BranchInst::Create(pass, work, IsSpecial(item, block), block);
+
+ block = work;
+
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto out = GetNodeValue(NewItems.front(), ctx, block);
+ result->addIncoming(out, block);
+ new StoreInst(GetConstant(1ULL, context), statePtr, block);
+ BranchInst::Create(pass, block);
+ }
+
+ block = pass;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Item);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ const TComputationNodePtrVector NewItems;
+};
+
+class TListMultiMapWrapper : public TBothWaysCodegeneratorNode<TListMultiMapWrapper> {
+private:
+ typedef TBothWaysCodegeneratorNode<TListMultiMapWrapper> TBaseComputation;
+
+ class TListValue : public TCustomListValue {
+ public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, const TComputationNodePtrVector& newItems)
+ : TComputationValue<TIterator>(memInfo)
+ , CompCtx(compCtx)
+ , Iter(std::move(iter))
+ , Item(item)
+ , NewItems(newItems)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Position) {
+ if (!Iter.Next(Item->RefValue(CompCtx))) {
+ return false;
+ }
+ }
+
+ value = NewItems[Position]->GetValue(CompCtx);
+ if (++Position == NewItems.size())
+ Position = 0U;
+ return true;
+ }
+
+ TComputationContext& CompCtx;
+ const NUdf::TUnboxedValue Iter;
+ IComputationExternalNode* const Item;
+ const TComputationNodePtrVector NewItems;
+ size_t Position = 0U;
+ };
+
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& list, IComputationExternalNode* item, const TComputationNodePtrVector& newItems)
+ : TCustomListValue(memInfo)
+ , CompCtx(compCtx)
+ , List(std::move(list))
+ , Item(item)
+ , NewItems(newItems)
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, NewItems);
+ }
+
+ ui64 GetListLength() const final {
+ if (!Length) {
+ Length = List.GetListLength() * NewItems.size();
+ }
+
+ return *Length;
+ }
+
+ bool HasListItems() const final {
+ if (!HasItems) {
+ HasItems = List.HasListItems();
+ }
+
+ return *HasItems;
+ }
+
+ bool HasFastListLength() const final {
+ return List.HasFastListLength();
+ }
+
+ TComputationContext& CompCtx;
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
+ const TComputationNodePtrVector NewItems;
+ };
+
+public:
+ TListMultiMapWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
+ : TBaseComputation(mutables), List(list), Item(item), NewItems(std::move(newItems))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = List->GetValue(ctx);
+
+ if (auto elements = list.GetElements()) {
+ auto size = list.GetListLength();
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(size * NewItems.size(), items);
+ while (size--) {
+ Item->SetValue(ctx, NUdf::TUnboxedValue(*elements++));
+ for (const auto newItem : NewItems)
+ *items++ = newItem->GetValue(ctx);
+ }
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<TListValue>(ctx, std::move(list), Item, NewItems);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ using TCodegenValue = TCustomListCodegenStatefulValueT<TCodegenStatefulIterator<ui64>>;
+
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<TCodegenValue>(Map, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto map = PHINode::Create(list->getType(), 2U, "map", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+ const auto itemsPtr = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto full = BinaryOperator::CreateMul(size, ConstantInt::get(size->getType(), NewItems.size()), "full", block);
+ const auto array = GenNewArray(ctx, full, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ index->addIncoming(ConstantInt::get(size->getType(), 0), block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto more = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, index, "more", block);
+
+ BranchInst::Create(next, stop, more, block);
+
+ block = next;
+ const auto src = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto item = new LoadInst(src, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto from = BinaryOperator::CreateMul(index, ConstantInt::get(index->getType(), NewItems.size()), "from", block);
+
+ for (ui32 i = 0U; i < NewItems.size(); ++i) {
+ const auto pos = BinaryOperator::CreateAdd(from, ConstantInt::get(from->getType(), i), (TString("pos_") += ToString(i)).c_str(), block);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {pos}, (TString("dst_") += ToString(i)).c_str(), block);
+ GetNodeValue(dst, NewItems[i], ctx, block);
+ }
+
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(loop, block);
+
+ block = stop;
+ if (List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ map->addIncoming(array, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListMultiMapWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ map->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ map->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return map;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ Own(Item);
+ std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TListMultiMapWrapper::DependsOn, this, std::placeholders::_1));
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListMultiMapWrapper>::GenerateFunctions(codegen);
+ MapFunc = GenerateMapper(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(MapFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListMultiMapWrapper>::FinalizeFunctions(codegen);
+ if (MapFunc)
+ Map = reinterpret_cast<TMapPtr>(codegen->GetPointerToFunction(MapFunc));
+ }
+
+ Function* GenerateMapper(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto positionType = Type::getInt64Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(positionType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto positionArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto position = new LoadInst(positionArg, "position", false, block);
-
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto choise = SwitchInst::Create(position, zero, NewItems.size() - 1U, block);
-
- for (ui32 i = 1U; i < NewItems.size();) {
- const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(positionType, i), part);
-
- block = part;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, NewItems[i], ctx, block);
- const auto next = ++i;
- new StoreInst(ConstantInt::get(positionType, NewItems.size() <= next ? 0 : next), positionArg, block);
- ReturnInst::Create(context, ConstantInt::getTrue(context), block);
- }
-
- block = zero;
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- BranchInst::Create(good, done, status, block);
- block = good;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- GetNodeValue(valuePtr, NewItems.front(), ctx, block);
- new StoreInst(ConstantInt::get(positionType, 1), positionArg, block);
-
- BranchInst::Create(done, block);
- block = done;
-
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TMapPtr = TCodegenValue::TNextPtr;
-
- Function* MapFunc = nullptr;
-
- TMapPtr Map = nullptr;
-#endif
-
- IComputationNode* const List;
- IComputationExternalNode* const Item;
- const TComputationNodePtrVector NewItems;
-};
-
-class TNarrowMultiMapWrapper : public TStatefulFlowCodegeneratorNode<TNarrowMultiMapWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TNarrowMultiMapWrapper>;
-public:
- TNarrowMultiMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& newItems)
- : TBaseComputation(mutables, flow, kind), Flow(flow), Items(std::move(items)), NewItems(std::move(newItems))
- , PasstroughtMap(GetPasstroughtMap(Items, NewItems)), Fields(Items.size(), nullptr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish())
- return NUdf::TUnboxedValuePod::MakeFinish();
-
- const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
- if (!pos) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U || PasstroughtMap[i])
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- default:
- break;
- }
- }
-
- const auto next = pos + 1ULL;
- state = NewItems.size() == next ? NUdf::TUnboxedValuePod::Invalid() : NUdf::TUnboxedValuePod(ui64(next));
- return NewItems[pos]->GetValue(ctx).Release();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto state = new LoadInst(statePtr, "state", block);
-
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- const auto result = PHINode::Create(state->getType(), NewItems.size() + 1U, "result", pass);
-
- const auto choise = SwitchInst::Create(state, zero, NewItems.size() - 1U, block);
-
- for (ui32 i = 1U; i < NewItems.size();) {
- const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(GetConstant(i, context), part);
-
- block = part;
-
- const auto out = GetNodeValue(NewItems[i], ctx, block);
- result->addIncoming(out, block);
- const auto next = ++i;
- new StoreInst(NewItems.size() <= next ? GetInvalid(context) : GetConstant(next, context), statePtr, block);
- BranchInst::Create(pass, block);
- }
-
- {
- block = zero;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
-
- const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
-
- result->addIncoming(outres, block);
-
- BranchInst::Create(work, pass, good, block);
-
- block = work;
-
- Value* head = nullptr;
- for (auto i = 0U; i < Items.size(); ++i) {
- if (Items[i]->GetDependencesCount() > 0U || PasstroughtMap[i]) {
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto positionArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto position = new LoadInst(positionArg, "position", false, block);
+
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto choise = SwitchInst::Create(position, zero, NewItems.size() - 1U, block);
+
+ for (ui32 i = 1U; i < NewItems.size();) {
+ const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(positionType, i), part);
+
+ block = part;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, NewItems[i], ctx, block);
+ const auto next = ++i;
+ new StoreInst(ConstantInt::get(positionType, NewItems.size() <= next ? 0 : next), positionArg, block);
+ ReturnInst::Create(context, ConstantInt::getTrue(context), block);
+ }
+
+ block = zero;
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ BranchInst::Create(good, done, status, block);
+ block = good;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ GetNodeValue(valuePtr, NewItems.front(), ctx, block);
+ new StoreInst(ConstantInt::get(positionType, 1), positionArg, block);
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TMapPtr = TCodegenValue::TNextPtr;
+
+ Function* MapFunc = nullptr;
+
+ TMapPtr Map = nullptr;
+#endif
+
+ IComputationNode* const List;
+ IComputationExternalNode* const Item;
+ const TComputationNodePtrVector NewItems;
+};
+
+class TNarrowMultiMapWrapper : public TStatefulFlowCodegeneratorNode<TNarrowMultiMapWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TNarrowMultiMapWrapper>;
+public:
+ TNarrowMultiMapWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& newItems)
+ : TBaseComputation(mutables, flow, kind), Flow(flow), Items(std::move(items)), NewItems(std::move(newItems))
+ , PasstroughtMap(GetPasstroughtMap(Items, NewItems)), Fields(Items.size(), nullptr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish())
+ return NUdf::TUnboxedValuePod::MakeFinish();
+
+ const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
+ if (!pos) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U || PasstroughtMap[i])
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ default:
+ break;
+ }
+ }
+
+ const auto next = pos + 1ULL;
+ state = NewItems.size() == next ? NUdf::TUnboxedValuePod::Invalid() : NUdf::TUnboxedValuePod(ui64(next));
+ return NewItems[pos]->GetValue(ctx).Release();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto state = new LoadInst(statePtr, "state", block);
+
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ const auto result = PHINode::Create(state->getType(), NewItems.size() + 1U, "result", pass);
+
+ const auto choise = SwitchInst::Create(state, zero, NewItems.size() - 1U, block);
+
+ for (ui32 i = 1U; i < NewItems.size();) {
+ const auto part = BasicBlock::Create(context, (TString("part_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(GetConstant(i, context), part);
+
+ block = part;
+
+ const auto out = GetNodeValue(NewItems[i], ctx, block);
+ result->addIncoming(out, block);
+ const auto next = ++i;
+ new StoreInst(NewItems.size() <= next ? GetInvalid(context) : GetConstant(next, context), statePtr, block);
+ BranchInst::Create(pass, block);
+ }
+
+ {
+ block = zero;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
+
+ const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
+
+ result->addIncoming(outres, block);
+
+ BranchInst::Create(work, pass, good, block);
+
+ block = work;
+
+ Value* head = nullptr;
+ for (auto i = 0U; i < Items.size(); ++i) {
+ if (Items[i]->GetDependencesCount() > 0U || PasstroughtMap[i]) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, NewItems.front() == Items[i] ? (head = getres.second[i](ctx, block)) : getres.second[i](ctx, block));
- }
- }
-
- const auto out = head ? head : GetNodeValue(NewItems.front(), ctx, block);
- result->addIncoming(out, block);
- new StoreInst(GetConstant(1ULL, context), statePtr, block);
- BranchInst::Create(pass, block);
- }
-
- block = pass;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowMultiMapWrapper::Own, flow, std::placeholders::_1));
- std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TNarrowMultiMapWrapper::DependsOn, flow, std::placeholders::_1));
- }
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- const TComputationNodePtrVector NewItems;
-
- const TPasstroughtMap PasstroughtMap;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-}
-
-IComputationNode* WrapMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected at least three arguments.");
-
- const auto listType = callable.GetInput(0).GetStaticType();
- const auto type = callable.GetType()->GetReturnType();
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
-
- TComputationNodePtrVector newItems;
- newItems.reserve(callable.GetInputsCount() - 2U);
- ui32 index = 1U;
- std::generate_n(std::back_inserter(newItems), callable.GetInputsCount() - 2U, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
- if (listType->IsFlow()) {
- return new TFlowMultiMapWrapper(ctx.Mutables, GetValueRepresentation(type), list, itemArg, std::move(newItems));
- } else if (listType->IsList()) {
- return new TListMultiMapWrapper(ctx.Mutables, list, itemArg, std::move(newItems));
- }
-
- THROW yexception() << "Expected flow or list.";
-}
-
-IComputationNode* WrapNarrowMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected at least three arguments.");
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() > width + 2U, "Wrong signature.");
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- TComputationNodePtrVector newItems;
- newItems.reserve(callable.GetInputsCount() - width - 1U);
- ui32 index = width;
- std::generate_n(std::back_inserter(newItems), callable.GetInputsCount() - width - 1U, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- TComputationExternalNodePtrVector args;
- args.reserve(width);
- index = 0U;
- std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- return new TNarrowMultiMapWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), wide, std::move(args), std::move(newItems));
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-}
+ }
+ }
+
+ const auto out = head ? head : GetNodeValue(NewItems.front(), ctx, block);
+ result->addIncoming(out, block);
+ new StoreInst(GetConstant(1ULL, context), statePtr, block);
+ BranchInst::Create(pass, block);
+ }
+
+ block = pass;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowMultiMapWrapper::Own, flow, std::placeholders::_1));
+ std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TNarrowMultiMapWrapper::DependsOn, flow, std::placeholders::_1));
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ const TComputationNodePtrVector NewItems;
+
+ const TPasstroughtMap PasstroughtMap;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+}
+
+IComputationNode* WrapMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected at least three arguments.");
+
+ const auto listType = callable.GetInput(0).GetStaticType();
+ const auto type = callable.GetType()->GetReturnType();
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+
+ TComputationNodePtrVector newItems;
+ newItems.reserve(callable.GetInputsCount() - 2U);
+ ui32 index = 1U;
+ std::generate_n(std::back_inserter(newItems), callable.GetInputsCount() - 2U, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
+ if (listType->IsFlow()) {
+ return new TFlowMultiMapWrapper(ctx.Mutables, GetValueRepresentation(type), list, itemArg, std::move(newItems));
+ } else if (listType->IsList()) {
+ return new TListMultiMapWrapper(ctx.Mutables, list, itemArg, std::move(newItems));
+ }
+
+ THROW yexception() << "Expected flow or list.";
+}
+
+IComputationNode* WrapNarrowMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected at least three arguments.");
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() > width + 2U, "Wrong signature.");
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ TComputationNodePtrVector newItems;
+ newItems.reserve(callable.GetInputsCount() - width - 1U);
+ ui32 index = width;
+ std::generate_n(std::back_inserter(newItems), callable.GetInputsCount() - width - 1U, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ TComputationExternalNodePtrVector args;
+ args.reserve(width);
+ index = 0U;
+ std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ return new TNarrowMultiMapWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), wide, std::move(args), std::move(newItems));
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_multimap.h b/ydb/library/yql/minikql/comp_nodes/mkql_multimap.h
index ddc71cf816..4dde289fa0 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_multimap.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_multimap.h
@@ -1,12 +1,12 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapNarrowMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapNarrowMultiMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_now.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_now.cpp
index 00cc366eeb..821eedc692 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_now.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_now.cpp
@@ -5,8 +5,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TNowWrapper : public TMutableComputationNode<TNowWrapper> {
typedef TMutableComputationNode<TNowWrapper> TBaseComputation;
public:
@@ -20,16 +20,16 @@ public:
return NUdf::TUnboxedValuePod(ctx.TimeProvider.Now().MicroSeconds());
}
-private:
- void RegisterDependencies() const final {
- std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TNowWrapper::DependsOn, this, std::placeholders::_1));
+private:
+ void RegisterDependencies() const final {
+ std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TNowWrapper::DependsOn, this, std::placeholders::_1));
}
- const TComputationNodePtrVector DependentNodes;
+ const TComputationNodePtrVector DependentNodes;
};
-}
-
+}
+
IComputationNode* WrapNow(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
TComputationNodePtrVector dependentNodes(callable.GetInputsCount());
for (ui32 i = 0; i < callable.GetInputsCount(); ++i) {
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_null.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_null.cpp
index 967dcd1872..a08f71206f 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_null.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_null.cpp
@@ -7,7 +7,7 @@ namespace NMiniKQL {
IComputationNode* WrapNull(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 0, "Expected 0 arg");
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod());
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod());
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_pickle.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_pickle.cpp
index b4557032b6..70c5d93d14 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_pickle.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_pickle.cpp
@@ -8,8 +8,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool Stable>
class TPickleWrapper : public TMutableComputationNode<TPickleWrapper<Stable>> {
typedef TMutableComputationNode<TPickleWrapper<Stable>> TBaseComputation;
@@ -26,14 +26,14 @@ public:
return MakeString(ValuePacker.RefMutableObject(ctx, Stable, Type).Pack(Data->GetValue(ctx)));
}
-private:
- void RegisterDependencies() const final {
+private:
+ void RegisterDependencies() const final {
this->DependsOn(Data);
}
TType* Type;
TMutableObjectOverBoxedValue<TValuePackerBoxed> ValuePacker;
- IComputationNode *const Data;
+ IComputationNode *const Data;
};
class TUnpickleWrapper : public TMutableComputationNode<TUnpickleWrapper> {
@@ -47,20 +47,20 @@ public:
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto data = Data->GetValue(ctx);
auto buffer = data.AsStringRef();
return ValuePacker.RefMutableObject(ctx, false, Type).Unpack(buffer, ctx.HolderFactory).Release();
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Data);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Data);
}
TType* const Type;
TMutableObjectOverBoxedValue<TValuePackerBoxed> ValuePacker;
- IComputationNode *const Data;
+ IComputationNode *const Data;
};
@@ -99,8 +99,8 @@ private:
IComputationNode *const Data;
};
-}
-
+}
+
IComputationNode* WrapPickle(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
return new TPickleWrapper<false>(ctx.Mutables, callable.GetInput(0).GetStaticType(), LocateNode(ctx.NodeLocator, callable, 0));
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_prepend.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_prepend.cpp
index 888952f13e..6789c4208d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_prepend.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_prepend.cpp
@@ -6,119 +6,119 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsVoid>
-class TPrependWrapper : public TMutableCodegeneratorNode<TPrependWrapper<IsVoid>> {
- typedef TMutableCodegeneratorNode<TPrependWrapper<IsVoid>> TBaseComputation;
+namespace {
+
+template<bool IsVoid>
+class TPrependWrapper : public TMutableCodegeneratorNode<TPrependWrapper<IsVoid>> {
+ typedef TMutableCodegeneratorNode<TPrependWrapper<IsVoid>> TBaseComputation;
public:
TPrependWrapper(TComputationMutables& mutables, IComputationNode* left, IComputationNode* right)
- : TBaseComputation(mutables, right->GetRepresentation())
+ : TBaseComputation(mutables, right->GetRepresentation())
, Left(left)
, Right(right)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto left = Left->GetValue(ctx);
- auto right = Right->GetValue(ctx);
+ auto right = Right->GetValue(ctx);
+
+ if (IsVoid && !left.IsBoxed())
+ return right.Release();
- if (IsVoid && !left.IsBoxed())
- return right.Release();
-
- return ctx.HolderFactory.Prepend(left.Release(), right.Release());
+ return ctx.HolderFactory.Prepend(left.Release(), right.Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Prepend));
-
- const auto left = GetNodeValue(Left, ctx, block);
- const auto right = GetNodeValue(Right, ctx, block);
-
- if (IsVoid) {
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(right->getType(), 2, "result", done);
- result->addIncoming(right, block);
-
- const uint64_t init[] = {0x0ULL, 0x300000000000000ULL};
- const auto mask = ConstantInt::get(left->getType(), APInt(128, 2, init));
- const auto boxed = BinaryOperator::CreateAnd(left, mask, "boxed", block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, boxed, mask, "check", block);
- BranchInst::Create(work, done, check, block);
- block = work;
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(right->getType(), {factory->getType(), left->getType(), right->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
- result->addIncoming(res, block);
- } else {
- const auto retPtr = new AllocaInst(right->getType(), 0U, "ret_ptr", block);
- const auto itemPtr = new AllocaInst(left->getType(), 0U, "item_ptr", block);
- new StoreInst(right, retPtr, block);
- new StoreInst(left, itemPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), itemPtr->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, itemPtr, retPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- result->addIncoming(res, block);
- }
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(right->getType(), {factory->getType(), left->getType(), right->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
- return res;
- } else {
- const auto retPtr = new AllocaInst(right->getType(), 0U, "ret_ptr", block);
- const auto itemPtr = new AllocaInst(left->getType(), 0U, "item_ptr", block);
- new StoreInst(right, retPtr, block);
- new StoreInst(left, itemPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), itemPtr->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, itemPtr, retPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- return res;
- }
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Left);
- this->DependsOn(Right);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::Prepend));
+
+ const auto left = GetNodeValue(Left, ctx, block);
+ const auto right = GetNodeValue(Right, ctx, block);
+
+ if (IsVoid) {
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(right->getType(), 2, "result", done);
+ result->addIncoming(right, block);
+
+ const uint64_t init[] = {0x0ULL, 0x300000000000000ULL};
+ const auto mask = ConstantInt::get(left->getType(), APInt(128, 2, init));
+ const auto boxed = BinaryOperator::CreateAnd(left, mask, "boxed", block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, boxed, mask, "check", block);
+ BranchInst::Create(work, done, check, block);
+ block = work;
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(right->getType(), {factory->getType(), left->getType(), right->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
+ result->addIncoming(res, block);
+ } else {
+ const auto retPtr = new AllocaInst(right->getType(), 0U, "ret_ptr", block);
+ const auto itemPtr = new AllocaInst(left->getType(), 0U, "item_ptr", block);
+ new StoreInst(right, retPtr, block);
+ new StoreInst(left, itemPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), itemPtr->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, itemPtr, retPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ result->addIncoming(res, block);
+ }
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(right->getType(), {factory->getType(), left->getType(), right->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory, left, right}, "res", block);
+ return res;
+ } else {
+ const auto retPtr = new AllocaInst(right->getType(), 0U, "ret_ptr", block);
+ const auto itemPtr = new AllocaInst(left->getType(), 0U, "item_ptr", block);
+ new StoreInst(right, retPtr, block);
+ new StoreInst(left, itemPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), itemPtr->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, itemPtr, retPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ return res;
+ }
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Left);
+ this->DependsOn(Right);
}
IComputationNode* const Left;
IComputationNode* const Right;
};
-}
-
+}
+
IComputationNode* WrapPrepend(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto leftType = callable.GetInput(0).GetStaticType();
- const auto rightType = AS_TYPE(TListType, callable.GetInput(1));
+ const auto leftType = callable.GetInput(0).GetStaticType();
+ const auto rightType = AS_TYPE(TListType, callable.GetInput(1));
- MKQL_ENSURE(rightType->GetItemType()->IsSameType(*leftType), "Mismatch item type");
+ MKQL_ENSURE(rightType->GetItemType()->IsSameType(*leftType), "Mismatch item type");
- const auto left = LocateNode(ctx.NodeLocator, callable, 0);
- const auto right = LocateNode(ctx.NodeLocator, callable, 1);
- if (leftType->IsVoid())
+ const auto left = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto right = LocateNode(ctx.NodeLocator, callable, 1);
+ if (leftType->IsVoid())
return new TPrependWrapper<true>(ctx.Mutables, left, right);
- else
+ else
return new TPrependWrapper<false>(ctx.Mutables, left, right);
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_queue.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_queue.cpp
index c151a457ed..49cc897f0e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_queue.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_queue.cpp
@@ -9,14 +9,14 @@ namespace NKikimr {
using namespace NUdf;
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TQueueResource : public TComputationValue<TQueueResource> {
public:
TQueueResource(TMemoryUsageInfo* memInfo, const TStringBuf& tag, TMaybe<ui64> capacity, ui64 initSize)
: TComputationValue(memInfo)
, ResourceTag(tag)
- , Buffer(capacity, TUnboxedValue(), initSize)
+ , Buffer(capacity, TUnboxedValue(), initSize)
, BufferBytes(CurrentMemUsage())
{
MKQL_MEM_TAKE(memInfo, &Buffer, BufferBytes);
@@ -34,11 +34,11 @@ public:
MKQL_MEM_TAKE(GetMemInfo(), &Buffer, BufferBytes);
}
- TSafeCircularBuffer<TUnboxedValue>& GetBuffer() {
- return Buffer;
- }
-
-private:
+ TSafeCircularBuffer<TUnboxedValue>& GetBuffer() {
+ return Buffer;
+ }
+
+private:
NUdf::TStringRef GetResourceTag() const override {
return NUdf::TStringRef(ResourceTag);
}
@@ -60,14 +60,14 @@ class TQueueResource;
class TQueueResourceUser {
public:
TQueueResourceUser(TStringBuf&& tag, IComputationNode* resource);
- TSafeCircularBuffer<NUdf::TUnboxedValue>& CheckAndGetBuffer(const NUdf::TUnboxedValuePod& resource) const;
+ TSafeCircularBuffer<NUdf::TUnboxedValue>& CheckAndGetBuffer(const NUdf::TUnboxedValuePod& resource) const;
void UpdateBufferStats(const NUdf::TUnboxedValuePod& resource) const;
protected:
const TStringBuf Tag;
IComputationNode* const Resource;
- TQueueResource& GetResource(const NUdf::TUnboxedValuePod& resource) const;
+ TQueueResource& GetResource(const NUdf::TUnboxedValuePod& resource) const;
};
TQueueResourceUser::TQueueResourceUser(TStringBuf&& tag, IComputationNode* resource)
@@ -75,7 +75,7 @@ TQueueResourceUser::TQueueResourceUser(TStringBuf&& tag, IComputationNode* resou
, Resource(resource)
{}
-TSafeCircularBuffer<TUnboxedValue>& TQueueResourceUser::CheckAndGetBuffer(const TUnboxedValuePod& resource) const {
+TSafeCircularBuffer<TUnboxedValue>& TQueueResourceUser::CheckAndGetBuffer(const TUnboxedValuePod& resource) const {
return GetResource(resource).GetBuffer();
}
@@ -83,33 +83,33 @@ void TQueueResourceUser::UpdateBufferStats(const TUnboxedValuePod& resource) con
GetResource(resource).UpdateBufferStats();
}
-TQueueResource& TQueueResourceUser::GetResource(const TUnboxedValuePod& resource) const {
+TQueueResource& TQueueResourceUser::GetResource(const TUnboxedValuePod& resource) const {
const TStringBuf tag = resource.GetResourceTag();
Y_VERIFY_DEBUG(tag == Tag, "Expected correct Queue resource");
return *static_cast<TQueueResource*>(resource.GetResource());
}
-class TQueueCreateWrapper : public TMutableComputationNode<TQueueCreateWrapper> {
+class TQueueCreateWrapper : public TMutableComputationNode<TQueueCreateWrapper> {
typedef TMutableComputationNode<TQueueCreateWrapper> TBaseComputation;
public:
TQueueCreateWrapper(TComputationMutables& mutables, TComputationNodePtrVector&& dependentNodes, const TString& name, TMaybe<ui64> capacity, ui64 initSize)
: TBaseComputation(mutables)
, DependentNodes(std::move(dependentNodes))
- , Name(name)
+ , Name(name)
, Capacity(capacity)
, InitSize(initSize)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return NUdf::TUnboxedValuePod(new TQueueResource(&ctx.HolderFactory.GetMemInfo(), Name, Capacity, InitSize));
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return NUdf::TUnboxedValuePod(new TQueueResource(&ctx.HolderFactory.GetMemInfo(), Name, Capacity, InitSize));
}
private:
- void RegisterDependencies() const final {
- std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TQueueCreateWrapper::DependsOn, this, std::placeholders::_1));
- }
-
- const TComputationNodePtrVector DependentNodes;
+ void RegisterDependencies() const final {
+ std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TQueueCreateWrapper::DependsOn, this, std::placeholders::_1));
+ }
+
+ const TComputationNodePtrVector DependentNodes;
const TString Name;
const TMaybe<ui64> Capacity;
const ui64 InitSize;
@@ -131,13 +131,13 @@ public:
if (buffer.IsUnbounded()) {
UpdateBufferStats(resource);
}
- return resource.Release();
+ return resource.Release();
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Resource);
- DependsOn(Value);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Resource);
+ DependsOn(Value);
}
IComputationNode* const Value;
@@ -154,40 +154,40 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto resource = Resource->GetValue(ctx);
CheckAndGetBuffer(resource).PopFront();
- return resource.Release();
+ return resource.Release();
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Resource);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Resource);
}
};
-class TQueuePeekWrapper : public TMutableComputationNode<TQueuePeekWrapper>, public TQueueResourceUser {
+class TQueuePeekWrapper : public TMutableComputationNode<TQueuePeekWrapper>, public TQueueResourceUser {
typedef TMutableComputationNode<TQueuePeekWrapper> TBaseComputation;
public:
TQueuePeekWrapper(TComputationMutables& mutables, TComputationNodePtrVector&& dependentNodes, const TResourceType* resourceType, IComputationNode* resource, IComputationNode* index)
: TBaseComputation(mutables)
, TQueueResourceUser(resourceType->GetTag(), resource)
- , Index(index), DependentNodes(std::move(dependentNodes))
+ , Index(index), DependentNodes(std::move(dependentNodes))
{}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
auto resource = Resource->GetValue(ctx);
auto index = Index->GetValue(ctx);
const auto& valRef = CheckAndGetBuffer(resource).Get(index.Get<ui64>());
- return !valRef ? NUdf::TUnboxedValuePod() : valRef.MakeOptional();
+ return !valRef ? NUdf::TUnboxedValuePod() : valRef.MakeOptional();
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Resource);
- DependsOn(Index);
- std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TQueuePeekWrapper::DependsOn, this, std::placeholders::_1));
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Resource);
+ DependsOn(Index);
+ std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TQueuePeekWrapper::DependsOn, this, std::placeholders::_1));
}
IComputationNode* const Index;
- const TComputationNodePtrVector DependentNodes;
+ const TComputationNodePtrVector DependentNodes;
};
class TQueueRangeWrapper : public TMutableComputationNode<TQueueRangeWrapper>, public TQueueResourceUser {
@@ -317,7 +317,7 @@ public:
, FrontIndex(Buffer.UsedSize())
{}
-private:
+private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value) override {
NUdf::TUnboxedValue item;
if (State != EPreserveState::Feed) {
@@ -355,11 +355,11 @@ private:
GoOn,
Emit,
};
- const NUdf::TUnboxedValue Stream;
+ const NUdf::TUnboxedValue Stream;
const NUdf::TUnboxedValue Queue;
const ui64 OutpaceGoal;
TSafeCircularBuffer<TUnboxedValue>& Buffer;
- const size_t FrontIndex;
+ const size_t FrontIndex;
EPreserveState State = EPreserveState::Feed;
ui64 Outpace = 0;
@@ -375,31 +375,31 @@ public:
, Outpace(outpace)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TPreserveStreamValue>(Stream->GetValue(ctx), Resource->GetValue(ctx), Tag, Resource, Outpace);
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Resource);
- DependsOn(Stream);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Resource);
+ DependsOn(Stream);
}
IComputationNode* const Stream;
const ui64 Outpace;
};
-template<class T, class...Args>
-IComputationNode* MakeNodeWithDeps(TCallable& callable, const TComputationNodeFactoryContext& ctx, unsigned reqArgs, Args...args) {
- TComputationNodePtrVector dependentNodes(callable.GetInputsCount() - reqArgs);
+template<class T, class...Args>
+IComputationNode* MakeNodeWithDeps(TCallable& callable, const TComputationNodeFactoryContext& ctx, unsigned reqArgs, Args...args) {
+ TComputationNodePtrVector dependentNodes(callable.GetInputsCount() - reqArgs);
for (ui32 i = reqArgs; i < callable.GetInputsCount(); ++i) {
dependentNodes[i - reqArgs] = LocateNode(ctx.NodeLocator, callable, i);
}
return new T(ctx.Mutables, std::move(dependentNodes), std::forward<Args>(args)...);
}
-}
-
+}
+
IComputationNode* WrapQueueCreate(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
const unsigned reqArgs = 3;
MKQL_ENSURE(callable.GetInputsCount() >= reqArgs, "QueueCreate: Expected at least " << reqArgs << " arg");
@@ -410,9 +410,9 @@ IComputationNode* WrapQueueCreate(TCallable& callable, const TComputationNodeFac
capacity = queueCapacityValue->AsValue().Get<ui64>();
}
auto queueInitSizeValue = AS_VALUE(TDataLiteral, callable.GetInput(2));
- const TString name(queueNameValue->AsValue().AsStringRef());
- const auto initSize = queueInitSizeValue->AsValue().Get<ui64>();
- return MakeNodeWithDeps<TQueueCreateWrapper>(callable, ctx, reqArgs, name, capacity, initSize);
+ const TString name(queueNameValue->AsValue().AsStringRef());
+ const auto initSize = queueInitSizeValue->AsValue().Get<ui64>();
+ return MakeNodeWithDeps<TQueueCreateWrapper>(callable, ctx, reqArgs, name, capacity, initSize);
}
IComputationNode* WrapQueuePush(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
@@ -438,7 +438,7 @@ IComputationNode* WrapQueuePeek(TCallable& callable, const TComputationNodeFacto
MKQL_ENSURE(indexType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64 as queue index");
auto resource = LocateNode(ctx.NodeLocator, callable, 0);
auto index = LocateNode(ctx.NodeLocator, callable, 1);
- return MakeNodeWithDeps<TQueuePeekWrapper>(callable, ctx, reqArgs, resourceType, resource, index);
+ return MakeNodeWithDeps<TQueuePeekWrapper>(callable, ctx, reqArgs, resourceType, resource, index);
}
IComputationNode* WrapQueueRange(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_random.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_random.cpp
index 7a81f34a59..b489966771 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_random.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_random.cpp
@@ -8,8 +8,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TRandomMTResource : public TComputationValue<TRandomMTResource> {
public:
TRandomMTResource(TMemoryUsageInfo* memInfo, ui64 seed)
@@ -18,7 +18,7 @@ public:
{
}
-private:
+private:
NUdf::TStringRef GetResourceTag() const override {
return NUdf::TStringRef(RandomMTResource);
}
@@ -41,12 +41,12 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx) const {
const ui64 seedValue = Seed->GetValue(compCtx).Get<ui64>();
- return compCtx.HolderFactory.Create<TRandomMTResource>(seedValue);
+ return compCtx.HolderFactory.Create<TRandomMTResource>(seedValue);
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Seed);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Seed);
}
IComputationNode* const Seed;
@@ -62,23 +62,23 @@ public:
{
}
- NUdf::TUnboxedValue DoCalculate(TComputationContext& compCtx) const {
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& compCtx) const {
auto rand = Rand->GetValue(compCtx);
Y_VERIFY_DEBUG(rand.GetResourceTag() == NUdf::TStringRef(RandomMTResource));
- NUdf::TUnboxedValue *items = nullptr;
- const auto tuple = ResPair.NewArray(compCtx, 2, items);
- items[0] = NUdf::TUnboxedValuePod(static_cast<TMersenne<ui64>*>(rand.GetResource())->GenRand());
- items[1] = std::move(rand);
- return tuple;
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto tuple = ResPair.NewArray(compCtx, 2, items);
+ items[0] = NUdf::TUnboxedValuePod(static_cast<TMersenne<ui64>*>(rand.GetResource())->GenRand());
+ items[1] = std::move(rand);
+ return tuple;
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Rand);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Rand);
}
IComputationNode* const Rand;
- const TContainerCacheOnContext ResPair;
+ const TContainerCacheOnContext ResPair;
};
template <ERandom Rnd>
@@ -106,16 +106,16 @@ public:
Y_FAIL("Unexpected");
}
-private:
- void RegisterDependencies() const final {
- std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TRandomWrapper::DependsOn, this, std::placeholders::_1));
+private:
+ void RegisterDependencies() const final {
+ std::for_each(DependentNodes.cbegin(), DependentNodes.cend(), std::bind(&TRandomWrapper::DependsOn, this, std::placeholders::_1));
}
- const TComputationNodePtrVector DependentNodes;
+ const TComputationNodePtrVector DependentNodes;
};
-}
-
+}
+
IComputationNode* WrapNewMTRand(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_reduce.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_reduce.cpp
index 4a0a2e32bd..a0bf05f0ac 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_reduce.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_reduce.cpp
@@ -6,17 +6,17 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsStream>
-class TReduceWrapper : public TMutableCodegeneratorRootNode<TReduceWrapper<IsStream>> {
- typedef TMutableCodegeneratorRootNode<TReduceWrapper<IsStream>> TBaseComputation;
+namespace {
+
+template<bool IsStream>
+class TReduceWrapper : public TMutableCodegeneratorRootNode<TReduceWrapper<IsStream>> {
+ typedef TMutableCodegeneratorRootNode<TReduceWrapper<IsStream>> TBaseComputation;
public:
- TReduceWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state1,
+ TReduceWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list, IComputationExternalNode* item, IComputationExternalNode* state1,
IComputationNode* newState1, IComputationNode* newState2,
- IComputationNode* initialState1, IComputationExternalNode* itemState2, IComputationExternalNode* state3,
+ IComputationNode* initialState1, IComputationExternalNode* itemState2, IComputationExternalNode* state3,
IComputationNode* newState3, IComputationNode* initialState3)
- : TBaseComputation(mutables, kind)
+ : TBaseComputation(mutables, kind)
, List(list)
, Item(item)
, State1(state1)
@@ -38,113 +38,113 @@ public:
[this, &compCtx] (NUdf::TUnboxedValue&& item) {
Item->SetValue(compCtx, std::move(item));
State1->SetValue(compCtx, NewState1->GetValue(compCtx));
- }
- );
+ }
+ );
ItemState2->SetValue(compCtx, NewState2->GetValue(compCtx));
return NewState3->GetValue(compCtx).Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto &context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- const auto codegenState1 = dynamic_cast<ICodegeneratorExternalNode*>(State1);
- const auto codegenItemState2 = dynamic_cast<ICodegeneratorExternalNode*>(ItemState2);
- const auto codegenState3 = dynamic_cast<ICodegeneratorExternalNode*>(State3);
-
- MKQL_ENSURE(codegenState1, "State1 must be codegenerator node.");
- MKQL_ENSURE(codegenState3, "State3 must be codegenerator node.");
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
- MKQL_ENSURE(codegenItemState2, "ItemState2 must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init1 = GetNodeValue(InitialState1, ctx, block);
-
- codegenState1->CreateSetValue(ctx, block, init1);
-
- const auto init3 = GetNodeValue(InitialState3, ctx, block);
-
- codegenState3->CreateSetValue(ctx, block, init3);
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto itemPtr = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(valueType, 0U, "item_ptr", block);
- new StoreInst(ConstantInt::get(valueType, 0), itemPtr, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- if constexpr (IsStream) {
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(Type::getInt32Ty(context), list, ctx.Codegen, block, itemPtr);
-
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block);
-
- BranchInst::Create(done, good, icmp, block);
- block = good;
-
- codegenItem->CreateSetValue(ctx, block, itemPtr);
-
- const auto newState1 = GetNodeValue(NewState1, ctx, block);
-
- codegenState1->CreateSetValue(ctx, block, newState1);
-
- BranchInst::Create(loop, block);
-
- block = done;
- } else {
- const auto iterPtr = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(valueType, 0U, "iter_ptr", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
- const auto iter = new LoadInst(iterPtr, "iter", block);
-
- BranchInst::Create(loop, block);
- block = loop;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
-
- BranchInst::Create(done, good, icmp, block);
- block = good;
-
- codegenItem->CreateSetValue(ctx, block, itemPtr);
-
- const auto newState1 = GetNodeValue(NewState1, ctx, block);
-
- codegenState1->CreateSetValue(ctx, block, newState1);
-
- BranchInst::Create(loop, block);
-
- block = done;
- UnRefBoxed(iter, ctx, block);
- }
-
- const auto newState2 = GetNodeValue(NewState2, ctx, block);
-
- codegenItemState2->CreateSetValue(ctx, block, newState2);
-
- const auto newState3 = GetNodeValue(NewState3, ctx, block);
-
- return newState3;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
- this->DependsOn(InitialState1);
- this->DependsOn(InitialState3);
- this->DependsOn(NewState1);
- this->DependsOn(NewState2);
- this->DependsOn(NewState3);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto &context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ const auto codegenState1 = dynamic_cast<ICodegeneratorExternalNode*>(State1);
+ const auto codegenItemState2 = dynamic_cast<ICodegeneratorExternalNode*>(ItemState2);
+ const auto codegenState3 = dynamic_cast<ICodegeneratorExternalNode*>(State3);
+
+ MKQL_ENSURE(codegenState1, "State1 must be codegenerator node.");
+ MKQL_ENSURE(codegenState3, "State3 must be codegenerator node.");
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+ MKQL_ENSURE(codegenItemState2, "ItemState2 must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init1 = GetNodeValue(InitialState1, ctx, block);
+
+ codegenState1->CreateSetValue(ctx, block, init1);
+
+ const auto init3 = GetNodeValue(InitialState3, ctx, block);
+
+ codegenState3->CreateSetValue(ctx, block, init3);
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto itemPtr = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(valueType, 0U, "item_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(valueType, 0U, "item_ptr", block);
+ new StoreInst(ConstantInt::get(valueType, 0), itemPtr, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ if constexpr (IsStream) {
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(Type::getInt32Ty(context), list, ctx.Codegen, block, itemPtr);
+
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, status, ConstantInt::get(status->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block);
+
+ BranchInst::Create(done, good, icmp, block);
+ block = good;
+
+ codegenItem->CreateSetValue(ctx, block, itemPtr);
+
+ const auto newState1 = GetNodeValue(NewState1, ctx, block);
+
+ codegenState1->CreateSetValue(ctx, block, newState1);
+
+ BranchInst::Create(loop, block);
+
+ block = done;
+ } else {
+ const auto iterPtr = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(valueType, 0U, "iter_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(valueType, 0U, "iter_ptr", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(iterPtr, list, ctx.Codegen, block);
+ const auto iter = new LoadInst(iterPtr, "iter", block);
+
+ BranchInst::Create(loop, block);
+ block = loop;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, itemPtr);
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::getFalse(context), "cond", block);
+
+ BranchInst::Create(done, good, icmp, block);
+ block = good;
+
+ codegenItem->CreateSetValue(ctx, block, itemPtr);
+
+ const auto newState1 = GetNodeValue(NewState1, ctx, block);
+
+ codegenState1->CreateSetValue(ctx, block, newState1);
+
+ BranchInst::Create(loop, block);
+
+ block = done;
+ UnRefBoxed(iter, ctx, block);
+ }
+
+ const auto newState2 = GetNodeValue(NewState2, ctx, block);
+
+ codegenItemState2->CreateSetValue(ctx, block, newState2);
+
+ const auto newState3 = GetNodeValue(NewState3, ctx, block);
+
+ return newState3;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
+ this->DependsOn(InitialState1);
+ this->DependsOn(InitialState3);
+ this->DependsOn(NewState1);
+ this->DependsOn(NewState2);
+ this->DependsOn(NewState3);
this->Own(Item);
this->Own(State1);
this->Own(ItemState2);
@@ -152,19 +152,19 @@ private:
}
IComputationNode* const List;
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State1;
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State1;
IComputationNode* const NewState1;
IComputationNode* const NewState2;
IComputationNode* const InitialState1;
- IComputationExternalNode* const ItemState2;
- IComputationExternalNode* const State3;
+ IComputationExternalNode* const ItemState2;
+ IComputationExternalNode* const State3;
IComputationNode* const NewState3;
IComputationNode* const InitialState3;
};
-}
-
+}
+
IComputationNode* WrapReduce(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 10, "Expected 10 args");
@@ -174,18 +174,18 @@ IComputationNode* WrapReduce(TCallable& callable, const TComputationNodeFactoryC
auto newState1 = LocateNode(ctx.NodeLocator, callable, 5);
auto newState2 = LocateNode(ctx.NodeLocator, callable, 6);
auto newState3 = LocateNode(ctx.NodeLocator, callable, 9);
- auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
- auto state1NodeArg = LocateExternalNode(ctx.NodeLocator, callable, 4);
- auto itemState2Arg = LocateExternalNode(ctx.NodeLocator, callable, 7);
- auto state3NodeArg = LocateExternalNode(ctx.NodeLocator, callable, 8);
- const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
- if (callable.GetInput(0).GetStaticType()->IsStream()) {
- return new TReduceWrapper<true>(ctx.Mutables, kind, list, itemArg, state1NodeArg, newState1, newState2,
- initialState1, itemState2Arg, state3NodeArg, newState3, initialState3);
- } else {
- return new TReduceWrapper<false>(ctx.Mutables, kind, list, itemArg, state1NodeArg, newState1, newState2,
- initialState1, itemState2Arg, state3NodeArg, newState3, initialState3);
- }
+ auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ auto state1NodeArg = LocateExternalNode(ctx.NodeLocator, callable, 4);
+ auto itemState2Arg = LocateExternalNode(ctx.NodeLocator, callable, 7);
+ auto state3NodeArg = LocateExternalNode(ctx.NodeLocator, callable, 8);
+ const auto kind = GetValueRepresentation(callable.GetType()->GetReturnType());
+ if (callable.GetInput(0).GetStaticType()->IsStream()) {
+ return new TReduceWrapper<true>(ctx.Mutables, kind, list, itemArg, state1NodeArg, newState1, newState2,
+ initialState1, itemState2Arg, state3NodeArg, newState3, initialState3);
+ } else {
+ return new TReduceWrapper<false>(ctx.Mutables, kind, list, itemArg, state1NodeArg, newState1, newState2,
+ initialState1, itemState2Arg, state3NodeArg, newState3, initialState3);
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_removemember.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_removemember.cpp
index 28ec32b0eb..bd5f29452c 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_removemember.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_removemember.cpp
@@ -6,24 +6,24 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TRemoveMemberWrapper : public TMutableCodegeneratorFallbackNode<TRemoveMemberWrapper> {
- typedef TMutableCodegeneratorFallbackNode<TRemoveMemberWrapper> TBaseComputation;
+namespace {
+
+class TRemoveMemberWrapper : public TMutableCodegeneratorFallbackNode<TRemoveMemberWrapper> {
+ typedef TMutableCodegeneratorFallbackNode<TRemoveMemberWrapper> TBaseComputation;
public:
- TRemoveMemberWrapper(TComputationMutables& mutables, IComputationNode* structObj, ui32 index, std::vector<EValueRepresentation>&& representations)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ TRemoveMemberWrapper(TComputationMutables& mutables, IComputationNode* structObj, ui32 index, std::vector<EValueRepresentation>&& representations)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, StructObj(structObj)
, Index(index)
- , Representations(std::move(representations))
+ , Representations(std::move(representations))
, Cache(mutables)
- {}
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& baseStruct = StructObj->GetValue(ctx);
- NUdf::TUnboxedValue* itemsPtr = nullptr;
- const auto result = Cache.NewArray(ctx, Representations.size() - 1U, itemsPtr);
+ NUdf::TUnboxedValue* itemsPtr = nullptr;
+ const auto result = Cache.NewArray(ctx, Representations.size() - 1U, itemsPtr);
if (Representations.size() > 1) {
Y_VERIFY(itemsPtr);
if (const auto ptr = baseStruct.GetElements()) {
@@ -38,123 +38,123 @@ public:
for (ui32 i = 0; i < Index; ++i) {
*itemsPtr++ = baseStruct.GetElement(i);
}
-
+
for (ui32 i = Index + 1; i < Representations.size(); ++i) {
*itemsPtr++ = baseStruct.GetElement(i);
}
- }
+ }
}
- return result;
+ return result;
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- if (Representations.size() > CodegenArraysFallbackLimit)
- return TBaseComputation::DoGenerateGetValue(ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto newSize = Representations.size() - 1U;
-
- const auto valType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valType);
- const auto idxType = Type::getInt32Ty(context);
- const auto type = ArrayType::get(valType, newSize);
- const auto itms = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
- const auto result = Cache.GenNewArray(newSize, itms, ctx, block);
- const auto itemsPtr = new LoadInst(itms, "items", block);
-
- const auto array = GetNodeValue(StructObj, ctx, block);
-
- const auto zero = ConstantInt::get(idxType, 0);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, array, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- for (ui32 i = 0; i < Index; ++i) {
- const auto index = ConstantInt::get(idxType, i);
- const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
- const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "dst", block);
- const auto item = new LoadInst(srcPtr, "item", block);
- new StoreInst(item, dstPtr, block);
- ValueAddRef(Representations[i], dstPtr, ctx, block);
- }
-
- for (ui32 i = Index + 1U; i < Representations.size(); ++i) {
- const auto oldIndex = ConstantInt::get(idxType, i);
- const auto newIndex = ConstantInt::get(idxType, i - 1U);
- const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "src", block);
- const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "dst", block);
- const auto item = new LoadInst(srcPtr, "item", block);
- new StoreInst(item, dstPtr, block);
- ValueAddRef(Representations[i], dstPtr, ctx, block);
- }
- BranchInst::Create(done, block);
- }
- {
- block = slow;
- for (ui32 i = 0; i < Index; ++i) {
- const auto index = ConstantInt::get(idxType, i);
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, index);
- }
-
- for (ui32 i = Index + 1U; i < Representations.size(); ++i) {
- const auto oldIndex = ConstantInt::get(idxType, i);
- const auto newIndex = ConstantInt::get(idxType, i - 1U);
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "item", block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, oldIndex);
- }
- BranchInst::Create(done, block);
- }
- block = done;
- if (StructObj->IsTemporaryValue())
- CleanupBoxed(array, ctx, block);
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(StructObj);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ if (Representations.size() > CodegenArraysFallbackLimit)
+ return TBaseComputation::DoGenerateGetValue(ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto newSize = Representations.size() - 1U;
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valType);
+ const auto idxType = Type::getInt32Ty(context);
+ const auto type = ArrayType::get(valType, newSize);
+ const auto itms = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
+ const auto result = Cache.GenNewArray(newSize, itms, ctx, block);
+ const auto itemsPtr = new LoadInst(itms, "items", block);
+
+ const auto array = GetNodeValue(StructObj, ctx, block);
+
+ const auto zero = ConstantInt::get(idxType, 0);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, array, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ for (ui32 i = 0; i < Index; ++i) {
+ const auto index = ConstantInt::get(idxType, i);
+ const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {index}, "src", block);
+ const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "dst", block);
+ const auto item = new LoadInst(srcPtr, "item", block);
+ new StoreInst(item, dstPtr, block);
+ ValueAddRef(Representations[i], dstPtr, ctx, block);
+ }
+
+ for (ui32 i = Index + 1U; i < Representations.size(); ++i) {
+ const auto oldIndex = ConstantInt::get(idxType, i);
+ const auto newIndex = ConstantInt::get(idxType, i - 1U);
+ const auto srcPtr = GetElementPtrInst::CreateInBounds(elements, {oldIndex}, "src", block);
+ const auto dstPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "dst", block);
+ const auto item = new LoadInst(srcPtr, "item", block);
+ new StoreInst(item, dstPtr, block);
+ ValueAddRef(Representations[i], dstPtr, ctx, block);
+ }
+ BranchInst::Create(done, block);
+ }
+ {
+ block = slow;
+ for (ui32 i = 0; i < Index; ++i) {
+ const auto index = ConstantInt::get(idxType, i);
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, index}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, index);
+ }
+
+ for (ui32 i = Index + 1U; i < Representations.size(); ++i) {
+ const auto oldIndex = ConstantInt::get(idxType, i);
+ const auto newIndex = ConstantInt::get(idxType, i - 1U);
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {zero, newIndex}, "item", block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(itemPtr, array, ctx.Codegen, block, oldIndex);
+ }
+ BranchInst::Create(done, block);
+ }
+ block = done;
+ if (StructObj->IsTemporaryValue())
+ CleanupBoxed(array, ctx, block);
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(StructObj);
}
IComputationNode* const StructObj;
const ui32 Index;
- const std::vector<EValueRepresentation> Representations;
-
- const TContainerCacheOnContext Cache;
+ const std::vector<EValueRepresentation> Representations;
+
+ const TContainerCacheOnContext Cache;
};
-}
-
+}
+
IComputationNode* WrapRemoveMember(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto structType = AS_TYPE(TStructType, callable.GetInput(0));
- const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1));
+ const auto structType = AS_TYPE(TStructType, callable.GetInput(0));
+ const auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const ui32 index = indexData->AsValue().Get<ui32>();
+ const ui32 index = indexData->AsValue().Get<ui32>();
MKQL_ENSURE(index < structType->GetMembersCount(), "Bad member index");
- std::vector<EValueRepresentation> representations;
- representations.reserve(structType->GetMembersCount());
- for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
- representations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
- }
-
- const auto structObj = LocateNode(ctx.NodeLocator, callable, 0);
- return new TRemoveMemberWrapper(ctx.Mutables, structObj, index, std::move(representations));
+ std::vector<EValueRepresentation> representations;
+ representations.reserve(structType->GetMembersCount());
+ for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
+ representations.emplace_back(GetValueRepresentation(structType->GetMemberType(i)));
+ }
+
+ const auto structObj = LocateNode(ctx.NodeLocator, callable, 0);
+ return new TRemoveMemberWrapper(ctx.Mutables, structObj, index, std::move(representations));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_replicate.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_replicate.cpp
index 6947c0e793..44489b6266 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_replicate.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_replicate.cpp
@@ -7,8 +7,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TReplicateWrapper : public TMutableComputationNode<TReplicateWrapper> {
typedef TMutableComputationNode<TReplicateWrapper> TBaseComputation;
public:
@@ -29,10 +29,10 @@ public:
if (Current < End) {
switch (Mode) {
case EDictItems::Payloads:
- this->ThrowNotSupported(__func__);
+ this->ThrowNotSupported(__func__);
break;
case EDictItems::Keys:
- this->ThrowNotSupported(__func__);
+ this->ThrowNotSupported(__func__);
break;
case EDictItems::Both:
key = NUdf::TUnboxedValuePod(ui64(Current));
@@ -57,7 +57,7 @@ public:
value = NUdf::TUnboxedValuePod(ui64(Current));
break;
case EDictItems::Both:
- this->ThrowNotSupported(__func__);
+ this->ThrowNotSupported(__func__);
break;
}
@@ -68,15 +68,15 @@ public:
return false;
}
- bool Skip() override {
- if (Current < End) {
- ++Current;
- return true;
- }
-
- return false;
- }
-
+ bool Skip() override {
+ if (Current < End) {
+ ++Current;
+ return true;
+ }
+
+ return false;
+ }
+
const NUdf::TUnboxedValue Item;
ui64 Current;
const ui64 End;
@@ -92,7 +92,7 @@ public:
private:
NUdf::TUnboxedValue GetListIterator() const override {
- return Ctx.HolderFactory.Create<TIterator<EDictItems::Payloads>>(Item, Count);
+ return Ctx.HolderFactory.Create<TIterator<EDictItems::Payloads>>(Item, Count);
}
bool HasFastListLength() const override {
@@ -168,11 +168,11 @@ public:
}
NUdf::TUnboxedValue GetDictIterator() const override {
- return Ctx.HolderFactory.Create<TIterator<EDictItems::Both>>(Item, Count);
+ return Ctx.HolderFactory.Create<TIterator<EDictItems::Both>>(Item, Count);
}
NUdf::TUnboxedValue GetKeysIterator() const override {
- return Ctx.HolderFactory.Create<TIterator<EDictItems::Keys>>(Item, Count);
+ return Ctx.HolderFactory.Create<TIterator<EDictItems::Keys>>(Item, Count);
}
NUdf::TUnboxedValue GetPayloadsIterator() const override {
@@ -197,7 +197,7 @@ public:
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto count = Count->GetValue(ctx).Get<ui64>();
const ui64 MAX_VALUE = 1ull << 32;
if (count >= MAX_VALUE) {
@@ -213,10 +213,10 @@ public:
return ctx.HolderFactory.Create<TValue>(ctx, Item->GetValue(ctx), count);
}
-private:
- void RegisterDependencies() const final {
- DependsOn(Item);
- DependsOn(Count);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Item);
+ DependsOn(Count);
}
IComputationNode* const Item;
@@ -224,16 +224,16 @@ private:
const NUdf::TSourcePosition Pos;
};
-}
-
+}
+
IComputationNode* WrapReplicate(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2 || callable.GetInputsCount() == 5, "Expected 2 or 5 args");
- const auto countType = AS_TYPE(TDataType, callable.GetInput(1));
- MKQL_ENSURE(countType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
+ const auto countType = AS_TYPE(TDataType, callable.GetInput(1));
+ MKQL_ENSURE(countType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto count = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto count = LocateNode(ctx.NodeLocator, callable, 1);
NUdf::TSourcePosition pos;
if (callable.GetInputsCount() == 5) {
const TStringBuf file = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_reverse.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_reverse.cpp
index d5e5b594e9..4056cfdf67 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_reverse.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_reverse.cpp
@@ -6,63 +6,63 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TReverseWrapper : public TMutableCodegeneratorNode<TReverseWrapper> {
- typedef TMutableCodegeneratorNode<TReverseWrapper> TBaseComputation;
+namespace {
+
+class TReverseWrapper : public TMutableCodegeneratorNode<TReverseWrapper> {
+ typedef TMutableCodegeneratorNode<TReverseWrapper> TBaseComputation;
public:
TReverseWrapper(TComputationMutables& mutables, IComputationNode* list)
- : TBaseComputation(mutables, list->GetRepresentation())
+ : TBaseComputation(mutables, list->GetRepresentation())
, List(list)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.ReverseList(ctx.Builder, List->GetValue(ctx).Release());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.ReverseList(ctx.Builder, List->GetValue(ctx).Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto indexType = Type::getInt32Ty(context);
-
- const auto first = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "first", block);
- const auto fourth = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "fourth", block);
-
- const auto factory = new LoadInst(first, "factory", block);
- const auto builder = new LoadInst(fourth, "builder", block);
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ReverseList));
-
- const auto list = GetNodeValue(List, ctx, block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto result = CallInst::Create(funcPtr, {factory, builder, list}, "result", block);
- return result;
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- new StoreInst(list, retPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr}, "", block);
- const auto result = new LoadInst(retPtr, "result", block);
- return result;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto indexType = Type::getInt32Ty(context);
+
+ const auto first = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "first", block);
+ const auto fourth = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "fourth", block);
+
+ const auto factory = new LoadInst(first, "factory", block);
+ const auto builder = new LoadInst(fourth, "builder", block);
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ReverseList));
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto result = CallInst::Create(funcPtr, {factory, builder, list}, "result", block);
+ return result;
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ new StoreInst(list, retPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr}, "", block);
+ const auto result = new LoadInst(retPtr, "result", block);
+ return result;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
}
IComputationNode* const List;
};
-}
-
+}
+
IComputationNode* WrapReverse(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_safe_circular_buffer.h b/ydb/library/yql/minikql/comp_nodes/mkql_safe_circular_buffer.h
index bdbc280afd..282349756b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_safe_circular_buffer.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_safe_circular_buffer.h
@@ -3,7 +3,7 @@
#include <util/system/yassert.h>
#include <util/generic/maybe.h>
-#include <vector>
+#include <vector>
namespace NKikimr {
namespace NMiniKQL {
@@ -59,7 +59,7 @@ public:
}
size_t Size() const {
- return Buffer.size();
+ return Buffer.size();
}
size_t UsedSize() const {
@@ -79,8 +79,8 @@ public:
void Clear() {
Head = Count = 0;
- Buffer.clear();
- Buffer.shrink_to_fit();
+ Buffer.clear();
+ Buffer.shrink_to_fit();
}
private:
@@ -97,7 +97,7 @@ private:
return index % size;
}
- std::vector<T> Buffer;
+ std::vector<T> Buffer;
const T EmptyValue;
const bool Unbounded;
size_t Head = 0;
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_saveload.h b/ydb/library/yql/minikql/comp_nodes/mkql_saveload.h
index 01306bcfa7..0440994f8d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_saveload.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_saveload.h
@@ -11,10 +11,10 @@
namespace NKikimr {
namespace NMiniKQL {
-Y_FORCE_INLINE void WriteByte(TString& out, ui8 value) {
- out.append((char)value);
-}
-
+Y_FORCE_INLINE void WriteByte(TString& out, ui8 value) {
+ out.append((char)value);
+}
+
Y_FORCE_INLINE void WriteBool(TString& out, bool value) {
out.append((char)value);
}
@@ -36,13 +36,13 @@ Y_FORCE_INLINE bool ReadBool(TStringBuf& in) {
return result;
}
-Y_FORCE_INLINE ui8 ReadByte(TStringBuf& in) {
+Y_FORCE_INLINE ui8 ReadByte(TStringBuf& in) {
MKQL_ENSURE(in.size(), "Serialized state is corrupted");
ui8 result = *in.data();
- in.Skip(1);
- return result;
-}
-
+ in.Skip(1);
+ return result;
+}
+
Y_FORCE_INLINE ui32 ReadUi32(TStringBuf& in) {
ui32 result;
auto count = Unpack32(in.data(), in.size(), result);
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_size.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_size.cpp
index 5a0d8b58f5..57c4268416 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_size.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_size.cpp
@@ -7,150 +7,150 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
extern "C" void DeleteString(void* strData);
-template<size_t Size>
-class TSizePrimitiveTypeWrapper : public TDecoratorCodegeneratorNode<TSizePrimitiveTypeWrapper<Size>> {
- typedef TDecoratorCodegeneratorNode<TSizePrimitiveTypeWrapper<Size>> TBaseComputation;
-public:
- TSizePrimitiveTypeWrapper(IComputationNode* data)
- : TBaseComputation(data)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
- return value ? NUdf::TUnboxedValuePod(ui32(Size)) : NUdf::TUnboxedValuePod();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
- const uint64_t init[] = {Size, 0x100000000000000ULL};
- const auto size = ConstantInt::get(value->getType(), APInt(128, 2, init));
- return SelectInst::Create(IsEmpty(value, block), value, size, "size", block);
- }
-#endif
-};
-
-template<bool IsOptional>
-class TSizeWrapper : public TMutableCodegeneratorNode<TSizeWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TSizeWrapper<IsOptional>> TBaseComputation;
+template<size_t Size>
+class TSizePrimitiveTypeWrapper : public TDecoratorCodegeneratorNode<TSizePrimitiveTypeWrapper<Size>> {
+ typedef TDecoratorCodegeneratorNode<TSizePrimitiveTypeWrapper<Size>> TBaseComputation;
+public:
+ TSizePrimitiveTypeWrapper(IComputationNode* data)
+ : TBaseComputation(data)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
+ return value ? NUdf::TUnboxedValuePod(ui32(Size)) : NUdf::TUnboxedValuePod();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
+ const uint64_t init[] = {Size, 0x100000000000000ULL};
+ const auto size = ConstantInt::get(value->getType(), APInt(128, 2, init));
+ return SelectInst::Create(IsEmpty(value, block), value, size, "size", block);
+ }
+#endif
+};
+
+template<bool IsOptional>
+class TSizeWrapper : public TMutableCodegeneratorNode<TSizeWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TSizeWrapper<IsOptional>> TBaseComputation;
public:
TSizeWrapper(TComputationMutables& mutables, IComputationNode* data)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
, Data(data)
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& data = Data->GetValue(ctx);
- if (IsOptional && !data) {
- return NUdf::TUnboxedValuePod();
- }
-
+ if (IsOptional && !data) {
+ return NUdf::TUnboxedValuePod();
+ }
+
const ui32 size = data.AsStringRef().Size();
- return NUdf::TUnboxedValuePod(size);
+ return NUdf::TUnboxedValuePod(size);
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto data = GetNodeValue(this->Data, ctx, block);
-
- const auto type = Type::getInt8Ty(context);
- const auto embType = FixedVectorType::get(type, 16);
- const auto cast = CastInst::Create(Instruction::BitCast, data, embType, "cast", block);
-
- const auto mark = ExtractElementInst::Create(cast, {ConstantInt::get(type, 15)}, "mark", block);
- const auto bsize = ExtractElementInst::Create(cast, {ConstantInt::get(type, 14)}, "bsize", block);
-
- const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
- const auto str = BasicBlock::Create(context, "str", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(data->getType(), 4, "result", done);
- result->addIncoming(ConstantInt::get(data->getType(), 0), block);
-
- const auto choise = SwitchInst::Create(mark, done, 2, block);
- choise->addCase(ConstantInt::get(type, 1), emb);
- choise->addCase(ConstantInt::get(type, 2), str);
-
- {
- block = emb;
-
- const auto full = SetterFor<ui32>(bsize, context, block);
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = str;
-
- const auto type32 = Type::getInt32Ty(context);
- const auto strType = FixedVectorType::get(type32, 4);
- const auto four = CastInst::Create(Instruction::BitCast, data, strType, "four", block);
- const auto ssize = ExtractElementInst::Create(four, {ConstantInt::get(type, 2)}, "ssize", block);
- const auto full = SetterFor<ui32>(ssize, context, block);
-
- const auto half = CastInst::Create(Instruction::Trunc, data, Type::getInt64Ty(context), "half", block);
- const auto strPtrType = PointerType::getUnqual(StructType::get(context, {type32, type32, type32, type32}));
- const auto strptr = CastInst::Create(Instruction::IntToPtr, half, strPtrType, "str_ptr", block);
- const auto refptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "refptr", block);
- const auto refs = new LoadInst(refptr, "refs", block);
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, refs, ConstantInt::get(refs->getType(), 0), "test", block);
-
- const auto free = BasicBlock::Create(context, "free", ctx.Func);
-
- result->addIncoming(full, block);
- BranchInst::Create(done, free, test, block);
-
- block = free;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {strptr->getType()}, false);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto data = GetNodeValue(this->Data, ctx, block);
+
+ const auto type = Type::getInt8Ty(context);
+ const auto embType = FixedVectorType::get(type, 16);
+ const auto cast = CastInst::Create(Instruction::BitCast, data, embType, "cast", block);
+
+ const auto mark = ExtractElementInst::Create(cast, {ConstantInt::get(type, 15)}, "mark", block);
+ const auto bsize = ExtractElementInst::Create(cast, {ConstantInt::get(type, 14)}, "bsize", block);
+
+ const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
+ const auto str = BasicBlock::Create(context, "str", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(data->getType(), 4, "result", done);
+ result->addIncoming(ConstantInt::get(data->getType(), 0), block);
+
+ const auto choise = SwitchInst::Create(mark, done, 2, block);
+ choise->addCase(ConstantInt::get(type, 1), emb);
+ choise->addCase(ConstantInt::get(type, 2), str);
+
+ {
+ block = emb;
+
+ const auto full = SetterFor<ui32>(bsize, context, block);
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = str;
+
+ const auto type32 = Type::getInt32Ty(context);
+ const auto strType = FixedVectorType::get(type32, 4);
+ const auto four = CastInst::Create(Instruction::BitCast, data, strType, "four", block);
+ const auto ssize = ExtractElementInst::Create(four, {ConstantInt::get(type, 2)}, "ssize", block);
+ const auto full = SetterFor<ui32>(ssize, context, block);
+
+ const auto half = CastInst::Create(Instruction::Trunc, data, Type::getInt64Ty(context), "half", block);
+ const auto strPtrType = PointerType::getUnqual(StructType::get(context, {type32, type32, type32, type32}));
+ const auto strptr = CastInst::Create(Instruction::IntToPtr, half, strPtrType, "str_ptr", block);
+ const auto refptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "refptr", block);
+ const auto refs = new LoadInst(refptr, "refs", block);
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, refs, ConstantInt::get(refs->getType(), 0), "test", block);
+
+ const auto free = BasicBlock::Create(context, "free", ctx.Func);
+
+ result->addIncoming(full, block);
+ BranchInst::Create(done, free, test, block);
+
+ block = free;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {strptr->getType()}, false);
const auto name = "DeleteString";
ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteString));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {strptr}, "", block);
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
+ CallInst::Create(func, {strptr}, "", block);
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
}
IComputationNode* const Data;
};
-}
-
+}
+
IComputationNode* WrapSize(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
-
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
-
- switch(dataType->GetSchemeType()) {
-#define MAKE_PRIMITIVE_TYPE_SIZE(type, layout) \
- case NUdf::TDataType<type>::Id: \
- if (isOptional) \
- return new TSizePrimitiveTypeWrapper<sizeof(layout)>(data); \
- else \
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(ui32(sizeof(layout))));
- KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_SIZE)
-#undef MAKE_PRIMITIVE_TYPE_SIZE
- }
-
- if (isOptional)
- return new TSizeWrapper<true>(ctx.Mutables, data);
- else
- return new TSizeWrapper<false>(ctx.Mutables, data);
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+
+ switch(dataType->GetSchemeType()) {
+#define MAKE_PRIMITIVE_TYPE_SIZE(type, layout) \
+ case NUdf::TDataType<type>::Id: \
+ if (isOptional) \
+ return new TSizePrimitiveTypeWrapper<sizeof(layout)>(data); \
+ else \
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod(ui32(sizeof(layout))));
+ KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_SIZE)
+#undef MAKE_PRIMITIVE_TYPE_SIZE
+ }
+
+ if (isOptional)
+ return new TSizeWrapper<true>(ctx.Mutables, data);
+ else
+ return new TSizeWrapper<false>(ctx.Mutables, data);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_skip.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_skip.cpp
index 9409856d49..62a7f10f24 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_skip.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_skip.cpp
@@ -6,226 +6,226 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TSkipFlowWrapper : public TStatefulFlowCodegeneratorNode<TSkipFlowWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TSkipFlowWrapper>;
-public:
- TSkipFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* count)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Count(count)
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- state = Count->GetValue(ctx);
- }
-
- if (auto count = state.Get<ui64>()) {
- do {
- const auto item = Flow->GetValue(ctx);
- if (item.IsSpecial()) {
- state = NUdf::TUnboxedValuePod(count);
- return item;
- }
- } while (--count);
-
- state = NUdf::TUnboxedValuePod::Zero();
- }
-
- return Flow->GetValue(ctx);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = PHINode::Create(load->getType(), 2U, "state", main);
- state->addIncoming(load, block);
- BranchInst::Create(init, main, IsInvalid(load, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Count, ctx, block);
- const auto save = new LoadInst(statePtr, "save", block);
- state->addIncoming(save, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 2U, "result", done);
-
- const auto trunc = GetterFor<ui64>(state, context, block);
-
- const auto count = PHINode::Create(trunc->getType(), 2U, "count", work);
- count->addIncoming(trunc, block);
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
-
- BranchInst::Create(work, skip, plus, block);
-
- block = work;
- const auto item = GetNodeValue(Flow, ctx, block);
- BranchInst::Create(pass, good, IsSpecial(item, block), block);
-
- block = pass;
- result->addIncoming(item, block);
- new StoreInst(SetterFor<ui64>(count, context, block), statePtr, block);
- BranchInst::Create(done, block);
-
- block = good;
-
+namespace {
+
+class TSkipFlowWrapper : public TStatefulFlowCodegeneratorNode<TSkipFlowWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TSkipFlowWrapper>;
+public:
+ TSkipFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* count)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Count(count)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ state = Count->GetValue(ctx);
+ }
+
+ if (auto count = state.Get<ui64>()) {
+ do {
+ const auto item = Flow->GetValue(ctx);
+ if (item.IsSpecial()) {
+ state = NUdf::TUnboxedValuePod(count);
+ return item;
+ }
+ } while (--count);
+
+ state = NUdf::TUnboxedValuePod::Zero();
+ }
+
+ return Flow->GetValue(ctx);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = PHINode::Create(load->getType(), 2U, "state", main);
+ state->addIncoming(load, block);
+ BranchInst::Create(init, main, IsInvalid(load, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Count, ctx, block);
+ const auto save = new LoadInst(statePtr, "save", block);
+ state->addIncoming(save, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 2U, "result", done);
+
+ const auto trunc = GetterFor<ui64>(state, context, block);
+
+ const auto count = PHINode::Create(trunc->getType(), 2U, "count", work);
+ count->addIncoming(trunc, block);
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
+
+ BranchInst::Create(work, skip, plus, block);
+
+ block = work;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ BranchInst::Create(pass, good, IsSpecial(item, block), block);
+
+ block = pass;
+ result->addIncoming(item, block);
+ new StoreInst(SetterFor<ui64>(count, context, block), statePtr, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+
ValueCleanup(Flow->GetRepresentation(), item, ctx, block);
- const auto decr = BinaryOperator::CreateSub(count, ConstantInt::get(count->getType(), 1ULL), "decr", block);
- count->addIncoming(decr, block);
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0ULL), "next", block);
- BranchInst::Create(work, exit, next, block);
-
- block = exit;
- new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
- BranchInst::Create(skip, block);
-
- block = skip;
- const auto res = GetNodeValue(Flow, ctx, block);
- result->addIncoming(res, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow))
- DependsOn(flow, Count);
- }
-
- IComputationNode* const Flow;
- IComputationNode* const Count;
-};
-
-class TWideSkipWrapper : public TStatefulWideFlowCodegeneratorNode<TWideSkipWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideSkipWrapper>;
-public:
- TWideSkipWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* count, ui32 size)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Count(count), Stubs(size, nullptr)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = Count->GetValue(ctx);
- }
-
- if (auto count = state.Get<ui64>()) {
- do if (const auto result = Flow->FetchValues(ctx, Stubs.data()); EFetchResult::One != result) {
- state = NUdf::TUnboxedValuePod(count);
- return result;
- } while (--count);
-
- state = NUdf::TUnboxedValuePod::Zero();
- }
-
- return Flow->FetchValues(ctx, output);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = PHINode::Create(load->getType(), 2U, "state", main);
- state->addIncoming(load, block);
- BranchInst::Create(init, main, IsInvalid(load, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Count, ctx, block);
- const auto save = new LoadInst(statePtr, "save", block);
- state->addIncoming(save, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 2U, "result", done);
-
- const auto trunc = GetterFor<ui64>(state, context, block);
-
- const auto count = PHINode::Create(trunc->getType(), 2U, "count", work);
- count->addIncoming(trunc, block);
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
-
- BranchInst::Create(work, skip, plus, block);
-
- block = work;
- const auto status = GetNodeValues(Flow, ctx, block).first;
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status, ConstantInt::get(status->getType(), 0), "special", block);
- BranchInst::Create(pass, good, special, block);
-
- block = pass;
- new StoreInst(SetterFor<ui64>(count, context, block), statePtr, block);
- result->addIncoming(status, block);
- BranchInst::Create(done, block);
-
- block = good;
-
- const auto decr = BinaryOperator::CreateSub(count, ConstantInt::get(count->getType(), 1ULL), "decr", block);
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0ULL), "next", block);
- count->addIncoming(decr, block);
- BranchInst::Create(work, exit, next, block);
-
- block = exit;
- new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
- BranchInst::Create(skip, block);
-
- block = skip;
- auto getres = GetNodeValues(Flow, ctx, block);
- result->addIncoming(getres.first, block);
- BranchInst::Create(done, block);
-
- block = done;
- return {result, std::move(getres.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow))
- DependsOn(flow, Count);
- }
-
- IComputationWideFlowNode* const Flow;
- IComputationNode* const Count;
- mutable std::vector<NUdf::TUnboxedValue*> Stubs;
-};
-
-class TSkipStreamWrapper : public TMutableComputationNode<TSkipStreamWrapper> {
- typedef TMutableComputationNode<TSkipStreamWrapper> TBaseComputation;
+ const auto decr = BinaryOperator::CreateSub(count, ConstantInt::get(count->getType(), 1ULL), "decr", block);
+ count->addIncoming(decr, block);
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0ULL), "next", block);
+ BranchInst::Create(work, exit, next, block);
+
+ block = exit;
+ new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ const auto res = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(res, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow))
+ DependsOn(flow, Count);
+ }
+
+ IComputationNode* const Flow;
+ IComputationNode* const Count;
+};
+
+class TWideSkipWrapper : public TStatefulWideFlowCodegeneratorNode<TWideSkipWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideSkipWrapper>;
+public:
+ TWideSkipWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* count, ui32 size)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Count(count), Stubs(size, nullptr)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = Count->GetValue(ctx);
+ }
+
+ if (auto count = state.Get<ui64>()) {
+ do if (const auto result = Flow->FetchValues(ctx, Stubs.data()); EFetchResult::One != result) {
+ state = NUdf::TUnboxedValuePod(count);
+ return result;
+ } while (--count);
+
+ state = NUdf::TUnboxedValuePod::Zero();
+ }
+
+ return Flow->FetchValues(ctx, output);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = PHINode::Create(load->getType(), 2U, "state", main);
+ state->addIncoming(load, block);
+ BranchInst::Create(init, main, IsInvalid(load, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Count, ctx, block);
+ const auto save = new LoadInst(statePtr, "save", block);
+ state->addIncoming(save, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 2U, "result", done);
+
+ const auto trunc = GetterFor<ui64>(state, context, block);
+
+ const auto count = PHINode::Create(trunc->getType(), 2U, "count", work);
+ count->addIncoming(trunc, block);
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
+
+ BranchInst::Create(work, skip, plus, block);
+
+ block = work;
+ const auto status = GetNodeValues(Flow, ctx, block).first;
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status, ConstantInt::get(status->getType(), 0), "special", block);
+ BranchInst::Create(pass, good, special, block);
+
+ block = pass;
+ new StoreInst(SetterFor<ui64>(count, context, block), statePtr, block);
+ result->addIncoming(status, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+
+ const auto decr = BinaryOperator::CreateSub(count, ConstantInt::get(count->getType(), 1ULL), "decr", block);
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0ULL), "next", block);
+ count->addIncoming(decr, block);
+ BranchInst::Create(work, exit, next, block);
+
+ block = exit;
+ new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ auto getres = GetNodeValues(Flow, ctx, block);
+ result->addIncoming(getres.first, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return {result, std::move(getres.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow))
+ DependsOn(flow, Count);
+ }
+
+ IComputationWideFlowNode* const Flow;
+ IComputationNode* const Count;
+ mutable std::vector<NUdf::TUnboxedValue*> Stubs;
+};
+
+class TSkipStreamWrapper : public TMutableComputationNode<TSkipStreamWrapper> {
+ typedef TMutableComputationNode<TSkipStreamWrapper> TBaseComputation;
public:
class TStreamValue : public TComputationValue<TStreamValue> {
public:
@@ -238,7 +238,7 @@ public:
, Index_(0)
{}
- private:
+ private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
for (;;) {
if (Index_ >= Count_) {
@@ -254,105 +254,105 @@ public:
}
}
- const NUdf::TUnboxedValue Input_;
+ const NUdf::TUnboxedValue Input_;
const ui64 Count_;
ui64 Index_;
};
- TSkipStreamWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
- : TBaseComputation(mutables, list->GetRepresentation())
- , List(list)
- , Count(count)
- {
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Count->GetValue(ctx).Get<ui64>());
- }
-
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Count);
- }
-
-private:
- IComputationNode* const List;
- IComputationNode* const Count;
-};
-
-class TSkipWrapper : public TMutableCodegeneratorNode<TSkipWrapper> {
- typedef TMutableCodegeneratorNode<TSkipWrapper> TBaseComputation;
-public:
+ TSkipStreamWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
+ : TBaseComputation(mutables, list->GetRepresentation())
+ , List(list)
+ , Count(count)
+ {
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Count->GetValue(ctx).Get<ui64>());
+ }
+
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Count);
+ }
+
+private:
+ IComputationNode* const List;
+ IComputationNode* const Count;
+};
+
+class TSkipWrapper : public TMutableCodegeneratorNode<TSkipWrapper> {
+ typedef TMutableCodegeneratorNode<TSkipWrapper> TBaseComputation;
+public:
TSkipWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
- : TBaseComputation(mutables, list->GetRepresentation())
+ : TBaseComputation(mutables, list->GetRepresentation())
, List(list)
, Count(count)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.SkipList(ctx.Builder, List->GetValue(ctx).Release(), Count->GetValue(ctx).Get<ui64>());
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
- const auto builder = ctx.GetBuilder();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::SkipList));
-
- const auto list = GetNodeValue(List, ctx, block);
- const auto cnt = GetNodeValue(Count, ctx, block);
- const auto count = GetterFor<ui64>(cnt, context, block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto result = CallInst::Create(funcPtr, {factory, builder, list, count}, "result", block);
- return result;
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- new StoreInst(list, retPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr, count}, "", block);
- const auto result = new LoadInst(retPtr, "result", block);
- return result;
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.SkipList(ctx.Builder, List->GetValue(ctx).Release(), Count->GetValue(ctx).Get<ui64>());
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+ const auto builder = ctx.GetBuilder();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::SkipList));
+
+ const auto list = GetNodeValue(List, ctx, block);
+ const auto cnt = GetNodeValue(Count, ctx, block);
+ const auto count = GetterFor<ui64>(cnt, context, block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto result = CallInst::Create(funcPtr, {factory, builder, list, count}, "result", block);
+ return result;
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ new StoreInst(list, retPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr, count}, "", block);
+ const auto result = new LoadInst(retPtr, "result", block);
+ return result;
}
}
-#endif
+#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Count);
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Count);
}
IComputationNode* const List;
IComputationNode* const Count;
};
-}
-
+}
+
IComputationNode* WrapSkip(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto type = callable.GetInput(0).GetStaticType();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto count = LocateNode(ctx.NodeLocator, callable, 1);
- if (type->IsFlow()) {
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
- return new TWideSkipWrapper(ctx.Mutables, wide, count, AS_TYPE(TTupleType, AS_TYPE(TFlowType, type)->GetItemType())->GetElementsCount());
- else
- return new TSkipFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, count);
- } else if (type->IsStream()) {
- return new TSkipStreamWrapper(ctx.Mutables, flow, count);
- } else if (type->IsList()) {
- return new TSkipWrapper(ctx.Mutables, flow, count);
+ const auto type = callable.GetInput(0).GetStaticType();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto count = LocateNode(ctx.NodeLocator, callable, 1);
+ if (type->IsFlow()) {
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
+ return new TWideSkipWrapper(ctx.Mutables, wide, count, AS_TYPE(TTupleType, AS_TYPE(TFlowType, type)->GetItemType())->GetElementsCount());
+ else
+ return new TSkipFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, count);
+ } else if (type->IsStream()) {
+ return new TSkipStreamWrapper(ctx.Mutables, flow, count);
+ } else if (type->IsList()) {
+ return new TSkipWrapper(ctx.Mutables, flow, count);
}
- THROW yexception() << "Expected flow, list or stream.";
+ THROW yexception() << "Expected flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_sort.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_sort.cpp
index f9ace62338..2f67b24406 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_sort.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_sort.cpp
@@ -5,21 +5,21 @@
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-#include <algorithm>
+#include <algorithm>
#include <iterator>
-
+
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
std::vector<NUdf::EDataSlot> PrepareKeyTypesByScheme(const std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>& keySchemeTypes) {
MKQL_ENSURE(!keySchemeTypes.empty(), "No key types provided");
std::vector<NUdf::EDataSlot> keyTypes;
keyTypes.reserve(keySchemeTypes.size());
- for (const auto& schemeType: keySchemeTypes) {
- keyTypes.emplace_back(std::get<0>(schemeType));
- const auto& info = NUdf::GetDataTypeInfo(keyTypes.back());
+ for (const auto& schemeType: keySchemeTypes) {
+ keyTypes.emplace_back(std::get<0>(schemeType));
+ const auto& info = NUdf::GetDataTypeInfo(keyTypes.back());
MKQL_ENSURE(info.Features & NUdf::CanCompare, "Cannot compare key type: " << info.Name);
}
return keyTypes;
@@ -42,7 +42,7 @@ public:
}
}
- std::vector<TMaybe<TGenericPresortEncoder>> Columns;
+ std::vector<TMaybe<TGenericPresortEncoder>> Columns;
bool NeedEncode = false;
};
@@ -185,127 +185,127 @@ private:
NUdf::TUnboxedValue* Second;
};
-using TComparator = std::function<bool(const TKeyPayloadPairVector::value_type&, const TKeyPayloadPairVector::value_type&)>;
-using TAlgorithm = void(*)(TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TComparator);
+using TComparator = std::function<bool(const TKeyPayloadPairVector::value_type&, const TKeyPayloadPairVector::value_type&)>;
+using TAlgorithm = void(*)(TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TComparator);
using TAlgorithmInplace = void(*)(TGatherIterator, TGatherIterator, TComparator);
-using TNthAlgorithm = void(*)(TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TComparator);
-
-struct TCompareDescr {
- TCompareDescr(TComputationMutables& mutables, std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes)
- : KeySchemeTypes(std::move(keySchemeTypes))
- , KeyTypes(PrepareKeyTypesByScheme(KeySchemeTypes))
- , Encoders(mutables)
- {}
-
- static TKeyPayloadPairVector::value_type::first_type& Set(TKeyPayloadPairVector::value_type& item) { return item.first; }
- static TUnboxedValueVector::value_type& Set(TUnboxedValueVector::value_type& item) { return item; }
-
- static const TKeyPayloadPairVector::value_type::first_type& Get(const TKeyPayloadPairVector::value_type& item) { return item.first; }
- static const TUnboxedValueVector::value_type& Get(const TUnboxedValueVector::value_type& item) { return item; }
-
- template<class Container>
- std::function<bool(const typename Container::value_type&, const typename Container::value_type&)>
+using TNthAlgorithm = void(*)(TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TKeyPayloadPairVector::iterator, TComparator);
+
+struct TCompareDescr {
+ TCompareDescr(TComputationMutables& mutables, std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes)
+ : KeySchemeTypes(std::move(keySchemeTypes))
+ , KeyTypes(PrepareKeyTypesByScheme(KeySchemeTypes))
+ , Encoders(mutables)
+ {}
+
+ static TKeyPayloadPairVector::value_type::first_type& Set(TKeyPayloadPairVector::value_type& item) { return item.first; }
+ static TUnboxedValueVector::value_type& Set(TUnboxedValueVector::value_type& item) { return item; }
+
+ static const TKeyPayloadPairVector::value_type::first_type& Get(const TKeyPayloadPairVector::value_type& item) { return item.first; }
+ static const TUnboxedValueVector::value_type& Get(const TUnboxedValueVector::value_type& item) { return item; }
+
+ template<class Container>
+ std::function<bool(const typename Container::value_type&, const typename Container::value_type&)>
MakeComparator(const NUdf::TUnboxedValue& ascending) const {
if (KeyTypes.size() > 1U) {
// sort tuples
return [this, &ascending](const typename Container::value_type& x, const typename Container::value_type& y) {
const auto& left = Get(x);
const auto& right = Get(y);
-
+
for (ui32 i = 0; i < KeyTypes.size(); ++i) {
const auto& keyType = KeyTypes[i];
const auto& leftElem = left.GetElement(i);
const auto& rightElem = right.GetElement(i);
const bool asc = ascending.GetElement(i).Get<bool>();
-
+
if (const auto cmp = CompareValues(keyType, asc, std::get<1>(KeySchemeTypes[i]), leftElem, rightElem)) {
return cmp < 0;
- }
+ }
}
-
+
return false;
};
} else {
// sort one column
const bool isOptional = std::get<1>(KeySchemeTypes.front());
const bool asc = ascending.Get<bool>();
-
+
return [this, asc, isOptional](const typename Container::value_type& x, const typename Container::value_type& y) {
return CompareValues(KeyTypes.front(), asc, isOptional, Get(x), Get(y)) < 0;
};
- }
- }
-
- template<class Container>
- void Prepare(TComputationContext& ctx, Container& items) const {
- if (!KeyTypes.empty()) {
- auto& encoders = Encoders.RefMutableObject(ctx, KeySchemeTypes);
- if (KeyTypes.size() > 1U) {
- // sort tuples
- if (encoders.NeedEncode) {
- // rebuild tuples
- for (auto& x : items) {
- NUdf::TUnboxedValue* arrayItems = nullptr;
- NUdf::TUnboxedValue array = ctx.HolderFactory.CreateDirectArrayHolder(KeyTypes.size(), arrayItems);
- for (ui32 i = 0; i < KeyTypes.size(); ++i) {
- if (auto& e = encoders.Columns[i]) {
- arrayItems[i] = MakeString(e->Encode(Get(x).GetElement(i), false));
- } else {
- arrayItems[i] = Get(x).GetElement(i);
- }
- }
-
- Set(x) = std::move(array);
- }
- }
- } else if (auto& encoder = encoders.Columns.front()) {
- for (auto& x : items) {
- Set(x) = MakeString(encoder->Encode(Get(x), false));
- }
- }
- }
- }
-
- const std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>> KeySchemeTypes;
- const std::vector<NUdf::EDataSlot> KeyTypes;
- TMutableObjectOverBoxedValue<TEncoders> Encoders;
-};
-
+ }
+ }
+
+ template<class Container>
+ void Prepare(TComputationContext& ctx, Container& items) const {
+ if (!KeyTypes.empty()) {
+ auto& encoders = Encoders.RefMutableObject(ctx, KeySchemeTypes);
+ if (KeyTypes.size() > 1U) {
+ // sort tuples
+ if (encoders.NeedEncode) {
+ // rebuild tuples
+ for (auto& x : items) {
+ NUdf::TUnboxedValue* arrayItems = nullptr;
+ NUdf::TUnboxedValue array = ctx.HolderFactory.CreateDirectArrayHolder(KeyTypes.size(), arrayItems);
+ for (ui32 i = 0; i < KeyTypes.size(); ++i) {
+ if (auto& e = encoders.Columns[i]) {
+ arrayItems[i] = MakeString(e->Encode(Get(x).GetElement(i), false));
+ } else {
+ arrayItems[i] = Get(x).GetElement(i);
+ }
+ }
+
+ Set(x) = std::move(array);
+ }
+ }
+ } else if (auto& encoder = encoders.Columns.front()) {
+ for (auto& x : items) {
+ Set(x) = MakeString(encoder->Encode(Get(x), false));
+ }
+ }
+ }
+ }
+
+ const std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>> KeySchemeTypes;
+ const std::vector<NUdf::EDataSlot> KeyTypes;
+ TMutableObjectOverBoxedValue<TEncoders> Encoders;
+};
+
template<class TWrapperImpl, bool MaybeInplace>
class TAlgoBaseWrapper : public TMutableComputationNode<TAlgoBaseWrapper<TWrapperImpl, MaybeInplace>> {
using TBaseComputation = TMutableComputationNode<TAlgoBaseWrapper<TWrapperImpl, MaybeInplace>>;
-protected:
- TAlgoBaseWrapper(
- TComputationMutables& mutables,
- std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
- IComputationNode* list,
- IComputationExternalNode* item,
- IComputationNode* key,
+protected:
+ TAlgoBaseWrapper(
+ TComputationMutables& mutables,
+ std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
+ IComputationNode* list,
+ IComputationExternalNode* item,
+ IComputationNode* key,
IComputationNode* ascending,
bool stealed)
- : TBaseComputation(mutables)
- , Description(mutables, std::move(keySchemeTypes))
- , List(list)
- , Item(item)
- , Key(key)
- , Ascending(ascending)
+ : TBaseComputation(mutables)
+ , Description(mutables, std::move(keySchemeTypes))
+ , List(list)
+ , Item(item)
+ , Key(key)
+ , Ascending(ascending)
, Stealed(stealed)
- {}
-
-public:
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto& list = List->GetValue(ctx);
+ {}
+
+public:
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto& list = List->GetValue(ctx);
auto ptr = list.GetElements();
if (MaybeInplace && ptr) {
TUnboxedValueVector keys;
NUdf::TUnboxedValue *inplace = nullptr;
NUdf::TUnboxedValue res;
-
+
auto size = list.GetListLength();
if (!size) {
return ctx.HolderFactory.GetEmptyContainer();
}
-
+
if (Stealed) {
res = list;
inplace = const_cast<NUdf::TUnboxedValue*>(ptr);
@@ -332,10 +332,10 @@ public:
TKeyPayloadPairVector items;
if (ptr) {
auto size = list.GetListLength();
- items.reserve(size);
+ items.reserve(size);
for (ui32 i = 0; i < size; ++i) {
Item->SetValue(ctx, NUdf::TUnboxedValuePod(ptr[i]));
- items.emplace_back(Key->GetValue(ctx), Item->GetValue(ctx));
+ items.emplace_back(Key->GetValue(ctx), Item->GetValue(ctx));
}
} else {
const auto& iter = list.GetListIterator();
@@ -347,62 +347,62 @@ public:
Item->SetValue(ctx, std::move(item));
items.emplace_back(Key->GetValue(ctx), Item->GetValue(ctx));
}
- }
-
+ }
+
if (items.empty()) {
return ctx.HolderFactory.GetEmptyContainer();
- }
-
+ }
+
Description.Prepare(ctx, items);
return static_cast<const TWrapperImpl*>(this)->Perform(ctx, items,
Description.MakeComparator<TKeyPayloadPairVector>(Ascending->GetValue(ctx)));
- }
- }
-
-protected:
- void RegisterDependencies() const override {
- this->DependsOn(List);
- this->Own(Item);
- this->DependsOn(Key);
- this->DependsOn(Ascending);
- }
-
-private:
- TCompareDescr Description;
- IComputationNode* const List;
- IComputationExternalNode* const Item;
- IComputationNode* const Key;
- IComputationNode* const Ascending;
+ }
+ }
+
+protected:
+ void RegisterDependencies() const override {
+ this->DependsOn(List);
+ this->Own(Item);
+ this->DependsOn(Key);
+ this->DependsOn(Ascending);
+ }
+
+private:
+ TCompareDescr Description;
+ IComputationNode* const List;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Key;
+ IComputationNode* const Ascending;
const bool Stealed;
-};
-
+};
+
class TAlgoWrapper : public TAlgoBaseWrapper<TAlgoWrapper, true> {
using TBaseComputation = TAlgoBaseWrapper<TAlgoWrapper, true>;
-public:
- TAlgoWrapper(
- TAlgorithm algorithm,
+public:
+ TAlgoWrapper(
+ TAlgorithm algorithm,
TAlgorithmInplace algorithmInplace,
- TComputationMutables& mutables,
- std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
- IComputationNode* list,
- IComputationExternalNode* item,
- IComputationNode* key,
+ TComputationMutables& mutables,
+ std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
+ IComputationNode* list,
+ IComputationExternalNode* item,
+ IComputationNode* key,
IComputationNode* ascending,
bool stealed)
: TBaseComputation(mutables, std::move(keySchemeTypes), list, item, key, ascending, stealed)
- , Algorithm(algorithm)
+ , Algorithm(algorithm)
, AlgorithmInplace(algorithmInplace)
- {}
-
- NUdf::TUnboxedValuePod Perform(TComputationContext& ctx, TKeyPayloadPairVector& items, const TComparator& comparator) const {
- Algorithm(items.begin(), items.end(), comparator);
-
- NUdf::TUnboxedValue *inplace = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(items.size(), inplace);
- for (auto& item : items) {
- *inplace++ = std::move(item.second);
- }
- return result;
+ {}
+
+ NUdf::TUnboxedValuePod Perform(TComputationContext& ctx, TKeyPayloadPairVector& items, const TComparator& comparator) const {
+ Algorithm(items.begin(), items.end(), comparator);
+
+ NUdf::TUnboxedValue *inplace = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(items.size(), inplace);
+ for (auto& item : items) {
+ *inplace++ = std::move(item.second);
+ }
+ return result;
}
void PerformInplace(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue* keys, NUdf::TUnboxedValue* items, const TComparator& comparator) const {
@@ -410,42 +410,42 @@ public:
}
private:
- const TAlgorithm Algorithm;
+ const TAlgorithm Algorithm;
const TAlgorithmInplace AlgorithmInplace;
-};
+};
class TNthAlgoWrapper : public TAlgoBaseWrapper<TNthAlgoWrapper, false> {
using TBaseComputation = TAlgoBaseWrapper<TNthAlgoWrapper, false>;
-public:
- TNthAlgoWrapper(
- TNthAlgorithm algorithm,
- TComputationMutables& mutables,
- std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
- IComputationNode* list,
- IComputationNode* nth,
- IComputationExternalNode* item,
- IComputationNode* key,
- IComputationNode* ascending)
+public:
+ TNthAlgoWrapper(
+ TNthAlgorithm algorithm,
+ TComputationMutables& mutables,
+ std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
+ IComputationNode* list,
+ IComputationNode* nth,
+ IComputationExternalNode* item,
+ IComputationNode* key,
+ IComputationNode* ascending)
: TBaseComputation(mutables, std::move(keySchemeTypes), list, item, key, ascending, false)
- , Algorithm(algorithm), Nth(nth)
- {}
-
- NUdf::TUnboxedValuePod Perform(TComputationContext& ctx, TKeyPayloadPairVector& items, const TComparator& comparator) const {
- const auto n = std::min<ui64>(Nth->GetValue(ctx).Get<ui64>(), items.size());
- if (!n) {
- return ctx.HolderFactory.GetEmptyContainer();
- }
-
- Algorithm(items.begin(), items.begin() + n, items.end(), comparator);
- items.resize(n);
-
- NUdf::TUnboxedValue *inplace = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(n, inplace);
- for (auto& item : items) {
- *inplace++ = std::move(item.second);
- }
- return result;
- }
+ , Algorithm(algorithm), Nth(nth)
+ {}
+
+ NUdf::TUnboxedValuePod Perform(TComputationContext& ctx, TKeyPayloadPairVector& items, const TComparator& comparator) const {
+ const auto n = std::min<ui64>(Nth->GetValue(ctx).Get<ui64>(), items.size());
+ if (!n) {
+ return ctx.HolderFactory.GetEmptyContainer();
+ }
+
+ Algorithm(items.begin(), items.begin() + n, items.end(), comparator);
+ items.resize(n);
+
+ NUdf::TUnboxedValue *inplace = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(n, inplace);
+ for (auto& item : items) {
+ *inplace++ = std::move(item.second);
+ }
+ return result;
+ }
void PerformInplace(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue* keys, NUdf::TUnboxedValue* items, const TComparator& comparator) const {
Y_UNUSED(ctx);
@@ -456,169 +456,169 @@ public:
Y_FAIL("Not supported");
}
-private:
- void RegisterDependencies() const final {
- TBaseComputation::RegisterDependencies();
- this->DependsOn(Nth);
- }
-
- const TNthAlgorithm Algorithm;
- IComputationNode* const Nth;
-};
-
-class TKeepTopWrapper : public TMutableComputationNode<TKeepTopWrapper> {
- using TBaseComputation = TMutableComputationNode<TKeepTopWrapper>;
-public:
- TKeepTopWrapper(
- TComputationMutables& mutables,
- std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
- IComputationNode* count,
- IComputationNode* list,
- IComputationNode* item,
- IComputationExternalNode* arg,
- IComputationNode* key,
- IComputationNode* ascending,
- IComputationExternalNode* hotkey)
- : TBaseComputation(mutables)
- , Description(mutables, std::move(keySchemeTypes))
- , Count(count)
- , List(list)
- , Item(item)
- , Arg(arg)
- , Key(key)
- , Ascending(ascending)
- , HotKey(hotkey)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- const auto count = Count->GetValue(ctx).Get<ui64>();
- if (!count) {
- return ctx.HolderFactory.GetEmptyContainer();
- }
-
- auto list = List->GetValue(ctx);
- auto item = Item->GetValue(ctx);
-
- const auto size = list.GetListLength();
-
- if (size < count) {
- return ctx.HolderFactory.Append(list.Release(), item.Release());
- }
-
- auto hotkey = HotKey->GetValue(ctx);
-
- if (size == count) {
- if (hotkey.IsInvalid()) {
- TUnboxedValueVector keys;
- keys.reserve(size);
-
- const auto ptr = list.GetElements();
- std::transform(ptr, ptr + size, std::back_inserter(keys), [&](const NUdf::TUnboxedValuePod item) {
- Arg->SetValue(ctx, item);
- return Key->GetValue(ctx);
- });
-
- const auto& ascending = Ascending->GetValue(ctx);
+private:
+ void RegisterDependencies() const final {
+ TBaseComputation::RegisterDependencies();
+ this->DependsOn(Nth);
+ }
+
+ const TNthAlgorithm Algorithm;
+ IComputationNode* const Nth;
+};
+
+class TKeepTopWrapper : public TMutableComputationNode<TKeepTopWrapper> {
+ using TBaseComputation = TMutableComputationNode<TKeepTopWrapper>;
+public:
+ TKeepTopWrapper(
+ TComputationMutables& mutables,
+ std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>>&& keySchemeTypes,
+ IComputationNode* count,
+ IComputationNode* list,
+ IComputationNode* item,
+ IComputationExternalNode* arg,
+ IComputationNode* key,
+ IComputationNode* ascending,
+ IComputationExternalNode* hotkey)
+ : TBaseComputation(mutables)
+ , Description(mutables, std::move(keySchemeTypes))
+ , Count(count)
+ , List(list)
+ , Item(item)
+ , Arg(arg)
+ , Key(key)
+ , Ascending(ascending)
+ , HotKey(hotkey)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ const auto count = Count->GetValue(ctx).Get<ui64>();
+ if (!count) {
+ return ctx.HolderFactory.GetEmptyContainer();
+ }
+
+ auto list = List->GetValue(ctx);
+ auto item = Item->GetValue(ctx);
+
+ const auto size = list.GetListLength();
+
+ if (size < count) {
+ return ctx.HolderFactory.Append(list.Release(), item.Release());
+ }
+
+ auto hotkey = HotKey->GetValue(ctx);
+
+ if (size == count) {
+ if (hotkey.IsInvalid()) {
+ TUnboxedValueVector keys;
+ keys.reserve(size);
+
+ const auto ptr = list.GetElements();
+ std::transform(ptr, ptr + size, std::back_inserter(keys), [&](const NUdf::TUnboxedValuePod item) {
+ Arg->SetValue(ctx, item);
+ return Key->GetValue(ctx);
+ });
+
+ const auto& ascending = Ascending->GetValue(ctx);
const auto max = std::max_element(keys.begin(), keys.end(), Description.MakeComparator<TUnboxedValueVector>(ascending));
- hotkey = *max;
- HotKey->SetValue(ctx, std::move(*max));
+ hotkey = *max;
+ HotKey->SetValue(ctx, std::move(*max));
}
- }
-
- const auto copy = item;
- Arg->SetValue(ctx, item.Release());
- const auto& key = Key->GetValue(ctx);
-
- const auto& ascending = Ascending->GetValue(ctx);
+ }
+
+ const auto copy = item;
+ Arg->SetValue(ctx, item.Release());
+ const auto& key = Key->GetValue(ctx);
+
+ const auto& ascending = Ascending->GetValue(ctx);
if (Description.MakeComparator<TUnboxedValueVector>(ascending)(key, hotkey)) {
- const auto reserve = std::max<ui64>(count << 1ULL, 1ULL << 8ULL);
- if (size < reserve) {
- return ctx.HolderFactory.Append(list.Release(), Arg->GetValue(ctx).Release());
- }
-
- TKeyPayloadPairVector items(1U, TKeyPayloadPair(Key->GetValue(ctx), Arg->GetValue(ctx)));
- items.reserve(items.size() + size);
-
- const auto ptr = list.GetElements();
- std::transform(ptr, ptr + size, std::back_inserter(items), [&](const NUdf::TUnboxedValuePod item) {
- Arg->SetValue(ctx, item);
- return TKeyPayloadPair(Key->GetValue(ctx), Arg->GetValue(ctx));
- });
-
- Description.Prepare(ctx, items);
+ const auto reserve = std::max<ui64>(count << 1ULL, 1ULL << 8ULL);
+ if (size < reserve) {
+ return ctx.HolderFactory.Append(list.Release(), Arg->GetValue(ctx).Release());
+ }
+
+ TKeyPayloadPairVector items(1U, TKeyPayloadPair(Key->GetValue(ctx), Arg->GetValue(ctx)));
+ items.reserve(items.size() + size);
+
+ const auto ptr = list.GetElements();
+ std::transform(ptr, ptr + size, std::back_inserter(items), [&](const NUdf::TUnboxedValuePod item) {
+ Arg->SetValue(ctx, item);
+ return TKeyPayloadPair(Key->GetValue(ctx), Arg->GetValue(ctx));
+ });
+
+ Description.Prepare(ctx, items);
std::nth_element(items.begin(), items.begin() + count - 1U, items.end(), Description.MakeComparator<TKeyPayloadPairVector>(ascending));
- items.resize(count);
-
- NUdf::TUnboxedValue *inplace = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, inplace); /// TODO: Use list holder.
- for (auto& item : items) {
- *inplace++ = std::move(item.second);
- }
- return result;
- }
-
- return list.Release();
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(Count);
- DependsOn(List);
- DependsOn(Item);
- Own(Arg);
- DependsOn(Key);
- DependsOn(Ascending);
- Own(HotKey);
- }
-
- TCompareDescr Description;
- IComputationNode* const Count;
+ items.resize(count);
+
+ NUdf::TUnboxedValue *inplace = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(count, inplace); /// TODO: Use list holder.
+ for (auto& item : items) {
+ *inplace++ = std::move(item.second);
+ }
+ return result;
+ }
+
+ return list.Release();
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(Count);
+ DependsOn(List);
+ DependsOn(Item);
+ Own(Arg);
+ DependsOn(Key);
+ DependsOn(Ascending);
+ Own(HotKey);
+ }
+
+ TCompareDescr Description;
+ IComputationNode* const Count;
IComputationNode* const List;
IComputationNode* const Item;
- IComputationExternalNode* const Arg;
+ IComputationExternalNode* const Arg;
IComputationNode* const Key;
IComputationNode* const Ascending;
- IComputationExternalNode* const HotKey;
+ IComputationExternalNode* const HotKey;
};
-std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>> GetKeySchemeTypes(TType* keyType, TType* ascType) {
+std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>> GetKeySchemeTypes(TType* keyType, TType* ascType) {
std::vector<std::tuple<NUdf::EDataSlot, bool, TType*>> keySchemeTypes;
if (ascType->IsTuple()) {
MKQL_ENSURE(keyType->IsTuple(), "Key must be tuple");
- const auto keyDetailedType = static_cast<TTupleType*>(keyType);
- const auto keyElementsCount = keyDetailedType->GetElementsCount();
+ const auto keyDetailedType = static_cast<TTupleType*>(keyType);
+ const auto keyElementsCount = keyDetailedType->GetElementsCount();
keySchemeTypes.reserve(keyElementsCount);
for (ui32 i = 0; i < keyElementsCount; ++i) {
- const auto elementType = keyDetailedType->GetElementType(i);
+ const auto elementType = keyDetailedType->GetElementType(i);
bool isOptional;
- const auto unpacked = UnpackOptional(elementType, isOptional);
+ const auto unpacked = UnpackOptional(elementType, isOptional);
if (!unpacked->IsData()) {
- keySchemeTypes.emplace_back(NUdf::EDataSlot::String, false, elementType);
+ keySchemeTypes.emplace_back(NUdf::EDataSlot::String, false, elementType);
} else {
- keySchemeTypes.emplace_back(*static_cast<TDataType*>(unpacked)->GetDataSlot(), isOptional, nullptr);
+ keySchemeTypes.emplace_back(*static_cast<TDataType*>(unpacked)->GetDataSlot(), isOptional, nullptr);
}
}
} else {
keySchemeTypes.reserve(1);
bool isOptional;
- const auto unpacked = UnpackOptional(keyType, isOptional);
+ const auto unpacked = UnpackOptional(keyType, isOptional);
if (!unpacked->IsData()) {
- keySchemeTypes.emplace_back(NUdf::EDataSlot::String, false, keyType);
+ keySchemeTypes.emplace_back(NUdf::EDataSlot::String, false, keyType);
} else {
- keySchemeTypes.emplace_back(*static_cast<TDataType*>(unpacked)->GetDataSlot(), isOptional, nullptr);
+ keySchemeTypes.emplace_back(*static_cast<TDataType*>(unpacked)->GetDataSlot(), isOptional, nullptr);
}
}
- return keySchemeTypes;
-}
+ return keySchemeTypes;
+}
IComputationNode* WrapAlgo(TAlgorithm algorithm, TAlgorithmInplace algorithmInplace, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
-
- const auto keyNode = callable.GetInput(2);
- const auto sortNode = callable.GetInput(3);
-
- const auto keyType = keyNode.GetStaticType();
- const auto ascType = sortNode.GetStaticType();
+ MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
+
+ const auto keyNode = callable.GetInput(2);
+ const auto sortNode = callable.GetInput(3);
+
+ const auto keyType = keyNode.GetStaticType();
+ const auto ascType = sortNode.GetStaticType();
auto listNode = callable.GetInput(0);
IComputationNode* list = nullptr;
bool stealed = false;
@@ -629,77 +629,77 @@ IComputationNode* WrapAlgo(TAlgorithm algorithm, TAlgorithmInplace algorithmInpl
stealed = true;
}
}
-
+
if (!list) {
list = LocateNode(ctx.NodeLocator, callable, 0);
}
- const auto key = LocateNode(ctx.NodeLocator, callable, 2);
- const auto ascending = LocateNode(ctx.NodeLocator, callable, 3);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ const auto key = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto ascending = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
return new TAlgoWrapper(algorithm, algorithmInplace, ctx.Mutables, GetKeySchemeTypes(keyType, ascType), list,
itemArg, key, ascending, stealed);
}
-IComputationNode* WrapNthAlgo(TNthAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
-
- const auto keyNode = callable.GetInput(3);
- const auto sortNode = callable.GetInput(4);
-
- const auto keyType = keyNode.GetStaticType();
- const auto ascType = sortNode.GetStaticType();
-
- const auto list = LocateNode(ctx.NodeLocator, callable, 0);
- const auto nth = LocateNode(ctx.NodeLocator, callable, 1);
- const auto key = LocateNode(ctx.NodeLocator, callable, 3);
- const auto ascending = LocateNode(ctx.NodeLocator, callable, 4);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
-
- return new TNthAlgoWrapper(algorithm, ctx.Mutables, GetKeySchemeTypes(keyType, ascType), list, nth, itemArg, key, ascending);
+IComputationNode* WrapNthAlgo(TNthAlgorithm algorithm, TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
+
+ const auto keyNode = callable.GetInput(3);
+ const auto sortNode = callable.GetInput(4);
+
+ const auto keyType = keyNode.GetStaticType();
+ const auto ascType = sortNode.GetStaticType();
+
+ const auto list = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto nth = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto key = LocateNode(ctx.NodeLocator, callable, 3);
+ const auto ascending = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 2);
+
+ return new TNthAlgoWrapper(algorithm, ctx.Mutables, GetKeySchemeTypes(keyType, ascType), list, nth, itemArg, key, ascending);
}
-
-}
-
+
+}
+
IComputationNode* WrapUnstableSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
return WrapAlgo(&std::sort<TKeyPayloadPairVector::iterator, TComparator>,
&std::sort<TGatherIterator, TComparator>, callable, ctx);
}
-IComputationNode* WrapSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+IComputationNode* WrapSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
return WrapAlgo(&std::stable_sort<TKeyPayloadPairVector::iterator, TComparator>,
&std::stable_sort<TGatherIterator, TComparator>, callable, ctx);
}
-
-IComputationNode* WrapTop(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapNthAlgo(&std::nth_element<TKeyPayloadPairVector::iterator, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapTopSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapNthAlgo(&std::partial_sort<TKeyPayloadPairVector::iterator, TComparator>, callable, ctx);
-}
-
-IComputationNode* WrapKeepTop(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 7, "Expected 7 args");
-
- const auto keyNode = callable.GetInput(4);
- const auto sortNode = callable.GetInput(5);
-
- const auto keyType = keyNode.GetStaticType();
- const auto ascType = sortNode.GetStaticType();
-
- const auto count = LocateNode(ctx.NodeLocator, callable, 0);
- const auto list = LocateNode(ctx.NodeLocator, callable, 1);
- const auto item = LocateNode(ctx.NodeLocator, callable, 2);
-
- const auto key = LocateNode(ctx.NodeLocator, callable, 4);
- const auto ascending = LocateNode(ctx.NodeLocator, callable, 5);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
- const auto hotkey = LocateExternalNode(ctx.NodeLocator, callable, 6);
-
- return new TKeepTopWrapper(ctx.Mutables, GetKeySchemeTypes(keyType, ascType), count, list, item, itemArg, key, ascending, hotkey);
-}
-
-}
-}
+
+IComputationNode* WrapTop(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapNthAlgo(&std::nth_element<TKeyPayloadPairVector::iterator, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapTopSort(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapNthAlgo(&std::partial_sort<TKeyPayloadPairVector::iterator, TComparator>, callable, ctx);
+}
+
+IComputationNode* WrapKeepTop(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 7, "Expected 7 args");
+
+ const auto keyNode = callable.GetInput(4);
+ const auto sortNode = callable.GetInput(5);
+
+ const auto keyType = keyNode.GetStaticType();
+ const auto ascType = sortNode.GetStaticType();
+
+ const auto count = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto list = LocateNode(ctx.NodeLocator, callable, 1);
+ const auto item = LocateNode(ctx.NodeLocator, callable, 2);
+
+ const auto key = LocateNode(ctx.NodeLocator, callable, 4);
+ const auto ascending = LocateNode(ctx.NodeLocator, callable, 5);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 3);
+ const auto hotkey = LocateExternalNode(ctx.NodeLocator, callable, 6);
+
+ return new TKeepTopWrapper(ctx.Mutables, GetKeySchemeTypes(keyType, ascType), count, list, item, itemArg, key, ascending, hotkey);
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_sort.h b/ydb/library/yql/minikql/comp_nodes/mkql_sort.h
index 847197affd..93f99c90cd 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_sort.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_sort.h
@@ -8,11 +8,11 @@ IComputationNode* WrapUnstableSort(TCallable& callable, const TComputationNodeFa
IComputationNode* WrapSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapTop(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapTopSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapKeepTop(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
+IComputationNode* WrapTop(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapTopSort(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapKeepTop(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_source.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_source.cpp
index 04c558272e..20cdca896b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_source.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_source.cpp
@@ -1,82 +1,82 @@
-#include "mkql_source.h"
+#include "mkql_source.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-class TSourceOfWrapper : public TMutableComputationNode<TSourceOfWrapper> {
- typedef TMutableComputationNode<TSourceOfWrapper> TBaseComputation;
-private:
- class TValue : public TComputationValue<TValue> {
- public:
- TValue(TMemoryUsageInfo* memInfo)
- : TComputationValue<TValue>(memInfo)
- {}
-
- private:
- ui32 GetTraverseCount() const override { return 0U; }
-
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- result = NUdf::TUnboxedValuePod();
- return NUdf::EFetchStatus::Ok;
- }
- };
-
-public:
- TSourceOfWrapper(TComputationMutables& mutables)
- : TBaseComputation(mutables)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TValue>();
- }
-
-private:
- void RegisterDependencies() const final {}
-};
-
-class TSourceWrapper : public TStatelessWideFlowCodegeneratorNode<TSourceWrapper> {
-using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TSourceWrapper>;
-public:
- TSourceWrapper()
- : TStatelessWideFlowCodegeneratorNode<TSourceWrapper>(nullptr)
- {}
-
- EFetchResult DoCalculate(TComputationContext&, NUdf::TUnboxedValue*const*) const {
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*&) const {
- return {ConstantInt::get(Type::getInt32Ty(ctx.Codegen->GetContext()), static_cast<i32>(EFetchResult::One)), {}};
- }
-#endif
-private:
- void RegisterDependencies() const final {}
-};
-
-}
-
-IComputationNode* WrapSourceOf(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args.");
- const auto type = callable.GetType()->GetReturnType();
- if (type->IsFlow()) {
- return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod());
- } else if (type->IsStream()) {
- return new TSourceOfWrapper(ctx.Mutables);
- }
-
- THROW yexception() << "Expected flow or stream.";
-}
-
-IComputationNode* WrapSource(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args.");
- MKQL_ENSURE(!AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount(), "Expected zero width of output flow.");
- return new TSourceWrapper;
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+class TSourceOfWrapper : public TMutableComputationNode<TSourceOfWrapper> {
+ typedef TMutableComputationNode<TSourceOfWrapper> TBaseComputation;
+private:
+ class TValue : public TComputationValue<TValue> {
+ public:
+ TValue(TMemoryUsageInfo* memInfo)
+ : TComputationValue<TValue>(memInfo)
+ {}
+
+ private:
+ ui32 GetTraverseCount() const override { return 0U; }
+
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ result = NUdf::TUnboxedValuePod();
+ return NUdf::EFetchStatus::Ok;
+ }
+ };
+
+public:
+ TSourceOfWrapper(TComputationMutables& mutables)
+ : TBaseComputation(mutables)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TValue>();
+ }
+
+private:
+ void RegisterDependencies() const final {}
+};
+
+class TSourceWrapper : public TStatelessWideFlowCodegeneratorNode<TSourceWrapper> {
+using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TSourceWrapper>;
+public:
+ TSourceWrapper()
+ : TStatelessWideFlowCodegeneratorNode<TSourceWrapper>(nullptr)
+ {}
+
+ EFetchResult DoCalculate(TComputationContext&, NUdf::TUnboxedValue*const*) const {
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*&) const {
+ return {ConstantInt::get(Type::getInt32Ty(ctx.Codegen->GetContext()), static_cast<i32>(EFetchResult::One)), {}};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {}
+};
+
+}
+
+IComputationNode* WrapSourceOf(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args.");
+ const auto type = callable.GetType()->GetReturnType();
+ if (type->IsFlow()) {
+ return ctx.NodeFactory.CreateImmutableNode(NUdf::TUnboxedValuePod());
+ } else if (type->IsStream()) {
+ return new TSourceOfWrapper(ctx.Mutables);
+ }
+
+ THROW yexception() << "Expected flow or stream.";
+}
+
+IComputationNode* WrapSource(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args.");
+ MKQL_ENSURE(!AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount(), "Expected zero width of output flow.");
+ return new TSourceWrapper;
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_source.h b/ydb/library/yql/minikql/comp_nodes/mkql_source.h
index 1e72e8db5d..e8d7c3ee6a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_source.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_source.h
@@ -1,11 +1,11 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapSourceOf(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapSource(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapSourceOf(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapSource(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.cpp
index cfdcfcaef4..ddd2c5e3ed 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.cpp
@@ -1,104 +1,104 @@
-#include "mkql_squeeze_state.h"
-#include "mkql_saveload.h"
-
+#include "mkql_squeeze_state.h"
+#include "mkql_saveload.h"
+
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_pack.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-TSqueezeState::TSqueezeState(
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* updateState,
- IComputationExternalNode* inSave,
- IComputationNode* outSave,
- IComputationExternalNode* inLoad,
- IComputationNode* outLoad,
- const TType* stateType
-)
- : Item(item)
- , State(state)
- , Switch(outSwitch)
- , InitState(initState)
- , UpdateState(updateState)
- , InSave(inSave)
- , OutSave(outSave)
- , InLoad(inLoad)
- , OutLoad(outLoad)
- , StateType(stateType)
-{}
-
-TSqueezeState::TSqueezeState(const TSqueezeState& state)
- : Item(state.Item)
- , State(state.State)
- , Switch(state.Switch)
- , InitState(state.InitState)
- , UpdateState(state.UpdateState)
- , InSave(state.InSave)
- , OutSave(state.OutSave)
- , InLoad(state.InLoad)
- , OutLoad(state.OutLoad)
- , StateType(state.StateType)
-{}
-
-NUdf::TUnboxedValuePod TSqueezeState::Save(TComputationContext& ctx) const {
- TString out;
- WriteByte(out, static_cast<ui8>(Stage));
- if (ESqueezeState::Work == Stage) {
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+TSqueezeState::TSqueezeState(
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* updateState,
+ IComputationExternalNode* inSave,
+ IComputationNode* outSave,
+ IComputationExternalNode* inLoad,
+ IComputationNode* outLoad,
+ const TType* stateType
+)
+ : Item(item)
+ , State(state)
+ , Switch(outSwitch)
+ , InitState(initState)
+ , UpdateState(updateState)
+ , InSave(inSave)
+ , OutSave(outSave)
+ , InLoad(inLoad)
+ , OutLoad(outLoad)
+ , StateType(stateType)
+{}
+
+TSqueezeState::TSqueezeState(const TSqueezeState& state)
+ : Item(state.Item)
+ , State(state.State)
+ , Switch(state.Switch)
+ , InitState(state.InitState)
+ , UpdateState(state.UpdateState)
+ , InSave(state.InSave)
+ , OutSave(state.OutSave)
+ , InLoad(state.InLoad)
+ , OutLoad(state.OutLoad)
+ , StateType(state.StateType)
+{}
+
+NUdf::TUnboxedValuePod TSqueezeState::Save(TComputationContext& ctx) const {
+ TString out;
+ WriteByte(out, static_cast<ui8>(Stage));
+ if (ESqueezeState::Work == Stage) {
InSave->SetValue(ctx, State->GetValue(ctx));
WriteUnboxedValue(out, GetPacker(), OutSave->GetValue(ctx));
- }
- return MakeString(out);
-}
-
-void TSqueezeState::Load(TComputationContext& ctx, const NUdf::TStringRef& state) {
- TStringBuf in(state.Data(), state.Size());
- Stage = static_cast<ESqueezeState>(ReadByte(in));
- if (ESqueezeState::Work == Stage) {
+ }
+ return MakeString(out);
+}
+
+void TSqueezeState::Load(TComputationContext& ctx, const NUdf::TStringRef& state) {
+ TStringBuf in(state.Data(), state.Size());
+ Stage = static_cast<ESqueezeState>(ReadByte(in));
+ if (ESqueezeState::Work == Stage) {
InLoad->SetValue(ctx, ReadUnboxedValue(in, GetPacker(), ctx));
State->SetValue(ctx, OutLoad->GetValue(ctx));
- }
-}
-
-const TValuePacker& TSqueezeState::GetPacker() const {
- if (!Packer && StateType)
+ }
+}
+
+const TValuePacker& TSqueezeState::GetPacker() const {
+ if (!Packer && StateType)
Packer = MakeHolder<TValuePacker>(false, StateType);
- return *Packer;
-}
-
-TSqueezeCodegenValue::TSqueezeCodegenValue(TMemoryUsageInfo* memInfo, const TSqueezeState& state, TFetchPtr fetch, TComputationContext& ctx, NUdf::TUnboxedValue&& stream)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Stream(std::move(stream))
- , Ctx(ctx)
- , State(state)
-{}
-
-ui32 TSqueezeCodegenValue::GetTraverseCount() const {
- return 1U;
-}
-
-NUdf::TUnboxedValue TSqueezeCodegenValue::GetTraverseItem(ui32) const {
- return Stream;
-}
-
-NUdf::TUnboxedValue TSqueezeCodegenValue::Save() const {
- return State.Save(Ctx);
-}
-
-void TSqueezeCodegenValue::Load(const NUdf::TStringRef& state) {
- State.Load(Ctx, state);
-}
-
-NUdf::EFetchStatus TSqueezeCodegenValue::Fetch(NUdf::TUnboxedValue& result) {
- if (ESqueezeState::Finished == State.Stage)
- return NUdf::EFetchStatus::Finish;
- return FetchFunc(&Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result, State.Stage);
-}
-
-}
-}
+ return *Packer;
+}
+
+TSqueezeCodegenValue::TSqueezeCodegenValue(TMemoryUsageInfo* memInfo, const TSqueezeState& state, TFetchPtr fetch, TComputationContext& ctx, NUdf::TUnboxedValue&& stream)
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Stream(std::move(stream))
+ , Ctx(ctx)
+ , State(state)
+{}
+
+ui32 TSqueezeCodegenValue::GetTraverseCount() const {
+ return 1U;
+}
+
+NUdf::TUnboxedValue TSqueezeCodegenValue::GetTraverseItem(ui32) const {
+ return Stream;
+}
+
+NUdf::TUnboxedValue TSqueezeCodegenValue::Save() const {
+ return State.Save(Ctx);
+}
+
+void TSqueezeCodegenValue::Load(const NUdf::TStringRef& state) {
+ State.Load(Ctx, state);
+}
+
+NUdf::EFetchStatus TSqueezeCodegenValue::Fetch(NUdf::TUnboxedValue& result) {
+ if (ESqueezeState::Finished == State.Stage)
+ return NUdf::EFetchStatus::Finish;
+ return FetchFunc(&Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result, State.Stage);
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.h b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.h
index 993e06343f..6896c9f2a9 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_state.h
@@ -1,82 +1,82 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_pack.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-enum class ESqueezeState : ui8 {
- Idle = 0,
- Work,
- Finished
-};
-
-struct TSqueezeState {
- TSqueezeState(
- IComputationExternalNode* item,
- IComputationExternalNode* state,
- IComputationNode* outSwitch,
- IComputationNode* initState,
- IComputationNode* newState,
- IComputationExternalNode* inSave,
- IComputationNode* outSave,
- IComputationExternalNode* inLoad,
- IComputationNode* outLoad,
- const TType* stateType
- );
-
- TSqueezeState(const TSqueezeState& state);
-
- NUdf::TUnboxedValuePod Save(TComputationContext& ctx) const;
-
- void Load(TComputationContext& ctx, const NUdf::TStringRef& state);
-
- ESqueezeState Stage = ESqueezeState::Idle;
-
- IComputationExternalNode* const Item;
- IComputationExternalNode* const State;
- IComputationNode* const Switch;
- IComputationNode* const InitState;
- IComputationNode* const UpdateState;
-
- IComputationExternalNode* const InSave;
- IComputationNode* const OutSave;
- IComputationExternalNode* const InLoad;
- IComputationNode* const OutLoad;
-
-private:
- const TValuePacker& GetPacker() const;
-
- const TType* StateType;
-
- mutable THolder<TValuePacker> Packer;
-};
-
-class TSqueezeCodegenValue : public TComputationValue<TSqueezeCodegenValue> {
-public:
- using TBase = TComputationValue<TSqueezeCodegenValue>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&, ESqueezeState&);
-
- TSqueezeCodegenValue(TMemoryUsageInfo* memInfo, const TSqueezeState& state, TFetchPtr fetch, TComputationContext& ctx, NUdf::TUnboxedValue&& stream);
-
-private:
- ui32 GetTraverseCount() const final;
-
- NUdf::TUnboxedValue GetTraverseItem(ui32) const final;
-
- NUdf::TUnboxedValue Save() const final;
-
- void Load(const NUdf::TStringRef& state) final;
-
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final;
-
- const TFetchPtr FetchFunc;
- const NUdf::TUnboxedValue Stream;
- TComputationContext& Ctx;
- TSqueezeState State;
-};
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+enum class ESqueezeState : ui8 {
+ Idle = 0,
+ Work,
+ Finished
+};
+
+struct TSqueezeState {
+ TSqueezeState(
+ IComputationExternalNode* item,
+ IComputationExternalNode* state,
+ IComputationNode* outSwitch,
+ IComputationNode* initState,
+ IComputationNode* newState,
+ IComputationExternalNode* inSave,
+ IComputationNode* outSave,
+ IComputationExternalNode* inLoad,
+ IComputationNode* outLoad,
+ const TType* stateType
+ );
+
+ TSqueezeState(const TSqueezeState& state);
+
+ NUdf::TUnboxedValuePod Save(TComputationContext& ctx) const;
+
+ void Load(TComputationContext& ctx, const NUdf::TStringRef& state);
+
+ ESqueezeState Stage = ESqueezeState::Idle;
+
+ IComputationExternalNode* const Item;
+ IComputationExternalNode* const State;
+ IComputationNode* const Switch;
+ IComputationNode* const InitState;
+ IComputationNode* const UpdateState;
+
+ IComputationExternalNode* const InSave;
+ IComputationNode* const OutSave;
+ IComputationExternalNode* const InLoad;
+ IComputationNode* const OutLoad;
+
+private:
+ const TValuePacker& GetPacker() const;
+
+ const TType* StateType;
+
+ mutable THolder<TValuePacker> Packer;
+};
+
+class TSqueezeCodegenValue : public TComputationValue<TSqueezeCodegenValue> {
+public:
+ using TBase = TComputationValue<TSqueezeCodegenValue>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&, ESqueezeState&);
+
+ TSqueezeCodegenValue(TMemoryUsageInfo* memInfo, const TSqueezeState& state, TFetchPtr fetch, TComputationContext& ctx, NUdf::TUnboxedValue&& stream);
+
+private:
+ ui32 GetTraverseCount() const final;
+
+ NUdf::TUnboxedValue GetTraverseItem(ui32) const final;
+
+ NUdf::TUnboxedValue Save() const final;
+
+ void Load(const NUdf::TStringRef& state) final;
+
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final;
+
+ const TFetchPtr FetchFunc;
+ const NUdf::TUnboxedValue Stream;
+ TComputationContext& Ctx;
+ TSqueezeState State;
+};
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.cpp
index 38f85470cd..facb20ba54 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.cpp
@@ -1,191 +1,191 @@
-
-#include "mkql_squeeze_to_list.h"
-
+
+#include "mkql_squeeze_to_list.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-class TSqueezeToListWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeToListWrapper> {
-using TBase = TStatefulFlowCodegeneratorNode<TSqueezeToListWrapper>;
-public:
- class TState : public TComputationValue<TState> {
- using TBase = TComputationValue<TState>;
- public:
- TState(TMemoryUsageInfo* memInfo, ui64 limit)
- : TBase(memInfo), Limit(limit)
- {}
-
- NUdf::TUnboxedValuePod Pull(TComputationContext& ctx) {
- if (Accumulator.empty())
- return ctx.HolderFactory.GetEmptyContainer();
-
- NUdf::TUnboxedValue *items = nullptr;
- const auto list = ctx.HolderFactory.CreateDirectArrayHolder(Accumulator.size(), items);
- std::move(Accumulator.begin(), Accumulator.end(), items);
- Accumulator.clear();
- return list;
- }
-
- bool Push(NUdf::TUnboxedValuePod value) {
- Accumulator.emplace_back(std::move(value));
- return Limit <= Accumulator.size();
- }
- private:
- const ui64 Limit;
- TUnboxedValueDeque Accumulator;
- };
-
- TSqueezeToListWrapper(TComputationMutables& mutables, IComputationNode* flow, IComputationNode* limit)
- : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
- , Flow(flow), Limit(limit)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return NUdf::TUnboxedValuePod::MakeFinish();
- } else if (!state.HasValue()) {
- MakeState(ctx, Limit->GetValue(ctx).GetOrDefault(std::numeric_limits<ui64>::max()), state);
- }
-
- while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
- if (auto item = Flow->GetValue(ctx); item.IsYield()) {
- return item.Release();
- } else if (item.IsFinish() || statePtr->Push(item.Release())) {
- const auto list = statePtr->Pull(ctx);
- state = NUdf::TUnboxedValuePod::MakeFinish();
- return list;
- }
- }
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+class TSqueezeToListWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeToListWrapper> {
+using TBase = TStatefulFlowCodegeneratorNode<TSqueezeToListWrapper>;
+public:
+ class TState : public TComputationValue<TState> {
+ using TBase = TComputationValue<TState>;
+ public:
+ TState(TMemoryUsageInfo* memInfo, ui64 limit)
+ : TBase(memInfo), Limit(limit)
+ {}
+
+ NUdf::TUnboxedValuePod Pull(TComputationContext& ctx) {
+ if (Accumulator.empty())
+ return ctx.HolderFactory.GetEmptyContainer();
+
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto list = ctx.HolderFactory.CreateDirectArrayHolder(Accumulator.size(), items);
+ std::move(Accumulator.begin(), Accumulator.end(), items);
+ Accumulator.clear();
+ return list;
+ }
+
+ bool Push(NUdf::TUnboxedValuePod value) {
+ Accumulator.emplace_back(std::move(value));
+ return Limit <= Accumulator.size();
+ }
+ private:
+ const ui64 Limit;
+ TUnboxedValueDeque Accumulator;
+ };
+
+ TSqueezeToListWrapper(TComputationMutables& mutables, IComputationNode* flow, IComputationNode* limit)
+ : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ , Flow(flow), Limit(limit)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ } else if (!state.HasValue()) {
+ MakeState(ctx, Limit->GetValue(ctx).GetOrDefault(std::numeric_limits<ui64>::max()), state);
+ }
+
+ while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
+ if (auto item = Flow->GetValue(ctx); item.IsYield()) {
+ return item.Release();
+ } else if (item.IsFinish() || statePtr->Push(item.Release())) {
+ const auto list = statePtr->Pull(ctx);
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ return list;
+ }
+ }
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- structPtrType // accumulator
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
- block = make;
-
- const auto value = GetNodeValue(Limit, ctx, block);
- const auto limit = SelectInst::Create(IsExists(value, block), GetterFor<ui64>(value, context, block), ConstantInt::get(Type::getInt64Ty(context), std::numeric_limits<ui64>::max()), "limit", block);
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeToListWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), limit->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, limit, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- result->addIncoming(GetFinish(context), block);
-
- BranchInst::Create(over, more, IsFinish(state, block), block);
-
- block = more;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(GetYield(context), block);
-
- const auto choise = SwitchInst::Create(item, plus, 2U, block);
- choise->addCase(GetFinish(context), done);
- choise->addCase(GetYield(context), over);
-
- block = plus;
-
- const auto push = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Push));
-
- const auto arg = WrapArgumentForWindows(item, ctx, block);
-
- const auto pushType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), arg->getType()}, false);
- const auto pushPtr = CastInst::Create(Instruction::IntToPtr, push, PointerType::getUnqual(pushType), "push", block);
- const auto stop = CallInst::Create(pushPtr, {stateArg, arg}, "stop", block);
-
- BranchInst::Create(done, more, stop, block);
-
- block = done;
-
- const auto pull = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Pull));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto pullType = FunctionType::get(valueType, {stateArg->getType(), ctx.Ctx->getType()}, false);
- const auto pullPtr = CastInst::Create(Instruction::IntToPtr, pull, PointerType::getUnqual(pullType), "pull", block);
- const auto list = CallInst::Create(pullPtr, {stateArg, ctx.Ctx}, "list", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(list, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto pullType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType(), ctx.Ctx->getType()}, false);
- const auto pullPtr = CastInst::Create(Instruction::IntToPtr, pull, PointerType::getUnqual(pullType), "pull", block);
- CallInst::Create(pullPtr, {stateArg, ptr, ctx.Ctx}, "", block);
- const auto list = new LoadInst(ptr, "list", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(list, block);
- }
-
- new StoreInst(GetFinish(context), statePtr, block);
- BranchInst::Create(over, block);
-
- block = over;
- return result;
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, const ui64 limit, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TState>(limit);
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->DependsOn(flow, Limit);
- }
- }
-
- IComputationNode* const Flow;
- IComputationNode* const Limit;
-};
-
-}
-
-IComputationNode* WrapSqueezeToList(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected pair of arguments.");
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto limit = LocateNode(ctx.NodeLocator, callable, 1);
- return new TSqueezeToListWrapper(ctx.Mutables, flow, limit);
-}
-
-}
-}
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ structPtrType // accumulator
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
+ block = make;
+
+ const auto value = GetNodeValue(Limit, ctx, block);
+ const auto limit = SelectInst::Create(IsExists(value, block), GetterFor<ui64>(value, context, block), ConstantInt::get(Type::getInt64Ty(context), std::numeric_limits<ui64>::max()), "limit", block);
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeToListWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), limit->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, limit, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ BranchInst::Create(over, more, IsFinish(state, block), block);
+
+ block = more;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(GetYield(context), block);
+
+ const auto choise = SwitchInst::Create(item, plus, 2U, block);
+ choise->addCase(GetFinish(context), done);
+ choise->addCase(GetYield(context), over);
+
+ block = plus;
+
+ const auto push = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Push));
+
+ const auto arg = WrapArgumentForWindows(item, ctx, block);
+
+ const auto pushType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), arg->getType()}, false);
+ const auto pushPtr = CastInst::Create(Instruction::IntToPtr, push, PointerType::getUnqual(pushType), "push", block);
+ const auto stop = CallInst::Create(pushPtr, {stateArg, arg}, "stop", block);
+
+ BranchInst::Create(done, more, stop, block);
+
+ block = done;
+
+ const auto pull = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Pull));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto pullType = FunctionType::get(valueType, {stateArg->getType(), ctx.Ctx->getType()}, false);
+ const auto pullPtr = CastInst::Create(Instruction::IntToPtr, pull, PointerType::getUnqual(pullType), "pull", block);
+ const auto list = CallInst::Create(pullPtr, {stateArg, ctx.Ctx}, "list", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(list, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto pullType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType(), ctx.Ctx->getType()}, false);
+ const auto pullPtr = CastInst::Create(Instruction::IntToPtr, pull, PointerType::getUnqual(pullType), "pull", block);
+ CallInst::Create(pullPtr, {stateArg, ptr, ctx.Ctx}, "", block);
+ const auto list = new LoadInst(ptr, "list", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(list, block);
+ }
+
+ new StoreInst(GetFinish(context), statePtr, block);
+ BranchInst::Create(over, block);
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, const ui64 limit, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TState>(limit);
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->DependsOn(flow, Limit);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationNode* const Limit;
+};
+
+}
+
+IComputationNode* WrapSqueezeToList(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected pair of arguments.");
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto limit = LocateNode(ctx.NodeLocator, callable, 1);
+ return new TSqueezeToListWrapper(ctx.Mutables, flow, limit);
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.h b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.h
index e51831bc94..dc8aef394f 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_squeeze_to_list.h
@@ -1,11 +1,11 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapSqueezeToList(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapSqueezeToList(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_switch.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_switch.cpp
index b31a36c2de..4571141d80 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_switch.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_switch.cpp
@@ -11,526 +11,526 @@ namespace NMiniKQL {
using NYql::EnsureDynamicCast;
-namespace {
-
+namespace {
+
static const TStatKey Switch_FlushesCount("Switch_FlushesCount", true);
static const TStatKey Switch_MaxRowsCount("Switch_MaxRowsCount", false);
-
+
using TPagedUnboxedValueList = TPagedList<NUdf::TUnboxedValue>;
struct TSwitchHandler {
- std::vector<ui32, TMKQLAllocator<ui32>> InputIndices;
- IComputationExternalNode* Item = nullptr;
+ std::vector<ui32, TMKQLAllocator<ui32>> InputIndices;
+ IComputationExternalNode* Item = nullptr;
IComputationNode* NewItem = nullptr;
- std::optional<ui32> ResultVariantOffset;
+ std::optional<ui32> ResultVariantOffset;
bool IsOutputVariant = false;
- EValueRepresentation Kind = EValueRepresentation::Any;
+ EValueRepresentation Kind = EValueRepresentation::Any;
};
-using TSwitchHandlersList = std::vector<TSwitchHandler, TMKQLAllocator<TSwitchHandler>>;
-
-class TState : public TComputationValue<TState> {
- typedef TComputationValue<TState> TBase;
-public:
- TState(TMemoryUsageInfo* memInfo, ui32 size)
- : TBase(memInfo), ChildReadIndex(size)
- {}
-
- ui32 ChildReadIndex;
- NUdf::EFetchStatus InputStatus = NUdf::EFetchStatus::Ok;
-};
-
-template <bool IsInputVariant, bool TrackRss>
-class TSwitchFlowWrapper : public TStatefulFlowCodegeneratorNode<TSwitchFlowWrapper<IsInputVariant, TrackRss>> {
- typedef TStatefulFlowCodegeneratorNode<TSwitchFlowWrapper<IsInputVariant, TrackRss>> TBaseComputation;
-private:
- class TFlowState : public TState {
- public:
- TFlowState(TMemoryUsageInfo* memInfo, TAlignedPagePool& pool, ui32 size)
- : TState(memInfo, size), Buffer(pool)
- {}
-
- void Add(NUdf::TUnboxedValuePod item) {
- Buffer.Add(item);
- }
-
- void PushStat(IStatsRegistry* stats) const {
- if (const auto size = Buffer.Size()) {
- MKQL_SET_MAX_STAT(stats, Switch_MaxRowsCount, static_cast<i64>(size));
- MKQL_INC_STAT(stats, Switch_FlushesCount);
- }
- }
-
- NUdf::TUnboxedValuePod Get(ui32 i) const {
- if (Buffer.Size() == i) {
- return NUdf::EFetchStatus::Finish == InputStatus ?
- NUdf::TUnboxedValuePod::MakeFinish():
- NUdf::TUnboxedValuePod::MakeYield();
- }
-
- return Buffer[i];
- }
-
- void Clear() {
- Buffer.Clear();
- }
-
- NUdf::TUnboxedValuePod Handler(ui32 index, const TSwitchHandler& handler, TComputationContext& ctx) {
- while (true) {
- auto current = Get(Position++);
- if (current.IsSpecial()) {
- Position = 0U;
- return current;
- }
-
- ui32 streamIndex = 0U;
- if constexpr (IsInputVariant) {
- streamIndex = current.GetVariantIndex();
- current = current.GetVariantItem().Release();
- }
-
- for (ui32 var = 0U; var < handler.InputIndices.size(); ++var) {
- if (handler.InputIndices[var] == streamIndex) {
- if (handler.InputIndices.size() > 1) {
- current = ctx.HolderFactory.CreateVariantHolder(current, var);
- }
-
- return current;
- }
- }
- }
- }
-
- ui32 Position = 0U;
- TPagedUnboxedValueList Buffer;
- };
-public:
- TSwitchFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, ui64 memLimit, TSwitchHandlersList&& handlers)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
- , Flow(flow)
- , MemLimit(memLimit)
- , Handlers(std::move(handlers))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- while (const auto ptr = static_cast<TFlowState*>(state.AsBoxed().Get())) {
- if (ptr->ChildReadIndex == Handlers.size()) {
- switch (ptr->InputStatus) {
- case NUdf::EFetchStatus::Ok: break;
- case NUdf::EFetchStatus::Yield:
- ptr->InputStatus = NUdf::EFetchStatus::Ok;
- return NUdf::TUnboxedValuePod::MakeYield();
- case NUdf::EFetchStatus::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
- const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
-
- do {
- auto current = Flow->GetValue(ctx);
- if (current.IsFinish()) {
- ptr->InputStatus = NUdf::EFetchStatus::Finish;
- break;
- } else if (current.IsYield()) {
- ptr->InputStatus = NUdf::EFetchStatus::Yield;
- break;
- }
- ptr->Add(current.Release());
- } while (!ctx.CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
-
-
- ptr->ChildReadIndex = 0U;
- ptr->PushStat(ctx.Stats);
- }
-
- const auto& handler = Handlers[ptr->ChildReadIndex];
- auto childRes = handler.NewItem->GetValue(ctx);
- if (childRes.IsSpecial()) {
- if (++ptr->ChildReadIndex == Handlers.size()) {
- ptr->Clear();
- }
-
- continue;
- }
-
- if (const auto offset = handler.ResultVariantOffset) {
- ui32 localIndex = 0U;
- if (handler.IsOutputVariant) {
- localIndex = childRes.GetVariantIndex();
- childRes = childRes.Release().GetVariantItem();
- }
-
- childRes = ctx.HolderFactory.CreateVariantHolder(childRes.Release(), *offset + localIndex);
- }
-
- return childRes.Release();
- }
+using TSwitchHandlersList = std::vector<TSwitchHandler, TMKQLAllocator<TSwitchHandler>>;
+
+class TState : public TComputationValue<TState> {
+ typedef TComputationValue<TState> TBase;
+public:
+ TState(TMemoryUsageInfo* memInfo, ui32 size)
+ : TBase(memInfo), ChildReadIndex(size)
+ {}
+
+ ui32 ChildReadIndex;
+ NUdf::EFetchStatus InputStatus = NUdf::EFetchStatus::Ok;
+};
+
+template <bool IsInputVariant, bool TrackRss>
+class TSwitchFlowWrapper : public TStatefulFlowCodegeneratorNode<TSwitchFlowWrapper<IsInputVariant, TrackRss>> {
+ typedef TStatefulFlowCodegeneratorNode<TSwitchFlowWrapper<IsInputVariant, TrackRss>> TBaseComputation;
+private:
+ class TFlowState : public TState {
+ public:
+ TFlowState(TMemoryUsageInfo* memInfo, TAlignedPagePool& pool, ui32 size)
+ : TState(memInfo, size), Buffer(pool)
+ {}
+
+ void Add(NUdf::TUnboxedValuePod item) {
+ Buffer.Add(item);
+ }
+
+ void PushStat(IStatsRegistry* stats) const {
+ if (const auto size = Buffer.Size()) {
+ MKQL_SET_MAX_STAT(stats, Switch_MaxRowsCount, static_cast<i64>(size));
+ MKQL_INC_STAT(stats, Switch_FlushesCount);
+ }
+ }
+
+ NUdf::TUnboxedValuePod Get(ui32 i) const {
+ if (Buffer.Size() == i) {
+ return NUdf::EFetchStatus::Finish == InputStatus ?
+ NUdf::TUnboxedValuePod::MakeFinish():
+ NUdf::TUnboxedValuePod::MakeYield();
+ }
+
+ return Buffer[i];
+ }
+
+ void Clear() {
+ Buffer.Clear();
+ }
+
+ NUdf::TUnboxedValuePod Handler(ui32 index, const TSwitchHandler& handler, TComputationContext& ctx) {
+ while (true) {
+ auto current = Get(Position++);
+ if (current.IsSpecial()) {
+ Position = 0U;
+ return current;
+ }
+
+ ui32 streamIndex = 0U;
+ if constexpr (IsInputVariant) {
+ streamIndex = current.GetVariantIndex();
+ current = current.GetVariantItem().Release();
+ }
+
+ for (ui32 var = 0U; var < handler.InputIndices.size(); ++var) {
+ if (handler.InputIndices[var] == streamIndex) {
+ if (handler.InputIndices.size() > 1) {
+ current = ctx.HolderFactory.CreateVariantHolder(current, var);
+ }
+
+ return current;
+ }
+ }
+ }
+ }
+
+ ui32 Position = 0U;
+ TPagedUnboxedValueList Buffer;
+ };
+public:
+ TSwitchFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, ui64 memLimit, TSwitchHandlersList&& handlers)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Any)
+ , Flow(flow)
+ , MemLimit(memLimit)
+ , Handlers(std::move(handlers))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ while (const auto ptr = static_cast<TFlowState*>(state.AsBoxed().Get())) {
+ if (ptr->ChildReadIndex == Handlers.size()) {
+ switch (ptr->InputStatus) {
+ case NUdf::EFetchStatus::Ok: break;
+ case NUdf::EFetchStatus::Yield:
+ ptr->InputStatus = NUdf::EFetchStatus::Ok;
+ return NUdf::TUnboxedValuePod::MakeYield();
+ case NUdf::EFetchStatus::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+ const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
+
+ do {
+ auto current = Flow->GetValue(ctx);
+ if (current.IsFinish()) {
+ ptr->InputStatus = NUdf::EFetchStatus::Finish;
+ break;
+ } else if (current.IsYield()) {
+ ptr->InputStatus = NUdf::EFetchStatus::Yield;
+ break;
+ }
+ ptr->Add(current.Release());
+ } while (!ctx.CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
+
+
+ ptr->ChildReadIndex = 0U;
+ ptr->PushStat(ctx.Stats);
+ }
+
+ const auto& handler = Handlers[ptr->ChildReadIndex];
+ auto childRes = handler.NewItem->GetValue(ctx);
+ if (childRes.IsSpecial()) {
+ if (++ptr->ChildReadIndex == Handlers.size()) {
+ ptr->Clear();
+ }
+
+ continue;
+ }
+
+ if (const auto offset = handler.ResultVariantOffset) {
+ ui32 localIndex = 0U;
+ if (handler.IsOutputVariant) {
+ localIndex = childRes.GetVariantIndex();
+ childRes = childRes.Release().GetVariantItem();
+ }
+
+ childRes = ctx.HolderFactory.CreateVariantHolder(childRes.Release(), *offset + localIndex);
+ }
+
+ return childRes.Release();
+ }
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
-private:
- Function* GenerateHandler(ui32 i, const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- TStringStream out;
- out << this->DebugString() << "::Handler_" << i << "_(" << static_cast<const void*>(this) << ").";
- const auto& name = out.Str();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto funcType = FunctionType::get(valueType, {PointerType::getUnqual(GetCompContextType(context))}, false);
-
- TCodegenContext ctx(codegen);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+private:
+ Function* GenerateHandler(ui32 i, const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ TStringStream out;
+ out << this->DebugString() << "::Handler_" << i << "_(" << static_cast<const void*>(this) << ").";
+ const auto& name = out.Str();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto funcType = FunctionType::get(valueType, {PointerType::getUnqual(GetCompContextType(context))}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*ctx.Func->arg_begin();
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto indexType = Type::getInt32Ty(context);
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- indexType, // index
- statusType, // status
- indexType, // position
- structPtrType // buffer
- });
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- auto block = main;
-
- const auto placeholder = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
- new AllocaInst(valueType, 0U, "placeholder", block) : nullptr;
-
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
- const auto posPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 7)}, "pos_ptr", block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto pos = new LoadInst(posPtr, "pos", block);
-
- const auto getFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Get));
-
- Value* input;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto getType = FunctionType::get(valueType, {stateArg->getType(), pos->getType()}, false);
- const auto getPtr = CastInst::Create(Instruction::IntToPtr, getFunc, PointerType::getUnqual(getType), "get", block);
- input = CallInst::Create(getPtr, {stateArg, pos}, "input", block);
- } else {
- const auto getType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), placeholder->getType(), pos->getType()}, false);
- const auto getPtr = CastInst::Create(Instruction::IntToPtr, getFunc, PointerType::getUnqual(getType), "get", block);
- CallInst::Create(getPtr, {stateArg, placeholder, pos}, "", block);
- input = new LoadInst(placeholder, "input", block);
- }
-
- const auto plus = BinaryOperator::CreateAdd(pos, ConstantInt::get(pos->getType(), 1), "plus", block);
- new StoreInst(plus, posPtr, block);
-
- BranchInst::Create(done, good, IsSpecial(input, block), block);
-
- block = done;
- new StoreInst(ConstantInt::get(pos->getType(), 0), posPtr, block);
- ReturnInst::Create(context, input, block);
-
- block = good;
-
- const auto unpack = IsInputVariant ? GetVariantParts(input, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), input);
-
- const auto& handler = Handlers[i];
- const auto choise = SwitchInst::Create(unpack.first, loop, handler.InputIndices.size(), block);
-
- for (ui32 idx = 0U; idx < handler.InputIndices.size(); ++idx) {
- const auto index = ConstantInt::get(indexType, idx);
-
- const auto var = BasicBlock::Create(context, (TString("var_") += ToString(idx)).c_str(), ctx.Func);
-
- choise->addCase(ConstantInt::get(indexType, handler.InputIndices[idx]), var);
- block = var;
-
- if (handler.InputIndices.size() > 1U) {
- const auto variant = MakeVariant(unpack.second, ConstantInt::get(indexType, idx), ctx, block);
- ReturnInst::Create(context, variant, block);
- } else {
- ReturnInst::Create(context, unpack.second, block);
- }
- }
-
- return ctx.Func;
- }
-public:
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- for (ui32 i = 0U; i < Handlers.size(); ++i) {
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*ctx.Func->arg_begin();
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ indexType, // index
+ statusType, // status
+ indexType, // position
+ structPtrType // buffer
+ });
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ auto block = main;
+
+ const auto placeholder = NYql::NCodegen::ETarget::Windows == ctx.Codegen->GetEffectiveTarget() ?
+ new AllocaInst(valueType, 0U, "placeholder", block) : nullptr;
+
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+ const auto posPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 7)}, "pos_ptr", block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto pos = new LoadInst(posPtr, "pos", block);
+
+ const auto getFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Get));
+
+ Value* input;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto getType = FunctionType::get(valueType, {stateArg->getType(), pos->getType()}, false);
+ const auto getPtr = CastInst::Create(Instruction::IntToPtr, getFunc, PointerType::getUnqual(getType), "get", block);
+ input = CallInst::Create(getPtr, {stateArg, pos}, "input", block);
+ } else {
+ const auto getType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), placeholder->getType(), pos->getType()}, false);
+ const auto getPtr = CastInst::Create(Instruction::IntToPtr, getFunc, PointerType::getUnqual(getType), "get", block);
+ CallInst::Create(getPtr, {stateArg, placeholder, pos}, "", block);
+ input = new LoadInst(placeholder, "input", block);
+ }
+
+ const auto plus = BinaryOperator::CreateAdd(pos, ConstantInt::get(pos->getType(), 1), "plus", block);
+ new StoreInst(plus, posPtr, block);
+
+ BranchInst::Create(done, good, IsSpecial(input, block), block);
+
+ block = done;
+ new StoreInst(ConstantInt::get(pos->getType(), 0), posPtr, block);
+ ReturnInst::Create(context, input, block);
+
+ block = good;
+
+ const auto unpack = IsInputVariant ? GetVariantParts(input, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), input);
+
+ const auto& handler = Handlers[i];
+ const auto choise = SwitchInst::Create(unpack.first, loop, handler.InputIndices.size(), block);
+
+ for (ui32 idx = 0U; idx < handler.InputIndices.size(); ++idx) {
+ const auto index = ConstantInt::get(indexType, idx);
+
+ const auto var = BasicBlock::Create(context, (TString("var_") += ToString(idx)).c_str(), ctx.Func);
+
+ choise->addCase(ConstantInt::get(indexType, handler.InputIndices[idx]), var);
+ block = var;
+
+ if (handler.InputIndices.size() > 1U) {
+ const auto variant = MakeVariant(unpack.second, ConstantInt::get(indexType, idx), ctx, block);
+ ReturnInst::Create(context, variant, block);
+ } else {
+ ReturnInst::Create(context, unpack.second, block);
+ }
+ }
+
+ return ctx.Func;
+ }
+public:
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ for (ui32 i = 0U; i < Handlers.size(); ++i) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(Handlers[i].Item)->SetValueGetter(GenerateHandler(i, ctx.Codegen));
- }
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto indexType = Type::getInt32Ty(context);
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- indexType, // index
- statusType, // status
- indexType, // position
- structPtrType // buffer
- });
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(valueType, Handlers.size() + 2U, "result", exit);
-
- BranchInst::Create(main, make, HasValue(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSwitchFlowWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- const auto indexPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 5)}, "index_ptr", block);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto index = new LoadInst(indexPtr, "index", block);
- const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ConstantInt::get(index->getType(), Handlers.size()), "empty", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(next, full, empty, block);
-
- {
- block = next;
-
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 6)}, "last", block);
-
- const auto last = new LoadInst(statusPtr, "last", block);
-
- result->addIncoming(GetFinish(context), block);
- const auto choise = SwitchInst::Create(last, pull, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
- result->addIncoming(GetYield(context), block);
- BranchInst::Create(exit, block);
-
- block = pull;
-
- const auto used = GetMemoryUsed(MemLimit, ctx, block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto finsh = IsFinish(item, block);
- const auto yield = IsYield(item, block);
- const auto special = BinaryOperator::CreateOr(finsh, yield, "special", block);
-
- const auto fin = SelectInst::Create(finsh, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "fin", block);
- const auto save = SelectInst::Create(yield, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), fin, "save", block);
- new StoreInst(save, statusPtr, block);
-
- BranchInst::Create(done, good, special, block);
-
- block = good;
-
- const auto addFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Add));
- const auto addArg = WrapArgumentForWindows(item, ctx, block);
- const auto addType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), addArg->getType()}, false);
- const auto addPtr = CastInst::Create(Instruction::IntToPtr, addFunc, PointerType::getUnqual(addType), "add", block);
- CallInst::Create(addPtr, {stateArg, addArg}, "", block);
-
- const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
- BranchInst::Create(done, loop, check, block);
-
- block = done;
- new StoreInst(ConstantInt::get(indexType, 0), indexPtr, block);
-
- const auto stat = ctx.GetStat();
- const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::PushStat));
- const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
- const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
- CallInst::Create(statPtr, {stateArg, stat}, "", block);
-
- BranchInst::Create(more, block);
- }
-
- {
- block = full;
-
- const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto drop = BasicBlock::Create(context, "drop", ctx.Func);
-
- new UnreachableInst(context, stub);
- const auto choise = SwitchInst::Create(index, stub, Handlers.size(), block);
-
- for (ui32 i = 0U; i < Handlers.size(); ++i) {
- const auto idx = ConstantInt::get(indexType, i);
-
- const auto var = BasicBlock::Create(context, (TString("var_") += ToString(i)).c_str(), ctx.Func);
-
- choise->addCase(idx, var);
- block = var;
-
- const auto output = GetNodeValue(Handlers[i].NewItem, ctx, block);
-
- if (const auto offset = Handlers[i].ResultVariantOffset) {
- const auto good = BasicBlock::Create(context, (TString("good_") += ToString(i)).c_str(), ctx.Func);
- BranchInst::Create(next, good, IsSpecial(output, block), block);
- block = good;
-
- const auto unpack = Handlers[i].IsOutputVariant ? GetVariantParts(output, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), output);
- const auto reindex = BinaryOperator::CreateAdd(unpack.first, ConstantInt::get(indexType, *offset), "reindex", block);
- const auto variant = MakeVariant(unpack.second, reindex, ctx, block);
- result->addIncoming(variant, block);
- BranchInst::Create(exit, block);
- } else {
- result->addIncoming(output, block);
- BranchInst::Create(next, exit, IsSpecial(output, block), block);
- }
- }
-
- block = next;
-
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(index->getType(), 1), "plus", block);
- new StoreInst(plus, indexPtr, block);
- const auto flush = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, plus, ConstantInt::get(plus->getType(), Handlers.size()), "flush", block);
- BranchInst::Create(drop, more, flush, block);
-
- block = drop;
-
- const auto clearFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Clear));
- const auto clearType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
- const auto clearPtr = CastInst::Create(Instruction::IntToPtr, clearFunc, PointerType::getUnqual(clearType), "clear", block);
- CallInst::Create(clearPtr, {stateArg}, "", block);
-
- BranchInst::Create(more, block);
-
- block = exit;
- return result;
- }
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TFlowState>(ctx.HolderFactory.GetPagePool(), Handlers.size());
- if (const auto ptr = static_cast<TFlowState*>(state.AsBoxed().Get())) {
- for (ui32 i = 0U; i < Handlers.size(); ++i) {
- const auto& handler = Handlers[i];
- handler.Item->SetGetter(std::bind(&TFlowState::Handler, ptr, i, std::cref(handler), std::placeholders::_1));
- }
- }
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- for (const auto& x : Handlers) {
- this->Own(flow, x.Item);
- this->DependsOn(flow, x.NewItem);
- }
- }
- }
-
- IComputationNode *const Flow;
- const ui64 MemLimit;
- const TSwitchHandlersList Handlers;
-};
-
-template <bool IsInputVariant, bool TrackRss>
-class TSwitchWrapper : public TCustomValueCodegeneratorNode<TSwitchWrapper<IsInputVariant, TrackRss>> {
- typedef TCustomValueCodegeneratorNode<TSwitchWrapper<IsInputVariant, TrackRss>> TBaseComputation;
-private:
+ }
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ indexType, // index
+ statusType, // status
+ indexType, // position
+ structPtrType // buffer
+ });
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(valueType, Handlers.size() + 2U, "result", exit);
+
+ BranchInst::Create(main, make, HasValue(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSwitchFlowWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ const auto indexPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 5)}, "index_ptr", block);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto index = new LoadInst(indexPtr, "index", block);
+ const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ConstantInt::get(index->getType(), Handlers.size()), "empty", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(next, full, empty, block);
+
+ {
+ block = next;
+
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 6)}, "last", block);
+
+ const auto last = new LoadInst(statusPtr, "last", block);
+
+ result->addIncoming(GetFinish(context), block);
+ const auto choise = SwitchInst::Create(last, pull, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
+ result->addIncoming(GetYield(context), block);
+ BranchInst::Create(exit, block);
+
+ block = pull;
+
+ const auto used = GetMemoryUsed(MemLimit, ctx, block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto finsh = IsFinish(item, block);
+ const auto yield = IsYield(item, block);
+ const auto special = BinaryOperator::CreateOr(finsh, yield, "special", block);
+
+ const auto fin = SelectInst::Create(finsh, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "fin", block);
+ const auto save = SelectInst::Create(yield, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), fin, "save", block);
+ new StoreInst(save, statusPtr, block);
+
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+
+ const auto addFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Add));
+ const auto addArg = WrapArgumentForWindows(item, ctx, block);
+ const auto addType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), addArg->getType()}, false);
+ const auto addPtr = CastInst::Create(Instruction::IntToPtr, addFunc, PointerType::getUnqual(addType), "add", block);
+ CallInst::Create(addPtr, {stateArg, addArg}, "", block);
+
+ const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
+ BranchInst::Create(done, loop, check, block);
+
+ block = done;
+ new StoreInst(ConstantInt::get(indexType, 0), indexPtr, block);
+
+ const auto stat = ctx.GetStat();
+ const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::PushStat));
+ const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
+ const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
+ CallInst::Create(statPtr, {stateArg, stat}, "", block);
+
+ BranchInst::Create(more, block);
+ }
+
+ {
+ block = full;
+
+ const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto drop = BasicBlock::Create(context, "drop", ctx.Func);
+
+ new UnreachableInst(context, stub);
+ const auto choise = SwitchInst::Create(index, stub, Handlers.size(), block);
+
+ for (ui32 i = 0U; i < Handlers.size(); ++i) {
+ const auto idx = ConstantInt::get(indexType, i);
+
+ const auto var = BasicBlock::Create(context, (TString("var_") += ToString(i)).c_str(), ctx.Func);
+
+ choise->addCase(idx, var);
+ block = var;
+
+ const auto output = GetNodeValue(Handlers[i].NewItem, ctx, block);
+
+ if (const auto offset = Handlers[i].ResultVariantOffset) {
+ const auto good = BasicBlock::Create(context, (TString("good_") += ToString(i)).c_str(), ctx.Func);
+ BranchInst::Create(next, good, IsSpecial(output, block), block);
+ block = good;
+
+ const auto unpack = Handlers[i].IsOutputVariant ? GetVariantParts(output, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), output);
+ const auto reindex = BinaryOperator::CreateAdd(unpack.first, ConstantInt::get(indexType, *offset), "reindex", block);
+ const auto variant = MakeVariant(unpack.second, reindex, ctx, block);
+ result->addIncoming(variant, block);
+ BranchInst::Create(exit, block);
+ } else {
+ result->addIncoming(output, block);
+ BranchInst::Create(next, exit, IsSpecial(output, block), block);
+ }
+ }
+
+ block = next;
+
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(index->getType(), 1), "plus", block);
+ new StoreInst(plus, indexPtr, block);
+ const auto flush = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, plus, ConstantInt::get(plus->getType(), Handlers.size()), "flush", block);
+ BranchInst::Create(drop, more, flush, block);
+
+ block = drop;
+
+ const auto clearFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TFlowState::Clear));
+ const auto clearType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
+ const auto clearPtr = CastInst::Create(Instruction::IntToPtr, clearFunc, PointerType::getUnqual(clearType), "clear", block);
+ CallInst::Create(clearPtr, {stateArg}, "", block);
+
+ BranchInst::Create(more, block);
+
+ block = exit;
+ return result;
+ }
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TFlowState>(ctx.HolderFactory.GetPagePool(), Handlers.size());
+ if (const auto ptr = static_cast<TFlowState*>(state.AsBoxed().Get())) {
+ for (ui32 i = 0U; i < Handlers.size(); ++i) {
+ const auto& handler = Handlers[i];
+ handler.Item->SetGetter(std::bind(&TFlowState::Handler, ptr, i, std::cref(handler), std::placeholders::_1));
+ }
+ }
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ for (const auto& x : Handlers) {
+ this->Own(flow, x.Item);
+ this->DependsOn(flow, x.NewItem);
+ }
+ }
+ }
+
+ IComputationNode *const Flow;
+ const ui64 MemLimit;
+ const TSwitchHandlersList Handlers;
+};
+
+template <bool IsInputVariant, bool TrackRss>
+class TSwitchWrapper : public TCustomValueCodegeneratorNode<TSwitchWrapper<IsInputVariant, TrackRss>> {
+ typedef TCustomValueCodegeneratorNode<TSwitchWrapper<IsInputVariant, TrackRss>> TBaseComputation;
+private:
class TChildStream : public TComputationValue<TChildStream> {
public:
using TBase = TComputationValue<TChildStream>;
- TChildStream(TMemoryUsageInfo* memInfo, const TSwitchHandler& handler,
- TComputationContext& ctx, const TPagedUnboxedValueList* buffer)
+ TChildStream(TMemoryUsageInfo* memInfo, const TSwitchHandler& handler,
+ TComputationContext& ctx, const TPagedUnboxedValueList* buffer)
: TBase(memInfo)
- , Handler(handler)
+ , Handler(handler)
, Ctx(ctx)
, Buffer(buffer)
- {}
+ {}
- void Reset(bool isFinished) {
- BufferIndex = InputIndex = 0U;
- IsFinished = isFinished;
+ void Reset(bool isFinished) {
+ BufferIndex = InputIndex = 0U;
+ IsFinished = isFinished;
}
- private:
+ private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
for (;;) {
- if (BufferIndex == Buffer->Size()) {
+ if (BufferIndex == Buffer->Size()) {
return IsFinished ? NUdf::EFetchStatus::Finish : NUdf::EFetchStatus::Yield;
}
- auto current = (*Buffer)[BufferIndex];
+ auto current = (*Buffer)[BufferIndex];
ui32 streamIndex = 0;
- if constexpr (IsInputVariant) {
+ if constexpr (IsInputVariant) {
streamIndex = current.GetVariantIndex();
- current = current.Release().GetVariantItem();
+ current = current.Release().GetVariantItem();
}
- for (; InputIndex < Handler.InputIndices.size(); ++InputIndex) {
- if (Handler.InputIndices[InputIndex] == streamIndex) {
- if (Handler.InputIndices.size() > 1) {
- current = Ctx.HolderFactory.CreateVariantHolder(current.Release(), InputIndex);
+ for (; InputIndex < Handler.InputIndices.size(); ++InputIndex) {
+ if (Handler.InputIndices[InputIndex] == streamIndex) {
+ if (Handler.InputIndices.size() > 1) {
+ current = Ctx.HolderFactory.CreateVariantHolder(current.Release(), InputIndex);
}
result = std::move(current);
@@ -540,420 +540,420 @@ private:
}
InputIndex = 0;
- ++BufferIndex;
+ ++BufferIndex;
}
}
- const TSwitchHandler Handler;
+ const TSwitchHandler Handler;
TComputationContext& Ctx;
const TPagedUnboxedValueList* const Buffer;
- ui32 BufferIndex = 0U;
- ui32 InputIndex = 0U;
- bool IsFinished = false;
+ ui32 BufferIndex = 0U;
+ ui32 InputIndex = 0U;
+ bool IsFinished = false;
};
- class TValueBase : public TState {
+ class TValueBase : public TState {
public:
- void Add(NUdf::TUnboxedValue&& item) {
- Buffer.Add(std::move(item));
- }
-
- void Reset() {
- if (const auto size = Buffer.Size()) {
- MKQL_SET_MAX_STAT(Ctx.Stats, Switch_MaxRowsCount, static_cast<i64>(size));
- MKQL_INC_STAT(Ctx.Stats, Switch_FlushesCount);
- }
-
- ChildReadIndex = 0U;
- for (const auto& stream : ChildrenInStreams) {
- stream->Reset(NUdf::EFetchStatus::Finish == InputStatus);
- }
- }
-
- bool Get(NUdf::TUnboxedValue& result) {
- if (ChildrenOutStreams[ChildReadIndex].Fetch(result) == NUdf::EFetchStatus::Ok) {
- return true;
- }
-
- if (++ChildReadIndex == Handlers.size()) {
- Buffer.Clear();
- }
-
- return false;
- }
-
- protected:
- TValueBase(TMemoryUsageInfo* memInfo, const TSwitchHandlersList& handlers, TComputationContext& ctx)
- : TState(memInfo, handlers.size())
- , Handlers(handlers)
- , Buffer(ctx.HolderFactory.GetPagePool())
+ void Add(NUdf::TUnboxedValue&& item) {
+ Buffer.Add(std::move(item));
+ }
+
+ void Reset() {
+ if (const auto size = Buffer.Size()) {
+ MKQL_SET_MAX_STAT(Ctx.Stats, Switch_MaxRowsCount, static_cast<i64>(size));
+ MKQL_INC_STAT(Ctx.Stats, Switch_FlushesCount);
+ }
+
+ ChildReadIndex = 0U;
+ for (const auto& stream : ChildrenInStreams) {
+ stream->Reset(NUdf::EFetchStatus::Finish == InputStatus);
+ }
+ }
+
+ bool Get(NUdf::TUnboxedValue& result) {
+ if (ChildrenOutStreams[ChildReadIndex].Fetch(result) == NUdf::EFetchStatus::Ok) {
+ return true;
+ }
+
+ if (++ChildReadIndex == Handlers.size()) {
+ Buffer.Clear();
+ }
+
+ return false;
+ }
+
+ protected:
+ TValueBase(TMemoryUsageInfo* memInfo, const TSwitchHandlersList& handlers, TComputationContext& ctx)
+ : TState(memInfo, handlers.size())
+ , Handlers(handlers)
+ , Buffer(ctx.HolderFactory.GetPagePool())
, Ctx(ctx)
{
- ChildrenInStreams.reserve(Handlers.size());
- ChildrenOutStreams.reserve(Handlers.size());
- for (const auto& handler : Handlers) {
- const auto stream = Ctx.HolderFactory.Create<TChildStream>(handler, Ctx, &Buffer);
- ChildrenInStreams.emplace_back(static_cast<TChildStream*>(stream.AsBoxed().Get()));
- handler.Item->SetValue(Ctx, stream);
- ChildrenOutStreams.emplace_back(handler.NewItem->GetValue(Ctx));
+ ChildrenInStreams.reserve(Handlers.size());
+ ChildrenOutStreams.reserve(Handlers.size());
+ for (const auto& handler : Handlers) {
+ const auto stream = Ctx.HolderFactory.Create<TChildStream>(handler, Ctx, &Buffer);
+ ChildrenInStreams.emplace_back(static_cast<TChildStream*>(stream.AsBoxed().Get()));
+ handler.Item->SetValue(Ctx, stream);
+ ChildrenOutStreams.emplace_back(handler.NewItem->GetValue(Ctx));
}
}
- const TSwitchHandlersList Handlers;
- TPagedUnboxedValueList Buffer;
- TComputationContext& Ctx;
- std::vector<NUdf::TRefCountedPtr<TChildStream>, TMKQLAllocator<NUdf::TRefCountedPtr<TChildStream>>> ChildrenInStreams;
- TUnboxedValueVector ChildrenOutStreams;
- };
-
- class TValue : public TValueBase {
- public:
- TValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
- const TSwitchHandlersList& handlers, ui64 memLimit, TComputationContext& ctx)
- : TValueBase(memInfo, handlers, ctx)
- , Stream(std::move(stream)), MemLimit(memLimit)
- {}
-
- private:
+ const TSwitchHandlersList Handlers;
+ TPagedUnboxedValueList Buffer;
+ TComputationContext& Ctx;
+ std::vector<NUdf::TRefCountedPtr<TChildStream>, TMKQLAllocator<NUdf::TRefCountedPtr<TChildStream>>> ChildrenInStreams;
+ TUnboxedValueVector ChildrenOutStreams;
+ };
+
+ class TValue : public TValueBase {
+ public:
+ TValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream,
+ const TSwitchHandlersList& handlers, ui64 memLimit, TComputationContext& ctx)
+ : TValueBase(memInfo, handlers, ctx)
+ , Stream(std::move(stream)), MemLimit(memLimit)
+ {}
+
+ private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
for (;;) {
- if (this->ChildReadIndex == this->Handlers.size()) {
- switch (this->InputStatus) {
- case NUdf::EFetchStatus::Ok: break;
- case NUdf::EFetchStatus::Yield:
- this->InputStatus = NUdf::EFetchStatus::Ok;
- return NUdf::EFetchStatus::Yield;
- case NUdf::EFetchStatus::Finish:
- return NUdf::EFetchStatus::Finish;
+ if (this->ChildReadIndex == this->Handlers.size()) {
+ switch (this->InputStatus) {
+ case NUdf::EFetchStatus::Ok: break;
+ case NUdf::EFetchStatus::Yield:
+ this->InputStatus = NUdf::EFetchStatus::Ok;
+ return NUdf::EFetchStatus::Yield;
+ case NUdf::EFetchStatus::Finish:
+ return NUdf::EFetchStatus::Finish;
}
- const auto initUsage = this->MemLimit ? this->Ctx.HolderFactory.GetMemoryUsed() : 0ULL;
+ const auto initUsage = this->MemLimit ? this->Ctx.HolderFactory.GetMemoryUsed() : 0ULL;
- do {
- NUdf::TUnboxedValue current;
- this->InputStatus = this->Stream.Fetch(current);
- if (NUdf::EFetchStatus::Ok != this->InputStatus) {
- break;
+ do {
+ NUdf::TUnboxedValue current;
+ this->InputStatus = this->Stream.Fetch(current);
+ if (NUdf::EFetchStatus::Ok != this->InputStatus) {
+ break;
}
- this->Add(std::move(current));
- } while (!this->Ctx.template CheckAdjustedMemLimit<TrackRss>(this->MemLimit, initUsage));
+ this->Add(std::move(current));
+ } while (!this->Ctx.template CheckAdjustedMemLimit<TrackRss>(this->MemLimit, initUsage));
- this->Reset();
+ this->Reset();
}
- if (!this->Get(result)) {
+ if (!this->Get(result)) {
continue;
}
- const auto& handler = this->Handlers[this->ChildReadIndex];
- if (const auto offset = handler.ResultVariantOffset) {
+ const auto& handler = this->Handlers[this->ChildReadIndex];
+ if (const auto offset = handler.ResultVariantOffset) {
ui32 localIndex = 0;
if (handler.IsOutputVariant) {
- localIndex = result.GetVariantIndex();
- result = result.Release().GetVariantItem();
+ localIndex = result.GetVariantIndex();
+ result = result.Release().GetVariantItem();
}
- result = this->Ctx.HolderFactory.CreateVariantHolder(result.Release(), *offset + localIndex);
+ result = this->Ctx.HolderFactory.CreateVariantHolder(result.Release(), *offset + localIndex);
}
return NUdf::EFetchStatus::Ok;
}
}
- const NUdf::TUnboxedValue Stream;
- const ui64 MemLimit;
+ const NUdf::TUnboxedValue Stream;
+ const ui64 MemLimit;
};
-
-#ifndef MKQL_DISABLE_CODEGEN
- class TCodegenValue : public TStreamCodegenSelfStateValue<TValueBase> {
- public:
- using TFetchPtr = typename TStreamCodegenSelfStateValue<TValueBase>::TFetchPtr;
- TCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, const TSwitchHandlersList& handlers)
- : TStreamCodegenSelfStateValue<TValueBase>(memInfo, fetch, ctx, std::move(stream), handlers, *ctx)
- {}
- };
-#endif
-public:
- TSwitchWrapper(TComputationMutables& mutables, IComputationNode* stream, ui64 memLimit, TSwitchHandlersList&& handlers)
- : TBaseComputation(mutables)
+
+#ifndef MKQL_DISABLE_CODEGEN
+ class TCodegenValue : public TStreamCodegenSelfStateValue<TValueBase> {
+ public:
+ using TFetchPtr = typename TStreamCodegenSelfStateValue<TValueBase>::TFetchPtr;
+ TCodegenValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, const TSwitchHandlersList& handlers)
+ : TStreamCodegenSelfStateValue<TValueBase>(memInfo, fetch, ctx, std::move(stream), handlers, *ctx)
+ {}
+ };
+#endif
+public:
+ TSwitchWrapper(TComputationMutables& mutables, IComputationNode* stream, ui64 memLimit, TSwitchHandlersList&& handlers)
+ : TBaseComputation(mutables)
, Stream(stream)
, MemLimit(memLimit)
, Handlers(std::move(handlers))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && Switch)
- return ctx.HolderFactory.Create<TCodegenValue>(Switch, &ctx, Stream->GetValue(ctx), Handlers);
-#endif
- return ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx), Handlers, MemLimit, ctx);
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && Switch)
+ return ctx.HolderFactory.Create<TCodegenValue>(Switch, &ctx, Stream->GetValue(ctx), Handlers);
+#endif
+ return ctx.HolderFactory.Create<TValue>(Stream->GetValue(ctx), Handlers, MemLimit, ctx);
}
-
-private:
- void RegisterDependencies() const final {
+
+private:
+ void RegisterDependencies() const final {
this->DependsOn(Stream);
- for (const auto& x : Handlers) {
+ for (const auto& x : Handlers) {
this->Own(x.Item);
this->DependsOn(x.NewItem);
}
}
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- SwitchFunc = GenerateSwitch(codegen);
- codegen->ExportSymbol(SwitchFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (SwitchFunc)
- Switch = reinterpret_cast<TSwitchPtr>(codegen->GetPointerToFunction(SwitchFunc));
- }
-
- Function* GenerateSwitch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto& name = this->MakeName("Fetch");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(ptrValueType) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
- const auto indexType = Type::getInt32Ty(context);
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- indexType, // index
- statusType, // status
- structPtrType // buffer
- });
- const auto statePtrType = PointerType::getUnqual(stateType);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType}, false);
-
- TCodegenContext ctx(codegen);
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ SwitchFunc = GenerateSwitch(codegen);
+ codegen->ExportSymbol(SwitchFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (SwitchFunc)
+ Switch = reinterpret_cast<TSwitchPtr>(codegen->GetPointerToFunction(SwitchFunc));
+ }
+
+ Function* GenerateSwitch(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto& name = this->MakeName("Fetch");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(ptrValueType) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ indexType, // index
+ statusType, // status
+ structPtrType // buffer
+ });
+ const auto statePtrType = PointerType::getUnqual(stateType);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, statePtrType, ptrValueType}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto stateArg = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- auto block = main;
-
- const auto indexPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "index_ptr", block);
-
- const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
- new StoreInst(ConstantInt::get(valueType, 0), itemPtr, block);
-
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto index = new LoadInst(indexPtr, "index", block);
- const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ConstantInt::get(index->getType(), Handlers.size()), "empty", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(next, full, empty, block);
-
- {
- block = next;
-
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "last", block);
-
- const auto last = new LoadInst(statusPtr, "last", block);
-
- const auto choise = SwitchInst::Create(last, pull, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
- choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
- BranchInst::Create(exit, block);
-
- block = exit;
- ReturnInst::Create(context, last, block);
-
- block = pull;
-
- const auto used = GetMemoryUsed(MemLimit, ctx, block);
-
- const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto fetch = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, itemPtr);
- new StoreInst(fetch, statusPtr, block);
-
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, fetch, ConstantInt::get(fetch->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
-
- BranchInst::Create(good, done, ok, block);
-
- block = good;
-
- const auto addFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Add));
- const auto addType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), itemPtr->getType()}, false);
- const auto addPtr = CastInst::Create(Instruction::IntToPtr, addFunc, PointerType::getUnqual(addType), "add", block);
- CallInst::Create(addPtr, {stateArg, itemPtr}, "", block);
-
- const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
- BranchInst::Create(done, loop, check, block);
-
- block = done;
-
- const auto resetFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Reset));
- const auto resetType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType()}, false);
- const auto resetPtr = CastInst::Create(Instruction::IntToPtr, resetFunc, PointerType::getUnqual(resetType), "reset", block);
- CallInst::Create(resetPtr, {stateArg}, "", block);
-
- BranchInst::Create(more, block);
- }
-
- {
- block = full;
-
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), exit);
- new UnreachableInst(context, stub);
-
- const auto nextFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Get));
- const auto nextType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), valuePtr->getType()}, false);
- const auto nextPtr = CastInst::Create(Instruction::IntToPtr, nextFunc, PointerType::getUnqual(nextType), "next", block);
- const auto has = CallInst::Create(nextPtr, {stateArg, valuePtr}, "has", block);
-
- BranchInst::Create(good, more, has, block);
-
- block = good;
-
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateVariantHolder));
-
- const auto choise = SwitchInst::Create(index, stub, Handlers.size(), block);
-
- for (ui32 i = 0U; i < Handlers.size(); ++i) {
- const auto idx = ConstantInt::get(indexType, i);
- if (const auto offset = Handlers[i].ResultVariantOffset) {
- const auto var = BasicBlock::Create(context, (TString("var_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(idx, var);
- block = var;
-
- const auto output = new LoadInst(valuePtr, "output", block);
- ValueRelease(Handlers[i].Kind, output, ctx, block);
-
- const auto unpack = Handlers[i].IsOutputVariant ? GetVariantParts(output, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), output);
- const auto reindex = BinaryOperator::CreateAdd(unpack.first, ConstantInt::get(indexType, *offset), "reindex", block);
- const auto variant = MakeVariant(unpack.second, reindex, ctx, block);
- new StoreInst(variant, valuePtr, block);
-
- ValueAddRef(EValueRepresentation::Any, variant, ctx, block);
- ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
- } else {
- choise->addCase(idx, exit);
- }
- }
- }
-
- return ctx.Func;
- }
-
- using TSwitchPtr = typename TCodegenValue::TFetchPtr;
-
- Function* SwitchFunc = nullptr;
-
- TSwitchPtr Switch = nullptr;
-#endif
-
- IComputationNode *const Stream;
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto stateArg = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ auto block = main;
+
+ const auto indexPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "index_ptr", block);
+
+ const auto itemPtr = new AllocaInst(valueType, 0U, "item_ptr", block);
+ new StoreInst(ConstantInt::get(valueType, 0), itemPtr, block);
+
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto index = new LoadInst(indexPtr, "index", block);
+ const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, index, ConstantInt::get(index->getType(), Handlers.size()), "empty", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(next, full, empty, block);
+
+ {
+ block = next;
+
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "last", block);
+
+ const auto last = new LoadInst(statusPtr, "last", block);
+
+ const auto choise = SwitchInst::Create(last, pull, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Yield)), rest);
+ choise->addCase(ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)), exit);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), statusPtr, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ ReturnInst::Create(context, last, block);
+
+ block = pull;
+
+ const auto used = GetMemoryUsed(MemLimit, ctx, block);
+
+ const auto stream = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto fetch = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, stream, codegen, block, itemPtr);
+ new StoreInst(fetch, statusPtr, block);
+
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, fetch, ConstantInt::get(fetch->getType(), static_cast<ui32>(NUdf::EFetchStatus::Ok)), "ok", block);
+
+ BranchInst::Create(good, done, ok, block);
+
+ block = good;
+
+ const auto addFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Add));
+ const auto addType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), itemPtr->getType()}, false);
+ const auto addPtr = CastInst::Create(Instruction::IntToPtr, addFunc, PointerType::getUnqual(addType), "add", block);
+ CallInst::Create(addPtr, {stateArg, itemPtr}, "", block);
+
+ const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
+ BranchInst::Create(done, loop, check, block);
+
+ block = done;
+
+ const auto resetFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Reset));
+ const auto resetType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType()}, false);
+ const auto resetPtr = CastInst::Create(Instruction::IntToPtr, resetFunc, PointerType::getUnqual(resetType), "reset", block);
+ CallInst::Create(resetPtr, {stateArg}, "", block);
+
+ BranchInst::Create(more, block);
+ }
+
+ {
+ block = full;
+
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), exit);
+ new UnreachableInst(context, stub);
+
+ const auto nextFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TValueBase::Get));
+ const auto nextType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType(), valuePtr->getType()}, false);
+ const auto nextPtr = CastInst::Create(Instruction::IntToPtr, nextFunc, PointerType::getUnqual(nextType), "next", block);
+ const auto has = CallInst::Create(nextPtr, {stateArg, valuePtr}, "has", block);
+
+ BranchInst::Create(good, more, has, block);
+
+ block = good;
+
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateVariantHolder));
+
+ const auto choise = SwitchInst::Create(index, stub, Handlers.size(), block);
+
+ for (ui32 i = 0U; i < Handlers.size(); ++i) {
+ const auto idx = ConstantInt::get(indexType, i);
+ if (const auto offset = Handlers[i].ResultVariantOffset) {
+ const auto var = BasicBlock::Create(context, (TString("var_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(idx, var);
+ block = var;
+
+ const auto output = new LoadInst(valuePtr, "output", block);
+ ValueRelease(Handlers[i].Kind, output, ctx, block);
+
+ const auto unpack = Handlers[i].IsOutputVariant ? GetVariantParts(output, ctx, block) : std::make_pair(ConstantInt::get(indexType, 0), output);
+ const auto reindex = BinaryOperator::CreateAdd(unpack.first, ConstantInt::get(indexType, *offset), "reindex", block);
+ const auto variant = MakeVariant(unpack.second, reindex, ctx, block);
+ new StoreInst(variant, valuePtr, block);
+
+ ValueAddRef(EValueRepresentation::Any, variant, ctx, block);
+ ReturnInst::Create(context, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), block);
+ } else {
+ choise->addCase(idx, exit);
+ }
+ }
+ }
+
+ return ctx.Func;
+ }
+
+ using TSwitchPtr = typename TCodegenValue::TFetchPtr;
+
+ Function* SwitchFunc = nullptr;
+
+ TSwitchPtr Switch = nullptr;
+#endif
+
+ IComputationNode *const Stream;
const ui64 MemLimit;
- const TSwitchHandlersList Handlers;
+ const TSwitchHandlersList Handlers;
};
-}
-
+}
+
IComputationNode* WrapSwitch(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() >= 6, "Expected at least 6 args");
MKQL_ENSURE((callable.GetInputsCount() - 2) % 4 == 0, "Corrupted arguments for Switch");
- TSwitchHandlersList handlers;
- handlers.reserve(callable.GetInputsCount() >> 2U);
- const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
- const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui64>();
- const auto type = callable.GetType()->GetReturnType();
+ TSwitchHandlersList handlers;
+ handlers.reserve(callable.GetInputsCount() >> 2U);
+ const auto stream = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui64>();
+ const auto type = callable.GetType()->GetReturnType();
for (ui32 i = 2; i < callable.GetInputsCount(); i += 4) {
TSwitchHandler handler;
- const auto tuple = AS_VALUE(TTupleLiteral, callable.GetInput(i));
+ const auto tuple = AS_VALUE(TTupleLiteral, callable.GetInput(i));
for (ui32 tupleIndex = 0; tupleIndex < tuple->GetValuesCount(); ++tupleIndex) {
- handler.InputIndices.emplace_back(AS_VALUE(TDataLiteral, tuple->GetValue(tupleIndex))->AsValue().Get<ui32>());
+ handler.InputIndices.emplace_back(AS_VALUE(TDataLiteral, tuple->GetValue(tupleIndex))->AsValue().Get<ui32>());
}
- const auto itemType = type->IsFlow() ?
- AS_TYPE(TFlowType, callable.GetInput(i + 2))->GetItemType():
- AS_TYPE(TStreamType, callable.GetInput(i + 2))->GetItemType();
- handler.IsOutputVariant = itemType->IsVariant();
- handler.Kind = GetValueRepresentation(itemType);
+ const auto itemType = type->IsFlow() ?
+ AS_TYPE(TFlowType, callable.GetInput(i + 2))->GetItemType():
+ AS_TYPE(TStreamType, callable.GetInput(i + 2))->GetItemType();
+ handler.IsOutputVariant = itemType->IsVariant();
+ handler.Kind = GetValueRepresentation(itemType);
handler.NewItem = LocateNode(ctx.NodeLocator, callable, i + 2);
- handler.Item = LocateExternalNode(ctx.NodeLocator, callable, i + 1);
- const auto offsetNode = callable.GetInput(i + 3);
+ handler.Item = LocateExternalNode(ctx.NodeLocator, callable, i + 1);
+ const auto offsetNode = callable.GetInput(i + 3);
if (!offsetNode.GetStaticType()->IsVoid()) {
- handler.ResultVariantOffset = AS_VALUE(TDataLiteral, offsetNode)->AsValue().Get<ui32>();
+ handler.ResultVariantOffset = AS_VALUE(TDataLiteral, offsetNode)->AsValue().Get<ui32>();
}
- handlers.emplace_back(handler);
+ handlers.emplace_back(handler);
}
const bool trackRss = EGraphPerProcess::Single == ctx.GraphPerProcess;
- if (type->IsFlow()) {
- const bool isInputVariant = AS_TYPE(TFlowType, callable.GetInput(0))->GetItemType()->IsVariant();
- const auto kind = GetValueRepresentation(type);
- if (isInputVariant && trackRss) {
- return new TSwitchFlowWrapper<true, true>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
- } else if (isInputVariant) {
- return new TSwitchFlowWrapper<true, false>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
- } else if (trackRss) {
- return new TSwitchFlowWrapper<false, true>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
- } else {
- return new TSwitchFlowWrapper<false, false>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
- }
- } else if (type->IsStream()) {
- const bool isInputVariant = AS_TYPE(TStreamType, callable.GetInput(0))->GetItemType()->IsVariant();
- if (isInputVariant && trackRss) {
- return new TSwitchWrapper<true, true>(ctx.Mutables, stream, memLimit, std::move(handlers));
- } else if (isInputVariant) {
- return new TSwitchWrapper<true, false>(ctx.Mutables, stream, memLimit, std::move(handlers));
- } else if (trackRss) {
- return new TSwitchWrapper<false, true>(ctx.Mutables, stream, memLimit, std::move(handlers));
- } else {
- return new TSwitchWrapper<false, false>(ctx.Mutables, stream, memLimit, std::move(handlers));
- }
+ if (type->IsFlow()) {
+ const bool isInputVariant = AS_TYPE(TFlowType, callable.GetInput(0))->GetItemType()->IsVariant();
+ const auto kind = GetValueRepresentation(type);
+ if (isInputVariant && trackRss) {
+ return new TSwitchFlowWrapper<true, true>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
+ } else if (isInputVariant) {
+ return new TSwitchFlowWrapper<true, false>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
+ } else if (trackRss) {
+ return new TSwitchFlowWrapper<false, true>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
+ } else {
+ return new TSwitchFlowWrapper<false, false>(ctx.Mutables, kind, stream, memLimit, std::move(handlers));
+ }
+ } else if (type->IsStream()) {
+ const bool isInputVariant = AS_TYPE(TStreamType, callable.GetInput(0))->GetItemType()->IsVariant();
+ if (isInputVariant && trackRss) {
+ return new TSwitchWrapper<true, true>(ctx.Mutables, stream, memLimit, std::move(handlers));
+ } else if (isInputVariant) {
+ return new TSwitchWrapper<true, false>(ctx.Mutables, stream, memLimit, std::move(handlers));
+ } else if (trackRss) {
+ return new TSwitchWrapper<false, true>(ctx.Mutables, stream, memLimit, std::move(handlers));
+ } else {
+ return new TSwitchWrapper<false, false>(ctx.Mutables, stream, memLimit, std::move(handlers));
+ }
}
-
- THROW yexception() << "Expected flow or stream.";
+
+ THROW yexception() << "Expected flow or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_take.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_take.cpp
index 75e28716fa..1b6e9701b2 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_take.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_take.cpp
@@ -6,185 +6,185 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TTakeFlowWrapper : public TStatefulFlowCodegeneratorNode<TTakeFlowWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TTakeFlowWrapper>;
-public:
- TTakeFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* count)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Count(count)
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- state = Count->GetValue(ctx);
- }
-
- if (auto count = state.Get<ui64>()) {
- const auto item = Flow->GetValue(ctx);
- if (!(item.IsSpecial())) {
- state = NUdf::TUnboxedValuePod(--count);
- }
- return item;
- }
-
- return NUdf::TUnboxedValuePod::MakeFinish();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = PHINode::Create(load->getType(), 2U, "state", main);
- state->addIncoming(load, block);
-
- BranchInst::Create(init, main, IsInvalid(load, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Count, ctx, block);
- const auto save = new LoadInst(statePtr, "save", block);
- state->addIncoming(save, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", done);
- result->addIncoming(GetFinish(context), block);
-
- const auto trunc = GetterFor<ui64>(state, context, block);
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
-
- BranchInst::Create(work, done, plus, block);
-
- block = work;
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(done, good, IsSpecial(item, block), block);
-
- block = good;
- result->addIncoming(item, block);
-
- const auto decr = BinaryOperator::CreateSub(trunc, ConstantInt::get(trunc->getType(), 1ULL), "decr", block);
- new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
-
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow))
- DependsOn(flow, Count);
- }
-
- IComputationNode* const Flow;
- IComputationNode* const Count;
-};
-
-class TWideTakeWrapper : public TStatefulWideFlowCodegeneratorNode<TWideTakeWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideTakeWrapper>;
-public:
- TWideTakeWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* count)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Count(count)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = Count->GetValue(ctx);
- }
-
- if (auto count = state.Get<ui64>()) {
- if (const auto result = Flow->FetchValues(ctx, output); EFetchResult::One == result) {
- state = NUdf::TUnboxedValuePod(--count);
- return EFetchResult::One;
- } else {
- return result;
- }
- }
-
- return EFetchResult::Finish;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- const auto load = new LoadInst(statePtr, "load", block);
- const auto state = PHINode::Create(load->getType(), 2U, "state", main);
- state->addIncoming(load, block);
-
- BranchInst::Create(init, main, IsInvalid(load, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Count, ctx, block);
- const auto save = new LoadInst(statePtr, "save", block);
- state->addIncoming(save, block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 3U, "result", done);
- result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
-
- const auto trunc = GetterFor<ui64>(state, context, block);
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
-
- BranchInst::Create(work, done, plus, block);
-
- block = work;
- const auto getres = GetNodeValues(Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
- result->addIncoming(getres.first, block);
- BranchInst::Create(done, good, special, block);
-
- block = good;
-
- const auto decr = BinaryOperator::CreateSub(trunc, ConstantInt::get(trunc->getType(), 1ULL), "decr", block);
- new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
- result->addIncoming(getres.first, block);
- BranchInst::Create(done, block);
-
- block = done;
- return {result, std::move(getres.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow))
- DependsOn(flow, Count);
- }
-
- IComputationWideFlowNode* const Flow;
- IComputationNode* const Count;
-};
-
-class TTakeStreamWrapper : public TMutableComputationNode<TTakeStreamWrapper> {
- typedef TMutableComputationNode<TTakeStreamWrapper> TBaseComputation;
+namespace {
+
+class TTakeFlowWrapper : public TStatefulFlowCodegeneratorNode<TTakeFlowWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TTakeFlowWrapper>;
+public:
+ TTakeFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationNode* count)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Count(count)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ state = Count->GetValue(ctx);
+ }
+
+ if (auto count = state.Get<ui64>()) {
+ const auto item = Flow->GetValue(ctx);
+ if (!(item.IsSpecial())) {
+ state = NUdf::TUnboxedValuePod(--count);
+ }
+ return item;
+ }
+
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = PHINode::Create(load->getType(), 2U, "state", main);
+ state->addIncoming(load, block);
+
+ BranchInst::Create(init, main, IsInvalid(load, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Count, ctx, block);
+ const auto save = new LoadInst(statePtr, "save", block);
+ state->addIncoming(save, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", done);
+ result->addIncoming(GetFinish(context), block);
+
+ const auto trunc = GetterFor<ui64>(state, context, block);
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
+
+ BranchInst::Create(work, done, plus, block);
+
+ block = work;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(done, good, IsSpecial(item, block), block);
+
+ block = good;
+ result->addIncoming(item, block);
+
+ const auto decr = BinaryOperator::CreateSub(trunc, ConstantInt::get(trunc->getType(), 1ULL), "decr", block);
+ new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow))
+ DependsOn(flow, Count);
+ }
+
+ IComputationNode* const Flow;
+ IComputationNode* const Count;
+};
+
+class TWideTakeWrapper : public TStatefulWideFlowCodegeneratorNode<TWideTakeWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideTakeWrapper>;
+public:
+ TWideTakeWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* count)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow), Count(count)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = Count->GetValue(ctx);
+ }
+
+ if (auto count = state.Get<ui64>()) {
+ if (const auto result = Flow->FetchValues(ctx, output); EFetchResult::One == result) {
+ state = NUdf::TUnboxedValuePod(--count);
+ return EFetchResult::One;
+ } else {
+ return result;
+ }
+ }
+
+ return EFetchResult::Finish;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ const auto load = new LoadInst(statePtr, "load", block);
+ const auto state = PHINode::Create(load->getType(), 2U, "state", main);
+ state->addIncoming(load, block);
+
+ BranchInst::Create(init, main, IsInvalid(load, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Count, ctx, block);
+ const auto save = new LoadInst(statePtr, "save", block);
+ state->addIncoming(save, block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 3U, "result", done);
+ result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
+
+ const auto trunc = GetterFor<ui64>(state, context, block);
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, trunc, ConstantInt::get(trunc->getType(), 0ULL), "plus", block);
+
+ BranchInst::Create(work, done, plus, block);
+
+ block = work;
+ const auto getres = GetNodeValues(Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
+ result->addIncoming(getres.first, block);
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+
+ const auto decr = BinaryOperator::CreateSub(trunc, ConstantInt::get(trunc->getType(), 1ULL), "decr", block);
+ new StoreInst(SetterFor<ui64>(decr, context, block), statePtr, block);
+ result->addIncoming(getres.first, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return {result, std::move(getres.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow))
+ DependsOn(flow, Count);
+ }
+
+ IComputationWideFlowNode* const Flow;
+ IComputationNode* const Count;
+};
+
+class TTakeStreamWrapper : public TMutableComputationNode<TTakeStreamWrapper> {
+ typedef TMutableComputationNode<TTakeStreamWrapper> TBaseComputation;
public:
class TStreamValue : public TComputationValue<TStreamValue> {
public:
@@ -197,13 +197,13 @@ public:
, Index_(0)
{}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
if (Index_ >= Count_) {
return NUdf::EFetchStatus::Finish;
}
- const auto status = Input_.Fetch(result);
+ const auto status = Input_.Fetch(result);
if (status != NUdf::EFetchStatus::Ok) {
return status;
}
@@ -212,105 +212,105 @@ public:
return status;
}
- const NUdf::TUnboxedValue Input_;
+ const NUdf::TUnboxedValue Input_;
const ui64 Count_;
ui64 Index_;
};
- TTakeStreamWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
- , List(list)
- , Count(count)
- {
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Count->GetValue(ctx).Get<ui64>());
- }
-
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Count);
- }
-
- IComputationNode* const List;
- IComputationNode* const Count;
-};
-
-class TTakeWrapper : public TMutableCodegeneratorNode<TTakeWrapper> {
- typedef TMutableCodegeneratorNode<TTakeWrapper> TBaseComputation;
-public:
+ TTakeStreamWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ , List(list)
+ , Count(count)
+ {
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Count->GetValue(ctx).Get<ui64>());
+ }
+
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Count);
+ }
+
+ IComputationNode* const List;
+ IComputationNode* const Count;
+};
+
+class TTakeWrapper : public TMutableCodegeneratorNode<TTakeWrapper> {
+ typedef TMutableCodegeneratorNode<TTakeWrapper> TBaseComputation;
+public:
TTakeWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationNode* count)
- : TBaseComputation(mutables, list->GetRepresentation())
+ : TBaseComputation(mutables, list->GetRepresentation())
, List(list)
, Count(count)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.TakeList(ctx.Builder, List->GetValue(ctx).Release(), Count->GetValue(ctx).Get<ui64>());
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto factory = ctx.GetFactory();
- const auto builder = ctx.GetBuilder();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::TakeList));
-
- const auto list = GetNodeValue(List, ctx, block);
- const auto cnt = GetNodeValue(Count, ctx, block);
- const auto count = GetterFor<ui64>(cnt, context, block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto result = CallInst::Create(funcPtr, {factory, builder, list, count}, "result", block);
- return result;
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- new StoreInst(list, retPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr, count}, "", block);
- const auto result = new LoadInst(retPtr, "result", block);
- return result;
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.TakeList(ctx.Builder, List->GetValue(ctx).Release(), Count->GetValue(ctx).Get<ui64>());
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto factory = ctx.GetFactory();
+ const auto builder = ctx.GetBuilder();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::TakeList));
+
+ const auto list = GetNodeValue(List, ctx, block);
+ const auto cnt = GetNodeValue(Count, ctx, block);
+ const auto count = GetterFor<ui64>(cnt, context, block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto result = CallInst::Create(funcPtr, {factory, builder, list, count}, "result", block);
+ return result;
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ new StoreInst(list, retPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr, count}, "", block);
+ const auto result = new LoadInst(retPtr, "result", block);
+ return result;
}
}
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
- DependsOn(Count);
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
+ DependsOn(Count);
}
IComputationNode* const List;
IComputationNode* const Count;
};
-}
-
+}
+
IComputationNode* WrapTake(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args");
- const auto type = callable.GetInput(0).GetStaticType();
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto count = LocateNode(ctx.NodeLocator, callable, 1);
- if (type->IsFlow()) {
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
- return new TWideTakeWrapper(ctx.Mutables, wide, count);
- else
- return new TTakeFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, count);
- } else if (type->IsStream()) {
- return new TTakeStreamWrapper(ctx.Mutables, flow, count);
- } else if (type->IsList()) {
- return new TTakeWrapper(ctx.Mutables, flow, count);
+ const auto type = callable.GetInput(0).GetStaticType();
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto count = LocateNode(ctx.NodeLocator, callable, 1);
+ if (type->IsFlow()) {
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow))
+ return new TWideTakeWrapper(ctx.Mutables, wide, count);
+ else
+ return new TTakeFlowWrapper(ctx.Mutables, GetValueRepresentation(type), flow, count);
+ } else if (type->IsStream()) {
+ return new TTakeStreamWrapper(ctx.Mutables, flow, count);
+ } else if (type->IsList()) {
+ return new TTakeWrapper(ctx.Mutables, flow, count);
}
-
- THROW yexception() << "Expected flow, list or stream.";
+
+ THROW yexception() << "Expected flow, list or stream.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_timezone.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_timezone.cpp
index 218e96b07d..3d2129e53b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_timezone.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_timezone.cpp
@@ -9,8 +9,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TTimezoneIdWrapper : public TMutableComputationNode<TTimezoneIdWrapper> {
typedef TMutableComputationNode<TTimezoneIdWrapper> TBaseComputation;
public:
@@ -71,142 +71,142 @@ private:
IComputationNode* const Value;
};
-template <bool IsOptional1, bool IsOptional2>
-class TAddTimezoneWrapper : public TMutableCodegeneratorNode<TAddTimezoneWrapper<IsOptional1, IsOptional2>> {
- typedef TMutableCodegeneratorNode<TAddTimezoneWrapper<IsOptional1, IsOptional2>> TBaseComputation;
+template <bool IsOptional1, bool IsOptional2>
+class TAddTimezoneWrapper : public TMutableCodegeneratorNode<TAddTimezoneWrapper<IsOptional1, IsOptional2>> {
+ typedef TMutableCodegeneratorNode<TAddTimezoneWrapper<IsOptional1, IsOptional2>> TBaseComputation;
public:
TAddTimezoneWrapper(TComputationMutables& mutables, IComputationNode* value, IComputationNode* id)
- : TBaseComputation(mutables, EValueRepresentation::Embedded)
- , Datetime(value)
+ : TBaseComputation(mutables, EValueRepresentation::Embedded)
+ , Datetime(value)
, Id(id)
- , TimezonesCount(InitTimezones())
- , BlackList(GetTzBlackList())
- {}
+ , TimezonesCount(InitTimezones())
+ , BlackList(GetTzBlackList())
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto value = Datetime->GetValue(ctx);
- if (IsOptional1 && !value) {
+ auto value = Datetime->GetValue(ctx);
+ if (IsOptional1 && !value) {
return {};
}
- const auto zone = Id->GetValue(ctx);
- if (IsOptional2 && !zone) {
+ const auto zone = Id->GetValue(ctx);
+ if (IsOptional2 && !zone) {
return {};
}
- const auto id = zone.Get<ui16>();
- if (!IsValidTimezoneId(id)) {
- return {};
- }
-
- value.SetTimezoneId(id);
+ const auto id = zone.Get<ui16>();
+ if (!IsValidTimezoneId(id)) {
+ return {};
+ }
+
+ value.SetTimezoneId(id);
return value.Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto setz = BasicBlock::Create(context, "setz", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto value = GetNodeValue(Datetime, ctx, block);
- const auto result = PHINode::Create(value->getType(), 2U + (IsOptional1 ? 1U : 0U), "result", done);
-
- if (IsOptional1) {
- result->addIncoming(value, block);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- BranchInst::Create(done, good, IsEmpty(value, block), block);
-
- block = good;
- }
-
- const auto tz = GetNodeValue(Id, ctx, block);
- const auto id = GetterFor<ui16>(tz, context, block);
-
- const auto big = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, id, ConstantInt::get(id->getType(), TimezonesCount), "big", block);
- auto test = IsOptional2 ? BinaryOperator::CreateOr(IsEmpty(tz, block), big, "test", block) : static_cast<Value*>(big);
-
- for (const auto black : BlackList) {
- const auto& str = ToString(black);
- const auto bad = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, id, ConstantInt::get(id->getType(), black), ("bad_" + str).c_str(), block);
- test = BinaryOperator::CreateOr(test, bad, ("test_" + str).c_str(), block);
- }
-
- result->addIncoming(ConstantInt::get(value->getType(), 0), block);
- BranchInst::Create(done, setz, test, block);
-
- {
- block = setz;
-
- const uint64_t init[] = {~0ULL, ~0xFFFFULL};
- const auto mask = ConstantInt::get(value->getType(), APInt(128, 2, init));
- const auto clean = BinaryOperator::CreateAnd(value, mask, "clean", block);
- const auto tzid = BinaryOperator::CreateShl(tz, ConstantInt::get(tz->getType(), 64), "tzid", block);
- const auto full = BinaryOperator::CreateOr(clean, tzid, "full", block);
-
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
- }
-
-
- block = done;
- return result;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto setz = BasicBlock::Create(context, "setz", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto value = GetNodeValue(Datetime, ctx, block);
+ const auto result = PHINode::Create(value->getType(), 2U + (IsOptional1 ? 1U : 0U), "result", done);
+
+ if (IsOptional1) {
+ result->addIncoming(value, block);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ BranchInst::Create(done, good, IsEmpty(value, block), block);
+
+ block = good;
+ }
+
+ const auto tz = GetNodeValue(Id, ctx, block);
+ const auto id = GetterFor<ui16>(tz, context, block);
+
+ const auto big = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, id, ConstantInt::get(id->getType(), TimezonesCount), "big", block);
+ auto test = IsOptional2 ? BinaryOperator::CreateOr(IsEmpty(tz, block), big, "test", block) : static_cast<Value*>(big);
+
+ for (const auto black : BlackList) {
+ const auto& str = ToString(black);
+ const auto bad = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, id, ConstantInt::get(id->getType(), black), ("bad_" + str).c_str(), block);
+ test = BinaryOperator::CreateOr(test, bad, ("test_" + str).c_str(), block);
+ }
+
+ result->addIncoming(ConstantInt::get(value->getType(), 0), block);
+ BranchInst::Create(done, setz, test, block);
+
+ {
+ block = setz;
+
+ const uint64_t init[] = {~0ULL, ~0xFFFFULL};
+ const auto mask = ConstantInt::get(value->getType(), APInt(128, 2, init));
+ const auto clean = BinaryOperator::CreateAnd(value, mask, "clean", block);
+ const auto tzid = BinaryOperator::CreateShl(tz, ConstantInt::get(tz->getType(), 64), "tzid", block);
+ const auto full = BinaryOperator::CreateOr(clean, tzid, "full", block);
+
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+ }
+
+
+ block = done;
+ return result;
+ }
+#endif
private:
void RegisterDependencies() const final {
- this->DependsOn(Datetime);
- this->DependsOn(Id);
+ this->DependsOn(Datetime);
+ this->DependsOn(Id);
}
- IComputationNode* const Datetime;
+ IComputationNode* const Datetime;
IComputationNode* const Id;
- const ui16 TimezonesCount;
- const std::vector<ui16> BlackList;
+ const ui16 TimezonesCount;
+ const std::vector<ui16> BlackList;
};
-}
-
+}
+
IComputationNode* WrapTimezoneId(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected string");
- const auto value = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto value = LocateNode(ctx.NodeLocator, callable, 0);
return new TTimezoneIdWrapper(ctx.Mutables, value);
}
IComputationNode* WrapTimezoneName(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected Uint16");
- const auto value = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected Uint16");
+ const auto value = LocateNode(ctx.NodeLocator, callable, 0);
return new TTimezoneNameWrapper(ctx.Mutables, value);
}
IComputationNode* WrapAddTimezone(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 arg");
bool isOptional1;
- const auto dataType1 = UnpackOptionalData(callable.GetInput(0), isOptional1);
- MKQL_ENSURE(NUdf::GetDataTypeInfo(*dataType1->GetDataSlot()).Features & NUdf::DateType, "Expected date type");
+ const auto dataType1 = UnpackOptionalData(callable.GetInput(0), isOptional1);
+ MKQL_ENSURE(NUdf::GetDataTypeInfo(*dataType1->GetDataSlot()).Features & NUdf::DateType, "Expected date type");
bool isOptional2;
- const auto dataType2 = UnpackOptionalData(callable.GetInput(1), isOptional2);
+ const auto dataType2 = UnpackOptionalData(callable.GetInput(1), isOptional2);
MKQL_ENSURE(dataType2->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected ui16");
- const auto value = LocateNode(ctx.NodeLocator, callable, 0);
- const auto id = LocateNode(ctx.NodeLocator, callable, 1);
- if (isOptional1 && isOptional2) {
- return new TAddTimezoneWrapper<true, true>(ctx.Mutables, value, id);
- } else if (isOptional1) {
- return new TAddTimezoneWrapper<true, false>(ctx.Mutables, value, id);
- } else if (isOptional2) {
- return new TAddTimezoneWrapper<false, true>(ctx.Mutables, value, id);
- } else {
- return new TAddTimezoneWrapper<false, false>(ctx.Mutables, value, id);
- }
+ const auto value = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto id = LocateNode(ctx.NodeLocator, callable, 1);
+ if (isOptional1 && isOptional2) {
+ return new TAddTimezoneWrapper<true, true>(ctx.Mutables, value, id);
+ } else if (isOptional1) {
+ return new TAddTimezoneWrapper<true, false>(ctx.Mutables, value, id);
+ } else if (isOptional2) {
+ return new TAddTimezoneWrapper<false, true>(ctx.Mutables, value, id);
+ } else {
+ return new TAddTimezoneWrapper<false, false>(ctx.Mutables, value, id);
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_tobytes.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_tobytes.cpp
index 9d20f8f382..876eef4ad6 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_tobytes.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_tobytes.cpp
@@ -7,105 +7,105 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template<bool IsOptional, typename Type>
-class TToBytesPrimitiveTypeWrapper : public TDecoratorCodegeneratorNode<TToBytesPrimitiveTypeWrapper<IsOptional, Type>> {
-using TBaseComputation = TDecoratorCodegeneratorNode<TToBytesPrimitiveTypeWrapper<IsOptional, Type>>;
-public:
- TToBytesPrimitiveTypeWrapper(IComputationNode* data)
- : TBaseComputation(data)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx, const NUdf::TUnboxedValuePod& value) const {
- if (IsOptional && !value)
- return NUdf::TUnboxedValuePod();
-
- const auto& v = value.Get<Type>();
- return NUdf::TUnboxedValuePod::Embedded(NUdf::TStringRef(reinterpret_cast<const char*>(&v), sizeof(v)));
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
- const uint64_t one[] = {0ULL, sizeof(Type) << 48ULL};
- const auto size = ConstantInt::get(value->getType(), APInt(128, 2, one));
- const uint64_t two[] = {0xFFFFFFFFFFFFFFFFULL, 0xFF00FFFFFFFFFFFFULL};
- const auto mask = ConstantInt::get(value->getType(), APInt(128, 2, two));
- const auto result = BinaryOperator::CreateOr(BinaryOperator::CreateAnd(value, mask, "and", block), size, "or", block);
- if constexpr (IsOptional)
- return SelectInst::Create(IsExists(value, block), result, GetEmpty(ctx.Codegen->GetContext()), "select", block);
- return result;
- }
-#endif
-};
-
+namespace {
+
+template<bool IsOptional, typename Type>
+class TToBytesPrimitiveTypeWrapper : public TDecoratorCodegeneratorNode<TToBytesPrimitiveTypeWrapper<IsOptional, Type>> {
+using TBaseComputation = TDecoratorCodegeneratorNode<TToBytesPrimitiveTypeWrapper<IsOptional, Type>>;
+public:
+ TToBytesPrimitiveTypeWrapper(IComputationNode* data)
+ : TBaseComputation(data)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx, const NUdf::TUnboxedValuePod& value) const {
+ if (IsOptional && !value)
+ return NUdf::TUnboxedValuePod();
+
+ const auto& v = value.Get<Type>();
+ return NUdf::TUnboxedValuePod::Embedded(NUdf::TStringRef(reinterpret_cast<const char*>(&v), sizeof(v)));
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
+ const uint64_t one[] = {0ULL, sizeof(Type) << 48ULL};
+ const auto size = ConstantInt::get(value->getType(), APInt(128, 2, one));
+ const uint64_t two[] = {0xFFFFFFFFFFFFFFFFULL, 0xFF00FFFFFFFFFFFFULL};
+ const auto mask = ConstantInt::get(value->getType(), APInt(128, 2, two));
+ const auto result = BinaryOperator::CreateOr(BinaryOperator::CreateAnd(value, mask, "and", block), size, "or", block);
+ if constexpr (IsOptional)
+ return SelectInst::Create(IsExists(value, block), result, GetEmpty(ctx.Codegen->GetContext()), "select", block);
+ return result;
+ }
+#endif
+};
+
template<bool IsOptional, typename Type>
-class TToBytesTzTypeWrapper : public TDecoratorComputationNode<TToBytesTzTypeWrapper<IsOptional, Type>> {
-using TBaseComputation = TDecoratorComputationNode<TToBytesTzTypeWrapper<IsOptional, Type>>;
+class TToBytesTzTypeWrapper : public TDecoratorComputationNode<TToBytesTzTypeWrapper<IsOptional, Type>> {
+using TBaseComputation = TDecoratorComputationNode<TToBytesTzTypeWrapper<IsOptional, Type>>;
public:
- TToBytesTzTypeWrapper(IComputationNode* data)
- : TBaseComputation(data)
+ TToBytesTzTypeWrapper(IComputationNode* data)
+ : TBaseComputation(data)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx, const NUdf::TUnboxedValuePod& value) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx, const NUdf::TUnboxedValuePod& value) const {
if (IsOptional && !value)
return NUdf::TUnboxedValuePod();
- const auto v = NYql::SwapBytes(value.Get<Type>());
- const auto tzId = NYql::SwapBytes(value.GetTimezoneId());
+ const auto v = NYql::SwapBytes(value.Get<Type>());
+ const auto tzId = NYql::SwapBytes(value.GetTimezoneId());
char buf[sizeof(Type) + sizeof(ui16)];
- std::memcpy(buf, &v, sizeof(v));
- std::memcpy(buf + sizeof(Type), &tzId, sizeof(tzId));
+ std::memcpy(buf, &v, sizeof(v));
+ std::memcpy(buf + sizeof(Type), &tzId, sizeof(tzId));
return NUdf::TUnboxedValuePod::Embedded(NUdf::TStringRef(buf, sizeof(buf)));
}
};
-class TToBytesWrapper : public TDecoratorCodegeneratorNode<TToBytesWrapper> {
-using TBaseComputation = TDecoratorCodegeneratorNode<TToBytesWrapper>;
+class TToBytesWrapper : public TDecoratorCodegeneratorNode<TToBytesWrapper> {
+using TBaseComputation = TDecoratorCodegeneratorNode<TToBytesWrapper>;
public:
- TToBytesWrapper(IComputationNode* optional)
- : TBaseComputation(optional)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const { return value; }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*&) const { return value; }
-#endif
+ TToBytesWrapper(IComputationNode* optional)
+ : TBaseComputation(optional)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const { return value; }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*&) const { return value; }
+#endif
};
-}
-
+}
+
IComputationNode* WrapToBytes(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
- bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
- switch(dataType->GetSchemeType()) {
-#define MAKE_PRIMITIVE_TYPE_BYTES(type, layout) \
- case NUdf::TDataType<type>::Id: \
- if (isOptional) \
- return new TToBytesPrimitiveTypeWrapper<true, layout>(data); \
- else \
- return new TToBytesPrimitiveTypeWrapper<false, layout>(data);
-
- KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_BYTES)
-#undef MAKE_PRIMITIVE_TYPE_BYTES
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ switch(dataType->GetSchemeType()) {
+#define MAKE_PRIMITIVE_TYPE_BYTES(type, layout) \
+ case NUdf::TDataType<type>::Id: \
+ if (isOptional) \
+ return new TToBytesPrimitiveTypeWrapper<true, layout>(data); \
+ else \
+ return new TToBytesPrimitiveTypeWrapper<false, layout>(data);
+
+ KNOWN_FIXED_VALUE_TYPES(MAKE_PRIMITIVE_TYPE_BYTES)
+#undef MAKE_PRIMITIVE_TYPE_BYTES
#define MAKE_TZ_TYPE_BYTES(type, layout) \
case NUdf::TDataType<type>::Id: \
if (isOptional) \
- return new TToBytesTzTypeWrapper<true, layout>(data); \
+ return new TToBytesTzTypeWrapper<true, layout>(data); \
else \
- return new TToBytesTzTypeWrapper<false, layout>(data);
+ return new TToBytesTzTypeWrapper<false, layout>(data);
MAKE_TZ_TYPE_BYTES(NUdf::TTzDate, ui16);
MAKE_TZ_TYPE_BYTES(NUdf::TTzDatetime, ui32);
MAKE_TZ_TYPE_BYTES(NUdf::TTzTimestamp, ui64);
#undef MAKE_TZ_TYPE_BYTES
- default:
- break;
- }
-
- return new TToBytesWrapper(data);
+ default:
+ break;
+ }
+
+ return new TToBytesWrapper(data);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_todict.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_todict.cpp
index 8825c5db1c..2e299e487d 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_todict.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_todict.cpp
@@ -11,64 +11,64 @@
#include <ydb/library/yql/utils/cast.h>
#include <ydb/library/yql/utils/hash.h>
-#include <algorithm>
-#include <unordered_map>
-
+#include <algorithm>
+#include <unordered_map>
+
namespace NKikimr {
namespace NMiniKQL {
using NYql::EnsureDynamicCast;
-namespace {
-
-class THashedMultiMapAccumulator {
+namespace {
+
+class THashedMultiMapAccumulator {
using TMapType = std::unordered_map<
NUdf::TUnboxedValue,
- TUnboxedValueVector,
+ TUnboxedValueVector,
NYql::TVaryingHash<NUdf::TUnboxedValue, TValueHasher>,
TValueEqual,
- TMKQLAllocator<std::pair<const NUdf::TUnboxedValue, TUnboxedValueVector>>>;
+ TMKQLAllocator<std::pair<const NUdf::TUnboxedValue, TUnboxedValueVector>>>;
- TComputationContext& Ctx;
+ TComputationContext& Ctx;
TType* KeyType;
- const TKeyTypes& KeyTypes;
+ const TKeyTypes& KeyTypes;
bool IsTuple;
- std::optional<TValuePacker> Packer;
+ std::optional<TValuePacker> Packer;
TMapType Map;
-
-public:
+
+public:
THashedMultiMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple), Map(0, TValueHasher(KeyTypes, isTuple), TValueEqual(KeyTypes, isTuple))
{
if (encoded) {
- Packer.emplace(true, keyType);
+ Packer.emplace(true, keyType);
}
-
+
Y_UNUSED(payloadType);
- Map.reserve(itemsCountHint);
+ Map.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
{
if (Packer) {
key = MakeString(Packer->Pack(key));
}
- const auto ins = Map.emplace(std::move(key), 1U);
- if (ins.second)
- ins.first->second.front() = std::move(payload);
- else
- ins.first->second.emplace_back(std::move(payload));
+ const auto ins = Map.emplace(std::move(key), 1U);
+ if (ins.second)
+ ins.first->second.front() = std::move(payload);
+ else
+ ins.first->second.emplace_back(std::move(payload));
}
- NUdf::TUnboxedValue Build()
+ NUdf::TUnboxedValue Build()
{
- const auto filler = [this](TValuesDictHashMap& targetMap) {
- targetMap.reserve(Map.size());
+ const auto filler = [this](TValuesDictHashMap& targetMap) {
+ targetMap.reserve(Map.size());
- for (auto& pair : Map) {
- auto itemFactory = [](const NUdf::TUnboxedValuePod& value) {
+ for (auto& pair : Map) {
+ auto itemFactory = [](const NUdf::TUnboxedValuePod& value) {
return value;
};
@@ -77,7 +77,7 @@ public:
auto payloadList = CreateOwningVectorListAdapter(std::move(pair.second), itemFactory,
start, finish, false, Ctx.HolderFactory.GetMemInfo());
- targetMap.emplace(pair.first, std::move(payloadList));
+ targetMap.emplace(pair.first, std::move(payloadList));
}
};
@@ -85,42 +85,42 @@ public:
}
};
-class THashedMapAccumulator {
+class THashedMapAccumulator {
using TMapType = TValuesDictHashMap;
- TComputationContext& Ctx;
+ TComputationContext& Ctx;
TType* KeyType;
- const TKeyTypes& KeyTypes;
+ const TKeyTypes& KeyTypes;
const bool IsTuple;
- std::optional<TValuePacker> Packer;
+ std::optional<TValuePacker> Packer;
TMapType Map;
-
-public:
+
+public:
THashedMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple), Map(0, TValueHasher(KeyTypes, isTuple), TValueEqual(KeyTypes, isTuple))
{
if (encoded) {
- Packer.emplace(true, keyType);
+ Packer.emplace(true, keyType);
}
-
+
Y_UNUSED(payloadType);
- Map.reserve(itemsCountHint);
+ Map.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
{
if (Packer) {
key = MakeString(Packer->Pack(key));
}
- Map.emplace(std::move(key), std::move(payload));
+ Map.emplace(std::move(key), std::move(payload));
}
- NUdf::TUnboxedValue Build()
+ NUdf::TUnboxedValue Build()
{
const auto filler = [this](TMapType& targetMap) {
- targetMap = std::move(Map);
+ targetMap = std::move(Map);
};
return Ctx.HolderFactory.CreateDirectHashedDictHolder(filler, KeyTypes, IsTuple, true, Packer ? KeyType : nullptr);
@@ -128,45 +128,45 @@ public:
};
template<typename T>
-class THashedSingleFixedMultiMapAccumulator {
+class THashedSingleFixedMultiMapAccumulator {
using TMapType = std::unordered_map<
T,
- TUnboxedValueVector,
+ TUnboxedValueVector,
NYql::TVaryingHash<T, TMyHash<T>>,
- TMyEquals<T>,
- TMKQLAllocator<std::pair<const T, TUnboxedValueVector>>>;
+ TMyEquals<T>,
+ TMKQLAllocator<std::pair<const T, TUnboxedValueVector>>>;
- TComputationContext& Ctx;
- const TKeyTypes& KeyTypes;
+ TComputationContext& Ctx;
+ const TKeyTypes& KeyTypes;
TMapType Map;
-
-public:
+
+public:
THashedSingleFixedMultiMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
- : Ctx(ctx), KeyTypes(keyTypes), Map(0, TMyHash<T>(), TMyEquals<T>())
+ : Ctx(ctx), KeyTypes(keyTypes), Map(0, TMyHash<T>(), TMyEquals<T>())
{
- Y_UNUSED(keyType);
+ Y_UNUSED(keyType);
Y_UNUSED(payloadType);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.reserve(itemsCountHint);
+ Map.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
{
- const auto ins = Map.emplace(key.Get<T>(), 1U);
- if (ins.second)
- ins.first->second.front() = std::move(payload);
- else
- ins.first->second.emplace_back(std::move(payload));
+ const auto ins = Map.emplace(key.Get<T>(), 1U);
+ if (ins.second)
+ ins.first->second.front() = std::move(payload);
+ else
+ ins.first->second.emplace_back(std::move(payload));
}
- NUdf::TUnboxedValue Build()
+ NUdf::TUnboxedValue Build()
{
- const auto filler = [this](TValuesDictHashMap& targetMap) {
- targetMap.reserve(Map.size());
+ const auto filler = [this](TValuesDictHashMap& targetMap) {
+ targetMap.reserve(Map.size());
- for (auto& pair : Map) {
- auto itemFactory = [](const NUdf::TUnboxedValuePod& value) {
+ for (auto& pair : Map) {
+ auto itemFactory = [](const NUdf::TUnboxedValuePod& value) {
return value;
};
@@ -174,9 +174,9 @@ public:
ui64 finish = pair.second.size();
auto payloadList = CreateOwningVectorListAdapter(std::move(pair.second), itemFactory,
start, finish, false,
- Ctx.HolderFactory.GetMemInfo());
+ Ctx.HolderFactory.GetMemInfo());
- targetMap.emplace(NUdf::TUnboxedValuePod(pair.first), std::move(payloadList));
+ targetMap.emplace(NUdf::TUnboxedValuePod(pair.first), std::move(payloadList));
}
};
@@ -185,69 +185,69 @@ public:
};
template<typename T>
-class THashedSingleFixedMapAccumulator {
+class THashedSingleFixedMapAccumulator {
using TMapType = TValuesDictHashSingleFixedMap<T>;
- TComputationContext& Ctx;
+ TComputationContext& Ctx;
TMapType Map;
-
-public:
+
+public:
THashedSingleFixedMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Map(0, TMyHash<T>(), TMyEquals<T>())
{
- Y_UNUSED(keyType);
+ Y_UNUSED(keyType);
Y_UNUSED(payloadType);
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.reserve(itemsCountHint);
+ Map.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
{
- Map.emplace(key.Get<T>(), std::move(payload));
+ Map.emplace(key.Get<T>(), std::move(payload));
}
- NUdf::TUnboxedValue Build()
+ NUdf::TUnboxedValue Build()
{
- return Ctx.HolderFactory.CreateDirectHashedSingleFixedMapHolder<T>(std::move(Map));
+ return Ctx.HolderFactory.CreateDirectHashedSingleFixedMapHolder<T>(std::move(Map));
}
};
-class THashedSetAccumulator {
+class THashedSetAccumulator {
using TSetType = TValuesDictHashSet;
- TComputationContext& Ctx;
+ TComputationContext& Ctx;
TType* KeyType;
- const TKeyTypes& KeyTypes;
+ const TKeyTypes& KeyTypes;
bool IsTuple;
- std::optional<TValuePacker> Packer;
+ std::optional<TValuePacker> Packer;
TSetType Set;
-
-public:
+
+public:
THashedSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple), Set(0, TValueHasher(KeyTypes, isTuple), TValueEqual(KeyTypes, isTuple))
{
if (encoded) {
- Packer.emplace(true, keyType);
+ Packer.emplace(true, keyType);
}
-
- Set.reserve(itemsCountHint);
+
+ Set.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key)
- {
+ void Add(NUdf::TUnboxedValue&& key)
+ {
if (Packer) {
key = MakeString(Packer->Pack(key));
}
- Set.emplace(std::move(key));
+ Set.emplace(std::move(key));
}
- NUdf::TUnboxedValue Build()
- {
+ NUdf::TUnboxedValue Build()
+ {
const auto filler = [this](TSetType& targetSet) {
- targetSet = std::move(Set);
+ targetSet = std::move(Set);
};
return Ctx.HolderFactory.CreateDirectHashedSetHolder(filler, KeyTypes, IsTuple, true, Packer ? KeyType : nullptr);
@@ -255,385 +255,385 @@ public:
};
template <typename T>
-class THashedSingleFixedSetAccumulator {
+class THashedSingleFixedSetAccumulator {
using TSetType = TValuesDictHashSingleFixedSet<T>;
- TComputationContext& Ctx;
+ TComputationContext& Ctx;
TSetType Set;
-
-public:
+
+public:
THashedSingleFixedSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Set(0, TMyHash<T>(), TMyEquals<T>())
- {
- Y_UNUSED(keyType);
+ {
+ Y_UNUSED(keyType);
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Set.reserve(itemsCountHint);
+ Set.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key)
- {
- Set.emplace(key.Get<T>());
+ void Add(NUdf::TUnboxedValue&& key)
+ {
+ Set.emplace(key.Get<T>());
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedSingleFixedSetHolder<T>(std::move(Set));
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedSingleFixedSetHolder<T>(std::move(Set));
}
};
template <typename T>
-class THashedSingleFixedCompactSetAccumulator {
+class THashedSingleFixedCompactSetAccumulator {
using TSetType = TValuesDictHashSingleFixedCompactSet<T>;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TSetType Set;
-
-public:
+
+public:
THashedSingleFixedCompactSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Set(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR)
- {
- Y_UNUSED(keyType);
+ {
+ Y_UNUSED(keyType);
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Set.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Set.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key)
- {
- Set.Insert(key.Get<T>());
+ void Add(NUdf::TUnboxedValue&& key)
+ {
+ Set.Insert(key.Get<T>());
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactSetHolder<T>(std::move(Set));
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactSetHolder<T>(std::move(Set));
}
};
-class THashedCompactSetAccumulator {
+class THashedCompactSetAccumulator {
using TSetType = TValuesDictHashCompactSet;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TSetType Set;
- TType *KeyType;
- TValuePacker KeyPacker;
-
-public:
+ TType *KeyType;
+ TValuePacker KeyPacker;
+
+public:
THashedCompactSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Set(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR, TSmallValueHash(), TSmallValueEqual())
, KeyType(keyType), KeyPacker(true, keyType)
- {
+ {
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Set.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Set.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key)
- {
- Set.Insert(AddSmallValue(Pool, KeyPacker.Pack(key)));
+ void Add(NUdf::TUnboxedValue&& key)
+ {
+ Set.Insert(AddSmallValue(Pool, KeyPacker.Pack(key)));
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedCompactSetHolder(std::move(Set), std::move(Pool), KeyType, &Ctx);
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedCompactSetHolder(std::move(Set), std::move(Pool), KeyType, &Ctx);
}
};
template <bool Multi>
-class THashedCompactMapAccumulator;
+class THashedCompactMapAccumulator;
template <>
-class THashedCompactMapAccumulator<false> {
+class THashedCompactMapAccumulator<false> {
using TMapType = TValuesDictHashCompactMap;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TMapType Map;
- TType *KeyType, *PayloadType;
- TValuePacker KeyPacker, PayloadPacker;
-
-public:
+ TType *KeyType, *PayloadType;
+ TValuePacker KeyPacker, PayloadPacker;
+
+public:
THashedCompactMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Map(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR)
, KeyType(keyType), PayloadType(payloadType), KeyPacker(true, keyType), PayloadPacker(false, payloadType)
- {
+ {
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
- Map.InsertNew(AddSmallValue(Pool, KeyPacker.Pack(key)), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
+ Map.InsertNew(AddSmallValue(Pool, KeyPacker.Pack(key)), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedCompactMapHolder(std::move(Map), std::move(Pool), KeyType, PayloadType, &Ctx);
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedCompactMapHolder(std::move(Map), std::move(Pool), KeyType, PayloadType, &Ctx);
}
};
template <>
-class THashedCompactMapAccumulator<true> {
+class THashedCompactMapAccumulator<true> {
using TMapType = TValuesDictHashCompactMultiMap;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TMapType Map;
- TType *KeyType, *PayloadType;
- TValuePacker KeyPacker, PayloadPacker;
-
-public:
+ TType *KeyType, *PayloadType;
+ TValuePacker KeyPacker, PayloadPacker;
+
+public:
THashedCompactMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Map(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR)
, KeyType(keyType), PayloadType(payloadType), KeyPacker(true, keyType), PayloadPacker(false, payloadType)
- {
+ {
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
- Map.Insert(AddSmallValue(Pool, KeyPacker.Pack(key)), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
+ Map.Insert(AddSmallValue(Pool, KeyPacker.Pack(key)), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedCompactMultiMapHolder(std::move(Map), std::move(Pool), KeyType, PayloadType, &Ctx);
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedCompactMultiMapHolder(std::move(Map), std::move(Pool), KeyType, PayloadType, &Ctx);
}
};
template <typename T, bool Multi>
-class THashedSingleFixedCompactMapAccumulator;
+class THashedSingleFixedCompactMapAccumulator;
template <typename T>
-class THashedSingleFixedCompactMapAccumulator<T, false> {
+class THashedSingleFixedCompactMapAccumulator<T, false> {
using TMapType = TValuesDictHashSingleFixedCompactMap<T>;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TMapType Map;
- TType *PayloadType;
- TValuePacker PayloadPacker;
-
-public:
+ TType *PayloadType;
+ TValuePacker PayloadPacker;
+
+public:
THashedSingleFixedCompactMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Map(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR)
, PayloadType(payloadType), PayloadPacker(false, payloadType)
- {
- Y_UNUSED(keyType);
+ {
+ Y_UNUSED(keyType);
Y_UNUSED(keyTypes);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
- Map.InsertNew(key.Get<T>(), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
+ Map.InsertNew(key.Get<T>(), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
}
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactMapHolder(std::move(Map), std::move(Pool), PayloadType, &Ctx);
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactMapHolder(std::move(Map), std::move(Pool), PayloadType, &Ctx);
}
};
template <typename T>
-class THashedSingleFixedCompactMapAccumulator<T, true> {
+class THashedSingleFixedCompactMapAccumulator<T, true> {
using TMapType = TValuesDictHashSingleFixedCompactMultiMap<T>;
- TComputationContext& Ctx;
- TPagedArena Pool;
+ TComputationContext& Ctx;
+ TPagedArena Pool;
TMapType Map;
- TType *PayloadType;
- TValuePacker PayloadPacker;
-
-public:
+ TType *PayloadType;
+ TValuePacker PayloadPacker;
+
+public:
THashedSingleFixedCompactMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), Pool(&Ctx.HolderFactory.GetPagePool()), Map(Ctx.HolderFactory.GetPagePool(), itemsCountHint / COMPACT_HASH_MAX_LOAD_FACTOR)
, PayloadType(payloadType), PayloadPacker(false, payloadType)
- {
+ {
Y_UNUSED(keyTypes);
- Y_UNUSED(keyType);
+ Y_UNUSED(keyType);
Y_UNUSED(isTuple);
Y_UNUSED(encoded);
- Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
+ Map.SetMaxLoadFactor(COMPACT_HASH_MAX_LOAD_FACTOR);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
- Map.Insert(key.Get<T>(), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
+ Map.Insert(key.Get<T>(), AddSmallValue(Pool, PayloadPacker.Pack(payload)));
+ }
+
+ NUdf::TUnboxedValue Build()
+ {
+ return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactMultiMapHolder(std::move(Map), std::move(Pool), PayloadType, &Ctx);
}
+};
+
+class TSortedSetAccumulator {
+ TComputationContext& Ctx;
+ TType* KeyType;
+ const TKeyTypes& KeyTypes;
+ bool IsTuple;
+ std::optional<TGenericPresortEncoder> Packer;
+ TUnboxedValueVector Items;
+
+public:
+ TSortedSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
+ : Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple)
+ {
+ if (encoded) {
+ Packer.emplace(KeyType);
+ }
+
+ Items.reserve(itemsCountHint);
+ }
+
+ void Add(NUdf::TUnboxedValue&& key)
+ {
+ if (Packer) {
+ key = MakeString(Packer->Encode(key, false));
+ }
+
+ Items.emplace_back(std::move(key));
+ }
+
+ NUdf::TUnboxedValue Build()
+ {
+ const TSortedSetFiller filler = [this](TUnboxedValueVector& values) {
+ std::stable_sort(Items.begin(), Items.end(), TValueLess(KeyTypes, IsTuple));
+ Items.erase(std::unique(Items.begin(), Items.end(), TValueEqual(KeyTypes, IsTuple)), Items.end());
+ values = std::move(Items);
+ };
- NUdf::TUnboxedValue Build()
- {
- return Ctx.HolderFactory.CreateDirectHashedSingleFixedCompactMultiMapHolder(std::move(Map), std::move(Pool), PayloadType, &Ctx);
+ return Ctx.HolderFactory.CreateDirectSortedSetHolder(filler, KeyTypes, IsTuple,
+ EDictSortMode::SortedUniqueAscending, true, Packer ? KeyType : nullptr);
}
};
-class TSortedSetAccumulator {
- TComputationContext& Ctx;
- TType* KeyType;
- const TKeyTypes& KeyTypes;
- bool IsTuple;
- std::optional<TGenericPresortEncoder> Packer;
- TUnboxedValueVector Items;
-
-public:
- TSortedSetAccumulator(TType* keyType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
- : Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple)
- {
- if (encoded) {
- Packer.emplace(KeyType);
- }
-
- Items.reserve(itemsCountHint);
- }
-
- void Add(NUdf::TUnboxedValue&& key)
- {
- if (Packer) {
- key = MakeString(Packer->Encode(key, false));
- }
-
- Items.emplace_back(std::move(key));
- }
-
- NUdf::TUnboxedValue Build()
- {
- const TSortedSetFiller filler = [this](TUnboxedValueVector& values) {
- std::stable_sort(Items.begin(), Items.end(), TValueLess(KeyTypes, IsTuple));
- Items.erase(std::unique(Items.begin(), Items.end(), TValueEqual(KeyTypes, IsTuple)), Items.end());
- values = std::move(Items);
- };
-
- return Ctx.HolderFactory.CreateDirectSortedSetHolder(filler, KeyTypes, IsTuple,
- EDictSortMode::SortedUniqueAscending, true, Packer ? KeyType : nullptr);
- }
-};
-
-template<bool IsMulti>
-class TSortedMapAccumulator;
-
-template<>
-class TSortedMapAccumulator<false> {
- TComputationContext& Ctx;
+template<bool IsMulti>
+class TSortedMapAccumulator;
+
+template<>
+class TSortedMapAccumulator<false> {
+ TComputationContext& Ctx;
TType* KeyType;
- const TKeyTypes& KeyTypes;
+ const TKeyTypes& KeyTypes;
bool IsTuple;
- std::optional<TGenericPresortEncoder> Packer;
+ std::optional<TGenericPresortEncoder> Packer;
+
+ TKeyPayloadPairVector Items;
- TKeyPayloadPairVector Items;
-
-public:
+public:
TSortedMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple)
{
if (encoded) {
- Packer.emplace(KeyType);
+ Packer.emplace(KeyType);
}
-
- Y_UNUSED(payloadType);
- Items.reserve(itemsCountHint);
+
+ Y_UNUSED(payloadType);
+ Items.reserve(itemsCountHint);
}
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
if (Packer) {
key = MakeString(Packer->Encode(key, false));
}
- Items.emplace_back(std::move(key), std::move(payload));
+ Items.emplace_back(std::move(key), std::move(payload));
}
- NUdf::TUnboxedValue Build()
- {
- const TSortedDictFiller filler = [this](TKeyPayloadPairVector& values) {
- values = std::move(Items);
- };
+ NUdf::TUnboxedValue Build()
+ {
+ const TSortedDictFiller filler = [this](TKeyPayloadPairVector& values) {
+ values = std::move(Items);
+ };
return Ctx.HolderFactory.CreateDirectSortedDictHolder(filler, KeyTypes, IsTuple, EDictSortMode::RequiresSorting, true, Packer ? KeyType : nullptr);
- }
-};
-
-template<>
-class TSortedMapAccumulator<true> {
- TComputationContext& Ctx;
+ }
+};
+
+template<>
+class TSortedMapAccumulator<true> {
+ TComputationContext& Ctx;
TType* KeyType;
- const TKeyTypes& KeyTypes;
+ const TKeyTypes& KeyTypes;
bool IsTuple;
- std::optional<TGenericPresortEncoder> Packer;
- TKeyPayloadPairVector Items;
+ std::optional<TGenericPresortEncoder> Packer;
+ TKeyPayloadPairVector Items;
-public:
+public:
TSortedMapAccumulator(TType* keyType, TType* payloadType, const TKeyTypes& keyTypes, bool isTuple, bool encoded, TComputationContext& ctx, ui64 itemsCountHint)
: Ctx(ctx), KeyType(keyType), KeyTypes(keyTypes), IsTuple(isTuple)
{
if (encoded) {
- Packer.emplace(KeyType);
+ Packer.emplace(KeyType);
}
-
- Y_UNUSED(payloadType);
- Items.reserve(itemsCountHint);
- }
- void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
- {
+ Y_UNUSED(payloadType);
+ Items.reserve(itemsCountHint);
+ }
+
+ void Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& payload)
+ {
if (Packer) {
key = MakeString(Packer->Encode(key, false));
}
- Items.emplace_back(std::move(key), std::move(payload));
+ Items.emplace_back(std::move(key), std::move(payload));
}
- NUdf::TUnboxedValue Build()
- {
- const TSortedDictFiller filler = [this](TKeyPayloadPairVector& values) {
+ NUdf::TUnboxedValue Build()
+ {
+ const TSortedDictFiller filler = [this](TKeyPayloadPairVector& values) {
std::stable_sort(Items.begin(), Items.end(), TKeyPayloadPairLess(KeyTypes, IsTuple));
-
- TKeyPayloadPairVector groups;
- groups.reserve(Items.size());
- if (!Items.empty()) {
- TDefaultListRepresentation currentList(std::move(Items.begin()->second));
- auto lastKey = std::move(Items.begin()->first);
+
+ TKeyPayloadPairVector groups;
+ groups.reserve(Items.size());
+ if (!Items.empty()) {
+ TDefaultListRepresentation currentList(std::move(Items.begin()->second));
+ auto lastKey = std::move(Items.begin()->first);
TValueEqual eqPredicate(KeyTypes, IsTuple);
- for (auto it = Items.begin() + 1; it != Items.end(); ++it) {
- if (eqPredicate(lastKey, it->first)) {
- currentList = currentList.Append(std::move(it->second));
- }
- else {
- auto payload = Ctx.HolderFactory.CreateDirectListHolder(std::move(currentList));
- groups.emplace_back(std::move(lastKey), std::move(payload));
- currentList = TDefaultListRepresentation(std::move(it->second));
- lastKey = std::move(it->first);
- }
- }
-
- auto payload = Ctx.HolderFactory.CreateDirectListHolder(std::move(currentList));
- groups.emplace_back(std::move(lastKey), std::move(payload));
- }
-
- values = std::move(groups);
- };
-
+ for (auto it = Items.begin() + 1; it != Items.end(); ++it) {
+ if (eqPredicate(lastKey, it->first)) {
+ currentList = currentList.Append(std::move(it->second));
+ }
+ else {
+ auto payload = Ctx.HolderFactory.CreateDirectListHolder(std::move(currentList));
+ groups.emplace_back(std::move(lastKey), std::move(payload));
+ currentList = TDefaultListRepresentation(std::move(it->second));
+ lastKey = std::move(it->first);
+ }
+ }
+
+ auto payload = Ctx.HolderFactory.CreateDirectListHolder(std::move(currentList));
+ groups.emplace_back(std::move(lastKey), std::move(payload));
+ }
+
+ values = std::move(groups);
+ };
+
return Ctx.HolderFactory.CreateDirectSortedDictHolder(filler, KeyTypes, IsTuple,
EDictSortMode::SortedUniqueAscending, true, Packer ? KeyType : nullptr);
}
-};
-
+};
+
template <typename TSetAccumulator, bool IsStream>
class TSetWrapper : public TMutableComputationNode<TSetWrapper<TSetAccumulator, IsStream>> {
typedef TMutableComputationNode<TSetWrapper<TSetAccumulator, IsStream>> TBaseComputation;
-public:
+public:
class TStreamValue : public TComputationValue<TStreamValue> {
public:
TStreamValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& input, IComputationExternalNode* const item,
@@ -679,87 +679,87 @@ public:
bool Finished = false;
};
- TSetWrapper(TComputationMutables& mutables, TType* keyType, IComputationNode* list, IComputationExternalNode* item,
- IComputationNode* key, ui64 itemsCountHint)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ TSetWrapper(TComputationMutables& mutables, TType* keyType, IComputationNode* list, IComputationExternalNode* item,
+ IComputationNode* key, ui64 itemsCountHint)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, KeyType(keyType)
- , List(list)
- , Item(item)
- , Key(key)
- , ItemsCountHint(itemsCountHint)
+ , List(list)
+ , Item(item)
+ , Key(key)
+ , ItemsCountHint(itemsCountHint)
{
GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
if constexpr (IsStream) {
return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Item, Key,
TSetAccumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint), ctx);
}
const auto& list = List->GetValue(ctx);
- auto itemsCountHint = ItemsCountHint;
+ auto itemsCountHint = ItemsCountHint;
if (list.HasFastListLength()) {
- if (const auto size = list.GetListLength())
- itemsCountHint = size;
- else
- return ctx.HolderFactory.GetEmptyContainer();
- }
-
+ if (const auto size = list.GetListLength())
+ itemsCountHint = size;
+ else
+ return ctx.HolderFactory.GetEmptyContainer();
+ }
+
TSetAccumulator accumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, itemsCountHint);
-
+
TThresher<false>::DoForEachItem(list,
[this, &accumulator, &ctx] (NUdf::TUnboxedValue&& item) {
Item->SetValue(ctx, std::move(item));
accumulator.Add(Key->GetValue(ctx));
- }
- );
-
- return accumulator.Build().Release();
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
+ }
+ );
+
+ return accumulator.Build().Release();
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
this->Own(Item);
- this->DependsOn(Key);
- }
-
+ this->DependsOn(Key);
+ }
+
TType* const KeyType;
IComputationNode* const List;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const Key;
- const ui64 ItemsCountHint;
+ const ui64 ItemsCountHint;
TKeyTypes KeyTypes;
bool IsTuple;
bool Encoded;
};
template <typename TSetAccumulator>
-class TSqueezeSetFlowWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeSetFlowWrapper<TSetAccumulator>> {
- using TBase = TStatefulFlowCodegeneratorNode<TSqueezeSetFlowWrapper<TSetAccumulator>>;
-public:
+class TSqueezeSetFlowWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeSetFlowWrapper<TSetAccumulator>> {
+ using TBase = TStatefulFlowCodegeneratorNode<TSqueezeSetFlowWrapper<TSetAccumulator>>;
+public:
class TState : public TComputationValue<TState> {
using TBase = TComputationValue<TState>;
public:
TState(TMemoryUsageInfo* memInfo, TSetAccumulator&& setAccum)
: TBase(memInfo), SetAccum(std::move(setAccum)) {}
- NUdf::TUnboxedValuePod Build() {
- return SetAccum.Build().Release();
+ NUdf::TUnboxedValuePod Build() {
+ return SetAccum.Build().Release();
}
- void Insert(NUdf::TUnboxedValuePod value) {
- SetAccum.Add(value);
+ void Insert(NUdf::TUnboxedValuePod value) {
+ SetAccum.Add(value);
}
private:
TSetAccumulator SetAccum;
};
- TSqueezeSetFlowWrapper(TComputationMutables& mutables, TType* keyType,
+ TSqueezeSetFlowWrapper(TComputationMutables& mutables, TType* keyType,
IComputationNode* flow, IComputationExternalNode* item, IComputationNode* key, ui64 itemsCountHint)
- : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
, KeyType(keyType)
, Flow(flow)
, Item(item)
@@ -769,140 +769,140 @@ public:
GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
}
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return state.Release();
- } else if (!state.HasValue()) {
- MakeState(ctx, state);
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return state.Release();
+ } else if (!state.HasValue()) {
+ MakeState(ctx, state);
}
- while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
- if (auto item = Flow->GetValue(ctx); item.IsYield()) {
- return item.Release();
- } else if (item.IsFinish()) {
- const auto dict = statePtr->Build();
- state = std::move(item);
- return dict;
- } else {
- Item->SetValue(ctx, std::move(item));
- statePtr->Insert(Key->GetValue(ctx).Release());
- }
+ while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
+ if (auto item = Flow->GetValue(ctx); item.IsYield()) {
+ return item.Release();
+ } else if (item.IsFinish()) {
+ const auto dict = statePtr->Build();
+ state = std::move(item);
+ return dict;
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ statePtr->Insert(Key->GetValue(ctx).Release());
+ }
}
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Item);
MKQL_ENSURE(codegenItemArg, "Item must be codegenerator node.");
- const auto valueType = Type::getInt128Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- structPtrType // accumulator
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeSetFlowWrapper<TSetAccumulator>::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- result->addIncoming(GetFinish(context), block);
-
- BranchInst::Create(over, more, IsFinish(state, block), block);
-
- block = more;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(GetYield(context), block);
-
- const auto choise = SwitchInst::Create(item, plus, 2U, block);
- choise->addCase(GetFinish(context), done);
- choise->addCase(GetYield(context), over);
-
- block = plus;
-
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto key = GetNodeValue(Key, ctx, block);
-
- const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
-
- const auto keyArg = WrapArgumentForWindows(key, ctx, block);
-
- const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType()}, false);
- const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
- CallInst::Create(insPtr, {stateArg, keyArg}, "", block);
-
- BranchInst::Create(more, block);
-
- block = done;
-
- const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
- const auto dict = new LoadInst(ptr, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ structPtrType // accumulator
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeSetFlowWrapper<TSetAccumulator>::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ BranchInst::Create(over, more, IsFinish(state, block), block);
+
+ block = more;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(GetYield(context), block);
+
+ const auto choise = SwitchInst::Create(item, plus, 2U, block);
+ choise->addCase(GetFinish(context), done);
+ choise->addCase(GetYield(context), over);
+
+ block = plus;
+
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto key = GetNodeValue(Key, ctx, block);
+
+ const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
+
+ const auto keyArg = WrapArgumentForWindows(key, ctx, block);
+
+ const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType()}, false);
+ const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
+ CallInst::Create(insPtr, {stateArg, keyArg}, "", block);
+
+ BranchInst::Create(more, block);
+
+ block = done;
+
+ const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
+ const auto dict = new LoadInst(ptr, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
}
- new StoreInst(item, statePtr, block);
- BranchInst::Create(over, block);
-
- block = over;
- return result;
+ new StoreInst(item, statePtr, block);
+ BranchInst::Create(over, block);
+
+ block = over;
+ return result;
}
#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TState>(TSetAccumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
- }
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TState>(TSetAccumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
+ }
void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->Own(flow, Item);
- this->DependsOn(flow, Key);
- }
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->Own(flow, Item);
+ this->DependsOn(flow, Key);
+ }
}
TType* const KeyType;
@@ -915,201 +915,201 @@ private:
bool Encoded;
};
-template <typename TSetAccumulator>
-class TSqueezeSetWideWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeSetWideWrapper<TSetAccumulator>> {
- using TBase = TStatefulFlowCodegeneratorNode<TSqueezeSetWideWrapper<TSetAccumulator>>;
-public:
- class TState : public TComputationValue<TState> {
- using TBase = TComputationValue<TState>;
- public:
- TState(TMemoryUsageInfo* memInfo, TSetAccumulator&& setAccum)
- : TBase(memInfo), SetAccum(std::move(setAccum)) {}
-
- NUdf::TUnboxedValuePod Build() {
- return SetAccum.Build().Release();
- }
-
- void Insert(NUdf::TUnboxedValuePod value) {
- SetAccum.Add(value);
- }
-
- private:
- TSetAccumulator SetAccum;
- };
-
- TSqueezeSetWideWrapper(TComputationMutables& mutables, TType* keyType,
- IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* key, ui64 itemsCountHint)
- : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
- , KeyType(keyType)
- , Flow(flow)
- , Items(std::move(items))
- , Key(key)
- , ItemsCountHint(itemsCountHint)
- , PasstroughKey(GetPasstroughtMap({Key}, Items).front())
- , Fields(Items.size(), nullptr)
- {
- GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return state.Release();
- } else if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Key == Items[i] || Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::One:
- statePtr->Insert(Key->GetValue(ctx).Release());
- continue;
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- case EFetchResult::Finish: {
- const auto dict = statePtr->Build();
- state = NUdf::TUnboxedValuePod::MakeFinish();
- return dict;
- }
- }
- }
+template <typename TSetAccumulator>
+class TSqueezeSetWideWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeSetWideWrapper<TSetAccumulator>> {
+ using TBase = TStatefulFlowCodegeneratorNode<TSqueezeSetWideWrapper<TSetAccumulator>>;
+public:
+ class TState : public TComputationValue<TState> {
+ using TBase = TComputationValue<TState>;
+ public:
+ TState(TMemoryUsageInfo* memInfo, TSetAccumulator&& setAccum)
+ : TBase(memInfo), SetAccum(std::move(setAccum)) {}
+
+ NUdf::TUnboxedValuePod Build() {
+ return SetAccum.Build().Release();
+ }
+
+ void Insert(NUdf::TUnboxedValuePod value) {
+ SetAccum.Add(value);
+ }
+
+ private:
+ TSetAccumulator SetAccum;
+ };
+
+ TSqueezeSetWideWrapper(TComputationMutables& mutables, TType* keyType,
+ IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* key, ui64 itemsCountHint)
+ : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ , KeyType(keyType)
+ , Flow(flow)
+ , Items(std::move(items))
+ , Key(key)
+ , ItemsCountHint(itemsCountHint)
+ , PasstroughKey(GetPasstroughtMap({Key}, Items).front())
+ , Fields(Items.size(), nullptr)
+ {
+ GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return state.Release();
+ } else if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Key == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::One:
+ statePtr->Insert(Key->GetValue(ctx).Release());
+ continue;
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ case EFetchResult::Finish: {
+ const auto dict = statePtr->Build();
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ return dict;
+ }
+ }
+ }
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- structPtrType // accumulator
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeSetWideWrapper<TSetAccumulator>::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- result->addIncoming(GetFinish(context), block);
-
- BranchInst::Create(over, more, IsFinish(state, block), block);
-
- block = more;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- result->addIncoming(GetYield(context), block);
-
- const auto action = SwitchInst::Create(getres.first, plus, 2U, block);
- action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Finish)), done);
- action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Yield)), over);
-
- block = plus;
-
- if (!PasstroughKey) {
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ structPtrType // accumulator
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeSetWideWrapper<TSetAccumulator>::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ BranchInst::Create(over, more, IsFinish(state, block), block);
+
+ block = more;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ result->addIncoming(GetYield(context), block);
+
+ const auto action = SwitchInst::Create(getres.first, plus, 2U, block);
+ action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Finish)), done);
+ action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Yield)), over);
+
+ block = plus;
+
+ if (!PasstroughKey) {
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
- }
-
- const auto key = PasstroughKey ? getres.second[*PasstroughKey](ctx, block) : GetNodeValue(Key, ctx, block);
-
- const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
-
- const auto keyArg = WrapArgumentForWindows(key, ctx, block);
-
- const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType()}, false);
- const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
- CallInst::Create(insPtr, {stateArg, keyArg}, "", block);
-
- BranchInst::Create(more, block);
-
- block = done;
-
- const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
- const auto dict = new LoadInst(ptr, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- }
-
- new StoreInst(GetFinish(context), statePtr, block);
- BranchInst::Create(over, block);
-
- block = over;
- return result;
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TState>(TSetAccumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TSqueezeSetWideWrapper::Own, flow, std::placeholders::_1));
- this->DependsOn(flow, Key);
- }
- }
-
- TType* const KeyType;
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const Key;
- const ui64 ItemsCountHint;
- TKeyTypes KeyTypes;
- bool IsTuple;
- bool Encoded;
-
- const std::optional<size_t> PasstroughKey;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
+ }
+
+ const auto key = PasstroughKey ? getres.second[*PasstroughKey](ctx, block) : GetNodeValue(Key, ctx, block);
+
+ const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
+
+ const auto keyArg = WrapArgumentForWindows(key, ctx, block);
+
+ const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType()}, false);
+ const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
+ CallInst::Create(insPtr, {stateArg, keyArg}, "", block);
+
+ BranchInst::Create(more, block);
+
+ block = done;
+
+ const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
+ const auto dict = new LoadInst(ptr, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ }
+
+ new StoreInst(GetFinish(context), statePtr, block);
+ BranchInst::Create(over, block);
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TState>(TSetAccumulator(KeyType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TSqueezeSetWideWrapper::Own, flow, std::placeholders::_1));
+ this->DependsOn(flow, Key);
+ }
+ }
+
+ TType* const KeyType;
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const Key;
+ const ui64 ItemsCountHint;
+ TKeyTypes KeyTypes;
+ bool IsTuple;
+ bool Encoded;
+
+ const std::optional<size_t> PasstroughKey;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
template <typename TMapAccumulator, bool IsStream>
class TMapWrapper : public TMutableComputationNode<TMapWrapper<TMapAccumulator, IsStream>> {
typedef TMutableComputationNode<TMapWrapper<TMapAccumulator, IsStream>> TBaseComputation;
@@ -1161,71 +1161,71 @@ public:
bool Finished = false;
};
- TMapWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType, IComputationNode* list, IComputationExternalNode* item,
- IComputationNode* key, IComputationNode* payload, ui64 itemsCountHint)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ TMapWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType, IComputationNode* list, IComputationExternalNode* item,
+ IComputationNode* key, IComputationNode* payload, ui64 itemsCountHint)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, KeyType(keyType)
- , PayloadType(payloadType)
- , List(list)
- , Item(item)
- , Key(key)
- , Payload(payload)
- , ItemsCountHint(itemsCountHint)
+ , PayloadType(payloadType)
+ , List(list)
+ , Item(item)
+ , Key(key)
+ , Payload(payload)
+ , ItemsCountHint(itemsCountHint)
{
GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
if constexpr (IsStream) {
return ctx.HolderFactory.Create<TStreamValue>(List->GetValue(ctx), Item, Key, Payload,
TMapAccumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint), ctx);
}
const auto& list = List->GetValue(ctx);
-
- auto itemsCountHint = ItemsCountHint;
+
+ auto itemsCountHint = ItemsCountHint;
if (list.HasFastListLength()) {
- if (const auto size = list.GetListLength())
- itemsCountHint = size;
- else
- return ctx.HolderFactory.GetEmptyContainer();
- }
-
+ if (const auto size = list.GetListLength())
+ itemsCountHint = size;
+ else
+ return ctx.HolderFactory.GetEmptyContainer();
+ }
+
TMapAccumulator accumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, itemsCountHint);
-
+
TThresher<false>::DoForEachItem(list,
[this, &accumulator, &ctx] (NUdf::TUnboxedValue&& item) {
Item->SetValue(ctx, std::move(item));
accumulator.Add(Key->GetValue(ctx), Payload->GetValue(ctx));
- }
- );
-
- return accumulator.Build().Release();
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
+ }
+ );
+
+ return accumulator.Build().Release();
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
this->Own(Item);
- this->DependsOn(Key);
- this->DependsOn(Payload);
- }
-
+ this->DependsOn(Key);
+ this->DependsOn(Payload);
+ }
+
TType* const KeyType;
- TType* PayloadType;
- IComputationNode* const List;
- IComputationExternalNode* const Item;
- IComputationNode* const Key;
- IComputationNode* const Payload;
- const ui64 ItemsCountHint;
+ TType* PayloadType;
+ IComputationNode* const List;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Key;
+ IComputationNode* const Payload;
+ const ui64 ItemsCountHint;
TKeyTypes KeyTypes;
bool IsTuple;
bool Encoded;
-};
-
+};
+
template <typename TMapAccumulator>
-class TSqueezeMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeMapFlowWrapper<TMapAccumulator>> {
- using TBase = TStatefulFlowCodegeneratorNode<TSqueezeMapFlowWrapper<TMapAccumulator>>;
+class TSqueezeMapFlowWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeMapFlowWrapper<TMapAccumulator>> {
+ using TBase = TStatefulFlowCodegeneratorNode<TSqueezeMapFlowWrapper<TMapAccumulator>>;
public:
class TState : public TComputationValue<TState> {
using TBase = TComputationValue<TState>;
@@ -1233,22 +1233,22 @@ public:
TState(TMemoryUsageInfo* memInfo, TMapAccumulator&& mapAccum)
: TBase(memInfo), MapAccum(std::move(mapAccum)) {}
- NUdf::TUnboxedValuePod Build() {
- return MapAccum.Build().Release();
+ NUdf::TUnboxedValuePod Build() {
+ return MapAccum.Build().Release();
}
- void Insert(NUdf::TUnboxedValuePod key, NUdf::TUnboxedValuePod value) {
- MapAccum.Add(key, value);
+ void Insert(NUdf::TUnboxedValuePod key, NUdf::TUnboxedValuePod value) {
+ MapAccum.Add(key, value);
}
private:
TMapAccumulator MapAccum;
};
- TSqueezeMapFlowWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType,
+ TSqueezeMapFlowWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType,
IComputationNode* flow, IComputationExternalNode* item, IComputationNode* key, IComputationNode* payload,
ui64 itemsCountHint)
- : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
, KeyType(keyType)
, PayloadType(payloadType)
, Flow(flow)
@@ -1260,143 +1260,143 @@ public:
GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
}
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return state;
- } else if (!state.HasValue()) {
- MakeState(ctx, state);
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return state;
+ } else if (!state.HasValue()) {
+ MakeState(ctx, state);
}
- while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
- if (auto item = Flow->GetValue(ctx); item.IsYield()) {
- return item.Release();
- } else if (item.IsFinish()) {
- const auto dict = statePtr->Build();
- state = std::move(item);
- return dict;
- } else {
- Item->SetValue(ctx, std::move(item));
- statePtr->Insert(Key->GetValue(ctx).Release(), Payload->GetValue(ctx).Release());
- }
+ while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
+ if (auto item = Flow->GetValue(ctx); item.IsYield()) {
+ return item.Release();
+ } else if (item.IsFinish()) {
+ const auto dict = statePtr->Build();
+ state = std::move(item);
+ return dict;
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ statePtr->Insert(Key->GetValue(ctx).Release(), Payload->GetValue(ctx).Release());
+ }
}
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
- const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ const auto codegenItemArg = dynamic_cast<ICodegeneratorExternalNode*>(Item);
MKQL_ENSURE(codegenItemArg, "Item must be codegenerator node.");
- const auto valueType = Type::getInt128Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- structPtrType // accumulator
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeMapFlowWrapper<TMapAccumulator>::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- result->addIncoming(GetFinish(context), block);
-
- BranchInst::Create(over, more, IsFinish(state, block), block);
-
- block = more;
-
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(GetYield(context), block);
-
- const auto choise = SwitchInst::Create(item, plus, 2U, block);
- choise->addCase(GetFinish(context), done);
- choise->addCase(GetYield(context), over);
-
- block = plus;
-
- codegenItemArg->CreateSetValue(ctx, block, item);
- const auto key = GetNodeValue(Key, ctx, block);
- const auto payload = GetNodeValue(Payload, ctx, block);
-
- const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
-
- const auto keyArg = WrapArgumentForWindows(key, ctx, block);
- const auto payloadArg = WrapArgumentForWindows(payload, ctx, block);
-
- const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType(), payloadArg->getType()}, false);
- const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
- CallInst::Create(insPtr, {stateArg, keyArg, payloadArg}, "", block);
-
- BranchInst::Create(more, block);
-
- block = done;
-
- const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
- const auto dict = new LoadInst(ptr, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
+ const auto valueType = Type::getInt128Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ structPtrType // accumulator
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeMapFlowWrapper<TMapAccumulator>::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ BranchInst::Create(over, more, IsFinish(state, block), block);
+
+ block = more;
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(GetYield(context), block);
+
+ const auto choise = SwitchInst::Create(item, plus, 2U, block);
+ choise->addCase(GetFinish(context), done);
+ choise->addCase(GetYield(context), over);
+
+ block = plus;
+
+ codegenItemArg->CreateSetValue(ctx, block, item);
+ const auto key = GetNodeValue(Key, ctx, block);
+ const auto payload = GetNodeValue(Payload, ctx, block);
+
+ const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
+
+ const auto keyArg = WrapArgumentForWindows(key, ctx, block);
+ const auto payloadArg = WrapArgumentForWindows(payload, ctx, block);
+
+ const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType(), payloadArg->getType()}, false);
+ const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
+ CallInst::Create(insPtr, {stateArg, keyArg, payloadArg}, "", block);
+
+ BranchInst::Create(more, block);
+
+ block = done;
+
+ const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
+ const auto dict = new LoadInst(ptr, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
}
- new StoreInst(item, statePtr, block);
- BranchInst::Create(over, block);
-
- block = over;
- return result;
+ new StoreInst(item, statePtr, block);
+ BranchInst::Create(over, block);
+
+ block = over;
+ return result;
}
#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TState>(TMapAccumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
- }
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TState>(TMapAccumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
+ }
void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->Own(flow, Item);
- this->DependsOn(flow, Key);
- this->DependsOn(flow, Payload);
- }
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->Own(flow, Item);
+ this->DependsOn(flow, Key);
+ this->DependsOn(flow, Payload);
+ }
}
TType* const KeyType;
@@ -1411,347 +1411,347 @@ private:
bool Encoded;
};
-template <typename TMapAccumulator>
-class TSqueezeMapWideWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeMapWideWrapper<TMapAccumulator>> {
- using TBase = TStatefulFlowCodegeneratorNode<TSqueezeMapWideWrapper<TMapAccumulator>>;
-public:
- class TState : public TComputationValue<TState> {
- using TBase = TComputationValue<TState>;
- public:
- TState(TMemoryUsageInfo* memInfo, TMapAccumulator&& mapAccum)
- : TBase(memInfo), MapAccum(std::move(mapAccum)) {}
-
- NUdf::TUnboxedValuePod Build() {
- return MapAccum.Build().Release();
- }
-
- void Insert(NUdf::TUnboxedValuePod key, NUdf::TUnboxedValuePod value) {
- MapAccum.Add(key, value);
- }
-
- private:
- TMapAccumulator MapAccum;
- };
-
- TSqueezeMapWideWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType,
- IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* key, IComputationNode* payload,
- ui64 itemsCountHint)
- : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
- , KeyType(keyType)
- , PayloadType(payloadType)
- , Flow(flow)
- , Items(std::move(items))
- , Key(key)
- , Payload(payload)
- , ItemsCountHint(itemsCountHint)
- , PasstroughKey(GetPasstroughtMap({Key, Payload}, Items).front())
- , PasstroughPayload(GetPasstroughtMap({Key, Payload}, Items).back())
- , Fields(Items.size(), nullptr)
- {
- GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
- }
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish()) {
- return state;
- } else if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Key == Items[i] || Payload == Items[i] || Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::One:
- statePtr->Insert(Key->GetValue(ctx).Release(), Payload->GetValue(ctx).Release());
- continue;
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- case EFetchResult::Finish: {
- const auto dict = statePtr->Build();
- state = NUdf::TUnboxedValuePod::MakeFinish();
- return dict;
- }
- }
- }
+template <typename TMapAccumulator>
+class TSqueezeMapWideWrapper : public TStatefulFlowCodegeneratorNode<TSqueezeMapWideWrapper<TMapAccumulator>> {
+ using TBase = TStatefulFlowCodegeneratorNode<TSqueezeMapWideWrapper<TMapAccumulator>>;
+public:
+ class TState : public TComputationValue<TState> {
+ using TBase = TComputationValue<TState>;
+ public:
+ TState(TMemoryUsageInfo* memInfo, TMapAccumulator&& mapAccum)
+ : TBase(memInfo), MapAccum(std::move(mapAccum)) {}
+
+ NUdf::TUnboxedValuePod Build() {
+ return MapAccum.Build().Release();
+ }
+
+ void Insert(NUdf::TUnboxedValuePod key, NUdf::TUnboxedValuePod value) {
+ MapAccum.Add(key, value);
+ }
+
+ private:
+ TMapAccumulator MapAccum;
+ };
+
+ TSqueezeMapWideWrapper(TComputationMutables& mutables, TType* keyType, TType* payloadType,
+ IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* key, IComputationNode* payload,
+ ui64 itemsCountHint)
+ : TBase(mutables, flow, EValueRepresentation::Boxed, EValueRepresentation::Any)
+ , KeyType(keyType)
+ , PayloadType(payloadType)
+ , Flow(flow)
+ , Items(std::move(items))
+ , Key(key)
+ , Payload(payload)
+ , ItemsCountHint(itemsCountHint)
+ , PasstroughKey(GetPasstroughtMap({Key, Payload}, Items).front())
+ , PasstroughPayload(GetPasstroughtMap({Key, Payload}, Items).back())
+ , Fields(Items.size(), nullptr)
+ {
+ GetDictionaryKeyTypes(KeyType, KeyTypes, IsTuple, Encoded);
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsFinish()) {
+ return state;
+ } else if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ while (const auto statePtr = static_cast<TState*>(state.AsBoxed().Get())) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Key == Items[i] || Payload == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::One:
+ statePtr->Insert(Key->GetValue(ctx).Release(), Payload->GetValue(ctx).Release());
+ continue;
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ case EFetchResult::Finish: {
+ const auto dict = statePtr->Build();
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ return dict;
+ }
+ }
+ }
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- structPtrType // accumulator
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
-
- BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeMapWideWrapper<TMapAccumulator>::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
-
- const auto result = PHINode::Create(valueType, 3U, "result", over);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
-
- result->addIncoming(GetFinish(context), block);
-
- BranchInst::Create(over, more, IsFinish(state, block), block);
-
- block = more;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- result->addIncoming(GetYield(context), block);
-
- const auto action = SwitchInst::Create(getres.first, plus, 2U, block);
- action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Finish)), done);
- action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Yield)), over);
-
- block = plus;
-
- if (!(PasstroughKey && PasstroughPayload)) {
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ structPtrType // accumulator
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+
+ BranchInst::Create(make, main, IsInvalid(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TSqueezeMapWideWrapper<TMapAccumulator>::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto plus = BasicBlock::Create(context, "plus", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, 3U, "result", over);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+
+ result->addIncoming(GetFinish(context), block);
+
+ BranchInst::Create(over, more, IsFinish(state, block), block);
+
+ block = more;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ result->addIncoming(GetYield(context), block);
+
+ const auto action = SwitchInst::Create(getres.first, plus, 2U, block);
+ action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Finish)), done);
+ action->addCase(ConstantInt::get(Type::getInt32Ty(context), i32(EFetchResult::Yield)), over);
+
+ block = plus;
+
+ if (!(PasstroughKey && PasstroughPayload)) {
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
- }
-
- const auto key = PasstroughKey ? getres.second[*PasstroughKey](ctx, block) : GetNodeValue(Key, ctx, block);
- const auto payload = PasstroughPayload ? getres.second[*PasstroughPayload](ctx, block) : GetNodeValue(Payload, ctx, block);
-
- const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
-
- const auto keyArg = WrapArgumentForWindows(key, ctx, block);
- const auto payloadArg = WrapArgumentForWindows(payload, ctx, block);
-
- const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType(), payloadArg->getType()}, false);
- const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
- CallInst::Create(insPtr, {stateArg, keyArg, payloadArg}, "", block);
-
- BranchInst::Create(more, block);
-
- block = done;
-
- const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- } else {
- const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
- CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
- const auto dict = new LoadInst(ptr, "dict", block);
- UnRefBoxed(state, ctx, block);
- result->addIncoming(dict, block);
- }
-
- new StoreInst(GetFinish(context), statePtr, block);
- BranchInst::Create(over, block);
-
- block = over;
- return result;
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
- state = ctx.HolderFactory.Create<TState>(TMapAccumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TSqueezeMapWideWrapper::Own, flow, std::placeholders::_1));
- this->DependsOn(flow, Key);
- this->DependsOn(flow, Payload);
- }
- }
-
- TType* const KeyType;
- TType* PayloadType;
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const Key;
- IComputationNode* const Payload;
- const ui64 ItemsCountHint;
- TKeyTypes KeyTypes;
- bool IsTuple;
- bool Encoded;
-
- const std::optional<size_t> PasstroughKey;
- const std::optional<size_t> PasstroughPayload;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-template <typename TAccumulator>
+ }
+
+ const auto key = PasstroughKey ? getres.second[*PasstroughKey](ctx, block) : GetNodeValue(Key, ctx, block);
+ const auto payload = PasstroughPayload ? getres.second[*PasstroughPayload](ctx, block) : GetNodeValue(Payload, ctx, block);
+
+ const auto insert = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Insert));
+
+ const auto keyArg = WrapArgumentForWindows(key, ctx, block);
+ const auto payloadArg = WrapArgumentForWindows(payload, ctx, block);
+
+ const auto insType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), keyArg->getType(), payloadArg->getType()}, false);
+ const auto insPtr = CastInst::Create(Instruction::IntToPtr, insert, PointerType::getUnqual(insType), "insert", block);
+ CallInst::Create(insPtr, {stateArg, keyArg, payloadArg}, "", block);
+
+ BranchInst::Create(more, block);
+
+ block = done;
+
+ const auto build = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Build));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {stateArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ const auto dict = CallInst::Create(funcPtr, {stateArg}, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ } else {
+ const auto ptr = new AllocaInst(valueType, 0U, "ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), ptr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, build, PointerType::getUnqual(funType), "build", block);
+ CallInst::Create(funcPtr, {stateArg, ptr}, "", block);
+ const auto dict = new LoadInst(ptr, "dict", block);
+ UnRefBoxed(state, ctx, block);
+ result->addIncoming(dict, block);
+ }
+
+ new StoreInst(GetFinish(context), statePtr, block);
+ BranchInst::Create(over, block);
+
+ block = over;
+ return result;
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+ state = ctx.HolderFactory.Create<TState>(TMapAccumulator(KeyType, PayloadType, KeyTypes, IsTuple, Encoded, ctx, ItemsCountHint));
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TSqueezeMapWideWrapper::Own, flow, std::placeholders::_1));
+ this->DependsOn(flow, Key);
+ this->DependsOn(flow, Payload);
+ }
+ }
+
+ TType* const KeyType;
+ TType* PayloadType;
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const Key;
+ IComputationNode* const Payload;
+ const ui64 ItemsCountHint;
+ TKeyTypes KeyTypes;
+ bool IsTuple;
+ bool Encoded;
+
+ const std::optional<size_t> PasstroughKey;
+ const std::optional<size_t> PasstroughPayload;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+template <typename TAccumulator>
IComputationNode* WrapToSet(TCallable& callable, const TNodeLocator& nodeLocator, TComputationMutables& mutables) {
- const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
- const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
+ const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
+ const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
+
+ const auto flow = LocateNode(nodeLocator, callable, 0U);
+ const auto keySelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 5U);
- const auto flow = LocateNode(nodeLocator, callable, 0U);
- const auto keySelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 5U);
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ const auto width = callable.GetInputsCount() - 6U;
+ TComputationExternalNodePtrVector args(width, nullptr);
+ auto index = 0U;
+ std::generate_n(args.begin(), width, [&](){ return LocateExternalNode(nodeLocator, callable, ++index); });
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- const auto width = callable.GetInputsCount() - 6U;
- TComputationExternalNodePtrVector args(width, nullptr);
- auto index = 0U;
- std::generate_n(args.begin(), width, [&](){ return LocateExternalNode(nodeLocator, callable, ++index); });
+ return new TSqueezeSetWideWrapper<TAccumulator>(mutables, keyType, wide, std::move(args), keySelector, itemsCountHint);
+ }
- return new TSqueezeSetWideWrapper<TAccumulator>(mutables, keyType, wide, std::move(args), keySelector, itemsCountHint);
- }
-
- const auto itemArg = LocateExternalNode(nodeLocator, callable, 1U);
- const auto type = callable.GetInput(0U).GetStaticType();
+ const auto itemArg = LocateExternalNode(nodeLocator, callable, 1U);
+ const auto type = callable.GetInput(0U).GetStaticType();
if (type->IsList()) {
- return new TSetWrapper<TAccumulator, false>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TSetWrapper<TAccumulator, false>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
}
if (type->IsFlow()) {
- return new TSqueezeSetFlowWrapper<TAccumulator>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TSqueezeSetFlowWrapper<TAccumulator>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
}
if (type->IsStream()) {
- return new TSetWrapper<TAccumulator, true>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TSetWrapper<TAccumulator, true>(mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
}
THROW yexception() << "Expected list, flow or stream.";
-}
-
-template <typename TAccumulator>
+}
+
+template <typename TAccumulator>
IComputationNode* WrapToMap(TCallable& callable, const TNodeLocator& nodeLocator, TComputationMutables& mutables) {
- const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
- const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
-
- const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
-
- const auto flow = LocateNode(nodeLocator, callable, 0U);
- const auto keySelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 5U);
- const auto payloadSelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 4U);
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- const auto width = callable.GetInputsCount() - 6U;
- TComputationExternalNodePtrVector args(width, nullptr);
- auto index = 0U;
- std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(nodeLocator, callable, ++index); });
-
- return new TSqueezeMapWideWrapper<TAccumulator>(mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
- }
-
- const auto itemArg = LocateExternalNode(nodeLocator, callable, 1U);
- const auto type = callable.GetInput(0U).GetStaticType();
-
+ const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
+ const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
+
+ const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
+
+ const auto flow = LocateNode(nodeLocator, callable, 0U);
+ const auto keySelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 5U);
+ const auto payloadSelector = LocateNode(nodeLocator, callable, callable.GetInputsCount() - 4U);
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ const auto width = callable.GetInputsCount() - 6U;
+ TComputationExternalNodePtrVector args(width, nullptr);
+ auto index = 0U;
+ std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(nodeLocator, callable, ++index); });
+
+ return new TSqueezeMapWideWrapper<TAccumulator>(mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
+ }
+
+ const auto itemArg = LocateExternalNode(nodeLocator, callable, 1U);
+ const auto type = callable.GetInput(0U).GetStaticType();
+
if (type->IsList()) {
- return new TMapWrapper<TAccumulator, false>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TMapWrapper<TAccumulator, false>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsFlow()) {
- return new TSqueezeMapFlowWrapper<TAccumulator>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TSqueezeMapFlowWrapper<TAccumulator>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsStream()) {
- return new TMapWrapper<TAccumulator, true>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TMapWrapper<TAccumulator, true>(mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
THROW yexception() << "Expected list, flow or stream.";
-}
-
+}
+
template <bool IsList>
IComputationNode* WrapToSortedDictInternal(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 6U, "Expected six or more args.");
-
- const auto type = callable.GetInput(0U).GetStaticType();
+ MKQL_ENSURE(callable.GetInputsCount() >= 6U, "Expected six or more args.");
+
+ const auto type = callable.GetInput(0U).GetStaticType();
if constexpr (IsList) {
MKQL_ENSURE(type->IsList(), "Expected list.");
} else {
MKQL_ENSURE(type->IsFlow() || type->IsStream(), "Expected flow or stream.");
}
- const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
- const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
-
- const auto multiData = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 3U));
- const bool isMulti = multiData->AsValue().Get<bool>();
- const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- const auto keySelector = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() -5U);
- const auto payloadSelector = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() -4U);
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- const auto width = callable.GetInputsCount() - 6U;
- TComputationExternalNodePtrVector args(width, nullptr);
- auto index = 0U;
- std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- if (!isMulti && payloadType->IsVoid()) {
- return new TSqueezeSetWideWrapper<TSortedSetAccumulator>(ctx.Mutables, keyType, wide, std::move(args), keySelector, itemsCountHint);
- } else if (isMulti) {
- return new TSqueezeMapWideWrapper<TSortedMapAccumulator<true>>(ctx.Mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
- } else {
- return new TSqueezeMapWideWrapper<TSortedMapAccumulator<false>>(ctx.Mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
- }
- }
-
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
- if (!isMulti && payloadType->IsVoid()) {
+ const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
+ const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
+
+ const auto multiData = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 3U));
+ const bool isMulti = multiData->AsValue().Get<bool>();
+ const auto itemsCountHint = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 1U))->AsValue().Get<ui64>();
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ const auto keySelector = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() -5U);
+ const auto payloadSelector = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() -4U);
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ const auto width = callable.GetInputsCount() - 6U;
+ TComputationExternalNodePtrVector args(width, nullptr);
+ auto index = 0U;
+ std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ if (!isMulti && payloadType->IsVoid()) {
+ return new TSqueezeSetWideWrapper<TSortedSetAccumulator>(ctx.Mutables, keyType, wide, std::move(args), keySelector, itemsCountHint);
+ } else if (isMulti) {
+ return new TSqueezeMapWideWrapper<TSortedMapAccumulator<true>>(ctx.Mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
+ } else {
+ return new TSqueezeMapWideWrapper<TSortedMapAccumulator<false>>(ctx.Mutables, keyType, payloadType, wide, std::move(args), keySelector, payloadSelector, itemsCountHint);
+ }
+ }
+
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
+ if (!isMulti && payloadType->IsVoid()) {
+ if (type->IsList()) {
+ return new TSetWrapper<TSortedSetAccumulator, false>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ }
+ if (type->IsFlow()) {
+ return new TSqueezeSetFlowWrapper<TSortedSetAccumulator>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ }
+ if (type->IsStream()) {
+ return new TSetWrapper<TSortedSetAccumulator, true>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ }
+ } else if (isMulti) {
if (type->IsList()) {
- return new TSetWrapper<TSortedSetAccumulator, false>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TMapWrapper<TSortedMapAccumulator<true>, false>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsFlow()) {
- return new TSqueezeSetFlowWrapper<TSortedSetAccumulator>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TSqueezeMapFlowWrapper<TSortedMapAccumulator<true>>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsStream()) {
- return new TSetWrapper<TSortedSetAccumulator, true>(ctx.Mutables, keyType, flow, itemArg, keySelector, itemsCountHint);
+ return new TMapWrapper<TSortedMapAccumulator<true>, true>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
- } else if (isMulti) {
- if (type->IsList()) {
- return new TMapWrapper<TSortedMapAccumulator<true>, false>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
- }
- if (type->IsFlow()) {
- return new TSqueezeMapFlowWrapper<TSortedMapAccumulator<true>>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
- }
- if (type->IsStream()) {
- return new TMapWrapper<TSortedMapAccumulator<true>, true>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
- }
} else {
if (type->IsList()) {
- return new TMapWrapper<TSortedMapAccumulator<false>, false>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TMapWrapper<TSortedMapAccumulator<false>, false>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsFlow()) {
- return new TSqueezeMapFlowWrapper<TSortedMapAccumulator<false>>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TSqueezeMapFlowWrapper<TSortedMapAccumulator<false>>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
if (type->IsStream()) {
- return new TMapWrapper<TSortedMapAccumulator<false>, true>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
+ return new TMapWrapper<TSortedMapAccumulator<false>, true>(ctx.Mutables, keyType, payloadType, flow, itemArg, keySelector, payloadSelector, itemsCountHint);
}
}
@@ -1760,27 +1760,27 @@ IComputationNode* WrapToSortedDictInternal(TCallable& callable, const TComputati
template <bool IsList>
IComputationNode* WrapToHashedDictInternal(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 6U, "Expected six or more args.");
+ MKQL_ENSURE(callable.GetInputsCount() >= 6U, "Expected six or more args.");
- const auto type = callable.GetInput(0U).GetStaticType();
+ const auto type = callable.GetInput(0U).GetStaticType();
if constexpr (IsList) {
MKQL_ENSURE(type->IsList(), "Expected list.");
} else {
MKQL_ENSURE(type->IsFlow() || type->IsStream(), "Expected flow or stream.");
}
- const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
- const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
- const bool multi = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 3U))->AsValue().Get<bool>();
- const bool isCompact = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 2U))->AsValue().Get<bool>();
- const auto payloadSelectorNode = callable.GetInput(callable.GetInputsCount() - 4U);
+ const auto keyType = callable.GetInput(callable.GetInputsCount() - 5U).GetStaticType();
+ const auto payloadType = callable.GetInput(callable.GetInputsCount() - 4U).GetStaticType();
+ const bool multi = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 3U))->AsValue().Get<bool>();
+ const bool isCompact = AS_VALUE(TDataLiteral, callable.GetInput(callable.GetInputsCount() - 2U))->AsValue().Get<bool>();
+ const auto payloadSelectorNode = callable.GetInput(callable.GetInputsCount() - 4U);
- if (!multi && payloadType->IsVoid()) {
+ if (!multi && payloadType->IsVoid()) {
if (isCompact) {
if (keyType->IsData()) {
#define USE_HASHED_SINGLE_FIXED_COMPACT_SET(xType, xLayoutType) \
case NUdf::TDataType<xType>::Id: \
- return WrapToSet< \
+ return WrapToSet< \
THashedSingleFixedCompactSetAccumulator<xLayoutType>>(callable, ctx.NodeLocator, ctx.Mutables);
switch (AS_TYPE(TDataType, keyType)->GetSchemeType()) {
@@ -1795,7 +1795,7 @@ IComputationNode* WrapToHashedDictInternal(TCallable& callable, const TComputati
if (keyType->IsData()) {
#define USE_HASHED_SINGLE_FIXED_SET(xType, xLayoutType) \
case NUdf::TDataType<xType>::Id: \
- return WrapToSet< \
+ return WrapToSet< \
THashedSingleFixedSetAccumulator<xLayoutType>>(callable, ctx.NodeLocator, ctx.Mutables);
switch (AS_TYPE(TDataType, keyType)->GetSchemeType()) {
@@ -1811,10 +1811,10 @@ IComputationNode* WrapToHashedDictInternal(TCallable& callable, const TComputati
#define USE_HASHED_SINGLE_FIXED_COMPACT_MAP(xType, xLayoutType) \
case NUdf::TDataType<xType>::Id: \
if (multi) { \
- return WrapToMap< \
+ return WrapToMap< \
THashedSingleFixedCompactMapAccumulator<xLayoutType, true>>(callable, ctx.NodeLocator, ctx.Mutables); \
} else { \
- return WrapToMap< \
+ return WrapToMap< \
THashedSingleFixedCompactMapAccumulator<xLayoutType, false>>(callable, ctx.NodeLocator, ctx.Mutables); \
}
@@ -1835,10 +1835,10 @@ IComputationNode* WrapToHashedDictInternal(TCallable& callable, const TComputati
#define USE_HASHED_SINGLE_FIXED_MAP(xType, xLayoutType) \
case NUdf::TDataType<xType>::Id: \
if (multi) { \
- return WrapToMap< \
+ return WrapToMap< \
THashedSingleFixedMultiMapAccumulator<xLayoutType>>(callable, ctx.NodeLocator, ctx.Mutables); \
} else { \
- return WrapToMap< \
+ return WrapToMap< \
THashedSingleFixedMapAccumulator<xLayoutType>>(callable, ctx.NodeLocator, ctx.Mutables); \
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_toindexdict.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_toindexdict.cpp
index b1294352d0..5e78b4e100 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_toindexdict.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_toindexdict.cpp
@@ -6,63 +6,63 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TToIndexDictWrapper : public TMutableCodegeneratorNode<TToIndexDictWrapper> {
- typedef TMutableCodegeneratorNode<TToIndexDictWrapper> TBaseComputation;
+namespace {
+
+class TToIndexDictWrapper : public TMutableCodegeneratorNode<TToIndexDictWrapper> {
+ typedef TMutableCodegeneratorNode<TToIndexDictWrapper> TBaseComputation;
public:
TToIndexDictWrapper(TComputationMutables& mutables, IComputationNode* list)
- : TBaseComputation(mutables, list->GetRepresentation())
+ : TBaseComputation(mutables, list->GetRepresentation())
, List(list)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.ToIndexDict(ctx.Builder, List->GetValue(ctx).Release());
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.ToIndexDict(ctx.Builder, List->GetValue(ctx).Release());
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto indexType = Type::getInt32Ty(context);
-
- const auto first = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "first", block);
- const auto fourth = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "fourth", block);
-
- const auto factory = new LoadInst(first, "factory", block);
- const auto builder = new LoadInst(fourth, "builder", block);
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ToIndexDict));
-
- const auto list = GetNodeValue(List, ctx, block);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto result = CallInst::Create(funcPtr, {factory, builder, list}, "result", block);
- return result;
- } else {
- const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
- new StoreInst(list, retPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr}, "", block);
- const auto result = new LoadInst(retPtr, "result", block);
- return result;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(List);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto indexType = Type::getInt32Ty(context);
+
+ const auto first = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "first", block);
+ const auto fourth = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "fourth", block);
+
+ const auto factory = new LoadInst(first, "factory", block);
+ const auto builder = new LoadInst(fourth, "builder", block);
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::ToIndexDict));
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType(), {factory->getType(), builder->getType(), list->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto result = CallInst::Create(funcPtr, {factory, builder, list}, "result", block);
+ return result;
+ } else {
+ const auto retPtr = new AllocaInst(list->getType(), 0U, "ret_ptr", block);
+ new StoreInst(list, retPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType(), builder->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr, builder, retPtr}, "", block);
+ const auto result = new LoadInst(retPtr, "result", block);
+ return result;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(List);
}
IComputationNode* const List;
};
-}
-
+}
+
IComputationNode* WrapToIndexDict(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
return new TToIndexDictWrapper(ctx.Mutables, LocateNode(ctx.NodeLocator, callable, 0));
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.cpp
index 872832fc94..c41f8c6f0e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.cpp
@@ -5,232 +5,232 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool IsOptional>
-class THeadWrapper : public TMutableCodegeneratorPtrNode<THeadWrapper<IsOptional>> {
- typedef TMutableCodegeneratorPtrNode<THeadWrapper<IsOptional>> TBaseComputation;
+namespace {
+
+template <bool IsOptional>
+class THeadWrapper : public TMutableCodegeneratorPtrNode<THeadWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorPtrNode<THeadWrapper<IsOptional>> TBaseComputation;
public:
- THeadWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list)
- : TBaseComputation(mutables, kind), List(list)
- {}
+ THeadWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list)
+ : TBaseComputation(mutables, kind), List(list)
+ {}
NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- const auto& value = List->GetValue(ctx);
- if (const auto ptr = value.GetElements()) {
- if (value.GetListLength() > 0ULL) {
- return NUdf::TUnboxedValuePod(*ptr).MakeOptionalIf<IsOptional>();
- }
- } else if (const auto iter = value.GetListIterator()) {
- NUdf::TUnboxedValue result;
- if (iter.Next(result)) {
- return result.Release().MakeOptionalIf<IsOptional>();
- }
- }
-
- return NUdf::TUnboxedValue();
+ const auto& value = List->GetValue(ctx);
+ if (const auto ptr = value.GetElements()) {
+ if (value.GetListLength() > 0ULL) {
+ return NUdf::TUnboxedValuePod(*ptr).MakeOptionalIf<IsOptional>();
+ }
+ } else if (const auto iter = value.GetListIterator()) {
+ NUdf::TUnboxedValue result;
+ if (iter.Next(result)) {
+ return result.Release().MakeOptionalIf<IsOptional>();
+ }
+ }
+
+ return NUdf::TUnboxedValue();
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* result, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto many = BasicBlock::Create(context, "many", ctx.Func);
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = IsOptional ? BasicBlock::Create(context, "good", ctx.Func) : done;
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0ULL), "test", block);
- BranchInst::Create(many, none, test, block);
-
- block = many;
- const auto item = new LoadInst(elements, "item", block);
- ValueAddRef(this->GetRepresentation(), item, ctx, block);
- new StoreInst(IsOptional ? MakeOptional(context, item, block) : item, result, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = slow;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(result, list, ctx.Codegen, block);
-
- const auto iter = new LoadInst(result, "iter", block);
- new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
- UnRefBoxed(iter, ctx, block);
-
- BranchInst::Create(good, none, status, block);
-
- if (IsOptional) {
- block = good;
-
- const auto item = new LoadInst(result, "item", block);
- new StoreInst(MakeOptional(context, item, block), result, block);
- BranchInst::Create(done, block);
- }
- }
-
- block = none;
- new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
- BranchInst::Create(done, block);
-
- block = done;
- if (List->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
- }
-
- IComputationNode* const List;
-};
-
-template <bool IsOptional>
-class TLastWrapper : public TMutableCodegeneratorPtrNode<TLastWrapper<IsOptional>> {
- typedef TMutableCodegeneratorPtrNode<TLastWrapper<IsOptional>> TBaseComputation;
-public:
- TLastWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list)
- : TBaseComputation(mutables, kind), List(list)
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- const auto& value = List->GetValue(ctx);
- if (const auto ptr = value.GetElements()) {
- if (const auto size = value.GetListLength()) {
- return NUdf::TUnboxedValuePod(ptr[size - 1U]).MakeOptionalIf<IsOptional>();
- }
- } else if (const auto iter = value.GetListIterator()) {
- NUdf::TUnboxedValue result;
- if (iter.Next(result)) {
- while (iter.Next(result)) continue;
- return result.Release().MakeOptionalIf<IsOptional>();
- }
- }
-
- return NUdf::TUnboxedValue();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* result, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
-
- const auto list = GetNodeValue(List, ctx, block);
-
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto many = BasicBlock::Create(context, "many", ctx.Func);
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(slow, fast, null, block);
- {
- block = fast;
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0ULL), "test", block);
- BranchInst::Create(many, none, test, block);
-
- block = many;
- const auto index = BinaryOperator::CreateSub(size, ConstantInt::get(size->getType(), 1), "index", block);
- const auto last = GetElementPtrInst::CreateInBounds(elements, {index}, "last", block);
- const auto item = new LoadInst(last, "item", block);
- ValueAddRef(this->GetRepresentation(), item, ctx, block);
- new StoreInst(IsOptional ? MakeOptional(context, item, block) : item, result, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = slow;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(result, list, ctx.Codegen, block);
-
- const auto iter = new LoadInst(result, "iter", block);
- new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
-
- const auto first = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
- BranchInst::Create(loop, nope, first, block);
-
- block = nope;
-
- UnRefBoxed(iter, ctx, block);
- BranchInst::Create(none, block);
-
- block = loop;
-
- const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
- BranchInst::Create(loop, good, status, block);
-
- block = good;
-
- UnRefBoxed(iter, ctx, block);
-
- if (IsOptional) {
- const auto item = new LoadInst(result, "item", block);
- new StoreInst(MakeOptional(context, item, block), result, block);
- }
-
- BranchInst::Create(done, block);
- }
-
- block = none;
- new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
- BranchInst::Create(done, block);
-
- block = done;
- if (List->IsTemporaryValue())
- CleanupBoxed(list, ctx, block);
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(List);
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* result, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto many = BasicBlock::Create(context, "many", ctx.Func);
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = IsOptional ? BasicBlock::Create(context, "good", ctx.Func) : done;
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0ULL), "test", block);
+ BranchInst::Create(many, none, test, block);
+
+ block = many;
+ const auto item = new LoadInst(elements, "item", block);
+ ValueAddRef(this->GetRepresentation(), item, ctx, block);
+ new StoreInst(IsOptional ? MakeOptional(context, item, block) : item, result, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = slow;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(result, list, ctx.Codegen, block);
+
+ const auto iter = new LoadInst(result, "iter", block);
+ new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
+ UnRefBoxed(iter, ctx, block);
+
+ BranchInst::Create(good, none, status, block);
+
+ if (IsOptional) {
+ block = good;
+
+ const auto item = new LoadInst(result, "item", block);
+ new StoreInst(MakeOptional(context, item, block), result, block);
+ BranchInst::Create(done, block);
+ }
+ }
+
+ block = none;
+ new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ if (List->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
}
IComputationNode* const List;
};
-}
-
-IComputationNode* WrapHead(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+template <bool IsOptional>
+class TLastWrapper : public TMutableCodegeneratorPtrNode<TLastWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorPtrNode<TLastWrapper<IsOptional>> TBaseComputation;
+public:
+ TLastWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* list)
+ : TBaseComputation(mutables, kind), List(list)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ const auto& value = List->GetValue(ctx);
+ if (const auto ptr = value.GetElements()) {
+ if (const auto size = value.GetListLength()) {
+ return NUdf::TUnboxedValuePod(ptr[size - 1U]).MakeOptionalIf<IsOptional>();
+ }
+ } else if (const auto iter = value.GetListIterator()) {
+ NUdf::TUnboxedValue result;
+ if (iter.Next(result)) {
+ while (iter.Next(result)) continue;
+ return result.Release().MakeOptionalIf<IsOptional>();
+ }
+ }
+
+ return NUdf::TUnboxedValue();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* result, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+
+ const auto list = GetNodeValue(List, ctx, block);
+
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(ptrType, list, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elements, ConstantPointerNull::get(ptrType), "null", block);
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto many = BasicBlock::Create(context, "many", ctx.Func);
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(slow, fast, null, block);
+ {
+ block = fast;
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, size, ConstantInt::get(size->getType(), 0ULL), "test", block);
+ BranchInst::Create(many, none, test, block);
+
+ block = many;
+ const auto index = BinaryOperator::CreateSub(size, ConstantInt::get(size->getType(), 1), "index", block);
+ const auto last = GetElementPtrInst::CreateInBounds(elements, {index}, "last", block);
+ const auto item = new LoadInst(last, "item", block);
+ ValueAddRef(this->GetRepresentation(), item, ctx, block);
+ new StoreInst(IsOptional ? MakeOptional(context, item, block) : item, result, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = slow;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListIterator>(result, list, ctx.Codegen, block);
+
+ const auto iter = new LoadInst(result, "iter", block);
+ new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
+
+ const auto first = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
+ BranchInst::Create(loop, nope, first, block);
+
+ block = nope;
+
+ UnRefBoxed(iter, ctx, block);
+ BranchInst::Create(none, block);
+
+ block = loop;
+
+ const auto status = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(Type::getInt1Ty(context), iter, ctx.Codegen, block, result);
+ BranchInst::Create(loop, good, status, block);
+
+ block = good;
+
+ UnRefBoxed(iter, ctx, block);
+
+ if (IsOptional) {
+ const auto item = new LoadInst(result, "item", block);
+ new StoreInst(MakeOptional(context, item, block), result, block);
+ }
+
+ BranchInst::Create(done, block);
+ }
+
+ block = none;
+ new StoreInst(ConstantInt::get(valueType, 0ULL), result, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ if (List->IsTemporaryValue())
+ CleanupBoxed(list, ctx, block);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(List);
+ }
+
+ IComputationNode* const List;
+};
+
+}
+
+IComputationNode* WrapHead(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
+ if (AS_TYPE(TOptionalType, callable.GetType()->GetReturnType())->IsOptional()) {
+ return new THeadWrapper<true>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
+ } else {
+ return new THeadWrapper<false>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
+ }
+}
+
+IComputationNode* WrapLast(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
- if (AS_TYPE(TOptionalType, callable.GetType()->GetReturnType())->IsOptional()) {
- return new THeadWrapper<true>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
- } else {
- return new THeadWrapper<false>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
- }
-}
-
-IComputationNode* WrapLast(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
- if (AS_TYPE(TOptionalType, callable.GetType()->GetReturnType())->IsOptional()) {
- return new TLastWrapper<true>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
- } else {
- return new TLastWrapper<false>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
- }
+ if (AS_TYPE(TOptionalType, callable.GetType()->GetReturnType())->IsOptional()) {
+ return new TLastWrapper<true>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
+ } else {
+ return new TLastWrapper<false>(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), LocateNode(ctx.NodeLocator, callable, 0));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.h b/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.h
index da9b9a8c13..df81fc10c4 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_tooptional.h
@@ -4,8 +4,8 @@
namespace NKikimr {
namespace NMiniKQL {
-IComputationNode* WrapHead(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapLast(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapHead(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapLast(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_tostring.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_tostring.cpp
index 0785016278..66e6c73c87 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_tostring.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_tostring.cpp
@@ -11,276 +11,276 @@
#include <ydb/library/yql/public/udf/udf_terminator.h>
#ifndef MKQL_DISABLE_CODEGEN
-extern "C" NYql::NUdf::TUnboxedValuePod DataToString(NYql::NUdf::TUnboxedValuePod data, NYql::NUdf::EDataSlot slot) {
- return NKikimr::NMiniKQL::ValueToString(slot, data);
-}
-
-extern "C" NYql::NUdf::TUnboxedValuePod DecimalToString(NYql::NDecimal::TInt128 decimal, ui8 precision, ui8 scale) {
- if (const auto str = NYql::NDecimal::ToString(decimal, precision, scale)) {
- return NKikimr::NMiniKQL::MakeString(NYql::NUdf::TStringRef(str, std::strlen(str)));
- }
- return NYql::NUdf::TUnboxedValuePod();
-}
+extern "C" NYql::NUdf::TUnboxedValuePod DataToString(NYql::NUdf::TUnboxedValuePod data, NYql::NUdf::EDataSlot slot) {
+ return NKikimr::NMiniKQL::ValueToString(slot, data);
+}
+
+extern "C" NYql::NUdf::TUnboxedValuePod DecimalToString(NYql::NDecimal::TInt128 decimal, ui8 precision, ui8 scale) {
+ if (const auto str = NYql::NDecimal::ToString(decimal, precision, scale)) {
+ return NKikimr::NMiniKQL::MakeString(NYql::NUdf::TStringRef(str, std::strlen(str)));
+ }
+ return NYql::NUdf::TUnboxedValuePod();
+}
#endif
-
+
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool IsOptional>
-class TDecimalToStringWrapper : public TMutableCodegeneratorNode<TDecimalToStringWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TDecimalToStringWrapper<IsOptional>> TBaseComputation;
+class TDecimalToStringWrapper : public TMutableCodegeneratorNode<TDecimalToStringWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TDecimalToStringWrapper<IsOptional>> TBaseComputation;
public:
- TDecimalToStringWrapper(TComputationMutables& mutables, IComputationNode* data, ui8 precision, ui8 scale)
- : TBaseComputation(mutables, EValueRepresentation::String)
+ TDecimalToStringWrapper(TComputationMutables& mutables, IComputationNode* data, ui8 precision, ui8 scale)
+ : TBaseComputation(mutables, EValueRepresentation::String)
, Data(data)
- , Precision(precision)
- , Scale(scale)
+ , Precision(precision)
+ , Scale(scale)
{
- MKQL_ENSURE(precision > 0 && precision <= NYql::NDecimal::MaxPrecision, "Wrong precision.");
- MKQL_ENSURE(scale <= precision, "Wrong scale.");
+ MKQL_ENSURE(precision > 0 && precision <= NYql::NDecimal::MaxPrecision, "Wrong precision.");
+ MKQL_ENSURE(scale <= precision, "Wrong scale.");
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& dataValue = Data->GetValue(ctx);
- if (IsOptional && !dataValue) {
- return NUdf::TUnboxedValuePod();
+ if (IsOptional && !dataValue) {
+ return NUdf::TUnboxedValuePod();
}
-
- if (const auto str = NYql::NDecimal::ToString(dataValue.GetInt128(), Precision, Scale)) {
- return MakeString(NUdf::TStringRef(str, std::strlen(str)));
+
+ if (const auto str = NYql::NDecimal::ToString(dataValue.GetInt128(), Precision, Scale)) {
+ return MakeString(NUdf::TStringRef(str, std::strlen(str)));
}
-
- Throw();
+
+ Throw();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto psType = Type::getInt8Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto name = "DecimalToString";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalToString));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto psType = Type::getInt8Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto name = "DecimalToString";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DecimalToString));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, psType, psType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, psType, psType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, psType, psType }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, psType, psType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto fail = BasicBlock::Create(context, "fail", ctx.Func);
- const auto nice = BasicBlock::Create(context, "nice", ctx.Func);
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto precision = ConstantInt::get(psType, Precision);
- const auto scale = ConstantInt::get(psType, Scale);
- const auto value = GetNodeValue(Data, ctx, block);
-
- Value* result;
- if (IsOptional) {
- const auto call = BasicBlock::Create(context, "call", ctx.Func);
- const auto res = PHINode::Create(valType, 2, "result", nice);
- res->addIncoming(zero, block);
- result = res;
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
- BranchInst::Create(nice, call, check, block);
-
- block = call;
-
- Value* string;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- string = CallInst::Create(func, { GetterForInt128(value, block), precision, scale }, "to_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(GetterForInt128(value, block), retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
- string = new LoadInst(retPtr, "res", block);
- }
-
- res->addIncoming(string, block);
-
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, string, zero, "test", block);
- BranchInst::Create(fail, nice, test, block);
- } else {
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- result = CallInst::Create(func, { GetterForInt128(value, block), precision, scale }, "to_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(GetterForInt128(value, block), retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
- result = new LoadInst(retPtr, "res", block);
- }
-
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, result, zero, "test", block);
- BranchInst::Create(fail, nice, test, block);
- }
-
- block = fail;
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDecimalToStringWrapper::Throw));
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
- CallInst::Create(doFuncPtr, {}, "", block);
- new UnreachableInst(context, block);
-
- block = nice;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
+ }
+
+ const auto fail = BasicBlock::Create(context, "fail", ctx.Func);
+ const auto nice = BasicBlock::Create(context, "nice", ctx.Func);
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto precision = ConstantInt::get(psType, Precision);
+ const auto scale = ConstantInt::get(psType, Scale);
+ const auto value = GetNodeValue(Data, ctx, block);
+
+ Value* result;
+ if (IsOptional) {
+ const auto call = BasicBlock::Create(context, "call", ctx.Func);
+ const auto res = PHINode::Create(valType, 2, "result", nice);
+ res->addIncoming(zero, block);
+ result = res;
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
+ BranchInst::Create(nice, call, check, block);
+
+ block = call;
+
+ Value* string;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ string = CallInst::Create(func, { GetterForInt128(value, block), precision, scale }, "to_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(GetterForInt128(value, block), retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
+ string = new LoadInst(retPtr, "res", block);
+ }
+
+ res->addIncoming(string, block);
+
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, string, zero, "test", block);
+ BranchInst::Create(fail, nice, test, block);
+ } else {
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ result = CallInst::Create(func, { GetterForInt128(value, block), precision, scale }, "to_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(GetterForInt128(value, block), retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, precision, scale }, "", block);
+ result = new LoadInst(retPtr, "res", block);
+ }
+
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, result, zero, "test", block);
+ BranchInst::Create(fail, nice, test, block);
+ }
+
+ block = fail;
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDecimalToStringWrapper::Throw));
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), {}, false)), "thrower", block);
+ CallInst::Create(doFuncPtr, {}, "", block);
+ new UnreachableInst(context, block);
+
+ block = nice;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
+ }
+
+ [[noreturn]] static void Throw() {
+ UdfTerminate("Ivalid Decimal value.");
}
- [[noreturn]] static void Throw() {
- UdfTerminate("Ivalid Decimal value.");
- }
-
IComputationNode* const Data;
- const ui8 Precision, Scale;
+ const ui8 Precision, Scale;
};
-template <bool IsOptional>
-class TToStringWrapper : public TMutableCodegeneratorNode<TToStringWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TToStringWrapper<IsOptional>> TBaseComputation;
-public:
- TToStringWrapper(TComputationMutables& mutables, IComputationNode* data, NUdf::TDataTypeId schemeType)
- : TBaseComputation(mutables, EValueRepresentation::String)
- , Data(data)
- , SchemeType(NUdf::GetDataSlot(schemeType))
- {}
-
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
- const auto& dataValue = Data->GetValue(ctx);
- if (IsOptional && !dataValue) {
- return NUdf::TUnboxedValuePod();
- }
-
- return ValueToString(SchemeType, dataValue);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto slotType = Type::getInt32Ty(context);
- const auto valTypePtr = PointerType::getUnqual(valType);
-
- const auto name = "DataToString";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DataToString));
+template <bool IsOptional>
+class TToStringWrapper : public TMutableCodegeneratorNode<TToStringWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TToStringWrapper<IsOptional>> TBaseComputation;
+public:
+ TToStringWrapper(TComputationMutables& mutables, IComputationNode* data, NUdf::TDataTypeId schemeType)
+ : TBaseComputation(mutables, EValueRepresentation::String)
+ , Data(data)
+ , SchemeType(NUdf::GetDataSlot(schemeType))
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ const auto& dataValue = Data->GetValue(ctx);
+ if (IsOptional && !dataValue) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return ValueToString(SchemeType, dataValue);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto slotType = Type::getInt32Ty(context);
+ const auto valTypePtr = PointerType::getUnqual(valType);
+
+ const auto name = "DataToString";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DataToString));
llvm::Value* func;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto fnType = FunctionType::get(valType, { valType, slotType }, false);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto fnType = FunctionType::get(valType, { valType, slotType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- } else {
- const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, slotType }, false);
+ } else {
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), { valTypePtr, valTypePtr, slotType }, false);
func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- }
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto slot = ConstantInt::get(slotType, static_cast<ui32>(SchemeType));
- const auto value = GetNodeValue(Data, ctx, block);
-
- if (IsOptional) {
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto call = BasicBlock::Create(context, "call", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(zero, block);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
- BranchInst::Create(done, call, check, block);
-
- block = call;
-
- Value* string;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- string = CallInst::Create(func, { value, slot }, "to_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(value, retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, slot }, "", block);
- string = new LoadInst(retPtr, "res", block);
- }
-
- if (Data->IsTemporaryValue())
- ValueCleanup(Data->GetRepresentation(), value, ctx, block);
-
- result->addIncoming(string, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- Value* string;
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- string = CallInst::Create(func, { value, slot }, "to_string", block);
- } else {
- const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
- new StoreInst(value, retPtr, block);
- CallInst::Create(func, { retPtr, retPtr, slot}, "", block);
- string = new LoadInst(retPtr, "res", block);
- }
-
- if (Data->IsTemporaryValue())
- ValueCleanup(Data->GetRepresentation(), value, ctx, block);
-
- return string;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Data);
- }
-
- IComputationNode* const Data;
- const NUdf::EDataSlot SchemeType;
-};
-
-class TAsIsWrapper : public TDecoratorCodegeneratorNode<TAsIsWrapper> {
-using TBaseComputation = TDecoratorCodegeneratorNode<TAsIsWrapper>;
-public:
- TAsIsWrapper(IComputationNode* optional)
- : TBaseComputation(optional)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const { return value; }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*&) const { return value; }
-#endif
-};
-
-}
-
+ }
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto slot = ConstantInt::get(slotType, static_cast<ui32>(SchemeType));
+ const auto value = GetNodeValue(Data, ctx, block);
+
+ if (IsOptional) {
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto call = BasicBlock::Create(context, "call", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, zero, "check", block);
+ BranchInst::Create(done, call, check, block);
+
+ block = call;
+
+ Value* string;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ string = CallInst::Create(func, { value, slot }, "to_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(value, retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, slot }, "", block);
+ string = new LoadInst(retPtr, "res", block);
+ }
+
+ if (Data->IsTemporaryValue())
+ ValueCleanup(Data->GetRepresentation(), value, ctx, block);
+
+ result->addIncoming(string, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ Value* string;
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ string = CallInst::Create(func, { value, slot }, "to_string", block);
+ } else {
+ const auto retPtr = new AllocaInst(valType, 0U, "ret_ptr", block);
+ new StoreInst(value, retPtr, block);
+ CallInst::Create(func, { retPtr, retPtr, slot}, "", block);
+ string = new LoadInst(retPtr, "res", block);
+ }
+
+ if (Data->IsTemporaryValue())
+ ValueCleanup(Data->GetRepresentation(), value, ctx, block);
+
+ return string;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Data);
+ }
+
+ IComputationNode* const Data;
+ const NUdf::EDataSlot SchemeType;
+};
+
+class TAsIsWrapper : public TDecoratorCodegeneratorNode<TAsIsWrapper> {
+using TBaseComputation = TDecoratorCodegeneratorNode<TAsIsWrapper>;
+public:
+ TAsIsWrapper(IComputationNode* optional)
+ : TBaseComputation(optional)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const { return value; }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext&, Value* value, BasicBlock*&) const { return value; }
+#endif
+};
+
+}
+
IComputationNode* WrapToString(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arg");
bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
- const auto schemeType = dataType->GetSchemeType();
-
- const auto data = LocateNode(ctx.NodeLocator, callable, 0);
- if (NUdf::EDataTypeFeatures::StringType & NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Features) {
- return new TAsIsWrapper(data);
- } else if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- const auto& params = static_cast<TDataDecimalType*>(dataType)->GetParams();
- if (isOptional) {
- return new TDecimalToStringWrapper<true>(ctx.Mutables, data, params.first, params.second);
- } else {
- return new TDecimalToStringWrapper<false>(ctx.Mutables, data, params.first, params.second);
- }
+ const auto dataType = UnpackOptionalData(callable.GetInput(0), isOptional);
+ const auto schemeType = dataType->GetSchemeType();
+
+ const auto data = LocateNode(ctx.NodeLocator, callable, 0);
+ if (NUdf::EDataTypeFeatures::StringType & NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Features) {
+ return new TAsIsWrapper(data);
+ } else if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
+ const auto& params = static_cast<TDataDecimalType*>(dataType)->GetParams();
+ if (isOptional) {
+ return new TDecimalToStringWrapper<true>(ctx.Mutables, data, params.first, params.second);
+ } else {
+ return new TDecimalToStringWrapper<false>(ctx.Mutables, data, params.first, params.second);
+ }
} else {
- if (isOptional) {
- return new TToStringWrapper<true>(ctx.Mutables, data, schemeType);
- } else {
- return new TToStringWrapper<false>(ctx.Mutables, data, schemeType);
- }
+ if (isOptional) {
+ return new TToStringWrapper<true>(ctx.Mutables, data, schemeType);
+ } else {
+ return new TToStringWrapper<false>(ctx.Mutables, data, schemeType);
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_udf.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_udf.cpp
index c4cb733db4..893cb08456 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_udf.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_udf.cpp
@@ -12,8 +12,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
class TUdfRunCodegeneratorNode: public TUnboxedImmutableRunCodegeneratorNode {
public:
TUdfRunCodegeneratorNode(TMemoryUsageInfo* memInfo,
@@ -26,7 +26,7 @@ public:
}
#ifndef MKQL_DISABLE_CODEGEN
- void CreateRun(const TCodegenContext& ctx, BasicBlock*& block, Value* result, Value* args) const final {
+ void CreateRun(const TCodegenContext& ctx, BasicBlock*& block, Value* result, Value* args) const final {
ctx.Codegen->LoadBitCode(ModuleIR, ModuleIRUniqID);
auto& context = ctx.Codegen->GetContext();
@@ -36,7 +36,7 @@ public:
const auto data = ConstantInt::get(Type::getInt64Ty(context), reinterpret_cast<ui64>(UnboxedValue.AsBoxed().Get()));
const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
const auto builder = ctx.GetBuilder();
const auto funType = FunctionType::get(Type::getVoidTy(context), {boxed->getType(), result->getType(), builder->getType(), args->getType()}, false);
@@ -52,113 +52,113 @@ private:
template<class TValidatePolicy, class TValidateMode>
-class TUdfWrapper: public TMutableCodegeneratorPtrNode<TUdfWrapper<TValidatePolicy,TValidateMode>> {
- typedef TMutableCodegeneratorPtrNode<TUdfWrapper<TValidatePolicy,TValidateMode>> TBaseComputation;
+class TUdfWrapper: public TMutableCodegeneratorPtrNode<TUdfWrapper<TValidatePolicy,TValidateMode>> {
+ typedef TMutableCodegeneratorPtrNode<TUdfWrapper<TValidatePolicy,TValidateMode>> TBaseComputation;
public:
TUdfWrapper(
TComputationMutables& mutables,
- IComputationNode* functionImpl,
+ IComputationNode* functionImpl,
TString&& functionName,
IComputationNode* runConfigNode,
const TCallableType* callableType)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
- , FunctionImpl(functionImpl)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ , FunctionImpl(functionImpl)
, FunctionName(std::move(functionName))
, RunConfigNode(runConfigNode)
, CallableType(callableType)
{
- this->Stateless = false;
+ this->Stateless = false;
}
- NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
const auto runConfig = RunConfigNode->GetValue(ctx);
- auto callable = FunctionImpl->GetValue(ctx).Run(ctx.Builder, &runConfig);
- Wrap(callable);
- return callable;
+ auto callable = FunctionImpl->GetValue(ctx).Run(ctx.Builder, &runConfig);
+ Wrap(callable);
+ return callable;
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- GetNodeValue(pointer, RunConfigNode, ctx, block);
- const auto conf = new LoadInst(pointer, "conf", block);
-
- const auto func = GetNodeValue(FunctionImpl, ctx, block);
-
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Run>(pointer, func, ctx.Codegen, block, ctx.GetBuilder(), pointer);
-
- ValueUnRef(RunConfigNode->GetRepresentation(), conf, ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto wrap = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TUdfWrapper::Wrap));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), pointer->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, wrap, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, pointer}, "", block);
- }
-#endif
-private:
- void Wrap(NUdf::TUnboxedValue& callable) const {
- MKQL_ENSURE(bool(callable), "Returned empty value in function: " << FunctionName);
- TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, callable, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
- }
-
- void RegisterDependencies() const final {
- this->DependsOn(FunctionImpl);
- this->DependsOn(RunConfigNode);
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ GetNodeValue(pointer, RunConfigNode, ctx, block);
+ const auto conf = new LoadInst(pointer, "conf", block);
+
+ const auto func = GetNodeValue(FunctionImpl, ctx, block);
+
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Run>(pointer, func, ctx.Codegen, block, ctx.GetBuilder(), pointer);
+
+ ValueUnRef(RunConfigNode->GetRepresentation(), conf, ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto wrap = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TUdfWrapper::Wrap));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), pointer->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, wrap, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, pointer}, "", block);
+ }
+#endif
+private:
+ void Wrap(NUdf::TUnboxedValue& callable) const {
+ MKQL_ENSURE(bool(callable), "Returned empty value in function: " << FunctionName);
+ TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, callable, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
}
- IComputationNode* const FunctionImpl;
+ void RegisterDependencies() const final {
+ this->DependsOn(FunctionImpl);
+ this->DependsOn(RunConfigNode);
+ }
+
+ IComputationNode* const FunctionImpl;
const TString FunctionName;
IComputationNode* const RunConfigNode;
const TCallableType* const CallableType;
};
inline IComputationNode* CreateUdfWrapper(
- const TComputationNodeFactoryContext& ctx,
- NUdf::TUnboxedValue&& functionImpl,
+ const TComputationNodeFactoryContext& ctx,
+ NUdf::TUnboxedValue&& functionImpl,
TString&& functionName,
IComputationNode* runConfigNode,
const TCallableType* callableType)
{
- const auto node = ctx.NodeFactory.CreateImmutableNode(std::move(functionImpl));
- ctx.NodePushBack(node);
- switch (ctx.ValidateMode) {
+ const auto node = ctx.NodeFactory.CreateImmutableNode(std::move(functionImpl));
+ ctx.NodePushBack(node);
+ switch (ctx.ValidateMode) {
case NUdf::EValidateMode::None:
- return new TUdfWrapper<TValidateErrorPolicyNone,TValidateModeLazy<TValidateErrorPolicyNone>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
+ return new TUdfWrapper<TValidateErrorPolicyNone,TValidateModeLazy<TValidateErrorPolicyNone>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
case NUdf::EValidateMode::Lazy:
- if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
- return new TUdfWrapper<TValidateErrorPolicyFail,TValidateModeLazy<TValidateErrorPolicyFail>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
+ if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
+ return new TUdfWrapper<TValidateErrorPolicyFail,TValidateModeLazy<TValidateErrorPolicyFail>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
} else {
- return new TUdfWrapper<TValidateErrorPolicyThrow,TValidateModeLazy<TValidateErrorPolicyThrow>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
+ return new TUdfWrapper<TValidateErrorPolicyThrow,TValidateModeLazy<TValidateErrorPolicyThrow>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
}
case NUdf::EValidateMode::Greedy:
- if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
- return new TUdfWrapper<TValidateErrorPolicyFail,TValidateModeGreedy<TValidateErrorPolicyFail>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
+ if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
+ return new TUdfWrapper<TValidateErrorPolicyFail,TValidateModeGreedy<TValidateErrorPolicyFail>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
} else {
- return new TUdfWrapper<TValidateErrorPolicyThrow,TValidateModeGreedy<TValidateErrorPolicyThrow>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
+ return new TUdfWrapper<TValidateErrorPolicyThrow,TValidateModeGreedy<TValidateErrorPolicyThrow>>(ctx.Mutables, std::move(node), std::move(functionName), runConfigNode, callableType);
}
default:
- Y_FAIL("Unexpected validate mode: %u", static_cast<unsigned>(ctx.ValidateMode));
+ Y_FAIL("Unexpected validate mode: %u", static_cast<unsigned>(ctx.ValidateMode));
};
}
-}
-
+}
+
IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 4 || callable.GetInputsCount() == 7, "Expected 4 or 7 arguments");
- const auto funcNameNode = callable.GetInput(0);
- const auto userTypeNode = callable.GetInput(1);
- const auto typeCfgNode = callable.GetInput(2);
- const auto runCfgNode = callable.GetInput(3);
+ const auto funcNameNode = callable.GetInput(0);
+ const auto userTypeNode = callable.GetInput(1);
+ const auto typeCfgNode = callable.GetInput(2);
+ const auto runCfgNode = callable.GetInput(3);
MKQL_ENSURE(userTypeNode.IsImmediate(), "Expected immediate node");
MKQL_ENSURE(userTypeNode.GetStaticType()->IsType(), "Expected type");
- TString funcName(AS_VALUE(TDataLiteral, funcNameNode)->AsValue().AsStringRef());
- TStringBuf typeConfig(AS_VALUE(TDataLiteral, typeCfgNode)->AsValue().AsStringRef());
+ TString funcName(AS_VALUE(TDataLiteral, funcNameNode)->AsValue().AsStringRef());
+ TStringBuf typeConfig(AS_VALUE(TDataLiteral, typeCfgNode)->AsValue().AsStringRef());
NUdf::TSourcePosition pos;
if (callable.GetInputsCount() == 7) {
@@ -169,8 +169,8 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
ui32 flags = 0;
TFunctionTypeInfo funcInfo;
- const auto userType = static_cast<TType*>(userTypeNode.GetNode());
- const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
+ const auto userType = static_cast<TType*>(userTypeNode.GetNode());
+ const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, userType->IsVoid() ? nullptr : userType,
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
@@ -180,12 +180,12 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
", actual:" << PrintNode(funcInfo.FunctionType, true));
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set");
- const auto runConfigType = funcInfo.RunConfigType;
- const bool typesMatch = runConfigType->IsSameType(*runCfgNode.GetStaticType());
+ const auto runConfigType = funcInfo.RunConfigType;
+ const bool typesMatch = runConfigType->IsSameType(*runCfgNode.GetStaticType());
MKQL_ENSURE(typesMatch, "RunConfig '" << funcName << "' type mismatch, expected: " << PrintNode(runCfgNode.GetStaticType(), true) <<
", actual: " << PrintNode(runConfigType, true));
- NUdf::TUnboxedValue impl(NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()));
+ NUdf::TUnboxedValue impl(NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()));
if (runConfigType->IsVoid()) {
// use function implementation as is
@@ -196,37 +196,37 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
if (ctx.ValidateMode != NUdf::EValidateMode::None) {
if (ctx.ValidateMode == NUdf::EValidateMode::Lazy) {
if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
- TValidate<TValidateErrorPolicyFail, TValidateModeLazy<TValidateErrorPolicyFail>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
+ TValidate<TValidateErrorPolicyFail, TValidateModeLazy<TValidateErrorPolicyFail>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
} else {
- TValidate<TValidateErrorPolicyThrow, TValidateModeLazy<TValidateErrorPolicyThrow>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
+ TValidate<TValidateErrorPolicyThrow, TValidateModeLazy<TValidateErrorPolicyThrow>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
}
} else {
if (ctx.ValidatePolicy == NUdf::EValidatePolicy::Fail) {
- TValidate<TValidateErrorPolicyFail, TValidateModeGreedy<TValidateErrorPolicyFail>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
+ TValidate<TValidateErrorPolicyFail, TValidateModeGreedy<TValidateErrorPolicyFail>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
} else {
- TValidate<TValidateErrorPolicyThrow, TValidateModeGreedy<TValidateErrorPolicyThrow>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
+ TValidate<TValidateErrorPolicyThrow, TValidateModeGreedy<TValidateErrorPolicyThrow>>::WrapCallable(funcInfo.FunctionType, impl, TStringBuilder() << "FunctionWrapper<" << funcName << ">");
}
}
}
- return ctx.NodeFactory.CreateImmutableNode(std::move(impl));
+ return ctx.NodeFactory.CreateImmutableNode(std::move(impl));
}
// use function factory to get implementation by runconfig in runtime
- const auto runCfgCompNode = LocateNode(ctx.NodeLocator, *runCfgNode.GetNode());
- return CreateUdfWrapper(ctx, std::move(impl), std::move(funcName), runCfgCompNode, funcInfo.FunctionType);
+ const auto runCfgCompNode = LocateNode(ctx.NodeLocator, *runCfgNode.GetNode());
+ return CreateUdfWrapper(ctx, std::move(impl), std::move(funcName), runCfgCompNode, funcInfo.FunctionType);
}
IComputationNode* WrapScriptUdf(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 4 || callable.GetInputsCount() == 7, "Expected 4 or 7 arguments");
- const auto funcNameNode = callable.GetInput(0);
- const auto userTypeNode = callable.GetInput(1);
- const auto typeConfigNode = callable.GetInput(2);
- const auto programNode = callable.GetInput(3);
+ const auto funcNameNode = callable.GetInput(0);
+ const auto userTypeNode = callable.GetInput(1);
+ const auto typeConfigNode = callable.GetInput(2);
+ const auto programNode = callable.GetInput(3);
MKQL_ENSURE(userTypeNode.IsImmediate() && userTypeNode.GetStaticType()->IsType(), "Expected immediate type");
- TString funcName(AS_VALUE(TDataLiteral, funcNameNode)->AsValue().AsStringRef());
- TStringBuf typeConfig(AS_VALUE(TDataLiteral, typeConfigNode)->AsValue().AsStringRef());
+ TString funcName(AS_VALUE(TDataLiteral, funcNameNode)->AsValue().AsStringRef());
+ TStringBuf typeConfig(AS_VALUE(TDataLiteral, typeConfigNode)->AsValue().AsStringRef());
NUdf::TSourcePosition pos;
if (callable.GetInputsCount() == 7) {
@@ -237,21 +237,21 @@ IComputationNode* WrapScriptUdf(TCallable& callable, const TComputationNodeFacto
ui32 flags = 0;
TFunctionTypeInfo funcInfo;
- const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
+ const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, static_cast<TType*>(userTypeNode.GetNode()),
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
MKQL_ENSURE(status.IsOk(), status.GetError());
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set");
MKQL_ENSURE(!funcInfo.FunctionType, "Function type info is exist for same kind script, it's better use it");
- const auto callableType = callable.GetType();
+ const auto callableType = callable.GetType();
MKQL_ENSURE(callableType->GetKind() == TType::EKind::Callable, "Expected callable type in callable type info");
- const auto callableResultType = callableType->GetReturnType();
+ const auto callableResultType = callableType->GetReturnType();
MKQL_ENSURE(callableResultType->GetKind() == TType::EKind::Callable, "Expected callable type in result of script wrapper");
- const auto funcTypeInfo = static_cast<TCallableType*>(callableResultType);
+ const auto funcTypeInfo = static_cast<TCallableType*>(callableResultType);
- const auto programCompNode = LocateNode(ctx.NodeLocator, *programNode.GetNode());
- return CreateUdfWrapper(ctx, NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()), std::move(funcName), programCompNode, funcTypeInfo);
+ const auto programCompNode = LocateNode(ctx.NodeLocator, *programNode.GetNode());
+ return CreateUdfWrapper(ctx, NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()), std::move(funcName), programCompNode, funcTypeInfo);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_unwrap.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_unwrap.cpp
index cddb951661..daef4d28f9 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_unwrap.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_unwrap.cpp
@@ -8,47 +8,47 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TUnwrapWrapper : public TDecoratorCodegeneratorNode<TUnwrapWrapper> {
- typedef TDecoratorCodegeneratorNode<TUnwrapWrapper> TBaseComputation;
+namespace {
+
+class TUnwrapWrapper : public TDecoratorCodegeneratorNode<TUnwrapWrapper> {
+ typedef TDecoratorCodegeneratorNode<TUnwrapWrapper> TBaseComputation;
public:
TUnwrapWrapper(IComputationNode* optional, IComputationNode* message, const NUdf::TSourcePosition& pos)
- : TBaseComputation(optional)
+ : TBaseComputation(optional)
, Message(message)
, Pos(pos)
{
}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& compCtx, const NUdf::TUnboxedValuePod& value) const {
- if (value) {
- return value.GetOptionalValue();
+ if (value) {
+ return value.GetOptionalValue();
}
Throw(this, &compCtx);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
-
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- BranchInst::Create(kill, good, IsEmpty(value, block), block);
-
- block = kill;
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TUnwrapWrapper::Throw));
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* value, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ BranchInst::Create(kill, good, IsEmpty(value, block), block);
+
+ block = kill;
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TUnwrapWrapper::Throw));
const auto doFuncArg = ConstantInt::get(Type::getInt64Ty(context), (ui64)this);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), { Type::getInt64Ty(context), ctx.Ctx->getType() }, false)), "thrower", block);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(FunctionType::get(Type::getVoidTy(context), { Type::getInt64Ty(context), ctx.Ctx->getType() }, false)), "thrower", block);
CallInst::Create(doFuncPtr, { doFuncArg, ctx.Ctx }, "", block)->setTailCall();
- new UnreachableInst(context, block);
-
- block = good;
- return GetOptionalValue(context, value, block);
- }
-#endif
-private:
+ new UnreachableInst(context, block);
+
+ block = good;
+ return GetOptionalValue(context, value, block);
+ }
+#endif
+private:
[[noreturn]] static void Throw(TUnwrapWrapper const* thisPtr, TComputationContext* ctxPtr) {
auto message = thisPtr->Message->GetValue(*ctxPtr);
auto messageStr = message.AsStringRef();
@@ -65,8 +65,8 @@ private:
const NUdf::TSourcePosition Pos;
};
-}
-
+}
+
IComputationNode* WrapUnwrap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_varitem.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_varitem.cpp
index c26a1523e7..d4e097e84b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_varitem.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_varitem.cpp
@@ -8,11 +8,11 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool IsOptional>
-class TVariantItemWrapper: public TMutableCodegeneratorPtrNode<TVariantItemWrapper<IsOptional>> {
- typedef TMutableCodegeneratorPtrNode<TVariantItemWrapper<IsOptional>> TBaseComputation;
+class TVariantItemWrapper: public TMutableCodegeneratorPtrNode<TVariantItemWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorPtrNode<TVariantItemWrapper<IsOptional>> TBaseComputation;
public:
TVariantItemWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode)
: TBaseComputation(mutables, kind)
@@ -30,69 +30,69 @@ public:
return var.Release().GetVariantItem().Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt32Ty(context);
-
- const auto var = GetNodeValue(VarNode, ctx, block);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- if (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
-
- BranchInst::Create(none, good, IsEmpty(var, block), block);
-
- block = none;
- new StoreInst(var, pointer, block);
- BranchInst::Create(done, block);
-
- block = good;
- }
-
- const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
-
- const auto box = BasicBlock::Create(context, "box", ctx.Func);
- const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
- BranchInst::Create(emb, box, check, block);
-
- block = emb;
-
- const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
- const auto mask = ConstantInt::get(valueType, APInt(128, 2, init));
- const auto clean = BinaryOperator::CreateAnd(var, mask, "clean", block);
- new StoreInst(clean, pointer, block);
- ValueAddRef(this->RepresentationKind, pointer, ctx, block);
- BranchInst::Create(done, block);
-
- block = box;
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(pointer, var, ctx.Codegen, block);
- BranchInst::Create(done, block);
-
- block = done;
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+
+ const auto var = GetNodeValue(VarNode, ctx, block);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ if (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+
+ BranchInst::Create(none, good, IsEmpty(var, block), block);
+
+ block = none;
+ new StoreInst(var, pointer, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+ }
+
+ const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
+
+ const auto box = BasicBlock::Create(context, "box", ctx.Func);
+ const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
+ BranchInst::Create(emb, box, check, block);
+
+ block = emb;
+
+ const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
+ const auto mask = ConstantInt::get(valueType, APInt(128, 2, init));
+ const auto clean = BinaryOperator::CreateAnd(var, mask, "clean", block);
+ new StoreInst(clean, pointer, block);
+ ValueAddRef(this->RepresentationKind, pointer, ctx, block);
+ BranchInst::Create(done, block);
+
+ block = box;
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(pointer, var, ctx.Codegen, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ }
+#endif
private:
void RegisterDependencies() const final {
this->DependsOn(VarNode);
}
- IComputationNode *const VarNode;
+ IComputationNode *const VarNode;
};
-}
-
+}
+
IComputationNode* WrapVariantItem(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 argument");
bool isOptional;
- const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
- const auto varType = AS_TYPE(TVariantType, unpacked);
+ const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
+ const auto varType = AS_TYPE(TVariantType, unpacked);
- const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
if (isOptional) {
return new TVariantItemWrapper<true>(ctx.Mutables, GetValueRepresentation(varType->GetAlternativeType(0)), variant);
} else {
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_visitall.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_visitall.cpp
index bfa4cf868f..76adbc982b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_visitall.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_visitall.cpp
@@ -1,340 +1,340 @@
#include "mkql_visitall.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
-#include <util/string/cast.h>
+#include <util/string/cast.h>
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-class TVisitAllWrapper: public TMutableCodegeneratorNode<TVisitAllWrapper> {
-using TBaseComputation = TMutableCodegeneratorNode<TVisitAllWrapper>;
+namespace {
+
+class TVisitAllWrapper: public TMutableCodegeneratorNode<TVisitAllWrapper> {
+using TBaseComputation = TMutableCodegeneratorNode<TVisitAllWrapper>;
public:
- TVisitAllWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationNodePtrVector&& newNodes)
- : TBaseComputation(mutables, kind)
+ TVisitAllWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationNodePtrVector&& newNodes)
+ : TBaseComputation(mutables, kind)
, VarNode(varNode)
, Args(std::move(args))
, NewNodes(std::move(newNodes))
- {}
+ {}
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& var = VarNode->GetValue(ctx);
- const auto currentIndex = var.GetVariantIndex();
- if (currentIndex >= Args.size())
- return NUdf::TUnboxedValuePod();
+ const auto currentIndex = var.GetVariantIndex();
+ if (currentIndex >= Args.size())
+ return NUdf::TUnboxedValuePod();
Args[currentIndex]->SetValue(ctx, var.GetVariantItem());
return NewNodes[currentIndex]->GetValue(ctx).Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto variant = GetNodeValue(VarNode, ctx, block);
- const auto unpack = GetVariantParts(variant, ctx, block);
-
- const auto result = PHINode::Create(variant->getType(), Args.size() + 1U, "result", done);
- result->addIncoming(ConstantInt::get(variant->getType(), 0ULL), block);
-
- const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
-
- for (ui32 i = 0; i < NewNodes.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto variant = GetNodeValue(VarNode, ctx, block);
+ const auto unpack = GetVariantParts(variant, ctx, block);
+
+ const auto result = PHINode::Create(variant->getType(), Args.size() + 1U, "result", done);
+ result->addIncoming(ConstantInt::get(variant->getType(), 0ULL), block);
+
+ const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
+
+ for (ui32 i = 0; i < NewNodes.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
MKQL_ENSURE(codegenArg, "Arg must be codegenerator node.");
- codegenArg->CreateSetValue(ctx, block, unpack.second);
- const auto item = GetNodeValue(NewNodes[i], ctx, block);
-
- result->addIncoming(item, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(VarNode);
- std::for_each(Args.cbegin(), Args.cend(), std::bind(&TVisitAllWrapper::Own, this, std::placeholders::_1));
- std::for_each(NewNodes.cbegin(), NewNodes.cend(), std::bind(&TVisitAllWrapper::DependsOn, this, std::placeholders::_1));
- }
-
- IComputationNode *const VarNode;
- const TComputationExternalNodePtrVector Args;
- const TComputationNodePtrVector NewNodes;
-};
-
-class TFlowVisitAllWrapper: public TStatefulFlowCodegeneratorNode<TFlowVisitAllWrapper> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowVisitAllWrapper>;
-public:
- TFlowVisitAllWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationNodePtrVector&& newNodes)
- : TBaseComputation(mutables, nullptr, kind, EValueRepresentation::Embedded)
- , VarNode(varNode)
- , Args(std::move(args))
- , NewNodes(std::move(newNodes))
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsInvalid()) {
- const auto& var = VarNode->GetValue(ctx);
- const auto index = var.GetVariantIndex();
- state = NUdf::TUnboxedValuePod(index);
- if (index < Args.size()) {
- Args[index]->SetValue(ctx, var.GetVariantItem());
- }
+ codegenArg->CreateSetValue(ctx, block, unpack.second);
+ const auto item = GetNodeValue(NewNodes[i], ctx, block);
+
+ result->addIncoming(item, block);
+ BranchInst::Create(done, block);
}
-
- const auto index = state.Get<ui32>();
- return index < NewNodes.size() ? NewNodes[index]->GetValue(ctx).Release() : NUdf::TUnboxedValuePod::MakeFinish();
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(VarNode);
+ std::for_each(Args.cbegin(), Args.cend(), std::bind(&TVisitAllWrapper::Own, this, std::placeholders::_1));
+ std::for_each(NewNodes.cbegin(), NewNodes.cend(), std::bind(&TVisitAllWrapper::DependsOn, this, std::placeholders::_1));
+ }
+
+ IComputationNode *const VarNode;
+ const TComputationExternalNodePtrVector Args;
+ const TComputationNodePtrVector NewNodes;
+};
+
+class TFlowVisitAllWrapper: public TStatefulFlowCodegeneratorNode<TFlowVisitAllWrapper> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TFlowVisitAllWrapper>;
+public:
+ TFlowVisitAllWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationNodePtrVector&& newNodes)
+ : TBaseComputation(mutables, nullptr, kind, EValueRepresentation::Embedded)
+ , VarNode(varNode)
+ , Args(std::move(args))
+ , NewNodes(std::move(newNodes))
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.IsInvalid()) {
+ const auto& var = VarNode->GetValue(ctx);
+ const auto index = var.GetVariantIndex();
+ state = NUdf::TUnboxedValuePod(index);
+ if (index < Args.size()) {
+ Args[index]->SetValue(ctx, var.GetVariantItem());
+ }
+ }
+
+ const auto index = state.Get<ui32>();
+ return index < NewNodes.size() ? NewNodes[index]->GetValue(ctx).Release() : NUdf::TUnboxedValuePod::MakeFinish();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), NewNodes.size() + 2U, "result", done);
-
- BranchInst::Create(init, work, IsInvalid(statePtr, block), block);
-
- {
- block = init;
-
- const auto variant = GetNodeValue(VarNode, ctx, block);
- const auto unpack = GetVariantParts(variant, ctx, block);
- const auto index = SetterFor<ui32>(unpack.first, context, block);
- new StoreInst(index, statePtr, block);
- result->addIncoming(GetFinish(context), block);
- const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
-
- for (ui32 i = 0; i < Args.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("init_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), NewNodes.size() + 2U, "result", done);
+
+ BranchInst::Create(init, work, IsInvalid(statePtr, block), block);
+
+ {
+ block = init;
+
+ const auto variant = GetNodeValue(VarNode, ctx, block);
+ const auto unpack = GetVariantParts(variant, ctx, block);
+ const auto index = SetterFor<ui32>(unpack.first, context, block);
+ new StoreInst(index, statePtr, block);
+ result->addIncoming(GetFinish(context), block);
+ const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
+
+ for (ui32 i = 0; i < Args.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("init_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
MKQL_ENSURE(codegenArg, "Arg must be codegenerator node.");
- codegenArg->CreateSetValue(ctx, block, unpack.second);
- BranchInst::Create(work, block);
- }
- }
-
- {
- block = work;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto index = GetterFor<ui32>(state, context, block);
- result->addIncoming(GetFinish(context), block);
- const auto choise = SwitchInst::Create(index, done, NewNodes.size(), block);
- for (ui32 i = 0; i < NewNodes.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto item = GetNodeValue(NewNodes[i], ctx, block);
-
- result->addIncoming(item, block);
- BranchInst::Create(done, block);
- }
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOnAll(NewNodes)) {
- DependsOn(flow, VarNode);
- std::for_each(Args.cbegin(), Args.cend(), std::bind(&TFlowVisitAllWrapper::Own, flow, std::placeholders::_1));
- }
- std::for_each(Args.cbegin(), Args.cend(), std::bind(&IComputationNode::AddDependence, VarNode, std::placeholders::_1));
- }
-
- IComputationNode *const VarNode;
- const TComputationExternalNodePtrVector Args;
- const TComputationNodePtrVector NewNodes;
+ codegenArg->CreateSetValue(ctx, block, unpack.second);
+ BranchInst::Create(work, block);
+ }
+ }
+
+ {
+ block = work;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto index = GetterFor<ui32>(state, context, block);
+ result->addIncoming(GetFinish(context), block);
+ const auto choise = SwitchInst::Create(index, done, NewNodes.size(), block);
+ for (ui32 i = 0; i < NewNodes.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto item = GetNodeValue(NewNodes[i], ctx, block);
+
+ result->addIncoming(item, block);
+ BranchInst::Create(done, block);
+ }
+ }
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOnAll(NewNodes)) {
+ DependsOn(flow, VarNode);
+ std::for_each(Args.cbegin(), Args.cend(), std::bind(&TFlowVisitAllWrapper::Own, flow, std::placeholders::_1));
+ }
+ std::for_each(Args.cbegin(), Args.cend(), std::bind(&IComputationNode::AddDependence, VarNode, std::placeholders::_1));
+ }
+
+ IComputationNode *const VarNode;
+ const TComputationExternalNodePtrVector Args;
+ const TComputationNodePtrVector NewNodes;
};
-class TWideVisitAllWrapper: public TStatefulWideFlowCodegeneratorNode<TWideVisitAllWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideVisitAllWrapper>;
-public:
- TWideVisitAllWrapper(TComputationMutables& mutables, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationWideFlowNodePtrVector&& newNodes)
- : TBaseComputation(mutables, nullptr, EValueRepresentation::Embedded)
- , VarNode(varNode)
- , Args(std::move(args))
- , NewNodes(std::move(newNodes))
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- const auto& var = VarNode->GetValue(ctx);
- const auto index = var.GetVariantIndex();
- state = NUdf::TUnboxedValuePod(index);
- if (index < Args.size()) {
- Args[index]->SetValue(ctx, var.GetVariantItem());
- }
- }
-
- const auto index = state.Get<ui32>();
- return index < NewNodes.size() ? NewNodes[index]->FetchValues(ctx, output) : EFetchResult::Finish;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, NewNodes.size() + 2U, "result", done);
-
- BranchInst::Create(init, work, IsInvalid(statePtr, block), block);
-
- {
- block = init;
-
- const auto variant = GetNodeValue(VarNode, ctx, block);
- const auto unpack = GetVariantParts(variant, ctx, block);
- const auto index = SetterFor<ui32>(unpack.first, context, block);
- new StoreInst(index, statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
- const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
-
- for (ui32 i = 0; i < Args.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("init_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
+class TWideVisitAllWrapper: public TStatefulWideFlowCodegeneratorNode<TWideVisitAllWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideVisitAllWrapper>;
+public:
+ TWideVisitAllWrapper(TComputationMutables& mutables, IComputationNode* varNode, TComputationExternalNodePtrVector&& args, TComputationWideFlowNodePtrVector&& newNodes)
+ : TBaseComputation(mutables, nullptr, EValueRepresentation::Embedded)
+ , VarNode(varNode)
+ , Args(std::move(args))
+ , NewNodes(std::move(newNodes))
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ const auto& var = VarNode->GetValue(ctx);
+ const auto index = var.GetVariantIndex();
+ state = NUdf::TUnboxedValuePod(index);
+ if (index < Args.size()) {
+ Args[index]->SetValue(ctx, var.GetVariantItem());
+ }
+ }
+
+ const auto index = state.Get<ui32>();
+ return index < NewNodes.size() ? NewNodes[index]->FetchValues(ctx, output) : EFetchResult::Finish;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, NewNodes.size() + 2U, "result", done);
+
+ BranchInst::Create(init, work, IsInvalid(statePtr, block), block);
+
+ {
+ block = init;
+
+ const auto variant = GetNodeValue(VarNode, ctx, block);
+ const auto unpack = GetVariantParts(variant, ctx, block);
+ const auto index = SetterFor<ui32>(unpack.first, context, block);
+ new StoreInst(index, statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
+ const auto choise = SwitchInst::Create(unpack.first, done, Args.size(), block);
+
+ for (ui32 i = 0; i < Args.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("init_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto codegenArg = dynamic_cast<ICodegeneratorExternalNode*>(Args[i]);
MKQL_ENSURE(codegenArg, "Arg must be codegenerator node.");
- codegenArg->CreateSetValue(ctx, block, unpack.second);
- BranchInst::Create(work, block);
- }
- }
-
- std::vector<TGettersList> allGetters;
- allGetters.reserve(NewNodes.size());
-
- {
- block = work;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto index = GetterFor<ui32>(state, context, block);
- result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
- const auto choise = SwitchInst::Create(index, done, NewNodes.size(), block);
- for (ui32 i = 0; i < NewNodes.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- auto get = GetNodeValues(NewNodes[i], ctx, block);
- allGetters.emplace_back(std::move(get.second));
-
- result->addIncoming(get.first, block);
- BranchInst::Create(done, block);
- }
- }
-
- TGettersList getters;
- getters.reserve(allGetters.back().size());
- const auto index = static_cast<const IComputationNode*>(this)->GetIndex();
- size_t idx = 0U;
- std::generate_n(std::back_inserter(getters), allGetters.front().size(), [&]() {
- TGettersList slice;
- slice.reserve(allGetters.size());
- std::transform(allGetters.begin(), allGetters.end(), std::back_inserter(slice), [j = idx++](TGettersList& list) { return std::move(list[j]);});
- return [index, slice = std::move(slice)](const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- new UnreachableInst(context, stub);
-
- const auto res = PHINode::Create(Type::getInt128Ty(context), slice.size(), "res", done);
-
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), index)}, "state_ptr", block);
- const auto state = new LoadInst(statePtr, "state", block);
- const auto trunc = GetterFor<ui32>(state, context, block);
-
- const auto choise = SwitchInst::Create(trunc, stub, slice.size(), block);
- for (auto i = 0U; i < slice.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto get = slice[i](ctx, block);
-
- res->addIncoming(get, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return res;
- };
- });
-
- block = done;
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOnAll(NewNodes)) {
- DependsOn(flow, VarNode);
- std::for_each(Args.cbegin(), Args.cend(), std::bind(&TWideVisitAllWrapper::Own, flow, std::placeholders::_1));
- }
- std::for_each(Args.cbegin(), Args.cend(), std::bind(&IComputationNode::AddDependence, VarNode, std::placeholders::_1));
- }
-
- IComputationNode *const VarNode;
- const TComputationExternalNodePtrVector Args;
- const TComputationWideFlowNodePtrVector NewNodes;
-};
-
-}
-
+ codegenArg->CreateSetValue(ctx, block, unpack.second);
+ BranchInst::Create(work, block);
+ }
+ }
+
+ std::vector<TGettersList> allGetters;
+ allGetters.reserve(NewNodes.size());
+
+ {
+ block = work;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto index = GetterFor<ui32>(state, context, block);
+ result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
+ const auto choise = SwitchInst::Create(index, done, NewNodes.size(), block);
+ for (ui32 i = 0; i < NewNodes.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ auto get = GetNodeValues(NewNodes[i], ctx, block);
+ allGetters.emplace_back(std::move(get.second));
+
+ result->addIncoming(get.first, block);
+ BranchInst::Create(done, block);
+ }
+ }
+
+ TGettersList getters;
+ getters.reserve(allGetters.back().size());
+ const auto index = static_cast<const IComputationNode*>(this)->GetIndex();
+ size_t idx = 0U;
+ std::generate_n(std::back_inserter(getters), allGetters.front().size(), [&]() {
+ TGettersList slice;
+ slice.reserve(allGetters.size());
+ std::transform(allGetters.begin(), allGetters.end(), std::back_inserter(slice), [j = idx++](TGettersList& list) { return std::move(list[j]);});
+ return [index, slice = std::move(slice)](const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto stub = BasicBlock::Create(context, "stub", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ new UnreachableInst(context, stub);
+
+ const auto res = PHINode::Create(Type::getInt128Ty(context), slice.size(), "res", done);
+
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), index)}, "state_ptr", block);
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto trunc = GetterFor<ui32>(state, context, block);
+
+ const auto choise = SwitchInst::Create(trunc, stub, slice.size(), block);
+ for (auto i = 0U; i < slice.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto get = slice[i](ctx, block);
+
+ res->addIncoming(get, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return res;
+ };
+ });
+
+ block = done;
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOnAll(NewNodes)) {
+ DependsOn(flow, VarNode);
+ std::for_each(Args.cbegin(), Args.cend(), std::bind(&TWideVisitAllWrapper::Own, flow, std::placeholders::_1));
+ }
+ std::for_each(Args.cbegin(), Args.cend(), std::bind(&IComputationNode::AddDependence, VarNode, std::placeholders::_1));
+ }
+
+ IComputationNode *const VarNode;
+ const TComputationExternalNodePtrVector Args;
+ const TComputationWideFlowNodePtrVector NewNodes;
+};
+
+}
+
IComputationNode* WrapVisitAll(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() >= 3, "Expected at least 3 arguments");
- const auto varType = AS_TYPE(TVariantType, callable.GetInput(0));
+ const auto varType = AS_TYPE(TVariantType, callable.GetInput(0));
MKQL_ENSURE(callable.GetInputsCount() == varType->GetAlternativesCount() * 2 + 1, "Mismatch handlers count");
-
- const auto variant = LocateNode(ctx.NodeLocator, callable, 0U);
-
+
+ const auto variant = LocateNode(ctx.NodeLocator, callable, 0U);
+
TComputationNodePtrVector newNodes;
- newNodes.reserve(varType->GetAlternativesCount());
- for (auto i = 1U; i <= varType->GetAlternativesCount() << 1U; ++i) {
- newNodes.emplace_back(LocateNode(ctx.NodeLocator, callable, ++i));
+ newNodes.reserve(varType->GetAlternativesCount());
+ for (auto i = 1U; i <= varType->GetAlternativesCount() << 1U; ++i) {
+ newNodes.emplace_back(LocateNode(ctx.NodeLocator, callable, ++i));
}
- TComputationExternalNodePtrVector args;
- args.reserve(varType->GetAlternativesCount());
- for (auto i = 0U; i < varType->GetAlternativesCount() << 1U; ++i) {
- args.emplace_back(LocateExternalNode(ctx.NodeLocator, callable, ++i));
+ TComputationExternalNodePtrVector args;
+ args.reserve(varType->GetAlternativesCount());
+ for (auto i = 0U; i < varType->GetAlternativesCount() << 1U; ++i) {
+ args.emplace_back(LocateExternalNode(ctx.NodeLocator, callable, ++i));
}
- if (const auto type = callable.GetType()->GetReturnType(); type->IsFlow()) {
- TComputationWideFlowNodePtrVector wideNodes;
- wideNodes.reserve(newNodes.size());
- std::transform(newNodes.cbegin(), newNodes.cend(), std::back_inserter(wideNodes), [](IComputationNode* node){ return dynamic_cast<IComputationWideFlowNode*>(node); });
- wideNodes.erase(std::remove_if(wideNodes.begin(), wideNodes.end(), std::logical_not<IComputationWideFlowNode*>()), wideNodes.cend());
- if (wideNodes.empty())
- return new TFlowVisitAllWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), variant, std::move(args), std::move(newNodes));
- else if (wideNodes.size() == newNodes.size())
- return new TWideVisitAllWrapper(ctx.Mutables, variant, std::move(args), std::move(wideNodes));
- } else
- return new TVisitAllWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), variant, std::move(args), std::move(newNodes));
-
- THROW yexception() << "Wrong signature.";
+ if (const auto type = callable.GetType()->GetReturnType(); type->IsFlow()) {
+ TComputationWideFlowNodePtrVector wideNodes;
+ wideNodes.reserve(newNodes.size());
+ std::transform(newNodes.cbegin(), newNodes.cend(), std::back_inserter(wideNodes), [](IComputationNode* node){ return dynamic_cast<IComputationWideFlowNode*>(node); });
+ wideNodes.erase(std::remove_if(wideNodes.begin(), wideNodes.end(), std::logical_not<IComputationWideFlowNode*>()), wideNodes.cend());
+ if (wideNodes.empty())
+ return new TFlowVisitAllWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), variant, std::move(args), std::move(newNodes));
+ else if (wideNodes.size() == newNodes.size())
+ return new TWideVisitAllWrapper(ctx.Mutables, variant, std::move(args), std::move(wideNodes));
+ } else
+ return new TVisitAllWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), variant, std::move(args), std::move(newNodes));
+
+ THROW yexception() << "Wrong signature.";
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_way.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_way.cpp
index e0c30bc155..1071b8b780 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_way.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_way.cpp
@@ -10,132 +10,132 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool IsOptional>
-class TWayWrapper: public TMutableCodegeneratorNode<TWayWrapper<IsOptional>> {
- typedef TMutableCodegeneratorNode<TWayWrapper<IsOptional>> TBaseComputation;
+namespace {
+
+template <bool IsOptional>
+class TWayWrapper: public TMutableCodegeneratorNode<TWayWrapper<IsOptional>> {
+ typedef TMutableCodegeneratorNode<TWayWrapper<IsOptional>> TBaseComputation;
public:
- TWayWrapper(TComputationMutables& mutables, IComputationNode* varNode, EValueRepresentation kind, TComputationNodePtrVector&& literals)
- : TBaseComputation(mutables, kind)
+ TWayWrapper(TComputationMutables& mutables, IComputationNode* varNode, EValueRepresentation kind, TComputationNodePtrVector&& literals)
+ : TBaseComputation(mutables, kind)
, VarNode(varNode)
- , Literals(std::move(literals))
- {}
+ , Literals(std::move(literals))
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
const auto& var = VarNode->GetValue(ctx);
if (IsOptional && !var) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
const ui32 index = var.GetVariantIndex();
return Literals[index]->GetValue(ctx).Release();
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto indexType = Type::getInt32Ty(context);
-
-
- const auto var = GetNodeValue(VarNode, ctx, block);
-
- const auto zero = ConstantInt::get(valueType, 0ULL);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, Literals.size() + IsOptional ? 2U : 1U, "result", done);
-
- if (IsOptional) {
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- BranchInst::Create(done, good, IsEmpty(var, block), block);
- result->addIncoming(zero, block);
-
- block = good;
- }
-
- const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
-
- const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
- const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
-
- const auto index = PHINode::Create(indexType, 2, "index", step);
-
- BranchInst::Create(embed, boxed, check, block);
-
- block = embed;
-
- const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(indexType, 1), "dec", block);
- index->addIncoming(dec, block);
- BranchInst::Create(step, block);
-
- block = boxed;
-
- const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(indexType, var, ctx.Codegen, block);
- index->addIncoming(idx, block);
- BranchInst::Create(step, block);
-
- block = step;
-
- const auto choise = SwitchInst::Create(index, done, Literals.size(), block);
- result->addIncoming(zero, block);
-
- for (ui32 i = 0; i < Literals.size(); ++i) {
- const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- block = var;
-
- const auto way = GetNodeValue(Literals[i], ctx, block);
-
- result->addIncoming(way, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- this->DependsOn(VarNode);
- std::for_each(Literals.cbegin(), Literals.cend(),std::bind(&TWayWrapper<IsOptional>::DependsOn, this, std::placeholders::_1));
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto indexType = Type::getInt32Ty(context);
+
+
+ const auto var = GetNodeValue(VarNode, ctx, block);
+
+ const auto zero = ConstantInt::get(valueType, 0ULL);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, Literals.size() + IsOptional ? 2U : 1U, "result", done);
+
+ if (IsOptional) {
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ BranchInst::Create(done, good, IsEmpty(var, block), block);
+ result->addIncoming(zero, block);
+
+ block = good;
+ }
+
+ const auto lshr = BinaryOperator::CreateLShr(var, ConstantInt::get(valueType, 122), "lshr", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, lshr, indexType, "trunc", block);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(indexType , 0), "check", block);
+
+ const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
+ const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+
+ const auto index = PHINode::Create(indexType, 2, "index", step);
+
+ BranchInst::Create(embed, boxed, check, block);
+
+ block = embed;
+
+ const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(indexType, 1), "dec", block);
+ index->addIncoming(dec, block);
+ BranchInst::Create(step, block);
+
+ block = boxed;
+
+ const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(indexType, var, ctx.Codegen, block);
+ index->addIncoming(idx, block);
+ BranchInst::Create(step, block);
+
+ block = step;
+
+ const auto choise = SwitchInst::Create(index, done, Literals.size(), block);
+ result->addIncoming(zero, block);
+
+ for (ui32 i = 0; i < Literals.size(); ++i) {
+ const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), ctx.Func);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ block = var;
+
+ const auto way = GetNodeValue(Literals[i], ctx, block);
+
+ result->addIncoming(way, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(VarNode);
+ std::for_each(Literals.cbegin(), Literals.cend(),std::bind(&TWayWrapper<IsOptional>::DependsOn, this, std::placeholders::_1));
}
- IComputationNode *const VarNode;
- const TComputationNodePtrVector Literals;
+ IComputationNode *const VarNode;
+ const TComputationNodePtrVector Literals;
};
-}
-
+}
+
IComputationNode* WrapWay(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 argument");
bool isOptional;
- const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
- const auto varType = AS_TYPE(TVariantType, unpacked);
- const auto structType = varType->GetUnderlyingType()->IsTuple() ? nullptr : AS_TYPE(TStructType, varType->GetUnderlyingType());
- const auto size = varType->GetAlternativesCount();
-
- TComputationNodePtrVector literals(size);
- EValueRepresentation kind = EValueRepresentation::Embedded;
-
- for (ui32 idx = 0U; idx < size; ++idx) {
- const auto node = literals[idx] = ctx.NodeFactory.CreateImmutableNode(structType ? MakeString(structType->GetMemberName(idx)) : NUdf::TUnboxedValuePod(idx));
- ctx.NodePushBack(node);
- if (node->GetRepresentation() != EValueRepresentation::Embedded) {
- kind = EValueRepresentation::Any;
- }
- }
-
- const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto unpacked = UnpackOptional(callable.GetInput(0), isOptional);
+ const auto varType = AS_TYPE(TVariantType, unpacked);
+ const auto structType = varType->GetUnderlyingType()->IsTuple() ? nullptr : AS_TYPE(TStructType, varType->GetUnderlyingType());
+ const auto size = varType->GetAlternativesCount();
+
+ TComputationNodePtrVector literals(size);
+ EValueRepresentation kind = EValueRepresentation::Embedded;
+
+ for (ui32 idx = 0U; idx < size; ++idx) {
+ const auto node = literals[idx] = ctx.NodeFactory.CreateImmutableNode(structType ? MakeString(structType->GetMemberName(idx)) : NUdf::TUnboxedValuePod(idx));
+ ctx.NodePushBack(node);
+ if (node->GetRepresentation() != EValueRepresentation::Embedded) {
+ kind = EValueRepresentation::Any;
+ }
+ }
+
+ const auto variant = LocateNode(ctx.NodeLocator, callable, 0);
if (isOptional) {
- return new TWayWrapper<true>(ctx.Mutables, variant, kind, std::move(literals));
+ return new TWayWrapper<true>(ctx.Mutables, variant, kind, std::move(literals));
} else {
- return new TWayWrapper<false>(ctx.Mutables, variant, kind, std::move(literals));
+ return new TWayWrapper<false>(ctx.Mutables, variant, kind, std::move(literals));
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_weakmember.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_weakmember.cpp
index fbdcd7e678..e27d397bfd 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_weakmember.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_weakmember.cpp
@@ -9,7 +9,7 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
+namespace {
class TTryWeakMemberFromDictWrapper : public TMutableComputationNode<TTryWeakMemberFromDictWrapper> {
typedef TMutableComputationNode<TTryWeakMemberFromDictWrapper> TBaseComputation;
@@ -27,11 +27,11 @@ public:
NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
if (const auto& restDict = RestDict->GetValue(ctx)) {
- if (const auto& tryMember = restDict.Lookup(MemberName)) {
- return SimpleValueFromYson(SchemeType, tryMember.AsStringRef());
- }
- }
-
+ if (const auto& tryMember = restDict.Lookup(MemberName)) {
+ return SimpleValueFromYson(SchemeType, tryMember.AsStringRef());
+ }
+ }
+
if (const auto& otherDict = OtherDict->GetValue(ctx)) {
if (auto tryMember = otherDict.Lookup(MemberName)) {
const bool isString = otherDict.Contains(OtherIsStringMemberName);
@@ -50,19 +50,19 @@ public:
} else {
return {};
}
- } else {
- return SimpleValueFromYson(SchemeType, tryMember.AsStringRef());
+ } else {
+ return SimpleValueFromYson(SchemeType, tryMember.AsStringRef());
}
}
}
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
private:
- void RegisterDependencies() const final {
- DependsOn(OtherDict);
- DependsOn(RestDict);
+ void RegisterDependencies() const final {
+ DependsOn(OtherDict);
+ DependsOn(RestDict);
}
IComputationNode* const OtherDict;
@@ -72,8 +72,8 @@ private:
const NUdf::TUnboxedValue OtherIsStringMemberName;
};
-}
-
+}
+
IComputationNode* WrapTryWeakMemberFromDict(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 4, "Expected 4 args");
@@ -99,8 +99,8 @@ IComputationNode* WrapTryWeakMemberFromDict(TCallable& callable, const TComputat
auto otherDict = LocateNode(ctx.NodeLocator, callable, 0);
auto restDict = LocateNode(ctx.NodeLocator, callable, 1);
- auto memberNameStr = MakeString(memberName);
- auto otherIsStringMemberNameStr = MakeString("_yql_" + memberName);
+ auto memberNameStr = MakeString(memberName);
+ auto otherIsStringMemberNameStr = MakeString("_yql_" + memberName);
return new TTryWeakMemberFromDictWrapper(ctx.Mutables, otherDict, restDict, static_cast<NUdf::TDataTypeId>(schemeType),
std::move(memberNameStr), std::move(otherIsStringMemberNameStr));
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_while.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_while.cpp
index 67f7479bc6..a8650d5754 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_while.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_while.cpp
@@ -1,4 +1,4 @@
-#include "mkql_while.h"
+#include "mkql_while.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
@@ -6,188 +6,188 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
-template <bool SkipOrTake, bool Inclusive>
-class TWhileFlowWrapper : public TStatefulFlowCodegeneratorNode<TWhileFlowWrapper<SkipOrTake, Inclusive>> {
-using TBaseComputation = TStatefulFlowCodegeneratorNode<TWhileFlowWrapper<SkipOrTake, Inclusive>>;
-public:
- TWhileFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Item(item), Predicate(predicate)
- {}
-
- NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.HasValue() && state.Get<bool>()) {
- return SkipOrTake ? Flow->GetValue(ctx) : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod::MakeFinish());
- }
-
- if constexpr (SkipOrTake) {
- do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
- return item;
- else
- Item->SetValue(ctx, std::move(item));
- while (Predicate->GetValue(ctx).template Get<bool>());
-
- state = NUdf::TUnboxedValuePod(true);
- return Inclusive ? Flow->GetValue(ctx) : Item->GetValue(ctx);
- } else {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial())
- return item;
- else
- Item->SetValue(ctx, std::move(item));
-
- if (Predicate->GetValue(ctx).template Get<bool>()) {
- return Item->GetValue(ctx);
- }
-
- state = NUdf::TUnboxedValuePod(true);
- return Inclusive ? Item->GetValue(ctx).Release() : NUdf::TUnboxedValuePod::MakeFinish();
- }
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(valueType, SkipOrTake ? 3U : 4U, "result", done);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto finished = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetTrue(context), "finished", block);
-
- BranchInst::Create(skip, work, finished, block);
-
- block = work;
- const auto item = GetNodeValue(Flow, ctx, block);
- result->addIncoming(item, block);
- BranchInst::Create(done, good, IsSpecial(item, block), block);
-
- block = good;
- codegenItem->CreateSetValue(ctx, block, item);
- const auto pred = GetNodeValue(Predicate, ctx, block);
- const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
-
- if constexpr (SkipOrTake) {
- BranchInst::Create(work, stop, bit, block);
- } else {
- result->addIncoming(item, block);
- BranchInst::Create(done, stop, bit, block);
- }
-
- block = stop;
- new StoreInst(GetTrue(context), statePtr, block);
- const auto last = Inclusive ?
- (SkipOrTake ? GetNodeValue(Flow, ctx, block) : item):
- (SkipOrTake ? item : GetFinish(context));
- result->addIncoming(last, block);
- BranchInst::Create(done, block);
-
- block = skip;
- const auto res = SkipOrTake ? GetNodeValue(Flow, ctx, block) : GetFinish(context);
- result->addIncoming(res, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- this->Own(flow, Item);
- this->DependsOn(flow, Predicate);
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode* const Item;
- IComputationNode* const Predicate;
-};
-
-template <bool SkipOrTake, bool Inclusive, bool IsStream>
-class TBaseWhileWrapper {
-protected:
+namespace {
+
+template <bool SkipOrTake, bool Inclusive>
+class TWhileFlowWrapper : public TStatefulFlowCodegeneratorNode<TWhileFlowWrapper<SkipOrTake, Inclusive>> {
+using TBaseComputation = TStatefulFlowCodegeneratorNode<TWhileFlowWrapper<SkipOrTake, Inclusive>>;
+public:
+ TWhileFlowWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* flow, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables, flow, kind, EValueRepresentation::Embedded), Flow(flow), Item(item), Predicate(predicate)
+ {}
+
+ NUdf::TUnboxedValue DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
+ if (state.HasValue() && state.Get<bool>()) {
+ return SkipOrTake ? Flow->GetValue(ctx) : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod::MakeFinish());
+ }
+
+ if constexpr (SkipOrTake) {
+ do if (auto item = Flow->GetValue(ctx); item.IsSpecial())
+ return item;
+ else
+ Item->SetValue(ctx, std::move(item));
+ while (Predicate->GetValue(ctx).template Get<bool>());
+
+ state = NUdf::TUnboxedValuePod(true);
+ return Inclusive ? Flow->GetValue(ctx) : Item->GetValue(ctx);
+ } else {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial())
+ return item;
+ else
+ Item->SetValue(ctx, std::move(item));
+
+ if (Predicate->GetValue(ctx).template Get<bool>()) {
+ return Item->GetValue(ctx);
+ }
+
+ state = NUdf::TUnboxedValuePod(true);
+ return Inclusive ? Item->GetValue(ctx).Release() : NUdf::TUnboxedValuePod::MakeFinish();
+ }
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(valueType, SkipOrTake ? 3U : 4U, "result", done);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto finished = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetTrue(context), "finished", block);
+
+ BranchInst::Create(skip, work, finished, block);
+
+ block = work;
+ const auto item = GetNodeValue(Flow, ctx, block);
+ result->addIncoming(item, block);
+ BranchInst::Create(done, good, IsSpecial(item, block), block);
+
+ block = good;
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto pred = GetNodeValue(Predicate, ctx, block);
+ const auto bit = CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(context), "bit", block);
+
+ if constexpr (SkipOrTake) {
+ BranchInst::Create(work, stop, bit, block);
+ } else {
+ result->addIncoming(item, block);
+ BranchInst::Create(done, stop, bit, block);
+ }
+
+ block = stop;
+ new StoreInst(GetTrue(context), statePtr, block);
+ const auto last = Inclusive ?
+ (SkipOrTake ? GetNodeValue(Flow, ctx, block) : item):
+ (SkipOrTake ? item : GetFinish(context));
+ result->addIncoming(last, block);
+ BranchInst::Create(done, block);
+
+ block = skip;
+ const auto res = SkipOrTake ? GetNodeValue(Flow, ctx, block) : GetFinish(context);
+ result->addIncoming(res, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ this->Own(flow, Item);
+ this->DependsOn(flow, Predicate);
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode* const Item;
+ IComputationNode* const Predicate;
+};
+
+template <bool SkipOrTake, bool Inclusive, bool IsStream>
+class TBaseWhileWrapper {
+protected:
class TListValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
- : TComputationValue<TIterator>(memInfo)
+ TIterator(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, NUdf::TUnboxedValue&& iter, IComputationExternalNode* item, IComputationNode* predicate)
+ : TComputationValue<TIterator>(memInfo)
, CompCtx(compCtx)
- , Iter(std::move(iter))
+ , Iter(std::move(iter))
, Item(item)
, Predicate(predicate)
{}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (FilterWorkFinished) {
- return SkipOrTake ? Iter.Next(value) : false;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (FilterWorkFinished) {
+ return SkipOrTake ? Iter.Next(value) : false;
}
- if constexpr (SkipOrTake) {
- while (Iter.Next(Item->RefValue(CompCtx))) {
+ if constexpr (SkipOrTake) {
+ while (Iter.Next(Item->RefValue(CompCtx))) {
if (!Predicate->GetValue(CompCtx).template Get<bool>()) {
- FilterWorkFinished = true;
- if constexpr (Inclusive) {
- return Iter.Next(value);
- } else {
- value = Item->GetValue(CompCtx);
- return true;
- }
+ FilterWorkFinished = true;
+ if constexpr (Inclusive) {
+ return Iter.Next(value);
+ } else {
+ value = Item->GetValue(CompCtx);
+ return true;
+ }
}
- }
+ }
} else {
- if (Iter.Next(Item->RefValue(CompCtx))) {
+ if (Iter.Next(Item->RefValue(CompCtx))) {
if (Predicate->GetValue(CompCtx).template Get<bool>()) {
value = Item->GetValue(CompCtx);
return true;
- } else {
- FilterWorkFinished = true;
- if constexpr (Inclusive) {
- value = Item->GetValue(CompCtx);
- return true;
- }
+ } else {
+ FilterWorkFinished = true;
+ if constexpr (Inclusive) {
+ value = Item->GetValue(CompCtx);
+ return true;
+ }
}
}
- }
+ }
+
+ return false;
+ }
- return false;
- }
-
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Iter;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Iter;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
- bool FilterWorkFinished = false;
+ bool FilterWorkFinished = false;
};
- TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, IComputationExternalNode* item, IComputationNode* predicate)
+ TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& list, IComputationExternalNode* item, IComputationNode* predicate)
: TCustomListValue(memInfo)
, CompCtx(compCtx)
, List(list)
, Item(item)
, Predicate(predicate)
- {}
+ {}
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, Predicate);
+ }
- private:
- NUdf::TUnboxedValue GetListIterator() const override {
- return CompCtx.HolderFactory.Create<TIterator>(CompCtx, List.GetListIterator(), Item, Predicate);
- }
-
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue List;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue List;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
@@ -195,7 +195,7 @@ protected:
public:
using TBase = TComputationValue<TStreamValue>;
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, IComputationExternalNode* item, IComputationNode* predicate)
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const NUdf::TUnboxedValue& stream, IComputationExternalNode* item, IComputationNode* predicate)
: TBase(memInfo)
, CompCtx(compCtx)
, Stream(stream)
@@ -204,7 +204,7 @@ protected:
{
}
- private:
+ private:
ui32 GetTraverseCount() const override {
return 1;
}
@@ -215,480 +215,480 @@ protected:
}
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- if (FilterWorkFinished) {
- return SkipOrTake ? Stream.Fetch(result) : NUdf::EFetchStatus::Finish;
+ if (FilterWorkFinished) {
+ return SkipOrTake ? Stream.Fetch(result) : NUdf::EFetchStatus::Finish;
}
- if constexpr (SkipOrTake) {
- for (;;) {
- if (const auto status = Stream.Fetch(Item->RefValue(CompCtx)); status != NUdf::EFetchStatus::Ok) {
+ if constexpr (SkipOrTake) {
+ for (;;) {
+ if (const auto status = Stream.Fetch(Item->RefValue(CompCtx)); status != NUdf::EFetchStatus::Ok) {
return status;
}
if (!Predicate->GetValue(CompCtx).template Get<bool>()) {
- FilterWorkFinished = true;
- if constexpr (Inclusive) {
- return Stream.Fetch(result);
- } else {
- result = Item->GetValue(CompCtx);
- return NUdf::EFetchStatus::Ok;
- }
+ FilterWorkFinished = true;
+ if constexpr (Inclusive) {
+ return Stream.Fetch(result);
+ } else {
+ result = Item->GetValue(CompCtx);
+ return NUdf::EFetchStatus::Ok;
+ }
}
}
} else {
- switch (const auto status = Stream.Fetch(Item->RefValue(CompCtx))) {
- case NUdf::EFetchStatus::Yield:
+ switch (const auto status = Stream.Fetch(Item->RefValue(CompCtx))) {
+ case NUdf::EFetchStatus::Yield:
return status;
- case NUdf::EFetchStatus::Ok:
+ case NUdf::EFetchStatus::Ok:
if (Predicate->GetValue(CompCtx).template Get<bool>()) {
result = Item->GetValue(CompCtx);
- return NUdf::EFetchStatus::Ok;
- }
- case NUdf::EFetchStatus::Finish:
+ return NUdf::EFetchStatus::Ok;
+ }
+ case NUdf::EFetchStatus::Finish:
break;
- }
-
- FilterWorkFinished = true;
- if constexpr (Inclusive) {
- result = Item->GetValue(CompCtx);
- return NUdf::EFetchStatus::Ok;
- } else {
- return NUdf::EFetchStatus::Finish;
- }
+ }
+
+ FilterWorkFinished = true;
+ if constexpr (Inclusive) {
+ result = Item->GetValue(CompCtx);
+ return NUdf::EFetchStatus::Ok;
+ } else {
+ return NUdf::EFetchStatus::Finish;
+ }
}
}
TComputationContext& CompCtx;
- const NUdf::TUnboxedValue Stream;
- IComputationExternalNode* const Item;
+ const NUdf::TUnboxedValue Stream;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
- bool FilterWorkFinished = false;
+ bool FilterWorkFinished = false;
};
#ifndef MKQL_DISABLE_CODEGEN
- class TStreamCodegenWhileValue : public TStreamCodegenStatefulValueT<> {
- public:
- TStreamCodegenWhileValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream)
- : TStreamCodegenStatefulValueT(memInfo, fetch, ctx, std::move(stream))
- {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- return State ?
- (SkipOrTake ? Stream.Fetch(result) : NUdf::EFetchStatus::Finish):
- TStreamCodegenStatefulValueT::Fetch(result);
- }
- };
-
- class TCodegenIteratorWhile : public TCodegenStatefulIterator<> {
- public:
- TCodegenIteratorWhile(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator, const NUdf::TUnboxedValue& init)
- : TCodegenStatefulIterator(memInfo, next, ctx, std::move(iterator), init)
- {}
-
- private:
- bool Next(NUdf::TUnboxedValue& value) final {
- return State ?
- (SkipOrTake ? Iterator.Next(value) : false):
- TCodegenStatefulIterator::Next(value);
- }
- };
-
- using TCustomListCodegenWhileValue = TCustomListCodegenStatefulValueT<TCodegenIteratorWhile>;
+ class TStreamCodegenWhileValue : public TStreamCodegenStatefulValueT<> {
+ public:
+ TStreamCodegenWhileValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream)
+ : TStreamCodegenStatefulValueT(memInfo, fetch, ctx, std::move(stream))
+ {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ return State ?
+ (SkipOrTake ? Stream.Fetch(result) : NUdf::EFetchStatus::Finish):
+ TStreamCodegenStatefulValueT::Fetch(result);
+ }
+ };
+
+ class TCodegenIteratorWhile : public TCodegenStatefulIterator<> {
+ public:
+ TCodegenIteratorWhile(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator, const NUdf::TUnboxedValue& init)
+ : TCodegenStatefulIterator(memInfo, next, ctx, std::move(iterator), init)
+ {}
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) final {
+ return State ?
+ (SkipOrTake ? Iterator.Next(value) : false):
+ TCodegenStatefulIterator::Next(value);
+ }
+ };
+
+ using TCustomListCodegenWhileValue = TCustomListCodegenStatefulValueT<TCodegenIteratorWhile>;
#endif
-
- TBaseWhileWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : List(list), Item(item), Predicate(predicate)
- {}
-
-#ifndef MKQL_DISABLE_CODEGEN
- Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
-
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
- const auto contextType = GetCompContextType(context);
- const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
- const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
-
- TCodegenContext ctx(codegen);
+
+ TBaseWhileWrapper(IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : List(list), Item(item), Predicate(predicate)
+ {}
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Function* GenerateFilter(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto containerType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ? static_cast<Type*>(PointerType::getUnqual(valueType)) : static_cast<Type*>(valueType);
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = IsStream ? Type::getInt32Ty(context) : Type::getInt1Ty(context);
+ const auto funcType = FunctionType::get(statusType, {PointerType::getUnqual(contextType), containerType, PointerType::getUnqual(valueType), PointerType::getUnqual(valueType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- ctx.Ctx = &*args;
- const auto containerArg = &*++args;
- const auto statePtr = &*++args;
- const auto valuePtr = &*++args;
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto loop = SkipOrTake ? BasicBlock::Create(context, "loop", ctx.Func) : nullptr;
- if (loop) {
- BranchInst::Create(loop, block);
- block = loop;
- }
-
- const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
- const auto status = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
-
- const auto icmp = IsStream ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
-
- BranchInst::Create(good, done, icmp, block);
- block = good;
-
- const auto item = new LoadInst(itemPtr, "item", block);
- const auto predicate = GetNodeValue(Predicate, ctx, block);
-
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(SkipOrTake ? loop : pass, stop, boolPred, block);
-
- block = stop;
- new StoreInst(GetTrue(context), statePtr, block);
-
- if constexpr (SkipOrTake) {
- if constexpr (Inclusive) {
- const auto last = IsStream ?
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, valuePtr):
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, valuePtr);
- ReturnInst::Create(context, last, block);
- } else {
- BranchInst::Create(pass, block);
- }
- } else {
- if constexpr (Inclusive) {
- BranchInst::Create(pass, block);
- } else {
- ReturnInst::Create(context, IsStream ? ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)) : ConstantInt::getFalse(context), block);
- }
- }
-
- block = pass;
-
- SafeUnRefUnboxed(valuePtr, ctx, block);
- new StoreInst(item, valuePtr, block);
- ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
- BranchInst::Create(done, block);
-
- block = done;
- ReturnInst::Create(context, status, block);
- return ctx.Func;
- }
-
- using TFilterPtr = std::conditional_t<IsStream, typename TStreamCodegenWhileValue::TFetchPtr, typename TCustomListCodegenWhileValue::TNextPtr>;
-
- Function* FilterFunc = nullptr;
-
- TFilterPtr Filter = nullptr;
-#endif
-
+
+ auto args = ctx.Func->arg_begin();
+
+ ctx.Ctx = &*args;
+ const auto containerArg = &*++args;
+ const auto statePtr = &*++args;
+ const auto valuePtr = &*++args;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto container = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ new LoadInst(containerArg, "load_container", false, block) : static_cast<Value*>(containerArg);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto loop = SkipOrTake ? BasicBlock::Create(context, "loop", ctx.Func) : nullptr;
+ if (loop) {
+ BranchInst::Create(loop, block);
+ block = loop;
+ }
+
+ const auto itemPtr = codegenItem->CreateRefValue(ctx, block);
+ const auto status = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, itemPtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, itemPtr);
+
+ const auto icmp = IsStream ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, status, ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Ok)), "cond", block) : status;
+
+ BranchInst::Create(good, done, icmp, block);
+ block = good;
+
+ const auto item = new LoadInst(itemPtr, "item", block);
+ const auto predicate = GetNodeValue(Predicate, ctx, block);
+
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(SkipOrTake ? loop : pass, stop, boolPred, block);
+
+ block = stop;
+ new StoreInst(GetTrue(context), statePtr, block);
+
+ if constexpr (SkipOrTake) {
+ if constexpr (Inclusive) {
+ const auto last = IsStream ?
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Fetch>(statusType, container, codegen, block, valuePtr):
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::Next>(statusType, container, codegen, block, valuePtr);
+ ReturnInst::Create(context, last, block);
+ } else {
+ BranchInst::Create(pass, block);
+ }
+ } else {
+ if constexpr (Inclusive) {
+ BranchInst::Create(pass, block);
+ } else {
+ ReturnInst::Create(context, IsStream ? ConstantInt::get(statusType, static_cast<ui32>(NUdf::EFetchStatus::Finish)) : ConstantInt::getFalse(context), block);
+ }
+ }
+
+ block = pass;
+
+ SafeUnRefUnboxed(valuePtr, ctx, block);
+ new StoreInst(item, valuePtr, block);
+ ValueAddRef(Item->GetRepresentation(), valuePtr, ctx, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ ReturnInst::Create(context, status, block);
+ return ctx.Func;
+ }
+
+ using TFilterPtr = std::conditional_t<IsStream, typename TStreamCodegenWhileValue::TFetchPtr, typename TCustomListCodegenWhileValue::TNextPtr>;
+
+ Function* FilterFunc = nullptr;
+
+ TFilterPtr Filter = nullptr;
+#endif
+
IComputationNode* const List;
- IComputationExternalNode* const Item;
+ IComputationExternalNode* const Item;
IComputationNode* const Predicate;
};
-template <bool SkipOrTake, bool Inclusive>
-class TStreamWhileWrapper : public TCustomValueCodegeneratorNode<TStreamWhileWrapper<SkipOrTake, Inclusive>>,
- private TBaseWhileWrapper<SkipOrTake, Inclusive, true> {
- typedef TBaseWhileWrapper<SkipOrTake, Inclusive, true> TBaseWrapper;
- typedef TCustomValueCodegeneratorNode<TStreamWhileWrapper<SkipOrTake, Inclusive>> TBaseComputation;
-public:
- TStreamWhileWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
-#ifndef MKQL_DISABLE_CODEGEN
- if (ctx.ExecuteLLVM && this->Filter)
- return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamCodegenWhileValue>(this->Filter, &ctx, this->List->GetValue(ctx));
-#endif
- return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, this->List->GetValue(ctx), this->Item, this->Predicate);
- }
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(this->List);
- this->Own(this->Item);
- this->DependsOn(this->Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- this->FilterFunc = this->GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
- codegen->ExportSymbol(this->FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (this->FilterFunc)
- this->Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(this->FilterFunc));
- }
-#endif
-};
-
-template <bool SkipOrTake, bool Inclusive>
-class TListWhileWrapper : public TBothWaysCodegeneratorNode<TListWhileWrapper<SkipOrTake, Inclusive>>,
- private TBaseWhileWrapper<SkipOrTake, Inclusive, false> {
- typedef TBaseWhileWrapper<SkipOrTake, Inclusive, false> TBaseWrapper;
- typedef TBothWaysCodegeneratorNode<TListWhileWrapper<SkipOrTake, Inclusive>> TBaseComputation;
-public:
- TListWhileWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
- : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto list = this->List->GetValue(ctx);
-
- if (const auto elements = list.GetElements()) {
- const auto size = list.GetListLength();
-
- const ui64 init = Inclusive ? 1ULL : 0ULL;
- auto todo = size;
-
- for (auto e = elements; todo > init; --todo) {
- this->Item->SetValue(ctx, NUdf::TUnboxedValue(*e++));
- if (!this->Predicate->GetValue(ctx).template Get<bool>())
- break;
- }
-
- if (init && todo) {
- todo -= init;
- }
-
- const auto pass = size - todo;
- const auto copy = SkipOrTake ? todo : pass;
-
- if (copy == size) {
- return list.Release();
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- const auto result = ctx.HolderFactory.CreateDirectArrayHolder(copy, items);
- const auto from = SkipOrTake ? elements + pass : elements;
- std::copy_n(from, copy, items);
- return result;
- }
-
- return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), this->Item, this->Predicate);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
- return ctx.HolderFactory.Create<typename TBaseWrapper::TCustomListCodegenWhileValue>(this->Filter, &ctx, value);
- }
-
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(this->Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto list = GetNodeValue(this->List, ctx, block);
-
- const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
- const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto out = PHINode::Create(list->getType(), 4U, "out", done);
-
- const auto elementsType = PointerType::getUnqual(list->getType());
- const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
- const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
-
- BranchInst::Create(hard, lazy, fill, block);
-
- {
- block = hard;
-
- const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
-
- const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
- const auto zero = ConstantInt::get(size->getType(), 0);
- index->addIncoming(zero, block);
-
- const auto none = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zero, size, "none", block);
-
- out->addIncoming(list, block);
- BranchInst::Create(done, loop, none, block);
-
- block = loop;
-
- const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
- const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
- const auto more = CmpInst::Create(Instruction::ICmp, Inclusive ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_ULE, plus, size, "more", block);
- BranchInst::Create(test, stop, more, block);
-
- block = test;
-
- const auto item = new LoadInst(ptr, "item", block);
- codegenItem->CreateSetValue(ctx, block, item);
- const auto predicate = GetNodeValue(this->Predicate, ctx, block);
- const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
- index->addIncoming(plus, block);
- BranchInst::Create(loop, stop, boolPred, block);
-
- block = stop;
-
- const auto pass = Inclusive ? static_cast<Value*>(plus) : static_cast<Value*>(index);
- const auto copy = SkipOrTake ? BinaryOperator::CreateSub(size, pass, "copy", block) : pass;
- const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, copy, "asis", block);
-
- out->addIncoming(list, block);
- BranchInst::Create(done, make, asis, block);
-
- block = make;
-
- const auto itemsPtr = *this->Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
- const auto array = GenNewArray(ctx, copy, itemsPtr, block);
- const auto items = new LoadInst(itemsPtr, "items", block);
- const auto from = SkipOrTake ? GetElementPtrInst::CreateInBounds(elements, {pass}, "from", block) : elements;
-
- const auto move = BasicBlock::Create(context, "move", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto idx = PHINode::Create(copy->getType(), 2U, "idx", move);
- idx->addIncoming(ConstantInt::get(copy->getType(), 0), block);
-
- BranchInst::Create(move, block);
-
- block = move;
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, idx, copy, "finish", block);
- BranchInst::Create(exit, step, finish, block);
-
- block = step;
-
- const auto src = GetElementPtrInst::CreateInBounds(from, {idx}, "src", block);
- const auto itm = new LoadInst(src, "item", block);
- ValueAddRef(this->Item->GetRepresentation(), itm, ctx, block);
- const auto dst = GetElementPtrInst::CreateInBounds(items, {idx}, "dst", block);
- new StoreInst(itm, dst, block);
- const auto inc = BinaryOperator::CreateAdd(idx, ConstantInt::get(idx->getType(), 1), "inc", block);
- idx->addIncoming(inc, block);
- BranchInst::Create(move, block);
-
- block = exit;
- if (this->List->IsTemporaryValue()) {
- CleanupBoxed(list, ctx, block);
- }
- out->addIncoming(array, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = lazy;
-
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListWhileWrapper::MakeLazyList));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
- out->addIncoming(value, block);
- } else {
- const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
- new StoreInst(list, resultPtr, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- out->addIncoming(value, block);
- }
- BranchInst::Create(done, block);
- }
-
- block = done;
- return out;
- }
-#endif
-
-private:
- void RegisterDependencies() const final {
- this->DependsOn(this->List);
- this->Own(this->Item);
- this->DependsOn(this->Predicate);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListWhileWrapper<SkipOrTake, Inclusive>>::GenerateFunctions(codegen);
- this->FilterFunc = this->GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
- codegen->ExportSymbol(this->FilterFunc);
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- TMutableCodegeneratorRootNode<TListWhileWrapper<SkipOrTake, Inclusive>>::FinalizeFunctions(codegen);
- if (this->FilterFunc)
- this->Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(this->FilterFunc));
- }
-#endif
-};
-
-template <bool SkipOrTake, bool Inclusive>
-IComputationNode* WrapFilterWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+template <bool SkipOrTake, bool Inclusive>
+class TStreamWhileWrapper : public TCustomValueCodegeneratorNode<TStreamWhileWrapper<SkipOrTake, Inclusive>>,
+ private TBaseWhileWrapper<SkipOrTake, Inclusive, true> {
+ typedef TBaseWhileWrapper<SkipOrTake, Inclusive, true> TBaseWrapper;
+ typedef TCustomValueCodegeneratorNode<TStreamWhileWrapper<SkipOrTake, Inclusive>> TBaseComputation;
+public:
+ TStreamWhileWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+#ifndef MKQL_DISABLE_CODEGEN
+ if (ctx.ExecuteLLVM && this->Filter)
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamCodegenWhileValue>(this->Filter, &ctx, this->List->GetValue(ctx));
+#endif
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TStreamValue>(ctx, this->List->GetValue(ctx), this->Item, this->Predicate);
+ }
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(this->List);
+ this->Own(this->Item);
+ this->DependsOn(this->Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ this->FilterFunc = this->GenerateFilter(codegen, TBaseComputation::MakeName("Fetch"));
+ codegen->ExportSymbol(this->FilterFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (this->FilterFunc)
+ this->Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(this->FilterFunc));
+ }
+#endif
+};
+
+template <bool SkipOrTake, bool Inclusive>
+class TListWhileWrapper : public TBothWaysCodegeneratorNode<TListWhileWrapper<SkipOrTake, Inclusive>>,
+ private TBaseWhileWrapper<SkipOrTake, Inclusive, false> {
+ typedef TBaseWhileWrapper<SkipOrTake, Inclusive, false> TBaseWrapper;
+ typedef TBothWaysCodegeneratorNode<TListWhileWrapper<SkipOrTake, Inclusive>> TBaseComputation;
+public:
+ TListWhileWrapper(TComputationMutables& mutables, IComputationNode* list, IComputationExternalNode* item, IComputationNode* predicate)
+ : TBaseComputation(mutables), TBaseWrapper(list, item, predicate)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto list = this->List->GetValue(ctx);
+
+ if (const auto elements = list.GetElements()) {
+ const auto size = list.GetListLength();
+
+ const ui64 init = Inclusive ? 1ULL : 0ULL;
+ auto todo = size;
+
+ for (auto e = elements; todo > init; --todo) {
+ this->Item->SetValue(ctx, NUdf::TUnboxedValue(*e++));
+ if (!this->Predicate->GetValue(ctx).template Get<bool>())
+ break;
+ }
+
+ if (init && todo) {
+ todo -= init;
+ }
+
+ const auto pass = size - todo;
+ const auto copy = SkipOrTake ? todo : pass;
+
+ if (copy == size) {
+ return list.Release();
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto result = ctx.HolderFactory.CreateDirectArrayHolder(copy, items);
+ const auto from = SkipOrTake ? elements + pass : elements;
+ std::copy_n(from, copy, items);
+ return result;
+ }
+
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TListValue>(ctx, std::move(list), this->Item, this->Predicate);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ NUdf::TUnboxedValuePod MakeLazyList(TComputationContext& ctx, const NUdf::TUnboxedValuePod value) const {
+ return ctx.HolderFactory.Create<typename TBaseWrapper::TCustomListCodegenWhileValue>(this->Filter, &ctx, value);
+ }
+
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(this->Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto list = GetNodeValue(this->List, ctx, block);
+
+ const auto lazy = BasicBlock::Create(context, "lazy", ctx.Func);
+ const auto hard = BasicBlock::Create(context, "hard", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto out = PHINode::Create(list->getType(), 4U, "out", done);
+
+ const auto elementsType = PointerType::getUnqual(list->getType());
+ const auto elements = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, list, ctx.Codegen, block);
+ const auto fill = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elements, ConstantPointerNull::get(elementsType), "fill", block);
+
+ BranchInst::Create(hard, lazy, fill, block);
+
+ {
+ block = hard;
+
+ const auto size = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetListLength>(Type::getInt64Ty(context), list, ctx.Codegen, block);
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+
+ const auto index = PHINode::Create(size->getType(), 2U, "index", loop);
+ const auto zero = ConstantInt::get(size->getType(), 0);
+ index->addIncoming(zero, block);
+
+ const auto none = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, zero, size, "none", block);
+
+ out->addIncoming(list, block);
+ BranchInst::Create(done, loop, none, block);
+
+ block = loop;
+
+ const auto ptr = GetElementPtrInst::CreateInBounds(elements, {index}, "ptr", block);
+ const auto plus = BinaryOperator::CreateAdd(index, ConstantInt::get(size->getType(), 1), "plus", block);
+ const auto more = CmpInst::Create(Instruction::ICmp, Inclusive ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_ULE, plus, size, "more", block);
+ BranchInst::Create(test, stop, more, block);
+
+ block = test;
+
+ const auto item = new LoadInst(ptr, "item", block);
+ codegenItem->CreateSetValue(ctx, block, item);
+ const auto predicate = GetNodeValue(this->Predicate, ctx, block);
+ const auto boolPred = CastInst::Create(Instruction::Trunc, predicate, Type::getInt1Ty(context), "bool", block);
+ index->addIncoming(plus, block);
+ BranchInst::Create(loop, stop, boolPred, block);
+
+ block = stop;
+
+ const auto pass = Inclusive ? static_cast<Value*>(plus) : static_cast<Value*>(index);
+ const auto copy = SkipOrTake ? BinaryOperator::CreateSub(size, pass, "copy", block) : pass;
+ const auto asis = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, size, copy, "asis", block);
+
+ out->addIncoming(list, block);
+ BranchInst::Create(done, make, asis, block);
+
+ block = make;
+
+ const auto itemsPtr = *this->Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(list->getType()), 0U, "items_ptr", block);
+ const auto array = GenNewArray(ctx, copy, itemsPtr, block);
+ const auto items = new LoadInst(itemsPtr, "items", block);
+ const auto from = SkipOrTake ? GetElementPtrInst::CreateInBounds(elements, {pass}, "from", block) : elements;
+
+ const auto move = BasicBlock::Create(context, "move", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto idx = PHINode::Create(copy->getType(), 2U, "idx", move);
+ idx->addIncoming(ConstantInt::get(copy->getType(), 0), block);
+
+ BranchInst::Create(move, block);
+
+ block = move;
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, idx, copy, "finish", block);
+ BranchInst::Create(exit, step, finish, block);
+
+ block = step;
+
+ const auto src = GetElementPtrInst::CreateInBounds(from, {idx}, "src", block);
+ const auto itm = new LoadInst(src, "item", block);
+ ValueAddRef(this->Item->GetRepresentation(), itm, ctx, block);
+ const auto dst = GetElementPtrInst::CreateInBounds(items, {idx}, "dst", block);
+ new StoreInst(itm, dst, block);
+ const auto inc = BinaryOperator::CreateAdd(idx, ConstantInt::get(idx->getType(), 1), "inc", block);
+ idx->addIncoming(inc, block);
+ BranchInst::Create(move, block);
+
+ block = exit;
+ if (this->List->IsTemporaryValue()) {
+ CleanupBoxed(list, ctx, block);
+ }
+ out->addIncoming(array, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = lazy;
+
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TListWhileWrapper::MakeLazyList));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(list->getType() , {self->getType(), ctx.Ctx->getType(), list->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx, list}, "value", block);
+ out->addIncoming(value, block);
+ } else {
+ const auto resultPtr = new AllocaInst(list->getType(), 0U, "return", block);
+ new StoreInst(list, resultPtr, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType(), resultPtr->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx, resultPtr}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ out->addIncoming(value, block);
+ }
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return out;
+ }
+#endif
+
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(this->List);
+ this->Own(this->Item);
+ this->DependsOn(this->Predicate);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListWhileWrapper<SkipOrTake, Inclusive>>::GenerateFunctions(codegen);
+ this->FilterFunc = this->GenerateFilter(codegen, TBaseComputation::MakeName("Next"));
+ codegen->ExportSymbol(this->FilterFunc);
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ TMutableCodegeneratorRootNode<TListWhileWrapper<SkipOrTake, Inclusive>>::FinalizeFunctions(codegen);
+ if (this->FilterFunc)
+ this->Filter = reinterpret_cast<typename TBaseWrapper::TFilterPtr>(codegen->GetPointerToFunction(this->FilterFunc));
+ }
+#endif
+};
+
+template <bool SkipOrTake, bool Inclusive>
+IComputationNode* WrapFilterWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 3, "Expected 3 args");
- const auto type = callable.GetType()->GetReturnType();
-
- const auto predicateType = AS_TYPE(TDataType, callable.GetInput(2));
- MKQL_ENSURE(predicateType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
- const auto predicate = LocateNode(ctx.NodeLocator, callable, 2);
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
- if (type->IsFlow()) {
- return new TWhileFlowWrapper<SkipOrTake, Inclusive>(ctx.Mutables, GetValueRepresentation(type), flow, itemArg, predicate);
- } else if (type->IsStream()) {
- return new TStreamWhileWrapper<SkipOrTake, Inclusive>(ctx.Mutables, flow, itemArg, predicate);
- } else if (type->IsList()) {
- return new TListWhileWrapper<SkipOrTake, Inclusive>(ctx.Mutables, flow, itemArg, predicate);
+ const auto type = callable.GetType()->GetReturnType();
+
+ const auto predicateType = AS_TYPE(TDataType, callable.GetInput(2));
+ MKQL_ENSURE(predicateType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0);
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, 2);
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1);
+ if (type->IsFlow()) {
+ return new TWhileFlowWrapper<SkipOrTake, Inclusive>(ctx.Mutables, GetValueRepresentation(type), flow, itemArg, predicate);
+ } else if (type->IsStream()) {
+ return new TStreamWhileWrapper<SkipOrTake, Inclusive>(ctx.Mutables, flow, itemArg, predicate);
+ } else if (type->IsList()) {
+ return new TListWhileWrapper<SkipOrTake, Inclusive>(ctx.Mutables, flow, itemArg, predicate);
}
-
- THROW yexception() << "Expected flow, list or stream.";
+
+ THROW yexception() << "Expected flow, list or stream.";
+}
+
}
-}
-
IComputationNode* WrapTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapFilterWhile<false, false>(callable, ctx);
+ return WrapFilterWhile<false, false>(callable, ctx);
}
IComputationNode* WrapSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapFilterWhile<true, false>(callable, ctx);
+ return WrapFilterWhile<true, false>(callable, ctx);
+}
+
+IComputationNode* WrapTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapFilterWhile<false, true>(callable, ctx);
+}
+
+IComputationNode* WrapSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapFilterWhile<true, true>(callable, ctx);
}
-IComputationNode* WrapTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapFilterWhile<false, true>(callable, ctx);
}
-
-IComputationNode* WrapSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapFilterWhile<true, true>(callable, ctx);
}
-
-}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_while.h b/ydb/library/yql/minikql/comp_nodes/mkql_while.h
index 5226b049e9..958f5dc1e4 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_while.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_while.h
@@ -6,8 +6,8 @@ namespace NMiniKQL {
IComputationNode* WrapTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
IComputationNode* WrapSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.cpp
index f61450b5a1..00ef832c57 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.cpp
@@ -1,295 +1,295 @@
-#include "mkql_wide_chain_map.h"
+#include "mkql_wide_chain_map.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/computation/mkql_custom_list.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/utils/cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-class TWideChain1MapWrapper : public TStatefulWideFlowCodegeneratorNode<TWideChain1MapWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideChain1MapWrapper>;
-public:
- TWideChain1MapWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow,
- TComputationExternalNodePtrVector&& inputs,
- TComputationNodePtrVector&& initItems,
- TComputationExternalNodePtrVector&& outputs,
- TComputationNodePtrVector&& updateItems):
- TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow),
- Inputs(std::move(inputs)), InitItems(std::move(initItems)), Outputs(std::move(outputs)), UpdateItems(std::move(updateItems)),
- InputsOnInit(GetPasstroughtMap(Inputs, InitItems)), InputsOnUpdate(GetPasstroughtMap(Inputs, UpdateItems)),
- InitOnInputs(GetPasstroughtMap(InitItems, Inputs)), UpdateOnInputs(GetPasstroughtMap(UpdateItems, Inputs)),
- OutputsOnUpdate(GetPasstroughtMap(Outputs, UpdateItems)), UpdateOnOutputs(GetPasstroughtMap(UpdateItems, Outputs)),
- Fields(Inputs.size(), nullptr), TempState(Outputs.size())
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = NUdf::TUnboxedValuePod();
- return CalculateFirst(ctx, output);
- }
-
- return CalculateOther(ctx, output);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto flagPtr = new AllocaInst(Type::getInt1Ty(context), 0U, "flag_ptr", &ctx.Func->getEntryBlock().back());
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
- BranchInst::Create(done, good, special, block);
-
- block = good;
- for (auto i = 0U; i < Inputs.size(); ++i)
- if (Inputs[i]->GetDependencesCount() > 0U)
+namespace {
+
+class TWideChain1MapWrapper : public TStatefulWideFlowCodegeneratorNode<TWideChain1MapWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideChain1MapWrapper>;
+public:
+ TWideChain1MapWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow,
+ TComputationExternalNodePtrVector&& inputs,
+ TComputationNodePtrVector&& initItems,
+ TComputationExternalNodePtrVector&& outputs,
+ TComputationNodePtrVector&& updateItems):
+ TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow),
+ Inputs(std::move(inputs)), InitItems(std::move(initItems)), Outputs(std::move(outputs)), UpdateItems(std::move(updateItems)),
+ InputsOnInit(GetPasstroughtMap(Inputs, InitItems)), InputsOnUpdate(GetPasstroughtMap(Inputs, UpdateItems)),
+ InitOnInputs(GetPasstroughtMap(InitItems, Inputs)), UpdateOnInputs(GetPasstroughtMap(UpdateItems, Inputs)),
+ OutputsOnUpdate(GetPasstroughtMap(Outputs, UpdateItems)), UpdateOnOutputs(GetPasstroughtMap(UpdateItems, Outputs)),
+ Fields(Inputs.size(), nullptr), TempState(Outputs.size())
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = NUdf::TUnboxedValuePod();
+ return CalculateFirst(ctx, output);
+ }
+
+ return CalculateOther(ctx, output);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto flagPtr = new AllocaInst(Type::getInt1Ty(context), 0U, "flag_ptr", &ctx.Func->getEntryBlock().back());
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+ for (auto i = 0U; i < Inputs.size(); ++i)
+ if (Inputs[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Inputs[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- const auto flag = IsInvalid(statePtr, block);
- new StoreInst(flag, flagPtr, block);
- BranchInst::Create(init, next, flag, block);
-
- block = init;
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
- const auto& map = InitOnInputs[i];
- const auto value = map ? getres.second[*map](ctx, block) : GetNodeValue(InitItems[i], ctx, block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ const auto flag = IsInvalid(statePtr, block);
+ new StoreInst(flag, flagPtr, block);
+ BranchInst::Create(init, next, flag, block);
+
+ block = init;
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
+ const auto& map = InitOnInputs[i];
+ const auto value = map ? getres.second[*map](ctx, block) : GetNodeValue(InitItems[i], ctx, block);
EnsureDynamicCast<ICodegeneratorExternalNode*>(Outputs[i])->CreateSetValue(ctx, block, value);
- }
- }
-
- new StoreInst(GetEmpty(context), statePtr, block);
- BranchInst::Create(done, block);
-
- block = next;
-
- std::vector<Value*> outputs(Outputs.size(), nullptr);
- for (auto i = 0U; i < outputs.size(); ++i) {
- if (const auto& dep = OutputsOnUpdate[i]; Outputs[i]->GetDependencesCount() > 0U || (dep && *dep != i)) {
- const auto& map = UpdateOnInputs[i];
- outputs[i] = map ? getres.second[*map](ctx, block) : GetNodeValue(UpdateItems[i], ctx, block);
- }
- }
-
- for (auto i = 0U; i < outputs.size(); ++i)
- if (const auto out = outputs[i])
+ }
+ }
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+ BranchInst::Create(done, block);
+
+ block = next;
+
+ std::vector<Value*> outputs(Outputs.size(), nullptr);
+ for (auto i = 0U; i < outputs.size(); ++i) {
+ if (const auto& dep = OutputsOnUpdate[i]; Outputs[i]->GetDependencesCount() > 0U || (dep && *dep != i)) {
+ const auto& map = UpdateOnInputs[i];
+ outputs[i] = map ? getres.second[*map](ctx, block) : GetNodeValue(UpdateItems[i], ctx, block);
+ }
+ }
+
+ for (auto i = 0U; i < outputs.size(); ++i)
+ if (const auto out = outputs[i])
EnsureDynamicCast<ICodegeneratorExternalNode*>(Outputs[i])->CreateSetValue(ctx, block, out);
-
- BranchInst::Create(done, block);
-
- block = done;
-
- ICodegeneratorInlineWideNode::TGettersList result;
- result.reserve(Outputs.size());
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (const auto& one = InitOnInputs[i], two = UpdateOnInputs[i]; one && two && *one == *two)
- result.emplace_back(getres.second[*two]);
- else if (Outputs[i]->GetDependencesCount() > 0 || OutputsOnUpdate[i])
- result.emplace_back([output = Outputs[i]] (const TCodegenContext& ctx, BasicBlock*& block) { return GetNodeValue(output, ctx, block); });
- else
- result.emplace_back([this, i, source = getres.second, flagPtr] (const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", done);
-
- const auto flag = new LoadInst(flagPtr, "flag", block);
- BranchInst::Create(init, next, flag, block);
-
- block = init;
- if (const auto& map = InitOnInputs[i])
- result->addIncoming(source[*map](ctx, block), block);
- else
- result->addIncoming(GetNodeValue(InitItems[i], ctx, block), block);
- BranchInst::Create(done, block);
-
- block = next;
- if (const auto& map = UpdateOnInputs[i])
- result->addIncoming(source[*map](ctx, block), block);
- else
- result->addIncoming(GetNodeValue(UpdateItems[i], ctx, block), block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- });
- };
- return {getres.first, std::move(result)};
- }
-#endif
-private:
- EFetchResult CalculateFirst(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < Fields.size(); ++i) {
- if (Inputs[i]->GetDependencesCount() > 0U) {
- Fields[i] = &Inputs[i]->RefValue(ctx);
- continue;
- } else if (const auto& map = InputsOnInit[i]) {
- if (const auto& to = UpdateOnOutputs[*map]) {
- Fields[i] = &Outputs[*to]->RefValue(ctx);
- continue;
- } else if (const auto out = output[*map]) {
- Fields[i] = out;
- continue;
- }
- }
-
- Fields[i] = nullptr;
- }
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
- if (const auto& map = InitOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
- Outputs[i]->SetValue(ctx, InitItems[i]->GetValue(ctx));
- }
- }
- }
-
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (const auto out = output[i]) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i])
- *out = Outputs[i]->GetValue(ctx);
- else {
- if (const auto& map = InitOnInputs[i]) {
- if (const auto from = *map; !Inputs[from]->GetDependencesCount()) {
- if (const auto first = *InputsOnInit[from]; first != i)
- *out = *output[first];
- continue;
- }
- }
-
- *out = InitItems[i]->GetValue(ctx);
- }
- }
- }
-
- return EFetchResult::One;
- }
-
- EFetchResult CalculateOther(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < Fields.size(); ++i) {
- if (Inputs[i]->GetDependencesCount() > 0U) {
- Fields[i] = &Inputs[i]->RefValue(ctx);
- continue;
- } else if (const auto& map = InputsOnUpdate[i]) {
- if (const auto out = output[*map]) {
- Fields[i] = out;
- continue;
- }
- }
-
- Fields[i] = nullptr;
- }
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
- if (const auto& map = UpdateOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
- TempState[i] = UpdateItems[i]->GetValue(ctx);
- }
- }
- }
-
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
- if (const auto& map = UpdateOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
- Outputs[i]->SetValue(ctx, std::move(TempState[i]));
- }
- }
- }
-
- for (auto i = 0U; i < Outputs.size(); ++i) {
- if (const auto out = output[i]) {
- if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i])
- *out = Outputs[i]->GetValue(ctx);
- else {
- if (const auto& map = UpdateOnInputs[i]) {
- if (const auto from = *map; !Inputs[from]->GetDependencesCount()) {
- if (const auto first = *InputsOnUpdate[from]; first != i)
- *out = *output[first];
- continue;
- }
- }
-
- *out = UpdateItems[i]->GetValue(ctx);
- }
- }
- }
-
- return EFetchResult::One;
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Inputs.cbegin(), Inputs.cend(), std::bind(&TWideChain1MapWrapper::Own, flow, std::placeholders::_1));
- std::for_each(Outputs.cbegin(), Outputs.cend(), std::bind(&TWideChain1MapWrapper::Own, flow, std::placeholders::_1));
- std::for_each(InitItems.cbegin(), InitItems.cend(), std::bind(&TWideChain1MapWrapper::DependsOn, flow, std::placeholders::_1));
- std::for_each(UpdateItems.cbegin(), UpdateItems.cend(), std::bind(&TWideChain1MapWrapper::DependsOn, flow, std::placeholders::_1));
- }
- }
-
- IComputationWideFlowNode* const Flow;
-
- const TComputationExternalNodePtrVector Inputs;
- const TComputationNodePtrVector InitItems;
- const TComputationExternalNodePtrVector Outputs;
- const TComputationNodePtrVector UpdateItems;
-
- const TPasstroughtMap InputsOnInit, InputsOnUpdate, InitOnInputs, UpdateOnInputs, OutputsOnUpdate, UpdateOnOutputs;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
- mutable std::vector<NUdf::TUnboxedValue> TempState;
-};
-
-}
-
-IComputationNode* WrapWideChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected argument.");
- const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == inputWidth + outputWidth * 3U + 1U, "Wrong signature.");
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- TComputationNodePtrVector initOutput(outputWidth, nullptr), updateOutput(outputWidth, nullptr);
- auto index = inputWidth;
- std::generate(initOutput.begin(), initOutput.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- index += outputWidth;
- std::generate(updateOutput.begin(), updateOutput.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- TComputationExternalNodePtrVector inputs(inputWidth, nullptr), outputs(outputWidth, nullptr);
- index = 0U;
- std::generate(inputs.begin(), inputs.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- index += outputWidth;
- std::generate(outputs.begin(), outputs.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- return new TWideChain1MapWrapper(ctx.Mutables, wide, std::move(inputs), std::move(initOutput), std::move(outputs), std::move(updateOutput));
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-}
+
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ ICodegeneratorInlineWideNode::TGettersList result;
+ result.reserve(Outputs.size());
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (const auto& one = InitOnInputs[i], two = UpdateOnInputs[i]; one && two && *one == *two)
+ result.emplace_back(getres.second[*two]);
+ else if (Outputs[i]->GetDependencesCount() > 0 || OutputsOnUpdate[i])
+ result.emplace_back([output = Outputs[i]] (const TCodegenContext& ctx, BasicBlock*& block) { return GetNodeValue(output, ctx, block); });
+ else
+ result.emplace_back([this, i, source = getres.second, flagPtr] (const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 2U, "result", done);
+
+ const auto flag = new LoadInst(flagPtr, "flag", block);
+ BranchInst::Create(init, next, flag, block);
+
+ block = init;
+ if (const auto& map = InitOnInputs[i])
+ result->addIncoming(source[*map](ctx, block), block);
+ else
+ result->addIncoming(GetNodeValue(InitItems[i], ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = next;
+ if (const auto& map = UpdateOnInputs[i])
+ result->addIncoming(source[*map](ctx, block), block);
+ else
+ result->addIncoming(GetNodeValue(UpdateItems[i], ctx, block), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ });
+ };
+ return {getres.first, std::move(result)};
+ }
+#endif
+private:
+ EFetchResult CalculateFirst(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < Fields.size(); ++i) {
+ if (Inputs[i]->GetDependencesCount() > 0U) {
+ Fields[i] = &Inputs[i]->RefValue(ctx);
+ continue;
+ } else if (const auto& map = InputsOnInit[i]) {
+ if (const auto& to = UpdateOnOutputs[*map]) {
+ Fields[i] = &Outputs[*to]->RefValue(ctx);
+ continue;
+ } else if (const auto out = output[*map]) {
+ Fields[i] = out;
+ continue;
+ }
+ }
+
+ Fields[i] = nullptr;
+ }
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
+ if (const auto& map = InitOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
+ Outputs[i]->SetValue(ctx, InitItems[i]->GetValue(ctx));
+ }
+ }
+ }
+
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (const auto out = output[i]) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i])
+ *out = Outputs[i]->GetValue(ctx);
+ else {
+ if (const auto& map = InitOnInputs[i]) {
+ if (const auto from = *map; !Inputs[from]->GetDependencesCount()) {
+ if (const auto first = *InputsOnInit[from]; first != i)
+ *out = *output[first];
+ continue;
+ }
+ }
+
+ *out = InitItems[i]->GetValue(ctx);
+ }
+ }
+ }
+
+ return EFetchResult::One;
+ }
+
+ EFetchResult CalculateOther(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < Fields.size(); ++i) {
+ if (Inputs[i]->GetDependencesCount() > 0U) {
+ Fields[i] = &Inputs[i]->RefValue(ctx);
+ continue;
+ } else if (const auto& map = InputsOnUpdate[i]) {
+ if (const auto out = output[*map]) {
+ Fields[i] = out;
+ continue;
+ }
+ }
+
+ Fields[i] = nullptr;
+ }
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
+ if (const auto& map = UpdateOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
+ TempState[i] = UpdateItems[i]->GetValue(ctx);
+ }
+ }
+ }
+
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i]) {
+ if (const auto& map = UpdateOnInputs[i]; !map || Inputs[*map]->GetDependencesCount() > 0U) {
+ Outputs[i]->SetValue(ctx, std::move(TempState[i]));
+ }
+ }
+ }
+
+ for (auto i = 0U; i < Outputs.size(); ++i) {
+ if (const auto out = output[i]) {
+ if (Outputs[i]->GetDependencesCount() > 0U || OutputsOnUpdate[i])
+ *out = Outputs[i]->GetValue(ctx);
+ else {
+ if (const auto& map = UpdateOnInputs[i]) {
+ if (const auto from = *map; !Inputs[from]->GetDependencesCount()) {
+ if (const auto first = *InputsOnUpdate[from]; first != i)
+ *out = *output[first];
+ continue;
+ }
+ }
+
+ *out = UpdateItems[i]->GetValue(ctx);
+ }
+ }
+ }
+
+ return EFetchResult::One;
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Inputs.cbegin(), Inputs.cend(), std::bind(&TWideChain1MapWrapper::Own, flow, std::placeholders::_1));
+ std::for_each(Outputs.cbegin(), Outputs.cend(), std::bind(&TWideChain1MapWrapper::Own, flow, std::placeholders::_1));
+ std::for_each(InitItems.cbegin(), InitItems.cend(), std::bind(&TWideChain1MapWrapper::DependsOn, flow, std::placeholders::_1));
+ std::for_each(UpdateItems.cbegin(), UpdateItems.cend(), std::bind(&TWideChain1MapWrapper::DependsOn, flow, std::placeholders::_1));
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+
+ const TComputationExternalNodePtrVector Inputs;
+ const TComputationNodePtrVector InitItems;
+ const TComputationExternalNodePtrVector Outputs;
+ const TComputationNodePtrVector UpdateItems;
+
+ const TPasstroughtMap InputsOnInit, InputsOnUpdate, InitOnInputs, UpdateOnInputs, OutputsOnUpdate, UpdateOnOutputs;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+ mutable std::vector<NUdf::TUnboxedValue> TempState;
+};
+
+}
+
+IComputationNode* WrapWideChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected argument.");
+ const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == inputWidth + outputWidth * 3U + 1U, "Wrong signature.");
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ TComputationNodePtrVector initOutput(outputWidth, nullptr), updateOutput(outputWidth, nullptr);
+ auto index = inputWidth;
+ std::generate(initOutput.begin(), initOutput.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ index += outputWidth;
+ std::generate(updateOutput.begin(), updateOutput.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ TComputationExternalNodePtrVector inputs(inputWidth, nullptr), outputs(outputWidth, nullptr);
+ index = 0U;
+ std::generate(inputs.begin(), inputs.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ index += outputWidth;
+ std::generate(outputs.begin(), outputs.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ return new TWideChain1MapWrapper(ctx.Mutables, wide, std::move(inputs), std::move(initOutput), std::move(outputs), std::move(updateOutput));
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.h
index ba049e0421..a60e1a358b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chain_map.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapWideChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapWideChain1Map(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.cpp
index b85052a144..adb3a65dc4 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.cpp
@@ -1,374 +1,374 @@
-#include "mkql_chopper.h"
-
+#include "mkql_chopper.h"
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/utils/cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-using namespace std::placeholders;
-
-class TWideChopperWrapper : public TStatefulWideFlowCodegeneratorNode<TWideChopperWrapper> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideChopperWrapper>;
-public:
- enum class EState : ui64 {
- Work,
- Chop,
- Next,
- Skip
- };
-
- TWideChopperWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& itemArgs, TComputationNodePtrVector&& keys, TComputationExternalNodePtrVector&& keyArgs, IComputationNode* chop, IComputationWideFlowProxyNode* input, IComputationWideFlowNode* output)
- : TBaseComputation(mutables, flow, EValueRepresentation::Any)
- , Flow(flow)
- , ItemArgs(std::move(itemArgs))
- , Keys(std::move(keys))
- , KeyArgs(std::move(keyArgs))
- , Chop(chop)
- , Input(input)
- , Output(output)
- , ItemsOnKeys(GetPasstroughtMap(ItemArgs, Keys))
- , KeysOnItems(GetPasstroughtMap(Keys, ItemArgs))
- , SwitchItem(IsPasstrought(Chop, ItemArgs))
- , Fields(ItemArgs.size(), nullptr)
- {
- Input->SetFetcher(std::bind(&TWideChopperWrapper::DoCalculateInput, this, std::bind(&TWideChopperWrapper::RefState, this, _1), _1, _2));
- }
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- for (auto i = 0U; i < Fields.size(); ++i)
- Fields[i] = &ItemArgs[i]->RefValue(ctx);
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- for (ui32 i = 0U; i < Keys.size(); ++i)
- if (KeyArgs[i]->GetDependencesCount() > 0U)
- KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- } else if (EState::Skip == EState(state.Get<ui64>())) {
- do {
- for (auto i = 0U; i < Fields.size(); ++i)
- Fields[i] = &ItemArgs[i]->RefValue(ctx);
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- } while (!Chop->GetValue(ctx).Get<bool>());
-
- for (ui32 i = 0U; i < Keys.size(); ++i)
- if (KeyArgs[i]->GetDependencesCount() > 0U)
- KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- }
-
- while (true) {
- if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish == result) {
- Input->InvalidateValue(ctx);
- switch (EState(state.Get<ui64>())) {
- case EState::Work:
- case EState::Next:
- do {
- for (auto i = 0U; i < Fields.size(); ++i)
- Fields[i] = &ItemArgs[i]->RefValue(ctx);
- switch (const auto next = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Yield:
- state = NUdf::TUnboxedValuePod(ui64(EState::Skip));
- case EFetchResult::Finish:
- return next;
- case EFetchResult::One:
- break;
- }
- } while (!Chop->GetValue(ctx).Get<bool>());
- case EState::Chop:
- for (ui32 i = 0U; i < Keys.size(); ++i)
- if (KeyArgs[i]->GetDependencesCount() > 0U)
- KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
- state = NUdf::TUnboxedValuePod(ui64(EState::Next));
- default:
- continue;
- }
- } else
- return result;
- }
- }
-private:
- EFetchResult DoCalculateInput(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (EState::Next == EState(state.Get<ui64>())) {
- state = NUdf::TUnboxedValuePod(ui64(EState::Work));
- for (auto i = 0U; i < Fields.size(); ++i)
- if (const auto out = output[i])
- *out = ItemArgs[i]->GetValue(ctx);
- return EFetchResult::One;
- }
-
- for (auto i = 0U; i < Fields.size(); ++i)
- Fields[i] = &ItemArgs[i]->RefValue(ctx);
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- for (auto i = 0U; i < Fields.size(); ++i)
- if (const auto out = output[i])
- *out = *Fields[i];
-
- if (Chop->GetValue(ctx).Get<bool>()) {
- state = NUdf::TUnboxedValuePod(ui64(EState::Chop));
- return EFetchResult::Finish;
- }
-
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValuesInput(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto load = BasicBlock::Create(context, "load", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 4U, "result", done);
-
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
- const auto entry = new LoadInst(statePtr, "entry", block);
- const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, entry, GetConstant(ui64(EState::Next), context), "next", block);
-
- BranchInst::Create(load, work, next, block);
-
- block = load;
-
- new StoreInst(GetConstant(ui64(EState::Work), context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
-
- BranchInst::Create(done, block);
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
-
- block = work;
-
- auto getres = GetNodeValues(Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
- result->addIncoming(getres.first, block);
- BranchInst::Create(done, good, special, block);
-
- block = good;
-
- std::vector<Value*> items(ItemArgs.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
+namespace {
+
+using namespace std::placeholders;
+
+class TWideChopperWrapper : public TStatefulWideFlowCodegeneratorNode<TWideChopperWrapper> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideChopperWrapper>;
+public:
+ enum class EState : ui64 {
+ Work,
+ Chop,
+ Next,
+ Skip
+ };
+
+ TWideChopperWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& itemArgs, TComputationNodePtrVector&& keys, TComputationExternalNodePtrVector&& keyArgs, IComputationNode* chop, IComputationWideFlowProxyNode* input, IComputationWideFlowNode* output)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Any)
+ , Flow(flow)
+ , ItemArgs(std::move(itemArgs))
+ , Keys(std::move(keys))
+ , KeyArgs(std::move(keyArgs))
+ , Chop(chop)
+ , Input(input)
+ , Output(output)
+ , ItemsOnKeys(GetPasstroughtMap(ItemArgs, Keys))
+ , KeysOnItems(GetPasstroughtMap(Keys, ItemArgs))
+ , SwitchItem(IsPasstrought(Chop, ItemArgs))
+ , Fields(ItemArgs.size(), nullptr)
+ {
+ Input->SetFetcher(std::bind(&TWideChopperWrapper::DoCalculateInput, this, std::bind(&TWideChopperWrapper::RefState, this, _1), _1, _2));
+ }
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ Fields[i] = &ItemArgs[i]->RefValue(ctx);
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ for (ui32 i = 0U; i < Keys.size(); ++i)
+ if (KeyArgs[i]->GetDependencesCount() > 0U)
+ KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ } else if (EState::Skip == EState(state.Get<ui64>())) {
+ do {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ Fields[i] = &ItemArgs[i]->RefValue(ctx);
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ } while (!Chop->GetValue(ctx).Get<bool>());
+
+ for (ui32 i = 0U; i < Keys.size(); ++i)
+ if (KeyArgs[i]->GetDependencesCount() > 0U)
+ KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ }
+
+ while (true) {
+ if (const auto result = Output->FetchValues(ctx, output); EFetchResult::Finish == result) {
+ Input->InvalidateValue(ctx);
+ switch (EState(state.Get<ui64>())) {
+ case EState::Work:
+ case EState::Next:
+ do {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ Fields[i] = &ItemArgs[i]->RefValue(ctx);
+ switch (const auto next = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Yield:
+ state = NUdf::TUnboxedValuePod(ui64(EState::Skip));
+ case EFetchResult::Finish:
+ return next;
+ case EFetchResult::One:
+ break;
+ }
+ } while (!Chop->GetValue(ctx).Get<bool>());
+ case EState::Chop:
+ for (ui32 i = 0U; i < Keys.size(); ++i)
+ if (KeyArgs[i]->GetDependencesCount() > 0U)
+ KeyArgs[i]->SetValue(ctx, Keys[i]->GetValue(ctx));
+ state = NUdf::TUnboxedValuePod(ui64(EState::Next));
+ default:
+ continue;
+ }
+ } else
+ return result;
+ }
+ }
+private:
+ EFetchResult DoCalculateInput(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (EState::Next == EState(state.Get<ui64>())) {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Work));
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (const auto out = output[i])
+ *out = ItemArgs[i]->GetValue(ctx);
+ return EFetchResult::One;
+ }
+
+ for (auto i = 0U; i < Fields.size(); ++i)
+ Fields[i] = &ItemArgs[i]->RefValue(ctx);
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (const auto out = output[i])
+ *out = *Fields[i];
+
+ if (Chop->GetValue(ctx).Get<bool>()) {
+ state = NUdf::TUnboxedValuePod(ui64(EState::Chop));
+ return EFetchResult::Finish;
+ }
+
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValuesInput(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto load = BasicBlock::Create(context, "load", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 4U, "result", done);
+
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+ const auto entry = new LoadInst(statePtr, "entry", block);
+ const auto next = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, entry, GetConstant(ui64(EState::Next), context), "next", block);
+
+ BranchInst::Create(load, work, next, block);
+
+ block = load;
+
+ new StoreInst(GetConstant(ui64(EState::Work), context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+
+ BranchInst::Create(done, block);
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+
+ block = work;
+
+ auto getres = GetNodeValues(Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), 0), "special", block);
+ result->addIncoming(getres.first, block);
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+
+ std::vector<Value*> items(ItemArgs.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(ItemArgs[i])->CreateSetValue(ctx, block, items[i] = getres.second[i](ctx, block));
- }
-
- const auto chop = SwitchItem ? items[*SwitchItem] : GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
- BranchInst::Create(step, done, cast, block);
-
- block = step;
-
- new StoreInst(GetConstant(ui64(EState::Chop), context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
- BranchInst::Create(done, block);
-
- block = done;
-
- ICodegeneratorInlineWideNode::TGettersList getters;
- getters.reserve(ItemArgs.size());
- std::transform(ItemArgs.cbegin(), ItemArgs.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
- return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- });
- return {result, std::move(getters)};
- }
-public:
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ }
+
+ const auto chop = SwitchItem ? items[*SwitchItem] : GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+ BranchInst::Create(step, done, cast, block);
+
+ block = step;
+
+ new StoreInst(GetConstant(ui64(EState::Chop), context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ ICodegeneratorInlineWideNode::TGettersList getters;
+ getters.reserve(ItemArgs.size());
+ std::transform(ItemArgs.cbegin(), ItemArgs.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
+ return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ });
+ return {result, std::move(getters)};
+ }
+public:
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
EnsureDynamicCast<IWideFlowProxyCodegeneratorNode*>(Input)->SetGenerator(std::bind(&TWideChopperWrapper::DoGenGetValuesInput, this, _1, _2));
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 5U, "result", exit);
-
- const auto first = new LoadInst(statePtr, "first", block);
- const auto enter = SwitchInst::Create(first, loop, 2U, block);
- enter->addCase(GetInvalid(context), init);
- enter->addCase(GetConstant(ui64(EState::Skip), context), pass);
-
-
- {
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- block = init;
-
- const auto getfirst = GetNodeValues(Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getfirst.first, ConstantInt::get(getfirst.first->getType(), 0), "special", block);
- result->addIncoming(getfirst.first, block);
- BranchInst::Create(exit, next, special, block);
-
- block = next;
-
- new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
-
- std::vector<Value*> items(ItemArgs.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 5U, "result", exit);
+
+ const auto first = new LoadInst(statePtr, "first", block);
+ const auto enter = SwitchInst::Create(first, loop, 2U, block);
+ enter->addCase(GetInvalid(context), init);
+ enter->addCase(GetConstant(ui64(EState::Skip), context), pass);
+
+
+ {
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ block = init;
+
+ const auto getfirst = GetNodeValues(Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getfirst.first, ConstantInt::get(getfirst.first->getType(), 0), "special", block);
+ result->addIncoming(getfirst.first, block);
+ BranchInst::Create(exit, next, special, block);
+
+ block = next;
+
+ new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
+
+ std::vector<Value*> items(ItemArgs.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(ItemArgs[i])->CreateSetValue(ctx, block, items[i] = getfirst.second[i](ctx, block));
- }
-
- for (ui32 i = 0U; i < Keys.size(); ++i) {
- if (KeyArgs[i]->GetDependencesCount() > 0U) {
- const auto map = KeysOnItems[i];
- const auto key = map ? items[*map] : GetNodeValue(Keys[i], ctx, block);
+ }
+
+ for (ui32 i = 0U; i < Keys.size(); ++i) {
+ if (KeyArgs[i]->GetDependencesCount() > 0U) {
+ const auto map = KeysOnItems[i];
+ const auto key = map ? items[*map] : GetNodeValue(Keys[i], ctx, block);
EnsureDynamicCast<ICodegeneratorExternalNode*>(KeyArgs[i])->CreateSetValue(ctx, block, key);
- }
- }
-
- BranchInst::Create(loop, block);
- }
-
- const auto part = BasicBlock::Create(context, "part", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto step = BasicBlock::Create(context, "step", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- block = loop;
-
- auto getres = GetNodeValues(Output, ctx, block);
- const auto state = new LoadInst(statePtr, "state", block);
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, getres.first, ConstantInt::get(getres.first->getType(), 0), "finish", block);
- result->addIncoming(getres.first, block);
- BranchInst::Create(part, exit, finish, block);
-
- block = part;
-
+ }
+ }
+
+ BranchInst::Create(loop, block);
+ }
+
+ const auto part = BasicBlock::Create(context, "part", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto step = BasicBlock::Create(context, "step", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ block = loop;
+
+ auto getres = GetNodeValues(Output, ctx, block);
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, getres.first, ConstantInt::get(getres.first->getType(), 0), "finish", block);
+ result->addIncoming(getres.first, block);
+ BranchInst::Create(part, exit, finish, block);
+
+ block = part;
+
EnsureDynamicCast<IWideFlowProxyCodegeneratorNode*>(Input)->CreateInvalidate(ctx, block);
-
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
-
- const auto choise = SwitchInst::Create(state, exit, 3U, block);
- choise->addCase(GetConstant(ui64(EState::Next), context), pass);
- choise->addCase(GetConstant(ui64(EState::Work), context), pass);
- choise->addCase(GetConstant(ui64(EState::Chop), context), step);
-
- block = pass;
-
- const auto getnext = GetNodeValues(Flow, ctx, block);
-
- result->addIncoming(getnext.first, block);
-
- const auto way = SwitchInst::Create(getnext.first, good, 2U, block);
- way->addCase(ConstantInt::get(resultType, i32(EFetchResult::Finish)), exit);
- way->addCase(ConstantInt::get(resultType, i32(EFetchResult::Yield)), skip);
-
- block = good;
-
- std::vector<Value*> items(ItemArgs.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
+
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
+
+ const auto choise = SwitchInst::Create(state, exit, 3U, block);
+ choise->addCase(GetConstant(ui64(EState::Next), context), pass);
+ choise->addCase(GetConstant(ui64(EState::Work), context), pass);
+ choise->addCase(GetConstant(ui64(EState::Chop), context), step);
+
+ block = pass;
+
+ const auto getnext = GetNodeValues(Flow, ctx, block);
+
+ result->addIncoming(getnext.first, block);
+
+ const auto way = SwitchInst::Create(getnext.first, good, 2U, block);
+ way->addCase(ConstantInt::get(resultType, i32(EFetchResult::Finish)), exit);
+ way->addCase(ConstantInt::get(resultType, i32(EFetchResult::Yield)), skip);
+
+ block = good;
+
+ std::vector<Value*> items(ItemArgs.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(ItemArgs[i])->CreateSetValue(ctx, block, items[i] = getnext.second[i](ctx, block));
- }
-
- const auto chop = SwitchItem ? items[*SwitchItem] : GetNodeValue(Chop, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
-
- BranchInst::Create(step, pass, cast, block);
-
- block = step;
-
- new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
-
- for (ui32 i = 0U; i < Keys.size(); ++i) {
- if (KeyArgs[i]->GetDependencesCount() > 0U) {
- const auto map = KeysOnItems[i];
- const auto key = GetNodeValue(Keys[i], ctx, block);
+ }
+
+ const auto chop = SwitchItem ? items[*SwitchItem] : GetNodeValue(Chop, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, chop, Type::getInt1Ty(context), "bool", block);
+
+ BranchInst::Create(step, pass, cast, block);
+
+ block = step;
+
+ new StoreInst(GetConstant(ui64(EState::Next), context), statePtr, block);
+
+ for (ui32 i = 0U; i < Keys.size(); ++i) {
+ if (KeyArgs[i]->GetDependencesCount() > 0U) {
+ const auto map = KeysOnItems[i];
+ const auto key = GetNodeValue(Keys[i], ctx, block);
EnsureDynamicCast<ICodegeneratorExternalNode*>(KeyArgs[i])->CreateSetValue(ctx, block, key);
- }
- }
-
- BranchInst::Create(loop, block);
-
- block = skip;
- new StoreInst(GetConstant(ui64(EState::Skip), context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Yield)), block);
- BranchInst::Create(exit, block);
-
- block = exit;
- return {result, std::move(getres.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(ItemArgs.cbegin(), ItemArgs.cend(), std::bind(&TWideChopperWrapper::Own, flow, std::placeholders::_1));
- std::for_each(Keys.cbegin(), Keys.cend(), std::bind(&TWideChopperWrapper::DependsOn, flow, std::placeholders::_1));
- std::for_each(KeyArgs.cbegin(), KeyArgs.cend(), std::bind(&TWideChopperWrapper::Own, flow, std::placeholders::_1));
- OwnProxy(flow, Input);
- DependsOn(flow, Output);
- }
- }
-
- IComputationWideFlowNode *const Flow;
-
- const TComputationExternalNodePtrVector ItemArgs;
- const TComputationNodePtrVector Keys;
- const TComputationExternalNodePtrVector KeyArgs;
-
- IComputationNode *const Chop;
-
- IComputationWideFlowProxyNode *const Input;
- IComputationWideFlowNode *const Output;
-
- const TPasstroughtMap ItemsOnKeys, KeysOnItems;
-
- const std::optional<size_t> SwitchItem;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-}
-
-IComputationNode* WrapWideChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 4U, "Expected at least four args.");
-
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- const auto keysSize = (callable.GetInputsCount() - width - 4U) >> 1U;
-
- TComputationNodePtrVector keys;
- keys.reserve(keysSize);
- auto index = width;
- std::generate_n(std::back_inserter(keys), keysSize, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
-
- index += keysSize;
-
- const auto switchResult = LocateNode(ctx.NodeLocator, callable, ++index);
- const auto input = LocateNode(ctx.NodeLocator, callable, ++index, true);
- const auto output = LocateNode(ctx.NodeLocator, callable, ++index, true);
-
- TComputationExternalNodePtrVector itemArgs, keyArgs;
- itemArgs.reserve(width);
- index = 0U;
- std::generate_n(std::back_inserter(itemArgs), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
-
- index += keysSize;
- keyArgs.reserve(keysSize);
- std::generate_n(std::back_inserter(keyArgs), keysSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ }
+ }
+
+ BranchInst::Create(loop, block);
+
+ block = skip;
+ new StoreInst(GetConstant(ui64(EState::Skip), context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Yield)), block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return {result, std::move(getres.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(ItemArgs.cbegin(), ItemArgs.cend(), std::bind(&TWideChopperWrapper::Own, flow, std::placeholders::_1));
+ std::for_each(Keys.cbegin(), Keys.cend(), std::bind(&TWideChopperWrapper::DependsOn, flow, std::placeholders::_1));
+ std::for_each(KeyArgs.cbegin(), KeyArgs.cend(), std::bind(&TWideChopperWrapper::Own, flow, std::placeholders::_1));
+ OwnProxy(flow, Input);
+ DependsOn(flow, Output);
+ }
+ }
+
+ IComputationWideFlowNode *const Flow;
+
+ const TComputationExternalNodePtrVector ItemArgs;
+ const TComputationNodePtrVector Keys;
+ const TComputationExternalNodePtrVector KeyArgs;
+
+ IComputationNode *const Chop;
+
+ IComputationWideFlowProxyNode *const Input;
+ IComputationWideFlowNode *const Output;
+
+ const TPasstroughtMap ItemsOnKeys, KeysOnItems;
+
+ const std::optional<size_t> SwitchItem;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+}
+
+IComputationNode* WrapWideChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() >= 4U, "Expected at least four args.");
+
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ const auto keysSize = (callable.GetInputsCount() - width - 4U) >> 1U;
+
+ TComputationNodePtrVector keys;
+ keys.reserve(keysSize);
+ auto index = width;
+ std::generate_n(std::back_inserter(keys), keysSize, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
+
+ index += keysSize;
+
+ const auto switchResult = LocateNode(ctx.NodeLocator, callable, ++index);
+ const auto input = LocateNode(ctx.NodeLocator, callable, ++index, true);
+ const auto output = LocateNode(ctx.NodeLocator, callable, ++index, true);
+
+ TComputationExternalNodePtrVector itemArgs, keyArgs;
+ itemArgs.reserve(width);
+ index = 0U;
+ std::generate_n(std::back_inserter(itemArgs), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
+
+ index += keysSize;
+ keyArgs.reserve(keysSize);
+ std::generate_n(std::back_inserter(keyArgs), keysSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
return new TWideChopperWrapper(ctx.Mutables, wide, std::move(itemArgs), std::move(keys), std::move(keyArgs), switchResult,
EnsureDynamicCast<IComputationWideFlowProxyNode*>(input),
EnsureDynamicCast<IComputationWideFlowNode*>(output));
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-}
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.h
index 2df2cf4699..4eb5459886 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_chopper.h
@@ -1,10 +1,10 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapWideChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapWideChopper(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.cpp
index 290d3e6be4..1fe1734a15 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.cpp
@@ -1,1028 +1,1028 @@
-#include "mkql_wide_combine.h"
-
+#include "mkql_wide_combine.h"
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_stats_registry.h>
#include <ydb/library/yql/minikql/defs.h>
#include <ydb/library/yql/utils/cast.h>
-
+
#include <util/string/cast.h>
-namespace NKikimr {
-namespace NMiniKQL {
-
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
extern TStatKey Combine_FlushesCount;
extern TStatKey Combine_MaxRowsCount;
-namespace {
-
-struct TMyValueEqual {
- TMyValueEqual(const TKeyTypes& types)
- : Types(types)
- {}
-
- bool operator()(const NUdf::TUnboxedValuePod* left, const NUdf::TUnboxedValuePod* right) const {
- for (ui32 i = 0U; i < Types.size(); ++i)
- if (CompareValues(Types[i].first, true, Types[i].second, left[i], right[i]))
- return false;
- return true;
- }
-
- const TKeyTypes& Types;
-};
-
-struct TMyValueHasher {
- TMyValueHasher(const TKeyTypes& types)
- : Types(types)
- {}
-
- NUdf::THashType operator()(const NUdf::TUnboxedValuePod* values) const {
- if (Types.size() == 1U)
- if (const auto v = *values)
- return NUdf::GetValueHash(Types.front().first, v);
- else
- return HashOfNull;
-
- NUdf::THashType hash = 0ULL;
- for (const auto& type : Types) {
- if (const auto v = *values++)
- hash = CombineHashes(hash, NUdf::GetValueHash(type.first, v));
- else
- hash = CombineHashes(hash, HashOfNull);
- }
- return hash;
- }
-
- const TKeyTypes& Types;
-};
-
-using TEqualsPtr = bool(*)(const NUdf::TUnboxedValuePod*, const NUdf::TUnboxedValuePod*);
-using THashPtr = NUdf::THashType(*)(const NUdf::TUnboxedValuePod*);
-
-using TEqualsFunc = std::function<bool(const NUdf::TUnboxedValuePod*, const NUdf::TUnboxedValuePod*)>;
-using THashFunc = std::function<NUdf::THashType(const NUdf::TUnboxedValuePod*)>;
-
-using TDependsOn = std::function<void(IComputationNode*)>;
-using TOwn = std::function<void(IComputationExternalNode*)>;
-
-struct TCombinerNodes {
- TComputationExternalNodePtrVector ItemNodes, KeyNodes, StateNodes, FinishNodes;
- TComputationNodePtrVector KeyResultNodes, InitResultNodes, UpdateResultNodes, FinishResultNodes;
-
- TPasstroughtMap
- KeysOnItems,
- InitOnKeys,
- InitOnItems,
- UpdateOnKeys,
- UpdateOnItems,
- UpdateOnState,
- StateOnUpdate,
- ItemsOnResult,
- ResultOnItems;
-
- std::vector<bool> PasstroughtItems;
-
- void BuildMaps() {
- KeysOnItems = GetPasstroughtMap(KeyResultNodes, ItemNodes);
- InitOnKeys = GetPasstroughtMap(InitResultNodes, KeyNodes);
- InitOnItems = GetPasstroughtMap(InitResultNodes, ItemNodes);
- UpdateOnKeys = GetPasstroughtMap(UpdateResultNodes, KeyNodes);
- UpdateOnItems = GetPasstroughtMap(UpdateResultNodes, ItemNodes);
- UpdateOnState = GetPasstroughtMap(UpdateResultNodes, StateNodes);
- UpdateOnState = GetPasstroughtMap(UpdateResultNodes, StateNodes);
- StateOnUpdate = GetPasstroughtMap(StateNodes, UpdateResultNodes);
- ItemsOnResult = GetPasstroughtMap(FinishNodes, FinishResultNodes);
- ResultOnItems = GetPasstroughtMap(FinishResultNodes, FinishNodes);
-
- PasstroughtItems.resize(ItemNodes.size());
- auto anyResults = KeyResultNodes;
- anyResults.insert(anyResults.cend(), InitResultNodes.cbegin(), InitResultNodes.cend());
- anyResults.insert(anyResults.cend(), UpdateResultNodes.cbegin(), UpdateResultNodes.cend());
- const auto itemsOnResults = GetPasstroughtMap(ItemNodes, anyResults);
- std::transform(itemsOnResults.cbegin(), itemsOnResults.cend(), PasstroughtItems.begin(), [](const TPasstroughtMap::value_type& v) { return v.has_value(); });
- }
-
- void ExtractKey(TComputationContext& ctx, NUdf::TUnboxedValue** values, NUdf::TUnboxedValue* keys) const {
- std::for_each(ItemNodes.cbegin(), ItemNodes.cend(), [&](IComputationExternalNode* item) {
- if (const auto pointer = *values++)
- item->SetValue(ctx, std::move(*pointer));
- });
- for (ui32 i = 0U; i < KeyNodes.size(); ++i) {
- auto& key = KeyNodes[i]->RefValue(ctx);
- *keys++ = key = KeyResultNodes[i]->GetValue(ctx);
- }
- }
-
- void ProcessItem(TComputationContext& ctx, NUdf::TUnboxedValue* keys, NUdf::TUnboxedValue* state) const {
- if (keys) {
- std::fill_n(keys, KeyResultNodes.size(), NUdf::TUnboxedValuePod());
- auto source = state;
- std::for_each(StateNodes.cbegin(), StateNodes.cend(), [&](IComputationExternalNode* item){ item->SetValue(ctx, std::move(*source++)); });
- std::transform(UpdateResultNodes.cbegin(), UpdateResultNodes.cend(), state, [&](IComputationNode* node) { return node->GetValue(ctx); });
- } else {
- std::transform(InitResultNodes.cbegin(), InitResultNodes.cend(), state, [&](IComputationNode* node) { return node->GetValue(ctx); });
- }
- }
-
- void FinishItem(TComputationContext& ctx, NUdf::TUnboxedValue* state, NUdf::TUnboxedValue*const* output) const {
- std::for_each(FinishNodes.cbegin(), FinishNodes.cend(), [&](IComputationExternalNode* item) { item->SetValue(ctx, std::move(*state++)); });
- for (const auto node : FinishResultNodes)
- if (const auto out = *output++)
- *out = node->GetValue(ctx);
- }
-
- void RegisterDependencies(const TDependsOn& dependsOn, const TOwn& own) const {
- std::for_each(ItemNodes.cbegin(), ItemNodes.cend(), own);
- std::for_each(KeyNodes.cbegin(), KeyNodes.cend(), own);
- std::for_each(StateNodes.cbegin(), StateNodes.cend(), own);
- std::for_each(FinishNodes.cbegin(), FinishNodes.cend(), own);
-
- std::for_each(KeyResultNodes.cbegin(), KeyResultNodes.cend(), dependsOn);
- std::for_each(InitResultNodes.cbegin(), InitResultNodes.cend(), dependsOn);
- std::for_each(UpdateResultNodes.cbegin(), UpdateResultNodes.cend(), dependsOn);
- std::for_each(FinishResultNodes.cbegin(), FinishResultNodes.cend(), dependsOn);
- }
-};
-
-class TState : public TComputationValue<TState> {
- typedef TComputationValue<TState> TBase;
-public:
- TState(TMemoryUsageInfo* memInfo, ui32 keyWidth, ui32 stateWidth, const THashFunc& hash, const TEqualsFunc& equal)
- : TBase(memInfo), KeyWidth(keyWidth), StateWidth(stateWidth), States(0, hash, equal) {
- Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
- Tongue = Storage.back().data();
- }
-
- bool TasteIt() {
- const auto ins = States.emplace(Tongue);
- if (ins.second) {
- Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
- Tongue = Storage.back().data();
- }
- Throat = *ins.first + KeyWidth;
- return ins.second;
- }
-
- bool IsEmpty() {
- if (!States.empty())
- return false;
-
- if (Storage.size() > 1U) {
- Storage.clear();
- Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
- Tongue = Storage.back().data();
- }
- return true;
- }
-
- void PushStat(IStatsRegistry* stats) const {
- if (!States.empty()) {
- MKQL_SET_MAX_STAT(stats, Combine_MaxRowsCount, static_cast<i64>(States.size()));
- MKQL_INC_STAT(stats, Combine_FlushesCount);
- }
- }
-
- NUdf::TUnboxedValuePod* Extract() {
- return States.empty() ? nullptr : States.extract(States.cbegin()).value();
- }
-
- EFetchResult InputStatus = EFetchResult::One;
- NUdf::TUnboxedValuePod* Tongue = nullptr;
- NUdf::TUnboxedValuePod* Throat = nullptr;
-
-private:
- const ui32 KeyWidth, StateWidth;
- using TRow = std::vector<NUdf::TUnboxedValuePod, TMKQLAllocator<NUdf::TUnboxedValuePod>>;
- std::deque<TRow, TMKQLAllocator<TRow>> Storage;
- std::unordered_set<NUdf::TUnboxedValuePod*, THashFunc, TEqualsFunc, TMKQLAllocator<NUdf::TUnboxedValuePod*>> States;
-};
-
-template <bool TrackRss>
-class TWideCombinerWrapper: public TStatefulWideFlowCodegeneratorNode<TWideCombinerWrapper<TrackRss>>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideCombinerWrapper<TrackRss>>;
-public:
- TWideCombinerWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TCombinerNodes&& nodes, TKeyTypes&& keyTypes, ui64 memLimit)
- : TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
- , Flow(flow)
- , Nodes(std::move(nodes))
- , KeyTypes(std::move(keyTypes))
- , MemLimit(memLimit)
- , Fields(Nodes.ItemNodes.size(), nullptr)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- while (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
- if (ptr->IsEmpty()) {
- switch (ptr->InputStatus) {
- case EFetchResult::One: break;
- case EFetchResult::Yield:
- ptr->InputStatus = EFetchResult::One;
- return EFetchResult::Yield;
- case EFetchResult::Finish:
- return EFetchResult::Finish;
- }
-
- const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
-
- do {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U || Nodes.PasstroughtItems[i])
- Fields[i] = &Nodes.ItemNodes[i]->RefValue(ctx);
-
- ptr->InputStatus = Flow->FetchValues(ctx, Fields.data());
- if (EFetchResult::One != ptr->InputStatus) {
- break;
- }
-
- Nodes.ExtractKey(ctx, Fields.data(), static_cast<NUdf::TUnboxedValue*>(ptr->Tongue));
- Nodes.ProcessItem(ctx, ptr->TasteIt() ? nullptr : static_cast<NUdf::TUnboxedValue*>(ptr->Tongue), static_cast<NUdf::TUnboxedValue*>(ptr->Throat));
- } while (!ctx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
-
- ptr->PushStat(ctx.Stats);
- }
-
- if (const auto values = static_cast<NUdf::TUnboxedValue*>(ptr->Extract())) {
- Nodes.FinishItem(ctx, values, output);
- return EFetchResult::One;
- }
- }
+namespace {
+
+struct TMyValueEqual {
+ TMyValueEqual(const TKeyTypes& types)
+ : Types(types)
+ {}
+
+ bool operator()(const NUdf::TUnboxedValuePod* left, const NUdf::TUnboxedValuePod* right) const {
+ for (ui32 i = 0U; i < Types.size(); ++i)
+ if (CompareValues(Types[i].first, true, Types[i].second, left[i], right[i]))
+ return false;
+ return true;
+ }
+
+ const TKeyTypes& Types;
+};
+
+struct TMyValueHasher {
+ TMyValueHasher(const TKeyTypes& types)
+ : Types(types)
+ {}
+
+ NUdf::THashType operator()(const NUdf::TUnboxedValuePod* values) const {
+ if (Types.size() == 1U)
+ if (const auto v = *values)
+ return NUdf::GetValueHash(Types.front().first, v);
+ else
+ return HashOfNull;
+
+ NUdf::THashType hash = 0ULL;
+ for (const auto& type : Types) {
+ if (const auto v = *values++)
+ hash = CombineHashes(hash, NUdf::GetValueHash(type.first, v));
+ else
+ hash = CombineHashes(hash, HashOfNull);
+ }
+ return hash;
+ }
+
+ const TKeyTypes& Types;
+};
+
+using TEqualsPtr = bool(*)(const NUdf::TUnboxedValuePod*, const NUdf::TUnboxedValuePod*);
+using THashPtr = NUdf::THashType(*)(const NUdf::TUnboxedValuePod*);
+
+using TEqualsFunc = std::function<bool(const NUdf::TUnboxedValuePod*, const NUdf::TUnboxedValuePod*)>;
+using THashFunc = std::function<NUdf::THashType(const NUdf::TUnboxedValuePod*)>;
+
+using TDependsOn = std::function<void(IComputationNode*)>;
+using TOwn = std::function<void(IComputationExternalNode*)>;
+
+struct TCombinerNodes {
+ TComputationExternalNodePtrVector ItemNodes, KeyNodes, StateNodes, FinishNodes;
+ TComputationNodePtrVector KeyResultNodes, InitResultNodes, UpdateResultNodes, FinishResultNodes;
+
+ TPasstroughtMap
+ KeysOnItems,
+ InitOnKeys,
+ InitOnItems,
+ UpdateOnKeys,
+ UpdateOnItems,
+ UpdateOnState,
+ StateOnUpdate,
+ ItemsOnResult,
+ ResultOnItems;
+
+ std::vector<bool> PasstroughtItems;
+
+ void BuildMaps() {
+ KeysOnItems = GetPasstroughtMap(KeyResultNodes, ItemNodes);
+ InitOnKeys = GetPasstroughtMap(InitResultNodes, KeyNodes);
+ InitOnItems = GetPasstroughtMap(InitResultNodes, ItemNodes);
+ UpdateOnKeys = GetPasstroughtMap(UpdateResultNodes, KeyNodes);
+ UpdateOnItems = GetPasstroughtMap(UpdateResultNodes, ItemNodes);
+ UpdateOnState = GetPasstroughtMap(UpdateResultNodes, StateNodes);
+ UpdateOnState = GetPasstroughtMap(UpdateResultNodes, StateNodes);
+ StateOnUpdate = GetPasstroughtMap(StateNodes, UpdateResultNodes);
+ ItemsOnResult = GetPasstroughtMap(FinishNodes, FinishResultNodes);
+ ResultOnItems = GetPasstroughtMap(FinishResultNodes, FinishNodes);
+
+ PasstroughtItems.resize(ItemNodes.size());
+ auto anyResults = KeyResultNodes;
+ anyResults.insert(anyResults.cend(), InitResultNodes.cbegin(), InitResultNodes.cend());
+ anyResults.insert(anyResults.cend(), UpdateResultNodes.cbegin(), UpdateResultNodes.cend());
+ const auto itemsOnResults = GetPasstroughtMap(ItemNodes, anyResults);
+ std::transform(itemsOnResults.cbegin(), itemsOnResults.cend(), PasstroughtItems.begin(), [](const TPasstroughtMap::value_type& v) { return v.has_value(); });
+ }
+
+ void ExtractKey(TComputationContext& ctx, NUdf::TUnboxedValue** values, NUdf::TUnboxedValue* keys) const {
+ std::for_each(ItemNodes.cbegin(), ItemNodes.cend(), [&](IComputationExternalNode* item) {
+ if (const auto pointer = *values++)
+ item->SetValue(ctx, std::move(*pointer));
+ });
+ for (ui32 i = 0U; i < KeyNodes.size(); ++i) {
+ auto& key = KeyNodes[i]->RefValue(ctx);
+ *keys++ = key = KeyResultNodes[i]->GetValue(ctx);
+ }
+ }
+
+ void ProcessItem(TComputationContext& ctx, NUdf::TUnboxedValue* keys, NUdf::TUnboxedValue* state) const {
+ if (keys) {
+ std::fill_n(keys, KeyResultNodes.size(), NUdf::TUnboxedValuePod());
+ auto source = state;
+ std::for_each(StateNodes.cbegin(), StateNodes.cend(), [&](IComputationExternalNode* item){ item->SetValue(ctx, std::move(*source++)); });
+ std::transform(UpdateResultNodes.cbegin(), UpdateResultNodes.cend(), state, [&](IComputationNode* node) { return node->GetValue(ctx); });
+ } else {
+ std::transform(InitResultNodes.cbegin(), InitResultNodes.cend(), state, [&](IComputationNode* node) { return node->GetValue(ctx); });
+ }
+ }
+
+ void FinishItem(TComputationContext& ctx, NUdf::TUnboxedValue* state, NUdf::TUnboxedValue*const* output) const {
+ std::for_each(FinishNodes.cbegin(), FinishNodes.cend(), [&](IComputationExternalNode* item) { item->SetValue(ctx, std::move(*state++)); });
+ for (const auto node : FinishResultNodes)
+ if (const auto out = *output++)
+ *out = node->GetValue(ctx);
+ }
+
+ void RegisterDependencies(const TDependsOn& dependsOn, const TOwn& own) const {
+ std::for_each(ItemNodes.cbegin(), ItemNodes.cend(), own);
+ std::for_each(KeyNodes.cbegin(), KeyNodes.cend(), own);
+ std::for_each(StateNodes.cbegin(), StateNodes.cend(), own);
+ std::for_each(FinishNodes.cbegin(), FinishNodes.cend(), own);
+
+ std::for_each(KeyResultNodes.cbegin(), KeyResultNodes.cend(), dependsOn);
+ std::for_each(InitResultNodes.cbegin(), InitResultNodes.cend(), dependsOn);
+ std::for_each(UpdateResultNodes.cbegin(), UpdateResultNodes.cend(), dependsOn);
+ std::for_each(FinishResultNodes.cbegin(), FinishResultNodes.cend(), dependsOn);
+ }
+};
+
+class TState : public TComputationValue<TState> {
+ typedef TComputationValue<TState> TBase;
+public:
+ TState(TMemoryUsageInfo* memInfo, ui32 keyWidth, ui32 stateWidth, const THashFunc& hash, const TEqualsFunc& equal)
+ : TBase(memInfo), KeyWidth(keyWidth), StateWidth(stateWidth), States(0, hash, equal) {
+ Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
+ Tongue = Storage.back().data();
+ }
+
+ bool TasteIt() {
+ const auto ins = States.emplace(Tongue);
+ if (ins.second) {
+ Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
+ Tongue = Storage.back().data();
+ }
+ Throat = *ins.first + KeyWidth;
+ return ins.second;
+ }
+
+ bool IsEmpty() {
+ if (!States.empty())
+ return false;
+
+ if (Storage.size() > 1U) {
+ Storage.clear();
+ Storage.emplace_back(KeyWidth + StateWidth, NUdf::TUnboxedValuePod());
+ Tongue = Storage.back().data();
+ }
+ return true;
+ }
+
+ void PushStat(IStatsRegistry* stats) const {
+ if (!States.empty()) {
+ MKQL_SET_MAX_STAT(stats, Combine_MaxRowsCount, static_cast<i64>(States.size()));
+ MKQL_INC_STAT(stats, Combine_FlushesCount);
+ }
+ }
+
+ NUdf::TUnboxedValuePod* Extract() {
+ return States.empty() ? nullptr : States.extract(States.cbegin()).value();
+ }
+
+ EFetchResult InputStatus = EFetchResult::One;
+ NUdf::TUnboxedValuePod* Tongue = nullptr;
+ NUdf::TUnboxedValuePod* Throat = nullptr;
+
+private:
+ const ui32 KeyWidth, StateWidth;
+ using TRow = std::vector<NUdf::TUnboxedValuePod, TMKQLAllocator<NUdf::TUnboxedValuePod>>;
+ std::deque<TRow, TMKQLAllocator<TRow>> Storage;
+ std::unordered_set<NUdf::TUnboxedValuePod*, THashFunc, TEqualsFunc, TMKQLAllocator<NUdf::TUnboxedValuePod*>> States;
+};
+
+template <bool TrackRss>
+class TWideCombinerWrapper: public TStatefulWideFlowCodegeneratorNode<TWideCombinerWrapper<TrackRss>>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideCombinerWrapper<TrackRss>>;
+public:
+ TWideCombinerWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TCombinerNodes&& nodes, TKeyTypes&& keyTypes, ui64 memLimit)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
+ , Flow(flow)
+ , Nodes(std::move(nodes))
+ , KeyTypes(std::move(keyTypes))
+ , MemLimit(memLimit)
+ , Fields(Nodes.ItemNodes.size(), nullptr)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ while (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
+ if (ptr->IsEmpty()) {
+ switch (ptr->InputStatus) {
+ case EFetchResult::One: break;
+ case EFetchResult::Yield:
+ ptr->InputStatus = EFetchResult::One;
+ return EFetchResult::Yield;
+ case EFetchResult::Finish:
+ return EFetchResult::Finish;
+ }
+
+ const auto initUsage = MemLimit ? ctx.HolderFactory.GetMemoryUsed() : 0ULL;
+
+ do {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U || Nodes.PasstroughtItems[i])
+ Fields[i] = &Nodes.ItemNodes[i]->RefValue(ctx);
+
+ ptr->InputStatus = Flow->FetchValues(ctx, Fields.data());
+ if (EFetchResult::One != ptr->InputStatus) {
+ break;
+ }
+
+ Nodes.ExtractKey(ctx, Fields.data(), static_cast<NUdf::TUnboxedValue*>(ptr->Tongue));
+ Nodes.ProcessItem(ctx, ptr->TasteIt() ? nullptr : static_cast<NUdf::TUnboxedValue*>(ptr->Tongue), static_cast<NUdf::TUnboxedValue*>(ptr->Throat));
+ } while (!ctx.template CheckAdjustedMemLimit<TrackRss>(MemLimit, initUsage));
+
+ ptr->PushStat(ctx.Stats);
+ }
+
+ if (const auto values = static_cast<NUdf::TUnboxedValue*>(ptr->Extract())) {
+ Nodes.FinishItem(ctx, values, output);
+ return EFetchResult::One;
+ }
+ }
Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- statusType, // status
- ptrValueType, // tongue
- ptrValueType, // throat
- Type::getInt32Ty(context), // size
- Type::getInt32Ty(context), // size
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto keys = new AllocaInst(ArrayType::get(valueType, Nodes.KeyResultNodes.size()), 0U, "keys", &ctx.Func->getEntryBlock().back());
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
-
- BranchInst::Create(main, make, HasValue(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideCombinerWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
- const auto result = PHINode::Create(statusType, 3U, "result", over);
-
- const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
- const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
- const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "empty_func", block);
- const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
-
- BranchInst::Create(next, full, empty, block);
-
- {
- block = next;
-
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
-
- const auto last = new LoadInst(statusPtr, "last", block);
-
- result->addIncoming(last, block);
-
- const auto choise = SwitchInst::Create(last, pull, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), rest);
- choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), over);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::One)), statusPtr, block);
-
- result->addIncoming(last, block);
-
- BranchInst::Create(over, block);
-
- block = pull;
-
- const auto used = GetMemoryUsed(MemLimit, ctx, block);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), static_cast<i32>(EFetchResult::Yield)), "special", block);
-
- BranchInst::Create(done, good, special, block);
-
- block = good;
-
- std::vector<Value*> items(Nodes.ItemNodes.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
- if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U)
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ statusType, // status
+ ptrValueType, // tongue
+ ptrValueType, // throat
+ Type::getInt32Ty(context), // size
+ Type::getInt32Ty(context), // size
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto keys = new AllocaInst(ArrayType::get(valueType, Nodes.KeyResultNodes.size()), 0U, "keys", &ctx.Func->getEntryBlock().back());
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+
+ BranchInst::Create(main, make, HasValue(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideCombinerWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+ const auto result = PHINode::Create(statusType, 3U, "result", over);
+
+ const auto isEmptyFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::IsEmpty));
+ const auto isEmptyFuncType = FunctionType::get(Type::getInt1Ty(context), { statePtrType }, false);
+ const auto isEmptyFuncPtr = CastInst::Create(Instruction::IntToPtr, isEmptyFunc, PointerType::getUnqual(isEmptyFuncType), "empty_func", block);
+ const auto empty = CallInst::Create(isEmptyFuncPtr, { stateArg }, "empty", block);
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+
+ BranchInst::Create(next, full, empty, block);
+
+ {
+ block = next;
+
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto pull = BasicBlock::Create(context, "pull", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
+
+ const auto last = new LoadInst(statusPtr, "last", block);
+
+ result->addIncoming(last, block);
+
+ const auto choise = SwitchInst::Create(last, pull, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), rest);
+ choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), over);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::One)), statusPtr, block);
+
+ result->addIncoming(last, block);
+
+ BranchInst::Create(over, block);
+
+ block = pull;
+
+ const auto used = GetMemoryUsed(MemLimit, ctx, block);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, getres.first, ConstantInt::get(getres.first->getType(), static_cast<i32>(EFetchResult::Yield)), "special", block);
+
+ BranchInst::Create(done, good, special, block);
+
+ block = good;
+
+ std::vector<Value*> items(Nodes.ItemNodes.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
+ if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.ItemNodes[i])->CreateSetValue(ctx, block, items[i] = getres.second[i](ctx, block));
- else if (Nodes.PasstroughtItems[i])
- items[i] = getres.second[i](ctx, block);
- }
-
- const auto tonguePtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "tongue_ptr", block);
- const auto tongue = new LoadInst(tonguePtr, "tongue", block);
-
- std::vector<Value*> keyPointers(Nodes.KeyResultNodes.size(), nullptr), keys(Nodes.KeyResultNodes.size(), nullptr);
- for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
- auto& key = keys[i];
- const auto keyPtr = keyPointers[i] = GetElementPtrInst::CreateInBounds(tongue, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("key_") += ToString(i)).c_str(), block);
- if (const auto map = Nodes.KeysOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- key = it;
- } else {
- key = GetNodeValue(Nodes.KeyResultNodes[i], ctx, block);
- }
-
- if (Nodes.KeyNodes[i]->GetDependencesCount() > 0U)
+ else if (Nodes.PasstroughtItems[i])
+ items[i] = getres.second[i](ctx, block);
+ }
+
+ const auto tonguePtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "tongue_ptr", block);
+ const auto tongue = new LoadInst(tonguePtr, "tongue", block);
+
+ std::vector<Value*> keyPointers(Nodes.KeyResultNodes.size(), nullptr), keys(Nodes.KeyResultNodes.size(), nullptr);
+ for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
+ auto& key = keys[i];
+ const auto keyPtr = keyPointers[i] = GetElementPtrInst::CreateInBounds(tongue, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("key_") += ToString(i)).c_str(), block);
+ if (const auto map = Nodes.KeysOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ key = it;
+ } else {
+ key = GetNodeValue(Nodes.KeyResultNodes[i], ctx, block);
+ }
+
+ if (Nodes.KeyNodes[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.KeyNodes[i])->CreateSetValue(ctx, block, key);
-
- new StoreInst(key, keyPtr, block);
- }
-
- const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::TasteIt));
- const auto atType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
- const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
- const auto newKey = CallInst::Create(atPtr, {stateArg}, "new_key", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
-
- const auto throatPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 7)}, "throat_ptr", block);
- const auto throat = new LoadInst(throatPtr, "throat", block);
-
- std::vector<Value*> pointers;
- pointers.reserve(Nodes.StateNodes.size());
- for (ui32 i = 0U; i < Nodes.StateNodes.size(); ++i) {
- pointers.emplace_back(GetElementPtrInst::CreateInBounds(throat, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("state_") += ToString(i)).c_str(), block));
- }
-
- BranchInst::Create(init, next, newKey, block);
-
- block = init;
-
- for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
- ValueAddRef(Nodes.KeyResultNodes[i]->GetRepresentation(), keyPointers[i], ctx, block);
- }
-
- for (ui32 i = 0U; i < Nodes.InitResultNodes.size(); ++i) {
- if (const auto map = Nodes.InitOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- new StoreInst(it, pointers[i], block);
- ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), it, ctx, block);
- } else if (const auto map = Nodes.InitOnKeys[i]) {
- const auto key = keys[*map];
- new StoreInst(key, pointers[i], block);
- ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), key, ctx, block);
- } else {
- GetNodeValue(pointers[i], Nodes.InitResultNodes[i], ctx, block);
- }
- }
-
- BranchInst::Create(test, block);
-
- block = next;
-
- std::vector<Value*> stored(Nodes.StateNodes.size(), nullptr);
- for (ui32 i = 0U; i < stored.size(); ++i) {
- const bool hasDependency = Nodes.StateNodes[i]->GetDependencesCount() > 0U;
- if (const auto map = Nodes.StateOnUpdate[i]) {
- if (hasDependency || i != *map) {
- stored[i] = new LoadInst(pointers[i], (TString("state_") += ToString(i)).c_str(), block);
- if (hasDependency)
+
+ new StoreInst(key, keyPtr, block);
+ }
+
+ const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::TasteIt));
+ const auto atType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
+ const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
+ const auto newKey = CallInst::Create(atPtr, {stateArg}, "new_key", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+
+ const auto throatPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 7)}, "throat_ptr", block);
+ const auto throat = new LoadInst(throatPtr, "throat", block);
+
+ std::vector<Value*> pointers;
+ pointers.reserve(Nodes.StateNodes.size());
+ for (ui32 i = 0U; i < Nodes.StateNodes.size(); ++i) {
+ pointers.emplace_back(GetElementPtrInst::CreateInBounds(throat, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("state_") += ToString(i)).c_str(), block));
+ }
+
+ BranchInst::Create(init, next, newKey, block);
+
+ block = init;
+
+ for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
+ ValueAddRef(Nodes.KeyResultNodes[i]->GetRepresentation(), keyPointers[i], ctx, block);
+ }
+
+ for (ui32 i = 0U; i < Nodes.InitResultNodes.size(); ++i) {
+ if (const auto map = Nodes.InitOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ new StoreInst(it, pointers[i], block);
+ ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), it, ctx, block);
+ } else if (const auto map = Nodes.InitOnKeys[i]) {
+ const auto key = keys[*map];
+ new StoreInst(key, pointers[i], block);
+ ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), key, ctx, block);
+ } else {
+ GetNodeValue(pointers[i], Nodes.InitResultNodes[i], ctx, block);
+ }
+ }
+
+ BranchInst::Create(test, block);
+
+ block = next;
+
+ std::vector<Value*> stored(Nodes.StateNodes.size(), nullptr);
+ for (ui32 i = 0U; i < stored.size(); ++i) {
+ const bool hasDependency = Nodes.StateNodes[i]->GetDependencesCount() > 0U;
+ if (const auto map = Nodes.StateOnUpdate[i]) {
+ if (hasDependency || i != *map) {
+ stored[i] = new LoadInst(pointers[i], (TString("state_") += ToString(i)).c_str(), block);
+ if (hasDependency)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, stored[i]);
- }
- } else if (hasDependency) {
+ }
+ } else if (hasDependency) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, pointers[i]);
- } else {
- ValueUnRef(Nodes.StateNodes[i]->GetRepresentation(), pointers[i], ctx, block);
- }
- }
-
- for (ui32 i = 0U; i < Nodes.UpdateResultNodes.size(); ++i) {
- if (const auto map = Nodes.UpdateOnState[i]) {
- if (const auto j = *map; i != j) {
- auto& it = stored[j];
- if (!it)
- it = new LoadInst(pointers[j], (TString("state_") += ToString(j)).c_str(), block);
- new StoreInst(it, pointers[i], block);
- if (i != *Nodes.StateOnUpdate[j])
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
- }
- } else if (const auto map = Nodes.UpdateOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- new StoreInst(it, pointers[i], block);
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
- } else if (const auto map = Nodes.UpdateOnKeys[i]) {
- const auto key = keys[*map];
- new StoreInst(key, pointers[i], block);
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), key, ctx, block);
- } else {
- GetNodeValue(pointers[i], Nodes.UpdateResultNodes[i], ctx, block);
- }
- }
-
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
- BranchInst::Create(done, loop, check, block);
-
- block = done;
-
- new StoreInst(getres.first, statusPtr, block);
-
- const auto stat = ctx.GetStat();
- const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
- const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
- const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
- CallInst::Create(statPtr, {stateArg, stat}, "", block);
-
- BranchInst::Create(full, block);
- }
-
- {
- block = full;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
- const auto extractType = FunctionType::get(ptrValueType, {stateArg->getType()}, false);
- const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
- const auto out = CallInst::Create(extractPtr, {stateArg}, "out", block);
- const auto has = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, out, ConstantPointerNull::get(ptrValueType), "has", block);
-
- BranchInst::Create(good, more, has, block);
-
- block = good;
-
- for (ui32 i = 0U; i < Nodes.FinishNodes.size(); ++i) {
- const auto ptr = GetElementPtrInst::CreateInBounds(out, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("out_key_") += ToString(i)).c_str(), block);
- if (Nodes.FinishNodes[i]->GetDependencesCount() > 0 || Nodes.ItemsOnResult[i])
+ } else {
+ ValueUnRef(Nodes.StateNodes[i]->GetRepresentation(), pointers[i], ctx, block);
+ }
+ }
+
+ for (ui32 i = 0U; i < Nodes.UpdateResultNodes.size(); ++i) {
+ if (const auto map = Nodes.UpdateOnState[i]) {
+ if (const auto j = *map; i != j) {
+ auto& it = stored[j];
+ if (!it)
+ it = new LoadInst(pointers[j], (TString("state_") += ToString(j)).c_str(), block);
+ new StoreInst(it, pointers[i], block);
+ if (i != *Nodes.StateOnUpdate[j])
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
+ }
+ } else if (const auto map = Nodes.UpdateOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ new StoreInst(it, pointers[i], block);
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
+ } else if (const auto map = Nodes.UpdateOnKeys[i]) {
+ const auto key = keys[*map];
+ new StoreInst(key, pointers[i], block);
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), key, ctx, block);
+ } else {
+ GetNodeValue(pointers[i], Nodes.UpdateResultNodes[i], ctx, block);
+ }
+ }
+
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto check = CheckAdjustedMemLimit<TrackRss>(MemLimit, used, ctx, block);
+ BranchInst::Create(done, loop, check, block);
+
+ block = done;
+
+ new StoreInst(getres.first, statusPtr, block);
+
+ const auto stat = ctx.GetStat();
+ const auto statFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::PushStat));
+ const auto statType = FunctionType::get(Type::getVoidTy(context), {stateArg->getType(), stat->getType()}, false);
+ const auto statPtr = CastInst::Create(Instruction::IntToPtr, statFunc, PointerType::getUnqual(statType), "stat", block);
+ CallInst::Create(statPtr, {stateArg, stat}, "", block);
+
+ BranchInst::Create(full, block);
+ }
+
+ {
+ block = full;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
+ const auto extractType = FunctionType::get(ptrValueType, {stateArg->getType()}, false);
+ const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
+ const auto out = CallInst::Create(extractPtr, {stateArg}, "out", block);
+ const auto has = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, out, ConstantPointerNull::get(ptrValueType), "has", block);
+
+ BranchInst::Create(good, more, has, block);
+
+ block = good;
+
+ for (ui32 i = 0U; i < Nodes.FinishNodes.size(); ++i) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(out, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("out_key_") += ToString(i)).c_str(), block);
+ if (Nodes.FinishNodes[i]->GetDependencesCount() > 0 || Nodes.ItemsOnResult[i])
EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.FinishNodes[i])->CreateSetValue(ctx, block, ptr);
- else
- ValueUnRef(Nodes.FinishNodes[i]->GetRepresentation(), ptr, ctx, block);
- }
-
- result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::One)), block);
- BranchInst::Create(over, block);
- }
-
- block = over;
-
- ICodegeneratorInlineWideNode::TGettersList getters;
- getters.reserve(Nodes.FinishResultNodes.size());
- std::transform(Nodes.FinishResultNodes.cbegin(), Nodes.FinishResultNodes.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
- return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
-#ifdef MKQL_DISABLE_CODEGEN
- state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(), TMyValueHasher(KeyTypes), TMyValueEqual(KeyTypes));
-#else
- state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(),
- ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TMyValueHasher(KeyTypes)),
- ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TMyValueEqual(KeyTypes))
- );
-#endif
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- Nodes.RegisterDependencies(
- [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
- [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
- );
- }
- }
-
- IComputationWideFlowNode *const Flow;
- const TCombinerNodes Nodes;
- const TKeyTypes KeyTypes;
- const ui64 MemLimit;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-
-#ifndef MKQL_DISABLE_CODEGEN
- TEqualsPtr Equals = nullptr;
- THashPtr Hash = nullptr;
-
- Function* EqualsFunc = nullptr;
- Function* HashFunc = nullptr;
-
- template <bool EqualsOrHash>
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (EqualsFunc) {
- Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
- }
- if (HashFunc) {
- Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), KeyTypes));
- codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), KeyTypes));
- }
-#endif
-};
-
-class TWideLastCombinerWrapper: public TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWrapper>
-#ifndef MKQL_DISABLE_CODEGEN
- , public ICodegeneratorRootNode
-#endif
-{
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWrapper>;
-public:
- TWideLastCombinerWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TCombinerNodes&& nodes, TKeyTypes&& keyTypes)
- : TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
- , Flow(flow)
- , Nodes(std::move(nodes))
- , KeyTypes(std::move(keyTypes))
- , Fields(Nodes.ItemNodes.size(), nullptr)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (!state.HasValue()) {
- MakeState(ctx, state);
- }
-
- if (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
- while (EFetchResult::Finish != ptr->InputStatus) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U || Nodes.PasstroughtItems[i])
- Fields[i] = &Nodes.ItemNodes[i]->RefValue(ctx);
-
- switch (ptr->InputStatus = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::One:
- Nodes.ExtractKey(ctx, Fields.data(), static_cast<NUdf::TUnboxedValue*>(ptr->Tongue));
- Nodes.ProcessItem(ctx, ptr->TasteIt() ? nullptr : static_cast<NUdf::TUnboxedValue*>(ptr->Tongue), static_cast<NUdf::TUnboxedValue*>(ptr->Throat));
- continue;
- case EFetchResult::Yield:
- return EFetchResult::Yield;
- case EFetchResult::Finish:
- break;
- }
- }
-
- if (const auto values = static_cast<NUdf::TUnboxedValue*>(ptr->Extract())) {
- Nodes.FinishItem(ctx, values, output);
- return EFetchResult::One;
- }
-
- return EFetchResult::Finish;
- }
- Y_UNREACHABLE();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto contextType = GetCompContextType(context);
- const auto statusType = Type::getInt32Ty(context);
-
- const auto stateType = StructType::get(context, {
- structPtrType, // vtbl
- Type::getInt32Ty(context), // ref
- Type::getInt16Ty(context), // abi
- Type::getInt16Ty(context), // reserved
- structPtrType, // meminfo
- statusType, // status
- ptrValueType, // tongue
- ptrValueType, // throat
- Type::getInt32Ty(context), // size
- Type::getInt32Ty(context), // size
- });
-
- const auto statePtrType = PointerType::getUnqual(stateType);
-
- const auto keys = new AllocaInst(ArrayType::get(valueType, Nodes.KeyResultNodes.size()), 0U, "keys", &ctx.Func->getEntryBlock().back());
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- const auto more = BasicBlock::Create(context, "more", ctx.Func);
-
- BranchInst::Create(main, make, HasValue(statePtr, block), block);
- block = make;
-
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideLastCombinerWrapper::MakeState));
- const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
- const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
- CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
- BranchInst::Create(main, block);
-
- block = main;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
- const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
- BranchInst::Create(more, block);
-
- block = more;
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto full = BasicBlock::Create(context, "full", ctx.Func);
- const auto over = BasicBlock::Create(context, "over", ctx.Func);
- const auto result = PHINode::Create(statusType, 3U, "result", over);
-
- const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
- const auto last = new LoadInst(statusPtr, "last", block);
- const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, last, ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::Finish)), "finish", block);
-
- BranchInst::Create(full, loop, finish, block);
-
- {
- const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- block = loop;
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), block);
-
- const auto choise = SwitchInst::Create(getres.first, good, 2U, block);
- choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), over);
- choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), rest);
-
- block = rest;
- new StoreInst(ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::Finish)), statusPtr, block);
-
- BranchInst::Create(full, block);
-
- block = good;
-
- std::vector<Value*> items(Nodes.ItemNodes.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
- if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U)
- EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.ItemNodes[i])->CreateSetValue(ctx, block, items[i] = getres.second[i](ctx, block));
- else if (Nodes.PasstroughtItems[i])
- items[i] = getres.second[i](ctx, block);
- }
-
- const auto tonguePtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "tongue_ptr", block);
- const auto tongue = new LoadInst(tonguePtr, "tongue", block);
-
- std::vector<Value*> keyPointers(Nodes.KeyResultNodes.size(), nullptr), keys(Nodes.KeyResultNodes.size(), nullptr);
- for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
- auto& key = keys[i];
- const auto keyPtr = keyPointers[i] = GetElementPtrInst::CreateInBounds(tongue, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("key_") += ToString(i)).c_str(), block);
- if (const auto map = Nodes.KeysOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- key = it;
- } else {
- key = GetNodeValue(Nodes.KeyResultNodes[i], ctx, block);
- }
-
- if (Nodes.KeyNodes[i]->GetDependencesCount() > 0U)
- EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.KeyNodes[i])->CreateSetValue(ctx, block, key);
-
- new StoreInst(key, keyPtr, block);
- }
-
- const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::TasteIt));
- const auto atType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
- const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
- const auto newKey = CallInst::Create(atPtr, {stateArg}, "new_key", block);
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
-
- const auto throatPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 7)}, "throat_ptr", block);
- const auto throat = new LoadInst(throatPtr, "throat", block);
-
- std::vector<Value*> pointers;
- pointers.reserve(Nodes.StateNodes.size());
- for (ui32 i = 0U; i < Nodes.StateNodes.size(); ++i) {
- pointers.emplace_back(GetElementPtrInst::CreateInBounds(throat, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("state_") += ToString(i)).c_str(), block));
- }
-
- BranchInst::Create(init, next, newKey, block);
-
- block = init;
-
- for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
- ValueAddRef(Nodes.KeyResultNodes[i]->GetRepresentation(), keyPointers[i], ctx, block);
- }
-
- for (ui32 i = 0U; i < Nodes.InitResultNodes.size(); ++i) {
- if (const auto map = Nodes.InitOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- new StoreInst(it, pointers[i], block);
- ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), it, ctx, block);
- } else if (const auto map = Nodes.InitOnKeys[i]) {
- const auto key = keys[*map];
- new StoreInst(key, pointers[i], block);
- ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), key, ctx, block);
- } else {
- GetNodeValue(pointers[i], Nodes.InitResultNodes[i], ctx, block);
- }
- }
-
- BranchInst::Create(loop, block);
-
- block = next;
-
- std::vector<Value*> stored(Nodes.StateNodes.size(), nullptr);
- for (ui32 i = 0U; i < stored.size(); ++i) {
- const bool hasDependency = Nodes.StateNodes[i]->GetDependencesCount() > 0U;
- if (const auto map = Nodes.StateOnUpdate[i]) {
- if (hasDependency || i != *map) {
- stored[i] = new LoadInst(pointers[i], (TString("state_") += ToString(i)).c_str(), block);
- if (hasDependency)
- EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, stored[i]);
- }
- } else if (hasDependency) {
- EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, pointers[i]);
- } else {
- ValueUnRef(Nodes.StateNodes[i]->GetRepresentation(), pointers[i], ctx, block);
- }
- }
-
- for (ui32 i = 0U; i < Nodes.UpdateResultNodes.size(); ++i) {
- if (const auto map = Nodes.UpdateOnState[i]) {
- if (const auto j = *map; i != j) {
- auto& it = stored[j];
- if (!it)
- it = new LoadInst(pointers[j], (TString("state_") += ToString(j)).c_str(), block);
- new StoreInst(it, pointers[i], block);
- if (i != *Nodes.StateOnUpdate[j])
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
- }
- } else if (const auto map = Nodes.UpdateOnItems[i]) {
- auto& it = items[*map];
- if (!it)
- it = getres.second[*map](ctx, block);
- new StoreInst(it, pointers[i], block);
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
- } else if (const auto map = Nodes.UpdateOnKeys[i]) {
- const auto key = keys[*map];
- new StoreInst(key, pointers[i], block);
- ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), key, ctx, block);
- } else {
- GetNodeValue(pointers[i], Nodes.UpdateResultNodes[i], ctx, block);
- }
- }
-
- BranchInst::Create(loop, block);
- }
-
- {
- block = full;
-
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
-
- const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
- const auto extractType = FunctionType::get(ptrValueType, {stateArg->getType()}, false);
- const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
- const auto out = CallInst::Create(extractPtr, {stateArg}, "out", block);
- const auto has = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, out, ConstantPointerNull::get(ptrValueType), "has", block);
-
- result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), block);
-
- BranchInst::Create(good, over, has, block);
-
- block = good;
-
- for (ui32 i = 0U; i < Nodes.FinishNodes.size(); ++i) {
- const auto ptr = GetElementPtrInst::CreateInBounds(out, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("out_key_") += ToString(i)).c_str(), block);
- if (Nodes.FinishNodes[i]->GetDependencesCount() > 0 || Nodes.ItemsOnResult[i])
- EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.FinishNodes[i])->CreateSetValue(ctx, block, ptr);
- else
- ValueUnRef(Nodes.FinishNodes[i]->GetRepresentation(), ptr, ctx, block);
- }
-
- result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::One)), block);
- BranchInst::Create(over, block);
- }
-
- block = over;
-
- ICodegeneratorInlineWideNode::TGettersList getters;
- getters.reserve(Nodes.FinishResultNodes.size());
- std::transform(Nodes.FinishResultNodes.cbegin(), Nodes.FinishResultNodes.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
- return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
-#ifdef MKQL_DISABLE_CODEGEN
- state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(), TMyValueHasher(KeyTypes), TMyValueEqual(KeyTypes));
-#else
- state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(),
- ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TMyValueHasher(KeyTypes)),
- ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TMyValueEqual(KeyTypes))
- );
-#endif
- }
-
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- Nodes.RegisterDependencies(
- [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
- [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
- );
- }
- }
-
- IComputationWideFlowNode *const Flow;
- const TCombinerNodes Nodes;
- const TKeyTypes KeyTypes;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-
-#ifndef MKQL_DISABLE_CODEGEN
- TEqualsPtr Equals = nullptr;
- THashPtr Hash = nullptr;
-
- Function* EqualsFunc = nullptr;
- Function* HashFunc = nullptr;
-
- template <bool EqualsOrHash>
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- if (EqualsFunc) {
- Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
- }
- if (HashFunc) {
- Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
- }
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
- codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), KeyTypes));
- codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), KeyTypes));
- }
-#endif
-};
-
-}
-
-template<bool Last>
-IComputationNode* WrapWideCombinerT(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= (Last ? 3U : 4U), "Expected more arguments.");
-
- const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
-
- auto index = Last ? 0U : 1U;
-
- const auto keysSize = AS_VALUE(TDataLiteral, callable.GetInput(++index))->AsValue().Get<ui32>();
- const auto stateSize = AS_VALUE(TDataLiteral, callable.GetInput(++index))->AsValue().Get<ui32>();
-
- ++index += inputWidth;
-
- TKeyTypes keyTypes;
- keyTypes.reserve(keysSize);
- for (ui32 i = index; i < index + keysSize; ++i) {
- bool optional;
- keyTypes.emplace_back(*UnpackOptionalData(callable.GetInput(i).GetStaticType(), optional)->GetDataSlot(), optional);
- }
-
- TCombinerNodes nodes;
- nodes.KeyResultNodes.reserve(keysSize);
- std::generate_n(std::back_inserter(nodes.KeyResultNodes), keysSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
-
- index += keysSize;
- nodes.InitResultNodes.reserve(stateSize);
- std::generate_n(std::back_inserter(nodes.InitResultNodes), stateSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
-
- index += stateSize;
- nodes.UpdateResultNodes.reserve(stateSize);
- std::generate_n(std::back_inserter(nodes.UpdateResultNodes), stateSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
-
- index += keysSize + stateSize;
- nodes.FinishResultNodes.reserve(outputWidth);
- std::generate_n(std::back_inserter(nodes.FinishResultNodes), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
-
- index = Last ? 3U : 4U;
-
- nodes.ItemNodes.reserve(inputWidth);
- std::generate_n(std::back_inserter(nodes.ItemNodes), inputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
-
- index += keysSize;
- nodes.KeyNodes.reserve(keysSize);
- std::generate_n(std::back_inserter(nodes.KeyNodes), keysSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
-
- index += stateSize;
- nodes.StateNodes.reserve(stateSize);
- std::generate_n(std::back_inserter(nodes.StateNodes), stateSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
-
- index += stateSize;
- nodes.FinishNodes.reserve(keysSize + stateSize);
- std::generate_n(std::back_inserter(nodes.FinishNodes), keysSize + stateSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
-
- nodes.BuildMaps();
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- if constexpr (Last)
- return new TWideLastCombinerWrapper(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes));
- else {
- const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(1U))->AsValue().Get<ui64>();
- if (EGraphPerProcess::Single == ctx.GraphPerProcess)
- return new TWideCombinerWrapper<true>(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes), memLimit);
- else
- return new TWideCombinerWrapper<false>(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes), memLimit);
- }
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-IComputationNode* WrapWideCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideCombinerT<false>(callable, ctx);
-}
-
-IComputationNode* WrapWideLastCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideCombinerT<true>(callable, ctx);
-}
-
-}
-}
+ else
+ ValueUnRef(Nodes.FinishNodes[i]->GetRepresentation(), ptr, ctx, block);
+ }
+
+ result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::One)), block);
+ BranchInst::Create(over, block);
+ }
+
+ block = over;
+
+ ICodegeneratorInlineWideNode::TGettersList getters;
+ getters.reserve(Nodes.FinishResultNodes.size());
+ std::transform(Nodes.FinishResultNodes.cbegin(), Nodes.FinishResultNodes.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
+ return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+#ifdef MKQL_DISABLE_CODEGEN
+ state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(), TMyValueHasher(KeyTypes), TMyValueEqual(KeyTypes));
+#else
+ state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(),
+ ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TMyValueHasher(KeyTypes)),
+ ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TMyValueEqual(KeyTypes))
+ );
+#endif
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ Nodes.RegisterDependencies(
+ [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
+ [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
+ );
+ }
+ }
+
+ IComputationWideFlowNode *const Flow;
+ const TCombinerNodes Nodes;
+ const TKeyTypes KeyTypes;
+ const ui64 MemLimit;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+
+#ifndef MKQL_DISABLE_CODEGEN
+ TEqualsPtr Equals = nullptr;
+ THashPtr Hash = nullptr;
+
+ Function* EqualsFunc = nullptr;
+ Function* HashFunc = nullptr;
+
+ template <bool EqualsOrHash>
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (EqualsFunc) {
+ Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
+ }
+ if (HashFunc) {
+ Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), KeyTypes));
+ codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), KeyTypes));
+ }
+#endif
+};
+
+class TWideLastCombinerWrapper: public TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWrapper>
+#ifndef MKQL_DISABLE_CODEGEN
+ , public ICodegeneratorRootNode
+#endif
+{
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWrapper>;
+public:
+ TWideLastCombinerWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TCombinerNodes&& nodes, TKeyTypes&& keyTypes)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Boxed)
+ , Flow(flow)
+ , Nodes(std::move(nodes))
+ , KeyTypes(std::move(keyTypes))
+ , Fields(Nodes.ItemNodes.size(), nullptr)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (!state.HasValue()) {
+ MakeState(ctx, state);
+ }
+
+ if (const auto ptr = static_cast<TState*>(state.AsBoxed().Get())) {
+ while (EFetchResult::Finish != ptr->InputStatus) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U || Nodes.PasstroughtItems[i])
+ Fields[i] = &Nodes.ItemNodes[i]->RefValue(ctx);
+
+ switch (ptr->InputStatus = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::One:
+ Nodes.ExtractKey(ctx, Fields.data(), static_cast<NUdf::TUnboxedValue*>(ptr->Tongue));
+ Nodes.ProcessItem(ctx, ptr->TasteIt() ? nullptr : static_cast<NUdf::TUnboxedValue*>(ptr->Tongue), static_cast<NUdf::TUnboxedValue*>(ptr->Throat));
+ continue;
+ case EFetchResult::Yield:
+ return EFetchResult::Yield;
+ case EFetchResult::Finish:
+ break;
+ }
+ }
+
+ if (const auto values = static_cast<NUdf::TUnboxedValue*>(ptr->Extract())) {
+ Nodes.FinishItem(ctx, values, output);
+ return EFetchResult::One;
+ }
+
+ return EFetchResult::Finish;
+ }
+ Y_UNREACHABLE();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto contextType = GetCompContextType(context);
+ const auto statusType = Type::getInt32Ty(context);
+
+ const auto stateType = StructType::get(context, {
+ structPtrType, // vtbl
+ Type::getInt32Ty(context), // ref
+ Type::getInt16Ty(context), // abi
+ Type::getInt16Ty(context), // reserved
+ structPtrType, // meminfo
+ statusType, // status
+ ptrValueType, // tongue
+ ptrValueType, // throat
+ Type::getInt32Ty(context), // size
+ Type::getInt32Ty(context), // size
+ });
+
+ const auto statePtrType = PointerType::getUnqual(stateType);
+
+ const auto keys = new AllocaInst(ArrayType::get(valueType, Nodes.KeyResultNodes.size()), 0U, "keys", &ctx.Func->getEntryBlock().back());
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ const auto more = BasicBlock::Create(context, "more", ctx.Func);
+
+ BranchInst::Create(main, make, HasValue(statePtr, block), block);
+ block = make;
+
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ const auto makeFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TWideLastCombinerWrapper::MakeState));
+ const auto makeType = FunctionType::get(Type::getVoidTy(context), {self->getType(), ctx.Ctx->getType(), statePtr->getType()}, false);
+ const auto makeFuncPtr = CastInst::Create(Instruction::IntToPtr, makeFunc, PointerType::getUnqual(makeType), "function", block);
+ CallInst::Create(makeFuncPtr, {self, ctx.Ctx, statePtr}, "", block);
+ BranchInst::Create(main, block);
+
+ block = main;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto half = CastInst::Create(Instruction::Trunc, state, Type::getInt64Ty(context), "half", block);
+ const auto stateArg = CastInst::Create(Instruction::IntToPtr, half, statePtrType, "state_arg", block);
+ BranchInst::Create(more, block);
+
+ block = more;
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto full = BasicBlock::Create(context, "full", ctx.Func);
+ const auto over = BasicBlock::Create(context, "over", ctx.Func);
+ const auto result = PHINode::Create(statusType, 3U, "result", over);
+
+ const auto statusPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 5)}, "last", block);
+ const auto last = new LoadInst(statusPtr, "last", block);
+ const auto finish = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, last, ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::Finish)), "finish", block);
+
+ BranchInst::Create(full, loop, finish, block);
+
+ {
+ const auto rest = BasicBlock::Create(context, "rest", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ block = loop;
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), block);
+
+ const auto choise = SwitchInst::Create(getres.first, good, 2U, block);
+ choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Yield)), over);
+ choise->addCase(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), rest);
+
+ block = rest;
+ new StoreInst(ConstantInt::get(last->getType(), static_cast<i32>(EFetchResult::Finish)), statusPtr, block);
+
+ BranchInst::Create(full, block);
+
+ block = good;
+
+ std::vector<Value*> items(Nodes.ItemNodes.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
+ if (Nodes.ItemNodes[i]->GetDependencesCount() > 0U)
+ EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.ItemNodes[i])->CreateSetValue(ctx, block, items[i] = getres.second[i](ctx, block));
+ else if (Nodes.PasstroughtItems[i])
+ items[i] = getres.second[i](ctx, block);
+ }
+
+ const auto tonguePtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 6)}, "tongue_ptr", block);
+ const auto tongue = new LoadInst(tonguePtr, "tongue", block);
+
+ std::vector<Value*> keyPointers(Nodes.KeyResultNodes.size(), nullptr), keys(Nodes.KeyResultNodes.size(), nullptr);
+ for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
+ auto& key = keys[i];
+ const auto keyPtr = keyPointers[i] = GetElementPtrInst::CreateInBounds(tongue, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("key_") += ToString(i)).c_str(), block);
+ if (const auto map = Nodes.KeysOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ key = it;
+ } else {
+ key = GetNodeValue(Nodes.KeyResultNodes[i], ctx, block);
+ }
+
+ if (Nodes.KeyNodes[i]->GetDependencesCount() > 0U)
+ EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.KeyNodes[i])->CreateSetValue(ctx, block, key);
+
+ new StoreInst(key, keyPtr, block);
+ }
+
+ const auto atFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::TasteIt));
+ const auto atType = FunctionType::get(Type::getInt1Ty(context), {stateArg->getType()}, false);
+ const auto atPtr = CastInst::Create(Instruction::IntToPtr, atFunc, PointerType::getUnqual(atType), "function", block);
+ const auto newKey = CallInst::Create(atPtr, {stateArg}, "new_key", block);
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+
+ const auto throatPtr = GetElementPtrInst::CreateInBounds(stateArg, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 7)}, "throat_ptr", block);
+ const auto throat = new LoadInst(throatPtr, "throat", block);
+
+ std::vector<Value*> pointers;
+ pointers.reserve(Nodes.StateNodes.size());
+ for (ui32 i = 0U; i < Nodes.StateNodes.size(); ++i) {
+ pointers.emplace_back(GetElementPtrInst::CreateInBounds(throat, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("state_") += ToString(i)).c_str(), block));
+ }
+
+ BranchInst::Create(init, next, newKey, block);
+
+ block = init;
+
+ for (ui32 i = 0U; i < Nodes.KeyResultNodes.size(); ++i) {
+ ValueAddRef(Nodes.KeyResultNodes[i]->GetRepresentation(), keyPointers[i], ctx, block);
+ }
+
+ for (ui32 i = 0U; i < Nodes.InitResultNodes.size(); ++i) {
+ if (const auto map = Nodes.InitOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ new StoreInst(it, pointers[i], block);
+ ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), it, ctx, block);
+ } else if (const auto map = Nodes.InitOnKeys[i]) {
+ const auto key = keys[*map];
+ new StoreInst(key, pointers[i], block);
+ ValueAddRef(Nodes.InitResultNodes[i]->GetRepresentation(), key, ctx, block);
+ } else {
+ GetNodeValue(pointers[i], Nodes.InitResultNodes[i], ctx, block);
+ }
+ }
+
+ BranchInst::Create(loop, block);
+
+ block = next;
+
+ std::vector<Value*> stored(Nodes.StateNodes.size(), nullptr);
+ for (ui32 i = 0U; i < stored.size(); ++i) {
+ const bool hasDependency = Nodes.StateNodes[i]->GetDependencesCount() > 0U;
+ if (const auto map = Nodes.StateOnUpdate[i]) {
+ if (hasDependency || i != *map) {
+ stored[i] = new LoadInst(pointers[i], (TString("state_") += ToString(i)).c_str(), block);
+ if (hasDependency)
+ EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, stored[i]);
+ }
+ } else if (hasDependency) {
+ EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.StateNodes[i])->CreateSetValue(ctx, block, pointers[i]);
+ } else {
+ ValueUnRef(Nodes.StateNodes[i]->GetRepresentation(), pointers[i], ctx, block);
+ }
+ }
+
+ for (ui32 i = 0U; i < Nodes.UpdateResultNodes.size(); ++i) {
+ if (const auto map = Nodes.UpdateOnState[i]) {
+ if (const auto j = *map; i != j) {
+ auto& it = stored[j];
+ if (!it)
+ it = new LoadInst(pointers[j], (TString("state_") += ToString(j)).c_str(), block);
+ new StoreInst(it, pointers[i], block);
+ if (i != *Nodes.StateOnUpdate[j])
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
+ }
+ } else if (const auto map = Nodes.UpdateOnItems[i]) {
+ auto& it = items[*map];
+ if (!it)
+ it = getres.second[*map](ctx, block);
+ new StoreInst(it, pointers[i], block);
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), it, ctx, block);
+ } else if (const auto map = Nodes.UpdateOnKeys[i]) {
+ const auto key = keys[*map];
+ new StoreInst(key, pointers[i], block);
+ ValueAddRef(Nodes.UpdateResultNodes[i]->GetRepresentation(), key, ctx, block);
+ } else {
+ GetNodeValue(pointers[i], Nodes.UpdateResultNodes[i], ctx, block);
+ }
+ }
+
+ BranchInst::Create(loop, block);
+ }
+
+ {
+ block = full;
+
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+
+ const auto extractFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TState::Extract));
+ const auto extractType = FunctionType::get(ptrValueType, {stateArg->getType()}, false);
+ const auto extractPtr = CastInst::Create(Instruction::IntToPtr, extractFunc, PointerType::getUnqual(extractType), "extract", block);
+ const auto out = CallInst::Create(extractPtr, {stateArg}, "out", block);
+ const auto has = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, out, ConstantPointerNull::get(ptrValueType), "has", block);
+
+ result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::Finish)), block);
+
+ BranchInst::Create(good, over, has, block);
+
+ block = good;
+
+ for (ui32 i = 0U; i < Nodes.FinishNodes.size(); ++i) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(out, {ConstantInt::get(Type::getInt32Ty(context), i)}, (TString("out_key_") += ToString(i)).c_str(), block);
+ if (Nodes.FinishNodes[i]->GetDependencesCount() > 0 || Nodes.ItemsOnResult[i])
+ EnsureDynamicCast<ICodegeneratorExternalNode*>(Nodes.FinishNodes[i])->CreateSetValue(ctx, block, ptr);
+ else
+ ValueUnRef(Nodes.FinishNodes[i]->GetRepresentation(), ptr, ctx, block);
+ }
+
+ result->addIncoming(ConstantInt::get(statusType, static_cast<i32>(EFetchResult::One)), block);
+ BranchInst::Create(over, block);
+ }
+
+ block = over;
+
+ ICodegeneratorInlineWideNode::TGettersList getters;
+ getters.reserve(Nodes.FinishResultNodes.size());
+ std::transform(Nodes.FinishResultNodes.cbegin(), Nodes.FinishResultNodes.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
+ return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void MakeState(TComputationContext& ctx, NUdf::TUnboxedValue& state) const {
+#ifdef MKQL_DISABLE_CODEGEN
+ state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(), TMyValueHasher(KeyTypes), TMyValueEqual(KeyTypes));
+#else
+ state = ctx.HolderFactory.Create<TState>(Nodes.KeyNodes.size(), Nodes.StateNodes.size(),
+ ctx.ExecuteLLVM && Hash ? THashFunc(std::ptr_fun(Hash)) : THashFunc(TMyValueHasher(KeyTypes)),
+ ctx.ExecuteLLVM && Equals ? TEqualsFunc(std::ptr_fun(Equals)) : TEqualsFunc(TMyValueEqual(KeyTypes))
+ );
+#endif
+ }
+
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ Nodes.RegisterDependencies(
+ [this, flow](IComputationNode* node){ this->DependsOn(flow, node); },
+ [this, flow](IComputationExternalNode* node){ this->Own(flow, node); }
+ );
+ }
+ }
+
+ IComputationWideFlowNode *const Flow;
+ const TCombinerNodes Nodes;
+ const TKeyTypes KeyTypes;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+
+#ifndef MKQL_DISABLE_CODEGEN
+ TEqualsPtr Equals = nullptr;
+ THashPtr Hash = nullptr;
+
+ Function* EqualsFunc = nullptr;
+ Function* HashFunc = nullptr;
+
+ template <bool EqualsOrHash>
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::" << (EqualsOrHash ? "Equals" : "Hash") << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ if (EqualsFunc) {
+ Equals = reinterpret_cast<TEqualsPtr>(codegen->GetPointerToFunction(EqualsFunc));
+ }
+ if (HashFunc) {
+ Hash = reinterpret_cast<THashPtr>(codegen->GetPointerToFunction(HashFunc));
+ }
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final {
+ codegen->ExportSymbol(HashFunc = GenerateHashFunction(codegen, MakeName<false>(), KeyTypes));
+ codegen->ExportSymbol(EqualsFunc = GenerateEqualsFunction(codegen, MakeName<true>(), KeyTypes));
+ }
+#endif
+};
+
+}
+
+template<bool Last>
+IComputationNode* WrapWideCombinerT(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() >= (Last ? 3U : 4U), "Expected more arguments.");
+
+ const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+
+ auto index = Last ? 0U : 1U;
+
+ const auto keysSize = AS_VALUE(TDataLiteral, callable.GetInput(++index))->AsValue().Get<ui32>();
+ const auto stateSize = AS_VALUE(TDataLiteral, callable.GetInput(++index))->AsValue().Get<ui32>();
+
+ ++index += inputWidth;
+
+ TKeyTypes keyTypes;
+ keyTypes.reserve(keysSize);
+ for (ui32 i = index; i < index + keysSize; ++i) {
+ bool optional;
+ keyTypes.emplace_back(*UnpackOptionalData(callable.GetInput(i).GetStaticType(), optional)->GetDataSlot(), optional);
+ }
+
+ TCombinerNodes nodes;
+ nodes.KeyResultNodes.reserve(keysSize);
+ std::generate_n(std::back_inserter(nodes.KeyResultNodes), keysSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
+
+ index += keysSize;
+ nodes.InitResultNodes.reserve(stateSize);
+ std::generate_n(std::back_inserter(nodes.InitResultNodes), stateSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
+
+ index += stateSize;
+ nodes.UpdateResultNodes.reserve(stateSize);
+ std::generate_n(std::back_inserter(nodes.UpdateResultNodes), stateSize, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
+
+ index += keysSize + stateSize;
+ nodes.FinishResultNodes.reserve(outputWidth);
+ std::generate_n(std::back_inserter(nodes.FinishResultNodes), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, index++); } );
+
+ index = Last ? 3U : 4U;
+
+ nodes.ItemNodes.reserve(inputWidth);
+ std::generate_n(std::back_inserter(nodes.ItemNodes), inputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
+
+ index += keysSize;
+ nodes.KeyNodes.reserve(keysSize);
+ std::generate_n(std::back_inserter(nodes.KeyNodes), keysSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
+
+ index += stateSize;
+ nodes.StateNodes.reserve(stateSize);
+ std::generate_n(std::back_inserter(nodes.StateNodes), stateSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
+
+ index += stateSize;
+ nodes.FinishNodes.reserve(keysSize + stateSize);
+ std::generate_n(std::back_inserter(nodes.FinishNodes), keysSize + stateSize, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, index++); } );
+
+ nodes.BuildMaps();
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ if constexpr (Last)
+ return new TWideLastCombinerWrapper(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes));
+ else {
+ const auto memLimit = AS_VALUE(TDataLiteral, callable.GetInput(1U))->AsValue().Get<ui64>();
+ if (EGraphPerProcess::Single == ctx.GraphPerProcess)
+ return new TWideCombinerWrapper<true>(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes), memLimit);
+ else
+ return new TWideCombinerWrapper<false>(ctx.Mutables, wide, std::move(nodes), std::move(keyTypes), memLimit);
+ }
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+IComputationNode* WrapWideCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideCombinerT<false>(callable, ctx);
+}
+
+IComputationNode* WrapWideLastCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideCombinerT<true>(callable, ctx);
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.h
index e992309c58..68203f53d8 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_combine.h
@@ -1,13 +1,13 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapWideCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapWideLastCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapWideCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapWideLastCombiner(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.cpp
index 473f984995..6473ad4b44 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.cpp
@@ -1,284 +1,284 @@
-#include "mkql_wide_condense.h"
-
+#include "mkql_wide_condense.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/utils/cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-template <bool Interruptable>
-class TWideCondense1Wrapper : public TStatefulWideFlowCodegeneratorNode<TWideCondense1Wrapper<Interruptable>> {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideCondense1Wrapper<Interruptable>>;
-public:
- TWideCondense1Wrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow,
- TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& initState,
- TComputationExternalNodePtrVector&& state, IComputationNode* outSwitch, TComputationNodePtrVector&& updateState)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow)
- , Items(std::move(items)), InitState(std::move(initState))
- , State(std::move(state)), Switch(outSwitch), UpdateState(std::move(updateState))
- , Fields(Items.size(), nullptr), TempState(State.size()), SwitchItem(IsPasstrought(Switch, Items))
- , ItemsOnInit(GetPasstroughtMap(Items, InitState)), ItemsOnUpdate(GetPasstroughtMap(Items, UpdateState))
- , UpdateOnItems(GetPasstroughtMap(UpdateState, Items))
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsFinish()) {
- return EFetchResult::Finish;
- } else if (state.HasValue() && state.Get<bool>()) {
- state = NUdf::TUnboxedValuePod(false);
- for (ui32 i = 0U; i < State.size(); ++i)
- State[i]->SetValue(ctx, InitState[i]->GetValue(ctx));
- }
-
- while (true) {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U || ItemsOnInit[i] || ItemsOnUpdate[i] || SwitchItem && i == *SwitchItem)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Yield:
- return EFetchResult::Yield;
- case EFetchResult::Finish:
- break;
- case EFetchResult::One:
- if (state.IsInvalid()) {
- state = NUdf::TUnboxedValuePod(false);
- for (ui32 i = 0U; i < State.size(); ++i)
- State[i]->SetValue(ctx, InitState[i]->GetValue(ctx));
- } else {
- const auto& reset = Switch->GetValue(ctx);
- if (Interruptable && !reset) {
- break;
- }
-
- if (reset.template Get<bool>()) {
- for (const auto state : State) {
- if (const auto out = *output++) {
- *out = state->GetValue(ctx);
- }
- }
-
- state = NUdf::TUnboxedValuePod(true);
- return EFetchResult::One;
- }
-
- for (ui32 i = 0U; i < State.size(); ++i)
- TempState[i] = UpdateState[i]->GetValue(ctx);
- for (ui32 i = 0U; i < State.size(); ++i)
- State[i]->SetValue(ctx, std::move(TempState[i]));
- }
- continue;
- }
- break;
- }
-
- const bool empty = state.IsInvalid();
- state = NUdf::TUnboxedValuePod::MakeFinish();
- if (empty)
- return EFetchResult::Finish;
-
- for (const auto state : State) {
- if (const auto out = *output++) {
- *out = state->GetValue(ctx);
- }
- }
-
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 4U, "result", exit);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
-
- const auto empty = PHINode::Create(Type::getInt1Ty(context), 3U, "empty", work);
- const auto bit = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bit", block);
- empty->addIncoming(bit, block);
-
- const auto choise = SwitchInst::Create(state, work, 2U, block);
- choise->addCase(GetFinish(context), exit);
- choise->addCase(GetTrue(context), init);
-
- block = init;
-
- new StoreInst(GetFalse(context), statePtr, block);
-
- for (ui32 i = 0U; i < State.size(); ++i) {
+namespace {
+
+template <bool Interruptable>
+class TWideCondense1Wrapper : public TStatefulWideFlowCodegeneratorNode<TWideCondense1Wrapper<Interruptable>> {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideCondense1Wrapper<Interruptable>>;
+public:
+ TWideCondense1Wrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow,
+ TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& initState,
+ TComputationExternalNodePtrVector&& state, IComputationNode* outSwitch, TComputationNodePtrVector&& updateState)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), Flow(flow)
+ , Items(std::move(items)), InitState(std::move(initState))
+ , State(std::move(state)), Switch(outSwitch), UpdateState(std::move(updateState))
+ , Fields(Items.size(), nullptr), TempState(State.size()), SwitchItem(IsPasstrought(Switch, Items))
+ , ItemsOnInit(GetPasstroughtMap(Items, InitState)), ItemsOnUpdate(GetPasstroughtMap(Items, UpdateState))
+ , UpdateOnItems(GetPasstroughtMap(UpdateState, Items))
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsFinish()) {
+ return EFetchResult::Finish;
+ } else if (state.HasValue() && state.Get<bool>()) {
+ state = NUdf::TUnboxedValuePod(false);
+ for (ui32 i = 0U; i < State.size(); ++i)
+ State[i]->SetValue(ctx, InitState[i]->GetValue(ctx));
+ }
+
+ while (true) {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U || ItemsOnInit[i] || ItemsOnUpdate[i] || SwitchItem && i == *SwitchItem)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Yield:
+ return EFetchResult::Yield;
+ case EFetchResult::Finish:
+ break;
+ case EFetchResult::One:
+ if (state.IsInvalid()) {
+ state = NUdf::TUnboxedValuePod(false);
+ for (ui32 i = 0U; i < State.size(); ++i)
+ State[i]->SetValue(ctx, InitState[i]->GetValue(ctx));
+ } else {
+ const auto& reset = Switch->GetValue(ctx);
+ if (Interruptable && !reset) {
+ break;
+ }
+
+ if (reset.template Get<bool>()) {
+ for (const auto state : State) {
+ if (const auto out = *output++) {
+ *out = state->GetValue(ctx);
+ }
+ }
+
+ state = NUdf::TUnboxedValuePod(true);
+ return EFetchResult::One;
+ }
+
+ for (ui32 i = 0U; i < State.size(); ++i)
+ TempState[i] = UpdateState[i]->GetValue(ctx);
+ for (ui32 i = 0U; i < State.size(); ++i)
+ State[i]->SetValue(ctx, std::move(TempState[i]));
+ }
+ continue;
+ }
+ break;
+ }
+
+ const bool empty = state.IsInvalid();
+ state = NUdf::TUnboxedValuePod::MakeFinish();
+ if (empty)
+ return EFetchResult::Finish;
+
+ for (const auto state : State) {
+ if (const auto out = *output++) {
+ *out = state->GetValue(ctx);
+ }
+ }
+
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 4U, "result", exit);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Finish)), block);
+
+ const auto empty = PHINode::Create(Type::getInt1Ty(context), 3U, "empty", work);
+ const auto bit = CastInst::Create(Instruction::Trunc, state, Type::getInt1Ty(context), "bit", block);
+ empty->addIncoming(bit, block);
+
+ const auto choise = SwitchInst::Create(state, work, 2U, block);
+ choise->addCase(GetFinish(context), exit);
+ choise->addCase(GetTrue(context), init);
+
+ block = init;
+
+ new StoreInst(GetFalse(context), statePtr, block);
+
+ for (ui32 i = 0U; i < State.size(); ++i) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(State[i])->CreateSetValue(ctx, block, GetNodeValue(InitState[i], ctx, block));
- }
-
- empty->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(work, block);
-
- block = work;
- const auto getres = GetNodeValues(Flow, ctx, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Yield)), block);
-
- const auto action = SwitchInst::Create(getres.first, good, 2U, block);
- action->addCase(ConstantInt::get(resultType, i32(EFetchResult::Finish)), stop);
- action->addCase(ConstantInt::get(resultType, i32(EFetchResult::Yield)), exit);
-
- block = good;
-
- std::vector<Value*> items(Items.size(), nullptr);
- for (ui32 i = 0U; i < items.size(); ++i) {
- if (Items[i]->GetDependencesCount() > 0U || ItemsOnInit[i])
+ }
+
+ empty->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(work, block);
+
+ block = work;
+ const auto getres = GetNodeValues(Flow, ctx, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::Yield)), block);
+
+ const auto action = SwitchInst::Create(getres.first, good, 2U, block);
+ action->addCase(ConstantInt::get(resultType, i32(EFetchResult::Finish)), stop);
+ action->addCase(ConstantInt::get(resultType, i32(EFetchResult::Yield)), exit);
+
+ block = good;
+
+ std::vector<Value*> items(Items.size(), nullptr);
+ for (ui32 i = 0U; i < items.size(); ++i) {
+ if (Items[i]->GetDependencesCount() > 0U || ItemsOnInit[i])
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, items[i] = getres.second[i](ctx, block));
- else if (ItemsOnUpdate[i] || SwitchItem && i == *SwitchItem)
- items[i] = getres.second[i](ctx, block);
- }
-
- BranchInst::Create(init, next, empty, block);
-
- block = next;
-
- const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- const auto reset = SwitchItem ? items[*SwitchItem] : GetNodeValue(Switch, ctx, block);
-
- if constexpr (Interruptable) {
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- BranchInst::Create(stop, next, IsEmpty(reset, block), block);
- block = pass;
- }
-
- const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
- BranchInst::Create(swap, skip, cast, block);
-
- block = swap;
-
- new StoreInst(GetTrue(context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
- BranchInst::Create(exit, block);
-
- block = skip;
-
- std::vector<Value*> updates(State.size(), nullptr);
- for (ui32 i = 0U; i < State.size(); ++i) {
- if (const auto map = UpdateOnItems[i])
- updates[i] = items[*map];
- else if (State[i] != UpdateState[i])
- updates[i] = GetNodeValue(UpdateState[i], ctx, block);
- }
-
- for (ui32 i = 0U; i < updates.size(); ++i) {
- if (const auto s = updates[i])
+ else if (ItemsOnUpdate[i] || SwitchItem && i == *SwitchItem)
+ items[i] = getres.second[i](ctx, block);
+ }
+
+ BranchInst::Create(init, next, empty, block);
+
+ block = next;
+
+ const auto swap = BasicBlock::Create(context, "swap", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ const auto reset = SwitchItem ? items[*SwitchItem] : GetNodeValue(Switch, ctx, block);
+
+ if constexpr (Interruptable) {
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ BranchInst::Create(stop, next, IsEmpty(reset, block), block);
+ block = pass;
+ }
+
+ const auto cast = CastInst::Create(Instruction::Trunc, reset, Type::getInt1Ty(context), "bool", block);
+ BranchInst::Create(swap, skip, cast, block);
+
+ block = swap;
+
+ new StoreInst(GetTrue(context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, i32(EFetchResult::One)), block);
+ BranchInst::Create(exit, block);
+
+ block = skip;
+
+ std::vector<Value*> updates(State.size(), nullptr);
+ for (ui32 i = 0U; i < State.size(); ++i) {
+ if (const auto map = UpdateOnItems[i])
+ updates[i] = items[*map];
+ else if (State[i] != UpdateState[i])
+ updates[i] = GetNodeValue(UpdateState[i], ctx, block);
+ }
+
+ for (ui32 i = 0U; i < updates.size(); ++i) {
+ if (const auto s = updates[i])
EnsureDynamicCast<ICodegeneratorExternalNode*>(State[i])->CreateSetValue(ctx, block, s);
- }
-
- empty->addIncoming(ConstantInt::getFalse(context), block);
- BranchInst::Create(work, block);
-
- block = stop;
- new StoreInst(GetFinish(context), statePtr, block);
- const auto select = SelectInst::Create(empty, ConstantInt::get(resultType, i32(EFetchResult::Finish)), ConstantInt::get(resultType, i32(EFetchResult::One)), "output", block);
- result->addIncoming(select, block);
- BranchInst::Create(exit, block);
-
- block = exit;
-
- ICodegeneratorInlineWideNode::TGettersList getters;
- getters.reserve(State.size());
- std::transform(State.cbegin(), State.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
- return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideCondense1Wrapper::Own, flow, std::placeholders::_1));
- std::for_each(InitState.cbegin(), InitState.cend(), std::bind(&TWideCondense1Wrapper::DependsOn, flow, std::placeholders::_1));
- std::for_each(State.cbegin(), State.cend(), std::bind(&TWideCondense1Wrapper::Own, flow, std::placeholders::_1));
- TWideCondense1Wrapper::DependsOn(flow, Switch);
- std::for_each(UpdateState.cbegin(), UpdateState.cend(), std::bind(&TWideCondense1Wrapper::DependsOn, flow, std::placeholders::_1));
- }
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- const TComputationNodePtrVector InitState;
- const TComputationExternalNodePtrVector State;
- IComputationNode* const Switch;
- const TComputationNodePtrVector UpdateState;
-
- const std::optional<size_t> SwitchItem;
-
- const TPasstroughtMap ItemsOnInit, ItemsOnUpdate, UpdateOnItems;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
- mutable std::vector<NUdf::TUnboxedValue> TempState;
-};
-
-}
-
-IComputationNode* WrapWideCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() >= 2U, "Expected at least two args.");
-
- const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
-
- TComputationNodePtrVector initState, updateState;
- initState.reserve(outputWidth);
- updateState.reserve(outputWidth);
-
- ui32 index = inputWidth;
-
- std::generate_n(std::back_inserter(initState), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
-
- index += outputWidth;
-
- const auto outSwitch = LocateNode(ctx.NodeLocator, callable, ++index);
-
- bool isOptional;
- const auto dataType = UnpackOptionalData(callable.GetInput(index), isOptional);
- MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
-
- std::generate_n(std::back_inserter(updateState), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
-
- TComputationExternalNodePtrVector items, state;
- items.reserve(inputWidth);
- state.reserve(outputWidth);
-
- index = 0U;
-
- std::generate_n(std::back_inserter(items), inputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
-
- index += outputWidth;
-
- std::generate_n(std::back_inserter(state), outputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- if (isOptional) {
- return new TWideCondense1Wrapper<true>(ctx.Mutables, wide, std::move(items), std::move(initState), std::move(state), outSwitch, std::move(updateState));
- } else {
- return new TWideCondense1Wrapper<false>(ctx.Mutables, wide, std::move(items), std::move(initState), std::move(state), outSwitch, std::move(updateState));
- }
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-}
+ }
+
+ empty->addIncoming(ConstantInt::getFalse(context), block);
+ BranchInst::Create(work, block);
+
+ block = stop;
+ new StoreInst(GetFinish(context), statePtr, block);
+ const auto select = SelectInst::Create(empty, ConstantInt::get(resultType, i32(EFetchResult::Finish)), ConstantInt::get(resultType, i32(EFetchResult::One)), "output", block);
+ result->addIncoming(select, block);
+ BranchInst::Create(exit, block);
+
+ block = exit;
+
+ ICodegeneratorInlineWideNode::TGettersList getters;
+ getters.reserve(State.size());
+ std::transform(State.cbegin(), State.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
+ return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideCondense1Wrapper::Own, flow, std::placeholders::_1));
+ std::for_each(InitState.cbegin(), InitState.cend(), std::bind(&TWideCondense1Wrapper::DependsOn, flow, std::placeholders::_1));
+ std::for_each(State.cbegin(), State.cend(), std::bind(&TWideCondense1Wrapper::Own, flow, std::placeholders::_1));
+ TWideCondense1Wrapper::DependsOn(flow, Switch);
+ std::for_each(UpdateState.cbegin(), UpdateState.cend(), std::bind(&TWideCondense1Wrapper::DependsOn, flow, std::placeholders::_1));
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ const TComputationNodePtrVector InitState;
+ const TComputationExternalNodePtrVector State;
+ IComputationNode* const Switch;
+ const TComputationNodePtrVector UpdateState;
+
+ const std::optional<size_t> SwitchItem;
+
+ const TPasstroughtMap ItemsOnInit, ItemsOnUpdate, UpdateOnItems;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+ mutable std::vector<NUdf::TUnboxedValue> TempState;
+};
+
+}
+
+IComputationNode* WrapWideCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() >= 2U, "Expected at least two args.");
+
+ const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+
+ TComputationNodePtrVector initState, updateState;
+ initState.reserve(outputWidth);
+ updateState.reserve(outputWidth);
+
+ ui32 index = inputWidth;
+
+ std::generate_n(std::back_inserter(initState), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
+
+ index += outputWidth;
+
+ const auto outSwitch = LocateNode(ctx.NodeLocator, callable, ++index);
+
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(callable.GetInput(index), isOptional);
+ MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool.");
+
+ std::generate_n(std::back_inserter(updateState), outputWidth, [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); } );
+
+ TComputationExternalNodePtrVector items, state;
+ items.reserve(inputWidth);
+ state.reserve(outputWidth);
+
+ index = 0U;
+
+ std::generate_n(std::back_inserter(items), inputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
+
+ index += outputWidth;
+
+ std::generate_n(std::back_inserter(state), outputWidth, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); } );
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ if (isOptional) {
+ return new TWideCondense1Wrapper<true>(ctx.Mutables, wide, std::move(items), std::move(initState), std::move(state), outSwitch, std::move(updateState));
+ } else {
+ return new TWideCondense1Wrapper<false>(ctx.Mutables, wide, std::move(items), std::move(initState), std::move(state), outSwitch, std::move(updateState));
+ }
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.h
index 2ab11dd70a..34bcbf6282 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_condense.h
@@ -1,11 +1,11 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapWideCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapWideCondense1(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.cpp
index 6d581817cc..7a6ad7967a 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.cpp
@@ -1,440 +1,440 @@
-#include "mkql_wide_filter.h"
+#include "mkql_wide_filter.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/utils/cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-class TBaseWideFilterWrapper {
-protected:
- TBaseWideFilterWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
- : Flow(flow), Items(std::move(items)), Predicate(predicate), FilterByField(GetPasstroughtMap({Predicate}, Items).front()), Fields(Items.size(), nullptr)
- {}
-
- void PrepareArguments(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
- else
- Fields[i] = output[i];
- }
-
- void FillOutputs(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (const auto out = output[i])
- if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U)
- *out = *Fields[i];
- }
-#ifndef MKQL_DISABLE_CODEGEN
- template<bool ReplaceOriginalGetter = true>
- Value* GenGetPredicate(const TCodegenContext& ctx,
- std::conditional_t<ReplaceOriginalGetter, ICodegeneratorInlineWideNode::TGettersList, const ICodegeneratorInlineWideNode::TGettersList>& getters,
- BasicBlock*& block) const {
- if (FilterByField)
- return CastInst::Create(Instruction::Trunc, getters[*FilterByField](ctx, block), Type::getInt1Ty(ctx.Codegen->GetContext()), "predicate", block);
-
- for (auto i = 0U; i < Items.size(); ++i)
- if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U) {
+namespace {
+
+class TBaseWideFilterWrapper {
+protected:
+ TBaseWideFilterWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
+ : Flow(flow), Items(std::move(items)), Predicate(predicate), FilterByField(GetPasstroughtMap({Predicate}, Items).front()), Fields(Items.size(), nullptr)
+ {}
+
+ void PrepareArguments(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+ else
+ Fields[i] = output[i];
+ }
+
+ void FillOutputs(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (const auto out = output[i])
+ if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ *out = *Fields[i];
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ template<bool ReplaceOriginalGetter = true>
+ Value* GenGetPredicate(const TCodegenContext& ctx,
+ std::conditional_t<ReplaceOriginalGetter, ICodegeneratorInlineWideNode::TGettersList, const ICodegeneratorInlineWideNode::TGettersList>& getters,
+ BasicBlock*& block) const {
+ if (FilterByField)
+ return CastInst::Create(Instruction::Trunc, getters[*FilterByField](ctx, block), Type::getInt1Ty(ctx.Codegen->GetContext()), "predicate", block);
+
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Predicate == Items[i] || Items[i]->GetDependencesCount() > 0U) {
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getters[i](ctx, block));
- if constexpr (ReplaceOriginalGetter)
- getters[i] = [node=Items[i]](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- }
-
- const auto pred = GetNodeValue(Predicate, ctx, block);
- return CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(ctx.Codegen->GetContext()), "predicate", block);
- }
-#endif
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const Predicate;
-
- std::optional<size_t> FilterByField;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-class TWideFilterWrapper : public TStatelessWideFlowCodegeneratorNode<TWideFilterWrapper>, public TBaseWideFilterWrapper {
-using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideFilterWrapper>;
-public:
- TWideFilterWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
- : TBaseComputation(flow), TBaseWideFilterWrapper(flow, std::move(items), predicate)
- {}
-
- EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- while (true) {
- PrepareArguments(ctx, output);
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- if (Predicate->GetValue(ctx).Get<bool>()) {
- FillOutputs(ctx, output);
- return EFetchResult::One;
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
-
- BranchInst::Create(loop, block);
-
- block = loop;
-
- auto status = GetNodeValues(Flow, ctx, block);
-
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, status.first, ConstantInt::get(status.first->getType(), 0), "good", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- BranchInst::Create(work, pass, good, block);
-
- block = work;
-
- const auto predicate = GenGetPredicate(ctx, status.second, block);
-
- BranchInst::Create(pass, loop, predicate, block);
-
- block = pass;
- return status;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideFilterWrapper::Own, flow, std::placeholders::_1));
- DependsOn(flow, Predicate);
- }
- }
-};
-
-class TWideFilterWithLimitWrapper : public TStatefulWideFlowCodegeneratorNode<TWideFilterWithLimitWrapper>, public TBaseWideFilterWrapper {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideFilterWithLimitWrapper>;
-public:
- TWideFilterWithLimitWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* limit, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate), Limit(limit)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (state.IsInvalid()) {
- state = Limit->GetValue(ctx);
- } else if (!state.Get<ui64>()) {
- return EFetchResult::Finish;
- }
-
- while (true) {
- PrepareArguments(ctx, output);
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- if (Predicate->GetValue(ctx).Get<bool>()) {
- FillOutputs(ctx, output);
-
- auto todo = state.Get<ui64>();
- state = NUdf::TUnboxedValuePod(--todo);
- return EFetchResult::One;
- }
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto init = BasicBlock::Create(context, "init", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
-
- const auto valueType = Type::getInt128Ty(context);
- const auto resultType = Type::getInt32Ty(context);
- const auto result = PHINode::Create(resultType, 3U, "result", exit);
-
- BranchInst::Create(test, init, IsValid(statePtr, block), block);
-
- block = init;
-
- GetNodeValue(statePtr, Limit, ctx, block);
- BranchInst::Create(test, block);
-
- block = test;
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetFalse(context), "done", block);
- result->addIncoming(ConstantInt::get(resultType, -1), block);
-
- BranchInst::Create(exit, loop, done, block);
-
- block = loop;
-
- auto status = GetNodeValues(Flow, ctx, block);
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, status.first, ConstantInt::get(status.first->getType(), 0), "good", block);
-
- result->addIncoming(status.first, block);
-
- BranchInst::Create(work, exit, good, block);
-
- block = work;
-
- const auto predicate = GenGetPredicate(ctx, status.second, block);
-
- BranchInst::Create(pass, loop, predicate, block);
-
- block = pass;
-
- const auto decr = BinaryOperator::CreateSub(state, ConstantInt::get(state->getType(), 1ULL), "decr", block);
- new StoreInst(decr, statePtr, block);
-
- result->addIncoming(status.first, block);
-
- BranchInst::Create(exit, block);
-
- block = exit;
- return {result, std::move(status.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- DependsOn(flow, Limit);
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideFilterWithLimitWrapper::Own, flow, std::placeholders::_1));
- DependsOn(flow, Predicate);
- }
- }
-
- IComputationNode* const Limit;
-};
-
-template<bool Inclusive>
-class TWideTakeWhileWrapper : public TStatefulWideFlowCodegeneratorNode<TWideTakeWhileWrapper<Inclusive>>, public TBaseWideFilterWrapper {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideTakeWhileWrapper<Inclusive>>;
-public:
- TWideTakeWhileWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (!state.IsInvalid()) {
- return EFetchResult::Finish;
- }
-
- PrepareArguments(ctx, output);
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- const bool predicate = Predicate->GetValue(ctx).Get<bool>();
- if (!predicate)
- state = NUdf::TUnboxedValuePod();
-
- if (Inclusive || predicate) {
- FillOutputs(ctx, output);
- return EFetchResult::One;
- }
-
- return EFetchResult::Finish;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto resultType = Type::getInt32Ty(context);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(resultType, 4U, "result", done);
- result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
-
- const auto state = new LoadInst(statePtr, "state", block);
- const auto finished = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetTrue(context), "finished", block);
-
- BranchInst::Create(done, work, IsValid(statePtr, block), block);
-
- block = work;
- auto status = GetNodeValues(Flow, ctx, block);
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status.first, ConstantInt::get(resultType, 0), "special", block);
- result->addIncoming(status.first, block);
- BranchInst::Create(done, test, special, block);
-
- block = test;
-
- const auto predicate = GenGetPredicate(ctx, status.second, block);
- result->addIncoming(status.first, block);
- BranchInst::Create(done, stop, predicate, block);
-
- block = stop;
-
- new StoreInst(GetEmpty(context), statePtr, block);
- result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(Inclusive ? EFetchResult::One: EFetchResult::Finish)), block);
-
- BranchInst::Create(done, block);
-
- block = done;
- return {result, std::move(status.second)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideTakeWhileWrapper::Own, flow, std::placeholders::_1));
- TWideTakeWhileWrapper::DependsOn(flow, Predicate);
- }
- }
-};
-
-template<bool Inclusive>
-class TWideSkipWhileWrapper : public TStatefulWideFlowCodegeneratorNode<TWideSkipWhileWrapper<Inclusive>>, public TBaseWideFilterWrapper {
-using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideSkipWhileWrapper<Inclusive>>;
-public:
- TWideSkipWhileWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
- : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate)
- {}
-
- EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (!state.IsInvalid()) {
- return Flow->FetchValues(ctx, output);
- }
-
- do {
- PrepareArguments(ctx, output);
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
- } while (Predicate->GetValue(ctx).Get<bool>());
-
- state = NUdf::TUnboxedValuePod();
-
- if constexpr (Inclusive)
- return Flow->FetchValues(ctx, output);
- else {
- FillOutputs(ctx, output);
- return EFetchResult::One;
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto resultType = Type::getInt32Ty(context);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(work, block);
-
- block = work;
-
- const auto status = GetNodeValues(Flow, ctx, block);
-
- const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status.first, ConstantInt::get(resultType, 0), "special", block);
- const auto passtrought = BinaryOperator::CreateOr(special, IsValid(statePtr, block), "passtrought", block);
- BranchInst::Create(done, test, passtrought, block);
-
- block = test;
-
- const auto predicate = GenGetPredicate<false>(ctx, status.second, block);
- BranchInst::Create(work, stop, predicate, block);
-
- block = stop;
-
- new StoreInst(GetEmpty(context), statePtr, block);
-
- BranchInst::Create(Inclusive ? work : done, block);
-
- block = done;
- return status;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = this->FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideSkipWhileWrapper::Own, flow, std::placeholders::_1));
- TWideSkipWhileWrapper::DependsOn(flow, Predicate);
- }
- }
-};
-
-template<bool TakeOrSkip, bool Inclusive>
-IComputationNode* WrapWideWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Expected 3 or more args.");
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature");
- const auto predicate = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() - 1U);
- TComputationExternalNodePtrVector args;
- args.reserve(width);
- ui32 index = 0U;
- std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- if constexpr (TakeOrSkip) {
- return new TWideTakeWhileWrapper<Inclusive>(ctx.Mutables, wide, std::move(args), predicate);
- } else {
- return new TWideSkipWhileWrapper<Inclusive>(ctx.Mutables, wide, std::move(args), predicate);
- }
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-
-IComputationNode* WrapWideFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U || callable.GetInputsCount() == width + 3U, "Expected 3 or more args.");
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- const auto predicate = LocateNode(ctx.NodeLocator, callable, width + 1U);
- TComputationExternalNodePtrVector args;
- args.reserve(width);
- ui32 index = 0U;
- std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- if (const auto last = callable.GetInputsCount() - 1U; last == width + 1U) {
- return new TWideFilterWrapper(wide, std::move(args), predicate);
- } else {
- const auto limit = LocateNode(ctx.NodeLocator, callable, last);
- return new TWideFilterWithLimitWrapper(ctx.Mutables, wide, limit, std::move(args), predicate);
- }
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-IComputationNode* WrapWideTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideWhile<true, false>(callable, ctx);
-}
-
-IComputationNode* WrapWideSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideWhile<false, false>(callable, ctx);
-}
-
-IComputationNode* WrapWideTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideWhile<true, true>(callable, ctx);
-}
-
-IComputationNode* WrapWideSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- return WrapWideWhile<false, true>(callable, ctx);
-}
-
-
-}
-}
+ if constexpr (ReplaceOriginalGetter)
+ getters[i] = [node=Items[i]](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ }
+
+ const auto pred = GetNodeValue(Predicate, ctx, block);
+ return CastInst::Create(Instruction::Trunc, pred, Type::getInt1Ty(ctx.Codegen->GetContext()), "predicate", block);
+ }
+#endif
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const Predicate;
+
+ std::optional<size_t> FilterByField;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+class TWideFilterWrapper : public TStatelessWideFlowCodegeneratorNode<TWideFilterWrapper>, public TBaseWideFilterWrapper {
+using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideFilterWrapper>;
+public:
+ TWideFilterWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
+ : TBaseComputation(flow), TBaseWideFilterWrapper(flow, std::move(items), predicate)
+ {}
+
+ EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ while (true) {
+ PrepareArguments(ctx, output);
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ if (Predicate->GetValue(ctx).Get<bool>()) {
+ FillOutputs(ctx, output);
+ return EFetchResult::One;
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+
+ BranchInst::Create(loop, block);
+
+ block = loop;
+
+ auto status = GetNodeValues(Flow, ctx, block);
+
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, status.first, ConstantInt::get(status.first->getType(), 0), "good", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ BranchInst::Create(work, pass, good, block);
+
+ block = work;
+
+ const auto predicate = GenGetPredicate(ctx, status.second, block);
+
+ BranchInst::Create(pass, loop, predicate, block);
+
+ block = pass;
+ return status;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideFilterWrapper::Own, flow, std::placeholders::_1));
+ DependsOn(flow, Predicate);
+ }
+ }
+};
+
+class TWideFilterWithLimitWrapper : public TStatefulWideFlowCodegeneratorNode<TWideFilterWithLimitWrapper>, public TBaseWideFilterWrapper {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideFilterWithLimitWrapper>;
+public:
+ TWideFilterWithLimitWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, IComputationNode* limit, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate), Limit(limit)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (state.IsInvalid()) {
+ state = Limit->GetValue(ctx);
+ } else if (!state.Get<ui64>()) {
+ return EFetchResult::Finish;
+ }
+
+ while (true) {
+ PrepareArguments(ctx, output);
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ if (Predicate->GetValue(ctx).Get<bool>()) {
+ FillOutputs(ctx, output);
+
+ auto todo = state.Get<ui64>();
+ state = NUdf::TUnboxedValuePod(--todo);
+ return EFetchResult::One;
+ }
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto init = BasicBlock::Create(context, "init", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto loop = BasicBlock::Create(context, "loop", ctx.Func);
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto resultType = Type::getInt32Ty(context);
+ const auto result = PHINode::Create(resultType, 3U, "result", exit);
+
+ BranchInst::Create(test, init, IsValid(statePtr, block), block);
+
+ block = init;
+
+ GetNodeValue(statePtr, Limit, ctx, block);
+ BranchInst::Create(test, block);
+
+ block = test;
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto done = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetFalse(context), "done", block);
+ result->addIncoming(ConstantInt::get(resultType, -1), block);
+
+ BranchInst::Create(exit, loop, done, block);
+
+ block = loop;
+
+ auto status = GetNodeValues(Flow, ctx, block);
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, status.first, ConstantInt::get(status.first->getType(), 0), "good", block);
+
+ result->addIncoming(status.first, block);
+
+ BranchInst::Create(work, exit, good, block);
+
+ block = work;
+
+ const auto predicate = GenGetPredicate(ctx, status.second, block);
+
+ BranchInst::Create(pass, loop, predicate, block);
+
+ block = pass;
+
+ const auto decr = BinaryOperator::CreateSub(state, ConstantInt::get(state->getType(), 1ULL), "decr", block);
+ new StoreInst(decr, statePtr, block);
+
+ result->addIncoming(status.first, block);
+
+ BranchInst::Create(exit, block);
+
+ block = exit;
+ return {result, std::move(status.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ DependsOn(flow, Limit);
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideFilterWithLimitWrapper::Own, flow, std::placeholders::_1));
+ DependsOn(flow, Predicate);
+ }
+ }
+
+ IComputationNode* const Limit;
+};
+
+template<bool Inclusive>
+class TWideTakeWhileWrapper : public TStatefulWideFlowCodegeneratorNode<TWideTakeWhileWrapper<Inclusive>>, public TBaseWideFilterWrapper {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideTakeWhileWrapper<Inclusive>>;
+public:
+ TWideTakeWhileWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (!state.IsInvalid()) {
+ return EFetchResult::Finish;
+ }
+
+ PrepareArguments(ctx, output);
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ const bool predicate = Predicate->GetValue(ctx).Get<bool>();
+ if (!predicate)
+ state = NUdf::TUnboxedValuePod();
+
+ if (Inclusive || predicate) {
+ FillOutputs(ctx, output);
+ return EFetchResult::One;
+ }
+
+ return EFetchResult::Finish;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto resultType = Type::getInt32Ty(context);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(resultType, 4U, "result", done);
+ result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(EFetchResult::Finish)), block);
+
+ const auto state = new LoadInst(statePtr, "state", block);
+ const auto finished = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, state, GetTrue(context), "finished", block);
+
+ BranchInst::Create(done, work, IsValid(statePtr, block), block);
+
+ block = work;
+ auto status = GetNodeValues(Flow, ctx, block);
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status.first, ConstantInt::get(resultType, 0), "special", block);
+ result->addIncoming(status.first, block);
+ BranchInst::Create(done, test, special, block);
+
+ block = test;
+
+ const auto predicate = GenGetPredicate(ctx, status.second, block);
+ result->addIncoming(status.first, block);
+ BranchInst::Create(done, stop, predicate, block);
+
+ block = stop;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+ result->addIncoming(ConstantInt::get(resultType, static_cast<i32>(Inclusive ? EFetchResult::One: EFetchResult::Finish)), block);
+
+ BranchInst::Create(done, block);
+
+ block = done;
+ return {result, std::move(status.second)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideTakeWhileWrapper::Own, flow, std::placeholders::_1));
+ TWideTakeWhileWrapper::DependsOn(flow, Predicate);
+ }
+ }
+};
+
+template<bool Inclusive>
+class TWideSkipWhileWrapper : public TStatefulWideFlowCodegeneratorNode<TWideSkipWhileWrapper<Inclusive>>, public TBaseWideFilterWrapper {
+using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideSkipWhileWrapper<Inclusive>>;
+public:
+ TWideSkipWhileWrapper(TComputationMutables& mutables, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* predicate)
+ : TBaseComputation(mutables, flow, EValueRepresentation::Embedded), TBaseWideFilterWrapper(flow, std::move(items), predicate)
+ {}
+
+ EFetchResult DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (!state.IsInvalid()) {
+ return Flow->FetchValues(ctx, output);
+ }
+
+ do {
+ PrepareArguments(ctx, output);
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+ } while (Predicate->GetValue(ctx).Get<bool>());
+
+ state = NUdf::TUnboxedValuePod();
+
+ if constexpr (Inclusive)
+ return Flow->FetchValues(ctx, output);
+ else {
+ FillOutputs(ctx, output);
+ return EFetchResult::One;
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ ICodegeneratorInlineWideNode::TGenerateResult DoGenGetValues(const TCodegenContext& ctx, Value* statePtr, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto resultType = Type::getInt32Ty(context);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(work, block);
+
+ block = work;
+
+ const auto status = GetNodeValues(Flow, ctx, block);
+
+ const auto special = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, status.first, ConstantInt::get(resultType, 0), "special", block);
+ const auto passtrought = BinaryOperator::CreateOr(special, IsValid(statePtr, block), "passtrought", block);
+ BranchInst::Create(done, test, passtrought, block);
+
+ block = test;
+
+ const auto predicate = GenGetPredicate<false>(ctx, status.second, block);
+ BranchInst::Create(work, stop, predicate, block);
+
+ block = stop;
+
+ new StoreInst(GetEmpty(context), statePtr, block);
+
+ BranchInst::Create(Inclusive ? work : done, block);
+
+ block = done;
+ return status;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = this->FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideSkipWhileWrapper::Own, flow, std::placeholders::_1));
+ TWideSkipWhileWrapper::DependsOn(flow, Predicate);
+ }
+ }
+};
+
+template<bool TakeOrSkip, bool Inclusive>
+IComputationNode* WrapWideWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Expected 3 or more args.");
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature");
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() - 1U);
+ TComputationExternalNodePtrVector args;
+ args.reserve(width);
+ ui32 index = 0U;
+ std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ if constexpr (TakeOrSkip) {
+ return new TWideTakeWhileWrapper<Inclusive>(ctx.Mutables, wide, std::move(args), predicate);
+ } else {
+ return new TWideSkipWhileWrapper<Inclusive>(ctx.Mutables, wide, std::move(args), predicate);
+ }
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+
+IComputationNode* WrapWideFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U || callable.GetInputsCount() == width + 3U, "Expected 3 or more args.");
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ const auto predicate = LocateNode(ctx.NodeLocator, callable, width + 1U);
+ TComputationExternalNodePtrVector args;
+ args.reserve(width);
+ ui32 index = 0U;
+ std::generate_n(std::back_inserter(args), width, [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ if (const auto last = callable.GetInputsCount() - 1U; last == width + 1U) {
+ return new TWideFilterWrapper(wide, std::move(args), predicate);
+ } else {
+ const auto limit = LocateNode(ctx.NodeLocator, callable, last);
+ return new TWideFilterWithLimitWrapper(ctx.Mutables, wide, limit, std::move(args), predicate);
+ }
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+IComputationNode* WrapWideTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideWhile<true, false>(callable, ctx);
+}
+
+IComputationNode* WrapWideSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideWhile<false, false>(callable, ctx);
+}
+
+IComputationNode* WrapWideTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideWhile<true, true>(callable, ctx);
+}
+
+IComputationNode* WrapWideSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ return WrapWideWhile<false, true>(callable, ctx);
+}
+
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.h
index 5d55e7724a..f860b7c26b 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_filter.h
@@ -1,15 +1,15 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapWideFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapWideTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapWideSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapWideTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-IComputationNode* WrapWideSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapWideFilter(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapWideTakeWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapWideSkipWhile(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapWideTakeWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+IComputationNode* WrapWideSkipWhileInclusive(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.cpp
index 3487d411ef..a4e3e3ad04 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.cpp
@@ -1,306 +1,306 @@
-#include "mkql_wide_map.h"
+#include "mkql_wide_map.h"
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/utils/cast.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
using NYql::EnsureDynamicCast;
-namespace {
-
-class TExpandMapWrapper : public TStatelessWideFlowCodegeneratorNode<TExpandMapWrapper> {
-using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TExpandMapWrapper>;
-public:
- TExpandMapWrapper(IComputationNode* flow, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
- : TBaseComputation(flow), Flow(flow), Item(item), NewItems(std::move(newItems))
- {}
-
- EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
- return item.IsYield() ? EFetchResult::Yield : EFetchResult::Finish;
- } else {
- Item->SetValue(ctx, std::move(item));
- }
-
- for (const auto item : NewItems)
- if (const auto out = *output++)
- *out = item->GetValue(ctx);
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
- MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
-
- const auto item = GetNodeValue(Flow, ctx, block);
-
- const auto resultType = Type::getInt32Ty(context);
- const auto outres = SelectInst::Create(IsYield(item, block), ConstantInt::get(resultType, 0), ConstantInt::get(resultType, -1), "outres", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
- const auto result = PHINode::Create(outres->getType(), 2, "result", pass);
-
- result->addIncoming(outres, block);
-
- BranchInst::Create(pass, work, IsSpecial(item, block), block);
-
- block = work;
- codegenItem->CreateSetValue(ctx, block, item);
-
- result->addIncoming(ConstantInt::get(resultType, 1), block);
-
- BranchInst::Create(pass, block);
-
- block = pass;
-
- TGettersList getters;
- getters.reserve(NewItems.size());
- std::transform(NewItems.cbegin(), NewItems.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
- return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
- });
- return {result, std::move(getters)};
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- Own(flow, Item);
- std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TExpandMapWrapper::DependsOn, flow, std::placeholders::_1));
- }
- }
-
- IComputationNode* const Flow;
- IComputationExternalNode *const Item;
- const TComputationNodePtrVector NewItems;
-};
-
-class TWideMapWrapper : public TStatelessWideFlowCodegeneratorNode<TWideMapWrapper> {
-using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideMapWrapper>;
-public:
- TWideMapWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& newItems)
- : TBaseComputation(flow), Flow(flow), Items(std::move(items)), NewItems(std::move(newItems)), Fields(Items.size(), nullptr)
- , PasstroughtMap(GetPasstroughtMap(Items, NewItems)), ReversePasstroughtMap(GetPasstroughtMap(NewItems, Items))
- {}
-
- EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
- else if (const auto& map = PasstroughtMap[i])
- if (const auto out = output[*map])
- Fields[i] = out;
-
- if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
- return result;
-
- for (auto i = 0U; i < NewItems.size(); ++i) {
- if (const auto out = output[i]) {
- if (const auto& map = ReversePasstroughtMap[i]) {
- if (const auto from = *map; !Items[from]->GetDependencesCount()) {
- if (const auto first = *PasstroughtMap[from]; first != i)
- *out = *output[first];
- continue;
- }
- }
-
- *out = NewItems[i]->GetValue(ctx);
- }
- }
- return EFetchResult::One;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valueType = Type::getInt128Ty(context);
-
- const auto result = GetNodeValues(Flow, ctx, block);
-
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, result.first, ConstantInt::get(result.first->getType(), 0), "good", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- BranchInst::Create(work, pass, good, block);
-
- block = work;
-
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+namespace {
+
+class TExpandMapWrapper : public TStatelessWideFlowCodegeneratorNode<TExpandMapWrapper> {
+using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TExpandMapWrapper>;
+public:
+ TExpandMapWrapper(IComputationNode* flow, IComputationExternalNode* item, TComputationNodePtrVector&& newItems)
+ : TBaseComputation(flow), Flow(flow), Item(item), NewItems(std::move(newItems))
+ {}
+
+ EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ if (auto item = Flow->GetValue(ctx); item.IsSpecial()) {
+ return item.IsYield() ? EFetchResult::Yield : EFetchResult::Finish;
+ } else {
+ Item->SetValue(ctx, std::move(item));
+ }
+
+ for (const auto item : NewItems)
+ if (const auto out = *output++)
+ *out = item->GetValue(ctx);
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto codegenItem = dynamic_cast<ICodegeneratorExternalNode*>(Item);
+ MKQL_ENSURE(codegenItem, "Item must be codegenerator node.");
+
+ const auto item = GetNodeValue(Flow, ctx, block);
+
+ const auto resultType = Type::getInt32Ty(context);
+ const auto outres = SelectInst::Create(IsYield(item, block), ConstantInt::get(resultType, 0), ConstantInt::get(resultType, -1), "outres", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+ const auto result = PHINode::Create(outres->getType(), 2, "result", pass);
+
+ result->addIncoming(outres, block);
+
+ BranchInst::Create(pass, work, IsSpecial(item, block), block);
+
+ block = work;
+ codegenItem->CreateSetValue(ctx, block, item);
+
+ result->addIncoming(ConstantInt::get(resultType, 1), block);
+
+ BranchInst::Create(pass, block);
+
+ block = pass;
+
+ TGettersList getters;
+ getters.reserve(NewItems.size());
+ std::transform(NewItems.cbegin(), NewItems.cend(), std::back_inserter(getters), [&](IComputationNode* node) {
+ return [node](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); };
+ });
+ return {result, std::move(getters)};
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ Own(flow, Item);
+ std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TExpandMapWrapper::DependsOn, flow, std::placeholders::_1));
+ }
+ }
+
+ IComputationNode* const Flow;
+ IComputationExternalNode *const Item;
+ const TComputationNodePtrVector NewItems;
+};
+
+class TWideMapWrapper : public TStatelessWideFlowCodegeneratorNode<TWideMapWrapper> {
+using TBaseComputation = TStatelessWideFlowCodegeneratorNode<TWideMapWrapper>;
+public:
+ TWideMapWrapper(IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, TComputationNodePtrVector&& newItems)
+ : TBaseComputation(flow), Flow(flow), Items(std::move(items)), NewItems(std::move(newItems)), Fields(Items.size(), nullptr)
+ , PasstroughtMap(GetPasstroughtMap(Items, NewItems)), ReversePasstroughtMap(GetPasstroughtMap(NewItems, Items))
+ {}
+
+ EFetchResult DoCalculate(TComputationContext& ctx, NUdf::TUnboxedValue*const* output) const {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+ else if (const auto& map = PasstroughtMap[i])
+ if (const auto out = output[*map])
+ Fields[i] = out;
+
+ if (const auto result = Flow->FetchValues(ctx, Fields.data()); EFetchResult::One != result)
+ return result;
+
+ for (auto i = 0U; i < NewItems.size(); ++i) {
+ if (const auto out = output[i]) {
+ if (const auto& map = ReversePasstroughtMap[i]) {
+ if (const auto from = *map; !Items[from]->GetDependencesCount()) {
+ if (const auto first = *PasstroughtMap[from]; first != i)
+ *out = *output[first];
+ continue;
+ }
+ }
+
+ *out = NewItems[i]->GetValue(ctx);
+ }
+ }
+ return EFetchResult::One;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ TGenerateResult DoGenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valueType = Type::getInt128Ty(context);
+
+ const auto result = GetNodeValues(Flow, ctx, block);
+
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, result.first, ConstantInt::get(result.first->getType(), 0), "good", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ BranchInst::Create(work, pass, good, block);
+
+ block = work;
+
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, result.second[i](ctx, block));
-
- BranchInst::Create(pass, block);
-
- block = pass;
-
- TGettersList getters;
- getters.reserve(NewItems.size());
- for (auto i = 0U; i < NewItems.size(); ++i) {
- if (const auto map = ReversePasstroughtMap[i])
- getters.emplace_back(result.second[*map]);
- else
- getters.emplace_back([node=NewItems[i]](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); });
- };
- return {result.first, std::move(getters)};
-
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideMapWrapper::Own, flow, std::placeholders::_1));
- std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TWideMapWrapper::DependsOn, flow, std::placeholders::_1));
- }
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- const TComputationNodePtrVector NewItems;
- const TPasstroughtMap PasstroughtMap, ReversePasstroughtMap;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-class TNarrowMapWrapper : public TStatelessFlowCodegeneratorNode<TNarrowMapWrapper> {
-using TBaseComputation = TStatelessFlowCodegeneratorNode<TNarrowMapWrapper>;
-public:
- TNarrowMapWrapper(EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* newItem)
- : TBaseComputation(flow, kind)
- , Flow(flow)
- , Items(std::move(items))
- , NewItem(newItem)
- , PasstroughItem(GetPasstroughtMap({NewItem}, Items).front())
- , Fields(Items.size(), nullptr)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- for (auto i = 0U; i < Fields.size(); ++i)
- if (NewItem == Items[i] || Items[i]->GetDependencesCount() > 0U)
- Fields[i] = &Items[i]->RefValue(ctx);
-
- switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
- case EFetchResult::Finish:
- return NUdf::TUnboxedValuePod::MakeFinish();
- case EFetchResult::Yield:
- return NUdf::TUnboxedValuePod::MakeYield();
- case EFetchResult::One:
- return NewItem->GetValue(ctx).Release();
- }
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
-
- const auto getres = GetNodeValues(Flow, ctx, block);
-
- const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
-
- const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
-
- const auto result = PHINode::Create(outres->getType(), 2, "result", pass);
- result->addIncoming(outres, block);
-
- BranchInst::Create(work, pass, good, block);
-
- block = work;
-
- if (const auto passtrough = PasstroughItem) {
- result->addIncoming(getres.second[*passtrough](ctx, block), block);
- } else {
- for (auto i = 0U; i < Items.size(); ++i)
- if (Items[i]->GetDependencesCount() > 0U)
+
+ BranchInst::Create(pass, block);
+
+ block = pass;
+
+ TGettersList getters;
+ getters.reserve(NewItems.size());
+ for (auto i = 0U; i < NewItems.size(); ++i) {
+ if (const auto map = ReversePasstroughtMap[i])
+ getters.emplace_back(result.second[*map]);
+ else
+ getters.emplace_back([node=NewItems[i]](const TCodegenContext& ctx, BasicBlock*& block){ return GetNodeValue(node, ctx, block); });
+ };
+ return {result.first, std::move(getters)};
+
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TWideMapWrapper::Own, flow, std::placeholders::_1));
+ std::for_each(NewItems.cbegin(), NewItems.cend(), std::bind(&TWideMapWrapper::DependsOn, flow, std::placeholders::_1));
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ const TComputationNodePtrVector NewItems;
+ const TPasstroughtMap PasstroughtMap, ReversePasstroughtMap;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+class TNarrowMapWrapper : public TStatelessFlowCodegeneratorNode<TNarrowMapWrapper> {
+using TBaseComputation = TStatelessFlowCodegeneratorNode<TNarrowMapWrapper>;
+public:
+ TNarrowMapWrapper(EValueRepresentation kind, IComputationWideFlowNode* flow, TComputationExternalNodePtrVector&& items, IComputationNode* newItem)
+ : TBaseComputation(flow, kind)
+ , Flow(flow)
+ , Items(std::move(items))
+ , NewItem(newItem)
+ , PasstroughItem(GetPasstroughtMap({NewItem}, Items).front())
+ , Fields(Items.size(), nullptr)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ for (auto i = 0U; i < Fields.size(); ++i)
+ if (NewItem == Items[i] || Items[i]->GetDependencesCount() > 0U)
+ Fields[i] = &Items[i]->RefValue(ctx);
+
+ switch (const auto result = Flow->FetchValues(ctx, Fields.data())) {
+ case EFetchResult::Finish:
+ return NUdf::TUnboxedValuePod::MakeFinish();
+ case EFetchResult::Yield:
+ return NUdf::TUnboxedValuePod::MakeYield();
+ case EFetchResult::One:
+ return NewItem->GetValue(ctx).Release();
+ }
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto getres = GetNodeValues(Flow, ctx, block);
+
+ const auto yield = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, getres.first, ConstantInt::get(getres.first->getType(), 0), "yield", block);
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, getres.first, ConstantInt::get(getres.first->getType(), 0), "good", block);
+
+ const auto outres = SelectInst::Create(yield, GetYield(context), GetFinish(context), "outres", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto pass = BasicBlock::Create(context, "pass", ctx.Func);
+
+ const auto result = PHINode::Create(outres->getType(), 2, "result", pass);
+ result->addIncoming(outres, block);
+
+ BranchInst::Create(work, pass, good, block);
+
+ block = work;
+
+ if (const auto passtrough = PasstroughItem) {
+ result->addIncoming(getres.second[*passtrough](ctx, block), block);
+ } else {
+ for (auto i = 0U; i < Items.size(); ++i)
+ if (Items[i]->GetDependencesCount() > 0U)
EnsureDynamicCast<ICodegeneratorExternalNode*>(Items[i])->CreateSetValue(ctx, block, getres.second[i](ctx, block));
-
- result->addIncoming(GetNodeValue(NewItem, ctx, block), block);
- }
-
- BranchInst::Create(pass, block);
-
- block = pass;
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- if (const auto flow = FlowDependsOn(Flow)) {
- std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowMapWrapper::Own, flow, std::placeholders::_1));
- DependsOn(flow, NewItem);
- }
- }
-
- IComputationWideFlowNode* const Flow;
- const TComputationExternalNodePtrVector Items;
- IComputationNode* const NewItem;
-
- const std::optional<size_t> PasstroughItem;
-
- mutable std::vector<NUdf::TUnboxedValue*> Fields;
-};
-
-}
-
-IComputationNode* WrapExpandMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Expected two or more args.");
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
-
- TComputationNodePtrVector newItems(width, nullptr);
- ui32 index = 1U;
- std::generate(newItems.begin(), newItems.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
- return new TExpandMapWrapper(flow, itemArg, std::move(newItems));
-}
-
-IComputationNode* WrapWideMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected argument.");
- const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == inputWidth + outputWidth + 1U, "Wrong signature.");
-
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- TComputationNodePtrVector newItems(outputWidth, nullptr);
- ui32 index = inputWidth;
- std::generate(newItems.begin(), newItems.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
-
- TComputationExternalNodePtrVector args(inputWidth, nullptr);
- index = 0U;
- std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- return new TWideMapWrapper(wide, std::move(args), std::move(newItems));
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-IComputationNode* WrapNarrowMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() > 1U, "Expected two or more args.");
- const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
- MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature.");
- const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
- if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
- const auto newItem = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() - 1U);
-
- TComputationExternalNodePtrVector args(width, nullptr);
- ui32 index = 0U;
- std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
-
- return new TNarrowMapWrapper(GetValueRepresentation(callable.GetType()->GetReturnType()), wide, std::move(args), newItem);
- }
-
- THROW yexception() << "Expected wide flow.";
-}
-
-}
-}
+
+ result->addIncoming(GetNodeValue(NewItem, ctx, block), block);
+ }
+
+ BranchInst::Create(pass, block);
+
+ block = pass;
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ if (const auto flow = FlowDependsOn(Flow)) {
+ std::for_each(Items.cbegin(), Items.cend(), std::bind(&TNarrowMapWrapper::Own, flow, std::placeholders::_1));
+ DependsOn(flow, NewItem);
+ }
+ }
+
+ IComputationWideFlowNode* const Flow;
+ const TComputationExternalNodePtrVector Items;
+ IComputationNode* const NewItem;
+
+ const std::optional<size_t> PasstroughItem;
+
+ mutable std::vector<NUdf::TUnboxedValue*> Fields;
+};
+
+}
+
+IComputationNode* WrapExpandMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Expected two or more args.");
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+
+ TComputationNodePtrVector newItems(width, nullptr);
+ ui32 index = 1U;
+ std::generate(newItems.begin(), newItems.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ const auto itemArg = LocateExternalNode(ctx.NodeLocator, callable, 1U);
+ return new TExpandMapWrapper(flow, itemArg, std::move(newItems));
+}
+
+IComputationNode* WrapWideMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 0U, "Expected argument.");
+ const auto inputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ const auto outputWidth = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetType()->GetReturnType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == inputWidth + outputWidth + 1U, "Wrong signature.");
+
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ TComputationNodePtrVector newItems(outputWidth, nullptr);
+ ui32 index = inputWidth;
+ std::generate(newItems.begin(), newItems.end(), [&](){ return LocateNode(ctx.NodeLocator, callable, ++index); });
+
+ TComputationExternalNodePtrVector args(inputWidth, nullptr);
+ index = 0U;
+ std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ return new TWideMapWrapper(wide, std::move(args), std::move(newItems));
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+IComputationNode* WrapNarrowMap(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() > 1U, "Expected two or more args.");
+ const auto width = AS_TYPE(TTupleType, AS_TYPE(TFlowType, callable.GetInput(0U).GetStaticType())->GetItemType())->GetElementsCount();
+ MKQL_ENSURE(callable.GetInputsCount() == width + 2U, "Wrong signature.");
+ const auto flow = LocateNode(ctx.NodeLocator, callable, 0U);
+ if (const auto wide = dynamic_cast<IComputationWideFlowNode*>(flow)) {
+ const auto newItem = LocateNode(ctx.NodeLocator, callable, callable.GetInputsCount() - 1U);
+
+ TComputationExternalNodePtrVector args(width, nullptr);
+ ui32 index = 0U;
+ std::generate(args.begin(), args.end(), [&](){ return LocateExternalNode(ctx.NodeLocator, callable, ++index); });
+
+ return new TNarrowMapWrapper(GetValueRepresentation(callable.GetType()->GetReturnType()), wide, std::move(args), newItem);
+ }
+
+ THROW yexception() << "Expected wide flow.";
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.h b/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.h
index 2ea7ca79b3..8e301a3314 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_wide_map.h
@@ -1,14 +1,14 @@
-#pragma once
+#pragma once
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-IComputationNode* WrapExpandMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapWideMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-IComputationNode* WrapNarrowMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+IComputationNode* WrapExpandMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapWideMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+IComputationNode* WrapNarrowMap(TCallable& callable, const TComputationNodeFactoryContext& ctx);
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_zip.cpp b/ydb/library/yql/minikql/comp_nodes/mkql_zip.cpp
index 6f5e19dfef..702778d5da 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_zip.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_zip.cpp
@@ -6,8 +6,8 @@
namespace NKikimr {
namespace NMiniKQL {
-namespace {
-
+namespace {
+
template <bool All>
class TZipWrapper : public TMutableComputationNode<TZipWrapper<All>> {
typedef TMutableComputationNode<TZipWrapper<All>> TBaseComputation;
@@ -16,83 +16,83 @@ public:
class TValue : public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters, TComputationContext& ctx, const TSelf* self)
- : TComputationValue<TIterator>(memInfo)
- , Iters(std::move(iters))
+ TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters, TComputationContext& ctx, const TSelf* self)
+ : TComputationValue<TIterator>(memInfo)
+ , Iters(std::move(iters))
, Ctx(ctx)
, Self(self)
{}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- bool hasSome = false;
- NUdf::TUnboxedValue* items = nullptr;
- auto tuple = Self->ResTuple.NewArray(Ctx, Iters.size(), items);
- for (auto& iter : Iters) {
- if (iter) {
- NUdf::TUnboxedValue item;
- if (!iter.Next(item)) {
- if (All) {
- *items = std::move(item);
- iter = NUdf::TUnboxedValue();
- } else {
- Iters.clear();
- return false;
- }
- } else {
- *items = All ? NUdf::TUnboxedValue(item.Release().MakeOptional()) : std::move(item);
- hasSome = true;
- }
- } else {
- if (All) {
- *items = NUdf::TUnboxedValuePod();
- } else {
- Iters.clear();
- return false;
- }
- }
- ++items;
- }
-
- if (!hasSome)
- return false;
- value = std::move(tuple);
- return true;
- }
-
- bool Skip() override {
- bool hasSome = false;
- for (size_t i = 0, e = Iters.size(); i < e; i++) {
- auto& iter = Iters[i];
- if (iter) {
- if (!iter.Skip()) {
- if (All) {
- Iters[i] = NUdf::TUnboxedValue();
- } else {
- Iters.clear();
- return false;
- }
- } else {
- hasSome = true;
- }
- } else if (!All) {
- return false;
- }
- }
-
- return hasSome;
- }
-
- TUnboxedValueVector Iters;
-
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ bool hasSome = false;
+ NUdf::TUnboxedValue* items = nullptr;
+ auto tuple = Self->ResTuple.NewArray(Ctx, Iters.size(), items);
+ for (auto& iter : Iters) {
+ if (iter) {
+ NUdf::TUnboxedValue item;
+ if (!iter.Next(item)) {
+ if (All) {
+ *items = std::move(item);
+ iter = NUdf::TUnboxedValue();
+ } else {
+ Iters.clear();
+ return false;
+ }
+ } else {
+ *items = All ? NUdf::TUnboxedValue(item.Release().MakeOptional()) : std::move(item);
+ hasSome = true;
+ }
+ } else {
+ if (All) {
+ *items = NUdf::TUnboxedValuePod();
+ } else {
+ Iters.clear();
+ return false;
+ }
+ }
+ ++items;
+ }
+
+ if (!hasSome)
+ return false;
+ value = std::move(tuple);
+ return true;
+ }
+
+ bool Skip() override {
+ bool hasSome = false;
+ for (size_t i = 0, e = Iters.size(); i < e; i++) {
+ auto& iter = Iters[i];
+ if (iter) {
+ if (!iter.Skip()) {
+ if (All) {
+ Iters[i] = NUdf::TUnboxedValue();
+ } else {
+ Iters.clear();
+ return false;
+ }
+ } else {
+ hasSome = true;
+ }
+ } else if (!All) {
+ return false;
+ }
+ }
+
+ return hasSome;
+ }
+
+ TUnboxedValueVector Iters;
+
TComputationContext& Ctx;
- const TSelf* const Self;
+ const TSelf* const Self;
};
TValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists, TComputationContext& ctx,
- const TSelf* self)
+ const TSelf* self)
: TCustomListValue(memInfo)
, Lists(std::move(lists))
, Ctx(ctx)
@@ -103,23 +103,23 @@ public:
}
~TValue() {
- MKQL_MEM_RETURN(GetMemInfo(), &Lists, Lists.capacity() * sizeof(NUdf::TUnboxedValue));
- }
-
- private:
- NUdf::TUnboxedValue GetListIterator() const override {
- if (Lists.empty()) {
- return Ctx.HolderFactory.GetEmptyContainer();
- }
-
- TUnboxedValueVector iters;
- iters.reserve(Lists.size());
- for (auto& list : Lists) {
- iters.emplace_back(list.GetListIterator());
- }
-
- return Ctx.HolderFactory.Create<TIterator>(std::move(iters), Ctx, Self);
- }
+ MKQL_MEM_RETURN(GetMemInfo(), &Lists, Lists.capacity() * sizeof(NUdf::TUnboxedValue));
+ }
+
+ private:
+ NUdf::TUnboxedValue GetListIterator() const override {
+ if (Lists.empty()) {
+ return Ctx.HolderFactory.GetEmptyContainer();
+ }
+
+ TUnboxedValueVector iters;
+ iters.reserve(Lists.size());
+ for (auto& list : Lists) {
+ iters.emplace_back(list.GetListIterator());
+ }
+
+ return Ctx.HolderFactory.Create<TIterator>(std::move(iters), Ctx, Self);
+ }
ui64 GetListLength() const override {
if (!Length) {
@@ -142,7 +142,7 @@ public:
Length = length;
}
- return *Length;
+ return *Length;
}
bool HasListItems() const override {
@@ -155,68 +155,68 @@ public:
TUnboxedValueVector Lists;
TComputationContext& Ctx;
- const TSelf *const Self;
+ const TSelf *const Self;
};
TZipWrapper(TComputationMutables& mutables, TComputationNodePtrVector& lists)
: TBaseComputation(mutables)
, Lists(std::move(lists))
, ResTuple(mutables)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- TUnboxedValueVector listValues;
- TSmallVec<const NUdf::TUnboxedValue*, TMKQLAllocator<const NUdf::TUnboxedValue*>> arrays;
- listValues.reserve(Lists.size());
- arrays.reserve(Lists.size());
- for (auto& list : Lists) {
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ TUnboxedValueVector listValues;
+ TSmallVec<const NUdf::TUnboxedValue*, TMKQLAllocator<const NUdf::TUnboxedValue*>> arrays;
+ listValues.reserve(Lists.size());
+ arrays.reserve(Lists.size());
+ for (auto& list : Lists) {
listValues.emplace_back(list->GetValue(ctx));
- arrays.emplace_back(listValues.back().GetElements());
+ arrays.emplace_back(listValues.back().GetElements());
}
- if (std::any_of(arrays.cbegin(), arrays.cend(), std::logical_not<const NUdf::TUnboxedValue*>()))
- return ctx.HolderFactory.Create<TValue>(std::move(listValues), ctx, this);
-
- TSmallVec<ui64, TMKQLAllocator<ui64>> sizes;
- sizes.reserve(listValues.size());
- std::transform(listValues.cbegin(), listValues.cend(), std::back_inserter(sizes), std::bind(&NUdf::TUnboxedValuePod::GetListLength, std::placeholders::_1));
-
- const auto size = *(All ? std::max_element(sizes.cbegin(), sizes.cend()) : std::min_element(sizes.cbegin(), sizes.cend()));
-
- if (!size)
- return ctx.HolderFactory.GetEmptyContainer();
-
- NUdf::TUnboxedValue *listItems = nullptr;
- const auto list = ctx.HolderFactory.CreateDirectArrayHolder(size, listItems);
-
- for (auto i = 0U; i < size; ++i) {
- NUdf::TUnboxedValue *items = nullptr;
- *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(arrays.size(), items);
- for (auto j = 0U; j < arrays.size(); ++j) {
- if constexpr (All) {
- if (sizes[j] > i)
- *items++ = *arrays[j]++;
- else
- ++items;
- } else {
- *items++ = *arrays[j]++;
- }
- }
- }
- return list;
+ if (std::any_of(arrays.cbegin(), arrays.cend(), std::logical_not<const NUdf::TUnboxedValue*>()))
+ return ctx.HolderFactory.Create<TValue>(std::move(listValues), ctx, this);
+
+ TSmallVec<ui64, TMKQLAllocator<ui64>> sizes;
+ sizes.reserve(listValues.size());
+ std::transform(listValues.cbegin(), listValues.cend(), std::back_inserter(sizes), std::bind(&NUdf::TUnboxedValuePod::GetListLength, std::placeholders::_1));
+
+ const auto size = *(All ? std::max_element(sizes.cbegin(), sizes.cend()) : std::min_element(sizes.cbegin(), sizes.cend()));
+
+ if (!size)
+ return ctx.HolderFactory.GetEmptyContainer();
+
+ NUdf::TUnboxedValue *listItems = nullptr;
+ const auto list = ctx.HolderFactory.CreateDirectArrayHolder(size, listItems);
+
+ for (auto i = 0U; i < size; ++i) {
+ NUdf::TUnboxedValue *items = nullptr;
+ *listItems++ = ctx.HolderFactory.CreateDirectArrayHolder(arrays.size(), items);
+ for (auto j = 0U; j < arrays.size(); ++j) {
+ if constexpr (All) {
+ if (sizes[j] > i)
+ *items++ = *arrays[j]++;
+ else
+ ++items;
+ } else {
+ *items++ = *arrays[j]++;
+ }
+ }
+ }
+ return list;
}
-private:
- void RegisterDependencies() const final {
- std::for_each(Lists.cbegin(), Lists.cend(), std::bind(&TZipWrapper::DependsOn, this, std::placeholders::_1));
+private:
+ void RegisterDependencies() const final {
+ std::for_each(Lists.cbegin(), Lists.cend(), std::bind(&TZipWrapper::DependsOn, this, std::placeholders::_1));
}
- const TComputationNodePtrVector Lists;
- const TContainerCacheOnContext ResTuple;
+ const TComputationNodePtrVector Lists;
+ const TContainerCacheOnContext ResTuple;
};
-}
-
+}
+
template <bool All>
IComputationNode* WrapZip(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
TComputationNodePtrVector lists;
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_chain_map_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_chain_map_ut.cpp
index c36126aeb1..b41a0527de 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_chain_map_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_chain_map_ut.cpp
@@ -1,253 +1,253 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
namespace NKikimr {
namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLChainMapNodeTest) {
- Y_UNIT_TEST_LLVM(TestOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
-
- auto data0 = pb.NewEmptyOptional(dataType);
-
- auto data2 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(7),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
- }));
- auto data3 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(1),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
- }));
-
- auto list = pb.NewList(dataType, {data2, data0, data3});
-
- auto init = pb.NewTuple({
- pb.NewOptional(pb.NewDataLiteral<i32>(3)),
- pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"))
- });
-
- auto pgmReturn = pb.ChainMap(list, init,
- [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- auto skey = pb.AggrAdd(pb.Nth(state, 0), key);
- auto sval = pb.AggrConcat(pb.Nth(state, 1), val);
- return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
- }
- );
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+Y_UNIT_TEST_SUITE(TMiniKQLChainMapNodeTest) {
+ Y_UNIT_TEST_LLVM(TestOverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
+
+ auto data0 = pb.NewEmptyOptional(dataType);
+
+ auto data2 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(7),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
+ }));
+ auto data3 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(1),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
+ }));
+
+ auto list = pb.NewList(dataType, {data2, data0, data3});
+
+ auto init = pb.NewTuple({
+ pb.NewOptional(pb.NewDataLiteral<i32>(3)),
+ pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"))
+ });
+
+ auto pgmReturn = pb.ChainMap(list, init,
+ [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ auto skey = pb.AggrAdd(pb.Nth(state, 0), key);
+ auto sval = pb.AggrConcat(pb.Nth(state, 1), val);
+ return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
+ }
+ );
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(Test1OverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
+
+ auto data0 = pb.NewEmptyOptional(dataType);
+
+ auto data1 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(3),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("B")
+ }));
+ auto data2 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(7),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
+ }));
+ auto data3 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(1),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
+ }));
+
+ auto list = pb.NewList(dataType, {data1, data2, data3, data0});
+
+ auto pgmReturn = pb.Chain1Map(list,
+ [&](TRuntimeNode item) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ return {pb.NewTuple({key, val, key, val}), pb.NewTuple({key, val})};
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ auto skey = pb.Add(pb.Nth(state, 0), key);
+ auto sval = pb.Concat(pb.Nth(state, 1), val);
+ return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
+ }
+ );
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "B");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(Test1OverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
-
- auto data0 = pb.NewEmptyOptional(dataType);
-
- auto data1 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(3),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("B")
- }));
- auto data2 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(7),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
- }));
- auto data3 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(1),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
- }));
-
- auto list = pb.NewList(dataType, {data1, data2, data3, data0});
-
- auto pgmReturn = pb.Chain1Map(list,
- [&](TRuntimeNode item) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- return {pb.NewTuple({key, val, key, val}), pb.NewTuple({key, val})};
- },
- [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- auto skey = pb.Add(pb.Nth(state, 0), key);
- auto sval = pb.Concat(pb.Nth(state, 1), val);
- return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
- }
- );
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!item.GetElement(3));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
+
+ auto data0 = pb.NewEmptyOptional(dataType);
+
+ auto data2 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(7),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
+ }));
+ auto data3 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(1),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
+ }));
+
+ auto list = pb.NewList(dataType, {data2, data0, data3});
+
+ auto init = pb.NewTuple({
+ pb.NewOptional(pb.NewDataLiteral<i32>(3)),
+ pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"))
+ });
+
+ auto pgmReturn = pb.FromFlow(pb.ChainMap(pb.ToFlow(list), init,
+ [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ auto skey = pb.AggrAdd(pb.Nth(state, 0), key);
+ auto sval = pb.AggrConcat(pb.Nth(state, 1), val);
+ return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
+ }
+ ));
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(Test1OverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
+
+ auto data0 = pb.NewEmptyOptional(dataType);
+
+ auto data1 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(3),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("B")
+ }));
+ auto data2 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(7),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
+ }));
+ auto data3 = pb.NewOptional(pb.NewTuple({
+ pb.NewDataLiteral<i32>(1),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
+ }));
+
+ auto list = pb.NewList(dataType, {data1, data2, data3, data0});
+
+ auto pgmReturn = pb.FromFlow(pb.Chain1Map(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ return {pb.NewTuple({key, val, key, val}), pb.NewTuple({key, val})};
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ auto key = pb.Nth(item, 0);
+ auto val = pb.Nth(item, 1);
+ auto skey = pb.Add(pb.Nth(state, 0), key);
+ auto sval = pb.Concat(pb.Nth(state, 1), val);
+ return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
+ }
+ ));
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "B");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "B");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!item.GetElement(3));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
-
- auto data0 = pb.NewEmptyOptional(dataType);
-
- auto data2 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(7),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
- }));
- auto data3 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(1),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
- }));
-
- auto list = pb.NewList(dataType, {data2, data0, data3});
-
- auto init = pb.NewTuple({
- pb.NewOptional(pb.NewDataLiteral<i32>(3)),
- pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"))
- });
-
- auto pgmReturn = pb.FromFlow(pb.ChainMap(pb.ToFlow(list), init,
- [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- auto skey = pb.AggrAdd(pb.Nth(state, 0), key);
- auto sval = pb.AggrConcat(pb.Nth(state, 1), val);
- return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
- }
- ));
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(Test1OverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewOptionalType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)}));
-
- auto data0 = pb.NewEmptyOptional(dataType);
-
- auto data1 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(3),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("B")
- }));
- auto data2 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(7),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("A")
- }));
- auto data3 = pb.NewOptional(pb.NewTuple({
- pb.NewDataLiteral<i32>(1),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("D")
- }));
-
- auto list = pb.NewList(dataType, {data1, data2, data3, data0});
-
- auto pgmReturn = pb.FromFlow(pb.Chain1Map(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- return {pb.NewTuple({key, val, key, val}), pb.NewTuple({key, val})};
- },
- [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- auto key = pb.Nth(item, 0);
- auto val = pb.Nth(item, 1);
- auto skey = pb.Add(pb.Nth(state, 0), key);
- auto sval = pb.Concat(pb.Nth(state, 1), val);
- return {pb.NewTuple({key, val, skey, sval}), pb.NewTuple({skey, sval})};
- }
- ));
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "B");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 7);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 10);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BA");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 11);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!item.GetElement(3));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3), "BAD");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!item.GetElement(3));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_chopper_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
index d09a0fabe4..8d9d557669 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
@@ -1,4 +1,4 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
@@ -8,480 +8,480 @@ namespace NMiniKQL {
namespace {
-template<bool UseLLVM>
-TRuntimeNode MakeStream(TSetup<UseLLVM>& setup, ui64 count = 9U) {
- TProgramBuilder& pb = *setup.PgmBuilder;
+template<bool UseLLVM>
+TRuntimeNode MakeStream(TSetup<UseLLVM>& setup, ui64 count = 9U) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
TCallableBuilder callableBuilder(*setup.Env, "TestStream",
- pb.NewStreamType(
- pb.NewDataType(NUdf::EDataSlot::Uint64)
+ pb.NewStreamType(
+ pb.NewDataType(NUdf::EDataSlot::Uint64)
)
);
- callableBuilder.Add(pb.NewDataLiteral(count));
+ callableBuilder.Add(pb.NewDataLiteral(count));
return TRuntimeNode(callableBuilder.Build(), false);
}
-template<bool UseLLVM>
-TRuntimeNode MakeFlow(TSetup<UseLLVM>& setup, ui64 count = 9U) {
- TProgramBuilder& pb = *setup.PgmBuilder;
- return pb.ToFlow(MakeStream<UseLLVM>(setup, count));
-}
-
-template<bool UseLLVM>
-TRuntimeNode GroupWithBomb(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto keyExtractor = [&](TRuntimeNode item) { return item; };
- const auto groupSwitch = [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); };
-
- return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode, TRuntimeNode group) {
- const auto bomb = pb.NewDataLiteral<NUdf::EDataSlot::String>("BOMB");
- return pb.Ensure(pb.Map(group, [&] (TRuntimeNode) { return bomb; }), pb.NewDataLiteral<bool>(false), bomb, "", 0, 0);
- });
-}
-
-template<bool UseLLVM>
+template<bool UseLLVM>
+TRuntimeNode MakeFlow(TSetup<UseLLVM>& setup, ui64 count = 9U) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ return pb.ToFlow(MakeStream<UseLLVM>(setup, count));
+}
+
+template<bool UseLLVM>
+TRuntimeNode GroupWithBomb(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto keyExtractor = [&](TRuntimeNode item) { return item; };
+ const auto groupSwitch = [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); };
+
+ return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode, TRuntimeNode group) {
+ const auto bomb = pb.NewDataLiteral<NUdf::EDataSlot::String>("BOMB");
+ return pb.Ensure(pb.Map(group, [&] (TRuntimeNode) { return bomb; }), pb.NewDataLiteral<bool>(false), bomb, "", 0, 0);
+ });
+}
+
+template<bool UseLLVM>
TRuntimeNode Group(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch) {
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto keyExtractor = [&](TRuntimeNode item) { return item; };
+ const auto keyExtractor = [&](TRuntimeNode item) { return item; };
- return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode key, TRuntimeNode grpItem) {
- return pb.Condense(grpItem, pb.NewDataLiteral<NUdf::EDataSlot::String>("*"),
- [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
+ return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode key, TRuntimeNode grpItem) {
+ return pb.Condense(grpItem, pb.NewDataLiteral<NUdf::EDataSlot::String>("*"),
+ [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
[&] (TRuntimeNode item, TRuntimeNode state) {
- auto res = pb.Concat(pb.ToString(key), pb.ToString(item));
- res = pb.Concat(state, res);
- return pb.Concat(res, pb.NewDataLiteral<NUdf::EDataSlot::String>("*"));
- });
+ auto res = pb.Concat(pb.ToString(key), pb.ToString(item));
+ res = pb.Concat(state, res);
+ return pb.Concat(res, pb.NewDataLiteral<NUdf::EDataSlot::String>("*"));
+ });
+ });
+}
+
+template<bool UseLLVM>
+TRuntimeNode GroupGetKeysFirst(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto keyExtractor = [&](TRuntimeNode item) { return item; };
+
+ const bool isFlow = stream.GetStaticType()->IsFlow();
+
+ return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode key, TRuntimeNode grpItem) {
+ auto list = pb.ToList(pb.AggrConcat(
+ pb.NewOptional(pb.Concat(pb.ToString(key), pb.NewDataLiteral<NUdf::EDataSlot::String>(":"))),
+ pb.ToOptional(pb.Collect(pb.Condense1(grpItem,
+ [&] (TRuntimeNode item) { return pb.ToString(item); },
+ [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
+ [&] (TRuntimeNode item, TRuntimeNode state) {
+ return pb.Concat(state, pb.ToString(item));
+ }
+ )))
+ ));
+ return isFlow ? pb.ToFlow(list) : pb.Iterator(list, {});
});
}
-template<bool UseLLVM>
-TRuntimeNode GroupGetKeysFirst(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch) {
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto keyExtractor = [&](TRuntimeNode item) { return item; };
-
- const bool isFlow = stream.GetStaticType()->IsFlow();
-
- return pb.Chopper(stream, keyExtractor, groupSwitch, [&](TRuntimeNode key, TRuntimeNode grpItem) {
- auto list = pb.ToList(pb.AggrConcat(
- pb.NewOptional(pb.Concat(pb.ToString(key), pb.NewDataLiteral<NUdf::EDataSlot::String>(":"))),
- pb.ToOptional(pb.Collect(pb.Condense1(grpItem,
- [&] (TRuntimeNode item) { return pb.ToString(item); },
- [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
- [&] (TRuntimeNode item, TRuntimeNode state) {
- return pb.Concat(state, pb.ToString(item));
- }
- )))
- ));
- return isFlow ? pb.ToFlow(list) : pb.Iterator(list, {});
- });
-}
-
-template<bool UseLLVM>
+template<bool UseLLVM>
TRuntimeNode GroupKeys(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch) {
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto keyExtractor = [&](TRuntimeNode item) { return item; };
+ const auto keyExtractor = [&](TRuntimeNode item) { return item; };
- return pb.Chopper(stream, keyExtractor, groupSwitch,
- [&](TRuntimeNode key, TRuntimeNode group) {
- return pb.Map(pb.Take(group, pb.NewDataLiteral<ui64>(1ULL)), [&](TRuntimeNode) { return pb.ToString(key); });
- }
- );
+ return pb.Chopper(stream, keyExtractor, groupSwitch,
+ [&](TRuntimeNode key, TRuntimeNode group) {
+ return pb.Map(pb.Take(group, pb.NewDataLiteral<ui64>(1ULL)), [&](TRuntimeNode) { return pb.ToString(key); });
+ }
+ );
}
-template<bool UseLLVM>
-TRuntimeNode StreamToString(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- stream = pb.Condense(stream, pb.NewDataLiteral<NUdf::EDataSlot::String>("|"),
- [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
- [&] (TRuntimeNode item, TRuntimeNode state) {
- return pb.Concat(pb.Concat(state, item), pb.NewDataLiteral<NUdf::EDataSlot::String>("|"));
- }
- );
- if (stream.GetStaticType()->IsFlow()) {
- stream = pb.FromFlow(stream);
- }
- return stream;
+template<bool UseLLVM>
+TRuntimeNode StreamToString(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ stream = pb.Condense(stream, pb.NewDataLiteral<NUdf::EDataSlot::String>("|"),
+ [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
+ [&] (TRuntimeNode item, TRuntimeNode state) {
+ return pb.Concat(pb.Concat(state, item), pb.NewDataLiteral<NUdf::EDataSlot::String>("|"));
+ }
+ );
+ if (stream.GetStaticType()->IsFlow()) {
+ stream = pb.FromFlow(stream);
+ }
+ return stream;
}
} // unnamed
-Y_UNIT_TEST_SUITE(TMiniKQLChopperStreamTest) {
- Y_UNIT_TEST_LLVM(TestEmpty) {
- TSetup<LLVM> setup;
-
- const auto stream = GroupWithBomb(setup, MakeStream(setup, 0U));
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
- }
-
- Y_UNIT_TEST_LLVM(TestGrouping) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+Y_UNIT_TEST_SUITE(TMiniKQLChopperStreamTest) {
+ Y_UNIT_TEST_LLVM(TestEmpty) {
+ TSetup<LLVM> setup;
+
+ const auto stream = GroupWithBomb(setup, MakeStream(setup, 0U));
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGrouping) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
});
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingGetKeysFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeStream(setup);
- stream = GroupGetKeysFirst(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0:0|0:01|0:0|0:0|0:0123|");
- }
-
+ Y_UNIT_TEST_LLVM(TestGroupingGetKeysFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeStream(setup);
+ stream = GroupGetKeysFirst(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0:0|0:01|0:0|0:0|0:0123|");
+ }
+
Y_UNIT_TEST_LLVM(TestGroupingKeyNotEquals) {
TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- return pb.NotEquals(item, key);
+ return pb.NotEquals(item, key);
});
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*|*11*|*00*00*00*|*11*|*22*|*33*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup, 0);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
});
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
}
- Y_UNIT_TEST_LLVM(TestSingleGroup) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestSingleGroup) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
Y_UNUSED(item);
- return pb.NewDataLiteral<bool>(false);
+ return pb.NewDataLiteral<bool>(false);
});
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*01*00*00*00*01*02*03*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
TSwitchInput switchInput;
switchInput.Indicies.push_back(0);
switchInput.InputType = stream.GetStaticType();
- stream = pb.Switch(stream,
+ stream = pb.Switch(stream,
MakeArrayRef(&switchInput, 1),
[&](ui32 /*index*/, TRuntimeNode item1) {
return Group(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
Y_UNUSED(key);
- return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
+ return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
});
},
1,
- pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::String))
+ pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::String))
);
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithCutSubStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestGroupingWithCutSubStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = GroupKeys(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
});
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndCutSubStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndCutSubStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
auto stream = MakeStream(setup);
TSwitchInput switchInput;
switchInput.Indicies.push_back(0);
switchInput.InputType = stream.GetStaticType();
- stream = pb.Switch(stream,
+ stream = pb.Switch(stream,
+ MakeArrayRef(&switchInput, 1),
+ [&](ui32 /*index*/, TRuntimeNode item1) {
+ return GroupKeys(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
+ Y_UNUSED(key);
+ return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
+ });
+ },
+ 1,
+ pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::String))
+ );
+
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
+ }
+}
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 9u
+Y_UNIT_TEST_SUITE(TMiniKQLChopperFlowTest) {
+ Y_UNIT_TEST_LLVM(TestEmpty) {
+ TSetup<LLVM> setup;
+
+ const auto stream = GroupWithBomb(setup, MakeFlow(setup, 0U));
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGrouping) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingGetKeysFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ stream = GroupGetKeysFirst(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0:0|0:01|0:0|0:0|0:0123|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingKeyNotEquals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ return pb.NotEquals(item, key);
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*|*11*|*00*00*00*|*11*|*22*|*33*|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup, 0);
+ stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestSingleGroup) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ Y_UNUSED(item);
+ return pb.NewDataLiteral<bool>(false);
+ });
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*01*00*00*00*01*02*03*|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ TSwitchInput switchInput;
+ switchInput.Indicies.push_back(0);
+ switchInput.InputType = stream.GetStaticType();
+
+ stream = pb.Switch(stream,
+ MakeArrayRef(&switchInput, 1),
+ [&](ui32 /*index*/, TRuntimeNode item1) {
+ return Group(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
+ Y_UNUSED(key);
+ return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
+ });
+ },
+ 1,
+ pb.NewFlowType(pb.NewDataType(NUdf::EDataSlot::String))
+ );
+
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingWithCutSubStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+
+ stream = GroupKeys(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
+ Y_UNUSED(key);
+ return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
+ });
+
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndCutSubStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto stream = MakeFlow(setup);
+ TSwitchInput switchInput;
+ switchInput.Indicies.push_back(0);
+ switchInput.InputType = stream.GetStaticType();
+
+ stream = pb.Switch(stream,
MakeArrayRef(&switchInput, 1),
[&](ui32 /*index*/, TRuntimeNode item1) {
return GroupKeys(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
Y_UNUSED(key);
- return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
+ return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
});
},
1,
- pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::String))
+ pb.NewFlowType(pb.NewDataType(NUdf::EDataSlot::String))
);
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(setup, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 9u
-Y_UNIT_TEST_SUITE(TMiniKQLChopperFlowTest) {
- Y_UNIT_TEST_LLVM(TestEmpty) {
- TSetup<LLVM> setup;
-
- const auto stream = GroupWithBomb(setup, MakeFlow(setup, 0U));
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
- }
-
- Y_UNIT_TEST_LLVM(TestGrouping) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingGetKeysFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- stream = GroupGetKeysFirst(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0:0|0:01|0:0|0:0|0:0123|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingKeyNotEquals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- return pb.NotEquals(item, key);
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*|*11*|*00*00*00*|*11*|*22*|*33*|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup, 0);
- stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
- }
-
- Y_UNIT_TEST_LLVM(TestSingleGroup) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- Y_UNUSED(item);
- return pb.NewDataLiteral<bool>(false);
- });
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*01*00*00*00*01*02*03*|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- TSwitchInput switchInput;
- switchInput.Indicies.push_back(0);
- switchInput.InputType = stream.GetStaticType();
-
- stream = pb.Switch(stream,
- MakeArrayRef(&switchInput, 1),
- [&](ui32 /*index*/, TRuntimeNode item1) {
- return Group(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
- Y_UNUSED(key);
- return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
- });
- },
- 1,
- pb.NewFlowType(pb.NewDataType(NUdf::EDataSlot::String))
- );
-
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingWithCutSubStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
-
- stream = GroupKeys(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- Y_UNUSED(key);
- return pb.Equals(item, pb.NewDataLiteral<ui64>(0));
- });
-
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
- }
-
- Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndCutSubStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto stream = MakeFlow(setup);
- TSwitchInput switchInput;
- switchInput.Indicies.push_back(0);
- switchInput.InputType = stream.GetStaticType();
-
- stream = pb.Switch(stream,
- MakeArrayRef(&switchInput, 1),
- [&](ui32 /*index*/, TRuntimeNode item1) {
- return GroupKeys(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
- Y_UNUSED(key);
- return pb.Equals(item2, pb.NewDataLiteral<ui64>(0));
- });
- },
- 1,
- pb.NewFlowType(pb.NewDataType(NUdf::EDataSlot::String))
- );
-
- const auto pgm = StreamToString(setup, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
- }
-}
-#endif
+#endif
} // NMiniKQL
} // NKikimr
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_combine_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_combine_ut.cpp
index cc2df349c8..0a147c619d 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_combine_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_combine_ut.cpp
@@ -1,4 +1,4 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
@@ -6,22 +6,22 @@
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <cstring>
-#include <random>
-#include <ctime>
-#include <algorithm>
+#include <random>
+#include <ctime>
+#include <algorithm>
namespace NKikimr {
namespace NMiniKQL {
namespace {
-ui64 g_Yield = std::numeric_limits<ui64>::max();
+ui64 g_Yield = std::numeric_limits<ui64>::max();
ui64 g_TestStreamData[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2};
-ui64 g_TestYieldStreamData[] = {0, 1, 2, g_Yield, 0, g_Yield, 1, 2, 0, 1, 2, 0, g_Yield, 1, 2};
+ui64 g_TestYieldStreamData[] = {0, 1, 2, g_Yield, 0, g_Yield, 1, 2, 0, 1, 2, 0, g_Yield, 1, 2};
-template <bool WithYields>
-class TTestStreamWrapper: public TMutableComputationNode<TTestStreamWrapper<WithYields>> {
- typedef TMutableComputationNode<TTestStreamWrapper<WithYields>> TBaseComputation;
+template <bool WithYields>
+class TTestStreamWrapper: public TMutableComputationNode<TTestStreamWrapper<WithYields>> {
+ typedef TMutableComputationNode<TTestStreamWrapper<WithYields>> TBaseComputation;
public:
class TStreamValue : public TComputationValue<TStreamValue> {
public:
@@ -36,27 +36,27 @@ public:
private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- constexpr auto size = WithYields ? Y_ARRAY_SIZE(g_TestYieldStreamData) : Y_ARRAY_SIZE(g_TestStreamData);
- if (Index == size) {
+ constexpr auto size = WithYields ? Y_ARRAY_SIZE(g_TestYieldStreamData) : Y_ARRAY_SIZE(g_TestStreamData);
+ if (Index == size) {
return NUdf::EFetchStatus::Finish;
}
- const auto val = WithYields ? g_TestYieldStreamData[Index] : g_TestStreamData[Index];
- if (g_Yield == val) {
- ++Index;
- return NUdf::EFetchStatus::Yield;
- }
-
+ const auto val = WithYields ? g_TestYieldStreamData[Index] : g_TestStreamData[Index];
+ if (g_Yield == val) {
+ ++Index;
+ return NUdf::EFetchStatus::Yield;
+ }
+
NUdf::TUnboxedValue* items = nullptr;
- result = CompCtx.HolderFactory.CreateDirectArrayHolder(2, items);
- items[0] = NUdf::TUnboxedValuePod(val);
+ result = CompCtx.HolderFactory.CreateDirectArrayHolder(2, items);
+ items[0] = NUdf::TUnboxedValuePod(val);
if (((Index + 1) % Parent->PeakStep) == 0) {
- auto str = MakeStringNotFilled(64ul << 20);
+ auto str = MakeStringNotFilled(64ul << 20);
const auto& buf = str.AsStringRef();
memset(buf.Data(), ' ', buf.Size());
- items[1] = std::move(str);
+ items[1] = std::move(str);
} else {
- items[1] = NUdf::TUnboxedValuePod::Zero();
+ items[1] = NUdf::TUnboxedValuePod::Zero();
}
++Index;
@@ -65,7 +65,7 @@ public:
private:
TComputationContext& CompCtx;
- const TTestStreamWrapper* const Parent;
+ const TTestStreamWrapper* const Parent;
ui64 Index = 0;
};
@@ -75,23 +75,23 @@ public:
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
return ctx.HolderFactory.Create<TStreamValue>(ctx, this);
}
private:
- void RegisterDependencies() const final {
+ void RegisterDependencies() const final {
}
private:
const ui64 PeakStep;
};
-template <bool WithYields>
+template <bool WithYields>
IComputationNode* WrapTestStream(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
const ui64 peakStep = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().Get<ui64>();
- return new TTestStreamWrapper<WithYields>(ctx.Mutables, peakStep);
+ return new TTestStreamWrapper<WithYields>(ctx.Mutables, peakStep);
}
TIntrusivePtr<IRandomProvider> CreateRandomProvider() {
@@ -104,22 +104,22 @@ TIntrusivePtr<ITimeProvider> CreateTimeProvider() {
TComputationNodeFactory GetTestFactory() {
return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
- if (callable.GetType()->GetName() == "TestList") {
- return new TExternalComputationNode(ctx.Mutables);
- }
+ if (callable.GetType()->GetName() == "TestList") {
+ return new TExternalComputationNode(ctx.Mutables);
+ }
if (callable.GetType()->GetName() == "TestStream") {
- return WrapTestStream<false>(callable, ctx);
+ return WrapTestStream<false>(callable, ctx);
+ }
+ if (callable.GetType()->GetName() == "TestYieldStream") {
+ return WrapTestStream<true>(callable, ctx);
}
- if (callable.GetType()->GetName() == "TestYieldStream") {
- return WrapTestStream<true>(callable, ctx);
- }
return GetBuiltinFactory()(callable, ctx);
};
}
-template<bool UseLLVM>
-struct TSetup_ {
- TSetup_() {
+template<bool UseLLVM>
+struct TSetup_ {
+ TSetup_() {
FunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
RandomProvider = CreateRandomProvider();
TimeProvider = CreateTimeProvider();
@@ -128,11 +128,11 @@ struct TSetup_ {
PgmBuilder.Reset(new TProgramBuilder(*Env, *FunctionRegistry));
}
- TAutoPtr<IComputationGraph> BuildGraph(TRuntimeNode pgm, EGraphPerProcess graphPerProcess = EGraphPerProcess::Multi, const std::vector<TNode*>& entryPoints = std::vector<TNode*>()) {
+ TAutoPtr<IComputationGraph> BuildGraph(TRuntimeNode pgm, EGraphPerProcess graphPerProcess = EGraphPerProcess::Multi, const std::vector<TNode*>& entryPoints = std::vector<TNode*>()) {
Explorer.Walk(pgm.GetNode(), *Env);
TComputationPatternOpts opts(Alloc.Ref(), *Env, GetTestFactory(), FunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, UseLLVM ? "" : "OFF", graphPerProcess);
- Pattern = MakeComputationPattern(Explorer, pgm, entryPoints, opts);
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, UseLLVM ? "" : "OFF", graphPerProcess);
+ Pattern = MakeComputationPattern(Explorer, pgm, entryPoints, opts);
return Pattern->Clone(opts.ToComputationOptions(*RandomProvider, *TimeProvider));
}
@@ -148,880 +148,880 @@ struct TSetup_ {
IComputationPattern::TPtr Pattern;
};
-template <bool LLVM, bool WithYields = false>
-TRuntimeNode MakeStream(TSetup_<LLVM>& setup, ui64 peakStep) {
- TProgramBuilder& pb = *setup.PgmBuilder;
+template <bool LLVM, bool WithYields = false>
+TRuntimeNode MakeStream(TSetup_<LLVM>& setup, ui64 peakStep) {
+ TProgramBuilder& pb = *setup.PgmBuilder;
- TCallableBuilder callableBuilder(*setup.Env, WithYields ? "TestYieldStream" : "TestStream",
- pb.NewStreamType(
- pb.NewStructType({
+ TCallableBuilder callableBuilder(*setup.Env, WithYields ? "TestYieldStream" : "TestStream",
+ pb.NewStreamType(
+ pb.NewStructType({
{TStringBuf("a"), pb.NewDataType(NUdf::EDataSlot::Uint64)},
{TStringBuf("b"), pb.NewDataType(NUdf::EDataSlot::String)}
})
)
);
- callableBuilder.Add(pb.NewDataLiteral(peakStep));
+ callableBuilder.Add(pb.NewDataLiteral(peakStep));
return TRuntimeNode(callableBuilder.Build(), false);
}
-template <bool OverFlow>
-TRuntimeNode Combine(TProgramBuilder& pb, TRuntimeNode stream, std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)> finishLambda) {
- const auto keyExtractor = [&](TRuntimeNode item) {
- return pb.Member(item, "a");
+template <bool OverFlow>
+TRuntimeNode Combine(TProgramBuilder& pb, TRuntimeNode stream, std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)> finishLambda) {
+ const auto keyExtractor = [&](TRuntimeNode item) {
+ return pb.Member(item, "a");
};
- const auto init = [&](TRuntimeNode /*key*/, TRuntimeNode item) {
+ const auto init = [&](TRuntimeNode /*key*/, TRuntimeNode item) {
return item;
};
- const auto update = [&](TRuntimeNode /*key*/, TRuntimeNode item, TRuntimeNode state) {
- const auto a = pb.Add(pb.Member(item, "a"), pb.Member(state, "a"));
- const auto b = pb.Concat(pb.Member(item, "b"), pb.Member(state, "b"));
- return pb.NewStruct({
+ const auto update = [&](TRuntimeNode /*key*/, TRuntimeNode item, TRuntimeNode state) {
+ const auto a = pb.Add(pb.Member(item, "a"), pb.Member(state, "a"));
+ const auto b = pb.Concat(pb.Member(item, "b"), pb.Member(state, "b"));
+ return pb.NewStruct({
{TStringBuf("a"), a},
{TStringBuf("b"), b},
});
};
- return OverFlow ?
- pb.FromFlow(pb.CombineCore(pb.ToFlow(stream), keyExtractor, init, update, finishLambda, 64ul << 20)):
- pb.CombineCore(stream, keyExtractor, init, update, finishLambda, 64ul << 20);
+ return OverFlow ?
+ pb.FromFlow(pb.CombineCore(pb.ToFlow(stream), keyExtractor, init, update, finishLambda, 64ul << 20)):
+ pb.CombineCore(stream, keyExtractor, init, update, finishLambda, 64ul << 20);
}
-TRuntimeNode Reduce(TProgramBuilder& pb, TRuntimeNode stream) {
- return pb.Condense(stream, pb.NewDataLiteral<ui64>(0),
- [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
- [&] (TRuntimeNode item, TRuntimeNode state) { return pb.Add(state, item); }
- );
+TRuntimeNode Reduce(TProgramBuilder& pb, TRuntimeNode stream) {
+ return pb.Condense(stream, pb.NewDataLiteral<ui64>(0),
+ [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
+ [&] (TRuntimeNode item, TRuntimeNode state) { return pb.Add(state, item); }
+ );
}
-TRuntimeNode StreamToString(TProgramBuilder& pb, TRuntimeNode stream) {
- const auto sorted = pb.Sort(stream, pb.NewDataLiteral(true),
+TRuntimeNode StreamToString(TProgramBuilder& pb, TRuntimeNode stream) {
+ const auto sorted = pb.Sort(stream, pb.NewDataLiteral(true),
[&](TRuntimeNode item) {
return item;
});
- return pb.Condense(sorted, pb.NewDataLiteral<NUdf::EDataSlot::String>("|"),
- [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
- [&] (TRuntimeNode item, TRuntimeNode state) {
- return pb.Concat(pb.Concat(state, pb.ToString(item)), pb.NewDataLiteral<NUdf::EDataSlot::String>("|"));
- }
- );
+ return pb.Condense(sorted, pb.NewDataLiteral<NUdf::EDataSlot::String>("|"),
+ [&] (TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral<bool>(false); },
+ [&] (TRuntimeNode item, TRuntimeNode state) {
+ return pb.Concat(pb.Concat(state, pb.ToString(item)), pb.NewDataLiteral<NUdf::EDataSlot::String>("|"));
+ }
+ );
}
} // unnamed
-Y_UNIT_TEST_SUITE(TMiniKQLCombineStreamTest) {
- Y_UNIT_TEST_LLVM(TestFullCombineWithOptOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|4|8|");
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithListOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return list;
- };
-
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithStreamOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return pb.Iterator(list, MakeArrayRef(&state, 1));
- };
-
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithOptOutAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|1|1|2|2|2|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithListAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return list;
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithStreamAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return pb.Iterator(list, MakeArrayRef(&state, 1));
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestPartialFlush) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- const auto stream = MakeStream(setup, 6ul);
- const auto combine = Combine<false>(pb, stream, finish);
- {
- const auto pgm = Reduce(pb, combine);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
- }
- {
- const auto pgm = StreamToString(pb, combine);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|2|2|4|4|");
- }
- }
-
- Y_UNIT_TEST_LLVM(TestCombineInSingleProc) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- const auto stream = MakeStream(setup, 6ul);
- const auto pgm = Reduce(pb, Combine<false>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm, EGraphPerProcess::Single);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
- }
-
- Y_UNIT_TEST_LLVM(TestCombineSwithYield) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- auto stream = MakeStream(setup, Max<ui64>());
- TSwitchInput switchInput;
- switchInput.Indicies.push_back(0);
- switchInput.InputType = stream.GetStaticType();
-
- stream = pb.Switch(stream,
- MakeArrayRef(&switchInput, 1),
- [&](ui32 /*index*/, TRuntimeNode item) { return Combine<false>(pb, item, finish); },
- 1,
- pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::Uint64))
- );
-
- const auto pgm = StreamToString(pb, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
-
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|1|1|1|1|2|2|2|2|");
- }
-}
-
-Y_UNIT_TEST_SUITE(TMiniKQLCombineStreamPerfTest) {
- Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
- TSetup_<LLVM> setup;
-
- double positive = 0.0, negative = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- (sample.second > 0.0 ? positive : negative) += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
- [&](TRuntimeNode, TRuntimeNode item) { return item; },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); },
- [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
- 0ULL
- );
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- NUdf::TUnboxedValue first, second;
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
- const auto t2 = TInstant::Now();
-
- if (first.template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
- TSetup_<LLVM> setup;
-
- double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- if (sample.second > 0.0) {
- pSum += sample.second;
- pMax = std::max(pMax, sample.second);
- pMin = std::min(pMin, sample.second);
- } else {
- nSum += sample.second;
- nMax = std::max(nMax, sample.second);
- nMin = std::min(nMin, sample.second);
- }
- }
-
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.AggrMin(pb.Nth(state, 1U), item), pb.AggrMax(pb.Nth(state, 2U), item) }); },
- [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
- 0ULL
- );
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- NUdf::TUnboxedValue first, second;
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
- const auto t2 = TInstant::Now();
-
- if (first.GetElement(0).template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
- TSetup_<LLVM> setup;
-
- std::unordered_map<i8, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
- TSetup_<LLVM> setup;
-
- std::unordered_map<i8, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::pair<ui32, std::string>, double>> pairI8Samples(Ui16Samples.size());
- std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairI8Samples.begin(), [](std::pair<ui32, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
-
- struct TPairHash { size_t operator()(const std::pair<ui16, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (const auto sample : pairI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairI8Samples.size(), items));
- for (const auto sample : pairI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- NUdf::TUnboxedValue* keys = nullptr;
- pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
- keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
- keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 3u
-Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowTest) {
- Y_UNIT_TEST_LLVM(TestFullCombineWithOptOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
+Y_UNIT_TEST_SUITE(TMiniKQLCombineStreamTest) {
+ Y_UNIT_TEST_LLVM(TestFullCombineWithOptOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|4|8|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithListOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return list;
+ };
+
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithStreamOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return pb.Iterator(list, MakeArrayRef(&state, 1));
+ };
+
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithOptOutAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|1|1|2|2|2|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithListAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return list;
+ };
+
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithStreamAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return pb.Iterator(list, MakeArrayRef(&state, 1));
+ };
+
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestPartialFlush) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream(setup, 6ul);
+ const auto combine = Combine<false>(pb, stream, finish);
+ {
+ const auto pgm = Reduce(pb, combine);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
+ }
+ {
+ const auto pgm = StreamToString(pb, combine);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|2|2|4|4|");
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestCombineInSingleProc) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream(setup, 6ul);
+ const auto pgm = Reduce(pb, Combine<false>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm, EGraphPerProcess::Single);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
+ }
+
+ Y_UNIT_TEST_LLVM(TestCombineSwithYield) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ auto stream = MakeStream(setup, Max<ui64>());
+ TSwitchInput switchInput;
+ switchInput.Indicies.push_back(0);
+ switchInput.InputType = stream.GetStaticType();
+
+ stream = pb.Switch(stream,
+ MakeArrayRef(&switchInput, 1),
+ [&](ui32 /*index*/, TRuntimeNode item) { return Combine<false>(pb, item, finish); },
+ 1,
+ pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::Uint64))
+ );
+
+ const auto pgm = StreamToString(pb, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|1|1|1|1|2|2|2|2|");
+ }
+}
+
+Y_UNIT_TEST_SUITE(TMiniKQLCombineStreamPerfTest) {
+ Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
+ TSetup_<LLVM> setup;
+
+ double positive = 0.0, negative = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ (sample.second > 0.0 ? positive : negative) += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
+ [&](TRuntimeNode, TRuntimeNode item) { return item; },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); },
+ [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
+ 0ULL
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ NUdf::TUnboxedValue first, second;
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
+ const auto t2 = TInstant::Now();
+
+ if (first.template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
+ TSetup_<LLVM> setup;
+
+ double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ if (sample.second > 0.0) {
+ pSum += sample.second;
+ pMax = std::max(pMax, sample.second);
+ pMin = std::min(pMin, sample.second);
+ } else {
+ nSum += sample.second;
+ nMax = std::max(nMax, sample.second);
+ nMin = std::min(nMin, sample.second);
+ }
+ }
+
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.AggrMin(pb.Nth(state, 1U), item), pb.AggrMax(pb.Nth(state, 2U), item) }); },
+ [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
+ 0ULL
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ NUdf::TUnboxedValue first, second;
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
+ const auto t2 = TInstant::Now();
+
+ if (first.GetElement(0).template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
+ TSetup_<LLVM> setup;
+
+ std::unordered_map<i8, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
+ TSetup_<LLVM> setup;
+
+ std::unordered_map<i8, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, double>> pairI8Samples(Ui16Samples.size());
+ std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairI8Samples.begin(), [](std::pair<ui32, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
+
+ struct TPairHash { size_t operator()(const std::pair<ui16, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (const auto sample : pairI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.Iterator(TRuntimeNode(list, false), {}),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairI8Samples.size(), items));
+ for (const auto sample : pairI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ NUdf::TUnboxedValue* keys = nullptr;
+ pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
+ keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
+ keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+}
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 3u
+Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowTest) {
+ Y_UNIT_TEST_LLVM(TestFullCombineWithOptOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
};
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|4|8|");
}
- Y_UNIT_TEST_LLVM(TestFullCombineWithListOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
+ Y_UNIT_TEST_LLVM(TestFullCombineWithListOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
return list;
};
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
}
- Y_UNIT_TEST_LLVM(TestFullCombineWithStreamOut) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return pb.Iterator(list, MakeArrayRef(&state, 1));
+ Y_UNIT_TEST_LLVM(TestFullCombineWithStreamOut) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return pb.Iterator(list, MakeArrayRef(&state, 1));
};
- const auto stream = MakeStream(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto stream = MakeStream(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|4|4|8|8|");
}
- Y_UNIT_TEST_LLVM(TestFullCombineWithOptOutAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|1|1|2|2|2|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithListAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return list;
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestFullCombineWithStreamAndYields) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- const auto item = pb.Member(state, "a");
- const auto itemType = item.GetStaticType();
- auto list = pb.NewEmptyList(itemType);
- list = pb.Append(list, item);
- list = pb.Append(list, item);
- return pb.Iterator(list, MakeArrayRef(&state, 1));
- };
-
- const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
- const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
- NUdf::TUnboxedValue result;
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
- UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestPartialFlush) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
+ Y_UNIT_TEST_LLVM(TestFullCombineWithOptOutAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|1|1|2|2|2|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithListAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return list;
};
- const auto stream = MakeStream(setup, 6ul);
- const auto combine = Combine<true>(pb, stream, finish);
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestFullCombineWithStreamAndYields) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ const auto item = pb.Member(state, "a");
+ const auto itemType = item.GetStaticType();
+ auto list = pb.NewEmptyList(itemType);
+ list = pb.Append(list, item);
+ list = pb.Append(list, item);
+ return pb.Iterator(list, MakeArrayRef(&state, 1));
+ };
+
+ const auto stream = MakeStream<LLVM, true>(setup, Max<ui64>());
+ const auto pgm = StreamToString(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
+ NUdf::TUnboxedValue result;
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Yield);
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|0|1|1|1|1|2|2|2|2|2|2|4|4|");
+ UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestPartialFlush) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
+ };
+
+ const auto stream = MakeStream(setup, 6ul);
+ const auto combine = Combine<true>(pb, stream, finish);
{
- const auto pgm = Reduce(pb, combine);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = Reduce(pb, combine);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
}
{
- const auto pgm = StreamToString(pb, combine);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(pb, combine);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|2|2|4|4|");
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|2|2|4|4|");
}
}
- Y_UNIT_TEST_LLVM(TestCombineInSingleProc) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
+ Y_UNIT_TEST_LLVM(TestCombineInSingleProc) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
};
- const auto stream = MakeStream(setup, 6ul);
- const auto pgm = Reduce(pb, Combine<true>(pb, stream, finish));
- const auto graph = setup.BuildGraph(pgm, EGraphPerProcess::Single);
- const auto streamVal = graph->GetValue();
+ const auto stream = MakeStream(setup, 6ul);
+ const auto pgm = Reduce(pb, Combine<true>(pb, stream, finish));
+ const auto graph = setup.BuildGraph(pgm, EGraphPerProcess::Single);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
UNIT_ASSERT_VALUES_EQUAL(result.Get<ui64>(), 12ul);
}
- Y_UNIT_TEST_LLVM(TestCombineSwithYield) {
- TSetup_<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
- return pb.NewOptional(pb.Member(state, "a"));
+ Y_UNIT_TEST_LLVM(TestCombineSwithYield) {
+ TSetup_<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto finish = [&](TRuntimeNode /*key*/, TRuntimeNode state) {
+ return pb.NewOptional(pb.Member(state, "a"));
};
auto stream = MakeStream(setup, Max<ui64>());
@@ -1029,546 +1029,546 @@ Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowTest) {
switchInput.Indicies.push_back(0);
switchInput.InputType = stream.GetStaticType();
- stream = pb.Switch(stream,
+ stream = pb.Switch(stream,
MakeArrayRef(&switchInput, 1),
- [&](ui32 /*index*/, TRuntimeNode item) { return Combine<true>(pb, item, finish); },
+ [&](ui32 /*index*/, TRuntimeNode item) { return Combine<true>(pb, item, finish); },
1,
- pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::Uint64))
+ pb.NewStreamType(pb.NewDataType(NUdf::EDataSlot::Uint64))
);
- const auto pgm = StreamToString(pb, stream);
- const auto graph = setup.BuildGraph(pgm);
- const auto streamVal = graph->GetValue();
+ const auto pgm = StreamToString(pb, stream);
+ const auto graph = setup.BuildGraph(pgm);
+ const auto streamVal = graph->GetValue();
NUdf::TUnboxedValue result;
UNIT_ASSERT_EQUAL(streamVal.Fetch(result), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|1|1|1|1|2|2|2|2|");
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|1|1|1|1|2|2|2|2|");
+ }
+}
+
+Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowPerfTest) {
+ Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
+ TSetup_<LLVM> setup;
+
+ double positive = 0.0, negative = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ (sample.second > 0.0 ? positive : negative) += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.FromFlow(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
+ [&](TRuntimeNode, TRuntimeNode item) { return item; },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); },
+ [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ NUdf::TUnboxedValue first, second;
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
+ const auto t2 = TInstant::Now();
+
+ if (first.template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
+ TSetup_<LLVM> setup;
+
+ double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ if (sample.second > 0.0) {
+ pSum += sample.second;
+ pMax = std::max(pMax, sample.second);
+ pMin = std::min(pMin, sample.second);
+ } else {
+ nSum += sample.second;
+ nMax = std::max(nMax, sample.second);
+ nMin = std::min(nMin, sample.second);
+ }
+ }
+
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.FromFlow(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.AggrMin(pb.Nth(state, 1U), item), pb.AggrMax(pb.Nth(state, 2U), item) }); },
+ [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ NUdf::TUnboxedValue first, second;
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
+ const auto t2 = TInstant::Now();
+
+ if (first.GetElement(0).template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
+ TSetup_<LLVM> setup;
+
+ std::unordered_map<i8, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
+ TSetup_<LLVM> setup;
+
+ std::unordered_map<i8, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
+ TSetup_<LLVM> setup;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, double>> pairI8Samples(Ui16Samples.size());
+ std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairI8Samples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
+
+ struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (const auto sample : pairI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
+ [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairI8Samples.size(), items));
+ for (const auto sample : pairI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ NUdf::TUnboxedValue* keys = nullptr;
+ pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
+ keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
+ keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ const auto border = 9124596000000000ULL;
+
+ Y_UNIT_TEST_LLVM(TestTpch) {
+ TSetup_<LLVM> setup;
+
+ struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (auto& sample : TpchSamples) {
+ if (std::get<0U>(sample) <= border) {
+ const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
+ auto& item = ins.first->second;
+ ++item.first;
+ std::get<0U>(item.second) += std::get<3U>(sample);
+ std::get<1U>(item.second) += std::get<5U>(sample);
+ std::get<2U>(item.second) += std::get<6U>(sample);
+ const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
+ std::get<3U>(item.second) += v;
+ std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
+ }
+ }
+ for (auto& item : expects) {
+ std::get<1U>(item.second.second) /= item.second.first;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui64>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id)
+ }));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.CombineCore(
+ pb.Map(pb.Filter(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrLessOrEqual(pb.Nth(item, 0U), pb.NewDataLiteral<ui64>(border)); }
+ ),
+ [&](TRuntimeNode item) { return pb.NewTuple({pb.Nth(item, 1U), pb.Nth(item, 2U),pb.Nth(item, 3U),pb.Nth(item, 4U),pb.Nth(item, 5U),pb.Nth(item, 6U)}); } ),
+ [&](TRuntimeNode item) { return pb.NewTuple({pb.Nth(item, 0U), pb.Nth(item, 1U)}); },
+ [&](TRuntimeNode, TRuntimeNode item) {
+ const auto price = pb.Nth(item, 2U);
+ const auto disco = pb.Nth(item, 4U);
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return pb.NewTuple({pb.NewDataLiteral<ui64>(1ULL), price, disco, pb.Nth(item, 5U), v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), pb.Nth(item, 3U))) });
+ },
+ [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) {
+ const auto price = pb.Nth(item, 2U);
+ const auto disco = pb.Nth(item, 4U);
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return pb.NewTuple({pb.Increment(pb.Nth(state, 0U)), pb.AggrAdd(pb.Nth(state, 1U), price), pb.AggrAdd(pb.Nth(state, 2U), disco), pb.AggrAdd(pb.Nth(state, 3U), pb.Nth(item, 5U)), pb.AggrAdd(pb.Nth(state, 4U), v), pb.AggrAdd(pb.Nth(state, 5U), pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), pb.Nth(item, 3U)))) });
+ },
+ [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({pb.Nth(key, 0U), pb.Nth(key, 1U), pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Div(pb.Nth(state, 2U), pb.Nth(state, 0U)), pb.Nth(state, 3U), pb.Nth(state, 4U), pb.Nth(state, 5U)})); },
+ 0ULL
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
+ for (const auto sample : TpchSamples) {
+ NUdf::TUnboxedValue* elements = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
+ elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
+ elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
+ elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
+ elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
+ elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
+ elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
+ elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
}
-}
-
-Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowPerfTest) {
- Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
- TSetup_<LLVM> setup;
-
- double positive = 0.0, negative = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- (sample.second > 0.0 ? positive : negative) += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.FromFlow(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
- [&](TRuntimeNode, TRuntimeNode item) { return item; },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); },
- [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- NUdf::TUnboxedValue first, second;
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
- const auto t2 = TInstant::Now();
-
- if (first.template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
- TSetup_<LLVM> setup;
-
- double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- if (sample.second > 0.0) {
- pSum += sample.second;
- pMax = std::max(pMax, sample.second);
- pMin = std::min(pMin, sample.second);
- } else {
- nSum += sample.second;
- nMax = std::max(nMax, sample.second);
- nMin = std::min(nMin, sample.second);
- }
- }
-
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.FromFlow(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.AggrMin(pb.Nth(state, 1U), item), pb.AggrMax(pb.Nth(state, 2U), item) }); },
- [&](TRuntimeNode, TRuntimeNode state) { return pb.NewOptional(state); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- NUdf::TUnboxedValue first, second;
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- UNIT_ASSERT_EQUAL(value.Fetch(first), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_EQUAL(value.Fetch(second), NUdf::EFetchStatus::Ok);
- const auto t2 = TInstant::Now();
-
- if (first.GetElement(0).template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
- TSetup_<LLVM> setup;
-
- std::unordered_map<i8, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
- TSetup_<LLVM> setup;
-
- std::unordered_map<i8, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { return pb.Nth(item, 1U); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Nth(item, 1U)); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, state})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
- TSetup_<LLVM> setup;
-
- std::vector<std::pair<std::pair<ui32, std::string>, double>> pairI8Samples(Ui16Samples.size());
- std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairI8Samples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
-
- struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (const auto sample : pairI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.Nth(item, 0U); },
- [&](TRuntimeNode, TRuntimeNode item) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({v, v, v}); },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) { const auto v = pb.Nth(item, 1U); return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), v), pb.AggrMin(pb.Nth(state, 1U), v), pb.AggrMax(pb.Nth(state, 2U), v)}); },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({key, pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Nth(state, 2U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairI8Samples.size(), items));
- for (const auto sample : pairI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- NUdf::TUnboxedValue* keys = nullptr;
- pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
- keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
- keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- const auto border = 9124596000000000ULL;
-
- Y_UNIT_TEST_LLVM(TestTpch) {
- TSetup_<LLVM> setup;
-
- struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (auto& sample : TpchSamples) {
- if (std::get<0U>(sample) <= border) {
- const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
- auto& item = ins.first->second;
- ++item.first;
- std::get<0U>(item.second) += std::get<3U>(sample);
- std::get<1U>(item.second) += std::get<5U>(sample);
- std::get<2U>(item.second) += std::get<6U>(sample);
- const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
- std::get<3U>(item.second) += v;
- std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
- }
- }
- for (auto& item : expects) {
- std::get<1U>(item.second.second) /= item.second.first;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui64>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id)
- }));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.CombineCore(
- pb.Map(pb.Filter(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrLessOrEqual(pb.Nth(item, 0U), pb.NewDataLiteral<ui64>(border)); }
- ),
- [&](TRuntimeNode item) { return pb.NewTuple({pb.Nth(item, 1U), pb.Nth(item, 2U),pb.Nth(item, 3U),pb.Nth(item, 4U),pb.Nth(item, 5U),pb.Nth(item, 6U)}); } ),
- [&](TRuntimeNode item) { return pb.NewTuple({pb.Nth(item, 0U), pb.Nth(item, 1U)}); },
- [&](TRuntimeNode, TRuntimeNode item) {
- const auto price = pb.Nth(item, 2U);
- const auto disco = pb.Nth(item, 4U);
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return pb.NewTuple({pb.NewDataLiteral<ui64>(1ULL), price, disco, pb.Nth(item, 5U), v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), pb.Nth(item, 3U))) });
- },
- [&](TRuntimeNode, TRuntimeNode item, TRuntimeNode state) {
- const auto price = pb.Nth(item, 2U);
- const auto disco = pb.Nth(item, 4U);
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return pb.NewTuple({pb.Increment(pb.Nth(state, 0U)), pb.AggrAdd(pb.Nth(state, 1U), price), pb.AggrAdd(pb.Nth(state, 2U), disco), pb.AggrAdd(pb.Nth(state, 3U), pb.Nth(item, 5U)), pb.AggrAdd(pb.Nth(state, 4U), v), pb.AggrAdd(pb.Nth(state, 5U), pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), pb.Nth(item, 3U)))) });
- },
- [&](TRuntimeNode key, TRuntimeNode state) { return pb.NewOptional(pb.NewTuple({pb.Nth(key, 0U), pb.Nth(key, 1U), pb.Nth(state, 0U), pb.Nth(state, 1U), pb.Div(pb.Nth(state, 2U), pb.Nth(state, 0U)), pb.Nth(state, 3U), pb.Nth(state, 4U), pb.Nth(state, 5U)})); },
- 0ULL
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, EGraphPerProcess::Multi, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
- for (const auto sample : TpchSamples) {
- NUdf::TUnboxedValue* elements = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
- elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
- elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
- elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
- elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
- elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
- elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
- elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
}
-#endif
+#endif
} // NMiniKQL
} // NKikimr
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_compare_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_compare_ut.cpp
index 2f067c6eda..8f51d66bc0 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_compare_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_compare_ut.cpp
@@ -1,991 +1,991 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_printer.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_impl.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-#include <cfloat>
-#include <utility>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLCompareTest) {
- Y_UNIT_TEST_LLVM(SqlString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
- auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("010"));
- auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("020"));
-
- auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- auto optionalType = pb.NewOptionalType(dataType);
- auto pairType = pb.NewTupleType({optionalType, optionalType});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data0, data0}),
- pb.NewTuple({data0, data1}),
- pb.NewTuple({data0, data2}),
-
- pb.NewTuple({data1, data0}),
- pb.NewTuple({data1, data1}),
- pb.NewTuple({data1, data2}),
-
- pb.NewTuple({data2, data0}),
- pb.NewTuple({data2, data1}),
- pb.NewTuple({data2, data2})
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(AggrString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
- auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("010"));
- auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("020"));
-
- auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- auto optionalType = pb.NewOptionalType(dataType);
- auto pairType = pb.NewTupleType({optionalType, optionalType});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data0, data0}),
- pb.NewTuple({data0, data1}),
- pb.NewTuple({data0, data2}),
-
- pb.NewTuple({data1, data0}),
- pb.NewTuple({data1, data1}),
- pb.NewTuple({data1, data2}),
-
- pb.NewTuple({data2, data0}),
- pb.NewTuple({data2, data1}),
- pb.NewTuple({data2, data2})
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(SqlFloats) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<float>(-7.0f);
- auto data2 = pb.NewDataLiteral<float>(3.0f);
- auto data3 = pb.NewDataLiteral<float>(0.0f*HUGE_VALF);
- auto data4 = pb.NewDataLiteral<double>(-7.0);
- auto data5 = pb.NewDataLiteral<double>(3.0);
- auto data6 = pb.NewDataLiteral<double>(0.0*HUGE_VAL);
-
- auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<float>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data4}),
- pb.NewTuple({data1, data5}),
- pb.NewTuple({data1, data6}),
-
- pb.NewTuple({data2, data4}),
- pb.NewTuple({data2, data5}),
- pb.NewTuple({data2, data6}),
-
- pb.NewTuple({data3, data4}),
- pb.NewTuple({data3, data5}),
- pb.NewTuple({data3, data6}),
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(AggrFloats) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<float>(-7.0f);
- auto data2 = pb.NewDataLiteral<float>(3.0f);
- auto data3 = pb.NewDataLiteral<float>(0.0f*HUGE_VALF);
-
- auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<float>::Id), pb.NewDataType(NUdf::TDataType<float>::Id)});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data1}),
- pb.NewTuple({data1, data2}),
- pb.NewTuple({data1, data3}),
-
- pb.NewTuple({data2, data1}),
- pb.NewTuple({data2, data2}),
- pb.NewTuple({data2, data3}),
-
- pb.NewTuple({data3, data1}),
- pb.NewTuple({data3, data2}),
- pb.NewTuple({data3, data3}),
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(SqlSigned) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<i16>(-1);
- auto data2 = pb.NewDataLiteral<i16>(+1);
- auto data3 = pb.NewDataLiteral<i32>(-1);
- auto data4 = pb.NewDataLiteral<i32>(+1);
-
- auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i16>::Id), pb.NewDataType(NUdf::TDataType<i32>::Id)});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data3}),
- pb.NewTuple({data1, data4}),
-
- pb.NewTuple({data2, data3}),
- pb.NewTuple({data2, data4})
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(SqlSignedAndUnsigned) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<i8>(-1);
- auto data2 = pb.NewDataLiteral<i8>(127);
- auto data3 = pb.NewDataLiteral<ui8>(0xFF);
- auto data4 = pb.NewDataLiteral<ui8>(127);
-
- auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<ui8>::Id)});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data3}),
- pb.NewTuple({data1, data4}),
-
- pb.NewTuple({data2, data3}),
- pb.NewTuple({data2, data4})
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(SqlUnsignedAndSigned) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<ui16>(0);
- auto data2 = pb.NewDataLiteral<ui16>(0xFFFF);
- auto data3 = pb.NewDataLiteral<i64>(-1);
- auto data4 = pb.NewDataLiteral<i64>(0xFFFF);
-
- auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui16>::Id), pb.NewDataType(NUdf::TDataType<i64>::Id)});
- auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data3}),
- pb.NewTuple({data1, data4}),
-
- pb.NewTuple({data2, data3}),
- pb.NewTuple({data2, data4})
- });
-
- auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(SimpleSqlString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto opt1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- auto opt2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- auto optEmpty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
- auto pgmReturn = pb.NewEmptyList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)));
-
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmpty, optEmpty));
-
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmpty, optEmpty));
-
- pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Less(opt2, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.Less(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Less(optEmpty, optEmpty));
-
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt2, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(optEmpty, optEmpty));
-
- pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Greater(opt2, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.Greater(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.Greater(optEmpty, optEmpty));
-
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt2, opt1));
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, optEmpty));
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(optEmpty, opt2));
- pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(optEmpty, optEmpty));
-
- auto opt1s = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("A"));
- auto opt2s = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"));
- auto optEmptys = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
-
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, opt1s));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, opt2s));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, optEmptys));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmptys, opt2s));
- pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmptys, optEmptys));
-
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, opt1s));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, opt2s));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, optEmptys));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmptys, opt2s));
- pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmptys, optEmptys));
+#include <cfloat>
+#include <utility>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLCompareTest) {
+ Y_UNIT_TEST_LLVM(SqlString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
+ auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("010"));
+ auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("020"));
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ auto optionalType = pb.NewOptionalType(dataType);
+ auto pairType = pb.NewTupleType({optionalType, optionalType});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data0, data0}),
+ pb.NewTuple({data0, data1}),
+ pb.NewTuple({data0, data2}),
+
+ pb.NewTuple({data1, data0}),
+ pb.NewTuple({data1, data1}),
+ pb.NewTuple({data1, data2}),
+
+ pb.NewTuple({data2, data0}),
+ pb.NewTuple({data2, data1}),
+ pb.NewTuple({data2, data2})
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(AggrString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
+ auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("010"));
+ auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("020"));
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ auto optionalType = pb.NewOptionalType(dataType);
+ auto pairType = pb.NewTupleType({optionalType, optionalType});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data0, data0}),
+ pb.NewTuple({data0, data1}),
+ pb.NewTuple({data0, data2}),
+
+ pb.NewTuple({data1, data0}),
+ pb.NewTuple({data1, data1}),
+ pb.NewTuple({data1, data2}),
+
+ pb.NewTuple({data2, data0}),
+ pb.NewTuple({data2, data1}),
+ pb.NewTuple({data2, data2})
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
auto graph = setup.BuildGraph(pgmReturn);
auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(SqlFloats) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<float>(-7.0f);
+ auto data2 = pb.NewDataLiteral<float>(3.0f);
+ auto data3 = pb.NewDataLiteral<float>(0.0f*HUGE_VALF);
+ auto data4 = pb.NewDataLiteral<double>(-7.0);
+ auto data5 = pb.NewDataLiteral<double>(3.0);
+ auto data6 = pb.NewDataLiteral<double>(0.0*HUGE_VAL);
+
+ auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<float>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data4}),
+ pb.NewTuple({data1, data5}),
+ pb.NewTuple({data1, data6}),
+
+ pb.NewTuple({data2, data4}),
+ pb.NewTuple({data2, data5}),
+ pb.NewTuple({data2, data6}),
+
+ pb.NewTuple({data3, data4}),
+ pb.NewTuple({data3, data5}),
+ pb.NewTuple({data3, data6}),
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(AggrFloats) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<float>(-7.0f);
+ auto data2 = pb.NewDataLiteral<float>(3.0f);
+ auto data3 = pb.NewDataLiteral<float>(0.0f*HUGE_VALF);
+
+ auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<float>::Id), pb.NewDataType(NUdf::TDataType<float>::Id)});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data1}),
+ pb.NewTuple({data1, data2}),
+ pb.NewTuple({data1, data3}),
+
+ pb.NewTuple({data2, data1}),
+ pb.NewTuple({data2, data2}),
+ pb.NewTuple({data2, data3}),
+
+ pb.NewTuple({data3, data1}),
+ pb.NewTuple({data3, data2}),
+ pb.NewTuple({data3, data3}),
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(SqlSigned) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<i16>(-1);
+ auto data2 = pb.NewDataLiteral<i16>(+1);
+ auto data3 = pb.NewDataLiteral<i32>(-1);
+ auto data4 = pb.NewDataLiteral<i32>(+1);
+
+ auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i16>::Id), pb.NewDataType(NUdf::TDataType<i32>::Id)});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data3}),
+ pb.NewTuple({data1, data4}),
+
+ pb.NewTuple({data2, data3}),
+ pb.NewTuple({data2, data4})
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(SqlSignedAndUnsigned) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<i8>(-1);
+ auto data2 = pb.NewDataLiteral<i8>(127);
+ auto data3 = pb.NewDataLiteral<ui8>(0xFF);
+ auto data4 = pb.NewDataLiteral<ui8>(127);
+
+ auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<ui8>::Id)});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data3}),
+ pb.NewTuple({data1, data4}),
+
+ pb.NewTuple({data2, data3}),
+ pb.NewTuple({data2, data4})
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(SqlUnsignedAndSigned) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<ui16>(0);
+ auto data2 = pb.NewDataLiteral<ui16>(0xFFFF);
+ auto data3 = pb.NewDataLiteral<i64>(-1);
+ auto data4 = pb.NewDataLiteral<i64>(0xFFFF);
+
+ auto pairType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui16>::Id), pb.NewDataType(NUdf::TDataType<i64>::Id)});
+ auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data3}),
+ pb.NewTuple({data1, data4}),
+
+ pb.NewTuple({data2, data3}),
+ pb.NewTuple({data2, data4})
+ });
+
+ auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(SimpleSqlString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto opt1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ auto opt2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ auto optEmpty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
+ auto pgmReturn = pb.NewEmptyList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)));
+
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmpty, optEmpty));
+
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmpty, optEmpty));
+
+ pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Less(opt2, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.Less(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.Less(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Less(optEmpty, optEmpty));
+
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt2, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.LessOrEqual(optEmpty, optEmpty));
+
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(opt2, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.Greater(optEmpty, optEmpty));
+
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt2, opt1));
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(opt1, optEmpty));
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(optEmpty, opt2));
+ pgmReturn = pb.Append(pgmReturn, pb.GreaterOrEqual(optEmpty, optEmpty));
+
+ auto opt1s = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("A"));
+ auto opt2s = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("B"));
+ auto optEmptys = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
+
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, opt1s));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, opt2s));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(opt1s, optEmptys));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmptys, opt2s));
+ pgmReturn = pb.Append(pgmReturn, pb.Equals(optEmptys, optEmptys));
+
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, opt1s));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, opt2s));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(opt1s, optEmptys));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmptys, opt2s));
+ pgmReturn = pb.Append(pgmReturn, pb.NotEquals(optEmptys, optEmptys));
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
// equals
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // not equals
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // not equals
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // less
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // less
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // less or equal
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // less or equal
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // greater
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // greater
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // greater or equal
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // greater or equal
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // equals - string
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // equals - string
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // not equals - string
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // not equals - string
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TzMin) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
+ const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
+
+ const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
+ const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
+
+ const auto zones = pb.ListFromRange(data1, data2, data1);
+ const auto dates = pb.ListFromRange(data3, data4, data3);
+
+ const auto source = pb.Map(pb.Zip({pb.Reverse(dates), zones}),
+ [&](TRuntimeNode item) {
+ return pb.AddTimezone(pb.ToIntegral(pb.Nth(item, 0U), pb.NewDataType(NUdf::EDataSlot::Datetime, true)), pb.Nth(item, 1U));
+ });
+
+ const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.Min(item, state); }
+ ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:01,Africa/Asmara");
}
-
- Y_UNIT_TEST_LLVM(TzMin) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
- const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
-
- const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
- const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
-
- const auto zones = pb.ListFromRange(data1, data2, data1);
- const auto dates = pb.ListFromRange(data3, data4, data3);
-
- const auto source = pb.Map(pb.Zip({pb.Reverse(dates), zones}),
- [&](TRuntimeNode item) {
- return pb.AddTimezone(pb.ToIntegral(pb.Nth(item, 0U), pb.NewDataType(NUdf::EDataSlot::Datetime, true)), pb.Nth(item, 1U));
- });
-
- const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.Min(item, state); }
- ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:01,Africa/Asmara");
- }
-
- Y_UNIT_TEST_LLVM(TzMax) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
- const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
-
- const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
- const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
-
- const auto zones = pb.ListFromRange(data1, data2, data1);
- const auto dates = pb.ListFromRange(data3, data4, data3);
-
- const auto source = pb.Map(pb.Zip({dates, pb.Reverse(zones)}),
- [&](TRuntimeNode item) {
- return pb.AddTimezone(pb.ToIntegral(pb.Nth(item, 0U), pb.NewDataType(NUdf::EDataSlot::Datetime, true)), pb.Nth(item, 1U));
- });
-
- const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.Max(item, state); }
- ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:06,Europe/Moscow");
- }
-
- Y_UNIT_TEST_LLVM(TzAggrMin) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
- const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
-
- const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
- const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
-
- const auto zones = pb.ListFromRange(data1, data2, data1);
- const auto dates = pb.ListFromRange(data3, data4, data3);
-
- const auto source = pb.FlatMap(zones,
- [&](TRuntimeNode zone) {
- return pb.Map(dates,
- [&](TRuntimeNode date) {
- return pb.AddTimezone(pb.ToIntegral(date, pb.NewDataType(NUdf::EDataSlot::Datetime, true)), zone);
- });
- });
-
- const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrMin(item, state); }
- ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:01,Europe/Moscow");
- }
-
- Y_UNIT_TEST_LLVM(TzAggrMax) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
- const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
-
- const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
- const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
-
- const auto zones = pb.ListFromRange(data1, data2, data1);
- const auto dates = pb.ListFromRange(data3, data4, data3);
-
- const auto source = pb.FlatMap(dates,
- [&](TRuntimeNode date) {
- return pb.Map(zones,
- [&](TRuntimeNode zone) {
- return pb.AddTimezone(pb.ToIntegral(date, pb.NewDataType(NUdf::EDataSlot::Datetime, true)), zone);
- });
- });
-
- const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrMax(item, state); }
- ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:06,Africa/Asmara");
- }
+
+ Y_UNIT_TEST_LLVM(TzMax) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
+ const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
+
+ const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
+ const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
+
+ const auto zones = pb.ListFromRange(data1, data2, data1);
+ const auto dates = pb.ListFromRange(data3, data4, data3);
+
+ const auto source = pb.Map(pb.Zip({dates, pb.Reverse(zones)}),
+ [&](TRuntimeNode item) {
+ return pb.AddTimezone(pb.ToIntegral(pb.Nth(item, 0U), pb.NewDataType(NUdf::EDataSlot::Datetime, true)), pb.Nth(item, 1U));
+ });
+
+ const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.Max(item, state); }
+ ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:06,Europe/Moscow");
+ }
+
+ Y_UNIT_TEST_LLVM(TzAggrMin) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
+ const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
+
+ const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
+ const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
+
+ const auto zones = pb.ListFromRange(data1, data2, data1);
+ const auto dates = pb.ListFromRange(data3, data4, data3);
+
+ const auto source = pb.FlatMap(zones,
+ [&](TRuntimeNode zone) {
+ return pb.Map(dates,
+ [&](TRuntimeNode date) {
+ return pb.AddTimezone(pb.ToIntegral(date, pb.NewDataType(NUdf::EDataSlot::Datetime, true)), zone);
+ });
+ });
+
+ const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrMin(item, state); }
+ ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:01,Europe/Moscow");
+ }
+
+ Y_UNIT_TEST_LLVM(TzAggrMax) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(1ULL);
+ const auto data2 = pb.NewDataLiteral<ui16>(7ULL);
+
+ const auto data3 = pb.NewDataLiteral<ui32>(1ULL);
+ const auto data4 = pb.NewDataLiteral<ui32>(7ULL);
+
+ const auto zones = pb.ListFromRange(data1, data2, data1);
+ const auto dates = pb.ListFromRange(data3, data4, data3);
+
+ const auto source = pb.FlatMap(dates,
+ [&](TRuntimeNode date) {
+ return pb.Map(zones,
+ [&](TRuntimeNode zone) {
+ return pb.AddTimezone(pb.ToIntegral(date, pb.NewDataType(NUdf::EDataSlot::Datetime, true)), zone);
+ });
+ });
+
+ const auto pgmReturn = pb.ToString(pb.Unwrap(pb.Fold1(source,
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrMax(item, state); }
+ ), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), __FILE__, __LINE__, 0));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(result, "1970-01-01T03:00:06,Africa/Asmara");
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.cpp
index a83b7f2331..19f82aae4e 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.cpp
@@ -1,2004 +1,2004 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_printer.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_impl.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-#include <cfloat>
-#include <utility>
-#include <random>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-
-ui64 g_Yield = std::numeric_limits<ui64>::max();
-ui64 g_TestStreamData[] = {0, 0, 1, 0, 0, 0, 1, 2, 3};
-ui64 g_TestYieldStreamData[] = {0, 1, 2, g_Yield, 0, g_Yield, 1, 2, 0, 1, 2, 0, g_Yield, 1, 2};
-
-class TTestStreamWrapper: public TMutableComputationNode<TTestStreamWrapper> {
- typedef TMutableComputationNode<TTestStreamWrapper> TBaseComputation;
-public:
- class TStreamValue : public TComputationValue<TStreamValue> {
- public:
- using TBase = TComputationValue<TStreamValue>;
-
- TStreamValue(TMemoryUsageInfo* memInfo, ui64 count)
- : TBase(memInfo)
- , Count(count)
- {
- }
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- if (Index == Count) {
- return NUdf::EFetchStatus::Finish;
- }
-
- result = NUdf::TUnboxedValuePod(g_TestStreamData[Index++]);
- return NUdf::EFetchStatus::Ok;
- }
-
- private:
- ui64 Index = 0;
- const ui64 Count;
- };
-
- TTestStreamWrapper(TComputationMutables& mutables, ui64 count)
- : TBaseComputation(mutables)
- , Count(Min<ui64>(count, Y_ARRAY_SIZE(g_TestStreamData)))
- {
- }
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TStreamValue>(Count);
- }
-
-private:
- void RegisterDependencies() const final {}
-
-private:
- const ui64 Count;
-};
-
-class TTestYieldStreamWrapper: public TMutableComputationNode<TTestYieldStreamWrapper> {
- typedef TMutableComputationNode<TTestYieldStreamWrapper> TBaseComputation;
-public:
- class TStreamValue : public TComputationValue<TStreamValue> {
- public:
- using TBase = TComputationValue<TStreamValue>;
-
- TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx)
- : TBase(memInfo)
- , CompCtx(compCtx) {}
-
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- if (Index == Y_ARRAY_SIZE(g_TestYieldStreamData)) {
- return NUdf::EFetchStatus::Finish;
- }
-
- const auto value = g_TestYieldStreamData[Index];
- if (value == g_Yield) {
- ++Index;
- return NUdf::EFetchStatus::Yield;
- }
-
- NUdf::TUnboxedValue* items = nullptr;
- result = CompCtx.HolderFactory.CreateDirectArrayHolder(2, items);
- items[0] = NUdf::TUnboxedValuePod(value);
- items[1] = MakeString(ToString(Index));
-
- ++Index;
- return NUdf::EFetchStatus::Ok;
- }
-
- private:
- TComputationContext& CompCtx;
- ui64 Index = 0;
- };
-
- TTestYieldStreamWrapper(TComputationMutables& mutables)
- : TBaseComputation(mutables) {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.Create<TStreamValue>(ctx);
- }
-
-private:
- void RegisterDependencies() const final {}
-};
-
-IComputationNode* WrapTestStream(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
- const ui64 count = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().Get<ui64>();
- return new TTestStreamWrapper(ctx.Mutables, count);
-}
-
-
-IComputationNode* WrapTestYieldStream(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args");
- return new TTestYieldStreamWrapper(ctx.Mutables);
-}
-
-constexpr auto TotalSambles =
-#ifndef NDEBUG
-333333U;
-#else
-33333333ULL;
-#endif
-
-}
-
-std::vector<std::pair<i8, double>> MakeSamples() {
- std::default_random_engine eng;
- std::uniform_int_distribution<i8> keys(-100, +100);
- std::uniform_real_distribution<double> unif(-999.0, +999.0);
-
- std::vector<std::pair<i8, double>> samples(TotalSambles);
-
- eng.seed(std::time(nullptr));
- std::generate(samples.begin(), samples.end(), std::bind(&std::make_pair<i8, double>, std::bind(std::move(keys), std::move(eng)), std::bind(std::move(unif), std::move(eng))));
- return samples;
-}
-
-std::vector<std::pair<ui16, double>> MakeOtherSamples() {
- std::default_random_engine eng;
- std::uniform_int_distribution<ui16> keys(0U, 65535U);
- std::uniform_real_distribution<double> unif(-999.0, +999.0);
-
- std::vector<std::pair<ui16, double>> samples(TotalSambles);
-
- eng.seed(std::time(nullptr));
- std::generate(samples.begin(), samples.end(), std::bind(&std::make_pair<ui16, double>, std::bind(std::move(keys), std::move(eng)), std::bind(std::move(unif), std::move(eng))));
- return samples;
-}
-
-std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> MakeTpchSamples() {
- std::default_random_engine eng;
- std::uniform_int_distribution<ui64> dates(694303200000000ULL, 9124596000000005ULL);
- std::uniform_int_distribution<ui8> keys(0U, 3U);
- std::uniform_real_distribution<double> prices(900., 105000.0);
- std::uniform_real_distribution<double> taxes(0., 0.08);
- std::uniform_real_distribution<double> discs(0., 0.1);
- std::uniform_real_distribution<double> qntts(1., 50.);
-
- std::random_device rd;
- std::mt19937 gen(rd());
-
- std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> samples(TotalSambles);
-
- eng.seed(std::time(nullptr));
-
- std::generate(samples.begin(), samples.end(), [&]() {
- switch(keys(gen)) {
- case 0U: return std::make_tuple(dates(gen), "N", "O", prices(gen), taxes(gen), discs(gen), qntts(gen));
- case 1U: return std::make_tuple(dates(gen), "A", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
- case 2U: return std::make_tuple(dates(gen), "N", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
- case 3U: return std::make_tuple(dates(gen), "R", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
- }
- Y_FAIL("Unexpected");
- });
- return samples;
-}
-
-extern const std::vector<std::pair<i8, double>> I8Samples = MakeSamples();
-extern const std::vector<std::pair<ui16, double>> Ui16Samples = MakeOtherSamples();
-extern const std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> TpchSamples = MakeTpchSamples();
-
-TComputationNodeFactory GetTestFactory() {
- return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
- if (callable.GetType()->GetName() == "TestList") {
- return new TExternalComputationNode(ctx.Mutables);
+#include <cfloat>
+#include <utility>
+#include <random>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+
+ui64 g_Yield = std::numeric_limits<ui64>::max();
+ui64 g_TestStreamData[] = {0, 0, 1, 0, 0, 0, 1, 2, 3};
+ui64 g_TestYieldStreamData[] = {0, 1, 2, g_Yield, 0, g_Yield, 1, 2, 0, 1, 2, 0, g_Yield, 1, 2};
+
+class TTestStreamWrapper: public TMutableComputationNode<TTestStreamWrapper> {
+ typedef TMutableComputationNode<TTestStreamWrapper> TBaseComputation;
+public:
+ class TStreamValue : public TComputationValue<TStreamValue> {
+ public:
+ using TBase = TComputationValue<TStreamValue>;
+
+ TStreamValue(TMemoryUsageInfo* memInfo, ui64 count)
+ : TBase(memInfo)
+ , Count(count)
+ {
}
- if (callable.GetType()->GetName() == "TestStream") {
- return WrapTestStream(callable, ctx);
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ if (Index == Count) {
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ result = NUdf::TUnboxedValuePod(g_TestStreamData[Index++]);
+ return NUdf::EFetchStatus::Ok;
}
- if (callable.GetType()->GetName() == "TestYieldStream") {
- return WrapTestYieldStream(callable, ctx);
- }
-
- return GetBuiltinFactory()(callable, ctx);
+ private:
+ ui64 Index = 0;
+ const ui64 Count;
+ };
+
+ TTestStreamWrapper(TComputationMutables& mutables, ui64 count)
+ : TBaseComputation(mutables)
+ , Count(Min<ui64>(count, Y_ARRAY_SIZE(g_TestStreamData)))
+ {
+ }
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TStreamValue>(Count);
+ }
+
+private:
+ void RegisterDependencies() const final {}
+
+private:
+ const ui64 Count;
+};
+
+class TTestYieldStreamWrapper: public TMutableComputationNode<TTestYieldStreamWrapper> {
+ typedef TMutableComputationNode<TTestYieldStreamWrapper> TBaseComputation;
+public:
+ class TStreamValue : public TComputationValue<TStreamValue> {
+ public:
+ using TBase = TComputationValue<TStreamValue>;
+
+ TStreamValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx)
+ : TBase(memInfo)
+ , CompCtx(compCtx) {}
+
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ if (Index == Y_ARRAY_SIZE(g_TestYieldStreamData)) {
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ const auto value = g_TestYieldStreamData[Index];
+ if (value == g_Yield) {
+ ++Index;
+ return NUdf::EFetchStatus::Yield;
+ }
+
+ NUdf::TUnboxedValue* items = nullptr;
+ result = CompCtx.HolderFactory.CreateDirectArrayHolder(2, items);
+ items[0] = NUdf::TUnboxedValuePod(value);
+ items[1] = MakeString(ToString(Index));
+
+ ++Index;
+ return NUdf::EFetchStatus::Ok;
+ }
+
+ private:
+ TComputationContext& CompCtx;
+ ui64 Index = 0;
+ };
+
+ TTestYieldStreamWrapper(TComputationMutables& mutables)
+ : TBaseComputation(mutables) {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.Create<TStreamValue>(ctx);
+ }
+
+private:
+ void RegisterDependencies() const final {}
+};
+
+IComputationNode* WrapTestStream(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 args");
+ const ui64 count = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().Get<ui64>();
+ return new TTestStreamWrapper(ctx.Mutables, count);
+}
+
+
+IComputationNode* WrapTestYieldStream(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
+ MKQL_ENSURE(!callable.GetInputsCount(), "Expected no args");
+ return new TTestYieldStreamWrapper(ctx.Mutables);
+}
+
+constexpr auto TotalSambles =
+#ifndef NDEBUG
+333333U;
+#else
+33333333ULL;
+#endif
+
+}
+
+std::vector<std::pair<i8, double>> MakeSamples() {
+ std::default_random_engine eng;
+ std::uniform_int_distribution<i8> keys(-100, +100);
+ std::uniform_real_distribution<double> unif(-999.0, +999.0);
+
+ std::vector<std::pair<i8, double>> samples(TotalSambles);
+
+ eng.seed(std::time(nullptr));
+ std::generate(samples.begin(), samples.end(), std::bind(&std::make_pair<i8, double>, std::bind(std::move(keys), std::move(eng)), std::bind(std::move(unif), std::move(eng))));
+ return samples;
+}
+
+std::vector<std::pair<ui16, double>> MakeOtherSamples() {
+ std::default_random_engine eng;
+ std::uniform_int_distribution<ui16> keys(0U, 65535U);
+ std::uniform_real_distribution<double> unif(-999.0, +999.0);
+
+ std::vector<std::pair<ui16, double>> samples(TotalSambles);
+
+ eng.seed(std::time(nullptr));
+ std::generate(samples.begin(), samples.end(), std::bind(&std::make_pair<ui16, double>, std::bind(std::move(keys), std::move(eng)), std::bind(std::move(unif), std::move(eng))));
+ return samples;
+}
+
+std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> MakeTpchSamples() {
+ std::default_random_engine eng;
+ std::uniform_int_distribution<ui64> dates(694303200000000ULL, 9124596000000005ULL);
+ std::uniform_int_distribution<ui8> keys(0U, 3U);
+ std::uniform_real_distribution<double> prices(900., 105000.0);
+ std::uniform_real_distribution<double> taxes(0., 0.08);
+ std::uniform_real_distribution<double> discs(0., 0.1);
+ std::uniform_real_distribution<double> qntts(1., 50.);
+
+ std::random_device rd;
+ std::mt19937 gen(rd());
+
+ std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> samples(TotalSambles);
+
+ eng.seed(std::time(nullptr));
+
+ std::generate(samples.begin(), samples.end(), [&]() {
+ switch(keys(gen)) {
+ case 0U: return std::make_tuple(dates(gen), "N", "O", prices(gen), taxes(gen), discs(gen), qntts(gen));
+ case 1U: return std::make_tuple(dates(gen), "A", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
+ case 2U: return std::make_tuple(dates(gen), "N", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
+ case 3U: return std::make_tuple(dates(gen), "R", "F", prices(gen), taxes(gen), discs(gen), qntts(gen));
+ }
+ Y_FAIL("Unexpected");
+ });
+ return samples;
+}
+
+extern const std::vector<std::pair<i8, double>> I8Samples = MakeSamples();
+extern const std::vector<std::pair<ui16, double>> Ui16Samples = MakeOtherSamples();
+extern const std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> TpchSamples = MakeTpchSamples();
+
+TComputationNodeFactory GetTestFactory() {
+ return [](TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
+ if (callable.GetType()->GetName() == "TestList") {
+ return new TExternalComputationNode(ctx.Mutables);
+ }
+
+ if (callable.GetType()->GetName() == "TestStream") {
+ return WrapTestStream(callable, ctx);
+ }
+
+ if (callable.GetType()->GetName() == "TestYieldStream") {
+ return WrapTestYieldStream(callable, ctx);
+ }
+
+ return GetBuiltinFactory()(callable, ctx);
};
}
Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
Y_UNIT_TEST_LLVM(TestEmbeddedByteAt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(3);
- const auto data2 = pb.NewDataLiteral<ui32>(9);
- const auto data3 = pb.NewDataLiteral<ui32>(13);
- const auto data4 = pb.NewDataLiteral<ui32>(Max<ui32>());
-
- const auto str = pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789AB");
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ByteAt(str, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(3);
+ const auto data2 = pb.NewDataLiteral<ui32>(9);
+ const auto data3 = pb.NewDataLiteral<ui32>(13);
+ const auto data4 = pb.NewDataLiteral<ui32>(Max<ui32>());
+
+ const auto str = pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789AB");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ByteAt(str, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x30);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x33);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x39);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestStringByteAt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(3);
- const auto data2 = pb.NewDataLiteral<ui32>(21);
- const auto data3 = pb.NewDataLiteral<ui32>(22);
- const auto data4 = pb.NewDataLiteral<ui32>(Max<ui32>());
-
- const auto str = pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789ABCDEFGHIJKL");
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ByteAt(str, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(3);
+ const auto data2 = pb.NewDataLiteral<ui32>(21);
+ const auto data3 = pb.NewDataLiteral<ui32>(22);
+ const auto data4 = pb.NewDataLiteral<ui32>(Max<ui32>());
+
+ const auto str = pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789ABCDEFGHIJKL");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ByteAt(str, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x30);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x33);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0x4C);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestCountBitsUI8) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui8>(0x00);
- const auto data1 = pb.NewDataLiteral<ui8>(0x01);
- const auto data2 = pb.NewDataLiteral<ui8>(0x10);
- const auto data3 = pb.NewDataLiteral<ui8>(0x13);
- const auto data4 = pb.NewDataLiteral<ui8>(0xF0);
- const auto data5 = pb.NewDataLiteral<ui8>(0x0F);
- const auto data6 = pb.NewDataLiteral<ui8>(0x55);
- const auto data7 = pb.NewDataLiteral<ui8>(0xAA);
- const auto data8 = pb.NewDataLiteral<ui8>(0x7F);
- const auto data9 = pb.NewDataLiteral<ui8>(0xFF);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.CountBits(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui8>(0x00);
+ const auto data1 = pb.NewDataLiteral<ui8>(0x01);
+ const auto data2 = pb.NewDataLiteral<ui8>(0x10);
+ const auto data3 = pb.NewDataLiteral<ui8>(0x13);
+ const auto data4 = pb.NewDataLiteral<ui8>(0xF0);
+ const auto data5 = pb.NewDataLiteral<ui8>(0x0F);
+ const auto data6 = pb.NewDataLiteral<ui8>(0x55);
+ const auto data7 = pb.NewDataLiteral<ui8>(0xAA);
+ const auto data8 = pb.NewDataLiteral<ui8>(0x7F);
+ const auto data9 = pb.NewDataLiteral<ui8>(0xFF);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.CountBits(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 7);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 8);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestCountBitsUI16) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui16>(0x0000);
- const auto data1 = pb.NewDataLiteral<ui16>(0x0100);
- const auto data2 = pb.NewDataLiteral<ui16>(0x0010);
- const auto data3 = pb.NewDataLiteral<ui16>(0x0130);
- const auto data4 = pb.NewDataLiteral<ui16>(0xF000);
- const auto data5 = pb.NewDataLiteral<ui16>(0x0F00);
- const auto data6 = pb.NewDataLiteral<ui16>(0x0550);
- const auto data7 = pb.NewDataLiteral<ui16>(0xA00A);
- const auto data8 = pb.NewDataLiteral<ui16>(0x700F);
- const auto data9 = pb.NewDataLiteral<ui16>(0x0FF0);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.CountBits(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui16>(0x0000);
+ const auto data1 = pb.NewDataLiteral<ui16>(0x0100);
+ const auto data2 = pb.NewDataLiteral<ui16>(0x0010);
+ const auto data3 = pb.NewDataLiteral<ui16>(0x0130);
+ const auto data4 = pb.NewDataLiteral<ui16>(0xF000);
+ const auto data5 = pb.NewDataLiteral<ui16>(0x0F00);
+ const auto data6 = pb.NewDataLiteral<ui16>(0x0550);
+ const auto data7 = pb.NewDataLiteral<ui16>(0xA00A);
+ const auto data8 = pb.NewDataLiteral<ui16>(0x700F);
+ const auto data9 = pb.NewDataLiteral<ui16>(0x0FF0);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.CountBits(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 7);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 8);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestShiftLeft) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(7);
- const auto data3 = pb.NewDataLiteral<ui8>(10);
- const auto data4 = pb.NewDataLiteral<ui8>(30);
- const auto data5 = pb.NewDataLiteral<ui8>(32);
- const auto data6 = pb.NewDataLiteral<ui8>(40);
- const auto data7 = pb.NewDataLiteral<ui8>(57);
- const auto data8 = pb.NewDataLiteral<ui8>(200);
- const auto data9 = pb.NewDataLiteral<ui8>(255);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ShiftLeft(pb.NewDataLiteral<ui32>(0x830500F1U), item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(7);
+ const auto data3 = pb.NewDataLiteral<ui8>(10);
+ const auto data4 = pb.NewDataLiteral<ui8>(30);
+ const auto data5 = pb.NewDataLiteral<ui8>(32);
+ const auto data6 = pb.NewDataLiteral<ui8>(40);
+ const auto data7 = pb.NewDataLiteral<ui8>(57);
+ const auto data8 = pb.NewDataLiteral<ui8>(200);
+ const auto data9 = pb.NewDataLiteral<ui8>(255);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ShiftLeft(pb.NewDataLiteral<ui32>(0x830500F1U), item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x830500F1U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x060A01E2U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x82807880U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x1403C400U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x40000000U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestShiftRight) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(7);
- const auto data3 = pb.NewDataLiteral<ui8>(10);
- const auto data4 = pb.NewDataLiteral<ui8>(30);
- const auto data5 = pb.NewDataLiteral<ui8>(32);
- const auto data6 = pb.NewDataLiteral<ui8>(40);
- const auto data7 = pb.NewDataLiteral<ui8>(57);
- const auto data8 = pb.NewDataLiteral<ui8>(200);
- const auto data9 = pb.NewDataLiteral<ui8>(255);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ShiftRight(pb.NewDataLiteral<ui32>(0x830500F1U), item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(7);
+ const auto data3 = pb.NewDataLiteral<ui8>(10);
+ const auto data4 = pb.NewDataLiteral<ui8>(30);
+ const auto data5 = pb.NewDataLiteral<ui8>(32);
+ const auto data6 = pb.NewDataLiteral<ui8>(40);
+ const auto data7 = pb.NewDataLiteral<ui8>(57);
+ const auto data8 = pb.NewDataLiteral<ui8>(200);
+ const auto data9 = pb.NewDataLiteral<ui8>(255);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ShiftRight(pb.NewDataLiteral<ui32>(0x830500F1U), item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x830500F1U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x41828078U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x01060A01U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x20C140U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0x2U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestRotLeft) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(7);
- const auto data3 = pb.NewDataLiteral<ui8>(10);
- const auto data4 = pb.NewDataLiteral<ui8>(30);
- const auto data5 = pb.NewDataLiteral<ui8>(32);
- const auto data6 = pb.NewDataLiteral<ui8>(40);
- const auto data7 = pb.NewDataLiteral<ui8>(57);
- const auto data8 = pb.NewDataLiteral<ui8>(200);
- const auto data9 = pb.NewDataLiteral<ui8>(255);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.RotLeft(pb.NewDataLiteral<ui16>(0x87F5U), item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(7);
+ const auto data3 = pb.NewDataLiteral<ui8>(10);
+ const auto data4 = pb.NewDataLiteral<ui8>(30);
+ const auto data5 = pb.NewDataLiteral<ui8>(32);
+ const auto data6 = pb.NewDataLiteral<ui8>(40);
+ const auto data7 = pb.NewDataLiteral<ui8>(57);
+ const auto data8 = pb.NewDataLiteral<ui8>(200);
+ const auto data9 = pb.NewDataLiteral<ui8>(255);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.RotLeft(pb.NewDataLiteral<ui16>(0x87F5U), item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x87F5U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x0FEBU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xFAC3U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xD61FU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x61FDU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x87F5U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xF587U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xEB0FU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xF587U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xC3FAU);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestRotRight) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(7);
- const auto data3 = pb.NewDataLiteral<ui8>(10);
- const auto data4 = pb.NewDataLiteral<ui8>(30);
- const auto data5 = pb.NewDataLiteral<ui8>(32);
- const auto data6 = pb.NewDataLiteral<ui8>(40);
- const auto data7 = pb.NewDataLiteral<ui8>(57);
- const auto data8 = pb.NewDataLiteral<ui8>(200);
- const auto data9 = pb.NewDataLiteral<ui8>(255);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.RotRight(pb.NewDataLiteral<ui16>(0x87F5U), item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(7);
+ const auto data3 = pb.NewDataLiteral<ui8>(10);
+ const auto data4 = pb.NewDataLiteral<ui8>(30);
+ const auto data5 = pb.NewDataLiteral<ui8>(32);
+ const auto data6 = pb.NewDataLiteral<ui8>(40);
+ const auto data7 = pb.NewDataLiteral<ui8>(57);
+ const auto data8 = pb.NewDataLiteral<ui8>(200);
+ const auto data9 = pb.NewDataLiteral<ui8>(255);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.RotRight(pb.NewDataLiteral<ui16>(0x87F5U), item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x87F5U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xC3FAU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xEB0FU);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xFD61U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x1FD6U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x87F5U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xF587U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xFAC3U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0xF587U);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0x0FEBU);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestConvertIntToBool) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<i64>(0);
- const auto data1 = pb.NewDataLiteral<i64>(1);
- const auto data2 = pb.NewDataLiteral<i64>(2);
- const auto data3 = pb.NewDataLiteral<i64>(1024);
- const auto data4 = pb.NewDataLiteral<i64>(-1);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<bool>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.template Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.template Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.template Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.template Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.template Get<bool>());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<i64>(0);
+ const auto data1 = pb.NewDataLiteral<i64>(1);
+ const auto data2 = pb.NewDataLiteral<i64>(2);
+ const auto data3 = pb.NewDataLiteral<i64>(1024);
+ const auto data4 = pb.NewDataLiteral<i64>(-1);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<bool>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.template Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.template Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.template Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.template Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.template Get<bool>());
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFloatAbs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto data1 = pb.NewDataLiteral<float>(11.433f);
- const auto data2 = pb.NewDataLiteral<float>(-3.14f);
- const auto data3 = pb.NewDataLiteral<float>(0.0f);
- const auto data4 = pb.NewDataLiteral<float>(-HUGE_VALF);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Abs(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto data1 = pb.NewDataLiteral<float>(11.433f);
+ const auto data2 = pb.NewDataLiteral<float>(-3.14f);
+ const auto data3 = pb.NewDataLiteral<float>(0.0f);
+ const auto data4 = pb.NewDataLiteral<float>(-HUGE_VALF);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Abs(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 11.433f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 3.14f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.0f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), HUGE_VALF);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestIntegerAbs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto data1 = pb.NewDataLiteral<i32>(1334);
- const auto data2 = pb.NewDataLiteral<i32>(-4378);
- const auto data3 = pb.NewDataLiteral<i32>(0);
- const auto data4 = pb.NewDataLiteral<i32>(std::numeric_limits<i32>::min());
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Abs(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto data1 = pb.NewDataLiteral<i32>(1334);
+ const auto data2 = pb.NewDataLiteral<i32>(-4378);
+ const auto data3 = pb.NewDataLiteral<i32>(0);
+ const auto data4 = pb.NewDataLiteral<i32>(std::numeric_limits<i32>::min());
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Abs(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1334);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 4378);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), std::numeric_limits<i32>::min());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestToIntegral) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto ten = pb.ToIntegral(pb.NewDataLiteral(float(10.0)), pb.NewDataType(NUdf::TDataType<i32>::Id, true));
- const auto two = pb.ToIntegral(pb.NewDataLiteral(float(2.0)), pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- const auto pgmReturn = pb.NewTuple({ten, two});
-
- const auto graph = setup.BuildGraph(pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto ten = pb.ToIntegral(pb.NewDataLiteral(float(10.0)), pb.NewDataType(NUdf::TDataType<i32>::Id, true));
+ const auto two = pb.ToIntegral(pb.NewDataLiteral(float(2.0)), pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ const auto pgmReturn = pb.NewTuple({ten, two});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(0).template Get<i32>(), 10);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(1).template Get<ui32>(), 2U);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestFloatToI16) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0f);
- const auto data1 = pb.NewDataLiteral(0.0f*HUGE_VALF);
- const auto data2 = pb.NewDataLiteral(-3.14f);
- const auto data3 = pb.NewDataLiteral(12121324.0f);
- const auto data4 = pb.NewDataLiteral(-7898.8f);
- const auto data5 = pb.NewDataLiteral(210000.0f);
- const auto data6 = pb.NewDataLiteral(HUGE_VALF);
- const auto data7 = pb.NewDataLiteral(-HUGE_VALF);
- const auto data8 = pb.NewDataLiteral(-HUGE_VALF);
- const auto data9 = pb.NewDataLiteral(FLT_MIN/2.0f);
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0f);
+ const auto data1 = pb.NewDataLiteral(0.0f*HUGE_VALF);
+ const auto data2 = pb.NewDataLiteral(-3.14f);
+ const auto data3 = pb.NewDataLiteral(12121324.0f);
+ const auto data4 = pb.NewDataLiteral(-7898.8f);
+ const auto data5 = pb.NewDataLiteral(210000.0f);
+ const auto data6 = pb.NewDataLiteral(HUGE_VALF);
+ const auto data7 = pb.NewDataLiteral(-HUGE_VALF);
+ const auto data8 = pb.NewDataLiteral(-HUGE_VALF);
+ const auto data9 = pb.NewDataLiteral(FLT_MIN/2.0f);
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), -7898);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestDoubleToBool) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(12121324.0);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto data5 = pb.NewDataLiteral(210000.0);
- const auto data6 = pb.NewDataLiteral(HUGE_VAL);
- const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
- const auto data8 = pb.NewDataLiteral(-HUGE_VAL);
- const auto data9 = pb.NewDataLiteral(DBL_MIN/2.0);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<bool>::Id, true));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(12121324.0);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto data5 = pb.NewDataLiteral(210000.0);
+ const auto data6 = pb.NewDataLiteral(HUGE_VAL);
+ const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
+ const auto data8 = pb.NewDataLiteral(-HUGE_VAL);
+ const auto data9 = pb.NewDataLiteral(DBL_MIN/2.0);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<bool>::Id, true));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestDoubleToUI32) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(12121324.0);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto data5 = pb.NewDataLiteral(210000.0);
- const auto data6 = pb.NewDataLiteral(HUGE_VAL);
- const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
- const auto data8 = pb.NewDataLiteral(-HUGE_VAL);
- const auto data9 = pb.NewDataLiteral(DBL_MIN/2.0);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(12121324.0);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto data5 = pb.NewDataLiteral(210000.0);
+ const auto data6 = pb.NewDataLiteral(HUGE_VAL);
+ const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
+ const auto data8 = pb.NewDataLiteral(-HUGE_VAL);
+ const auto data9 = pb.NewDataLiteral(DBL_MIN/2.0);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 12121324U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 210000U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestUI64ToIntegral) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto data0 = pb.NewDataLiteral<ui64>(0U);
- const auto data1 = pb.NewDataLiteral<ui64>(1U);
- const auto data2 = pb.NewDataLiteral<ui64>(std::numeric_limits<i8>::max());
- const auto data3 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui8>::max());
- const auto data4 = pb.NewDataLiteral<ui64>(std::numeric_limits<i16>::max());
- const auto data5 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui16>::max());
- const auto data6 = pb.NewDataLiteral<ui64>(std::numeric_limits<i32>::max());
- const auto data7 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui32>::max());
- const auto data8 = pb.NewDataLiteral<ui64>(std::numeric_limits<i64>::max());
- const auto data9 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui64>::max());
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i64>::Id, true)),
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 1);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i8>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<ui8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<ui8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<ui8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<ui8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui8>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i16>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<ui16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<ui16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui16>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i32>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i32>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui32>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui32>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i64>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestI64ToIntegral) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<i64>::Id);
- const auto data0 = pb.NewDataLiteral<i64>(0);
- const auto data1 = pb.NewDataLiteral<i64>(-1);
- const auto data2 = pb.NewDataLiteral<i64>(std::numeric_limits<i8>::min());
- const auto data3 = pb.NewDataLiteral<i64>(std::numeric_limits<i8>::max());
- const auto data4 = pb.NewDataLiteral<i64>(std::numeric_limits<i16>::min());
- const auto data5 = pb.NewDataLiteral<i64>(std::numeric_limits<i16>::max());
- const auto data6 = pb.NewDataLiteral<i64>(std::numeric_limits<i32>::min());
- const auto data7 = pb.NewDataLiteral<i64>(std::numeric_limits<i32>::max());
- const auto data8 = pb.NewDataLiteral<i64>(std::numeric_limits<i64>::min());
- const auto data9 = pb.NewDataLiteral<i64>(std::numeric_limits<i64>::max());
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui64>::Id, true)),
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), -1);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -1);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -1);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::min());
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::min());
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::min());
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i8>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i8>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::min());
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::min());
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i16>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i16>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::min());
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i32>::max());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i32>::max());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i64>::max());
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFloatFromString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.14");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("1212.00");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-7898.8");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("21E4");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
- const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
- const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.StrictFromString(item, pb.NewDataType(NUdf::TDataType<float>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isnan(item.template Get<float>()));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -3.14f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 1212.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -7898.8f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 210000.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), HUGE_VALF);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -HUGE_VALF);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoubleFromString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.14");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("12121324.00");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-7898.8");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("21E4");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
- const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
- const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.StrictFromString(item, pb.NewDataType(NUdf::TDataType<double>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isnan(item.template Get<double>()));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 12121324.0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 210000.0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), HUGE_VAL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -HUGE_VAL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFloatToString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0f);
- const auto data1 = pb.NewDataLiteral(0.0f*HUGE_VALF);
- const auto data2 = pb.NewDataLiteral(-3.14f);
- const auto data3 = pb.NewDataLiteral(1212.0f);
- const auto data4 = pb.NewDataLiteral(-7898.8f);
- const auto data5 = pb.NewDataLiteral(210000.0f);
- const auto data6 = pb.NewDataLiteral(HUGE_VALF);
- const auto data7 = pb.NewDataLiteral(-HUGE_VALF);
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToString(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "0");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "nan");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-3.14");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "1212");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-7898.8");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "210000");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "inf");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-inf");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestInt64ToTimestamp) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(i64(0LL));
- const auto data1 = pb.NewDataLiteral(i64(1LL));
- const auto data2 = pb.NewDataLiteral(i64(-1LL));
- const auto data3 = pb.NewDataLiteral(std::numeric_limits<i64>::min());
- const auto data4 = pb.NewDataLiteral(std::numeric_limits<i64>::max());
- const auto data5 = pb.NewDataLiteral(i64(4291747200000000LL));
- const auto data6 = pb.NewDataLiteral(i64(4291747199999999LL));
- const auto type = pb.NewDataType(NUdf::TDataType<i64>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id, true));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 0ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 1ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 4291747199999999ULL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFloatConvertToUint32) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0f);
- const auto data3 = pb.NewDataLiteral(1212.0f);
- const auto data5 = pb.NewDataLiteral(210000.0f);
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, {data0, data3, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<ui32>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1212U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 210000U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFloatConvertToInt32) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0f);
- const auto data2 = pb.NewDataLiteral(-3.14f);
- const auto data3 = pb.NewDataLiteral(1212.0f);
- const auto data4 = pb.NewDataLiteral(-7898.8f);
- const auto data5 = pb.NewDataLiteral(210000.0f);
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, {data0, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<i32>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1212);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -7898);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 210000);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoubleConvertToInt64) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(1212.0);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto data5 = pb.NewDataLiteral(210000.0);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<i64>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 0LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -3LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 1212LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -7898LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 210000LL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoubleToInt64) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(1212.0);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto data5 = pb.NewDataLiteral(210000.0);
- const auto data6 = pb.NewDataLiteral(9223372036854776000.0);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data2, data3, data4, data5, data6});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToIntegral(item, pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i64>::Id)));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 0LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -3LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 1212LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -7898LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 210000LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoubleToString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(12121324.0);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto data5 = pb.NewDataLiteral(210000.0);
- const auto data6 = pb.NewDataLiteral(HUGE_VAL);
- const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToString(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "0");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "nan");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-3.14");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "12121324");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-7898.8");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "210000");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "inf");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-inf");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestUI64ToIntegral) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto data0 = pb.NewDataLiteral<ui64>(0U);
+ const auto data1 = pb.NewDataLiteral<ui64>(1U);
+ const auto data2 = pb.NewDataLiteral<ui64>(std::numeric_limits<i8>::max());
+ const auto data3 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui8>::max());
+ const auto data4 = pb.NewDataLiteral<ui64>(std::numeric_limits<i16>::max());
+ const auto data5 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui16>::max());
+ const auto data6 = pb.NewDataLiteral<ui64>(std::numeric_limits<i32>::max());
+ const auto data7 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui32>::max());
+ const auto data8 = pb.NewDataLiteral<ui64>(std::numeric_limits<i64>::max());
+ const auto data9 = pb.NewDataLiteral<ui64>(std::numeric_limits<ui64>::max());
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i64>::Id, true)),
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 1);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i8>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<ui8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<ui8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<ui8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<ui8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui8>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i16>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<ui16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<ui16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui16>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i32>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i32>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<ui32>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<ui32>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), std::numeric_limits<i64>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestI64ToIntegral) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<i64>::Id);
+ const auto data0 = pb.NewDataLiteral<i64>(0);
+ const auto data1 = pb.NewDataLiteral<i64>(-1);
+ const auto data2 = pb.NewDataLiteral<i64>(std::numeric_limits<i8>::min());
+ const auto data3 = pb.NewDataLiteral<i64>(std::numeric_limits<i8>::max());
+ const auto data4 = pb.NewDataLiteral<i64>(std::numeric_limits<i16>::min());
+ const auto data5 = pb.NewDataLiteral<i64>(std::numeric_limits<i16>::max());
+ const auto data6 = pb.NewDataLiteral<i64>(std::numeric_limits<i32>::min());
+ const auto data7 = pb.NewDataLiteral<i64>(std::numeric_limits<i32>::max());
+ const auto data8 = pb.NewDataLiteral<i64>(std::numeric_limits<i64>::min());
+ const auto data9 = pb.NewDataLiteral<i64>(std::numeric_limits<i64>::max());
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui64>::Id, true)),
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), -1);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -1);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -1);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::min());
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::min());
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::min());
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i8>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i8>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::min());
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::min());
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i16>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i16>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::min());
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), std::numeric_limits<i32>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), std::numeric_limits<i32>::max());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i32>::max());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<ui64>(), std::numeric_limits<i64>::max());
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFloatFromString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.14");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("1212.00");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-7898.8");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("21E4");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
+ const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
+ const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.StrictFromString(item, pb.NewDataType(NUdf::TDataType<float>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isnan(item.template Get<float>()));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -3.14f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 1212.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -7898.8f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 210000.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), HUGE_VALF);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -HUGE_VALF);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoubleFromString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.14");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("12121324.00");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-7898.8");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("21E4");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
+ const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
+ const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.StrictFromString(item, pb.NewDataType(NUdf::TDataType<double>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isnan(item.template Get<double>()));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 12121324.0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 210000.0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), HUGE_VAL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -HUGE_VAL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFloatToString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0f);
+ const auto data1 = pb.NewDataLiteral(0.0f*HUGE_VALF);
+ const auto data2 = pb.NewDataLiteral(-3.14f);
+ const auto data3 = pb.NewDataLiteral(1212.0f);
+ const auto data4 = pb.NewDataLiteral(-7898.8f);
+ const auto data5 = pb.NewDataLiteral(210000.0f);
+ const auto data6 = pb.NewDataLiteral(HUGE_VALF);
+ const auto data7 = pb.NewDataLiteral(-HUGE_VALF);
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToString(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "0");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "nan");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-3.14");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "1212");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-7898.8");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "210000");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "inf");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-inf");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestInt64ToTimestamp) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(i64(0LL));
+ const auto data1 = pb.NewDataLiteral(i64(1LL));
+ const auto data2 = pb.NewDataLiteral(i64(-1LL));
+ const auto data3 = pb.NewDataLiteral(std::numeric_limits<i64>::min());
+ const auto data4 = pb.NewDataLiteral(std::numeric_limits<i64>::max());
+ const auto data5 = pb.NewDataLiteral(i64(4291747200000000LL));
+ const auto data6 = pb.NewDataLiteral(i64(4291747199999999LL));
+ const auto type = pb.NewDataType(NUdf::TDataType<i64>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id, true));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 0ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 1ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 4291747199999999ULL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFloatConvertToUint32) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0f);
+ const auto data3 = pb.NewDataLiteral(1212.0f);
+ const auto data5 = pb.NewDataLiteral(210000.0f);
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, {data0, data3, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1212U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 210000U);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFloatConvertToInt32) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0f);
+ const auto data2 = pb.NewDataLiteral(-3.14f);
+ const auto data3 = pb.NewDataLiteral(1212.0f);
+ const auto data4 = pb.NewDataLiteral(-7898.8f);
+ const auto data5 = pb.NewDataLiteral(210000.0f);
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, {data0, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<i32>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1212);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -7898);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 210000);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoubleConvertToInt64) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(1212.0);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto data5 = pb.NewDataLiteral(210000.0);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<i64>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 0LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -3LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 1212LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -7898LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 210000LL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoubleToInt64) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(1212.0);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto data5 = pb.NewDataLiteral(210000.0);
+ const auto data6 = pb.NewDataLiteral(9223372036854776000.0);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data2, data3, data4, data5, data6});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToIntegral(item, pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i64>::Id)));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 0LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -3LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 1212LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -7898LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), 210000LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoubleToString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(0.0*HUGE_VAL);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(12121324.0);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto data5 = pb.NewDataLiteral(210000.0);
+ const auto data6 = pb.NewDataLiteral(HUGE_VAL);
+ const auto data7 = pb.NewDataLiteral(-HUGE_VAL);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToString(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "0");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "nan");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-3.14");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "12121324");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-7898.8");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "210000");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "inf");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-inf");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestNanvl) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewOptional(pb.NewDataLiteral(0.0f));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral(0.0f*HUGE_VALF));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral(HUGE_VALF));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral(-HUGE_VALF));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral(FLT_MIN/2.0f));
- const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
- const auto data = pb.NewDataLiteral(3.14);
-
- const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<float>::Id));
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Nanvl(item, data);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral(0.0f));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral(0.0f*HUGE_VALF));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral(HUGE_VALF));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral(-HUGE_VALF));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral(FLT_MIN/2.0f));
+ const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
+ const auto data = pb.NewDataLiteral(3.14);
+
+ const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<float>::Id));
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Nanvl(item, data);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.14);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), HUGE_VAL);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -HUGE_VAL);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), FLT_MIN/2.0f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
Y_UNIT_TEST_LLVM(TestConvertToFloat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto seven = pb.NewDataLiteral(i32(7));
- const auto pgmReturn = pb.Convert(seven, pb.NewDataType(NUdf::TDataType<float>::Id));
- const auto graph = setup.BuildGraph(pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto seven = pb.NewDataLiteral(i32(7));
+ const auto pgmReturn = pb.Convert(seven, pb.NewDataType(NUdf::TDataType<float>::Id));
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().template Get<float>(), 7.0f);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestAppend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- pgmReturn = pb.Append(pgmReturn, pb.NewDataLiteral<ui32>(34));
- pgmReturn = pb.Append(pgmReturn, pb.NewDataLiteral<ui32>(56));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ pgmReturn = pb.Append(pgmReturn, pb.NewDataLiteral<ui32>(34));
+ pgmReturn = pb.Append(pgmReturn, pb.NewDataLiteral<ui32>(56));
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 2);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestForkedAppend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {pb.NewDataLiteral<ui32>(34)});
- const auto list2 = pb.Append(list1, pb.NewDataLiteral<ui32>(56));
- const auto list3 = pb.Append(list1, pb.NewDataLiteral<ui32>(78));
- const auto pgmReturn = pb.NewTuple({list2, list3});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator1 = graph->GetValue().GetElement(0).GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator1.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {pb.NewDataLiteral<ui32>(34)});
+ const auto list2 = pb.Append(list1, pb.NewDataLiteral<ui32>(56));
+ const auto list3 = pb.Append(list1, pb.NewDataLiteral<ui32>(78));
+ const auto pgmReturn = pb.NewTuple({list2, list3});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator1 = graph->GetValue().GetElement(0).GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator1.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator1.Next(item));
+ UNIT_ASSERT(iterator1.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator1.Next(item));
- UNIT_ASSERT(!iterator1.Next(item));
+ UNIT_ASSERT(!iterator1.Next(item));
+ UNIT_ASSERT(!iterator1.Next(item));
- const auto iterator2 = graph->GetValue().GetElement(1).GetListIterator();
- UNIT_ASSERT(iterator2.Next(item));
+ const auto iterator2 = graph->GetValue().GetElement(1).GetListIterator();
+ UNIT_ASSERT(iterator2.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator2.Next(item));
+ UNIT_ASSERT(iterator2.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 78);
- UNIT_ASSERT(!iterator2.Next(item));
- UNIT_ASSERT(!iterator2.Next(item));
+ UNIT_ASSERT(!iterator2.Next(item));
+ UNIT_ASSERT(!iterator2.Next(item));
}
Y_UNIT_TEST_LLVM(TestPrepend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- pgmReturn = pb.Prepend(pb.NewDataLiteral<ui32>(34), pgmReturn);
- pgmReturn = pb.Prepend(pb.NewDataLiteral<ui32>(56), pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ pgmReturn = pb.Prepend(pb.NewDataLiteral<ui32>(34), pgmReturn);
+ pgmReturn = pb.Prepend(pb.NewDataLiteral<ui32>(56), pgmReturn);
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 2);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestPrependOfVoid) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- auto pgmReturn = pb.NewEmptyListOfVoid();
- pgmReturn = pb.Prepend(pb.NewVoid(), pgmReturn);
- pgmReturn = pb.Prepend(pb.NewVoid(), pgmReturn);
-
- const auto graph = setup.BuildGraph(pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ auto pgmReturn = pb.NewEmptyListOfVoid();
+ pgmReturn = pb.Prepend(pb.NewVoid(), pgmReturn);
+ pgmReturn = pb.Prepend(pb.NewVoid(), pgmReturn);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 0);
-
- const auto iterator = graph->GetValue().GetListIterator();
- UNIT_ASSERT(!iterator.Skip());
- UNIT_ASSERT(!iterator.Skip());
- }
-
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ UNIT_ASSERT(!iterator.Skip());
+ UNIT_ASSERT(!iterator.Skip());
+ }
+
Y_UNIT_TEST_LLVM(TestForkedPrepend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto list1 = pb.Prepend(pb.NewDataLiteral<ui32>(34), list);
- const auto list2 = pb.Prepend(pb.NewDataLiteral<ui32>(56), list1);
- const auto list3 = pb.Prepend(pb.NewDataLiteral<ui32>(78), list1);
- const auto pgmReturn = pb.NewTuple({list2, list3});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator1 = graph->GetValue().GetElement(0).GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator1.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto list1 = pb.Prepend(pb.NewDataLiteral<ui32>(34), list);
+ const auto list2 = pb.Prepend(pb.NewDataLiteral<ui32>(56), list1);
+ const auto list3 = pb.Prepend(pb.NewDataLiteral<ui32>(78), list1);
+ const auto pgmReturn = pb.NewTuple({list2, list3});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator1 = graph->GetValue().GetElement(0).GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator1.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator1.Next(item));
+ UNIT_ASSERT(iterator1.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator1.Next(item));
- UNIT_ASSERT(!iterator1.Next(item));
+ UNIT_ASSERT(!iterator1.Next(item));
+ UNIT_ASSERT(!iterator1.Next(item));
- const auto iterator2 = graph->GetValue().GetElement(1).GetListIterator();
- UNIT_ASSERT(iterator2.Next(item));
+ const auto iterator2 = graph->GetValue().GetElement(1).GetListIterator();
+ UNIT_ASSERT(iterator2.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 78);
- UNIT_ASSERT(iterator2.Next(item));
+ UNIT_ASSERT(iterator2.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator2.Next(item));
- UNIT_ASSERT(!iterator2.Next(item));
+ UNIT_ASSERT(!iterator2.Next(item));
+ UNIT_ASSERT(!iterator2.Next(item));
}
Y_UNIT_TEST_LLVM(TestAppendOfVoid) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- auto pgmReturn = pb.NewEmptyListOfVoid();
- pgmReturn = pb.Append(pgmReturn, pb.NewVoid());
- pgmReturn = pb.Append(pgmReturn, pb.NewVoid());
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ auto pgmReturn = pb.NewEmptyListOfVoid();
+ pgmReturn = pb.Append(pgmReturn, pb.NewVoid());
+ pgmReturn = pb.Append(pgmReturn, pb.NewVoid());
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 0);
- const auto iterator = graph->GetValue().GetListIterator();
- UNIT_ASSERT(!iterator.Skip());
- UNIT_ASSERT(!iterator.Skip());
+ const auto iterator = graph->GetValue().GetListIterator();
+ UNIT_ASSERT(!iterator.Skip());
+ UNIT_ASSERT(!iterator.Skip());
}
Y_UNIT_TEST_LLVM(TestExtend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto emptyList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto list1 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(34));
- const auto list2 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(56));
- const auto pgmReturn = pb.Extend(list1, list2);
-
- const auto graph = setup.BuildGraph(pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto emptyList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto list1 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(34));
+ const auto list2 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(56));
+ const auto pgmReturn = pb.Extend(list1, list2);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 2);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestExtend3) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto emptyList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto list1 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(34));
- const auto list2 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(56));
- const auto list3 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(7));
- const auto list4 = pb.Append(list3, pb.NewDataLiteral<ui32>(12));
- const auto pgmReturn = pb.Extend({ list1, emptyList, list2, list4 });
-
- const auto graph = setup.BuildGraph(pgmReturn);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto emptyList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto list1 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(34));
+ const auto list2 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(56));
+ const auto list3 = pb.Append(emptyList, pb.NewDataLiteral<ui32>(7));
+ const auto list4 = pb.Append(list3, pb.NewDataLiteral<ui32>(12));
+ const auto pgmReturn = pb.Extend({ list1, emptyList, list2, list4 });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 4);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 12);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestExtendOverFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(1.1);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(121324.323);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list1 = pb.NewList(type, {data0, data1, data2});
- const auto list2 = pb.NewList(type, {data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.Extend({pb.ToFlow(list2), pb.ToFlow(list1), pb.ToFlow(list2)}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 121324.323);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1.1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 121324.323);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestStreamForwardList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(34);
- const auto data2 = pb.NewDataLiteral<ui32>(56);
- const auto data3 = pb.NewDataLiteral<ui32>(7);
- const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(type, {data1, data2, data3});
-
- const auto pgmReturn = pb.ForwardList(pb.Iterator(list, {}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFlowForwardList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(34);
- const auto data2 = pb.NewDataLiteral<ui32>(56);
- const auto data3 = pb.NewDataLiteral<ui32>(7);
- const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(type, {data1, data2, data3});
-
- const auto pgmReturn = pb.ForwardList(pb.ToFlow(list));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFlowFromOptional) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(1.1);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
-
- const auto opt0 = pb.NewOptional(data0);
- const auto opt1 = pb.NewOptional(data1);
- const auto opt2 = pb.NewOptional(data2);
- const auto opt = pb.NewEmptyOptional(pb.NewOptionalType(type));
-
-
- const auto pgmReturn = pb.FromFlow(pb.Extend({pb.ToFlow(opt0), pb.ToFlow(opt), pb.ToFlow(opt1), pb.ToFlow(opt), pb.ToFlow(opt2)}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1.1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCollectOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(1.1);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(121324.323);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto data = pb.NewList(type, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.ToFlow(data));
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto list = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<double>(), 0.0);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(3).template Get<double>(), 121324.323);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<double>(), 1.1);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<double>(), -3.14);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(4).template Get<double>(), -7898.8);
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestExtendOverFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(1.1);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(121324.323);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list1 = pb.NewList(type, {data0, data1, data2});
+ const auto list2 = pb.NewList(type, {data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.Extend({pb.ToFlow(list2), pb.ToFlow(list1), pb.ToFlow(list2)}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 121324.323);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1.1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 121324.323);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -7898.8);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamForwardList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto data1 = pb.NewDataLiteral<ui32>(34);
+ const auto data2 = pb.NewDataLiteral<ui32>(56);
+ const auto data3 = pb.NewDataLiteral<ui32>(7);
+ const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(type, {data1, data2, data3});
+
+ const auto pgmReturn = pb.ForwardList(pb.Iterator(list, {}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFlowForwardList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto data1 = pb.NewDataLiteral<ui32>(34);
+ const auto data2 = pb.NewDataLiteral<ui32>(56);
+ const auto data3 = pb.NewDataLiteral<ui32>(7);
+ const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(type, {data1, data2, data3});
+
+ const auto pgmReturn = pb.ForwardList(pb.ToFlow(list));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFlowFromOptional) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(1.1);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+
+ const auto opt0 = pb.NewOptional(data0);
+ const auto opt1 = pb.NewOptional(data1);
+ const auto opt2 = pb.NewOptional(data2);
+ const auto opt = pb.NewEmptyOptional(pb.NewOptionalType(type));
+
+
+ const auto pgmReturn = pb.FromFlow(pb.Extend({pb.ToFlow(opt0), pb.ToFlow(opt), pb.ToFlow(opt1), pb.ToFlow(opt), pb.ToFlow(opt2)}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1.1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -3.14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCollectOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(1.1);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(121324.323);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto data = pb.NewList(type, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.ToFlow(data));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto list = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<double>(), 0.0);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(3).template Get<double>(), 121324.323);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<double>(), 1.1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<double>(), -3.14);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(4).template Get<double>(), -7898.8);
+ }
+
Y_UNIT_TEST_LLVM(TestAdd) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto pgmReturn = pb.Add(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto pgmReturn = pb.Add(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<ui32>();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(res, 3);
}
Y_UNIT_TEST_LLVM(TestSub) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(7);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto pgmReturn = pb.Sub(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(7);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto pgmReturn = pb.Sub(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<ui32>();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(res, 5);
}
Y_UNIT_TEST_LLVM(TestMul) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(3);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto pgmReturn = pb.Mul(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(3);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto pgmReturn = pb.Mul(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<ui32>();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(res, 6);
}
Y_UNIT_TEST_LLVM(TestDiv) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(17);
- const auto data2 = pb.NewDataLiteral<ui32>(3);
- const auto pgmReturn = pb.Div(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(17);
+ const auto data2 = pb.NewDataLiteral<ui32>(3);
+ const auto pgmReturn = pb.Div(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 5);
}
Y_UNIT_TEST_LLVM(TestDivZero) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(17);
- const auto data2 = pb.NewDataLiteral<ui32>(0);
- const auto pgmReturn = pb.Div(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(17);
+ const auto data2 = pb.NewDataLiteral<ui32>(0);
+ const auto pgmReturn = pb.Div(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(!value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(!value);
}
Y_UNIT_TEST_LLVM(TestIDivOverflow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<i32>(Min<i32>());
- const auto data2 = pb.NewDataLiteral<i32>(-1);
- const auto pgmReturn = pb.Div(data1, data2);
+ const auto data1 = pb.NewDataLiteral<i32>(Min<i32>());
+ const auto data2 = pb.NewDataLiteral<i32>(-1);
+ const auto pgmReturn = pb.Div(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(!value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(!value);
}
Y_UNIT_TEST_LLVM(TestMod) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(17);
- const auto data2 = pb.NewDataLiteral<ui32>(3);
- const auto pgmReturn = pb.Mod(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(17);
+ const auto data2 = pb.NewDataLiteral<ui32>(3);
+ const auto pgmReturn = pb.Mod(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 2);
}
Y_UNIT_TEST_LLVM(TestModZero) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(17);
- const auto data2 = pb.NewDataLiteral<ui32>(0);
- const auto pgmReturn = pb.Mod(data1, data2);
+ const auto data1 = pb.NewDataLiteral<ui32>(17);
+ const auto data2 = pb.NewDataLiteral<ui32>(0);
+ const auto pgmReturn = pb.Mod(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(!value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(!value);
}
Y_UNIT_TEST_LLVM(TestIModOverflow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<i32>(Min<i32>());
- const auto data2 = pb.NewDataLiteral<i32>(-1);
- const auto pgmReturn = pb.Mod(data1, data2);
+ const auto data1 = pb.NewDataLiteral<i32>(Min<i32>());
+ const auto data2 = pb.NewDataLiteral<i32>(-1);
+ const auto pgmReturn = pb.Mod(data1, data2);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(!value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(!value);
}
Y_UNIT_TEST_LLVM(TestStruct) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto structObj = pb.NewEmptyStruct();
- structObj = pb.AddMember(structObj, "x", data2);
- structObj = pb.AddMember(structObj, "z", data1);
- structObj = pb.AddMember(structObj, "y", data3);
- const auto pgmReturn = pb.NewList(dataType, {
- pb.Member(structObj, "x"),
- pb.Member(structObj, "y"),
- pb.Member(structObj, "z")
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto structObj = pb.NewEmptyStruct();
+ structObj = pb.AddMember(structObj, "x", data2);
+ structObj = pb.AddMember(structObj, "z", data1);
+ structObj = pb.AddMember(structObj, "y", data3);
+ const auto pgmReturn = pb.NewList(dataType, {
+ pb.Member(structObj, "x"),
+ pb.Member(structObj, "y"),
+ pb.Member(structObj, "z")
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestMapOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i32>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i32>(2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<i32>(3));
- const auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i32>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i32>(2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<i32>(3));
+ const auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
[&](TRuntimeNode item) {
- return pb.Sub(pb.Mul(item, data2), data1);
+ return pb.Sub(pb.Mul(item, data2), data1);
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 5);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestMapOverStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<i16>(0));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(-1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i16>(3));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<i16>(7));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<i16>(11));
- const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Div(data3, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<i16>(0));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(-1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i16>(3));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<i16>(7));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<i16>(11));
+ const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Div(data3, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
+ UNIT_ASSERT(!item);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), -7);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
@@ -2008,2044 +2008,2044 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 0);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
+ UNIT_ASSERT(!item);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMapOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("PREFIX:");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very large string");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("small");
- const auto type = pb.NewDataType(NUdf::EDataSlot::String);
- const auto list = pb.NewList(type, {data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.Map(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.Concat(data0, item);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:very large string");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:small");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
-#ifndef _win_
+ }
+
+ Y_UNIT_TEST_LLVM(TestMapOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("PREFIX:");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very large string");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("small");
+ const auto type = pb.NewDataType(NUdf::EDataSlot::String);
+ const auto list = pb.NewList(type, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.Map(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.Concat(data0, item);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:very large string");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "PREFIX:small");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+#ifndef _win_
Y_UNIT_TEST_LLVM(TestMapUnwrapThrow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(7));
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
- const auto list = pb.LazyList(pb.NewList(dataType, {data1, data0}));
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Sub(data2, pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(7));
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
+ const auto list = pb.LazyList(pb.NewList(dataType, {data1, data0}));
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Sub(data2, pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 6);
UNIT_ASSERT_EXCEPTION(iterator.Next(item), yexception);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestMapUnwrapThrowMessage) {
TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(7));
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
- const auto list = pb.LazyList(pb.NewList(dataType, {data1, data0}));
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(7));
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
+ const auto list = pb.LazyList(pb.NewList(dataType, {data1, data0}));
- const auto pgmReturn = pb.Map(list,
+ const auto pgmReturn = pb.Map(list,
[&](TRuntimeNode item) {
- return pb.Sub(data2, pb.Unwrap(item, pb.Concat(
- pb.NewDataLiteral<NUdf::EDataSlot::String>("a"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("b")),
+ return pb.Sub(data2, pb.Unwrap(item, pb.Concat(
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("a"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("b")),
"", 0, 0));
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
NUdf::TUnboxedValue item;
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 6);
UNIT_ASSERT_EXCEPTION(iterator.Next(item), yexception);
}
-
+
Y_UNIT_TEST_LLVM(TestMapEnsureThrowMessage) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
- const auto data1 = pb.NewDataLiteral<i8>(1);
- const auto data2 = pb.NewDataLiteral<i8>(7);
- const auto list = pb.LazyList(pb.NewList(dataType, {data1, data2}));
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Sub(data2,
- pb.Ensure(item, pb.Less(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>("BAD"),"", 0, 0));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 6);
- UNIT_ASSERT_EXCEPTION(iterator.Next(item), yexception);
- }
-#endif
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
+ const auto data1 = pb.NewDataLiteral<i8>(1);
+ const auto data2 = pb.NewDataLiteral<i8>(7);
+ const auto list = pb.LazyList(pb.NewList(dataType, {data1, data2}));
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Sub(data2,
+ pb.Ensure(item, pb.Less(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>("BAD"),"", 0, 0));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 6);
+ UNIT_ASSERT_EXCEPTION(iterator.Next(item), yexception);
+ }
+#endif
Y_UNIT_TEST_LLVM(TestMapWithCoalesce) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
- const auto data0 = pb.NewDataLiteral<i16>(0);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i16>(2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<i16>(3));
- const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Coalesce(item, data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
+ const auto data0 = pb.NewDataLiteral<i16>(0);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i16>(2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<i16>(3));
+ const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Coalesce(item, data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i16>(), 0);
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestSizeOfOptional) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<i16>(0));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(1));
- const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
- const auto list = pb.NewList(dataType, {data1, data0, data});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Size(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i16>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<i16>(0));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i16>(1));
+ const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i16>::Id);
+ const auto list = pb.NewList(dataType, {data1, data0, data});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Size(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestSizeOfOptionalString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<char*>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789"));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("XYZ"));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("qwertyuioplkjhgfdsazxcvbnm"));
- const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Size(pb.Concat(item, data0));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 20U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 13U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 10U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 36U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<char*>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789"));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("XYZ"));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("qwertyuioplkjhgfdsazxcvbnm"));
+ const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Size(pb.Concat(item, data0));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 20U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 13U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 10U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 36U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestMapWithIfExists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui16>::Id));
- const auto data0 = pb.NewDataLiteral<ui16>(666);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui16>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui16>(2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui16>(3));
- const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui16>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.If(pb.Exists(item), pb.Increment(pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)), data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui16>::Id));
+ const auto data0 = pb.NewDataLiteral<ui16>(666);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui16>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui16>(2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui16>(3));
+ const auto data = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui16>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.If(pb.Exists(item), pb.Increment(pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)), data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 666);
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestMapOverListLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto data3 = pb.NewDataLiteral<ui32>(3U);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto data3 = pb.NewDataLiteral<ui32>(3U);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto pgmReturn = pb.Map(pb.LazyList(list),
+ const auto pgmReturn = pb.Map(pb.LazyList(list),
[&](TRuntimeNode item) {
- return pb.Add(pb.Mul(item, data2), data1);
- }
- );
+ return pb.Add(pb.Mul(item, data2), data1);
+ }
+ );
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 5);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestMapOverOptional) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto list = pb.NewOptional(data1);
- const auto pgmReturn = pb.Map(list,
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto list = pb.NewOptional(data1);
+ const auto pgmReturn = pb.Map(list,
[&](TRuntimeNode item) {
- return pb.Add(pb.Mul(item, data2), data1);
+ return pb.Add(pb.Mul(item, data2), data1);
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 3);
}
Y_UNIT_TEST_LLVM(TestFloatMinMax) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<float>(-NAN);
- const auto data2 = pb.NewDataLiteral<float>(HUGE_VALF);
- const auto data3 = pb.NewDataLiteral<float>(3.14f);
- const auto data4 = pb.NewDataLiteral<float>(-2.13f);
- const auto data5 = pb.NewDataLiteral<float>(-HUGE_VALF);
- const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode left) {
- return pb.Map(list,
- [&](TRuntimeNode right) {
- return pb.NewTuple({pb.Min(left, right), pb.Max(left, right)});
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isnan(item.GetElement(0).template Get<float>()));
- UNIT_ASSERT(std::isnan(item.GetElement(1).template Get<float>()));
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<float>(-NAN);
+ const auto data2 = pb.NewDataLiteral<float>(HUGE_VALF);
+ const auto data3 = pb.NewDataLiteral<float>(3.14f);
+ const auto data4 = pb.NewDataLiteral<float>(-2.13f);
+ const auto data5 = pb.NewDataLiteral<float>(-HUGE_VALF);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode left) {
+ return pb.Map(list,
+ [&](TRuntimeNode right) {
+ return pb.NewTuple({pb.Min(left, right), pb.Max(left, right)});
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isnan(item.GetElement(0).template Get<float>()));
+ UNIT_ASSERT(std::isnan(item.GetElement(1).template Get<float>()));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), 3.14f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -2.13f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), 3.14f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), 3.14f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), 3.14f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), 3.14f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -2.13f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -2.13f);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -2.13f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -2.13f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), HUGE_VALF);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -2.13f);
-
- UNIT_ASSERT(iterator.Next(item));
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<float>(), -HUGE_VALF);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<float>(), -HUGE_VALF);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFloatMod) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<float>(-1.75f);
- const auto data2 = pb.NewDataLiteral<float>(3.14f);
- const auto data3 = pb.NewDataLiteral<float>(-6.28f);
- const auto data4 = pb.NewDataLiteral<float>(7.28f);
- const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Mod(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<float>(-1.75f);
+ const auto data2 = pb.NewDataLiteral<float>(3.14f);
+ const auto data3 = pb.NewDataLiteral<float>(-6.28f);
+ const auto data4 = pb.NewDataLiteral<float>(7.28f);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Mod(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.75f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.0f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.0f);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 1.0f);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestDoubleMod) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<double>(-1.75);
- const auto data2 = pb.NewDataLiteral<double>(3.14);
- const auto data3 = pb.NewDataLiteral<double>(-6.28);
- const auto data4 = pb.NewDataLiteral<double>(7.28);
- const auto dataType = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Mod(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<double>(-1.75);
+ const auto data2 = pb.NewDataLiteral<double>(3.14);
+ const auto data3 = pb.NewDataLiteral<double>(-6.28);
+ const auto data4 = pb.NewDataLiteral<double>(7.28);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Mod(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -1.75);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1.0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDiscardOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.Discard(pb.ToFlow(list)));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestHead) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto listType = pb.NewListType(itemType);
-
- const auto data0 = pb.NewEmptyList(itemType);
- const auto data1 = pb.NewList(itemType, {pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f), pb.NewDataLiteral<float>(3.14f)});
- const auto data2 = pb.NewList(itemType, {pb.NewDataLiteral<float>(3.14f), pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f)});
- const auto data3 = pb.LazyList(pb.NewList(itemType, {pb.NewDataLiteral<float>(1.1f), pb.NewDataLiteral<float>(-2.2f)}));
-
- const auto list = pb.NewList(listType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) { return pb.Head(item); });
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.5f);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 1.1f);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestLast) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto listType = pb.NewListType(itemType);
-
- const auto data0 = pb.NewEmptyList(itemType);
- const auto data1 = pb.NewList(itemType, {pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f), pb.NewDataLiteral<float>(3.14f)});
- const auto data2 = pb.NewList(itemType, {pb.NewDataLiteral<float>(3.14f), pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f)});
- const auto data3 = pb.LazyList(pb.NewList(itemType, {pb.NewDataLiteral<float>(1.1f), pb.NewDataLiteral<float>(-2.2f)}));
-
- const auto list = pb.NewList(listType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) { return pb.Last(item); });
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 3.14f);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.f);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -2.2f);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDiscardOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.Discard(pb.ToFlow(list)));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestHead) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto listType = pb.NewListType(itemType);
+
+ const auto data0 = pb.NewEmptyList(itemType);
+ const auto data1 = pb.NewList(itemType, {pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f), pb.NewDataLiteral<float>(3.14f)});
+ const auto data2 = pb.NewList(itemType, {pb.NewDataLiteral<float>(3.14f), pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f)});
+ const auto data3 = pb.LazyList(pb.NewList(itemType, {pb.NewDataLiteral<float>(1.1f), pb.NewDataLiteral<float>(-2.2f)}));
+
+ const auto list = pb.NewList(listType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) { return pb.Head(item); });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.5f);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 3.14f);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 1.1f);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestLast) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto listType = pb.NewListType(itemType);
+
+ const auto data0 = pb.NewEmptyList(itemType);
+ const auto data1 = pb.NewList(itemType, {pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f), pb.NewDataLiteral<float>(3.14f)});
+ const auto data2 = pb.NewList(itemType, {pb.NewDataLiteral<float>(3.14f), pb.NewDataLiteral<float>(-1.5f), pb.NewDataLiteral<float>(0.f)});
+ const auto data3 = pb.LazyList(pb.NewList(itemType, {pb.NewDataLiteral<float>(1.1f), pb.NewDataLiteral<float>(-2.2f)}));
+
+ const auto list = pb.NewList(listType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) { return pb.Last(item); });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 3.14f);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.f);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -2.2f);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestCoalesce) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- auto pgmReturn = pb.NewEmptyStruct();
- pgmReturn = pb.AddMember(pgmReturn, "A", pb.Coalesce(
- pb.NewOptional(data1), data2));
- pgmReturn = pb.AddMember(pgmReturn, "B", pb.Coalesce(
- pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), data2));
- pgmReturn = pb.AddMember(pgmReturn, "C", pb.Coalesce(
- pb.NewOptional(data2), pb.NewOptional(data3)));
- pgmReturn = pb.AddMember(pgmReturn, "D", pb.Coalesce(
- pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), pb.NewOptional(data3)));
- pgmReturn = pb.AddMember(pgmReturn, "E", pb.Coalesce(
- pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id)));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ auto pgmReturn = pb.NewEmptyStruct();
+ pgmReturn = pb.AddMember(pgmReturn, "A", pb.Coalesce(
+ pb.NewOptional(data1), data2));
+ pgmReturn = pb.AddMember(pgmReturn, "B", pb.Coalesce(
+ pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), data2));
+ pgmReturn = pb.AddMember(pgmReturn, "C", pb.Coalesce(
+ pb.NewOptional(data2), pb.NewOptional(data3)));
+ pgmReturn = pb.AddMember(pgmReturn, "D", pb.Coalesce(
+ pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), pb.NewOptional(data3)));
+ pgmReturn = pb.AddMember(pgmReturn, "E", pb.Coalesce(
+ pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id)));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0).template Get<ui32>(), 1);
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1).template Get<ui32>(), 2);
- UNIT_ASSERT(value.GetElement(2));
+ UNIT_ASSERT(value.GetElement(2));
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2).template Get<ui32>(), 2);
- UNIT_ASSERT(value.GetElement(3));
+ UNIT_ASSERT(value.GetElement(3));
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(3).template Get<ui32>(), 3);
- UNIT_ASSERT(!value.GetElement(4));
+ UNIT_ASSERT(!value.GetElement(4));
}
Y_UNIT_TEST_LLVM(TestExists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui64>(1);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui64>::Id));
- const auto list = pb.NewList(optionalType, {pb.NewOptional(data1), pb.NewEmptyOptional(optionalType)});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Exists(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui64>(1);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui64>::Id));
+ const auto list = pb.NewList(optionalType, {pb.NewOptional(data1), pb.NewEmptyOptional(optionalType)});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Exists(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIf) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto truth = pb.NewDataLiteral(true);
- const auto falsehood = pb.NewDataLiteral(false);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<bool>::Id), {truth, falsehood});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.If(item, data1, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto truth = pb.NewDataLiteral(true);
+ const auto falsehood = pb.NewDataLiteral(false);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<bool>::Id), {truth, falsehood});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.If(item, data1, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIfPresent) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto filled = pb.NewOptional(data1);
- const auto empty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)), {filled, empty});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.IfPresent({item},
- [&](TRuntimeNode::TList unpacked){
- return unpacked.front();
- }, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto filled = pb.NewOptional(data1);
+ const auto empty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)), {filled, empty});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.IfPresent({item},
+ [&](TRuntimeNode::TList unpacked){
+ return unpacked.front();
+ }, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestIfPresentTwo) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
- const auto empty1 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
-
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data4= pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto empty2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
-
- const auto list1 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, empty1, data2});
- const auto list2 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)), {data3, empty2, data4});
-
- const auto pgmReturn = pb.FlatMap(list1,
- [&](TRuntimeNode item1) {
- return pb.FlatMap(list2,
- [&](TRuntimeNode item2) {
- return pb.IfPresent({item1, item2},
- [&](TRuntimeNode::TList unpacked) {
- return pb.NewOptional(pb.If(unpacked.back(), pb.Minus(unpacked.front()), unpacked.front()));
- }, empty1);
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestIfPresentThree) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
- const auto empty1 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
-
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data4= pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto empty2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
-
- const auto data5 = pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i8>(5)));
- const auto data6 = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id));
- const auto type2 = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)));
- const auto empty3 = pb.NewEmptyOptional(type2);
-
- const auto list1 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, empty1, data2});
- const auto list2 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)), {data3, empty2, data4});
- const auto list3 = pb.NewList(type2, {data5, empty3, data6});
-
- const auto pgmReturn = pb.FlatMap(list1,
- [&](TRuntimeNode item1) {
- return pb.FlatMap(list2,
- [&](TRuntimeNode item2) {
- return pb.FlatMap(list3,
- [&](TRuntimeNode item3) {
- return pb.IfPresent({item1, item2, item3},
- [&](TRuntimeNode::TList unpacked) {
- return pb.NewOptional(pb.If(unpacked[1],
- pb.Add(unpacked.front(), pb.Coalesce(unpacked.back(), pb.NewDataLiteral<i8>(3))),
- pb.Sub(unpacked.front(), pb.Coalesce(unpacked.back(), pb.NewDataLiteral<i8>(7)))
- ));
- }, empty1);
- });
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +6);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -6);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -6);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -8);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestIfPresentSame) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
-
- const auto list = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, data0, data2});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- const auto minus = pb.Minus(item);
- return pb.NewTuple({
- pb.IfPresent({minus},
- [&](TRuntimeNode::TList unpacked) {
- return pb.Abs(unpacked.front());
- }, data0),
- pb.IfPresent({minus},
- [&](TRuntimeNode::TList unpacked) {
- return pb.Minus(unpacked.front());
- }, data0),
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i8>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i8>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i8>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i8>(), -1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestIfPresentTwo) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
+ const auto empty1 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
+
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data4= pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto empty2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+
+ const auto list1 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, empty1, data2});
+ const auto list2 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)), {data3, empty2, data4});
+
+ const auto pgmReturn = pb.FlatMap(list1,
+ [&](TRuntimeNode item1) {
+ return pb.FlatMap(list2,
+ [&](TRuntimeNode item2) {
+ return pb.IfPresent({item1, item2},
+ [&](TRuntimeNode::TList unpacked) {
+ return pb.NewOptional(pb.If(unpacked.back(), pb.Minus(unpacked.front()), unpacked.front()));
+ }, empty1);
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -1);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestIfPresentThree) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
+ const auto empty1 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
+
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data4= pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto empty2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+
+ const auto data5 = pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i8>(5)));
+ const auto data6 = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id));
+ const auto type2 = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)));
+ const auto empty3 = pb.NewEmptyOptional(type2);
+
+ const auto list1 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, empty1, data2});
+ const auto list2 = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id)), {data3, empty2, data4});
+ const auto list3 = pb.NewList(type2, {data5, empty3, data6});
+
+ const auto pgmReturn = pb.FlatMap(list1,
+ [&](TRuntimeNode item1) {
+ return pb.FlatMap(list2,
+ [&](TRuntimeNode item2) {
+ return pb.FlatMap(list3,
+ [&](TRuntimeNode item3) {
+ return pb.IfPresent({item1, item2, item3},
+ [&](TRuntimeNode::TList unpacked) {
+ return pb.NewOptional(pb.If(unpacked[1],
+ pb.Add(unpacked.front(), pb.Coalesce(unpacked.back(), pb.NewDataLiteral<i8>(3))),
+ pb.Sub(unpacked.front(), pb.Coalesce(unpacked.back(), pb.NewDataLiteral<i8>(7)))
+ ));
+ }, empty1);
+ });
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +6);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -6);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), +2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -6);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -8);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestIfPresentSame) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<i8>(+1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<i8>(-1));
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i8>::Id);
+
+ const auto list = pb.NewList(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i8>::Id)), {data1, data0, data2});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ const auto minus = pb.Minus(item);
+ return pb.NewTuple({
+ pb.IfPresent({minus},
+ [&](TRuntimeNode::TList unpacked) {
+ return pb.Abs(unpacked.front());
+ }, data0),
+ pb.IfPresent({minus},
+ [&](TRuntimeNode::TList unpacked) {
+ return pb.Minus(unpacked.front());
+ }, data0),
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i8>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i8>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i8>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i8>(), -1);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestIncDec) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(7);
- auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- pgmReturn = pb.Append(pgmReturn, pb.Increment(data1));
- pgmReturn = pb.Append(pgmReturn, pb.Decrement(data1));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(7);
+ auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ pgmReturn = pb.Append(pgmReturn, pb.Increment(data1));
+ pgmReturn = pb.Append(pgmReturn, pb.Decrement(data1));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 8);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestLogical) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto truth = pb.NewDataLiteral(true);
- const auto falsehood = pb.NewDataLiteral(false);
- auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<bool>::Id));
+ const auto truth = pb.NewDataLiteral(true);
+ const auto falsehood = pb.NewDataLiteral(false);
+ auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<bool>::Id));
- pgmReturn = pb.Append(pgmReturn, pb.And({truth, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.And({truth, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.And({falsehood, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.And({falsehood, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.And({truth, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.And({truth, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.And({falsehood, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.And({falsehood, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.Or({truth, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.Or({falsehood, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.Or({truth, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.Or({falsehood, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.Or({truth, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.Or({falsehood, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.Or({truth, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.Or({falsehood, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.Xor({truth, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.Xor({falsehood, truth}));
- pgmReturn = pb.Append(pgmReturn, pb.Xor({truth, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.Xor({falsehood, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.Xor({truth, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.Xor({falsehood, truth}));
+ pgmReturn = pb.Append(pgmReturn, pb.Xor({truth, falsehood}));
+ pgmReturn = pb.Append(pgmReturn, pb.Xor({falsehood, falsehood}));
- pgmReturn = pb.Append(pgmReturn, pb.Not(truth));
- pgmReturn = pb.Append(pgmReturn, pb.Not(falsehood));
+ pgmReturn = pb.Append(pgmReturn, pb.Not(truth));
+ pgmReturn = pb.Append(pgmReturn, pb.Not(falsehood));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ NUdf::TUnboxedValue item;
- NUdf::TUnboxedValue item;
-
// and
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // not
- UNIT_ASSERT(iterator.Next(item));
+
+ // not
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestZip) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
- pb.NewDataLiteral<ui32>(34),
- pb.NewDataLiteral<ui32>(56)
- });
- const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
- pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
- });
-
- const auto pgmReturn = pb.Zip({list1, list2});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto list = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 2U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).GetElement(0).template Get<ui32>(), 34);
- UNBOXED_VALUE_STR_EQUAL(list.GetElement(0).GetElement(1), "Q");
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).GetElement(0).template Get<ui32>(), 56);
- UNBOXED_VALUE_STR_EQUAL(list.GetElement(1).GetElement(1), "E");
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
+ pb.NewDataLiteral<ui32>(34),
+ pb.NewDataLiteral<ui32>(56)
+ });
+ const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
+ });
+
+ const auto pgmReturn = pb.Zip({list1, list2});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto list = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 2U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).GetElement(0).template Get<ui32>(), 34);
+ UNBOXED_VALUE_STR_EQUAL(list.GetElement(0).GetElement(1), "Q");
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).GetElement(0).template Get<ui32>(), 56);
+ UNBOXED_VALUE_STR_EQUAL(list.GetElement(1).GetElement(1), "E");
}
Y_UNIT_TEST_LLVM(TestZipLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
- pb.NewDataLiteral<ui32>(34),
- pb.NewDataLiteral<ui32>(56)
- });
- const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
- pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
- });
-
- const auto pgmReturn = pb.Zip({pb.LazyList(list1), list2});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
+ pb.NewDataLiteral<ui32>(34),
+ pb.NewDataLiteral<ui32>(56)
+ });
+ const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
+ });
+
+ const auto pgmReturn = pb.Zip({pb.LazyList(list1), list2});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 34);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "Q");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "Q");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 56);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestZipAll) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
- pb.NewDataLiteral<ui32>(34),
- pb.NewDataLiteral<ui32>(56)
- });
- const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
- pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
- });
-
- const auto pgmReturn = pb.ZipAll({list1, list2});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto list = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).GetElement(0).template Get<ui32>(), 34);
- UNBOXED_VALUE_STR_EQUAL(list.GetElement(0).GetElement(1), "Q");
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).GetElement(0).template Get<ui32>(), 56);
- UNBOXED_VALUE_STR_EQUAL(list.GetElement(1).GetElement(1), "E");
- UNIT_ASSERT(!list.GetElement(2).GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(list.GetElement(2).GetElement(1), "W");
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
+ pb.NewDataLiteral<ui32>(34),
+ pb.NewDataLiteral<ui32>(56)
+ });
+ const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
+ });
+
+ const auto pgmReturn = pb.ZipAll({list1, list2});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto list = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).GetElement(0).template Get<ui32>(), 34);
+ UNBOXED_VALUE_STR_EQUAL(list.GetElement(0).GetElement(1), "Q");
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).GetElement(0).template Get<ui32>(), 56);
+ UNBOXED_VALUE_STR_EQUAL(list.GetElement(1).GetElement(1), "E");
+ UNIT_ASSERT(!list.GetElement(2).GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(list.GetElement(2).GetElement(1), "W");
}
Y_UNIT_TEST_LLVM(TestZipAllLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
- pb.NewDataLiteral<ui32>(34),
- pb.NewDataLiteral<ui32>(56)
- });
- const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
- pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
- });
-
- const auto pgmReturn = pb.ZipAll({list1, pb.LazyList(list2)});
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {
+ pb.NewDataLiteral<ui32>(34),
+ pb.NewDataLiteral<ui32>(56)
+ });
+ const auto list2 = pb.NewList(pb.NewDataType(NUdf::TDataType<char*>::Id), {
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("Q"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("E"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("W")
+ });
+
+ const auto pgmReturn = pb.ZipAll({list1, pb.LazyList(list2)});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 34);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "Q");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "Q");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 56);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "W");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "W");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestReduce) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto empty = pb.AddMember(pb.AddMember(
- pb.NewEmptyStruct(), "Min", pb.NewEmptyOptional(dataType)),
- "Max", pb.NewEmptyOptional(dataType));
- const auto pgmReturn = pb.Reduce(list, empty,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto empty = pb.AddMember(pb.AddMember(
+ pb.NewEmptyStruct(), "Min", pb.NewEmptyOptional(dataType)),
+ "Max", pb.NewEmptyOptional(dataType));
+ const auto pgmReturn = pb.Reduce(list, empty,
[&](TRuntimeNode item, TRuntimeNode state1) {
- return pb.AddMember(
- pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), item)),
- "Max", pb.AggrMax(pb.Member(state1, "Max"), item)
- );
+ return pb.AddMember(
+ pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), item)),
+ "Max", pb.AggrMax(pb.Member(state1, "Max"), item)
+ );
},
[&](TRuntimeNode state) {
return state;
}, empty,
- [&](TRuntimeNode state1, TRuntimeNode state2) {
- return pb.AddMember(
- pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), pb.Member(state2, "Min")))
- , "Max", pb.AggrMax(pb.Member(state1, "Max"), pb.Member(state2, "Max"))
- );
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
+ [&](TRuntimeNode state1, TRuntimeNode state2) {
+ return pb.AddMember(
+ pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), pb.Member(state2, "Min")))
+ , "Max", pb.AggrMax(pb.Member(state1, "Max"), pb.Member(state2, "Max"))
+ );
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1).template Get<ui32>(), 1);
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0).template Get<ui32>(), 3);
}
Y_UNIT_TEST_LLVM(TestReduceOverStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto empty = pb.AddMember(pb.AddMember(
- pb.NewEmptyStruct(), "Min", pb.NewEmptyOptional(dataType)),
- "Max", pb.NewEmptyOptional(dataType));
- const auto pgmReturn = pb.Reduce(pb.Iterator(list, {}), empty,
- [&](TRuntimeNode item, TRuntimeNode state1) {
- return pb.AddMember(
- pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), item)),
- "Max", pb.AggrMax(pb.Member(state1, "Max"), item)
- );
- },
- [&](TRuntimeNode state) {
- return state;
- }, empty,
- [&](TRuntimeNode state1, TRuntimeNode state2) {
- return pb.AddMember(
- pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), pb.Member(state2, "Min")))
- , "Max", pb.AggrMax(pb.Member(state1, "Max"), pb.Member(state2, "Max"))
- );
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto empty = pb.AddMember(pb.AddMember(
+ pb.NewEmptyStruct(), "Min", pb.NewEmptyOptional(dataType)),
+ "Max", pb.NewEmptyOptional(dataType));
+ const auto pgmReturn = pb.Reduce(pb.Iterator(list, {}), empty,
+ [&](TRuntimeNode item, TRuntimeNode state1) {
+ return pb.AddMember(
+ pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), item)),
+ "Max", pb.AggrMax(pb.Member(state1, "Max"), item)
+ );
+ },
+ [&](TRuntimeNode state) {
+ return state;
+ }, empty,
+ [&](TRuntimeNode state1, TRuntimeNode state2) {
+ return pb.AddMember(
+ pb.AddMember(pb.NewEmptyStruct(), "Min", pb.AggrMin(pb.Member(state1, "Min"), pb.Member(state2, "Min")))
+ , "Max", pb.AggrMax(pb.Member(state1, "Max"), pb.Member(state2, "Max"))
+ );
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1).template Get<ui32>(), 1);
UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0).template Get<ui32>(), 3);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestListLength) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto pgmReturn = pb.Length(list);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto pgmReturn = pb.Length(list);
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().template Get<ui64>(), 2);
}
Y_UNIT_TEST_LLVM(TestReverse) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto pgmReturn = pb.Reverse(list);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto pgmReturn = pb.Reverse(list);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestSkipForAppend) {
const ui32 n = 100;
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
for (ui32 i = 0; i < n; ++i) {
- auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
for (ui32 j = 0; j < n; ++j) {
- list = pb.Append(list, pb.NewDataLiteral(j));
+ list = pb.Append(list, pb.NewDataLiteral(j));
}
- const auto skippedList = pb.Skip(list, pb.NewDataLiteral<ui64>(i));
+ const auto skippedList = pb.Skip(list, pb.NewDataLiteral<ui64>(i));
auto changedList = skippedList;
for (ui32 j = 0; j < n; ++j) {
- changedList = pb.Prepend(pb.NewDataLiteral(n + n - 1 - j), changedList);
+ changedList = pb.Prepend(pb.NewDataLiteral(n + n - 1 - j), changedList);
}
- auto pgmReturn = pb.NewEmptyList(list.GetStaticType());
- pgmReturn = pb.Append(pgmReturn, list);
- pgmReturn = pb.Append(pgmReturn, skippedList);
- pgmReturn = pb.Append(pgmReturn, changedList);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iteratorLists = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue test, item;
-
- UNIT_ASSERT(iteratorLists.Next(test));
- auto iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ auto pgmReturn = pb.NewEmptyList(list.GetStaticType());
+ pgmReturn = pb.Append(pgmReturn, list);
+ pgmReturn = pb.Append(pgmReturn, skippedList);
+ pgmReturn = pb.Append(pgmReturn, changedList);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iteratorLists = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue test, item;
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ auto iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = i; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = i; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j + n);
- }
-
- for (ui32 j = i; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ for (ui32 j = i; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iteratorLists.Next(test));
- UNIT_ASSERT(!iteratorLists.Next(test));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iteratorLists.Next(test));
+ UNIT_ASSERT(!iteratorLists.Next(test));
}
}
Y_UNIT_TEST_LLVM(TestSkipForPrepend) {
const ui32 n = 100;
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
for (ui32 i = 0; i < n; ++i) {
- auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
for (ui32 j = 0; j < n; ++j) {
- list = pb.Prepend(pb.NewDataLiteral(n - 1 - j), list);
+ list = pb.Prepend(pb.NewDataLiteral(n - 1 - j), list);
}
- const auto skippedList = pb.Skip(list, pb.NewDataLiteral<ui64>(i));
+ const auto skippedList = pb.Skip(list, pb.NewDataLiteral<ui64>(i));
auto changedList = skippedList;
for (ui32 j = 0; j < n; ++j) {
- changedList = pb.Prepend(pb.NewDataLiteral(n + n - 1 - j), changedList);
+ changedList = pb.Prepend(pb.NewDataLiteral(n + n - 1 - j), changedList);
}
- const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
+ const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iteratorLists = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue test, item;
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iteratorLists = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue test, item;
-
- UNIT_ASSERT(iteratorLists.Next(test));
- auto iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iteratorLists.Next(test));
+ auto iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = i; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = i; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j + n);
- }
-
- for (ui32 j = i; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ for (ui32 j = i; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iteratorLists.Next(test));
- UNIT_ASSERT(!iteratorLists.Next(test));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iteratorLists.Next(test));
+ UNIT_ASSERT(!iteratorLists.Next(test));
}
}
Y_UNIT_TEST_LLVM(TestTakeForAppend) {
const ui32 n = 100;
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
for (ui32 i = 0; i < n; ++i) {
- auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
for (ui32 j = 0; j < n; ++j) {
- list = pb.Append(list, pb.NewDataLiteral(j));
+ list = pb.Append(list, pb.NewDataLiteral(j));
}
- const auto skippedList = pb.Take(list, pb.NewDataLiteral<ui64>(i));
+ const auto skippedList = pb.Take(list, pb.NewDataLiteral<ui64>(i));
auto changedList = skippedList;
for (ui32 j = 0; j < n; ++j) {
- changedList = pb.Append(changedList, pb.NewDataLiteral(n + j));
+ changedList = pb.Append(changedList, pb.NewDataLiteral(n + j));
}
- const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
+ const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iteratorLists = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue test, item;
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iteratorLists = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue test, item;
-
- UNIT_ASSERT(iteratorLists.Next(test));
- auto iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iteratorLists.Next(test));
+ auto iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < i; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < i; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < i; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < i; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j + n);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iteratorLists.Next(test));
- UNIT_ASSERT(!iteratorLists.Next(test));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iteratorLists.Next(test));
+ UNIT_ASSERT(!iteratorLists.Next(test));
}
}
Y_UNIT_TEST_LLVM(TestTakeForPrepend) {
const ui32 n = 100;
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
for (ui32 i = 0; i < n; ++i) {
- auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ auto list = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
for (ui32 j = 0; j < n; ++j) {
- list = pb.Prepend(pb.NewDataLiteral(n - 1- j), list);
+ list = pb.Prepend(pb.NewDataLiteral(n - 1- j), list);
}
- const auto skippedList = pb.Take(list, pb.NewDataLiteral<ui64>(i));
+ const auto skippedList = pb.Take(list, pb.NewDataLiteral<ui64>(i));
auto changedList = skippedList;
for (ui32 j = 0; j < n; ++j) {
- changedList = pb.Append(changedList, pb.NewDataLiteral(n + j));
+ changedList = pb.Append(changedList, pb.NewDataLiteral(n + j));
}
- const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
+ const auto pgmReturn = pb.NewList(list.GetStaticType(), {list, skippedList, changedList});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iteratorLists = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue test, item;
-
- UNIT_ASSERT(iteratorLists.Next(test));
- auto iterator = test.GetListIterator();
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iteratorLists = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue test, item;
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ auto iterator = test.GetListIterator();
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < i; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < i; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
- UNIT_ASSERT(iteratorLists.Next(test));
- iterator = test.GetListIterator();
- for (ui32 j = 0; j < i; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
+ UNIT_ASSERT(iteratorLists.Next(test));
+ iterator = test.GetListIterator();
+ for (ui32 j = 0; j < i; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j);
- }
-
- for (ui32 j = 0; j < n; ++j) {
- UNIT_ASSERT(iterator.Next(item));
+ }
+
+ for (ui32 j = 0; j < n; ++j) {
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), j + n);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iteratorLists.Next(test));
- UNIT_ASSERT(!iteratorLists.Next(test));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iteratorLists.Next(test));
+ UNIT_ASSERT(!iteratorLists.Next(test));
}
}
Y_UNIT_TEST_LLVM(TestReplicate) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto pgmReturn = pb.Replicate(pb.NewDataLiteral<ui32>(34),
+ const auto pgmReturn = pb.Replicate(pb.NewDataLiteral<ui32>(34),
pb.NewDataLiteral<ui64>(4), "", 0, 0);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
for (ui32 i = 0; i < 4; ++i) {
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIntegralCasts) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(258);
- const auto pgmReturn = pb.Convert(data1, pb.NewDataType(NUdf::TDataType<ui8>::Id));
+ const auto data1 = pb.NewDataLiteral<ui32>(258);
+ const auto pgmReturn = pb.Convert(data1, pb.NewDataType(NUdf::TDataType<ui8>::Id));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<ui8>();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<ui8>();
UNIT_ASSERT_VALUES_EQUAL(res, 2);
}
Y_UNIT_TEST_LLVM(TestCastFourIntoTrue) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(4);
- const auto pgmReturn = pb.Convert(data1, pb.NewDataType(NUdf::TDataType<bool>::Id));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<bool>();
- UNIT_ASSERT(res);
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(4);
+ const auto pgmReturn = pb.Convert(data1, pb.NewDataType(NUdf::TDataType<bool>::Id));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<bool>();
+ UNIT_ASSERT(res);
+ }
+
Y_UNIT_TEST_LLVM(TestSubstring) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aabbccc");
- const auto start1 = pb.NewDataLiteral<ui32>(3);
- const auto count1 = pb.NewDataLiteral<ui32>(2);
- const auto start2 = pb.NewDataLiteral<ui32>(4);
- const auto count2 = pb.NewDataLiteral<ui32>(10);
- const auto start3 = pb.NewDataLiteral<ui32>(10);
- const auto count3 = pb.NewDataLiteral<ui32>(1);
- const auto start4 = pb.NewDataLiteral<ui32>(0);
- const auto count4 = pb.NewDataLiteral<ui32>(3);
-
- const auto dataType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<ui32>::Id)});
- const auto list = pb.NewList(dataType, {
- pb.NewTuple({start1, count1}),
- pb.NewTuple({start2, count2}),
- pb.NewTuple({start3, count3}),
- pb.NewTuple({start4, count4})
- });
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Substring(data1, pb.Nth(item, 0), pb.Nth(item, 1));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "bc");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "ccc");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "aab");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSubstringOptionalArgs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto null = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789"));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("abcdefghijklmnopqrstuvwxyz"));
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<const char*>::Id));
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Substring(item, null, null),
- pb.Substring(item, pb.NewOptional(pb.NewDataLiteral<ui32>(7U)), null),
- pb.Substring(item, null, pb.NewOptional(pb.NewDataLiteral<ui32>(6U))),
- pb.Substring(item, pb.NewOptional(pb.NewDataLiteral<ui32>(3U)), pb.NewOptional(pb.NewDataLiteral<ui32>(17U)))
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT(!item.GetElement(1U));
- UNIT_ASSERT(!item.GetElement(2U));
- UNIT_ASSERT(!item.GetElement(3U));
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "0123456789");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "789");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "012345");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "3456789");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "abcdefghijklmnopqrstuvwxyz");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "hijklmnopqrstuvwxyz");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "abcdef");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "defghijklmnopqrst");
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFindAndSubstring) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<const char*>::Id));
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("_/>_/>aab*SEP*bccc"));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("*SEP*_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc*SEP*"));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("(none)"));
-
- const auto sep1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
- const auto sep2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("_/>");
- const auto sep3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("*SEP*");
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<const char*>::Id), {sep1, sep2, sep3});
- const auto null = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
-
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode data) {
- return pb.Map(list1,
- [&](TRuntimeNode sep) {
- const auto first = pb.Find(data, sep, null);
- const auto last = pb.RFind(data, sep, null);
- const auto len = pb.Size(sep);
- return pb.NewTuple({
- pb.Substring(data, null, first),
- pb.Substring(data, pb.Add(first, len), pb.If(pb.Less(first, last), pb.Sub(last, pb.Add(first, len)), pb.NewDataLiteral<ui32>(0U))),
- pb.Substring(data, pb.Add(last, len), null)
- });
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT(!item.GetElement(1U));
- UNIT_ASSERT(!item.GetElement(2U));
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT(!item.GetElement(1U));
- UNIT_ASSERT(!item.GetElement(2U));
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT(!item.GetElement(1U));
- UNIT_ASSERT(!item.GetElement(2U));
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "_/>_/>aab*SEP*bccc");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "aab*SEP*bccc");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "_/>_/>aab");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "bccc");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "*SEP*_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc*SEP*");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "*SEP*");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "a>><<___*SEP*a_/>b54b*SEP*c");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "3434cc*SEP*");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "(none)");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "(none)");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "(none)");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "(none)");
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFindFromPos) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<NUdf::EDataSlot::String>("_</|>0123456789</|></|>abcxyz</|>*");
- const auto sep = pb.NewDataLiteral<NUdf::EDataSlot::String>("</|>");
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui32>(0U), pb.Size(data), pb.NewDataLiteral<ui32>(2U));
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Find(data, sep, item), pb.RFind(data, sep, item)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 1U);
- UNIT_ASSERT(!item.GetElement(1U));
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 19U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 15U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 19U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 15U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 29U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0U));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 29U);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestListFromRange) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui16>(0);
- const auto data1 = pb.NewDataLiteral<ui16>(9);
- const auto data2 = pb.NewDataLiteral<ui16>(1);
- const auto data3 = pb.NewDataLiteral<ui16>(2);
- const auto data4 = pb.NewDataLiteral<ui16>(3);
-
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui16>::Id), {data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- const auto l = pb.ListFromRange(data0, data1, item);
- return pb.NewTuple({pb.HasItems(l), pb.Length(l), pb.Head(l), pb.Last(l)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 9ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 8U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 5ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 8U);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 3ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 6U);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aabbccc");
+ const auto start1 = pb.NewDataLiteral<ui32>(3);
+ const auto count1 = pb.NewDataLiteral<ui32>(2);
+ const auto start2 = pb.NewDataLiteral<ui32>(4);
+ const auto count2 = pb.NewDataLiteral<ui32>(10);
+ const auto start3 = pb.NewDataLiteral<ui32>(10);
+ const auto count3 = pb.NewDataLiteral<ui32>(1);
+ const auto start4 = pb.NewDataLiteral<ui32>(0);
+ const auto count4 = pb.NewDataLiteral<ui32>(3);
+
+ const auto dataType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<ui32>::Id)});
+ const auto list = pb.NewList(dataType, {
+ pb.NewTuple({start1, count1}),
+ pb.NewTuple({start2, count2}),
+ pb.NewTuple({start3, count3}),
+ pb.NewTuple({start4, count4})
+ });
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Substring(data1, pb.Nth(item, 0), pb.Nth(item, 1));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "bc");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "ccc");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "aab");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSubstringOptionalArgs) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto null = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("0123456789"));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("abcdefghijklmnopqrstuvwxyz"));
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<const char*>::Id));
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Substring(item, null, null),
+ pb.Substring(item, pb.NewOptional(pb.NewDataLiteral<ui32>(7U)), null),
+ pb.Substring(item, null, pb.NewOptional(pb.NewDataLiteral<ui32>(6U))),
+ pb.Substring(item, pb.NewOptional(pb.NewDataLiteral<ui32>(3U)), pb.NewOptional(pb.NewDataLiteral<ui32>(17U)))
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT(!item.GetElement(1U));
+ UNIT_ASSERT(!item.GetElement(2U));
+ UNIT_ASSERT(!item.GetElement(3U));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "0123456789");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "789");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "012345");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "3456789");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "abcdefghijklmnopqrstuvwxyz");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "hijklmnopqrstuvwxyz");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "abcdef");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(3U), "defghijklmnopqrst");
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFindAndSubstring) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<const char*>::Id));
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("_/>_/>aab*SEP*bccc"));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("*SEP*_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc*SEP*"));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("(none)"));
+
+ const auto sep1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+ const auto sep2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("_/>");
+ const auto sep3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("*SEP*");
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<const char*>::Id), {sep1, sep2, sep3});
+ const auto null = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id);
+
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode data) {
+ return pb.Map(list1,
+ [&](TRuntimeNode sep) {
+ const auto first = pb.Find(data, sep, null);
+ const auto last = pb.RFind(data, sep, null);
+ const auto len = pb.Size(sep);
+ return pb.NewTuple({
+ pb.Substring(data, null, first),
+ pb.Substring(data, pb.Add(first, len), pb.If(pb.Less(first, last), pb.Sub(last, pb.Add(first, len)), pb.NewDataLiteral<ui32>(0U))),
+ pb.Substring(data, pb.Add(last, len), null)
+ });
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT(!item.GetElement(1U));
+ UNIT_ASSERT(!item.GetElement(2U));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT(!item.GetElement(1U));
+ UNIT_ASSERT(!item.GetElement(2U));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT(!item.GetElement(1U));
+ UNIT_ASSERT(!item.GetElement(2U));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "_/>_/>aab*SEP*bccc");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "aab*SEP*bccc");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "_/>_/>aab");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "bccc");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "*SEP*_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc*SEP*");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "*SEP*");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "a>><<___*SEP*a_/>b54b*SEP*c");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "3434cc*SEP*");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "_/>a>><<___*SEP*a_/>b54b*SEP*c_/>3434cc");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "(none)");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "(none)");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0U), "(none)");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1U), "(none)");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(2U), "(none)");
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFindFromPos) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<NUdf::EDataSlot::String>("_</|>0123456789</|></|>abcxyz</|>*");
+ const auto sep = pb.NewDataLiteral<NUdf::EDataSlot::String>("</|>");
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui32>(0U), pb.Size(data), pb.NewDataLiteral<ui32>(2U));
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Find(data, sep, item), pb.RFind(data, sep, item)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 1U);
+ UNIT_ASSERT(!item.GetElement(1U));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 15U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 1U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 19U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 15U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 19U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 15U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui32>(), 29U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 19U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 29U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0U));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui32>(), 29U);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestListFromRange) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui16>(0);
+ const auto data1 = pb.NewDataLiteral<ui16>(9);
+ const auto data2 = pb.NewDataLiteral<ui16>(1);
+ const auto data3 = pb.NewDataLiteral<ui16>(2);
+ const auto data4 = pb.NewDataLiteral<ui16>(3);
+
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui16>::Id), {data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ const auto l = pb.ListFromRange(data0, data1, item);
+ return pb.NewTuple({pb.HasItems(l), pb.Length(l), pb.Head(l), pb.Last(l)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 9ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 8U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 5ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 8U);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0U).template Get<bool>());
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<ui64>(), 3ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2U).template Get<ui16>(), 0U);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(3U).template Get<ui16>(), 6U);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestSize) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aaa");
- const auto data2 = pb.NewDataLiteral<ui32>(3);
- const auto data3 = pb.NewDataLiteral<ui64>(7878786987536ull);
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("qqqqq");
- const auto pgmReturn = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.Size(data1), pb.Size(data2), pb.Size(data3), pb.Size(data4)});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aaa");
+ const auto data2 = pb.NewDataLiteral<ui32>(3);
+ const auto data3 = pb.NewDataLiteral<ui64>(7878786987536ull);
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("qqqqq");
+ const auto pgmReturn = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.Size(data1), pb.Size(data2), pb.Size(data3), pb.Size(data4)});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 8);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 5);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestEnumerate) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto pgmReturn = pb.Enumerate(list1);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto pgmReturn = pb.Enumerate(list1);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 0);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 1);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestEnumerateLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto pgmReturn = pb.Enumerate(pb.LazyList(list1));
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto pgmReturn = pb.Enumerate(pb.LazyList(list1));
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 0);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 34);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 1);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestEnumerateLazyThenReverse) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto pgmReturn = pb.Reverse(pb.Enumerate(pb.LazyList(list1)));
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto pgmReturn = pb.Reverse(pb.Enumerate(pb.LazyList(list1)));
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 1);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 56);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 0);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestEnumerateLazyThenSkip) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto one = pb.NewDataLiteral<ui64>(1);
- const auto list = pb.Enumerate(pb.LazyList(list1));
- const auto skip = pb.Skip(list, one);
- const auto pgmReturn = pb.NewTuple({skip, pb.Length(list), pb.Length(skip)});
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetElement(0).GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto one = pb.NewDataLiteral<ui64>(1);
+ const auto list = pb.Enumerate(pb.LazyList(list1));
+ const auto skip = pb.Skip(list, one);
+ const auto pgmReturn = pb.NewTuple({skip, pb.Length(list), pb.Length(skip)});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetElement(0).GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 1);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 56);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(1).template Get<ui64>(), 2);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(2).template Get<ui64>(), 1);
}
Y_UNIT_TEST_LLVM(TestEnumerateLazyThenTake) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
- {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
- const auto one = pb.NewDataLiteral<ui64>(1);
- const auto list = pb.Enumerate(pb.LazyList(list1));
- const auto take = pb.Take(list, one);
- const auto pgmReturn = pb.NewTuple({take, pb.Length(list), pb.Length(take)});
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetElement(0).GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list1 = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ {pb.NewDataLiteral<ui32>(34), pb.NewDataLiteral<ui32>(56)});
+ const auto one = pb.NewDataLiteral<ui64>(1);
+ const auto list = pb.Enumerate(pb.LazyList(list1));
+ const auto take = pb.Take(list, one);
+ const auto pgmReturn = pb.NewTuple({take, pb.Length(list), pb.Length(take)});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetElement(0).GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 0);
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(1).template Get<ui64>(), 2);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(2).template Get<ui64>(), 1);
}
- template<bool LLVM>
+ template<bool LLVM>
void TestSortImpl(bool asc) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(3);
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aaa");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("qqq");
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aaa");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("qqq");
- const auto keyType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto payloadType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- auto structType = pb.NewEmptyStructType();
- structType = pb.NewStructType(structType, "payload", payloadType);
- structType = pb.NewStructType(structType, "key", keyType);
+ const auto keyType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto payloadType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ auto structType = pb.NewEmptyStructType();
+ structType = pb.NewStructType(structType, "payload", payloadType);
+ structType = pb.NewStructType(structType, "key", keyType);
- std::vector<std::pair<std::string_view, TRuntimeNode>> map1 = {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> map1 = {
{ "key", key1 },
{ "payload", payload1 }
};
- std::vector<std::pair<std::string_view, TRuntimeNode>> map2 = {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> map2 = {
{ "key", key2 },
{ "payload", payload2 }
};
- std::vector<std::pair<std::string_view, TRuntimeNode>> map3 = {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> map3 = {
{ "key", key3 },
{ "payload", payload3 }
};
- const auto list = pb.NewList(structType, {
- pb.NewStruct(map2),
- pb.NewStruct(map1),
- pb.NewStruct(map3)
- });
+ const auto list = pb.NewList(structType, {
+ pb.NewStruct(map2),
+ pb.NewStruct(map1),
+ pb.NewStruct(map3)
+ });
{
- const auto pgmReturn = pb.Sort(list, pb.NewDataLiteral(asc),
+ const auto pgmReturn = pb.Sort(list, pb.NewDataLiteral(asc),
[&](TRuntimeNode item) {
- return pb.Member(item, "key");
+ return pb.Member(item, "key");
});
if (asc) {
// ascending sort
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "aaa");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "aaa");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "qqq");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "qqq");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
} else {
// descending sort
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 3);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "qqq");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "qqq");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "");
- UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "");
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "aaa");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "aaa");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
}
}
Y_UNIT_TEST_LLVM(TestSort) {
- TestSortImpl<LLVM>(true);
- TestSortImpl<LLVM>(false);
+ TestSortImpl<LLVM>(true);
+ TestSortImpl<LLVM>(false);
}
using TTriple = std::tuple<ui32, ui32, ui32>;
- TRuntimeNode TupleOrder(TProgramBuilder& pb, bool asc1, bool asc2, bool asc3) {
+ TRuntimeNode TupleOrder(TProgramBuilder& pb, bool asc1, bool asc2, bool asc3) {
TVector<TRuntimeNode> ascending(3);
- ascending[0] = pb.NewDataLiteral(asc1);
- ascending[1] = pb.NewDataLiteral(asc2);
- ascending[2] = pb.NewDataLiteral(asc3);
+ ascending[0] = pb.NewDataLiteral(asc1);
+ ascending[1] = pb.NewDataLiteral(asc2);
+ ascending[2] = pb.NewDataLiteral(asc3);
TVector<TType*> tupleTypes(3);
- tupleTypes[0] = pb.NewDataType(NUdf::TDataType<bool>::Id);
- tupleTypes[1] = pb.NewDataType(NUdf::TDataType<bool>::Id);
- tupleTypes[2] = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ tupleTypes[0] = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ tupleTypes[1] = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ tupleTypes[2] = pb.NewDataType(NUdf::TDataType<bool>::Id);
- return pb.NewTuple(pb.NewTupleType(tupleTypes), ascending);
+ return pb.NewTuple(pb.NewTupleType(tupleTypes), ascending);
}
- template<bool LLVM>
+ template<bool LLVM>
TVector<TTriple> SortTuples(TSetup<LLVM>& setup, TRuntimeNode list, TRuntimeNode order)
{
- auto& pb = *setup.PgmBuilder;
- const auto pgmReturn = pb.Sort(list, order, [](TRuntimeNode item) { return item; });
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
+ auto& pb = *setup.PgmBuilder;
+ const auto pgmReturn = pb.Sort(list, order, [](TRuntimeNode item) { return item; });
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
TVector<TTriple> result;
- for (NUdf::TUnboxedValue value; iterator.Next(value);) {
- ui32 first = value.GetElement(0).template Get<ui32>();
- ui32 second = value.GetElement(1).template Get<ui32>();
- ui32 third = value.GetElement(2).template Get<ui32>();
+ for (NUdf::TUnboxedValue value; iterator.Next(value);) {
+ ui32 first = value.GetElement(0).template Get<ui32>();
+ ui32 second = value.GetElement(1).template Get<ui32>();
+ ui32 third = value.GetElement(2).template Get<ui32>();
result.push_back(TTriple{ first, second, third });
}
- UNIT_ASSERT(!iterator.Skip());
+ UNIT_ASSERT(!iterator.Skip());
return result;
}
Y_UNIT_TEST_LLVM(TestSortTuples) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto listMaker = [&]()
+ const auto listMaker = [&]()
{
TTriple testData[] = {
{ 1, 1, 1 },
@@ -4059,22 +4059,22 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
TVector<TRuntimeNode> tuplesList;
for (ui32 i = 0; i < Y_ARRAY_SIZE(testData); i++) {
TVector<TRuntimeNode> elements(3);
- elements[0] = pb.NewDataLiteral(std::get<0>(testData[i]));
- elements[1] = pb.NewDataLiteral(std::get<1>(testData[i]));
- elements[2] = pb.NewDataLiteral(std::get<2>(testData[i]));
- tuplesList.push_back(pb.NewTuple(elements));
+ elements[0] = pb.NewDataLiteral(std::get<0>(testData[i]));
+ elements[1] = pb.NewDataLiteral(std::get<1>(testData[i]));
+ elements[2] = pb.NewDataLiteral(std::get<2>(testData[i]));
+ tuplesList.push_back(pb.NewTuple(elements));
}
TVector<TType*> tupleTypes(3);
- tupleTypes[0] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- tupleTypes[1] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- tupleTypes[2] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ tupleTypes[0] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ tupleTypes[1] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ tupleTypes[2] = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- return pb.NewList(pb.NewTupleType(tupleTypes), tuplesList);
+ return pb.NewList(pb.NewTupleType(tupleTypes), tuplesList);
};
{
- TRuntimeNode order = TupleOrder(pb, true, true, true);
+ TRuntimeNode order = TupleOrder(pb, true, true, true);
TTriple expectedData[] = {
{ 1, 1, 1 },
{ 1, 1, 2 },
@@ -4089,7 +4089,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
}
{
- TRuntimeNode order = TupleOrder(pb, false, false, false);
+ TRuntimeNode order = TupleOrder(pb, false, false, false);
TTriple expectedData[] = {
{ 2, 1, 0 },
{ 2, 0, 1 },
@@ -4104,7 +4104,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
}
{
- TRuntimeNode order = TupleOrder(pb, true, false, true);
+ TRuntimeNode order = TupleOrder(pb, true, false, true);
TTriple expectedData[] = {
{ 1, 3, 0 },
{ 1, 2, 3 },
@@ -4119,7 +4119,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
}
{
- TRuntimeNode order = TupleOrder(pb, false, true, false);
+ TRuntimeNode order = TupleOrder(pb, false, true, false);
TTriple expectedData[] = {
{ 2, 0, 1 },
{ 2, 1, 0 },
@@ -4135,395 +4135,395 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
}
Y_UNIT_TEST_LLVM(TestAsList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto pgmReturn = pb.AsList(pb.NewDataLiteral<ui32>(34));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto pgmReturn = pb.AsList(pb.NewDataLiteral<ui32>(34));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestListIfTrue) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto pgmReturn = pb.ListIf(pb.NewDataLiteral(true),
- pb.NewDataLiteral<ui32>(34));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto pgmReturn = pb.ListIf(pb.NewDataLiteral(true),
+ pb.NewDataLiteral<ui32>(34));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 34);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestListIfFalse) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto pgmReturn = pb.ListIf(pb.NewDataLiteral(false),
- pb.NewDataLiteral<ui32>(34));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- UNIT_ASSERT(!iterator.Skip());
- UNIT_ASSERT(!iterator.Skip());
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto pgmReturn = pb.ListIf(pb.NewDataLiteral(false),
+ pb.NewDataLiteral<ui32>(34));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ UNIT_ASSERT(!iterator.Skip());
+ UNIT_ASSERT(!iterator.Skip());
}
Y_UNIT_TEST_LLVM(TestNth) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const auto element0 = pb.NewDataLiteral<ui32>(34);
- const auto element1 = pb.NewDataLiteral<ui32>(56);
- const auto tuple = pb.NewTuple({element0, element1});
- const auto pgmReturn = pb.Nth(tuple, 1);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue().template Get<ui32>();
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const auto element0 = pb.NewDataLiteral<ui32>(34);
+ const auto element1 = pb.NewDataLiteral<ui32>(56);
+ const auto tuple = pb.NewTuple({element0, element1});
+ const auto pgmReturn = pb.Nth(tuple, 1);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(res, 56);
}
Y_UNIT_TEST_LLVM(NonDeterministicEnv) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<float>(1);
- const auto data2 = pb.NewDataLiteral<float>(2);
- const auto data3 = pb.NewDataLiteral<float>(3);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<float>::Id), {data1, data2, data3});
- const auto pgmReturn = pb.Sort(list,
- pb.NewDataLiteral(false),
- [](TRuntimeNode item) { return item; }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::abs(item.template Get<float>() - 3.0) < 0.001);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::abs(item.template Get<float>() - 2.0) < 0.001);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::abs(item.template Get<float>() - 1.0) < 0.001);
- UNIT_ASSERT(false == iterator.Next(item));
- UNIT_ASSERT(false == iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<float>(1);
+ const auto data2 = pb.NewDataLiteral<float>(2);
+ const auto data3 = pb.NewDataLiteral<float>(3);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<float>::Id), {data1, data2, data3});
+ const auto pgmReturn = pb.Sort(list,
+ pb.NewDataLiteral(false),
+ [](TRuntimeNode item) { return item; }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::abs(item.template Get<float>() - 3.0) < 0.001);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::abs(item.template Get<float>() - 2.0) < 0.001);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::abs(item.template Get<float>() - 1.0) < 0.001);
+ UNIT_ASSERT(false == iterator.Next(item));
+ UNIT_ASSERT(false == iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIndexDictContains) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto item1 = pb.NewDataLiteral<ui32>(7);
- const auto item2 = pb.NewDataLiteral<ui32>(16);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
- const auto dict = pb.ToIndexDict(list);
- const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto key0 = pb.NewDataLiteral<ui64>(0);
- const auto key1 = pb.NewDataLiteral<ui64>(1);
- const auto key2 = pb.NewDataLiteral<ui64>(2);
- const auto keys = pb.NewList(type, {key0, key1, key2});
- const auto pgmReturn = pb.Map(keys,
- [&](TRuntimeNode key) { return pb.Contains(dict, key); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto item1 = pb.NewDataLiteral<ui32>(7);
+ const auto item2 = pb.NewDataLiteral<ui32>(16);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
+ const auto dict = pb.ToIndexDict(list);
+ const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto key0 = pb.NewDataLiteral<ui64>(0);
+ const auto key1 = pb.NewDataLiteral<ui64>(1);
+ const auto key2 = pb.NewDataLiteral<ui64>(2);
+ const auto keys = pb.NewList(type, {key0, key1, key2});
+ const auto pgmReturn = pb.Map(keys,
+ [&](TRuntimeNode key) { return pb.Contains(dict, key); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIndexDictLookup) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto item1 = pb.NewDataLiteral<i32>(7);
- const auto item2 = pb.NewDataLiteral<i32>(16);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<i32>::Id), {item1, item2});
- const auto dict = pb.ToIndexDict(list);
- const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto key0 = pb.NewDataLiteral<ui64>(0);
- const auto key1 = pb.NewDataLiteral<ui64>(1);
- const auto key2 = pb.NewDataLiteral<ui64>(2);
- const auto keys = pb.NewList(type, {key0, key1, key2});
- const auto pgmReturn = pb.Map(keys,
- [&](TRuntimeNode key) { return pb.Lookup(dict, key); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto item1 = pb.NewDataLiteral<i32>(7);
+ const auto item2 = pb.NewDataLiteral<i32>(16);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<i32>::Id), {item1, item2});
+ const auto dict = pb.ToIndexDict(list);
+ const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto key0 = pb.NewDataLiteral<ui64>(0);
+ const auto key1 = pb.NewDataLiteral<ui64>(1);
+ const auto key2 = pb.NewDataLiteral<ui64>(2);
+ const auto keys = pb.NewList(type, {key0, key1, key2});
+ const auto pgmReturn = pb.Map(keys,
+ [&](TRuntimeNode key) { return pb.Lookup(dict, key); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 16);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIndexDictContainsLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto item1 = pb.NewDataLiteral<ui32>(7);
- const auto item2 = pb.NewDataLiteral<ui32>(16);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
- const auto dict = pb.ToIndexDict(pb.LazyList(list));
- const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto key0 = pb.NewDataLiteral<ui64>(0);
- const auto key1 = pb.NewDataLiteral<ui64>(1);
- const auto key2 = pb.NewDataLiteral<ui64>(2);
- const auto keys = pb.NewList(type, {key0, key1, key2});
- const auto pgmReturn = pb.Map(keys,
- [&](TRuntimeNode key) { return pb.Contains(dict, key); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto item1 = pb.NewDataLiteral<ui32>(7);
+ const auto item2 = pb.NewDataLiteral<ui32>(16);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
+ const auto dict = pb.ToIndexDict(pb.LazyList(list));
+ const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto key0 = pb.NewDataLiteral<ui64>(0);
+ const auto key1 = pb.NewDataLiteral<ui64>(1);
+ const auto key2 = pb.NewDataLiteral<ui64>(2);
+ const auto keys = pb.NewList(type, {key0, key1, key2});
+ const auto pgmReturn = pb.Map(keys,
+ [&](TRuntimeNode key) { return pb.Contains(dict, key); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestIndexDictLookupLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto item1 = pb.NewDataLiteral<ui32>(7);
- const auto item2 = pb.NewDataLiteral<ui32>(16);
- const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
- const auto dict = pb.ToIndexDict(pb.LazyList(list));
- const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto key0 = pb.NewDataLiteral<ui64>(0);
- const auto key1 = pb.NewDataLiteral<ui64>(1);
- const auto key2 = pb.NewDataLiteral<ui64>(2);
- const auto keys = pb.NewList(type, {key0, key1, key2});
- const auto pgmReturn = pb.Map(keys,
- [&](TRuntimeNode key) { return pb.Lookup(dict, key); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto item1 = pb.NewDataLiteral<ui32>(7);
+ const auto item2 = pb.NewDataLiteral<ui32>(16);
+ const auto list = pb.NewList(pb.NewDataType(NUdf::TDataType<ui32>::Id), {item1, item2});
+ const auto dict = pb.ToIndexDict(pb.LazyList(list));
+ const auto type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto key0 = pb.NewDataLiteral<ui64>(0);
+ const auto key1 = pb.NewDataLiteral<ui64>(1);
+ const auto key2 = pb.NewDataLiteral<ui64>(2);
+ const auto keys = pb.NewList(type, {key0, key1, key2});
+ const auto pgmReturn = pb.Map(keys,
+ [&](TRuntimeNode key) { return pb.Lookup(dict, key); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 16);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToBytes) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto data1 = pb.NewDataLiteral(0.f);
- const auto data2 = pb.NewDataLiteral(-3.14f);
- const auto data3 = pb.NewDataLiteral(-HUGE_VALF);
- const auto data4 = pb.NewDataLiteral(HUGE_VALF);
- const auto list = pb.NewList(type, {data1, data2, data3, data4});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToBytes(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x00\x00");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\xc3\xf5\x48\xc0");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\xff");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\x7f");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToBytesOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id, true);
- const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral(0.f));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral(-3.14f));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral(-HUGE_VALF));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral(HUGE_VALF));
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToBytes(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x00\x00");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\xc3\xf5\x48\xc0");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\xff");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\x7f");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToStringTemporarryUtf8) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("long prefix ");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("01234567890 long string");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("01234567890 very long string");
- const auto list = pb.NewList(type, {data1, data2});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToString(pb.Concat(data0, item));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "long prefix 01234567890 long string");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "long prefix 01234567890 very long string");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToBytes) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto data1 = pb.NewDataLiteral(0.f);
+ const auto data2 = pb.NewDataLiteral(-3.14f);
+ const auto data3 = pb.NewDataLiteral(-HUGE_VALF);
+ const auto data4 = pb.NewDataLiteral(HUGE_VALF);
+ const auto list = pb.NewList(type, {data1, data2, data3, data4});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToBytes(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x00\x00");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\xc3\xf5\x48\xc0");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\xff");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\x7f");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToBytesOpt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id, true);
+ const auto data0 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral(0.f));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral(-3.14f));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral(-HUGE_VALF));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral(HUGE_VALF));
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToBytes(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x00\x00");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\xc3\xf5\x48\xc0");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\xff");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "\x00\x00\x80\x7f");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToStringTemporarryUtf8) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("long prefix ");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("01234567890 long string");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("01234567890 very long string");
+ const auto list = pb.NewList(type, {data1, data2});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToString(pb.Concat(data0, item));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "long prefix 01234567890 long string");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "long prefix 01234567890 very long string");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFromString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("234");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto list = pb.NewList(type, {data1, data2});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.FromString(item, pb.NewDataType(NUdf::TDataType<ui32>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("234");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto list = pb.NewList(type, {data1, data2});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.FromString(item, pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 234);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestStrictFromString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
TVector<TRuntimeNode> tupleItems;
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("234");
- tupleItems.push_back(pb.StrictFromString(data1, pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-1");
- tupleItems.push_back(pb.StrictFromString(data2, pb.NewDataType(NUdf::TDataType<i32>::Id)));
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("3.1415926");
- tupleItems.push_back(pb.StrictFromString(data3, pb.NewDataType(NUdf::TDataType<double>::Id)));
- const auto pgmReturn = pb.NewTuple(tupleItems);
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("234");
+ tupleItems.push_back(pb.StrictFromString(data1, pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-1");
+ tupleItems.push_back(pb.StrictFromString(data2, pb.NewDataType(NUdf::TDataType<i32>::Id)));
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("3.1415926");
+ tupleItems.push_back(pb.StrictFromString(data3, pb.NewDataType(NUdf::TDataType<double>::Id)));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
{
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 234);
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(1).template Get<i32>(), -1);
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(2).template Get<double>(), 3.1415926);
}
{
- const auto wrongData = pb.NewDataLiteral<NUdf::EDataSlot::String>("vgfsbhj");
- const auto fail = pb.StrictFromString(wrongData, pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto failgraph = setup.BuildGraph(fail, {});
+ const auto wrongData = pb.NewDataLiteral<NUdf::EDataSlot::String>("vgfsbhj");
+ const auto fail = pb.StrictFromString(wrongData, pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto failgraph = setup.BuildGraph(fail, {});
UNIT_ASSERT_EXCEPTION(failgraph->GetValue(), yexception);
}
{
- const auto wrongData = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
- const auto fail = pb.StrictFromString(wrongData, pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto failgraph = setup.BuildGraph(fail, {});
+ const auto wrongData = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+ const auto fail = pb.StrictFromString(wrongData, pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto failgraph = setup.BuildGraph(fail, {});
UNIT_ASSERT_EXCEPTION(failgraph->GetValue(), yexception);
}
}
Y_UNIT_TEST_LLVM(TestFromBytes) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
TVector<TRuntimeNode> tupleItems;
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>(TString("\xEA\x00\x00\x00", 4));
- tupleItems.push_back(pb.FromBytes(data1, NUdf::TDataType<ui32>::Id));
- const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
- tupleItems.push_back(pb.FromBytes(data2, NUdf::TDataType<ui32>::Id));
- const auto pgmReturn = pb.NewTuple(tupleItems);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNIT_ASSERT(res.GetElement(0));
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>(TString("\xEA\x00\x00\x00", 4));
+ tupleItems.push_back(pb.FromBytes(data1, NUdf::TDataType<ui32>::Id));
+ const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<const char*>::Id);
+ tupleItems.push_back(pb.FromBytes(data2, NUdf::TDataType<ui32>::Id));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNIT_ASSERT(res.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 234);
- UNIT_ASSERT(!res.GetElement(1));
+ UNIT_ASSERT(!res.GetElement(1));
}
Y_UNIT_TEST_LLVM(TestMTRand) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto seed = pb.NewDataLiteral<ui64>(42);
- auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui64>::Id));
- auto rnd = pb.NewMTRand(seed);
+ const auto seed = pb.NewDataLiteral<ui64>(42);
+ auto pgmReturn = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui64>::Id));
+ auto rnd = pb.NewMTRand(seed);
const ui32 n = 5;
const ui64 expectedValues[n] = {
13930160852258120406ull,
@@ -4533,392 +4533,392 @@ Y_UNIT_TEST_SUITE(TMiniKQLComputationNodeTest) {
16662371453428439381ull,
};
for (ui32 i = 0; i < n; ++i) {
- const auto pair = pb.NextMTRand(rnd);
- pgmReturn = pb.Append(pgmReturn, pb.Nth(pair, 0));
- rnd = pb.Nth(pair, 1);
+ const auto pair = pb.NextMTRand(rnd);
+ pgmReturn = pb.Append(pgmReturn, pb.Nth(pair, 0));
+ rnd = pb.Nth(pair, 1);
}
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
for (ui32 i = 0; i < n; ++i) {
- UNIT_ASSERT(iterator.Next(item));
- const ui64 value = item.template Get<ui64>();
- //Cout << value << Endl;
+ UNIT_ASSERT(iterator.Next(item));
+ const ui64 value = item.template Get<ui64>();
+ //Cout << value << Endl;
UNIT_ASSERT_VALUES_EQUAL(value, expectedValues[i]);
- }
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestRandom) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
const double expectedValue1 = 0.13387664401253274;
const ui64 expectedValue2 = 2516265689700432462;
- const auto rnd1 = pb.Random({});
- const auto rnd2 = pb.RandomNumber({});
+ const auto rnd1 = pb.Random({});
+ const auto rnd2 = pb.RandomNumber({});
TVector<TRuntimeNode> args;
args.push_back(rnd1);
args.push_back(rnd2);
- const auto pgmReturn = pb.NewTuple(args);
+ const auto pgmReturn = pb.NewTuple(args);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto tuple = graph->GetValue();
- UNIT_ASSERT_DOUBLES_EQUAL(tuple.GetElement(0).template Get<double>(), expectedValue1, 1e-3);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto tuple = graph->GetValue();
+ UNIT_ASSERT_DOUBLES_EQUAL(tuple.GetElement(0).template Get<double>(), expectedValue1, 1e-3);
UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).template Get<ui64>(), expectedValue2);
}
Y_UNIT_TEST_LLVM(TestNow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
const ui64 expectedValue = 10000000000000;
- const auto ts = pb.Now({});
+ const auto ts = pb.Now({});
TVector<TRuntimeNode> args;
args.push_back(ts);
- const auto pgmReturn = pb.NewTuple(args);
+ const auto pgmReturn = pb.NewTuple(args);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto tuple = graph->GetValue();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto tuple = graph->GetValue();
UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).template Get<ui64>(), expectedValue);
}
- Y_UNIT_TEST_LLVM(TestSkipAndTakeOverStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(2);
- const auto data3 = pb.NewDataLiteral<ui8>(3);
- const auto data4 = pb.NewDataLiteral<ui8>(4);
- const auto data5 = pb.NewDataLiteral<ui8>(5);
- const auto data6 = pb.NewDataLiteral<ui8>(6);
- const auto data7 = pb.NewDataLiteral<ui8>(7);
- const auto data8 = pb.NewDataLiteral<ui8>(8);
- const auto data9 = pb.NewDataLiteral<ui8>(9);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Take(pb.Skip(pb.Iterator(list, {}), pb.NewDataLiteral<ui64>(4ULL)), pb.NewDataLiteral<ui64>(3ULL));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 5);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 6);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipAndTakeOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<ui8>::Id);
- const auto data0 = pb.NewDataLiteral<ui8>(0);
- const auto data1 = pb.NewDataLiteral<ui8>(1);
- const auto data2 = pb.NewDataLiteral<ui8>(2);
- const auto data3 = pb.NewDataLiteral<ui8>(3);
- const auto data4 = pb.NewDataLiteral<ui8>(4);
- const auto data5 = pb.NewDataLiteral<ui8>(5);
- const auto data6 = pb.NewDataLiteral<ui8>(6);
- const auto data7 = pb.NewDataLiteral<ui8>(7);
- const auto data8 = pb.NewDataLiteral<ui8>(8);
- const auto data9 = pb.NewDataLiteral<ui8>(9);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.FromFlow(pb.Take(pb.Skip(pb.ToFlow(list), pb.NewDataLiteral<ui64>(4ULL)), pb.NewDataLiteral<ui64>(3ULL)));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 5);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 6);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestLazyListFromArray) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto data0 = pb.NewDataLiteral<ui32>(1U);
- const auto data1 = pb.NewDataLiteral<ui32>(2U);
- const auto data2 = pb.NewDataLiteral<ui32>(3U);
- const auto array = pb.NewList(type, {data0, data1, data2});
-
- const auto pgmReturn = pb.LazyList(array);
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto list = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElements(), nullptr);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<ui32>(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<ui32>(), 2U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<ui32>(), 3U);
- }
-
- Y_UNIT_TEST_LLVM(TestCollectLazyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto data0 = pb.NewDataLiteral<ui32>(1U);
- const auto data1 = pb.NewDataLiteral<ui32>(2U);
- const auto data2 = pb.NewDataLiteral<ui32>(3U);
- const auto array = pb.NewList(type, {data0, data1, data2});
-
- const auto pgmReturn = pb.Collect(pb.LazyList(array));
-
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto list = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
- UNIT_ASSERT(list.GetElements());
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<ui32>(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<ui32>(), 2U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<ui32>(), 3U);
- }
-
- Y_UNIT_TEST_LLVM(TestAddAllTimezones) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto zones = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(1000U), pb.NewDataLiteral<ui16>(1U));
- const auto pgmReturn = pb.Collect(pb.Map(zones, [&](TRuntimeNode id){ return pb.AddTimezone(pb.CurrentUtcDate({id}), id); }));
- const auto graph = setup.BuildGraph(pgmReturn);
-
- const auto list = graph->GetValue();
- UNIT_ASSERT(list.GetElement(0));
- UNIT_ASSERT(list.GetElement(1));
- UNIT_ASSERT(list.GetElement(2));
- UNIT_ASSERT(list.GetElement(585));
- UNIT_ASSERT(!list.GetElement(586));
- UNIT_ASSERT(list.GetElement(587));
- UNIT_ASSERT(list.GetElement(592));
- UNIT_ASSERT(!list.GetElement(593));
- UNIT_ASSERT(list.GetElement(594));
- }
-
- Y_UNIT_TEST_LLVM(TestRemoveTimezone) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Zulu");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Japan");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Jamaica");
-
- const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
- const auto datetimeTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDatetime, true);
-
- const auto list = pb.NewList(type, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode data) {
- return pb.Convert(pb.FromString(data, datetimeTypeTz), datetimeType);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), 3ULL);
-
- UNIT_ASSERT(!value.GetElement(0U).GetTimezoneId());
- UNIT_ASSERT(!value.GetElement(1U).GetTimezoneId());
- UNIT_ASSERT(!value.GetElement(2U).GetTimezoneId());
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<ui32>(), 1571922097U);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<ui32>(), 1571889697U);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<ui32>(), 1571940097U);
- }
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 25u
- Y_UNIT_TEST_LLVM(TestSqueezeToList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0);
- const auto data1 = pb.NewDataLiteral(1.1);
- const auto data2 = pb.NewDataLiteral(-3.14);
- const auto data3 = pb.NewDataLiteral(121324.323);
- const auto data4 = pb.NewDataLiteral(-7898.8);
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.SqueezeToList(pb.ToFlow(list), pb.NewDataLiteral<ui64>(1000ULL)));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue full;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(full));
- NUdf::TUnboxedValue stub;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
-
- UNIT_ASSERT_VALUES_EQUAL(full.GetListLength(), 5ULL);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(0U).template Get<double>(), 0.0);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(1U).template Get<double>(), 1.1);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(2U).template Get<double>(), -3.14);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(3U).template Get<double>(), 121324.323);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(4U).template Get<double>(), -7898.8);
- }
-
- Y_UNIT_TEST_LLVM(TestSqueezeToListWithLimit) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral(0.0f);
- const auto data1 = pb.NewDataLiteral(1.1f);
- const auto data2 = pb.NewDataLiteral(-3.14f);
- const auto data3 = pb.NewDataLiteral(12.323f);
- const auto data4 = pb.NewDataLiteral(-7898.8f);
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.SqueezeToList(pb.ToFlow(list), pb.NewDataLiteral<ui64>(3ULL)));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue full;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(full));
- NUdf::TUnboxedValue stub;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
-
- UNIT_ASSERT_VALUES_EQUAL(full.GetListLength(), 3ULL);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(0U).template Get<float>(), 0.0f);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(1U).template Get<float>(), 1.1f);
- UNIT_ASSERT_VALUES_EQUAL(full.GetElement(2U).template Get<float>(), -3.14f);
- }
-#endif
+ Y_UNIT_TEST_LLVM(TestSkipAndTakeOverStream) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(2);
+ const auto data3 = pb.NewDataLiteral<ui8>(3);
+ const auto data4 = pb.NewDataLiteral<ui8>(4);
+ const auto data5 = pb.NewDataLiteral<ui8>(5);
+ const auto data6 = pb.NewDataLiteral<ui8>(6);
+ const auto data7 = pb.NewDataLiteral<ui8>(7);
+ const auto data8 = pb.NewDataLiteral<ui8>(8);
+ const auto data9 = pb.NewDataLiteral<ui8>(9);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Take(pb.Skip(pb.Iterator(list, {}), pb.NewDataLiteral<ui64>(4ULL)), pb.NewDataLiteral<ui64>(3ULL));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 6);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipAndTakeOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<ui8>::Id);
+ const auto data0 = pb.NewDataLiteral<ui8>(0);
+ const auto data1 = pb.NewDataLiteral<ui8>(1);
+ const auto data2 = pb.NewDataLiteral<ui8>(2);
+ const auto data3 = pb.NewDataLiteral<ui8>(3);
+ const auto data4 = pb.NewDataLiteral<ui8>(4);
+ const auto data5 = pb.NewDataLiteral<ui8>(5);
+ const auto data6 = pb.NewDataLiteral<ui8>(6);
+ const auto data7 = pb.NewDataLiteral<ui8>(7);
+ const auto data8 = pb.NewDataLiteral<ui8>(8);
+ const auto data9 = pb.NewDataLiteral<ui8>(9);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.FromFlow(pb.Take(pb.Skip(pb.ToFlow(list), pb.NewDataLiteral<ui64>(4ULL)), pb.NewDataLiteral<ui64>(3ULL)));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui8>(), 6);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestLazyListFromArray) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto data0 = pb.NewDataLiteral<ui32>(1U);
+ const auto data1 = pb.NewDataLiteral<ui32>(2U);
+ const auto data2 = pb.NewDataLiteral<ui32>(3U);
+ const auto array = pb.NewList(type, {data0, data1, data2});
+
+ const auto pgmReturn = pb.LazyList(array);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto list = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElements(), nullptr);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<ui32>(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<ui32>(), 2U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<ui32>(), 3U);
+ }
+
+ Y_UNIT_TEST_LLVM(TestCollectLazyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto data0 = pb.NewDataLiteral<ui32>(1U);
+ const auto data1 = pb.NewDataLiteral<ui32>(2U);
+ const auto data2 = pb.NewDataLiteral<ui32>(3U);
+ const auto array = pb.NewList(type, {data0, data1, data2});
+
+ const auto pgmReturn = pb.Collect(pb.LazyList(array));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto list = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 3U);
+ UNIT_ASSERT(list.GetElements());
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0).template Get<ui32>(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1).template Get<ui32>(), 2U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2).template Get<ui32>(), 3U);
+ }
+
+ Y_UNIT_TEST_LLVM(TestAddAllTimezones) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto zones = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(1000U), pb.NewDataLiteral<ui16>(1U));
+ const auto pgmReturn = pb.Collect(pb.Map(zones, [&](TRuntimeNode id){ return pb.AddTimezone(pb.CurrentUtcDate({id}), id); }));
+ const auto graph = setup.BuildGraph(pgmReturn);
+
+ const auto list = graph->GetValue();
+ UNIT_ASSERT(list.GetElement(0));
+ UNIT_ASSERT(list.GetElement(1));
+ UNIT_ASSERT(list.GetElement(2));
+ UNIT_ASSERT(list.GetElement(585));
+ UNIT_ASSERT(!list.GetElement(586));
+ UNIT_ASSERT(list.GetElement(587));
+ UNIT_ASSERT(list.GetElement(592));
+ UNIT_ASSERT(!list.GetElement(593));
+ UNIT_ASSERT(list.GetElement(594));
+ }
+
+ Y_UNIT_TEST_LLVM(TestRemoveTimezone) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Zulu");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Japan");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("2019-10-24T13:01:37,Jamaica");
+
+ const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
+ const auto datetimeTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDatetime, true);
+
+ const auto list = pb.NewList(type, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode data) {
+ return pb.Convert(pb.FromString(data, datetimeTypeTz), datetimeType);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), 3ULL);
+
+ UNIT_ASSERT(!value.GetElement(0U).GetTimezoneId());
+ UNIT_ASSERT(!value.GetElement(1U).GetTimezoneId());
+ UNIT_ASSERT(!value.GetElement(2U).GetTimezoneId());
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<ui32>(), 1571922097U);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<ui32>(), 1571889697U);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<ui32>(), 1571940097U);
+ }
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 25u
+ Y_UNIT_TEST_LLVM(TestSqueezeToList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0);
+ const auto data1 = pb.NewDataLiteral(1.1);
+ const auto data2 = pb.NewDataLiteral(-3.14);
+ const auto data3 = pb.NewDataLiteral(121324.323);
+ const auto data4 = pb.NewDataLiteral(-7898.8);
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.SqueezeToList(pb.ToFlow(list), pb.NewDataLiteral<ui64>(1000ULL)));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue full;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(full));
+ NUdf::TUnboxedValue stub;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
+
+ UNIT_ASSERT_VALUES_EQUAL(full.GetListLength(), 5ULL);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(0U).template Get<double>(), 0.0);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(1U).template Get<double>(), 1.1);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(2U).template Get<double>(), -3.14);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(3U).template Get<double>(), 121324.323);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(4U).template Get<double>(), -7898.8);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSqueezeToListWithLimit) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral(0.0f);
+ const auto data1 = pb.NewDataLiteral(1.1f);
+ const auto data2 = pb.NewDataLiteral(-3.14f);
+ const auto data3 = pb.NewDataLiteral(12.323f);
+ const auto data4 = pb.NewDataLiteral(-7898.8f);
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.SqueezeToList(pb.ToFlow(list), pb.NewDataLiteral<ui64>(3ULL)));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue full;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(full));
+ NUdf::TUnboxedValue stub;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(stub));
+
+ UNIT_ASSERT_VALUES_EQUAL(full.GetListLength(), 3ULL);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(0U).template Get<float>(), 0.0f);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(1U).template Get<float>(), 1.1f);
+ UNIT_ASSERT_VALUES_EQUAL(full.GetElement(2U).template Get<float>(), -3.14f);
+ }
+#endif
Y_UNIT_TEST_LLVM(TestPerfHolders) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto ui32Type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto structType = pb.NewStructType({{"key", ui32Type}, {"value", strType}});
- const auto mark = pb.NewDataLiteral<NUdf::EDataSlot::String>("!");
+ const auto ui32Type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto structType = pb.NewStructType({{"key", ui32Type}, {"value", strType}});
+ const auto mark = pb.NewDataLiteral<NUdf::EDataSlot::String>("!");
- const auto listType = pb.NewListType(structType);
- TCallableBuilder listRet(pb.GetTypeEnvironment(), "TestList", listType);
- const auto listNode = listRet.Build();
+ const auto listType = pb.NewListType(structType);
+ TCallableBuilder listRet(pb.GetTypeEnvironment(), "TestList", listType);
+ const auto listNode = listRet.Build();
- const auto pgmReturn = pb.Map(pb.LazyList(TRuntimeNode(listNode, false)),
+ const auto pgmReturn = pb.Map(pb.LazyList(TRuntimeNode(listNode, false)),
[&](TRuntimeNode item) {
- return pb.NewStruct({
- {"key", pb.Member(item, "key")},
- {"value", pb.AggrConcat(mark, pb.Member(item, "value"))}
- });
+ return pb.NewStruct({
+ {"key", pb.Member(item, "key")},
+ {"value", pb.AggrConcat(mark, pb.Member(item, "value"))}
+ });
});
- std::vector<ui32> src(10000U);
- std::iota(src.begin(), src.end(), 0U);
+ std::vector<ui32> src(10000U);
+ std::iota(src.begin(), src.end(), 0U);
- const auto myStructFactory = [](const THolderFactory& factory, ui32 i) {
- NUdf::TUnboxedValue* itemsPtr = nullptr;
- const auto structObj = factory.CreateDirectArrayHolder(2U, itemsPtr);
- itemsPtr[0] = NUdf::TUnboxedValuePod(ui32(i));
- itemsPtr[1] = MakeString("ABCDEFGHIJKL");
+ const auto myStructFactory = [](const THolderFactory& factory, ui32 i) {
+ NUdf::TUnboxedValue* itemsPtr = nullptr;
+ const auto structObj = factory.CreateDirectArrayHolder(2U, itemsPtr);
+ itemsPtr[0] = NUdf::TUnboxedValuePod(ui32(i));
+ itemsPtr[1] = MakeString("ABCDEFGHIJKL");
return structObj;
};
- const auto t1 = TInstant::Now();
+ const auto t1 = TInstant::Now();
{
- const auto graph = setup.BuildGraph(pgmReturn, {listNode});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(src.size(), items));
- std::transform(src.cbegin(), src.cend(), items, std::bind(myStructFactory, std::ref(graph->GetHolderFactory()), std::placeholders::_1));
-
- const auto iterator = graph->GetValue().GetListIterator();
- ui32 i = 0U;
- for (NUdf::TUnboxedValue current; iterator.Next(current); ++i) {
+ const auto graph = setup.BuildGraph(pgmReturn, {listNode});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(src.size(), items));
+ std::transform(src.cbegin(), src.cend(), items, std::bind(myStructFactory, std::ref(graph->GetHolderFactory()), std::placeholders::_1));
+
+ const auto iterator = graph->GetValue().GetListIterator();
+ ui32 i = 0U;
+ for (NUdf::TUnboxedValue current; iterator.Next(current); ++i) {
UNIT_ASSERT_VALUES_EQUAL(current.GetElement(0).template Get<ui32>(), i);
- UNBOXED_VALUE_STR_EQUAL(current.GetElement(1), "!ABCDEFGHIJKL");
+ UNBOXED_VALUE_STR_EQUAL(current.GetElement(1), "!ABCDEFGHIJKL");
}
}
- const auto t2 = TInstant::Now();
+ const auto t2 = TInstant::Now();
Cout << t2 - t1 << Endl;
}
Y_UNIT_TEST_LLVM(TestPerfGrep) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto ui32Type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- auto structType = pb.NewEmptyStructType();
- structType = pb.NewStructType(structType, "key", ui32Type);
- structType = pb.NewStructType(structType, "value", strType);
- const auto keyIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("key");
- const auto valueIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("value");
+ const auto ui32Type = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ auto structType = pb.NewEmptyStructType();
+ structType = pb.NewStructType(structType, "key", ui32Type);
+ structType = pb.NewStructType(structType, "value", strType);
+ const auto keyIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("key");
+ const auto valueIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("value");
- TRuntimeNode rowArg = pb.Arg(structType);
+ TRuntimeNode rowArg = pb.Arg(structType);
- const auto pgmReturn = pb.Equals(pb.Member(rowArg, "value"),
- pb.NewDataLiteral<NUdf::EDataSlot::String>("ABCDE"));
+ const auto pgmReturn = pb.Equals(pb.Member(rowArg, "value"),
+ pb.NewDataLiteral<NUdf::EDataSlot::String>("ABCDE"));
- const auto t1 = TInstant::Now();
+ const auto t1 = TInstant::Now();
{
- const auto graph = setup.BuildGraph(pgmReturn, {rowArg.GetNode()});
- const auto row = graph->GetEntryPoint(0, true);
+ const auto graph = setup.BuildGraph(pgmReturn, {rowArg.GetNode()});
+ const auto row = graph->GetEntryPoint(0, true);
- NUdf::TUnboxedValue* items = nullptr;
- const auto structObj = graph->GetHolderFactory().CreateDirectArrayHolder(2, items);
+ NUdf::TUnboxedValue* items = nullptr;
+ const auto structObj = graph->GetHolderFactory().CreateDirectArrayHolder(2, items);
graph->Prepare();
const ui32 n = 10000;
for (ui32 i = 0; i < n; ++i) {
- items[keyIndex] = NUdf::TUnboxedValuePod(i);
- items[valueIndex] = NUdf::TUnboxedValuePod::Embedded("ABCDF");
+ items[keyIndex] = NUdf::TUnboxedValuePod(i);
+ items[valueIndex] = NUdf::TUnboxedValuePod::Embedded("ABCDF");
row->SetValue(graph->GetContext(), NUdf::TUnboxedValuePod(structObj));
- const bool keep = graph->GetValue().template Get<bool>();
+ const bool keep = graph->GetValue().template Get<bool>();
UNIT_ASSERT(!keep);
}
}
- const auto t2 = TInstant::Now();
+ const auto t2 = TInstant::Now();
Cout << t2 - t1 << Endl;
}
- Y_NO_INLINE NUdf::TUnboxedValuePod SpecialFunc(const NUdf::TUnboxedValuePod* args) {
- const auto stringRef = args[1].AsStringRef();
- return NUdf::TUnboxedValuePod(stringRef.Size() == 5 && std::memcmp(stringRef.Data(), "ABCDE", 5) == 0);
+ Y_NO_INLINE NUdf::TUnboxedValuePod SpecialFunc(const NUdf::TUnboxedValuePod* args) {
+ const auto stringRef = args[1].AsStringRef();
+ return NUdf::TUnboxedValuePod(stringRef.Size() == 5 && std::memcmp(stringRef.Data(), "ABCDE", 5) == 0);
}
Y_UNIT_TEST_LLVM(TestPerfGrepSpecialFunc) {
- const auto t1 = TInstant::Now();
+ const auto t1 = TInstant::Now();
{
- NUdf::TUnboxedValuePod items[2];
+ NUdf::TUnboxedValuePod items[2];
const ui32 n = 10000;
for (ui32 i = 0; i < n; ++i) {
- items[0] = NUdf::TUnboxedValuePod(i);
- items[1] = NUdf::TUnboxedValuePod::Embedded("ABCDF");
- bool keep = SpecialFunc(items).template Get<bool>();
+ items[0] = NUdf::TUnboxedValuePod(i);
+ items[1] = NUdf::TUnboxedValuePod::Embedded("ABCDF");
+ bool keep = SpecialFunc(items).template Get<bool>();
UNIT_ASSERT(!keep);
}
}
- const auto t2 = TInstant::Now();
+ const auto t2 = TInstant::Now();
Cout << t2 - t1 << Endl;
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.h b/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.h
index 89b537bb3c..db79fc7ab8 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.h
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_computation_node_ut.h
@@ -1,17 +1,17 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
#include <ydb/library/yql/minikql/mkql_program_builder.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h>
#include <ydb/library/yql/minikql/mkql_function_registry.h>
#include <ydb/library/yql/minikql/mkql_terminator.h>
-#include "../mkql_factories.h"
+#include "../mkql_factories.h"
#include <library/cpp/testing/unittest/registar.h>
#define UNBOXED_VALUE_STR_EQUAL(unboxed, expected) \
do { \
- const auto v = (unboxed); \
+ const auto v = (unboxed); \
if (!(v.AsStringRef() == (expected))) { \
UNIT_FAIL_IMPL( \
"equal assertion failed", \
@@ -19,14 +19,14 @@
} \
} while (0)
-
-
+
+
#if defined(_msan_enabled_) || defined(_ubsan_enabled_) || defined(WITH_VALGRIND)
#define Y_UNIT_TEST_TWIN_IMPL_REGISTER(N, OPT) \
- template<bool OPT> void N(NUnitTest::TTestContext&); \
- struct TTestRegistration##N { \
- TTestRegistration##N() { \
- TCurrentTest::AddTest(#N "-" #OPT, static_cast<void (*)(NUnitTest::TTestContext&)>(&N<false>), false); \
+ template<bool OPT> void N(NUnitTest::TTestContext&); \
+ struct TTestRegistration##N { \
+ TTestRegistration##N() { \
+ TCurrentTest::AddTest(#N "-" #OPT, static_cast<void (*)(NUnitTest::TTestContext&)>(&N<false>), false); \
} \
}; \
static TTestRegistration##N testRegistration##N;
@@ -36,72 +36,72 @@
struct TTestRegistration##N { \
TTestRegistration##N() { \
TCurrentTest::AddTest(#N "-" #OPT, static_cast<void (*)(NUnitTest::TTestContext&)>(&N<false>), false); \
- TCurrentTest::AddTest(#N "+" #OPT, static_cast<void (*)(NUnitTest::TTestContext&)>(&N<true>), false); \
- } \
- }; \
- static TTestRegistration##N testRegistration##N;
+ TCurrentTest::AddTest(#N "+" #OPT, static_cast<void (*)(NUnitTest::TTestContext&)>(&N<true>), false); \
+ } \
+ }; \
+ static TTestRegistration##N testRegistration##N;
#endif
-
+
#define Y_UNIT_TEST_TWIN(N, OPT) \
Y_UNIT_TEST_TWIN_IMPL_REGISTER(N, OPT) \
- template<bool OPT> \
- void N(NUnitTest::TTestContext&)
-
+ template<bool OPT> \
+ void N(NUnitTest::TTestContext&)
+
#define Y_UNIT_TEST_LLVM(N) Y_UNIT_TEST_TWIN(N, LLVM)
-
+
namespace NKikimr {
namespace NMiniKQL {
-TComputationNodeFactory GetTestFactory();
+TComputationNodeFactory GetTestFactory();
-template<typename T>
-NUdf::TUnboxedValuePod ToValue(T value) {
- return NUdf::TUnboxedValuePod(value);
+template<typename T>
+NUdf::TUnboxedValuePod ToValue(T value) {
+ return NUdf::TUnboxedValuePod(value);
}
-template<bool UseLLVM>
-struct TSetup {
- TSetup() {
- FunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
- RandomProvider = CreateDeterministicRandomProvider(1);
+template<bool UseLLVM>
+struct TSetup {
+ TSetup() {
+ FunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry());
+ RandomProvider = CreateDeterministicRandomProvider(1);
TimeProvider = CreateDeterministicTimeProvider(10000000);
-
- Env.Reset(new TTypeEnvironment(Alloc));
- PgmBuilder.Reset(new TProgramBuilder(*Env, *FunctionRegistry));
- }
-
- THolder<IComputationGraph> BuildGraph(TRuntimeNode pgm, const std::vector<TNode*>& entryPoints = std::vector<TNode*>()) {
- Reset();
- Explorer.Walk(pgm.GetNode(), *Env);
- TComputationPatternOpts opts(Alloc.Ref(), *Env, GetTestFactory(),
- FunctionRegistry.Get(), NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, UseLLVM ? "" : "OFF", EGraphPerProcess::Multi);
- Pattern = MakeComputationPattern(Explorer, pgm, entryPoints, opts);
- auto graph = Pattern->Clone(opts.ToComputationOptions(*RandomProvider, *TimeProvider));
- Terminator.Reset(new TBindTerminator(graph->GetTerminator()));
- return graph;
- }
-
- void Reset() {
- Terminator.Destroy();
- Pattern.Reset();
- }
-
- TIntrusivePtr<IFunctionRegistry> FunctionRegistry;
- TIntrusivePtr<IRandomProvider> RandomProvider;
- TIntrusivePtr<ITimeProvider> TimeProvider;
-
- TScopedAlloc Alloc;
- THolder<TTypeEnvironment> Env;
- THolder<TProgramBuilder> PgmBuilder;
-
- TExploringNodeVisitor Explorer;
- IComputationPattern::TPtr Pattern;
- THolder<TBindTerminator> Terminator;
-};
-
-extern const std::vector<std::pair<i8, double>> I8Samples;
-extern const std::vector<std::pair<ui16, double>> Ui16Samples;
-extern const std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> TpchSamples;
-
+
+ Env.Reset(new TTypeEnvironment(Alloc));
+ PgmBuilder.Reset(new TProgramBuilder(*Env, *FunctionRegistry));
+ }
+
+ THolder<IComputationGraph> BuildGraph(TRuntimeNode pgm, const std::vector<TNode*>& entryPoints = std::vector<TNode*>()) {
+ Reset();
+ Explorer.Walk(pgm.GetNode(), *Env);
+ TComputationPatternOpts opts(Alloc.Ref(), *Env, GetTestFactory(),
+ FunctionRegistry.Get(), NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, UseLLVM ? "" : "OFF", EGraphPerProcess::Multi);
+ Pattern = MakeComputationPattern(Explorer, pgm, entryPoints, opts);
+ auto graph = Pattern->Clone(opts.ToComputationOptions(*RandomProvider, *TimeProvider));
+ Terminator.Reset(new TBindTerminator(graph->GetTerminator()));
+ return graph;
+ }
+
+ void Reset() {
+ Terminator.Destroy();
+ Pattern.Reset();
+ }
+
+ TIntrusivePtr<IFunctionRegistry> FunctionRegistry;
+ TIntrusivePtr<IRandomProvider> RandomProvider;
+ TIntrusivePtr<ITimeProvider> TimeProvider;
+
+ TScopedAlloc Alloc;
+ THolder<TTypeEnvironment> Env;
+ THolder<TProgramBuilder> PgmBuilder;
+
+ TExploringNodeVisitor Explorer;
+ IComputationPattern::TPtr Pattern;
+ THolder<TBindTerminator> Terminator;
+};
+
+extern const std::vector<std::pair<i8, double>> I8Samples;
+extern const std::vector<std::pair<ui16, double>> Ui16Samples;
+extern const std::vector<std::tuple<ui64, std::string, std::string, double, double, double, double>> TpchSamples;
+
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_condense_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_condense_ut.cpp
index baca943178..653d6c0cc0 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_condense_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_condense_ut.cpp
@@ -1,495 +1,495 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
namespace NKikimr {
namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLCondenseNodeTest) {
+Y_UNIT_TEST_SUITE(TMiniKQLCondenseNodeTest) {
Y_UNIT_TEST_LLVM(TestSqueeze) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
- const auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
- const auto list = pb.NewList(dataType, {data4, data3, data2, data1});
-
- const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrMin(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
+ const auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
+ const auto list = pb.NewList(dataType, {data4, data3, data2, data1});
+
+ const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrMin(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestSqueezeOnEmpty) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
- const auto list = pb.NewEmptyList(dataType);
-
- const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrMin(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
+ const auto list = pb.NewEmptyList(dataType);
+
+ const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrMin(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), HUGE_VAL);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestSqueeze1OverEmpty) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewEmptyList(dataType);
- const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Minus(item);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Mul(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewEmptyList(dataType);
+ const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Minus(item);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Mul(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestSqueeze1OverSingle) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto data1 = pb.NewDataLiteral<i32>(1);
- const auto list = pb.NewList(dataType, {data1});
- const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Minus(item);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Mul(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto data1 = pb.NewDataLiteral<i32>(1);
+ const auto list = pb.NewList(dataType, {data1});
+ const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Minus(item);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Mul(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
-
+
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestSqueeze1OverMany) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto data1 = pb.NewDataLiteral<i32>(1);
- const auto data2 = pb.NewDataLiteral<i32>(2);
- const auto data3 = pb.NewDataLiteral<i32>(7);
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Minus(item);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Mul(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto data1 = pb.NewDataLiteral<i32>(1);
+ const auto data2 = pb.NewDataLiteral<i32>(2);
+ const auto data3 = pb.NewDataLiteral<i32>(7);
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Minus(item);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Mul(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
-
+
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
+ const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
+ const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
+ const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
+ const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
+ const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
+ const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Condense(pb.Iterator(list, {}), data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrAdd(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense1) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto data0 = pb.NewDataLiteral<i32>(-1);
+ const auto data1 = pb.NewDataLiteral<i32>(2);
+ const auto data2 = pb.NewDataLiteral<i32>(0);
+ const auto data3 = pb.NewDataLiteral<i32>(7);
+ const auto data4 = pb.NewDataLiteral<i32>(5);
+ const auto data5 = pb.NewDataLiteral<i32>(-7);
+ const auto data6 = pb.NewDataLiteral<i32>(-6);
+ const auto data7 = pb.NewDataLiteral<i32>(4);
+ const auto data8 = pb.NewDataLiteral<i32>(8);
+ const auto data9 = pb.NewDataLiteral<i32>(9);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+ const auto pgmReturn = pb.Condense1(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Minus(item);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.LessOrEqual(item, state);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Mul(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
+
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondenseOverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
+ const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
+ const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
+ const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
+ const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
+ const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
+ const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Condense(list, data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrAdd(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense1OverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto data0 = pb.NewDataLiteral<i32>(-1);
+ const auto data1 = pb.NewDataLiteral<i32>(2);
+ const auto data2 = pb.NewDataLiteral<i32>(0);
+ const auto data3 = pb.NewDataLiteral<i32>(7);
+ const auto data4 = pb.NewDataLiteral<i32>(5);
+ const auto data5 = pb.NewDataLiteral<i32>(-7);
+ const auto data6 = pb.NewDataLiteral<i32>(-6);
+ const auto data7 = pb.NewDataLiteral<i32>(4);
+ const auto data8 = pb.NewDataLiteral<i32>(8);
+ const auto data9 = pb.NewDataLiteral<i32>(9);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+ const auto pgmReturn = pb.Condense1(list,
+ [&](TRuntimeNode item) {
+ return pb.Minus(item);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.LessOrEqual(item, state);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Mul(item, state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondenseInterrupt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+ const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
+
+ const auto pgmReturn = pb.FromFlow(pb.Condense(pb.ToFlow(list), pb.NewDataLiteral<bool>(false),
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.If(state, pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id), pb.NewDataLiteral<bool>(false));
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Or({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(item.template Get<bool>());
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense1Interrupt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
+ const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
+ const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+ const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
+
+ const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ },
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.If(state, pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.And({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.template Get<bool>());
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondenseInterruptEndlessStream) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto pgmReturn = pb.Condense(pb.SourceOf(pb.NewStreamType(pb.NewNull().GetStaticType())), pb.NewDataLiteral<ui32>(0U),
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
+ },
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
+ }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
+
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense1InterruptEndlessFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.SourceOf(pb.NewFlowType(pb.NewNull().GetStaticType())),
+ [&](TRuntimeNode) {
+ return pb.NewDataLiteral<ui32>(0U);
+ },
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
+ },
+ [&](TRuntimeNode, TRuntimeNode state) {
+ return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
+
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
- const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
- const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
- const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
- const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
- const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
- const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Condense(pb.Iterator(list, {}), data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrAdd(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense1) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto data0 = pb.NewDataLiteral<i32>(-1);
- const auto data1 = pb.NewDataLiteral<i32>(2);
- const auto data2 = pb.NewDataLiteral<i32>(0);
- const auto data3 = pb.NewDataLiteral<i32>(7);
- const auto data4 = pb.NewDataLiteral<i32>(5);
- const auto data5 = pb.NewDataLiteral<i32>(-7);
- const auto data6 = pb.NewDataLiteral<i32>(-6);
- const auto data7 = pb.NewDataLiteral<i32>(4);
- const auto data8 = pb.NewDataLiteral<i32>(8);
- const auto data9 = pb.NewDataLiteral<i32>(9);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
- const auto pgmReturn = pb.Condense1(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Minus(item);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.LessOrEqual(item, state);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Mul(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
-
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondenseOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
- const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
- const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
- const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
- const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
- const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
- const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Condense(list, data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrAdd(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense1OverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto data0 = pb.NewDataLiteral<i32>(-1);
- const auto data1 = pb.NewDataLiteral<i32>(2);
- const auto data2 = pb.NewDataLiteral<i32>(0);
- const auto data3 = pb.NewDataLiteral<i32>(7);
- const auto data4 = pb.NewDataLiteral<i32>(5);
- const auto data5 = pb.NewDataLiteral<i32>(-7);
- const auto data6 = pb.NewDataLiteral<i32>(-6);
- const auto data7 = pb.NewDataLiteral<i32>(4);
- const auto data8 = pb.NewDataLiteral<i32>(8);
- const auto data9 = pb.NewDataLiteral<i32>(9);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
- const auto pgmReturn = pb.Condense1(list,
- [&](TRuntimeNode item) {
- return pb.Minus(item);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.LessOrEqual(item, state);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Mul(item, state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondenseInterrupt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
- const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
-
- const auto pgmReturn = pb.FromFlow(pb.Condense(pb.ToFlow(list), pb.NewDataLiteral<bool>(false),
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.If(state, pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id), pb.NewDataLiteral<bool>(false));
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Or({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(item.template Get<bool>());
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense1Interrupt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
- const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
- const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
- const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
-
- const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- },
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.If(state, pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.And({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.template Get<bool>());
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondenseInterruptEndlessStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto pgmReturn = pb.Condense(pb.SourceOf(pb.NewStreamType(pb.NewNull().GetStaticType())), pb.NewDataLiteral<ui32>(0U),
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
- },
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
- }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
-
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense1InterruptEndlessFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.SourceOf(pb.NewFlowType(pb.NewNull().GetStaticType())),
- [&](TRuntimeNode) {
- return pb.NewDataLiteral<ui32>(0U);
- },
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
- },
- [&](TRuntimeNode, TRuntimeNode state) {
- return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
-
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
-
- Y_UNIT_TEST_LLVM(TestCondenseListeralListInMap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
- const auto type = pb.NewDataType(NUdf::EDataSlot::String);
- const auto list2 = pb.NewList(type, {data1, data2});
- const auto list0 = pb.NewList(type, {data1, data2, data0});
-
- const auto pgmReturn = pb.Map(list0,
- [&](TRuntimeNode item) {
- return pb.Head(pb.Condense(list2,
- pb.NewDataLiteral(false),
- [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
- [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
- ));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.Get<bool>());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCondense1ListeralListInMap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
- const auto type = pb.NewDataType(NUdf::EDataSlot::String);
- const auto list2 = pb.NewList(type, {data1, data2});
- const auto list0 = pb.NewList(type, {data1, data2, data0});
-
- const auto pgmReturn = pb.Map(list0,
- [&](TRuntimeNode item) {
- return pb.Head(pb.Condense1(list2,
- [&](TRuntimeNode it) { return pb.AggrEquals(item, it); },
- [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
- [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
- ));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.Get<bool>());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.Get<bool>());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
+ }
+
+
+ Y_UNIT_TEST_LLVM(TestCondenseListeralListInMap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
+ const auto type = pb.NewDataType(NUdf::EDataSlot::String);
+ const auto list2 = pb.NewList(type, {data1, data2});
+ const auto list0 = pb.NewList(type, {data1, data2, data0});
+
+ const auto pgmReturn = pb.Map(list0,
+ [&](TRuntimeNode item) {
+ return pb.Head(pb.Condense(list2,
+ pb.NewDataLiteral(false),
+ [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
+ [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
+ ));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.Get<bool>());
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCondense1ListeralListInMap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
+ const auto type = pb.NewDataType(NUdf::EDataSlot::String);
+ const auto list2 = pb.NewList(type, {data1, data2});
+ const auto list0 = pb.NewList(type, {data1, data2, data0});
+
+ const auto pgmReturn = pb.Map(list0,
+ [&](TRuntimeNode item) {
+ return pb.Head(pb.Condense1(list2,
+ [&](TRuntimeNode it) { return pb.AggrEquals(item, it); },
+ [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
+ [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
+ ));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.Get<bool>());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.Get<bool>());
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_decimal_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_decimal_ut.cpp
index 4b59f6778b..eb5ff4df71 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_decimal_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_decimal_ut.cpp
@@ -1,2126 +1,2126 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLDecimalTest) {
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLDecimalTest) {
Y_UNIT_TEST_LLVM(TestNanvl) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewOptionalType(pb.NewDecimalType(13, 5));
- const auto data0 = pb.NewOptional(pb.NewDecimalLiteral(0, 13, 5));
- const auto data1 = pb.NewOptional(pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 13, 5));
- const auto data2 = pb.NewOptional(pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 5));
- const auto data3 = pb.NewOptional(pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 5));
- const auto data4 = pb.NewEmptyOptional(type);
- const auto data5 = pb.NewOptional(pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 5));
- const auto data = pb.NewDecimalLiteral(314159, 13, 5);
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Nanvl(item, data);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 314159);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 314159);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToIntegral) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDecimalType(13, 1);
- const auto data0 = pb.NewDecimalLiteral(0, 13, 1);
- const auto data1 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 13, 1);
- const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 1);
- const auto data3 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 1);
- const auto data4 = pb.NewDecimalLiteral(1270, 13, 1);
- const auto data5 = pb.NewDecimalLiteral(-1280, 13, 1);
- const auto data6 = pb.NewDecimalLiteral(2550, 13, 1);
- const auto data7 = pb.NewDecimalLiteral(-2560, 13, 1);
- const auto data8 = pb.NewDecimalLiteral(2560, 13, 1);
- const auto data9 = pb.NewDecimalLiteral(-2570, 13, 1);
- const auto dataA = pb.NewDecimalLiteral(327670, 13, 1);
- const auto dataB = pb.NewDecimalLiteral(-327680, 13, 1);
- const auto dataC = pb.NewDecimalLiteral(655350, 13, 1);
- const auto dataD = pb.NewDecimalLiteral(-655360, 13, 1);
- const auto dataE = pb.NewDecimalLiteral(21474836470, 13, 1);
- const auto dataF = pb.NewDecimalLiteral(-21474836480, 13, 1);
- const auto dataG = pb.NewDecimalLiteral(21474836480, 13, 1);
- const auto dataH = pb.NewDecimalLiteral(-21474836490, 13, 1);
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, dataA, dataB, dataC, dataD, dataE, dataF, dataG, dataH});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i64>::Id, true)),
- pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui64>::Id, true))
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT(!item.GetElements()[6]);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 127);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 127);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), -128);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -128);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -128);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -128);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 255);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 255);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -256);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -256);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -256);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 256);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 256);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 256);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 256);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 256);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 256);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -257);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -257);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -257);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 32767);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 32767);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 32767);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 32767);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 32767);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 32767);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -32768);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -32768);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -32768);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 65535);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 65535);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 65535);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 65535);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 65535);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -65536);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -65536);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 2147483647LL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 2147483647LL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 2147483647LL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 2147483647LL);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -2147483648LL);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -2147483648LL);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 2147483648LL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 2147483648LL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 2147483648LL);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElements()[0]);
- UNIT_ASSERT(!item.GetElements()[1]);
- UNIT_ASSERT(!item.GetElements()[2]);
- UNIT_ASSERT(!item.GetElements()[3]);
- UNIT_ASSERT(!item.GetElements()[4]);
- UNIT_ASSERT(!item.GetElements()[5]);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -2147483649LL);
- UNIT_ASSERT(!item.GetElements()[7]);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToFloat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 3);
- const auto data0 = pb.NewDecimalLiteral(2123, 10, 3);
- const auto data1 = pb.NewDecimalLiteral(233, 10, 3);
- const auto data2 = pb.NewDecimalLiteral(0, 10, 3);
- const auto data3 = pb.NewDecimalLiteral(-3277823, 10, 3);
- const auto data4 = pb.NewDecimalLiteral(-1, 10, 3);
- const auto data5 = pb.NewDecimalLiteral(7128, 10, 3);
- const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 3);
- const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 3);
- const auto data8 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 3);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<float>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 2.123f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.233f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.0f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -3277.823f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -0.001f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 7.128f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isnan(item.template Get<float>()));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isinf(item.template Get<float>()) && item.template Get<float>() > 0.0f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isinf(item.template Get<float>()) && item.template Get<float>() < 0.0f);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToDouble) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 5);
- const auto data0 = pb.NewDecimalLiteral(2123, 10, 5);
- const auto data1 = pb.NewDecimalLiteral(233, 10, 5);
- const auto data2 = pb.NewDecimalLiteral(0, 10, 5);
- const auto data3 = pb.NewDecimalLiteral(-3277823, 10, 5);
- const auto data4 = pb.NewDecimalLiteral(-1, 10, 5);
- const auto data5 = pb.NewDecimalLiteral(7128, 10, 5);
- const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 5);
- const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 5);
- const auto data8 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 5);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(item, pb.NewDataType(NUdf::TDataType<double>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.02123);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.00233);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -32.77823);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -0.00001);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.07128);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isnan(item.template Get<double>()));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isinf(item.template Get<double>()) && item.template Get<double>() > 0.0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(std::isinf(item.template Get<double>()) && item.template Get<double>() < 0.0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDiv) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 0);
- const auto data0 = pb.NewDecimalLiteral(2, 10, 0);
- const auto data1 = pb.NewDecimalLiteral(23, 10, 0);
- const auto data2 = pb.NewDecimalLiteral(-23, 10, 0);
- const auto data3 = pb.NewDecimalLiteral(25, 10, 0);
- const auto data4 = pb.NewDecimalLiteral(-25, 10, 0);
- const auto data5 = pb.NewDecimalLiteral(1, 10, 0);
- const auto data6 = pb.NewDecimalLiteral(-1, 10, 0);
- const auto data7 = pb.NewDecimalLiteral(3, 10, 0);
- const auto data8 = pb.NewDecimalLiteral(-3, 10, 0);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalDiv(item, data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 12);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -12);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 12);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -12);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDivInt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
- const auto data0 = pb.NewDecimalLiteral(-238973, 9, 3);
- const auto data1 = pb.NewDataLiteral<i8>(0);
- const auto data2 = pb.NewDataLiteral<i8>(-1);
- const auto data3 = pb.NewDataLiteral<i8>(-128);
- const auto data4 = pb.NewDataLiteral<i8>(3);
- const auto data5 = pb.NewDataLiteral<i8>(5);
- const auto data6 = pb.NewDataLiteral<i8>(-7);
- const auto data7 = pb.NewDataLiteral<i8>(13);
- const auto data8 = pb.NewDataLiteral<i8>(-19);
- const auto data9 = pb.NewDataLiteral<i8>(42);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalDiv(data0, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 238973);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 1866);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -79658);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -47795);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 34139);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -18383);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 12577);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -5690);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMod) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(5, 2);
- const auto data0 = pb.NewDecimalLiteral(-12323, 5, 2);
- const auto data1 = pb.NewDecimalLiteral(0, 5, 2);
- const auto data2 = pb.NewDecimalLiteral(NYql::NDecimal::Inf(), 5, 2);
- const auto data3 = pb.NewDecimalLiteral(-1, 5, 2);
- const auto data4 = pb.NewDecimalLiteral(2, 5, 2);
- const auto data5 = pb.NewDecimalLiteral(-3, 5, 2);
- const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 5, 2);
- const auto data7 = pb.NewDecimalLiteral(7, 5, 2);
- const auto data8 = pb.NewDecimalLiteral(-10000, 5, 2);
- const auto data9 = pb.NewDecimalLiteral(12329, 5, 2);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalMod(data0, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -2323);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -12323);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestModInt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<i16>::Id);
- const auto data0 = pb.NewDecimalLiteral(-743, 3, 2);
- const auto data1 = pb.NewDataLiteral<i16>(0);
- const auto data2 = pb.NewDataLiteral<i16>(1);
- const auto data3 = pb.NewDataLiteral<i16>(-2);
- const auto data4 = pb.NewDataLiteral<i16>(3);
- const auto data5 = pb.NewDataLiteral<i16>(4);
- const auto data6 = pb.NewDataLiteral<i16>(-5);
- const auto data7 = pb.NewDataLiteral<i16>(8);
- const auto data8 = pb.NewDataLiteral<i16>(10);
- const auto data9 = pb.NewDataLiteral<i16>(-10);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalMod(data0, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -43);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -143);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -143);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -343);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -243);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -743);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -743);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -743);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMul) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 2);
- const auto data0 = pb.NewDecimalLiteral(333, 10, 2);
- const auto data1 = pb.NewDecimalLiteral(-100, 10, 2);
- const auto data2 = pb.NewDecimalLiteral(-120, 10, 2);
- const auto data3 = pb.NewDecimalLiteral(3, 10, 2);
- const auto data4 = pb.NewDecimalLiteral(77, 10, 2);
- const auto data5 = pb.NewDecimalLiteral(122, 10, 2);
- const auto data6 = pb.NewDecimalLiteral(1223, 10, 2);
- const auto data7 = pb.NewDecimalLiteral(-999, 10, 2);
- const auto data8 = pb.NewDecimalLiteral(0, 10, 2);
- const auto data9 = pb.NewDecimalLiteral(-3003003003LL, 10, 2);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalMul(item, data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 1109);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -333);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -400);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 10);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 256);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 406);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 4073);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -3327);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMulInt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
- const auto data0 = pb.NewDecimalLiteral(-333, 7, 2);
- const auto data1 = pb.NewDataLiteral<ui16>(0);
- const auto data2 = pb.NewDataLiteral<ui16>(1);
- const auto data3 = pb.NewDataLiteral<ui16>(2);
- const auto data4 = pb.NewDataLiteral<ui16>(3);
- const auto data5 = pb.NewDataLiteral<ui16>(10);
- const auto data6 = pb.NewDataLiteral<ui16>(100);
- const auto data7 = pb.NewDataLiteral<ui16>(1000);
- const auto data8 = pb.NewDataLiteral<ui16>(10000);
- const auto data9 = pb.NewDataLiteral<ui16>(65535);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalMul(data0, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -333);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -666);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -999);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -3330);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -33300);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -333000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -3330000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestLongintMul) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 0);
- const auto data0 = pb.NewDecimalLiteral(333, 10, 0);
- const auto data1 = pb.NewDecimalLiteral(-100, 10, 0);
- const auto data2 = pb.NewDecimalLiteral(-120, 10, 0);
- const auto data3 = pb.NewDecimalLiteral(3, 10, 0);
- const auto data4 = pb.NewDecimalLiteral(77, 10, 0);
- const auto data5 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
- const auto data6 = pb.NewDecimalLiteral(30030031, 10, 0);
- const auto data7 = pb.NewDecimalLiteral(-30030031, 10, 0);
- const auto data8 = pb.NewDecimalLiteral(0, 10, 0);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.DecimalMul(item, data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 110889);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -33300);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -39960);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 999);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 25641);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestScaleUp) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 2);
- const auto data0 = pb.NewDecimalLiteral(333, 10, 2);
- const auto data1 = pb.NewDecimalLiteral(-100, 10, 2);
- const auto data2 = pb.NewDecimalLiteral(-120, 10, 2);
- const auto data3 = pb.NewDecimalLiteral(3, 10, 2);
- const auto data4 = pb.NewDecimalLiteral(77, 10, 2);
- const auto data5 = pb.NewDecimalLiteral(122, 10, 2);
- const auto data6 = pb.NewDecimalLiteral(1223, 10, 2);
- const auto data7 = pb.NewDecimalLiteral(-999, 10, 2);
- const auto data8 = pb.NewDecimalLiteral(0, 10, 2);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToDecimal(item, 12, 4);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 33300);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -10000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -12000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 300);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 7700);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 12200);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 122300);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -99900);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestScaleDown) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDecimalType(10, 2);
- const auto data0 = pb.NewDecimalLiteral(-251, 10, 2);
- const auto data1 = pb.NewDecimalLiteral(-250, 10, 2);
- const auto data2 = pb.NewDecimalLiteral(-150, 10, 2);
- const auto data3 = pb.NewDecimalLiteral(-51, 10, 2);
- const auto data4 = pb.NewDecimalLiteral(50, 10, 2);
- const auto data5 = pb.NewDecimalLiteral(50, 10, 2);
- const auto data6 = pb.NewDecimalLiteral(51, 10, 2);
- const auto data7 = pb.NewDecimalLiteral(150, 10, 2);
- const auto data8 = pb.NewDecimalLiteral(250, 10, 2);
- const auto data9 = pb.NewDecimalLiteral(251, 10, 2);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToDecimal(item, 8, 0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMinMax) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 2);
- const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 2);
- const auto data3 = pb.NewDecimalLiteral(314, 13, 2);
- const auto data4 = pb.NewDecimalLiteral(-213, 13, 2);
- const auto data5 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 2);
- const auto dataType = pb.NewDecimalType(13, 2);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode left) {
- return pb.Map(list,
- [&](TRuntimeNode right) {
- return pb.NewTuple({pb.Min(left, right), pb.Max(left, right)});
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestAddSub) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 2);
- const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 2);
- const auto data3 = pb.NewDecimalLiteral(314, 13, 2);
- const auto data4 = pb.NewDecimalLiteral(-213, 13, 2);
- const auto data5 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 2);
-
- const auto dataType = pb.NewDecimalType(13, 2);
- const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode left) {
- return pb.Map(list,
- [&](TRuntimeNode right) {
- return pb.NewTuple({pb.Add(left, right), pb.Sub(left, right)});
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 628);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 101);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 527);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 101);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -527);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -426);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCompares) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1l = pb.NewDecimalLiteral(-7, 10, 0);
- const auto data2l = pb.NewDecimalLiteral(3, 10, 0);
- const auto data3l = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
- const auto data4l = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 0);
- const auto data5l = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 0);
-
- const auto data1r = pb.NewDecimalLiteral(-700, 7, 2);
- const auto data2r = pb.NewDecimalLiteral(300, 7, 2);
- const auto data3r = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 7, 2);
- const auto data4r = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 7, 2);
- const auto data5r = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 7, 2);
-
- auto pairType = pb.NewTupleType({pb.NewDecimalType(10, 0), pb.NewDecimalType(7, 2)});
- const auto list = pb.NewList(pairType, {
- pb.NewTuple({data1l, data1r}),
- pb.NewTuple({data1l, data2r}),
- pb.NewTuple({data1l, data3r}),
- pb.NewTuple({data1l, data4r}),
- pb.NewTuple({data1l, data5r}),
-
- pb.NewTuple({data2l, data1r}),
- pb.NewTuple({data2l, data2r}),
- pb.NewTuple({data2l, data3r}),
- pb.NewTuple({data2l, data4r}),
- pb.NewTuple({data2l, data5r}),
-
- pb.NewTuple({data3l, data1r}),
- pb.NewTuple({data3l, data2r}),
- pb.NewTuple({data3l, data3r}),
- pb.NewTuple({data3l, data4r}),
- pb.NewTuple({data3l, data5r}),
-
- pb.NewTuple({data4l, data1r}),
- pb.NewTuple({data4l, data2r}),
- pb.NewTuple({data4l, data3r}),
- pb.NewTuple({data4l, data4r}),
- pb.NewTuple({data4l, data5r}),
-
- pb.NewTuple({data5l, data1r}),
- pb.NewTuple({data5l, data2r}),
- pb.NewTuple({data5l, data3r}),
- pb.NewTuple({data5l, data4r}),
- pb.NewTuple({data5l, data5r}),
- });
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestComparesWithIntegral) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto optType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i64>::Id));
-
- const auto data1l = pb.NewOptional(pb.NewDataLiteral<i64>(-7LL));
- const auto data2l = pb.NewOptional(pb.NewDataLiteral<i64>(3LL));
- const auto data3l = pb.NewEmptyOptional(optType);
- const auto data4l = pb.NewOptional(pb.NewDataLiteral<i64>(std::numeric_limits<i64>::min()));
- const auto data5l = pb.NewOptional(pb.NewDataLiteral<i64>(std::numeric_limits<i64>::max()));
-
- const auto data1r = pb.NewDecimalLiteral(-7000000000000000000LL, 20, 18);
- const auto data2r = pb.NewDecimalLiteral(3000000000000000000LL, 20, 18);
- const auto data3r = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 20, 18);
- const auto data4r = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 20, 18);
- const auto data5r = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 20, 18);
-
- auto pairType = pb.NewTupleType({optType, pb.NewDecimalType(20, 18)});
- const auto list = pb.NewList(pairType, {
- pb.NewTuple({data1l, data1r}),
- pb.NewTuple({data1l, data2r}),
- pb.NewTuple({data1l, data3r}),
- pb.NewTuple({data1l, data4r}),
- pb.NewTuple({data1l, data5r}),
-
- pb.NewTuple({data2l, data1r}),
- pb.NewTuple({data2l, data2r}),
- pb.NewTuple({data2l, data3r}),
- pb.NewTuple({data2l, data4r}),
- pb.NewTuple({data2l, data5r}),
-
- pb.NewTuple({data3l, data1r}),
- pb.NewTuple({data3l, data2r}),
- pb.NewTuple({data3l, data3r}),
- pb.NewTuple({data3l, data4r}),
- pb.NewTuple({data3l, data5r}),
-
- pb.NewTuple({data4l, data1r}),
- pb.NewTuple({data4l, data2r}),
- pb.NewTuple({data4l, data3r}),
- pb.NewTuple({data4l, data4r}),
- pb.NewTuple({data4l, data5r}),
-
- pb.NewTuple({data5l, data1r}),
- pb.NewTuple({data5l, data2r}),
- pb.NewTuple({data5l, data3r}),
- pb.NewTuple({data5l, data4r}),
- pb.NewTuple({data5l, data5r}),
- });
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0)); // ==
- UNIT_ASSERT(!item.GetElement(1)); // !=
- UNIT_ASSERT(!item.GetElement(2)); // <
- UNIT_ASSERT(!item.GetElement(3)); // <=
- UNIT_ASSERT(!item.GetElement(4)); // >
- UNIT_ASSERT(!item.GetElement(5)); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestAggrCompares) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDecimalLiteral(-7, 10, 0);
- const auto data2 = pb.NewDecimalLiteral(3, 10, 0);
- const auto data3 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
- const auto data4 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 0);
- const auto data5 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 0);
-
- auto pairType = pb.NewTupleType({pb.NewDecimalType(10, 0), pb.NewDecimalType(10, 0)});
- const auto list = pb.NewList(pairType, {
- pb.NewTuple({data1, data1}),
- pb.NewTuple({data1, data2}),
- pb.NewTuple({data1, data3}),
- pb.NewTuple({data1, data4}),
- pb.NewTuple({data1, data5}),
-
- pb.NewTuple({data2, data1}),
- pb.NewTuple({data2, data2}),
- pb.NewTuple({data2, data3}),
- pb.NewTuple({data2, data4}),
- pb.NewTuple({data2, data5}),
-
- pb.NewTuple({data3, data1}),
- pb.NewTuple({data3, data2}),
- pb.NewTuple({data3, data3}),
- pb.NewTuple({data3, data4}),
- pb.NewTuple({data3, data5}),
-
- pb.NewTuple({data4, data1}),
- pb.NewTuple({data4, data2}),
- pb.NewTuple({data4, data3}),
- pb.NewTuple({data4, data4}),
- pb.NewTuple({data4, data5}),
-
- pb.NewTuple({data5, data1}),
- pb.NewTuple({data5, data2}),
- pb.NewTuple({data5, data3}),
- pb.NewTuple({data5, data4}),
- pb.NewTuple({data5, data5}),
- });
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({
- pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
- pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
- UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
- UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
- UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
- UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
- UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestIncDec) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 4, 1);
- const auto data2 = pb.NewDecimalLiteral(-9999, 4, 1);
- const auto data3 = pb.NewDecimalLiteral(-7, 4, 1);
- const auto data4 = pb.NewDecimalLiteral(0, 4, 1);
- const auto data5 = pb.NewDecimalLiteral(13, 4, 1);
- const auto data6 = pb.NewDecimalLiteral(9999, 4, 1);
- const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 4, 1);
- const auto data8 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 4, 1);
-
- const auto list = pb.NewList(pb.NewDecimalType(4, 1), {data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Increment(item), pb.Decrement(item)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -9998);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -6);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -8);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +1);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == -1);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 14);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 12);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 9998);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestMinusAbs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 10, 1);
- const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 1);
- const auto data3 = pb.NewDecimalLiteral(-7, 10, 1);
- const auto data4 = pb.NewDecimalLiteral(0, 10, 1);
- const auto data5 = pb.NewDecimalLiteral(13, 10, 1);
- const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 1);
- const auto data8 = pb.NewDecimalLiteral(+NYql::NDecimal::Nan(), 10, 1);
-
- const auto list = pb.NewList(pb.NewDecimalType(10, 1), {data0, data1, data3, data4, data5, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Minus(item), pb.Abs(item)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 7);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 7);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == 0);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -13);
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +13);
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFromString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("1.0");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-.1");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("3.1415926");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
- const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>(".123E+2");
- const auto data8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("56.78e-3");
- const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.StrictFromString(item, pb.NewDecimalType(10, 7));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 10000000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -1000000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 31415926);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == +NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 123000000);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetInt128() == 567800);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestToString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDecimalLiteral(0, 10, 7);
- const auto data1 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 7);
- const auto data2 = pb.NewDecimalLiteral(10000000, 10, 7);
- const auto data3 = pb.NewDecimalLiteral(-1000000, 10, 7);
- const auto data4 = pb.NewDecimalLiteral(31415926, 10, 7);
- const auto data5 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 7);
- const auto data6 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 7);
- const auto type = pb.NewDecimalType(10, 7);
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.ToString(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "0");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "nan");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "1");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-0.1");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "3.1415926");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "inf");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "-inf");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFromStringToDouble) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+3.332873");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.332873");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+3.1415926");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.1415926");
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(pb.FromString(item, pb.NewDecimalType(35,25)), pb.NewDataType(NUdf::TDataType<double>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
-
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), 0.);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), +3.332873);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), -3.332873);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), +3.1415926);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), -3.1415926);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFromUtf8ToFloat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("0");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("+24.75");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("-24.75");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("+42.42");
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("-42.42");
-
- const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.Convert(pb.FromString(item, pb.NewDecimalType(35,25)), pb.NewDataType(NUdf::TDataType<float>::Id));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
-
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), 0.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), +24.75f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), -24.75f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), +42.42f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), -42.42f);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewOptionalType(pb.NewDecimalType(13, 5));
+ const auto data0 = pb.NewOptional(pb.NewDecimalLiteral(0, 13, 5));
+ const auto data1 = pb.NewOptional(pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 13, 5));
+ const auto data2 = pb.NewOptional(pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 5));
+ const auto data3 = pb.NewOptional(pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 5));
+ const auto data4 = pb.NewEmptyOptional(type);
+ const auto data5 = pb.NewOptional(pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 5));
+ const auto data = pb.NewDecimalLiteral(314159, 13, 5);
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Nanvl(item, data);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 314159);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 314159);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToIntegral) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDecimalType(13, 1);
+ const auto data0 = pb.NewDecimalLiteral(0, 13, 1);
+ const auto data1 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 13, 1);
+ const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 1);
+ const auto data3 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 1);
+ const auto data4 = pb.NewDecimalLiteral(1270, 13, 1);
+ const auto data5 = pb.NewDecimalLiteral(-1280, 13, 1);
+ const auto data6 = pb.NewDecimalLiteral(2550, 13, 1);
+ const auto data7 = pb.NewDecimalLiteral(-2560, 13, 1);
+ const auto data8 = pb.NewDecimalLiteral(2560, 13, 1);
+ const auto data9 = pb.NewDecimalLiteral(-2570, 13, 1);
+ const auto dataA = pb.NewDecimalLiteral(327670, 13, 1);
+ const auto dataB = pb.NewDecimalLiteral(-327680, 13, 1);
+ const auto dataC = pb.NewDecimalLiteral(655350, 13, 1);
+ const auto dataD = pb.NewDecimalLiteral(-655360, 13, 1);
+ const auto dataE = pb.NewDecimalLiteral(21474836470, 13, 1);
+ const auto dataF = pb.NewDecimalLiteral(-21474836480, 13, 1);
+ const auto dataG = pb.NewDecimalLiteral(21474836480, 13, 1);
+ const auto dataH = pb.NewDecimalLiteral(-21474836490, 13, 1);
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, dataA, dataB, dataC, dataD, dataE, dataF, dataG, dataH});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui8>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui16>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui32>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<i64>::Id, true)),
+ pb.ToIntegral(item, pb.NewDataType(NUdf::TDataType<ui64>::Id, true))
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT(!item.GetElements()[6]);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 127);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 127);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[0].Get<i8>(), -128);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -128);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -128);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -128);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[1].Get<ui8>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 255);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 255);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -256);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -256);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -256);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 256);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 256);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 256);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 256);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 256);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 256);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -257);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -257);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -257);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), 32767);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 32767);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 32767);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 32767);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 32767);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 32767);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[2].Get<i16>(), -32768);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -32768);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -32768);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[3].Get<ui16>(), 65535);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 65535);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 65535);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 65535);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 65535);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -65536);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -65536);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), 2147483647LL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 2147483647LL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 2147483647LL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 2147483647LL);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[4].Get<i32>(), -2147483648LL);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -2147483648LL);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[5].Get<ui32>(), 2147483648LL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), 2147483648LL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[7].Get<ui64>(), 2147483648LL);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElements()[0]);
+ UNIT_ASSERT(!item.GetElements()[1]);
+ UNIT_ASSERT(!item.GetElements()[2]);
+ UNIT_ASSERT(!item.GetElements()[3]);
+ UNIT_ASSERT(!item.GetElements()[4]);
+ UNIT_ASSERT(!item.GetElements()[5]);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElements()[6].Get<i64>(), -2147483649LL);
+ UNIT_ASSERT(!item.GetElements()[7]);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToFloat) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 3);
+ const auto data0 = pb.NewDecimalLiteral(2123, 10, 3);
+ const auto data1 = pb.NewDecimalLiteral(233, 10, 3);
+ const auto data2 = pb.NewDecimalLiteral(0, 10, 3);
+ const auto data3 = pb.NewDecimalLiteral(-3277823, 10, 3);
+ const auto data4 = pb.NewDecimalLiteral(-1, 10, 3);
+ const auto data5 = pb.NewDecimalLiteral(7128, 10, 3);
+ const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 3);
+ const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 3);
+ const auto data8 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 3);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<float>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 2.123f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.233f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 0.0f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -3277.823f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -0.001f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), 7.128f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isnan(item.template Get<float>()));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isinf(item.template Get<float>()) && item.template Get<float>() > 0.0f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isinf(item.template Get<float>()) && item.template Get<float>() < 0.0f);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToDouble) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 5);
+ const auto data0 = pb.NewDecimalLiteral(2123, 10, 5);
+ const auto data1 = pb.NewDecimalLiteral(233, 10, 5);
+ const auto data2 = pb.NewDecimalLiteral(0, 10, 5);
+ const auto data3 = pb.NewDecimalLiteral(-3277823, 10, 5);
+ const auto data4 = pb.NewDecimalLiteral(-1, 10, 5);
+ const auto data5 = pb.NewDecimalLiteral(7128, 10, 5);
+ const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 5);
+ const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 5);
+ const auto data8 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 5);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(item, pb.NewDataType(NUdf::TDataType<double>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.02123);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.00233);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -32.77823);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -0.00001);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 0.07128);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isnan(item.template Get<double>()));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isinf(item.template Get<double>()) && item.template Get<double>() > 0.0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(std::isinf(item.template Get<double>()) && item.template Get<double>() < 0.0);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDiv) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 0);
+ const auto data0 = pb.NewDecimalLiteral(2, 10, 0);
+ const auto data1 = pb.NewDecimalLiteral(23, 10, 0);
+ const auto data2 = pb.NewDecimalLiteral(-23, 10, 0);
+ const auto data3 = pb.NewDecimalLiteral(25, 10, 0);
+ const auto data4 = pb.NewDecimalLiteral(-25, 10, 0);
+ const auto data5 = pb.NewDecimalLiteral(1, 10, 0);
+ const auto data6 = pb.NewDecimalLiteral(-1, 10, 0);
+ const auto data7 = pb.NewDecimalLiteral(3, 10, 0);
+ const auto data8 = pb.NewDecimalLiteral(-3, 10, 0);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalDiv(item, data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 12);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -12);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 12);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -12);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDivInt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
+ const auto data0 = pb.NewDecimalLiteral(-238973, 9, 3);
+ const auto data1 = pb.NewDataLiteral<i8>(0);
+ const auto data2 = pb.NewDataLiteral<i8>(-1);
+ const auto data3 = pb.NewDataLiteral<i8>(-128);
+ const auto data4 = pb.NewDataLiteral<i8>(3);
+ const auto data5 = pb.NewDataLiteral<i8>(5);
+ const auto data6 = pb.NewDataLiteral<i8>(-7);
+ const auto data7 = pb.NewDataLiteral<i8>(13);
+ const auto data8 = pb.NewDataLiteral<i8>(-19);
+ const auto data9 = pb.NewDataLiteral<i8>(42);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalDiv(data0, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 238973);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 1866);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -79658);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -47795);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 34139);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -18383);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 12577);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -5690);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestMod) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(5, 2);
+ const auto data0 = pb.NewDecimalLiteral(-12323, 5, 2);
+ const auto data1 = pb.NewDecimalLiteral(0, 5, 2);
+ const auto data2 = pb.NewDecimalLiteral(NYql::NDecimal::Inf(), 5, 2);
+ const auto data3 = pb.NewDecimalLiteral(-1, 5, 2);
+ const auto data4 = pb.NewDecimalLiteral(2, 5, 2);
+ const auto data5 = pb.NewDecimalLiteral(-3, 5, 2);
+ const auto data6 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 5, 2);
+ const auto data7 = pb.NewDecimalLiteral(7, 5, 2);
+ const auto data8 = pb.NewDecimalLiteral(-10000, 5, 2);
+ const auto data9 = pb.NewDecimalLiteral(12329, 5, 2);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalMod(data0, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -2323);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -12323);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestModInt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i16>::Id);
+ const auto data0 = pb.NewDecimalLiteral(-743, 3, 2);
+ const auto data1 = pb.NewDataLiteral<i16>(0);
+ const auto data2 = pb.NewDataLiteral<i16>(1);
+ const auto data3 = pb.NewDataLiteral<i16>(-2);
+ const auto data4 = pb.NewDataLiteral<i16>(3);
+ const auto data5 = pb.NewDataLiteral<i16>(4);
+ const auto data6 = pb.NewDataLiteral<i16>(-5);
+ const auto data7 = pb.NewDataLiteral<i16>(8);
+ const auto data8 = pb.NewDataLiteral<i16>(10);
+ const auto data9 = pb.NewDataLiteral<i16>(-10);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalMod(data0, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -43);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -143);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -143);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -343);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -243);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -743);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -743);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -743);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestMul) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 2);
+ const auto data0 = pb.NewDecimalLiteral(333, 10, 2);
+ const auto data1 = pb.NewDecimalLiteral(-100, 10, 2);
+ const auto data2 = pb.NewDecimalLiteral(-120, 10, 2);
+ const auto data3 = pb.NewDecimalLiteral(3, 10, 2);
+ const auto data4 = pb.NewDecimalLiteral(77, 10, 2);
+ const auto data5 = pb.NewDecimalLiteral(122, 10, 2);
+ const auto data6 = pb.NewDecimalLiteral(1223, 10, 2);
+ const auto data7 = pb.NewDecimalLiteral(-999, 10, 2);
+ const auto data8 = pb.NewDecimalLiteral(0, 10, 2);
+ const auto data9 = pb.NewDecimalLiteral(-3003003003LL, 10, 2);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalMul(item, data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 1109);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -333);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -400);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 10);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 256);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 406);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 4073);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -3327);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestMulInt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
+ const auto data0 = pb.NewDecimalLiteral(-333, 7, 2);
+ const auto data1 = pb.NewDataLiteral<ui16>(0);
+ const auto data2 = pb.NewDataLiteral<ui16>(1);
+ const auto data3 = pb.NewDataLiteral<ui16>(2);
+ const auto data4 = pb.NewDataLiteral<ui16>(3);
+ const auto data5 = pb.NewDataLiteral<ui16>(10);
+ const auto data6 = pb.NewDataLiteral<ui16>(100);
+ const auto data7 = pb.NewDataLiteral<ui16>(1000);
+ const auto data8 = pb.NewDataLiteral<ui16>(10000);
+ const auto data9 = pb.NewDataLiteral<ui16>(65535);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalMul(data0, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -333);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -666);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -999);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -3330);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -33300);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -333000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -3330000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestLongintMul) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 0);
+ const auto data0 = pb.NewDecimalLiteral(333, 10, 0);
+ const auto data1 = pb.NewDecimalLiteral(-100, 10, 0);
+ const auto data2 = pb.NewDecimalLiteral(-120, 10, 0);
+ const auto data3 = pb.NewDecimalLiteral(3, 10, 0);
+ const auto data4 = pb.NewDecimalLiteral(77, 10, 0);
+ const auto data5 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
+ const auto data6 = pb.NewDecimalLiteral(30030031, 10, 0);
+ const auto data7 = pb.NewDecimalLiteral(-30030031, 10, 0);
+ const auto data8 = pb.NewDecimalLiteral(0, 10, 0);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.DecimalMul(item, data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 110889);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -33300);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -39960);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 999);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 25641);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestScaleUp) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 2);
+ const auto data0 = pb.NewDecimalLiteral(333, 10, 2);
+ const auto data1 = pb.NewDecimalLiteral(-100, 10, 2);
+ const auto data2 = pb.NewDecimalLiteral(-120, 10, 2);
+ const auto data3 = pb.NewDecimalLiteral(3, 10, 2);
+ const auto data4 = pb.NewDecimalLiteral(77, 10, 2);
+ const auto data5 = pb.NewDecimalLiteral(122, 10, 2);
+ const auto data6 = pb.NewDecimalLiteral(1223, 10, 2);
+ const auto data7 = pb.NewDecimalLiteral(-999, 10, 2);
+ const auto data8 = pb.NewDecimalLiteral(0, 10, 2);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToDecimal(item, 12, 4);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 33300);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -10000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -12000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 300);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 7700);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 12200);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 122300);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -99900);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestScaleDown) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDecimalType(10, 2);
+ const auto data0 = pb.NewDecimalLiteral(-251, 10, 2);
+ const auto data1 = pb.NewDecimalLiteral(-250, 10, 2);
+ const auto data2 = pb.NewDecimalLiteral(-150, 10, 2);
+ const auto data3 = pb.NewDecimalLiteral(-51, 10, 2);
+ const auto data4 = pb.NewDecimalLiteral(50, 10, 2);
+ const auto data5 = pb.NewDecimalLiteral(50, 10, 2);
+ const auto data6 = pb.NewDecimalLiteral(51, 10, 2);
+ const auto data7 = pb.NewDecimalLiteral(150, 10, 2);
+ const auto data8 = pb.NewDecimalLiteral(250, 10, 2);
+ const auto data9 = pb.NewDecimalLiteral(251, 10, 2);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToDecimal(item, 8, 0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMax) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 2);
+ const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 2);
+ const auto data3 = pb.NewDecimalLiteral(314, 13, 2);
+ const auto data4 = pb.NewDecimalLiteral(-213, 13, 2);
+ const auto data5 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 2);
+ const auto dataType = pb.NewDecimalType(13, 2);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode left) {
+ return pb.Map(list,
+ [&](TRuntimeNode right) {
+ return pb.NewTuple({pb.Min(left, right), pb.Max(left, right)});
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 314);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -213);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 314);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -213);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestAddSub) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 13, 2);
+ const auto data2 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 13, 2);
+ const auto data3 = pb.NewDecimalLiteral(314, 13, 2);
+ const auto data4 = pb.NewDecimalLiteral(-213, 13, 2);
+ const auto data5 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 13, 2);
+
+ const auto dataType = pb.NewDecimalType(13, 2);
+ const auto list = pb.NewList(dataType, {data1, data2, data3, data4, data5});
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode left) {
+ return pb.Map(list,
+ [&](TRuntimeNode right) {
+ return pb.NewTuple({pb.Add(left, right), pb.Sub(left, right)});
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 628);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 101);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 527);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 101);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -527);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -426);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCompares) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1l = pb.NewDecimalLiteral(-7, 10, 0);
+ const auto data2l = pb.NewDecimalLiteral(3, 10, 0);
+ const auto data3l = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
+ const auto data4l = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 0);
+ const auto data5l = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 0);
+
+ const auto data1r = pb.NewDecimalLiteral(-700, 7, 2);
+ const auto data2r = pb.NewDecimalLiteral(300, 7, 2);
+ const auto data3r = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 7, 2);
+ const auto data4r = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 7, 2);
+ const auto data5r = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 7, 2);
+
+ auto pairType = pb.NewTupleType({pb.NewDecimalType(10, 0), pb.NewDecimalType(7, 2)});
+ const auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1l, data1r}),
+ pb.NewTuple({data1l, data2r}),
+ pb.NewTuple({data1l, data3r}),
+ pb.NewTuple({data1l, data4r}),
+ pb.NewTuple({data1l, data5r}),
+
+ pb.NewTuple({data2l, data1r}),
+ pb.NewTuple({data2l, data2r}),
+ pb.NewTuple({data2l, data3r}),
+ pb.NewTuple({data2l, data4r}),
+ pb.NewTuple({data2l, data5r}),
+
+ pb.NewTuple({data3l, data1r}),
+ pb.NewTuple({data3l, data2r}),
+ pb.NewTuple({data3l, data3r}),
+ pb.NewTuple({data3l, data4r}),
+ pb.NewTuple({data3l, data5r}),
+
+ pb.NewTuple({data4l, data1r}),
+ pb.NewTuple({data4l, data2r}),
+ pb.NewTuple({data4l, data3r}),
+ pb.NewTuple({data4l, data4r}),
+ pb.NewTuple({data4l, data5r}),
+
+ pb.NewTuple({data5l, data1r}),
+ pb.NewTuple({data5l, data2r}),
+ pb.NewTuple({data5l, data3r}),
+ pb.NewTuple({data5l, data4r}),
+ pb.NewTuple({data5l, data5r}),
+ });
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestComparesWithIntegral) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto optType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i64>::Id));
+
+ const auto data1l = pb.NewOptional(pb.NewDataLiteral<i64>(-7LL));
+ const auto data2l = pb.NewOptional(pb.NewDataLiteral<i64>(3LL));
+ const auto data3l = pb.NewEmptyOptional(optType);
+ const auto data4l = pb.NewOptional(pb.NewDataLiteral<i64>(std::numeric_limits<i64>::min()));
+ const auto data5l = pb.NewOptional(pb.NewDataLiteral<i64>(std::numeric_limits<i64>::max()));
+
+ const auto data1r = pb.NewDecimalLiteral(-7000000000000000000LL, 20, 18);
+ const auto data2r = pb.NewDecimalLiteral(3000000000000000000LL, 20, 18);
+ const auto data3r = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 20, 18);
+ const auto data4r = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 20, 18);
+ const auto data5r = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 20, 18);
+
+ auto pairType = pb.NewTupleType({optType, pb.NewDecimalType(20, 18)});
+ const auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1l, data1r}),
+ pb.NewTuple({data1l, data2r}),
+ pb.NewTuple({data1l, data3r}),
+ pb.NewTuple({data1l, data4r}),
+ pb.NewTuple({data1l, data5r}),
+
+ pb.NewTuple({data2l, data1r}),
+ pb.NewTuple({data2l, data2r}),
+ pb.NewTuple({data2l, data3r}),
+ pb.NewTuple({data2l, data4r}),
+ pb.NewTuple({data2l, data5r}),
+
+ pb.NewTuple({data3l, data1r}),
+ pb.NewTuple({data3l, data2r}),
+ pb.NewTuple({data3l, data3r}),
+ pb.NewTuple({data3l, data4r}),
+ pb.NewTuple({data3l, data5r}),
+
+ pb.NewTuple({data4l, data1r}),
+ pb.NewTuple({data4l, data2r}),
+ pb.NewTuple({data4l, data3r}),
+ pb.NewTuple({data4l, data4r}),
+ pb.NewTuple({data4l, data5r}),
+
+ pb.NewTuple({data5l, data1r}),
+ pb.NewTuple({data5l, data2r}),
+ pb.NewTuple({data5l, data3r}),
+ pb.NewTuple({data5l, data4r}),
+ pb.NewTuple({data5l, data5r}),
+ });
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.Equals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.NotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Less(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.LessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.Greater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.GreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0)); // ==
+ UNIT_ASSERT(!item.GetElement(1)); // !=
+ UNIT_ASSERT(!item.GetElement(2)); // <
+ UNIT_ASSERT(!item.GetElement(3)); // <=
+ UNIT_ASSERT(!item.GetElement(4)); // >
+ UNIT_ASSERT(!item.GetElement(5)); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestAggrCompares) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDecimalLiteral(-7, 10, 0);
+ const auto data2 = pb.NewDecimalLiteral(3, 10, 0);
+ const auto data3 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 0);
+ const auto data4 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 0);
+ const auto data5 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 0);
+
+ auto pairType = pb.NewTupleType({pb.NewDecimalType(10, 0), pb.NewDecimalType(10, 0)});
+ const auto list = pb.NewList(pairType, {
+ pb.NewTuple({data1, data1}),
+ pb.NewTuple({data1, data2}),
+ pb.NewTuple({data1, data3}),
+ pb.NewTuple({data1, data4}),
+ pb.NewTuple({data1, data5}),
+
+ pb.NewTuple({data2, data1}),
+ pb.NewTuple({data2, data2}),
+ pb.NewTuple({data2, data3}),
+ pb.NewTuple({data2, data4}),
+ pb.NewTuple({data2, data5}),
+
+ pb.NewTuple({data3, data1}),
+ pb.NewTuple({data3, data2}),
+ pb.NewTuple({data3, data3}),
+ pb.NewTuple({data3, data4}),
+ pb.NewTuple({data3, data5}),
+
+ pb.NewTuple({data4, data1}),
+ pb.NewTuple({data4, data2}),
+ pb.NewTuple({data4, data3}),
+ pb.NewTuple({data4, data4}),
+ pb.NewTuple({data4, data5}),
+
+ pb.NewTuple({data5, data1}),
+ pb.NewTuple({data5, data2}),
+ pb.NewTuple({data5, data3}),
+ pb.NewTuple({data5, data4}),
+ pb.NewTuple({data5, data5}),
+ });
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({
+ pb.AggrEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrNotEquals(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLess(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrLessOrEqual(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreater(pb.Nth(item, 0), pb.Nth(item, 1)),
+ pb.AggrGreaterOrEqual(pb.Nth(item, 0), pb.Nth(item, 1))
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(!item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(!item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).template Get<bool>()); // ==
+ UNIT_ASSERT(!item.GetElement(1).template Get<bool>()); // !=
+ UNIT_ASSERT(!item.GetElement(2).template Get<bool>()); // <
+ UNIT_ASSERT(item.GetElement(3).template Get<bool>()); // <=
+ UNIT_ASSERT(!item.GetElement(4).template Get<bool>()); // >
+ UNIT_ASSERT(item.GetElement(5).template Get<bool>()); // >=
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestIncDec) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 4, 1);
+ const auto data2 = pb.NewDecimalLiteral(-9999, 4, 1);
+ const auto data3 = pb.NewDecimalLiteral(-7, 4, 1);
+ const auto data4 = pb.NewDecimalLiteral(0, 4, 1);
+ const auto data5 = pb.NewDecimalLiteral(13, 4, 1);
+ const auto data6 = pb.NewDecimalLiteral(9999, 4, 1);
+ const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 4, 1);
+ const auto data8 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 4, 1);
+
+ const auto list = pb.NewList(pb.NewDecimalType(4, 1), {data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Increment(item), pb.Decrement(item)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -9998);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -6);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -8);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +1);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == -1);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 14);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 12);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 9998);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinusAbs) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDecimalLiteral(-NYql::NDecimal::Nan(), 10, 1);
+ const auto data1 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 1);
+ const auto data3 = pb.NewDecimalLiteral(-7, 10, 1);
+ const auto data4 = pb.NewDecimalLiteral(0, 10, 1);
+ const auto data5 = pb.NewDecimalLiteral(13, 10, 1);
+ const auto data7 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 1);
+ const auto data8 = pb.NewDecimalLiteral(+NYql::NDecimal::Nan(), 10, 1);
+
+ const auto list = pb.NewList(pb.NewDecimalType(10, 1), {data0, data1, data3, data4, data5, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Minus(item), pb.Abs(item)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 7);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 7);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == 0);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == 0);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -13);
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +13);
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == +NYql::NDecimal::Inf());
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0).GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(item.GetElement(1).GetInt128() == NYql::NDecimal::Nan());
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFromString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0.0");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("NAN");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("1.0");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-.1");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("3.1415926");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+inf");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-INF");
+ const auto data7 = pb.NewDataLiteral<NUdf::EDataSlot::String>(".123E+2");
+ const auto data8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("56.78e-3");
+ const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6, data7, data8});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.StrictFromString(item, pb.NewDecimalType(10, 7));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == NYql::NDecimal::Nan());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 10000000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -1000000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 31415926);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == +NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == -NYql::NDecimal::Inf());
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 123000000);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetInt128() == 567800);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestToString) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDecimalLiteral(0, 10, 7);
+ const auto data1 = pb.NewDecimalLiteral(NYql::NDecimal::Nan(), 10, 7);
+ const auto data2 = pb.NewDecimalLiteral(10000000, 10, 7);
+ const auto data3 = pb.NewDecimalLiteral(-1000000, 10, 7);
+ const auto data4 = pb.NewDecimalLiteral(31415926, 10, 7);
+ const auto data5 = pb.NewDecimalLiteral(+NYql::NDecimal::Inf(), 10, 7);
+ const auto data6 = pb.NewDecimalLiteral(-NYql::NDecimal::Inf(), 10, 7);
+ const auto type = pb.NewDecimalType(10, 7);
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4, data5, data6});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.ToString(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "0");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "nan");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "1");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-0.1");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "3.1415926");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "inf");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "-inf");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFromStringToDouble) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("0");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+3.332873");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.332873");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("+3.1415926");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("-3.1415926");
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(pb.FromString(item, pb.NewDecimalType(35,25)), pb.NewDataType(NUdf::TDataType<double>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), 0.);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), +3.332873);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), -3.332873);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), +3.1415926);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<double>(), -3.1415926);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFromUtf8ToFloat) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("0");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("+24.75");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("-24.75");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("+42.42");
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("-42.42");
+
+ const auto list = pb.NewList(type, {data0, data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.Convert(pb.FromString(item, pb.NewDecimalType(35,25)), pb.NewDataType(NUdf::TDataType<float>::Id));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), 0.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), +24.75f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), -24.75f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), +42.42f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<float>(), -42.42f);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_dict_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_dict_ut.cpp
index 1f8e8db062..ac6d4c356b 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_dict_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_dict_ut.cpp
@@ -1,391 +1,391 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLDictRelatedNodesTest) {
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLDictRelatedNodesTest) {
Y_UNIT_TEST_LLVM(TestDictLength) {
- TSetup<LLVM> setup;
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
TVector<std::pair<TRuntimeNode, TRuntimeNode>> dictItems;
dictItems.push_back(std::make_pair(key1, payload1));
dictItems.push_back(std::make_pair(key2, payload2));
dictItems.push_back(std::make_pair(key3, payload3));
- const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
+ const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
pgmBuilder.NewDataType(NUdf::TDataType<char*>::Id), false);
- const auto dict = pgmBuilder.NewDict(dictType, dictItems);
- const auto pgmReturn = pgmBuilder.Length(dict);
+ const auto dict = pgmBuilder.NewDict(dictType, dictItems);
+ const auto pgmReturn = pgmBuilder.Length(dict);
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().template Get<ui64>(), 2);
}
Y_UNIT_TEST_LLVM(TestDictContains) {
- TSetup<LLVM> setup;
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
- const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
+ const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
TVector<std::pair<TRuntimeNode, TRuntimeNode>> dictItems;
dictItems.push_back(std::make_pair(key1, payload1));
dictItems.push_back(std::make_pair(key2, payload2));
dictItems.push_back(std::make_pair(key3, payload3));
- const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
+ const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
pgmBuilder.NewDataType(NUdf::TDataType<char*>::Id), false);
- const auto dict = pgmBuilder.NewDict(dictType, dictItems);
- const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
-
- const auto pgmReturn = pgmBuilder.Map(keys,
- [&](TRuntimeNode key) {
- return pgmBuilder.Contains(dict, key);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto dict = pgmBuilder.NewDict(dictType, dictItems);
+ const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
+
+ const auto pgmReturn = pgmBuilder.Map(keys,
+ [&](TRuntimeNode key) {
+ return pgmBuilder.Contains(dict, key);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestDictLookup) {
- TSetup<LLVM> setup;
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
- const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
+ const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
TVector<std::pair<TRuntimeNode, TRuntimeNode>> dictItems;
dictItems.push_back(std::make_pair(key1, payload1));
dictItems.push_back(std::make_pair(key2, payload2));
dictItems.push_back(std::make_pair(key3, payload3));
- const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
+ const auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id),
pgmBuilder.NewDataType(NUdf::TDataType<char*>::Id), false);
- const auto dict = pgmBuilder.NewDict(dictType, dictItems);
- const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
-
- const auto pgmReturn = pgmBuilder.Map(keys,
- [&](TRuntimeNode key) {
- return pgmBuilder.Lookup(dict, key);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- UNBOXED_VALUE_STR_EQUAL(item, "A");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- UNBOXED_VALUE_STR_EQUAL(item, "B");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ const auto dict = pgmBuilder.NewDict(dictType, dictItems);
+ const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
+
+ const auto pgmReturn = pgmBuilder.Map(keys,
+ [&](TRuntimeNode key) {
+ return pgmBuilder.Lookup(dict, key);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ UNBOXED_VALUE_STR_EQUAL(item, "A");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ UNBOXED_VALUE_STR_EQUAL(item, "B");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- template<bool Multi>
- TRuntimeNode PrepareTestDict(TProgramBuilder& pgmBuilder, TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto key4 = pgmBuilder.NewDataLiteral<ui32>(5);
- const auto key5 = pgmBuilder.NewDataLiteral<ui32>(7);
- const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("D");
- const auto payload5 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("E");
+ template<bool Multi>
+ TRuntimeNode PrepareTestDict(TProgramBuilder& pgmBuilder, TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto key3 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto key4 = pgmBuilder.NewDataLiteral<ui32>(5);
+ const auto key5 = pgmBuilder.NewDataLiteral<ui32>(7);
+ const auto payload1 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("D");
+ const auto payload5 = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("E");
auto structType = pgmBuilder.NewStructType(pgmBuilder.NewEmptyStructType(), "Key", pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
structType = pgmBuilder.NewStructType(structType, "Payload", pgmBuilder.NewDataType(NUdf::TDataType<char*>::Id));
- const auto list = pgmBuilder.NewList(structType, {
- pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key3), "Payload", payload3),
- pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key5), "Payload", payload5),
- pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key4), "Payload", payload4),
- pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key2), "Payload", payload2)
- });
- const auto dict = (pgmBuilder.*factory)(list, Multi,
+ const auto list = pgmBuilder.NewList(structType, {
+ pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key3), "Payload", payload3),
+ pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key5), "Payload", payload5),
+ pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key4), "Payload", payload4),
+ pgmBuilder.AddMember(pgmBuilder.AddMember(pgmBuilder.NewEmptyStruct(), "Key", key2), "Payload", payload2)
+ });
+ const auto dict = (pgmBuilder.*factory)(list, Multi,
[&](TRuntimeNode item) {
return pgmBuilder.Member(item, "Key");
},
[&](TRuntimeNode item) {
return pgmBuilder.Member(item, "Payload");
}, false, 0);
- return dict;
- }
-
- template<bool LLVM>
- void TestConvertedDictContains(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
-
- TSetup<LLVM> setup;
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
-
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(42);
- const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
-
- const auto pgmReturn = pgmBuilder.Map(keys,
- [&](TRuntimeNode key) {
- return pgmBuilder.Contains(dict, key);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ return dict;
+ }
+
+ template<bool LLVM>
+ void TestConvertedDictContains(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+ const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
+
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(42);
+ const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
+
+ const auto pgmReturn = pgmBuilder.Map(keys,
+ [&](TRuntimeNode key) {
+ return pgmBuilder.Contains(dict, key);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- template<bool LLVM>
+ template<bool LLVM>
void TestConvertedDictLookup(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- TSetup<LLVM> setup;
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
-
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(18);
- const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
-
- const auto pgmReturn = pgmBuilder.Map(keys,
- [&](TRuntimeNode key) {
- return pgmBuilder.Lookup(dict, key);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- UNBOXED_VALUE_STR_EQUAL(item, "A");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- UNBOXED_VALUE_STR_EQUAL(item, "C");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
+
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(18);
+ const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
+
+ const auto pgmReturn = pgmBuilder.Map(keys,
+ [&](TRuntimeNode key) {
+ return pgmBuilder.Lookup(dict, key);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ UNBOXED_VALUE_STR_EQUAL(item, "A");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ UNBOXED_VALUE_STR_EQUAL(item, "C");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestSortedDictContains) {
- TestConvertedDictContains<LLVM>(&TProgramBuilder::ToSortedDict);
+ TestConvertedDictContains<LLVM>(&TProgramBuilder::ToSortedDict);
}
Y_UNIT_TEST_LLVM(TestSortedDictLookup) {
- TestConvertedDictLookup<LLVM>(&TProgramBuilder::ToSortedDict);
+ TestConvertedDictLookup<LLVM>(&TProgramBuilder::ToSortedDict);
}
Y_UNIT_TEST_LLVM(TestHashedDictContains) {
- TestConvertedDictContains<LLVM>(&TProgramBuilder::ToHashedDict);
+ TestConvertedDictContains<LLVM>(&TProgramBuilder::ToHashedDict);
}
Y_UNIT_TEST_LLVM(TestHashedDictLookup) {
- TestConvertedDictLookup<LLVM>(&TProgramBuilder::ToHashedDict);
+ TestConvertedDictLookup<LLVM>(&TProgramBuilder::ToHashedDict);
}
- template<bool LLVM, bool SortBeforeCompare>
+ template<bool LLVM, bool SortBeforeCompare>
void TestDictItemsImpl(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- TSetup<LLVM> setup;
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
- const auto pgmReturn = pgmBuilder.DictItems(dict);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
-
- std::vector<std::pair<ui32, TString>> items;
- for (NUdf::TUnboxedValue item; iterator.Next(item);) {
- const auto& pay = item.GetElement(1);
- items.emplace_back(item.GetElement(0).template Get<ui32>(), pay.AsStringRef());
- }
-
- if (SortBeforeCompare) {
- std::sort(items.begin(), items.end(), [](const std::pair<ui32, TString>& left, const std::pair<ui32, TString>& right) {
+ const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
+ const auto pgmReturn = pgmBuilder.DictItems(dict);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ std::vector<std::pair<ui32, TString>> items;
+ for (NUdf::TUnboxedValue item; iterator.Next(item);) {
+ const auto& pay = item.GetElement(1);
+ items.emplace_back(item.GetElement(0).template Get<ui32>(), pay.AsStringRef());
+ }
+
+ if (SortBeforeCompare) {
+ std::sort(items.begin(), items.end(), [](const std::pair<ui32, TString>& left, const std::pair<ui32, TString>& right) {
return left.first < right.first;
});
}
- UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
+ UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
UNIT_ASSERT_VALUES_EQUAL(items[0].first, 1);
UNIT_ASSERT_VALUES_EQUAL(items[0].second, "A");
UNIT_ASSERT_VALUES_EQUAL(items[1].first, 2);
UNIT_ASSERT_VALUES_EQUAL(items[1].second, "C");
- UNIT_ASSERT_VALUES_EQUAL(items[2].first, 5);
- UNIT_ASSERT_VALUES_EQUAL(items[2].second, "D");
- UNIT_ASSERT_VALUES_EQUAL(items[3].first, 7);
- UNIT_ASSERT_VALUES_EQUAL(items[3].second, "E");
+ UNIT_ASSERT_VALUES_EQUAL(items[2].first, 5);
+ UNIT_ASSERT_VALUES_EQUAL(items[2].second, "D");
+ UNIT_ASSERT_VALUES_EQUAL(items[3].first, 7);
+ UNIT_ASSERT_VALUES_EQUAL(items[3].second, "E");
+ }
+
+ template<bool LLVM, bool SortBeforeCompare>
+ void TestDictKeysImpl(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+ const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
+ const auto pgmReturn = pgmBuilder.DictKeys(dict);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ std::vector<ui32> items;
+ for (NUdf::TUnboxedValue item; iterator.Next(item);) {
+ items.emplace_back(item.template Get<ui32>());
+ }
+
+ if (SortBeforeCompare) {
+ std::sort(items.begin(), items.end());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
+ UNIT_ASSERT_VALUES_EQUAL(items[0], 1);
+ UNIT_ASSERT_VALUES_EQUAL(items[1], 2);
+ UNIT_ASSERT_VALUES_EQUAL(items[2], 5);
+ UNIT_ASSERT_VALUES_EQUAL(items[3], 7);
+ }
+
+ template<bool LLVM, bool SortBeforeCompare>
+ void TestDictPayloadsImpl(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+ const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
+ const auto pgmReturn = pgmBuilder.DictPayloads(dict);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+
+ std::vector<TString> items;
+ for (NUdf::TUnboxedValue item; iterator.Next(item);) {
+ items.emplace_back(item.AsStringRef());
+ }
+
+ if (SortBeforeCompare) {
+ std::sort(items.begin(), items.end());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
+ UNIT_ASSERT_VALUES_EQUAL(items[0], "A");
+ UNIT_ASSERT_VALUES_EQUAL(items[1], "C");
+ UNIT_ASSERT_VALUES_EQUAL(items[2], "D");
+ UNIT_ASSERT_VALUES_EQUAL(items[3], "E");
}
- template<bool LLVM, bool SortBeforeCompare>
- void TestDictKeysImpl(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- TSetup<LLVM> setup;
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
- const auto pgmReturn = pgmBuilder.DictKeys(dict);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
-
- std::vector<ui32> items;
- for (NUdf::TUnboxedValue item; iterator.Next(item);) {
- items.emplace_back(item.template Get<ui32>());
- }
-
- if (SortBeforeCompare) {
- std::sort(items.begin(), items.end());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
- UNIT_ASSERT_VALUES_EQUAL(items[0], 1);
- UNIT_ASSERT_VALUES_EQUAL(items[1], 2);
- UNIT_ASSERT_VALUES_EQUAL(items[2], 5);
- UNIT_ASSERT_VALUES_EQUAL(items[3], 7);
- }
-
- template<bool LLVM, bool SortBeforeCompare>
- void TestDictPayloadsImpl(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- TSetup<LLVM> setup;
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<false>(pgmBuilder, factory);
- const auto pgmReturn = pgmBuilder.DictPayloads(dict);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
-
- std::vector<TString> items;
- for (NUdf::TUnboxedValue item; iterator.Next(item);) {
- items.emplace_back(item.AsStringRef());
- }
-
- if (SortBeforeCompare) {
- std::sort(items.begin(), items.end());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(items.size(), 4U);
- UNIT_ASSERT_VALUES_EQUAL(items[0], "A");
- UNIT_ASSERT_VALUES_EQUAL(items[1], "C");
- UNIT_ASSERT_VALUES_EQUAL(items[2], "D");
- UNIT_ASSERT_VALUES_EQUAL(items[3], "E");
- }
-
Y_UNIT_TEST_LLVM(TestSortedDictItems) {
- TestDictItemsImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
+ TestDictItemsImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
}
Y_UNIT_TEST_LLVM(TestHashedDictItems) {
- TestDictItemsImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
+ TestDictItemsImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSortedDictKeys) {
+ TestDictKeysImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
+ }
+
+ Y_UNIT_TEST_LLVM(TestHashedDictKeys) {
+ TestDictKeysImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSortedPayloadsKeys) {
+ TestDictPayloadsImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
+ }
+
+ Y_UNIT_TEST_LLVM(TestHashedPayloadsKeys) {
+ TestDictPayloadsImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
}
- Y_UNIT_TEST_LLVM(TestSortedDictKeys) {
- TestDictKeysImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
- }
-
- Y_UNIT_TEST_LLVM(TestHashedDictKeys) {
- TestDictKeysImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
- }
-
- Y_UNIT_TEST_LLVM(TestSortedPayloadsKeys) {
- TestDictPayloadsImpl<LLVM, false>(&TProgramBuilder::ToSortedDict);
- }
-
- Y_UNIT_TEST_LLVM(TestHashedPayloadsKeys) {
- TestDictPayloadsImpl<LLVM, true>(&TProgramBuilder::ToHashedDict);
- }
-
- template<bool LLVM>
+ template<bool LLVM>
void TestConvertedMultiDictLookup(TRuntimeNode(TProgramBuilder::* factory)(TRuntimeNode list, bool multi,
- const TProgramBuilder::TUnaryLambda& keySelector,
- const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
+ const TProgramBuilder::TUnaryLambda& keySelector,
+ const TProgramBuilder::TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint)) {
- TSetup<LLVM> setup;
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- const auto dict = PrepareTestDict<true>(pgmBuilder, factory);
- const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
- const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
- const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
- const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
- const auto pgmReturn = pgmBuilder.Map(keys,
- [&](TRuntimeNode key) {
- return pgmBuilder.Lookup(dict, key);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item, item2;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- auto iter2 = item.GetListIterator();
- UNIT_ASSERT(iter2.Next(item2));
- UNBOXED_VALUE_STR_EQUAL(item2, "A");
- UNIT_ASSERT(!iter2.Next(item2));
- UNIT_ASSERT(!iter2.Next(item2));
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
- iter2 = item.GetListIterator();
- UNIT_ASSERT(iter2.Next(item2));
- UNBOXED_VALUE_STR_EQUAL(item2, "C");
- UNIT_ASSERT(iter2.Next(item2));
- UNBOXED_VALUE_STR_EQUAL(item2, "B");
- UNIT_ASSERT(!iter2.Next(item2));
- UNIT_ASSERT(!iter2.Next(item2));
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ const auto dict = PrepareTestDict<true>(pgmBuilder, factory);
+ const auto key1 = pgmBuilder.NewDataLiteral<ui32>(1);
+ const auto key2 = pgmBuilder.NewDataLiteral<ui32>(2);
+ const auto missingKey = pgmBuilder.NewDataLiteral<ui32>(3);
+ const auto keys = pgmBuilder.NewList(pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id), {key1, key2, missingKey});
+ const auto pgmReturn = pgmBuilder.Map(keys,
+ [&](TRuntimeNode key) {
+ return pgmBuilder.Lookup(dict, key);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item, item2;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ auto iter2 = item.GetListIterator();
+ UNIT_ASSERT(iter2.Next(item2));
+ UNBOXED_VALUE_STR_EQUAL(item2, "A");
+ UNIT_ASSERT(!iter2.Next(item2));
+ UNIT_ASSERT(!iter2.Next(item2));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
+ iter2 = item.GetListIterator();
+ UNIT_ASSERT(iter2.Next(item2));
+ UNBOXED_VALUE_STR_EQUAL(item2, "C");
+ UNIT_ASSERT(iter2.Next(item2));
+ UNBOXED_VALUE_STR_EQUAL(item2, "B");
+ UNIT_ASSERT(!iter2.Next(item2));
+ UNIT_ASSERT(!iter2.Next(item2));
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestSortedMultiDictLookup) {
- TestConvertedMultiDictLookup<LLVM>(&TProgramBuilder::ToSortedDict);
+ TestConvertedMultiDictLookup<LLVM>(&TProgramBuilder::ToSortedDict);
}
Y_UNIT_TEST_LLVM(TestHashedMultiDictLookup) {
- TestConvertedMultiDictLookup<LLVM>(&TProgramBuilder::ToHashedDict);
+ TestConvertedMultiDictLookup<LLVM>(&TProgramBuilder::ToHashedDict);
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_filters_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_filters_ut.cpp
index 63e395f23e..e2c1c4dc69 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_filters_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_filters_ut.cpp
@@ -1,1119 +1,1119 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLFiltersTest) {
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLFiltersTest) {
Y_UNIT_TEST_LLVM(TestSkipNullMembers) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.SkipNullMembers(list, {"Payload"});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.SkipNullMembers(list, {"Payload"});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullMembers) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FilterNullMembers(list, {"Payload"});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullMembersMultiOptional) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+ const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(1)))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2)))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", justNothing}, {"Payload", justNothing}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FilterNullMembers(list, {"Payload"});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipNullMembersOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.SkipNullMembers(pb.ToFlow(list), {"Payload"}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullMembersOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.FilterNullMembers(pb.ToFlow(list), {"Payload"}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullMembersMultiOptionalOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
+ const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
+ const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
+
+ const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(1)))}, {"Payload", pb.NewEmptyOptional(dataType)}});
+ const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2)))}});
+ const auto data3 = pb.NewStruct(structType, {{"Key", justNothing}, {"Payload", justNothing}});
+
+ const auto list = pb.NewList(structType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.FilterNullMembers(pb.ToFlow(list), {"Payload"}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipNullElements) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.SkipNullElements(list, {1U, 2U});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullElements) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FilterNullElements(list, {1U, 2U});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullElementsMultiOptional) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+ const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
+
+ const auto data1 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-1)))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2))), justNothing});
+ const auto data3 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-3)))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(4))), justNothing, pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-4)))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FilterNullElements(list, {1U, 2U});
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipNullElementsOverOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.SkipNullElements(pb.ToFlow(list), {1U, 2U}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullElementsOverOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.FilterNullElements(pb.ToFlow(list), {1U, 2U}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterNullElementsOverMultiOptionalOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+ const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
+
+ const auto data1 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-1)))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2))), justNothing});
+ const auto data3 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-3)))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(4))), justNothing, pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-4)))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.FilterNullElements(pb.ToFlow(list), {1U, 2U}));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullMembers) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FilterNullMembers(list, {"Payload"});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullMembersMultiOptional) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
- const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(1)))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2)))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", justNothing}, {"Payload", justNothing}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FilterNullMembers(list, {"Payload"});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipNullMembersOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.SkipNullMembers(pb.ToFlow(list), {"Payload"}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullMembersOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(1))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewDataLiteral<i32>(2))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewDataLiteral<i32>(3))}, {"Payload", pb.NewEmptyOptional(dataType)}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.FilterNullMembers(pb.ToFlow(list), {"Payload"}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullMembersMultiOptionalOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
- const auto structType = pb.NewStructType({{"Key", dataType}, {"Payload", dataType}});
- const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
-
- const auto data1 = pb.NewStruct(structType, {{"Key", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(1)))}, {"Payload", pb.NewEmptyOptional(dataType)}});
- const auto data2 = pb.NewStruct(structType, {{"Key", pb.NewEmptyOptional(dataType)}, {"Payload", pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2)))}});
- const auto data3 = pb.NewStruct(structType, {{"Key", justNothing}, {"Payload", justNothing}});
-
- const auto list = pb.NewList(structType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.FilterNullMembers(pb.ToFlow(list), {"Payload"}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipNullElements) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.SkipNullElements(list, {1U, 2U});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullElements) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FilterNullElements(list, {1U, 2U});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullElementsMultiOptional) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
- const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
-
- const auto data1 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-1)))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2))), justNothing});
- const auto data3 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-3)))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(4))), justNothing, pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-4)))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FilterNullElements(list, {1U, 2U});
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipNullElementsOverOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.SkipNullElements(pb.ToFlow(list), {1U, 2U}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullElementsOverOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.FilterNullElements(pb.ToFlow(list), {1U, 2U}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterNullElementsOverMultiOptionalOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id)));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
- const auto justNothing = pb.NewOptional(pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<i32>::Id));
-
- const auto data1 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-1)))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(2))), justNothing});
- const auto data3 = pb.NewTuple(tupleType, {justNothing, pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-3)))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(4))), justNothing, pb.NewOptional(pb.NewOptional(pb.NewDataLiteral<i32>(-4)))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.FilterNullElements(pb.ToFlow(list), {1U, 2U}));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFilterOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto list = pb.NewList(optionalType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(data2)});
-
- const auto pgmReturn = pb.Filter(list,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto list = pb.NewList(optionalType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(data2)});
+
+ const auto pgmReturn = pb.Filter(list,
[&](TRuntimeNode item) {
- return pb.Exists(item);
+ return pb.Exists(item);
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestFilterOverStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto data4 = pb.NewDataLiteral<ui32>(4);
- const auto data5 = pb.NewDataLiteral<ui32>(5);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
- const auto pgmReturn = pb.Filter(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Greater(pb.Unwrap(pb.Mod(item, data3), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data1);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto data4 = pb.NewDataLiteral<ui32>(4);
+ const auto data5 = pb.NewDataLiteral<ui32>(5);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
+ const auto pgmReturn = pb.Filter(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Greater(pb.Unwrap(pb.Mod(item, data3), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data1);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 5);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto data4 = pb.NewDataLiteral<ui32>(4);
- const auto data5 = pb.NewDataLiteral<ui32>(5);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
- const auto pgmReturn = pb.FromFlow(pb.Filter(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.Greater(pb.Unwrap(pb.Mod(item, data3), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data1);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 5);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto data4 = pb.NewDataLiteral<ui32>(4);
+ const auto data5 = pb.NewDataLiteral<ui32>(5);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5});
+ const auto pgmReturn = pb.FromFlow(pb.Filter(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.Greater(pb.Unwrap(pb.Mod(item, data3), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data1);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFilterOverListLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- const auto data = pb.NewEmptyOptional(dataType);
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2U));
- const auto list = pb.NewList(dataType, {data, data2});
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ const auto data = pb.NewEmptyOptional(dataType);
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2U));
+ const auto list = pb.NewList(dataType, {data, data2});
- const auto pgmReturn = pb.Filter(pb.LazyList(list),
- [&](TRuntimeNode item) { return pb.Exists(item); }
- );
+ const auto pgmReturn = pb.Filter(pb.LazyList(list),
+ [&](TRuntimeNode item) { return pb.Exists(item); }
+ );
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(item);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(item);
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestFilterByString) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("100"));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("200"));
- const auto data3 = pb.NewEmptyOptional(optionalType);
- const auto list = pb.NewList(optionalType, {data0, data1, data2, data3, data1, data0});
-
- const auto pgmReturn = pb.Filter(list,
- [&](TRuntimeNode item) {
- return pb.Coalesce(pb.Equals(item, data1), pb.NewDataLiteral<bool>(false));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), 2ULL);
- UNBOXED_VALUE_STR_EQUAL(result.GetElement(0U), "100");
- UNBOXED_VALUE_STR_EQUAL(result.GetElement(1U), "100");
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("100"));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("200"));
+ const auto data3 = pb.NewEmptyOptional(optionalType);
+ const auto list = pb.NewList(optionalType, {data0, data1, data2, data3, data1, data0});
+
+ const auto pgmReturn = pb.Filter(list,
+ [&](TRuntimeNode item) {
+ return pb.Coalesce(pb.Equals(item, data1), pb.NewDataLiteral<bool>(false));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), 2ULL);
+ UNBOXED_VALUE_STR_EQUAL(result.GetElement(0U), "100");
+ UNBOXED_VALUE_STR_EQUAL(result.GetElement(1U), "100");
+ }
+
Y_UNIT_TEST_LLVM(TestSkipWhile) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.SkipWhile(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "200");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "300");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.SkipWhile(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "200");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "300");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestTakeWhile) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.TakeWhile(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "000");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "100");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhileOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.SkipWhile(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "200");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "300");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhileOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.TakeWhile(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "000");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "100");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhileInclusive) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.SkipWhileInclusive(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "300");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhileInclusive) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.TakeWhileInclusive(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "000");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "100");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "200");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhileInclusiveOnEmptyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {});
-
- const auto pgmReturn = pb.SkipWhileInclusive(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhileInclusiveOnEmptyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {});
-
- const auto pgmReturn = pb.TakeWhileInclusive(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhileInclusiveOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.SkipWhileInclusive(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "300");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhileInclusiveOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.TakeWhileInclusive(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, data2);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "000");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "100");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNBOXED_VALUE_STR_EQUAL(item, "200");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDateToStringCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
- const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- const auto date = pb.ToIntegral(item, dateType);
- const auto utf8 = pb.ToString<true>(date);
- return pb.AggrNotEquals(date, pb.FromString(utf8, dateType));
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestTzDateToStringCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
- const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
- const auto dateTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDate, true);
- const auto canada = pb.NewDataLiteral<ui16>(375U);
- const auto europe = pb.NewDataLiteral<ui16>(459U);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- const auto date = pb.Unwrap(pb.ToIntegral(item, dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- const auto date1 = pb.Unwrap(pb.FromString(pb.ToString<true>(pb.AddTimezone(date, canada)), dateTypeTz), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- const auto date2 = pb.Unwrap(pb.FromString(pb.ToString<true>(pb.AddTimezone(date, europe)), dateTypeTz), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- return pb.Or({pb.NotEquals(date, date1), pb.NotEquals(date, date2)});
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestInt16ToFloatCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<i16>(std::numeric_limits<i16>::min()), pb.NewDataLiteral<i16>(std::numeric_limits<i16>::max()), pb.NewDataLiteral<i16>(1));
- const auto type = pb.NewDataType(NUdf::EDataSlot::Float);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, pb.Convert(item, type));
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestUint16ToFloatCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(std::numeric_limits<ui16>::min()), pb.NewDataLiteral<ui16>(std::numeric_limits<ui16>::max()), pb.NewDataLiteral<ui16>(1U));
- const auto type = pb.NewDataType(NUdf::EDataSlot::Float);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- return pb.NotEquals(item, pb.Convert(item, type));
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestDateToDatetimeCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
- const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
- const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- const auto date = pb.ToIntegral(item, dateType);
- return pb.Coalesce(pb.NotEquals(date, pb.Convert(date, datetimeType)), pb.NewDataLiteral(false));
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestTzDateToDatetimeCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
- const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
- const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime);
- const auto canada = pb.NewDataLiteral<ui16>(375U);
- const auto europe = pb.NewDataLiteral<ui16>(459U);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- const auto date = pb.ToIntegral(item, dateType);
- const auto date1 = pb.Unwrap(pb.AddTimezone(date, canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- const auto date2 = pb.Unwrap(pb.AddTimezone(date, europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- return pb.Or({pb.NotEquals(date1, pb.Cast(date1, datetimeType)), pb.NotEquals(date2, pb.Cast(date2, datetimeType))});
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestDateAddTimezoneAndCastOrderCompleteCheck) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
- const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
- const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime);
- const auto datetimeTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDatetime);
- const auto canada = pb.NewDataLiteral<ui16>(375U);
- const auto europe = pb.NewDataLiteral<ui16>(459U);
- const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
- [&](TRuntimeNode item) {
- const auto date = pb.Unwrap(pb.ToIntegral(item, dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- const auto date1_1 = pb.Cast(pb.Unwrap(pb.AddTimezone(date, canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), datetimeTypeTz);
- const auto date1_2 = pb.Unwrap(pb.AddTimezone(pb.Cast(date, datetimeType), canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- const auto date2_1 = pb.Cast(pb.Unwrap(pb.AddTimezone(date, europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), datetimeTypeTz);
- const auto date2_2 = pb.Unwrap(pb.AddTimezone(pb.Cast(date, datetimeType), europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
- return pb.Or({pb.NotEquals(date1_1, date1_2), pb.NotEquals(date2_1, date2_2), pb.NotEquals(date1_1, date2_2), pb.NotEquals(date2_1, date1_2)});
- }
- )));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto result = graph->GetValue();
- UNIT_ASSERT(result.template Get<bool>());
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto data4 = pb.NewDataLiteral<ui32>(4);
- const auto data5 = pb.NewDataLiteral<ui32>(5);
- const auto data6 = pb.NewDataLiteral<ui32>(6);
- const auto limit = pb.NewDataLiteral<ui64>(3ULL);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto list = pb.NewList(optionalType, {
- pb.NewOptional(data0),
- pb.NewOptional(data1),
- pb.NewOptional(data2),
- pb.NewOptional(data3),
- pb.NewOptional(data4),
- pb.NewOptional(data5),
- pb.NewOptional(data3),
- pb.NewOptional(data4),
- pb.NewOptional(data6),
- pb.NewEmptyOptional(optionalType),
- pb.NewEmptyOptional(optionalType)
- });
-
- const auto pgmReturn = pb.Filter(list, limit,
- [&](TRuntimeNode item) {
- return pb.AggrEquals(pb.Unwrap(pb.Mod(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data0);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverEmptyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto limit = pb.NewDataLiteral<ui64>(3ULL);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto list = pb.NewEmptyList(optionalType);
-
- const auto pgmReturn = pb.Filter(list, limit,
- [&](TRuntimeNode) {
- return pb.NewDataLiteral<bool>(true);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverLazyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto start = pb.NewDataLiteral<ui64>(0ULL);
- const auto stop = pb.NewDataLiteral<ui64>(1000000000000ULL);
- const auto step = pb.NewDataLiteral<ui64>(1ULL);
-
- const auto limit = pb.NewDataLiteral<ui64>(7ULL);
- const auto list = pb.ListFromRange(start, stop, step);
-
- const auto pgmReturn = pb.Filter(list, limit,
- [&](TRuntimeNode item) {
- return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithSmallLimitGetTailOfLargeList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto start = pb.NewDataLiteral<ui64>(0ULL);
- const auto stop = pb.NewDataLiteral<ui64>(100100LL);
- const auto step = pb.NewDataLiteral<ui64>(1ULL);
-
- const auto limit = pb.NewDataLiteral<ui64>(3ULL);
- const auto list = pb.ListFromRange(start, stop, step);
-
- const auto pgmReturn = pb.Filter(pb.Collect(list), limit,
- [&](TRuntimeNode item) {
- return pb.AggrGreaterOrEqual(item, pb.NewDataLiteral<ui64>(100000LL));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100000LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100001LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100002LL);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverEnumerate) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto start = pb.NewDataLiteral<i64>(0LL);
- const auto stop = pb.NewDataLiteral<i64>(-1000000000000LL);
- const auto step = pb.NewDataLiteral<i64>(-1LL);
-
- const auto estart = pb.NewDataLiteral<ui64>(42ULL);
- const auto estep = pb.NewDataLiteral<ui64>(3ULL);
-
- const auto limit = pb.NewDataLiteral<ui64>(5ULL);
- const auto list = pb.Enumerate(pb.ListFromRange(start, stop, step), estart, estep);
-
- const auto pgmReturn = pb.Filter(list, limit,
- [&](TRuntimeNode item) {
- return pb.AggrEquals(pb.CountBits(pb.Add(pb.Nth(item, 0), pb.Nth(item, 1))), pb.NewDataLiteral<i64>(4LL));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 48ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -2LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 60ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -6LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 66ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -8LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 69ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -9LL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 96ULL);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -18LL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverStream) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewStreamType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- const auto stream = pb.ChainMap(pb.SourceOf(type), pb.NewDataLiteral<ui64>(0ULL),
- [&](TRuntimeNode, TRuntimeNode state) -> TRuntimeNodePair {
- return {state, pb.Increment(state)};
- }
- );
-
- const auto limit = pb.NewDataLiteral<ui64>(7ULL);
- const auto pgmReturn = pb.Filter(stream, limit,
- [&](TRuntimeNode item) {
- return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterWithLimitOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewFlowType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- const auto flow = pb.ChainMap(pb.SourceOf(type), pb.NewDataLiteral<ui64>(0ULL),
- [&](TRuntimeNode, TRuntimeNode state) -> TRuntimeNodePair {
- return {state, pb.Increment(state)};
- }
- );
-
- const auto limit = pb.NewDataLiteral<ui64>(7ULL);
- const auto pgmReturn = pb.FromFlow(pb.Filter(flow, limit,
- [&](TRuntimeNode item) {
- return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.TakeWhile(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "000");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "100");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhileOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.SkipWhile(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "200");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "300");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhileOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.TakeWhile(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "000");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "100");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhileInclusive) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.SkipWhileInclusive(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "300");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhileInclusive) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.TakeWhileInclusive(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "000");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "100");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "200");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhileInclusiveOnEmptyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {});
+
+ const auto pgmReturn = pb.SkipWhileInclusive(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhileInclusiveOnEmptyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {});
+
+ const auto pgmReturn = pb.TakeWhileInclusive(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, pb.NewDataLiteral<NUdf::EDataSlot::String>("000"));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhileInclusiveOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.SkipWhileInclusive(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "300");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhileInclusiveOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.TakeWhileInclusive(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, data2);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "000");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "100");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "200");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDateToStringCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
+ const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ const auto date = pb.ToIntegral(item, dateType);
+ const auto utf8 = pb.ToString<true>(date);
+ return pb.AggrNotEquals(date, pb.FromString(utf8, dateType));
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestTzDateToStringCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
+ const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
+ const auto dateTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDate, true);
+ const auto canada = pb.NewDataLiteral<ui16>(375U);
+ const auto europe = pb.NewDataLiteral<ui16>(459U);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ const auto date = pb.Unwrap(pb.ToIntegral(item, dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ const auto date1 = pb.Unwrap(pb.FromString(pb.ToString<true>(pb.AddTimezone(date, canada)), dateTypeTz), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ const auto date2 = pb.Unwrap(pb.FromString(pb.ToString<true>(pb.AddTimezone(date, europe)), dateTypeTz), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ return pb.Or({pb.NotEquals(date, date1), pb.NotEquals(date, date2)});
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestInt16ToFloatCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<i16>(std::numeric_limits<i16>::min()), pb.NewDataLiteral<i16>(std::numeric_limits<i16>::max()), pb.NewDataLiteral<i16>(1));
+ const auto type = pb.NewDataType(NUdf::EDataSlot::Float);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, pb.Convert(item, type));
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestUint16ToFloatCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(std::numeric_limits<ui16>::min()), pb.NewDataLiteral<ui16>(std::numeric_limits<ui16>::max()), pb.NewDataLiteral<ui16>(1U));
+ const auto type = pb.NewDataType(NUdf::EDataSlot::Float);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ return pb.NotEquals(item, pb.Convert(item, type));
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestDateToDatetimeCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
+ const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
+ const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ const auto date = pb.ToIntegral(item, dateType);
+ return pb.Coalesce(pb.NotEquals(date, pb.Convert(date, datetimeType)), pb.NewDataLiteral(false));
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestTzDateToDatetimeCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
+ const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
+ const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime);
+ const auto canada = pb.NewDataLiteral<ui16>(375U);
+ const auto europe = pb.NewDataLiteral<ui16>(459U);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ const auto date = pb.ToIntegral(item, dateType);
+ const auto date1 = pb.Unwrap(pb.AddTimezone(date, canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ const auto date2 = pb.Unwrap(pb.AddTimezone(date, europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ return pb.Or({pb.NotEquals(date1, pb.Cast(date1, datetimeType)), pb.NotEquals(date2, pb.Cast(date2, datetimeType))});
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestDateAddTimezoneAndCastOrderCompleteCheck) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui16>(0U), pb.NewDataLiteral<ui16>(NUdf::MAX_DATE), pb.NewDataLiteral<ui16>(1U));
+ const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
+ const auto datetimeType = pb.NewDataType(NUdf::EDataSlot::Datetime);
+ const auto datetimeTypeTz = pb.NewDataType(NUdf::EDataSlot::TzDatetime);
+ const auto canada = pb.NewDataLiteral<ui16>(375U);
+ const auto europe = pb.NewDataLiteral<ui16>(459U);
+ const auto pgmReturn = pb.Not(pb.HasItems(pb.Filter(list,
+ [&](TRuntimeNode item) {
+ const auto date = pb.Unwrap(pb.ToIntegral(item, dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ const auto date1_1 = pb.Cast(pb.Unwrap(pb.AddTimezone(date, canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), datetimeTypeTz);
+ const auto date1_2 = pb.Unwrap(pb.AddTimezone(pb.Cast(date, datetimeType), canada), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ const auto date2_1 = pb.Cast(pb.Unwrap(pb.AddTimezone(date, europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), datetimeTypeTz);
+ const auto date2_2 = pb.Unwrap(pb.AddTimezone(pb.Cast(date, datetimeType), europe), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
+ return pb.Or({pb.NotEquals(date1_1, date1_2), pb.NotEquals(date2_1, date2_2), pb.NotEquals(date1_1, date2_2), pb.NotEquals(date2_1, date1_2)});
+ }
+ )));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto result = graph->GetValue();
+ UNIT_ASSERT(result.template Get<bool>());
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto data4 = pb.NewDataLiteral<ui32>(4);
+ const auto data5 = pb.NewDataLiteral<ui32>(5);
+ const auto data6 = pb.NewDataLiteral<ui32>(6);
+ const auto limit = pb.NewDataLiteral<ui64>(3ULL);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto list = pb.NewList(optionalType, {
+ pb.NewOptional(data0),
+ pb.NewOptional(data1),
+ pb.NewOptional(data2),
+ pb.NewOptional(data3),
+ pb.NewOptional(data4),
+ pb.NewOptional(data5),
+ pb.NewOptional(data3),
+ pb.NewOptional(data4),
+ pb.NewOptional(data6),
+ pb.NewEmptyOptional(optionalType),
+ pb.NewEmptyOptional(optionalType)
+ });
+
+ const auto pgmReturn = pb.Filter(list, limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrEquals(pb.Unwrap(pb.Mod(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), data0);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverEmptyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto limit = pb.NewDataLiteral<ui64>(3ULL);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto list = pb.NewEmptyList(optionalType);
+
+ const auto pgmReturn = pb.Filter(list, limit,
+ [&](TRuntimeNode) {
+ return pb.NewDataLiteral<bool>(true);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverLazyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto start = pb.NewDataLiteral<ui64>(0ULL);
+ const auto stop = pb.NewDataLiteral<ui64>(1000000000000ULL);
+ const auto step = pb.NewDataLiteral<ui64>(1ULL);
+
+ const auto limit = pb.NewDataLiteral<ui64>(7ULL);
+ const auto list = pb.ListFromRange(start, stop, step);
+
+ const auto pgmReturn = pb.Filter(list, limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithSmallLimitGetTailOfLargeList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto start = pb.NewDataLiteral<ui64>(0ULL);
+ const auto stop = pb.NewDataLiteral<ui64>(100100LL);
+ const auto step = pb.NewDataLiteral<ui64>(1ULL);
+
+ const auto limit = pb.NewDataLiteral<ui64>(3ULL);
+ const auto list = pb.ListFromRange(start, stop, step);
+
+ const auto pgmReturn = pb.Filter(pb.Collect(list), limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrGreaterOrEqual(item, pb.NewDataLiteral<ui64>(100000LL));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100000LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100001LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 100002LL);
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverEnumerate) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto start = pb.NewDataLiteral<i64>(0LL);
+ const auto stop = pb.NewDataLiteral<i64>(-1000000000000LL);
+ const auto step = pb.NewDataLiteral<i64>(-1LL);
+
+ const auto estart = pb.NewDataLiteral<ui64>(42ULL);
+ const auto estep = pb.NewDataLiteral<ui64>(3ULL);
+
+ const auto limit = pb.NewDataLiteral<ui64>(5ULL);
+ const auto list = pb.Enumerate(pb.ListFromRange(start, stop, step), estart, estep);
+
+ const auto pgmReturn = pb.Filter(list, limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrEquals(pb.CountBits(pb.Add(pb.Nth(item, 0), pb.Nth(item, 1))), pb.NewDataLiteral<i64>(4LL));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 48ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -2LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 60ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -6LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 66ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -8LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 69ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -9LL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0U).template Get<ui64>(), 96ULL);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1U).template Get<i64>(), -18LL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverStream) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewStreamType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ const auto stream = pb.ChainMap(pb.SourceOf(type), pb.NewDataLiteral<ui64>(0ULL),
+ [&](TRuntimeNode, TRuntimeNode state) -> TRuntimeNodePair {
+ return {state, pb.Increment(state)};
+ }
+ );
+
+ const auto limit = pb.NewDataLiteral<ui64>(7ULL);
+ const auto pgmReturn = pb.Filter(stream, limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterWithLimitOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewFlowType(pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ const auto flow = pb.ChainMap(pb.SourceOf(type), pb.NewDataLiteral<ui64>(0ULL),
+ [&](TRuntimeNode, TRuntimeNode state) -> TRuntimeNodePair {
+ return {state, pb.Increment(state)};
+ }
+ );
+
+ const auto limit = pb.NewDataLiteral<ui64>(7ULL);
+ const auto pgmReturn = pb.FromFlow(pb.Filter(flow, limit,
+ [&](TRuntimeNode item) {
+ return pb.AggrEquals(pb.CountBits(item), pb.NewDataLiteral<ui64>(3ULL));
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 7ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 11ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 13ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 14ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 19ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 22ULL);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
index 5c4ad4c3a1..8ad155473d 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
@@ -1,82 +1,110 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
- Y_UNIT_TEST_LLVM(TestOverListAndPartialLists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2});
- const auto pgmReturn = pb.FlatMap(list,
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
+ Y_UNIT_TEST_LLVM(TestOverListAndPartialLists) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2});
+ const auto pgmReturn = pb.FlatMap(list,
[&](TRuntimeNode item) {
- return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
+ return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- Y_UNIT_TEST_LLVM(TestOverListAndStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<i8>(3);
- const auto data2 = pb.NewDataLiteral<i8>(-7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
- const auto list = pb.NewList(dataType, {data1, data2});
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode item) {
- return pb.Iterator(pb.NewList(dataType, {pb.Plus(item), pb.Minus(item)}), {});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ Y_UNIT_TEST_LLVM(TestOverListAndStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<i8>(3);
+ const auto data2 = pb.NewDataLiteral<i8>(-7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2});
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode item) {
+ return pb.Iterator(pb.NewList(dataType, {pb.Plus(item), pb.Minus(item)}), {});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -7);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 7);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverStreamAndPartialLists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(10);
- const auto data2 = pb.NewDataLiteral<ui16>(20);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
- const auto list = pb.NewList(dataType, {data1, data2});
- const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverStreamAndPartialLists) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(10);
+ const auto data2 = pb.NewDataLiteral<ui16>(20);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2});
+ const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndPartialLists) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui16>(10);
+ const auto data2 = pb.NewDataLiteral<ui16>(20);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
+ [&](TRuntimeNode item) {
+ return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
+ }));
+
+ const auto& graph = setup.BuildGraph(pgmReturn);
+ const NUdf::TUnboxedValue& iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
@@ -87,59 +115,31 @@ Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 1);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndPartialLists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui16>(10);
- const auto data2 = pb.NewDataLiteral<ui16>(20);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
- const auto list = pb.NewList(dataType, {data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
- [&](TRuntimeNode item) {
- return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
- }));
-
- const auto& graph = setup.BuildGraph(pgmReturn);
- const NUdf::TUnboxedValue& iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 10);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverStreamAndStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)}), {});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverStreamAndStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)}), {});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
@@ -150,703 +150,703 @@ Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndStreams) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)}), {});
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)}));
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverListAndFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
- [&](TRuntimeNode item) {
- return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)}));
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
- [&](TRuntimeNode) {
- return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Abs(it); });
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverListAndIndependentFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
- [&](TRuntimeNode) {
- return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Minus(it); });
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndPartialOptionals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i64>(-100);
- const auto data0 = pb.NewDataLiteral<i64>(0);
- const auto data1 = pb.NewDataLiteral<i64>(3);
- const auto data2 = pb.NewDataLiteral<i64>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
- [&](TRuntimeNode item) {
- return pb.Div(data, item);
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverStreamAndPartialOptionals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i64>(-100);
- const auto data0 = pb.NewDataLiteral<i64>(0);
- const auto data1 = pb.NewDataLiteral<i64>(3);
- const auto data2 = pb.NewDataLiteral<i64>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
- [&](TRuntimeNode item) {
- return pb.Div(data, item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndStreams) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)}), {});
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)}));
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverListAndFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
+ [&](TRuntimeNode item) {
+ return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)}));
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
+ [&](TRuntimeNode) {
+ return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Abs(it); });
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverListAndIndependentFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
+ [&](TRuntimeNode) {
+ return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Minus(it); });
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndPartialOptionals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i64>(-100);
+ const auto data0 = pb.NewDataLiteral<i64>(0);
+ const auto data1 = pb.NewDataLiteral<i64>(3);
+ const auto data2 = pb.NewDataLiteral<i64>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
+ [&](TRuntimeNode item) {
+ return pb.Div(data, item);
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverStreamAndPartialOptionals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i64>(-100);
+ const auto data0 = pb.NewDataLiteral<i64>(0);
+ const auto data1 = pb.NewDataLiteral<i64>(3);
+ const auto data2 = pb.NewDataLiteral<i64>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
+ [&](TRuntimeNode item) {
+ return pb.Div(data, item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -33);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -14);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FlatMap(list,
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FlatMap(list,
[&](TRuntimeNode item) {
- return pb.Div(data2, item);
+ return pb.Div(data2, item);
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- Y_UNIT_TEST_LLVM(TestOverListAndDoubleOptionals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<ui32>(0);
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FlatMap(list,
- [&](TRuntimeNode item) {
- return pb.NewOptional(pb.Div(data2, item));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialOptionals) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto list = pb.NewOptional(data2);
- const auto pgmReturn = pb.FlatMap(list,
+ Y_UNIT_TEST_LLVM(TestOverListAndDoubleOptionals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<ui32>(0);
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FlatMap(list,
[&](TRuntimeNode item) {
- return pb.Div(item, data2);
+ return pb.NewOptional(pb.Div(data2, item));
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialOptionals) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto list = pb.NewOptional(data2);
+ const auto pgmReturn = pb.FlatMap(list,
+ [&](TRuntimeNode item) {
+ return pb.Div(item, data2);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto value = graph->GetValue();
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 1);
}
- Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialLists) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialLists) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto list = pb.NewOptional(data2);
- const auto pgmReturn = pb.FlatMap(list,
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto list = pb.NewOptional(data2);
+ const auto pgmReturn = pb.FlatMap(list,
[&](TRuntimeNode item) {
- return pb.Append(pb.AsList(item), data1);
+ return pb.Append(pb.AsList(item), data1);
});
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- Y_UNIT_TEST_LLVM(TestOverListAndPartialListsLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestOverListAndPartialListsLazy) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2});
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2});
- const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
+ const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
[&](TRuntimeNode item) {
- return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
+ return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
});
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
}
- Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionalsLazy) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionalsLazy) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- const auto data0 = pb.NewDataLiteral<ui32>(0U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data0, data2});
+ const auto data0 = pb.NewDataLiteral<ui32>(0U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data2});
- const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
- [&](TRuntimeNode item) { return pb.Div(data2, item); }
- );
+ const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
+ [&](TRuntimeNode item) { return pb.Div(data2, item); }
+ );
- const auto graph = setup.BuildGraph(pgmReturn);
+ const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+ Y_UNIT_TEST_LLVM(TestNarrowWithList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.NewList(dataType, items), [](TRuntimeNode item){ return item; }); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestNarrowWithFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.ToFlow(pb.NewList(dataType, items)), [](TRuntimeNode item){ return item; }); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestNarrowWithIndependentFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+
+ const auto list = pb.NewList(tupleType, {data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList) { return pb.Map(
+ pb.ToFlow(pb.NewList(pb.NewDataType(NUdf::TDataType<float>::Id), {pb.NewDataLiteral<float>(+1.f), pb.NewDataLiteral<float>(-1.f)})),
+ [&](TRuntimeNode item) { return pb.Minus(item); }); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinNarrowWithList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto tupleType = pb.NewTupleType({});
+
+ const auto data = pb.NewTuple(tupleType, {});
+ const auto list = pb.NewList(tupleType, {data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.Replicate(pb.NewDataLiteral<i32>(7), pb.NewDataLiteral<ui64>(3), __FILE__, __LINE__, 0); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndWideFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)})),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
+ }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverListAndWideFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
+ [&](TRuntimeNode item) {
+ return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
+ {pb.Mod(data, item), pb.Div(data, item)})),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
+ }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +33);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -33);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +14);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -14);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentWideFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
+ [&](TRuntimeNode) {
+ return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
+ }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverListAndIndependentWideFlows) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data = pb.NewDataLiteral<i32>(-100);
+ const auto data0 = pb.NewDataLiteral<i32>(0);
+ const auto data1 = pb.NewDataLiteral<i32>(3);
+ const auto data2 = pb.NewDataLiteral<i32>(7);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2});
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
+ [&](TRuntimeNode) {
+ return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
+ }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
- Y_UNIT_TEST_LLVM(TestNarrowWithList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3});
-
- const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.NewList(dataType, items), [](TRuntimeNode item){ return item; }); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestNarrowWithFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3});
-
- const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.ToFlow(pb.NewList(dataType, items)), [](TRuntimeNode item){ return item; }); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestNarrowWithIndependentFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
-
- const auto list = pb.NewList(tupleType, {data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList) { return pb.Map(
- pb.ToFlow(pb.NewList(pb.NewDataType(NUdf::TDataType<float>::Id), {pb.NewDataLiteral<float>(+1.f), pb.NewDataLiteral<float>(-1.f)})),
- [&](TRuntimeNode item) { return pb.Minus(item); }); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinNarrowWithList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto tupleType = pb.NewTupleType({});
-
- const auto data = pb.NewTuple(tupleType, {});
- const auto list = pb.NewList(tupleType, {data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.Replicate(pb.NewDataLiteral<i32>(7), pb.NewDataLiteral<ui64>(3), __FILE__, __LINE__, 0); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndWideFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)})),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
- }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverListAndWideFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
- [&](TRuntimeNode item) {
- return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
- {pb.Mod(data, item), pb.Div(data, item)})),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
- }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +33);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -33);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +14);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -14);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentWideFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
- [&](TRuntimeNode) {
- return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
- }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverListAndIndependentWideFlows) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data = pb.NewDataLiteral<i32>(-100);
- const auto data0 = pb.NewDataLiteral<i32>(0);
- const auto data1 = pb.NewDataLiteral<i32>(3);
- const auto data2 = pb.NewDataLiteral<i32>(7);
- const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2});
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
- [&](TRuntimeNode) {
- return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
- }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-#endif
+#endif
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_fold_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_fold_ut.cpp
index 66869eea6d..87c596e094 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_fold_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_fold_ut.cpp
@@ -1,1184 +1,1184 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-#include <random>
-#include <ctime>
-#include <algorithm>
+#include <random>
+#include <ctime>
+#include <algorithm>
namespace NKikimr {
namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TMiniKQLFoldNodeTest) {
+Y_UNIT_TEST_SUITE(TMiniKQLFoldNodeTest) {
Y_UNIT_TEST_LLVM(TestFoldOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<ui32>(1);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto data3 = pb.NewDataLiteral<ui32>(3);
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto list = pb.NewList(dataType, {data1, data2, data3});
- auto pgmReturn = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<ui32>(1);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto data3 = pb.NewDataLiteral<ui32>(3);
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto list = pb.NewList(dataType, {data1, data2, data3});
+ auto pgmReturn = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
[&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Add(item, state);
+ return pb.Add(item, state);
});
auto graph = setup.BuildGraph(pgmReturn);
- auto res = graph->GetValue().template Get<ui32>();
+ auto res = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(res, 6);
}
Y_UNIT_TEST_LLVM(TestFold1OverEmptyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto list = pb.NewEmptyList(dataType);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto pgmReturn = pb.Fold1(list, [&](TRuntimeNode item) {
- return pb.Mul(item, data2);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto list = pb.NewEmptyList(dataType);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto pgmReturn = pb.Fold1(list, [&](TRuntimeNode item) {
+ return pb.Mul(item, data2);
},
[&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Add(item, state);
+ return pb.Add(item, state);
});
auto graph = setup.BuildGraph(pgmReturn);
auto value = graph->GetValue();
- UNIT_ASSERT(!value);
+ UNIT_ASSERT(!value);
}
Y_UNIT_TEST_LLVM(TestFold1OverSingleElementList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto data1 = pb.NewDataLiteral<ui32>(1);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto list = pb.NewList(dataType, {data1});
- auto pgmReturn = pb.Fold1(list,
- [&](TRuntimeNode item) {
- return pb.Mul(item, data2);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto data1 = pb.NewDataLiteral<ui32>(1);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto list = pb.NewList(dataType, {data1});
+ auto pgmReturn = pb.Fold1(list,
+ [&](TRuntimeNode item) {
+ return pb.Mul(item, data2);
},
[&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Add(item, state);
+ return pb.Add(item, state);
});
auto graph = setup.BuildGraph(pgmReturn);
auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 2);
}
Y_UNIT_TEST_LLVM(TestFold1OverManyElementList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto data1 = pb.NewDataLiteral<ui32>(1);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto list = pb.NewList(dataType, {data1, data2});
- auto pgmReturn = pb.Fold1(list,
- [&](TRuntimeNode item) {
- return pb.Mul(item, data2);
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto data1 = pb.NewDataLiteral<ui32>(1);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto list = pb.NewList(dataType, {data1, data2});
+ auto pgmReturn = pb.Fold1(list,
+ [&](TRuntimeNode item) {
+ return pb.Mul(item, data2);
},
[&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Add(item, state);
+ return pb.Add(item, state);
});
auto graph = setup.BuildGraph(pgmReturn);
auto value = graph->GetValue();
- UNIT_ASSERT(value);
+ UNIT_ASSERT(value);
UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 4);
}
Y_UNIT_TEST_LLVM(TestFoldWithAggrAdd) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<float>::Id));
- auto data1 = pb.NewOptional(pb.NewDataLiteral<float>(1));
- auto data2 = pb.NewOptional(pb.NewDataLiteral<float>(2));
- auto data3 = pb.NewOptional(pb.NewDataLiteral<float>(3));
- auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
- auto data0 = pb.NewOptional(pb.NewDataLiteral<float>(42));
- auto list = pb.NewList(dataType, {data4, data3, data2, data1});
-
- auto pgmReturn = pb.Fold(list, data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrAdd(pb.Increment(item), pb.Decrement(state));
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto res = graph->GetValue().template Get<float>();
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<float>::Id));
+ auto data1 = pb.NewOptional(pb.NewDataLiteral<float>(1));
+ auto data2 = pb.NewOptional(pb.NewDataLiteral<float>(2));
+ auto data3 = pb.NewOptional(pb.NewDataLiteral<float>(3));
+ auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<float>::Id);
+ auto data0 = pb.NewOptional(pb.NewDataLiteral<float>(42));
+ auto list = pb.NewList(dataType, {data4, data3, data2, data1});
+
+ auto pgmReturn = pb.Fold(list, data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrAdd(pb.Increment(item), pb.Decrement(state));
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto res = graph->GetValue().template Get<float>();
UNIT_ASSERT_VALUES_EQUAL(res, 47);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestNestedApply) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<i32>(1);
- auto data2 = pb.NewDataLiteral<i32>(2);
- auto data3 = pb.NewDataLiteral<i32>(3);
- auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
- auto list = pb.NewList(dataType, {data1, data2, data3});
-
- const auto callType = TCallableTypeBuilder(pb.GetTypeEnvironment(), "TEST", dataType).Add(dataType).Add(dataType).Build();
-
- auto pgmReturn = pb.Fold(list, pb.NewDataLiteral<i32>(100),
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Apply(pb.Callable(callType,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<i32>(1);
+ auto data2 = pb.NewDataLiteral<i32>(2);
+ auto data3 = pb.NewDataLiteral<i32>(3);
+ auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
+ auto list = pb.NewList(dataType, {data1, data2, data3});
+
+ const auto callType = TCallableTypeBuilder(pb.GetTypeEnvironment(), "TEST", dataType).Add(dataType).Add(dataType).Build();
+
+ auto pgmReturn = pb.Fold(list, pb.NewDataLiteral<i32>(100),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Apply(pb.Callable(callType,
[&](const TArrayRef<const TRuntimeNode>& args) {
- return pb.Sub(args[1], args[0]);
- }), {item, state});
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto res = graph->GetValue().template Get<i32>();
+ return pb.Sub(args[1], args[0]);
+ }), {item, state});
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto res = graph->GetValue().template Get<i32>();
UNIT_ASSERT_VALUES_EQUAL(res, 94);
- }
-
+ }
+
Y_UNIT_TEST_LLVM(TestLogicalOpts) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto truth = pb.NewDataLiteral(true);
- auto falsehood = pb.NewDataLiteral(false);
- auto type = pb.NewDataType(NUdf::TDataType<bool>::Id);
- auto args = pb.NewList(type, {truth, falsehood});
-
- auto optTruth = pb.NewOptional(truth);
- auto optFalsehood = pb.NewOptional(falsehood);
- auto empty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
- auto optType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
- auto opts = pb.NewList(optType, {empty, optTruth, optFalsehood});
-
- auto pgmReturn = pb.Fold(opts, pb.NewEmptyList(optType),
- [&](TRuntimeNode item, TRuntimeNode state) {
- const auto append = pb.Append(state, pb.Not(item));
-
- const auto one = pb.Fold(args, pb.NewEmptyList(optType),
- [&](TRuntimeNode item2, TRuntimeNode state2) {
- state2 = pb.Append(state2, pb.And({item, item2}));
- state2 = pb.Append(state2, pb.And({item2, item}));
- state2 = pb.Append(state2, pb.Or({item, item2}));
- state2 = pb.Append(state2, pb.Or({item2, item}));
- state2 = pb.Append(state2, pb.Xor({item, item2}));
- state2 = pb.Append(state2, pb.Xor({item2, item}));
- return state2;
- });
-
- const auto two = pb.Fold(opts, pb.NewEmptyList(optType),
- [&](TRuntimeNode item2, TRuntimeNode state2) {
- state2 = pb.Append(state2, pb.And({item, item2}));
- state2 = pb.Append(state2, pb.Or({item, item2}));
- state2 = pb.Append(state2, pb.Xor({item, item2}));
- return state2;
- });
-
- return pb.Extend({append, one, two});
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
-
- auto res = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(res.GetListLength(), 66ULL);
- auto iterator = res.GetListIterator();
-
- NUdf::TUnboxedValue item;
-
- /// empty
- // not
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto truth = pb.NewDataLiteral(true);
+ auto falsehood = pb.NewDataLiteral(false);
+ auto type = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ auto args = pb.NewList(type, {truth, falsehood});
+
+ auto optTruth = pb.NewOptional(truth);
+ auto optFalsehood = pb.NewOptional(falsehood);
+ auto empty = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
+ auto optType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
+ auto opts = pb.NewList(optType, {empty, optTruth, optFalsehood});
+
+ auto pgmReturn = pb.Fold(opts, pb.NewEmptyList(optType),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ const auto append = pb.Append(state, pb.Not(item));
+
+ const auto one = pb.Fold(args, pb.NewEmptyList(optType),
+ [&](TRuntimeNode item2, TRuntimeNode state2) {
+ state2 = pb.Append(state2, pb.And({item, item2}));
+ state2 = pb.Append(state2, pb.And({item2, item}));
+ state2 = pb.Append(state2, pb.Or({item, item2}));
+ state2 = pb.Append(state2, pb.Or({item2, item}));
+ state2 = pb.Append(state2, pb.Xor({item, item2}));
+ state2 = pb.Append(state2, pb.Xor({item2, item}));
+ return state2;
+ });
+
+ const auto two = pb.Fold(opts, pb.NewEmptyList(optType),
+ [&](TRuntimeNode item2, TRuntimeNode state2) {
+ state2 = pb.Append(state2, pb.And({item, item2}));
+ state2 = pb.Append(state2, pb.Or({item, item2}));
+ state2 = pb.Append(state2, pb.Xor({item, item2}));
+ return state2;
+ });
+
+ return pb.Extend({append, one, two});
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+
+ auto res = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(res.GetListLength(), 66ULL);
+ auto iterator = res.GetListIterator();
+
+ NUdf::TUnboxedValue item;
+
+ /// empty
+ // not
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
-
- /// true
- // not
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+
+ /// true
+ // not
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- /// false
- // not
- UNIT_ASSERT(iterator.Next(item));
+
+ /// false
+ // not
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
-
- // and
- UNIT_ASSERT(iterator.Next(item));
+
+ // and
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // or
- UNIT_ASSERT(iterator.Next(item));
+
+ // or
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- // xor
- UNIT_ASSERT(iterator.Next(item));
+
+ // xor
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
Y_UNIT_TEST_LLVM(TestFoldWithListInState) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<ui32>(1);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto data3 = pb.NewDataLiteral<ui32>(3);
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto list = pb.NewList(dataType, {data1, data2, data3});
- auto optType = pb.NewOptionalType(dataType);
- auto empty = pb.AddMember(pb.AddMember(
- pb.NewEmptyStruct(), "Max", pb.NewEmptyOptional(optType)),
- "List", pb.NewEmptyList(dataType));
-
- auto pgmReturn = pb.Fold(list, empty,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<ui32>(1);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto data3 = pb.NewDataLiteral<ui32>(3);
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto list = pb.NewList(dataType, {data1, data2, data3});
+ auto optType = pb.NewOptionalType(dataType);
+ auto empty = pb.AddMember(pb.AddMember(
+ pb.NewEmptyStruct(), "Max", pb.NewEmptyOptional(optType)),
+ "List", pb.NewEmptyList(dataType));
+
+ auto pgmReturn = pb.Fold(list, empty,
[&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Max",
- pb.IfPresent({pb.Member(state, "Max")},
- [&](TRuntimeNode::TList oldMax) {
- return pb.NewOptional(pb.Max(oldMax.front(), item));
- }, pb.NewOptional(item))),
- "List", pb.Append(pb.Member(state, "List"), item)
+ return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Max",
+ pb.IfPresent({pb.Member(state, "Max")},
+ [&](TRuntimeNode::TList oldMax) {
+ return pb.NewOptional(pb.Max(oldMax.front(), item));
+ }, pb.NewOptional(item))),
+ "List", pb.Append(pb.Member(state, "List"), item)
);
});
auto graph = setup.BuildGraph(pgmReturn);
- auto iterator = graph->GetValue().GetElement(0).GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ auto iterator = graph->GetValue().GetElement(0).GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
-
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetElement(1).template Get<ui32>(), 3);
}
Y_UNIT_TEST_LLVM(TestManyAppend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
+ auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
const ui32 n = 13;
for (ui32 i = 0; i < n; ++i)
- zeroList = pb.Extend(zeroList, zeroList);
+ zeroList = pb.Extend(zeroList, zeroList);
- auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.NewDataLiteral<ui32>(0)), "NewList",
- pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.NewDataLiteral<ui32>(0)), "NewList",
+ pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- auto fold = pb.Fold(zeroList, state,
+ auto fold = pb.Fold(zeroList, state,
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(item);
- auto oldList = pb.Member(state, "NewList");
- auto oldCounter = pb.Member(state, "Counter");
- return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
- "NewList", pb.Append(oldList, oldCounter));
+ auto oldList = pb.Member(state, "NewList");
+ auto oldCounter = pb.Member(state, "Counter");
+ return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
+ "NewList", pb.Append(oldList, oldCounter));
});
- auto pgmReturn = pb.Member(fold, "NewList");
+ auto pgmReturn = pb.Member(fold, "NewList");
auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 1 << n);
auto iterator = graph->GetValue().GetListIterator();
ui32 i = 0;
- for (NUdf::TUnboxedValue item; iterator.Next(item); ++i) {
+ for (NUdf::TUnboxedValue item; iterator.Next(item); ++i) {
UNIT_ASSERT_VALUES_EQUAL(i, item.template Get<ui32>());
- }
- UNIT_ASSERT(!iterator.Skip());
+ }
+ UNIT_ASSERT(!iterator.Skip());
UNIT_ASSERT_VALUES_EQUAL(i, 1 << n);
}
Y_UNIT_TEST_LLVM(TestManyPrepend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
+ auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
const ui32 n = 13;
for (ui32 i = 0; i < n; ++i)
- zeroList = pb.Extend(zeroList, zeroList);
+ zeroList = pb.Extend(zeroList, zeroList);
- auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.NewDataLiteral<ui32>(0)), "NewList",
- pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.NewDataLiteral<ui32>(0)), "NewList",
+ pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- auto fold = pb.Fold(zeroList, state,
+ auto fold = pb.Fold(zeroList, state,
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(item);
- auto oldList = pb.Member(state, "NewList");
- auto oldCounter = pb.Member(state, "Counter");
- return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
- "NewList", pb.Prepend(oldCounter, oldList));
+ auto oldList = pb.Member(state, "NewList");
+ auto oldCounter = pb.Member(state, "Counter");
+ return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
+ "NewList", pb.Prepend(oldCounter, oldList));
});
- auto pgmReturn = pb.Member(fold, "NewList");
+ auto pgmReturn = pb.Member(fold, "NewList");
auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 1 << n);
auto iterator = graph->GetValue().GetListIterator();
ui32 i = 1 << n;
- for (NUdf::TUnboxedValue item; iterator.Next(item);) {
+ for (NUdf::TUnboxedValue item; iterator.Next(item);) {
UNIT_ASSERT_VALUES_EQUAL(--i, item.template Get<ui32>());
- }
- UNIT_ASSERT(!iterator.Skip());
+ }
+ UNIT_ASSERT(!iterator.Skip());
UNIT_ASSERT_VALUES_EQUAL(i, 0);
}
Y_UNIT_TEST_LLVM(TestManyExtend) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
- auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
+ auto zeroList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ zeroList = pb.Append(zeroList, pb.NewDataLiteral<ui32>(0));
const ui32 n = 13;
for (ui32 i = 0; i < n; ++i)
- zeroList = pb.Extend(zeroList, zeroList);
+ zeroList = pb.Extend(zeroList, zeroList);
- auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.NewDataLiteral<ui32>(0)), "NewList",
- pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
+ auto state = pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.NewDataLiteral<ui32>(0)), "NewList",
+ pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id)));
- auto fold = pb.Fold(zeroList, state,
+ auto fold = pb.Fold(zeroList, state,
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(item);
- auto oldList = pb.Member(state, "NewList");
- auto oldCounter = pb.Member(state, "Counter");
- auto oldCounterMul2 = pb.Mul(oldCounter, pb.NewDataLiteral<ui32>(2));
- auto extList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
- extList = pb.Append(extList, oldCounterMul2);
- extList = pb.Append(extList, pb.Increment(oldCounterMul2));
- return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
- pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
- "NewList", pb.Extend(oldList, extList));
+ auto oldList = pb.Member(state, "NewList");
+ auto oldCounter = pb.Member(state, "Counter");
+ auto oldCounterMul2 = pb.Mul(oldCounter, pb.NewDataLiteral<ui32>(2));
+ auto extList = pb.NewEmptyList(pb.NewDataType(NUdf::TDataType<ui32>::Id));
+ extList = pb.Append(extList, oldCounterMul2);
+ extList = pb.Append(extList, pb.Increment(oldCounterMul2));
+ return pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Counter",
+ pb.Add(oldCounter, pb.NewDataLiteral<ui32>(1))),
+ "NewList", pb.Extend(oldList, extList));
});
- auto pgmReturn = pb.Member(fold, "NewList");
+ auto pgmReturn = pb.Member(fold, "NewList");
auto graph = setup.BuildGraph(pgmReturn);
UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 1 << (n+1));
auto iterator = graph->GetValue().GetListIterator();
ui32 i = 0;
- for (NUdf::TUnboxedValue item; iterator.Next(item); ++i) {
+ for (NUdf::TUnboxedValue item; iterator.Next(item); ++i) {
UNIT_ASSERT_VALUES_EQUAL(i, item.template Get<ui32>());
- }
- UNIT_ASSERT(!iterator.Skip());
+ }
+ UNIT_ASSERT(!iterator.Skip());
UNIT_ASSERT_VALUES_EQUAL(i, 1 << (n + 1));
}
Y_UNIT_TEST_LLVM(TestFoldSingular) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data1 = pb.NewDataLiteral<ui32>(1);
- auto data2 = pb.NewDataLiteral<ui32>(2);
- auto data3 = pb.NewDataLiteral<ui32>(3);
- auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- auto list = pb.NewList(dataType, {data1, data2, data3});
- auto fold1 = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data1 = pb.NewDataLiteral<ui32>(1);
+ auto data2 = pb.NewDataLiteral<ui32>(2);
+ auto data3 = pb.NewDataLiteral<ui32>(3);
+ auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ auto list = pb.NewList(dataType, {data1, data2, data3});
+ auto fold1 = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(state);
return item;
});
- auto fold2 = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
+ auto fold2 = pb.Fold(list, pb.NewDataLiteral<ui32>(0),
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(item);
return state;
});
- auto pgmReturn = pb.NewList(dataType, {fold1, fold2});
+ auto pgmReturn = pb.NewList(dataType, {fold1, fold2});
auto graph = setup.BuildGraph(pgmReturn);
auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumListSizes) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ auto item = pb.NewDataLiteral<float>(0.f);
+
+ auto listType = pb.NewListType(itemType);
+
+ auto data0 = pb.NewEmptyList(itemType);
+ auto data1 = pb.NewList(itemType, {item});
+ auto data2 = pb.NewList(itemType, {item, item, item});
+ auto data3 = pb.NewList(itemType, {item, item, item, item, item});
+
+ auto list = pb.NewList(listType, {data0, data1, data2, data3});
+
+ auto pgmReturn = pb.Fold1(list,
+ [&](TRuntimeNode item) { return pb.Length(item); },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Length(item)); }
+ );
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ UNIT_ASSERT_VALUES_EQUAL(9ULL, graph->GetValue().template Get<ui64>());
}
- Y_UNIT_TEST_LLVM(TestSumListSizes) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ Y_UNIT_TEST_LLVM(TestHasListsItems) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
+ auto item = pb.NewDataLiteral<float>(0.f);
- auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
- auto item = pb.NewDataLiteral<float>(0.f);
+ auto listType = pb.NewListType(itemType);
- auto listType = pb.NewListType(itemType);
+ auto data0 = pb.NewEmptyList(itemType);
+ auto data1 = pb.NewList(itemType, {item});
+ auto data2 = pb.NewEmptyList(itemType);
- auto data0 = pb.NewEmptyList(itemType);
- auto data1 = pb.NewList(itemType, {item});
- auto data2 = pb.NewList(itemType, {item, item, item});
- auto data3 = pb.NewList(itemType, {item, item, item, item, item});
+ auto list = pb.NewList(listType, {data0, data1, data2});
- auto list = pb.NewList(listType, {data0, data1, data2, data3});
+ auto pgmReturn = pb.Fold(list, pb.NewOptional(pb.NewDataLiteral<bool>(false)),
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.Or({state, pb.HasItems(item)}); }
+ );
- auto pgmReturn = pb.Fold1(list,
- [&](TRuntimeNode item) { return pb.Length(item); },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, pb.Length(item)); }
- );
-
auto graph = setup.BuildGraph(pgmReturn);
- UNIT_ASSERT_VALUES_EQUAL(9ULL, graph->GetValue().template Get<ui64>());
+ UNIT_ASSERT(graph->GetValue().template Get<bool>());
}
- Y_UNIT_TEST_LLVM(TestHasListsItems) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto itemType = pb.NewDataType(NUdf::TDataType<float>::Id);
- auto item = pb.NewDataLiteral<float>(0.f);
-
- auto listType = pb.NewListType(itemType);
-
- auto data0 = pb.NewEmptyList(itemType);
- auto data1 = pb.NewList(itemType, {item});
- auto data2 = pb.NewEmptyList(itemType);
-
- auto list = pb.NewList(listType, {data0, data1, data2});
-
- auto pgmReturn = pb.Fold(list, pb.NewOptional(pb.NewDataLiteral<bool>(false)),
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.Or({state, pb.HasItems(item)}); }
- );
-
- auto graph = setup.BuildGraph(pgmReturn);
- UNIT_ASSERT(graph->GetValue().template Get<bool>());
- }
-
Y_UNIT_TEST_LLVM(TestConcat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aa");
- auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bbb");
- auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("zzzz");
- auto type = pb.NewDataType(NUdf::EDataSlot::String);
- auto list = pb.NewList(type, {data1, data2, data3});
- auto pgmReturn = pb.Fold(list, data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Concat(state, item);
- });
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("aa");
+ auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bbb");
+ auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("zzzz");
+ auto type = pb.NewDataType(NUdf::EDataSlot::String);
+ auto list = pb.NewList(type, {data1, data2, data3});
+ auto pgmReturn = pb.Fold(list, data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Concat(state, item);
+ });
auto graph = setup.BuildGraph(pgmReturn);
auto res = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(res, "Xaabbbzzzz");
+ UNBOXED_VALUE_STR_EQUAL(res, "Xaabbbzzzz");
}
Y_UNIT_TEST_LLVM(TestConcatOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
- auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("very large string"));
- auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(" + "));
- auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("small"));
- auto type = pb.NewOptionalType(pb.NewDataType(NUdf::EDataSlot::String));
- auto list = pb.NewList(type, {data1, data2, data3, data0});
- auto pgmReturn = pb.Fold(list, data0,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.Concat(state, item);
- });
-
- auto graph = setup.BuildGraph(pgmReturn);
- auto res = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(res, "very large string + small");
- }
-
- Y_UNIT_TEST_LLVM(TestAggrConcat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::EDataSlot::Utf8));
- const auto data0 = pb.NewEmptyOptional(type);
- const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("PREFIX:"));
- const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("very large string"));
- const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(":SUFFIX"));
- const auto list = pb.NewList(type, {data0, data1, data0, data2, data3, data0});
-
- const auto pgmReturn = pb.Fold1(list,
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrConcat(state, item); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto str = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(str, "PREFIX:very large string:SUFFIX");
- }
-
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ auto data0 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("very large string"));
+ auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>(" + "));
+ auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("small"));
+ auto type = pb.NewOptionalType(pb.NewDataType(NUdf::EDataSlot::String));
+ auto list = pb.NewList(type, {data1, data2, data3, data0});
+ auto pgmReturn = pb.Fold(list, data0,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.Concat(state, item);
+ });
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ auto res = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(res, "very large string + small");
+ }
+
+ Y_UNIT_TEST_LLVM(TestAggrConcat) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto type = pb.NewOptionalType(pb.NewDataType(NUdf::EDataSlot::Utf8));
+ const auto data0 = pb.NewEmptyOptional(type);
+ const auto data1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("PREFIX:"));
+ const auto data2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("very large string"));
+ const auto data3 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(":SUFFIX"));
+ const auto list = pb.NewList(type, {data0, data1, data0, data2, data3, data0});
+
+ const auto pgmReturn = pb.Fold1(list,
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrConcat(state, item); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto str = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(str, "PREFIX:very large string:SUFFIX");
+ }
+
Y_UNIT_TEST_LLVM(TestLongFold) {
for (ui32 i = 0; i < 10; ++i) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
const ui32 n = 1000;
- auto firstList = pb.Replicate(pb.NewDataLiteral<ui32>(0),
+ auto firstList = pb.Replicate(pb.NewDataLiteral<ui32>(0),
pb.NewDataLiteral<ui64>(n), "", 0, 0);
auto secondList = pb.Replicate(firstList, pb.NewDataLiteral<ui64>(n), "", 0, 0);
- auto pgmReturn = pb.Fold(secondList, pb.NewDataLiteral<ui32>(0),
+ auto pgmReturn = pb.Fold(secondList, pb.NewDataLiteral<ui32>(0),
[&](TRuntimeNode item, TRuntimeNode state) {
- auto partialSum = pb.Fold(item, pb.NewDataLiteral<ui32>(0),
+ auto partialSum = pb.Fold(item, pb.NewDataLiteral<ui32>(0),
[&](TRuntimeNode item, TRuntimeNode state) {
Y_UNUSED(item);
- return pb.AggrAdd(state, pb.NewDataLiteral<ui32>(1));
+ return pb.AggrAdd(state, pb.NewDataLiteral<ui32>(1));
});
- return pb.AggrAdd(state, partialSum);
+ return pb.AggrAdd(state, partialSum);
});
auto graph = setup.BuildGraph(pgmReturn);
- auto value = graph->GetValue().template Get<ui32>();
+ auto value = graph->GetValue().template Get<ui32>();
UNIT_ASSERT_VALUES_EQUAL(value, n * n);
}
}
- Y_UNIT_TEST_LLVM(TestFoldFoldPerf) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
- const ui32 n = 3333U;
-
+ Y_UNIT_TEST_LLVM(TestFoldFoldPerf) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+ const ui32 n = 3333U;
+
const auto firstList = pb.Replicate(pb.NewDataLiteral<ui32>(1), pb.NewDataLiteral<ui64>(n), "", 0, 0);
-
+
const auto secondList = pb.Replicate(firstList, pb.NewDataLiteral<ui64>(n), "", 0, 0);
-
- const auto pgmReturn = pb.Fold(secondList, pb.NewDataLiteral<ui32>(0),
- [&](TRuntimeNode item, TRuntimeNode state) {
- const auto partialSum = pb.Fold(item, pb.NewDataLiteral<ui32>(0),
- [&](TRuntimeNode i2, TRuntimeNode state) {
- return pb.AggrAdd(state, i2);
- });
-
- return pb.AggrAdd(state, partialSum);
- });
-
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto t2 = TInstant::Now();
- const auto value = graph->GetValue().template Get<ui32>();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ")." << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value, n * n);
- }
-
- std::vector<double> MakeSamples() {
- std::default_random_engine eng;
- std::uniform_real_distribution<double> unif(-999.0, +999.0);
-
- std::vector<double> samples(3333333U);
-
- eng.seed(std::time(nullptr));
- std::generate(samples.begin(), samples.end(), std::bind(std::move(unif), std::move(eng)));
- return samples;
+
+ const auto pgmReturn = pb.Fold(secondList, pb.NewDataLiteral<ui32>(0),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ const auto partialSum = pb.Fold(item, pb.NewDataLiteral<ui32>(0),
+ [&](TRuntimeNode i2, TRuntimeNode state) {
+ return pb.AggrAdd(state, i2);
+ });
+
+ return pb.AggrAdd(state, partialSum);
+ });
+
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto t2 = TInstant::Now();
+ const auto value = graph->GetValue().template Get<ui32>();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ")." << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value, n * n);
+ }
+
+ std::vector<double> MakeSamples() {
+ std::default_random_engine eng;
+ std::uniform_real_distribution<double> unif(-999.0, +999.0);
+
+ std::vector<double> samples(3333333U);
+
+ eng.seed(std::time(nullptr));
+ std::generate(samples.begin(), samples.end(), std::bind(std::move(unif), std::move(eng)));
+ return samples;
+ }
+
+ static const auto Samples = MakeSamples();
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleArrayListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0);
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(pb.Collect(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
+ );
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0);
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(pb.LazyList(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
+ );
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleFilteredArrayListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0, [](double s, double v) { return v > 0.0 ? s + v : s; });
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(
+ pb.Filter(pb.Collect(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); }
+ ),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
+ );
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleFilteredLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0, [](double s, double v) { return v > 0.0 ? s + v : s; });
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(
+ pb.Filter(pb.LazyList(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); }
+ ),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
+ );
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleArrayListPerf) {
+ TSetup<LLVM> setup;
+
+ double min(Samples.front()), max(Samples.front()), sum(0.0);
+
+ const auto t = TInstant::Now();
+ for (const auto v : Samples) {
+ min = std::fmin(min, v);
+ max = std::fmax(max, v);
+ sum += v;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(pb.Collect(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
+ });
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
}
- static const auto Samples = MakeSamples();
-
- Y_UNIT_TEST_LLVM(TestSumDoubleArrayListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0);
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(pb.Collect(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
- );
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleLazyListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0);
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(pb.LazyList(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
- );
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ double min(Samples.front()), max(Samples.front()), sum(0.0);
+
+ const auto t = TInstant::Now();
+ for (const auto v : Samples) {
+ min = std::fmin(min, v);
+ max = std::fmax(max, v);
+ sum += v;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(pb.LazyList(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
+ });
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleFilteredArrayListPerf) {
+ TSetup<LLVM> setup;
+
+ double min(std::nan("")), max(std::nan("")), sum(0.0);
+
+ const auto t = TInstant::Now();
+ for (const auto v : Samples) {
+ if (v < 0.0) {
+ min = std::fmin(min, v);
+ max = std::fmax(max, v);
+ sum += v;
+ }
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(
+ pb.Filter(pb.Collect(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrLess(item, pb.NewDataLiteral(0.0)); }
+ ),
+ [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
+ });
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
}
- Y_UNIT_TEST_LLVM(TestSumDoubleFilteredArrayListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0, [](double s, double v) { return v > 0.0 ? s + v : s; });
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(
- pb.Filter(pb.Collect(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); }
- ),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
- );
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleFilteredLazyListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double sum = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0, [](double s, double v) { return v > 0.0 ? s + v : s; });
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(
- pb.Filter(pb.LazyList(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrGreater(item, pb.NewDataLiteral(0.0)); }
- ),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
- );
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleArrayListPerf) {
- TSetup<LLVM> setup;
-
- double min(Samples.front()), max(Samples.front()), sum(0.0);
-
- const auto t = TInstant::Now();
- for (const auto v : Samples) {
- min = std::fmin(min, v);
- max = std::fmax(max, v);
- sum += v;
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleFilteredLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ double min(std::nan("")), max(std::nan("")), sum(0.0);
+
+ const auto t = TInstant::Now();
+ for (const auto v : Samples) {
+ if (v < 0.0) {
+ min = std::fmin(min, v);
+ max = std::fmax(max, v);
+ sum += v;
+ }
}
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(pb.Collect(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
- });
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleLazyListPerf) {
- TSetup<LLVM> setup;
-
- double min(Samples.front()), max(Samples.front()), sum(0.0);
-
- const auto t = TInstant::Now();
- for (const auto v : Samples) {
- min = std::fmin(min, v);
- max = std::fmax(max, v);
- sum += v;
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(pb.LazyList(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
- });
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Fold1(
+ pb.Filter(pb.LazyList(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) { return pb.AggrLess(item, pb.NewDataLiteral(0.0)); }
+ ),
+ [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
+ });
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
+ }
+
+ Y_UNIT_TEST_LLVM(TestAvgDoubleByTupleFoldArrayListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto fold = pb.Fold(pb.Collect(TRuntimeNode(list, false)),
+ pb.NewTuple({pb.NewDataLiteral(0.0), pb.NewDataLiteral<ui64>(0ULL)}),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0), item), pb.Increment(pb.Nth(state, 1))});
+ });
+
+ const auto pgmReturn = pb.Div(pb.Nth(fold, 0U), pb.Nth(fold, 1U));
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
+ }
+
+ Y_UNIT_TEST_LLVM(TestAvgDoubleByTupleFoldLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto fold = pb.Fold(pb.LazyList(TRuntimeNode(list, false)),
+ pb.NewTuple({pb.NewDataLiteral(0.0), pb.NewDataLiteral<ui64>(0ULL)}),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.Increment(pb.Nth(state, 1U))});
+ });
+
+ const auto pgmReturn = pb.Div(pb.Nth(fold, 0U), pb.Nth(fold, 1U));
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
+ }
+
+ Y_UNIT_TEST_LLVM(TestAvgDoubleByCollectFoldLazyListPerf) {
+ TSetup<LLVM> setup;
+
+ const auto t = TInstant::Now();
+ const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto src = pb.Collect(pb.LazyList(TRuntimeNode(list, false)));
+ const auto pgmReturn = pb.Div(
+ pb.Fold(src, pb.NewDataLiteral(0.0),
+ [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
+ ),
+ pb.Length(src)
+ );
+
+ const auto t1 = TInstant::Now();
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
+ std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
+ const auto t2 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t3 = TInstant::Now();
+ Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
}
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleFilteredArrayListPerf) {
- TSetup<LLVM> setup;
-
- double min(std::nan("")), max(std::nan("")), sum(0.0);
-
- const auto t = TInstant::Now();
- for (const auto v : Samples) {
- if (v < 0.0) {
- min = std::fmin(min, v);
- max = std::fmax(max, v);
- sum += v;
- }
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(
- pb.Filter(pb.Collect(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrLess(item, pb.NewDataLiteral(0.0)); }
- ),
- [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
- });
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleFilteredLazyListPerf) {
- TSetup<LLVM> setup;
-
- double min(std::nan("")), max(std::nan("")), sum(0.0);
-
- const auto t = TInstant::Now();
- for (const auto v : Samples) {
- if (v < 0.0) {
- min = std::fmin(min, v);
- max = std::fmax(max, v);
- sum += v;
- }
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Fold1(
- pb.Filter(pb.LazyList(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) { return pb.AggrLess(item, pb.NewDataLiteral(0.0)); }
- ),
- [&](TRuntimeNode item) { return pb.NewTuple({item, item, item}); },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrMin(pb.Nth(state, 0U), item), pb.AggrMax(pb.Nth(state, 1U), item), pb.AggrAdd(pb.Nth(state, 2U), item)});
- });
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(0U).template Get<double>(), min);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(1U).template Get<double>(), max);
- UNIT_ASSERT_VALUES_EQUAL(value.GetElement(2U).template Get<double>(), sum);
- }
-
- Y_UNIT_TEST_LLVM(TestAvgDoubleByTupleFoldArrayListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto fold = pb.Fold(pb.Collect(TRuntimeNode(list, false)),
- pb.NewTuple({pb.NewDataLiteral(0.0), pb.NewDataLiteral<ui64>(0ULL)}),
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0), item), pb.Increment(pb.Nth(state, 1))});
- });
-
- const auto pgmReturn = pb.Div(pb.Nth(fold, 0U), pb.Nth(fold, 1U));
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
- }
-
- Y_UNIT_TEST_LLVM(TestAvgDoubleByTupleFoldLazyListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto fold = pb.Fold(pb.LazyList(TRuntimeNode(list, false)),
- pb.NewTuple({pb.NewDataLiteral(0.0), pb.NewDataLiteral<ui64>(0ULL)}),
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.NewTuple({pb.AggrAdd(pb.Nth(state, 0U), item), pb.Increment(pb.Nth(state, 1U))});
- });
-
- const auto pgmReturn = pb.Div(pb.Nth(fold, 0U), pb.Nth(fold, 1U));
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
- }
-
- Y_UNIT_TEST_LLVM(TestAvgDoubleByCollectFoldLazyListPerf) {
- TSetup<LLVM> setup;
-
- const auto t = TInstant::Now();
- const double avg = std::accumulate(Samples.cbegin(), Samples.cend(), 0.0) / Samples.size();
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto src = pb.Collect(pb.LazyList(TRuntimeNode(list, false)));
- const auto pgmReturn = pb.Div(
- pb.Fold(src, pb.NewDataLiteral(0.0),
- [&](TRuntimeNode item, TRuntimeNode state) { return pb.AggrAdd(state, item); }
- ),
- pb.Length(src)
- );
-
- const auto t1 = TInstant::Now();
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(Samples.size(), items));
- std::transform(Samples.cbegin(), Samples.cend(), items, &ToValue<double>);
- const auto t2 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t3 = TInstant::Now();
- Cerr << "Time is " << t3 - t1 << " (" << t2 - t1 << " + " << t3 - t2 << ") vs C++ " << cppTime << Endl;
- UNIT_ASSERT_VALUES_EQUAL(value.template Get<double>(), avg);
- }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_group_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_group_ut.cpp
index 4d7d8414d4..1833bbf509 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_group_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_group_ut.cpp
@@ -1,4 +1,4 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
@@ -8,8 +8,8 @@ namespace NMiniKQL {
namespace {
-template<bool UseLLVM>
-TRuntimeNode MakeStream(TSetup<UseLLVM>& setup, ui64 count = 9U) {
+template<bool UseLLVM>
+TRuntimeNode MakeStream(TSetup<UseLLVM>& setup, ui64 count = 9U) {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
TCallableBuilder callableBuilder(*setup.Env, "TestStream",
@@ -23,7 +23,7 @@ TRuntimeNode MakeStream(TSetup<UseLLVM>& setup, ui64 count = 9U) {
return TRuntimeNode(callableBuilder.Build(), false);
}
-template<bool UseLLVM>
+template<bool UseLLVM>
TRuntimeNode Group(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch,
const std::function<TRuntimeNode(TRuntimeNode)>& handler = {})
{
@@ -47,7 +47,7 @@ TRuntimeNode Group(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::funct
});
}
-template<bool UseLLVM>
+template<bool UseLLVM>
TRuntimeNode GroupKeys(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)>& groupSwitch) {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
@@ -61,8 +61,8 @@ TRuntimeNode GroupKeys(TSetup<UseLLVM>& setup, TRuntimeNode stream, const std::f
});
}
-template<bool UseLLVM>
-TRuntimeNode StreamToString(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
+template<bool UseLLVM>
+TRuntimeNode StreamToString(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
return pgmBuilder.Squeeze(stream, pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("|"), [&] (TRuntimeNode item, TRuntimeNode state) {
@@ -74,14 +74,14 @@ TRuntimeNode StreamToString(TSetup<UseLLVM>& setup, TRuntimeNode stream) {
Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
- Y_UNIT_TEST_LLVM(TestGrouping) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestGrouping) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
+ return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
});
auto pgm = StreamToString(setup, stream);
auto graph = setup.BuildGraph(pgm);
@@ -98,7 +98,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
auto stream = MakeStream(setup);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
- return pgmBuilder.NotEquals(item, key);
+ return pgmBuilder.NotEquals(item, key);
});
auto pgm = StreamToString(setup, stream);
auto graph = setup.BuildGraph(pgm);
@@ -109,14 +109,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*|*11*|*00*00*00*|*11*|*22*|*33*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestGroupingWithEmptyInput) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup, 0);
stream = Group(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
+ return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
});
auto pgm = StreamToString(setup, stream);
auto graph = setup.BuildGraph(pgm);
@@ -127,8 +127,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|");
}
- Y_UNIT_TEST_LLVM(TestSingleGroup) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestSingleGroup) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
@@ -146,8 +146,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*00*01*00*00*00*01*02*03*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestGroupingWithYield) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
@@ -160,7 +160,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
[&](ui32 /*index*/, TRuntimeNode item1) {
return Group(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
Y_UNUSED(key);
- return pgmBuilder.Equals(item2, pgmBuilder.NewDataLiteral<ui64>(0));
+ return pgmBuilder.Equals(item2, pgmBuilder.NewDataLiteral<ui64>(0));
});
},
1,
@@ -176,15 +176,15 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|*00*|*00*01*|*00*|*00*|*00*01*02*03*|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithoutFetchingSubStreams) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestGroupingWithoutFetchingSubStreams) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
stream = GroupKeys(setup, stream, [&](TRuntimeNode key, TRuntimeNode item) {
Y_UNUSED(key);
- return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
+ return pgmBuilder.Equals(item, pgmBuilder.NewDataLiteral<ui64>(0));
});
auto pgm = StreamToString(setup, stream);
@@ -196,8 +196,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
}
- Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndWithoutFetchingSubStreams) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestGroupingWithYieldAndWithoutFetchingSubStreams) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
@@ -210,7 +210,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLGroupingTest) {
[&](ui32 /*index*/, TRuntimeNode item1) {
return GroupKeys(setup, item1, [&](TRuntimeNode key, TRuntimeNode item2) {
Y_UNUSED(key);
- return pgmBuilder.Equals(item2, pgmBuilder.NewDataLiteral<ui64>(0));
+ return pgmBuilder.Equals(item2, pgmBuilder.NewDataLiteral<ui64>(0));
});
},
1,
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_heap_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_heap_ut.cpp
index 9893139cb5..3d4ac3787b 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_heap_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_heap_ut.cpp
@@ -1,317 +1,317 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLHeapTest) {
- Y_UNIT_TEST_LLVM(TestMakeHeap) {
- const std::array<float, 10U> xxx = {{0.f, 13.f, -3.14f, 1212.f, -7898.8f, 21E4f, HUGE_VALF, -HUGE_VALF, 3673.f, -32764.f}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto pgmReturn = pb.MakeHeap(list,
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrLess(pb.Abs(l), pb.Abs(r));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::make_heap(copy.begin(), copy.end(), [](float l, float r){ return std::abs(l) < std::abs(r); });
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestPopHeap) {
- const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, 1212.0, -7898.8, 210000.0, 17E13, -HUGE_VAL, 3673.0, -32764.0}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto comparer = [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
- };
-
- const auto pgmReturn = pb.PopHeap(pb.MakeHeap(list,comparer), comparer);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- const auto c = [](double l, double r){ return std::abs(l) > std::abs(r); };
- std::make_heap(copy.begin(), copy.end(), c);
- std::pop_heap(copy.begin(), copy.end(), c);
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestSortHeap) {
- const std::array<float, 10U> xxx = {{9E9f, -HUGE_VALF, 0.003f, 137.4f, -3.1415f, 1212.f, -7898.8f, 21E4f, 3673.f, -32764.f}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto pgmReturn = pb.SortHeap(
- pb.MakeHeap(list,
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrGreater(l, r);
- }),
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrGreater(l, r);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::make_heap(copy.begin(), copy.end(), std::greater<float>());
- std::sort_heap(copy.begin(), copy.end(), std::greater<float>());
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestStableSort) {
- const std::array<double, 10U> xxx = {{9E9f, -HUGE_VALF, 0.003f, HUGE_VALF, +3.1415f, -0.003f, -7898.8f, -3.1415f, 3673.f, 0.003f}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto pgmReturn = pb.StableSort(list,
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::stable_sort(copy.begin(), copy.end(), [](double l, double r){ return std::abs(l) > std::abs(r); });
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestNthElement) {
- const std::array<float, 10U> xxx = {{0.f, 13.f, -3.14f, 1212.f, -7898.8f, 21E4f, HUGE_VALF, -HUGE_VALF, 3673.f, -32764.f}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
- const auto list = pb.NewList(type, data);
- const auto n = pb.NewDataLiteral<ui64>(4U);
-
- const auto pgmReturn = pb.NthElement(list, n,
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::nth_element(copy.begin(), copy.begin() + 4U, copy.end(), [](float l, float r){ return std::abs(l) > std::abs(r); });
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestPartialSort) {
- const std::array<double, 10U> xxx = {{0.0, 13.0, -3.14, 1212.0, -7898.8, 21.0E4, HUGE_VAL, -HUGE_VAL, 3673.0, -32764.0}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, data);
- const auto n = pb.NewDataLiteral<ui64>(6U);
-
- const auto pgmReturn = pb.PartialSort(list, n,
- [&](TRuntimeNode l, TRuntimeNode r) {
- return pb.AggrLess(pb.Abs(l), pb.Abs(r));
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::partial_sort(copy.begin(), copy.begin() + 6U, copy.end(), [](double l, double r){ return std::abs(l) < std::abs(r); });
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestTopN) {
- const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, -7898.8, 210000.0, 17E13, 1212.0, -HUGE_VAL, 3673.0, -32764.0}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto comparator = [&](TRuntimeNode l, TRuntimeNode r) { return pb.AggrGreater(pb.Abs(l), pb.Abs(r)); };
-
- const auto n = 5ULL;
-
- const auto limit = pb.NewDataLiteral<ui64>(n);
- const auto last = pb.Decrement(limit);
-
- const auto pgmReturn = pb.Take(pb.NthElement(pb.Fold(list, pb.NewEmptyList(type),
- [&](TRuntimeNode item, TRuntimeNode state) {
- const auto size = pb.Length(state);
-
- return pb.If(pb.AggrLess(size, limit),
- pb.If(pb.AggrLess(size, last),
- pb.Append(state, item), pb.MakeHeap(pb.Append(state, item), comparator)),
- pb.If(comparator(item, pb.Unwrap(pb.ToOptional(state), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)),
- pb.PushHeap(pb.Append(pb.Take(pb.PopHeap(state, comparator), pb.Decrement(size)), item), comparator),
- state
- )
- );
- }
- ), last, comparator), limit);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), n);
-
- auto copy = xxx;
-
- const auto comp = [](double l, double r){ return std::abs(l) > std::abs(r); };
- std::nth_element(copy.begin(), copy.begin() + n - 1U, copy.end(), comp);
- const auto mm = std::minmax_element(copy.begin(), copy.begin() + n, comp);
-
- double min = result.GetElement(0).template Get<double>(), max = min;
- for (auto i = 1U; i < n; ++i) {
- const auto v = result.GetElement(i).template Get<double>();
- min = std::min(min, v, comp);
- max = std::max(max, v, comp);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(*mm.first, min);
- UNIT_ASSERT_VALUES_EQUAL(*mm.second, max);
- }
-
- Y_UNIT_TEST_LLVM(TestTopByNthElement) {
- const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, -7898.8, 210000.0, 17E13, 1212.0, -HUGE_VAL, 3673.0, -32764.0}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
-
- const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pb.NewList(type, data);
-
- const auto comparator = [&](TRuntimeNode l, TRuntimeNode r) { return pb.AggrLess(pb.Abs(l), pb.Abs(r)); };
-
- const auto n = 5ULL;
-
- const auto limit = pb.NewDataLiteral<ui64>(n);
- const auto reserve = pb.ShiftLeft(limit, pb.NewDataLiteral<ui8>(1U));
- const auto last = pb.Decrement(limit);
-
- const auto pgmReturn = pb.Take(pb.NthElement(pb.Fold(list, pb.NewEmptyList(type),
- [&](TRuntimeNode item, TRuntimeNode state) {
- const auto size = pb.Length(state);
-
- return pb.If(pb.AggrLess(size, limit),
- pb.If(pb.AggrLess(size, last),
- pb.Append(state, item), pb.MakeHeap(pb.Append(state, item), comparator)),
- pb.If(comparator(item, pb.Unwrap(pb.ToOptional(state), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)),
- pb.If(pb.AggrLess(size, reserve),
- pb.Append(state, item),
- pb.Take(pb.NthElement(pb.Prepend(item, pb.Skip(state, pb.NewDataLiteral<ui64>(1U))), last, comparator), limit)
- ),
- state
- )
- );
- }
- ), last, comparator), limit);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), n);
-
- auto copy = xxx;
-
- const auto comp = [](double l, double r){ return std::abs(l) < std::abs(r); };
- std::nth_element(copy.begin(), copy.begin() + n - 1U, copy.end(), comp);
- const auto mm = std::minmax_element(copy.begin(), copy.begin() + n, comp);
-
- double min = result.GetElement(0).template Get<double>(), max = min;
- for (auto i = 1U; i < n; ++i) {
- const auto v = result.GetElement(i).template Get<double>();
- min = std::min(min, v, comp);
- max = std::max(max, v, comp);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(*mm.first, min);
- UNIT_ASSERT_VALUES_EQUAL(*mm.second, max);
- }
-}
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLHeapTest) {
+ Y_UNIT_TEST_LLVM(TestMakeHeap) {
+ const std::array<float, 10U> xxx = {{0.f, 13.f, -3.14f, 1212.f, -7898.8f, 21E4f, HUGE_VALF, -HUGE_VALF, 3673.f, -32764.f}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto pgmReturn = pb.MakeHeap(list,
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrLess(pb.Abs(l), pb.Abs(r));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::make_heap(copy.begin(), copy.end(), [](float l, float r){ return std::abs(l) < std::abs(r); });
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestPopHeap) {
+ const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, 1212.0, -7898.8, 210000.0, 17E13, -HUGE_VAL, 3673.0, -32764.0}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto comparer = [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
+ };
+
+ const auto pgmReturn = pb.PopHeap(pb.MakeHeap(list,comparer), comparer);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ const auto c = [](double l, double r){ return std::abs(l) > std::abs(r); };
+ std::make_heap(copy.begin(), copy.end(), c);
+ std::pop_heap(copy.begin(), copy.end(), c);
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestSortHeap) {
+ const std::array<float, 10U> xxx = {{9E9f, -HUGE_VALF, 0.003f, 137.4f, -3.1415f, 1212.f, -7898.8f, 21E4f, 3673.f, -32764.f}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto pgmReturn = pb.SortHeap(
+ pb.MakeHeap(list,
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrGreater(l, r);
+ }),
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrGreater(l, r);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::make_heap(copy.begin(), copy.end(), std::greater<float>());
+ std::sort_heap(copy.begin(), copy.end(), std::greater<float>());
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestStableSort) {
+ const std::array<double, 10U> xxx = {{9E9f, -HUGE_VALF, 0.003f, HUGE_VALF, +3.1415f, -0.003f, -7898.8f, -3.1415f, 3673.f, 0.003f}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto pgmReturn = pb.StableSort(list,
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::stable_sort(copy.begin(), copy.end(), [](double l, double r){ return std::abs(l) > std::abs(r); });
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestNthElement) {
+ const std::array<float, 10U> xxx = {{0.f, 13.f, -3.14f, 1212.f, -7898.8f, 21E4f, HUGE_VALF, -HUGE_VALF, 3673.f, -32764.f}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](float f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<float>::Id);
+ const auto list = pb.NewList(type, data);
+ const auto n = pb.NewDataLiteral<ui64>(4U);
+
+ const auto pgmReturn = pb.NthElement(list, n,
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrGreater(pb.Abs(l), pb.Abs(r));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::nth_element(copy.begin(), copy.begin() + 4U, copy.end(), [](float l, float r){ return std::abs(l) > std::abs(r); });
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<float>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestPartialSort) {
+ const std::array<double, 10U> xxx = {{0.0, 13.0, -3.14, 1212.0, -7898.8, 21.0E4, HUGE_VAL, -HUGE_VAL, 3673.0, -32764.0}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, data);
+ const auto n = pb.NewDataLiteral<ui64>(6U);
+
+ const auto pgmReturn = pb.PartialSort(list, n,
+ [&](TRuntimeNode l, TRuntimeNode r) {
+ return pb.AggrLess(pb.Abs(l), pb.Abs(r));
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::partial_sort(copy.begin(), copy.begin() + 6U, copy.end(), [](double l, double r){ return std::abs(l) < std::abs(r); });
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestTopN) {
+ const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, -7898.8, 210000.0, 17E13, 1212.0, -HUGE_VAL, 3673.0, -32764.0}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto comparator = [&](TRuntimeNode l, TRuntimeNode r) { return pb.AggrGreater(pb.Abs(l), pb.Abs(r)); };
+
+ const auto n = 5ULL;
+
+ const auto limit = pb.NewDataLiteral<ui64>(n);
+ const auto last = pb.Decrement(limit);
+
+ const auto pgmReturn = pb.Take(pb.NthElement(pb.Fold(list, pb.NewEmptyList(type),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ const auto size = pb.Length(state);
+
+ return pb.If(pb.AggrLess(size, limit),
+ pb.If(pb.AggrLess(size, last),
+ pb.Append(state, item), pb.MakeHeap(pb.Append(state, item), comparator)),
+ pb.If(comparator(item, pb.Unwrap(pb.ToOptional(state), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)),
+ pb.PushHeap(pb.Append(pb.Take(pb.PopHeap(state, comparator), pb.Decrement(size)), item), comparator),
+ state
+ )
+ );
+ }
+ ), last, comparator), limit);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), n);
+
+ auto copy = xxx;
+
+ const auto comp = [](double l, double r){ return std::abs(l) > std::abs(r); };
+ std::nth_element(copy.begin(), copy.begin() + n - 1U, copy.end(), comp);
+ const auto mm = std::minmax_element(copy.begin(), copy.begin() + n, comp);
+
+ double min = result.GetElement(0).template Get<double>(), max = min;
+ for (auto i = 1U; i < n; ++i) {
+ const auto v = result.GetElement(i).template Get<double>();
+ min = std::min(min, v, comp);
+ max = std::max(max, v, comp);
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(*mm.first, min);
+ UNIT_ASSERT_VALUES_EQUAL(*mm.second, max);
+ }
+
+ Y_UNIT_TEST_LLVM(TestTopByNthElement) {
+ const std::array<double, 10U> xxx = {{0.0, 13.0, -3.140, -7898.8, 210000.0, 17E13, 1212.0, -HUGE_VAL, 3673.0, -32764.0}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(), [&pb](double f) { return pb.NewDataLiteral(f); } );
+
+ const auto type = pb.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pb.NewList(type, data);
+
+ const auto comparator = [&](TRuntimeNode l, TRuntimeNode r) { return pb.AggrLess(pb.Abs(l), pb.Abs(r)); };
+
+ const auto n = 5ULL;
+
+ const auto limit = pb.NewDataLiteral<ui64>(n);
+ const auto reserve = pb.ShiftLeft(limit, pb.NewDataLiteral<ui8>(1U));
+ const auto last = pb.Decrement(limit);
+
+ const auto pgmReturn = pb.Take(pb.NthElement(pb.Fold(list, pb.NewEmptyList(type),
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ const auto size = pb.Length(state);
+
+ return pb.If(pb.AggrLess(size, limit),
+ pb.If(pb.AggrLess(size, last),
+ pb.Append(state, item), pb.MakeHeap(pb.Append(state, item), comparator)),
+ pb.If(comparator(item, pb.Unwrap(pb.ToOptional(state), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)),
+ pb.If(pb.AggrLess(size, reserve),
+ pb.Append(state, item),
+ pb.Take(pb.NthElement(pb.Prepend(item, pb.Skip(state, pb.NewDataLiteral<ui64>(1U))), last, comparator), limit)
+ ),
+ state
+ )
+ );
+ }
+ ), last, comparator), limit);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), n);
+
+ auto copy = xxx;
+
+ const auto comp = [](double l, double r){ return std::abs(l) < std::abs(r); };
+ std::nth_element(copy.begin(), copy.begin() + n - 1U, copy.end(), comp);
+ const auto mm = std::minmax_element(copy.begin(), copy.begin() + n, comp);
+
+ double min = result.GetElement(0).template Get<double>(), max = min;
+ for (auto i = 1U; i < n; ++i) {
+ const auto v = result.GetElement(i).template Get<double>();
+ min = std::min(min, v, comp);
+ max = std::max(max, v, comp);
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(*mm.first, min);
+ UNIT_ASSERT_VALUES_EQUAL(*mm.second, max);
+ }
+}
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_dict_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_dict_ut.cpp
index 98a0a5d593..893722216d 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_dict_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_dict_ut.cpp
@@ -1,430 +1,430 @@
-#include "mkql_computation_node_ut.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
+#include "mkql_computation_node_ut.h"
-Y_UNIT_TEST_SUITE(TMiniKQLJoinDictNodeTest) {
- Y_UNIT_TEST_LLVM(TestInner) {
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLJoinDictNodeTest) {
+ Y_UNIT_TEST_LLVM(TestInner) {
for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
- const auto dict1 = pb.ToSortedDict(list1, true,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+ const auto dict1 = pb.ToSortedDict(list1, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToSortedDict(list2, true,
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToSortedDict(list2, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Inner);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
+ const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Inner);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
}
}
- Y_UNIT_TEST_LLVM(TestLeft) {
+ Y_UNIT_TEST_LLVM(TestLeft) {
for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
- const auto dict1 = pb.ToSortedDict(list1, true,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+ const auto dict1 = pb.ToSortedDict(list1, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToSortedDict(list2, true,
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToSortedDict(list2, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Left);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
+ const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Left);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
}
}
- Y_UNIT_TEST_LLVM(TestRight) {
+ Y_UNIT_TEST_LLVM(TestRight) {
for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
- const auto dict1 = pb.ToSortedDict(list1, true,
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+ const auto dict1 = pb.ToSortedDict(list1, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToSortedDict(list2, true,
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToSortedDict(list2, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Right);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(!tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Z");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
+ const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Right);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(!tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Z");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
}
}
- Y_UNIT_TEST_LLVM(TestFull) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
- const auto dict1 = pb.ToSortedDict(list1, true,
+ Y_UNIT_TEST_LLVM(TestFull) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+ const auto dict1 = pb.ToSortedDict(list1, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToSortedDict(list2, true,
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToSortedDict(list2, true,
[&](TRuntimeNode item) {
- return pb.Member(item, "Key");
+ return pb.Member(item, "Key");
},
[&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
+ return pb.Member(item, "Payload");
});
- const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Full);
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(!tuple.GetElement(0));
- UNIT_ASSERT(tuple.GetElement(1));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Z");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
+ const auto pgmReturn = pb.JoinDict(dict1, true, dict2, true, EJoinKind::Full);
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(!tuple.GetElement(0));
+ UNIT_ASSERT(tuple.GetElement(1));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Z");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
}
- Y_UNIT_TEST_LLVM(TestInnerFlat) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1U);
- const auto key2 = pb.NewDataLiteral<ui32>(2U);
- const auto key3 = pb.NewDataLiteral<ui32>(3U);
- const auto key4 = pb.NewDataLiteral<ui32>(4U);
- const auto key5 = pb.NewDataLiteral<ui32>(5U);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("D");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("E");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("F");
- const auto payload7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("G");
- const auto payload8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("H");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.NewStruct(structType, {{"Key", key1}, {"Payload", payload1}}),
- pb.NewStruct(structType, {{"Key", key2}, {"Payload", payload2}}),
- pb.NewStruct(structType, {{"Key", key3}, {"Payload", payload3}}),
- pb.NewStruct(structType, {{"Key", key4}, {"Payload", payload4}})
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.NewStruct(structType, {{"Key", key2}, {"Payload", payload8}}),
- pb.NewStruct(structType, {{"Key", key3}, {"Payload", payload7}}),
- pb.NewStruct(structType, {{"Key", key4}, {"Payload", payload6}}),
- pb.NewStruct(structType, {{"Key", key5}, {"Payload", payload5}})
- });
-
- const auto listList = pb.NewList(pb.NewListType(structType), {list1, list2});
-
- const auto pgmReturn = pb.FlatMap(listList,
- [&](TRuntimeNode left) {
- const auto dict1 = pb.ToSortedDict(left, false,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
- }, false, 0);
- return pb.FlatMap(listList,
- [&](TRuntimeNode right) {
- const auto dict2 = pb.ToSortedDict(right, false,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.Member(item, "Payload");
- }, false, 0);
- return pb.JoinDict(dict1, false, dict2, false, EJoinKind::Inner);
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto list = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 14U);
-
- const auto iterator = list.GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "A");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "C");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "D");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "H");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "G");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "D");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "F");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "H");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "G");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "C");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "F");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "H");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "H");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "G");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "G");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "F");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "F");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "E");
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
-
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
+ Y_UNIT_TEST_LLVM(TestInnerFlat) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1U);
+ const auto key2 = pb.NewDataLiteral<ui32>(2U);
+ const auto key3 = pb.NewDataLiteral<ui32>(3U);
+ const auto key4 = pb.NewDataLiteral<ui32>(4U);
+ const auto key5 = pb.NewDataLiteral<ui32>(5U);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("D");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("E");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("F");
+ const auto payload7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("G");
+ const auto payload8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("H");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.NewStruct(structType, {{"Key", key1}, {"Payload", payload1}}),
+ pb.NewStruct(structType, {{"Key", key2}, {"Payload", payload2}}),
+ pb.NewStruct(structType, {{"Key", key3}, {"Payload", payload3}}),
+ pb.NewStruct(structType, {{"Key", key4}, {"Payload", payload4}})
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.NewStruct(structType, {{"Key", key2}, {"Payload", payload8}}),
+ pb.NewStruct(structType, {{"Key", key3}, {"Payload", payload7}}),
+ pb.NewStruct(structType, {{"Key", key4}, {"Payload", payload6}}),
+ pb.NewStruct(structType, {{"Key", key5}, {"Payload", payload5}})
+ });
+
+ const auto listList = pb.NewList(pb.NewListType(structType), {list1, list2});
+
+ const auto pgmReturn = pb.FlatMap(listList,
+ [&](TRuntimeNode left) {
+ const auto dict1 = pb.ToSortedDict(left, false,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Payload");
+ }, false, 0);
+ return pb.FlatMap(listList,
+ [&](TRuntimeNode right) {
+ const auto dict2 = pb.ToSortedDict(right, false,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Payload");
+ }, false, 0);
+ return pb.JoinDict(dict1, false, dict2, false, EJoinKind::Inner);
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto list = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 14U);
+
+ const auto iterator = list.GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "A");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "A");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "C");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "D");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "H");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "G");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "D");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "F");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "H");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "B");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "G");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "C");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "F");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "D");
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "H");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "H");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "G");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "G");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "F");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "F");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "E");
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(1), "E");
+
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_ut.cpp
index 9eba2b56b4..89162e220b 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_join_ut.cpp
@@ -1,247 +1,247 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreTupleTest) {
- Y_UNIT_TEST_LLVM(Inner) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data1, data3, data2, data4});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, std::nullopt, EAnyJoinSettings::None, 3U, outputType));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(InnerOrderLeftFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {0U}, EAnyJoinSettings::None, 3U, outputType));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(InnerOrderRightFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data3, data4, data1, data2});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {1U}, EAnyJoinSettings::None, 3U, outputType));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreWideTest) {
- Y_UNIT_TEST_LLVM(Inner) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data1, data3, data2, data4});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
- EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, std::nullopt, EAnyJoinSettings::None, 3U, outputType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(InnerOrderLeftFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
- EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {0U}, EAnyJoinSettings::None, 3U, outputType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(InnerOrderRightFirst) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
-
- const auto list = pb.NewList(tupleType, {data3, data4, data1, data2});
-
- const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
- EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {1U}, EAnyJoinSettings::None, 3U, outputType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#endif
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreTupleTest) {
+ Y_UNIT_TEST_LLVM(Inner) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data1, data3, data2, data4});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, std::nullopt, EAnyJoinSettings::None, 3U, outputType));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(InnerOrderLeftFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {0U}, EAnyJoinSettings::None, 3U, outputType));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(InnerOrderRightFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data3, data4, data1, data2});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.CommonJoinCore(pb.ToFlow(list), EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {1U}, EAnyJoinSettings::None, 3U, outputType));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreWideTest) {
+ Y_UNIT_TEST_LLVM(Inner) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data1, data3, data2, data4});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
+ EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, std::nullopt, EAnyJoinSettings::None, 3U, outputType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(InnerOrderLeftFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
+ EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {0U}, EAnyJoinSettings::None, 3U, outputType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(InnerOrderRightFirst) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto indexType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto optionalType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({optionalType, optionalType, optionalType, indexType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-1)), pb.NewDataLiteral<ui32>(0)});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2)), pb.NewDataLiteral<ui32>(0)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(optionalType), pb.NewOptional(pb.NewDataLiteral<i32>(-3)), pb.NewDataLiteral<ui32>(1)});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(optionalType), pb.NewDataLiteral<ui32>(1)});
+
+ const auto list = pb.NewList(tupleType, {data3, data4, data1, data2});
+
+ const auto outputType = pb.NewFlowType(pb.NewTupleType({optionalType, optionalType}));
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.CommonJoinCore(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U)}; }),
+ EJoinKind::Inner, {0U, 0U}, {1U, 1U}, {}, {2U}, 0ULL, {1U}, EAnyJoinSettings::None, 3U, outputType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#endif
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_listfromrange_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_listfromrange_ut.cpp
index 5e49fbcf63..1ba1c92bdb 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_listfromrange_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_listfromrange_ut.cpp
@@ -13,13 +13,13 @@ TRuntimeNode MakeList(TSetup<UseLLVM>& setup, T Start, T End, i64 Step, const au
TProgramBuilder& pb = *setup.PgmBuilder;
const auto start = pb.Unwrap(pb.ToIntegral(pb.NewDataLiteral<T>(Start), dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
-
+
const auto end = pb.Unwrap(pb.ToIntegral(pb.NewDataLiteral<T>(End), dateType), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
-
+
const auto step = pb.NewDataLiteral<NUdf::EDataSlot::Interval>(
NUdf::TStringRef((const char*)&Step, sizeof(Step)));
-
- return pb.Collect(pb.ToFlow(pb.ListFromRange(start, end, step)));
+
+ return pb.Collect(pb.ToFlow(pb.ListFromRange(start, end, step)));
}
}
@@ -32,12 +32,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = 150;
i64 step = 86400000000LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
- const auto dates = MakeList(setup, start, end, step, dateType);
+
+ const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
NUdf::TUnboxedValue item;
for (size_t i = 0; i < end - start; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -52,12 +52,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = 140;
i64 step = -86400000000LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
- const auto dates = MakeList(setup, start, end, step, dateType);
+
+ const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), start - end);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), start - end);
NUdf::TUnboxedValue item;
for (int i = 0; i < start - end; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -73,11 +73,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
i64 step = 1000000LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
- const auto dates = MakeList(setup, start, end, step, dateType);
+ const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
NUdf::TUnboxedValue item;
for (size_t i = 0; i < end - start; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -93,11 +93,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
i64 step = 1LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Timestamp, true);
- const auto dates = MakeList(setup, start, end, step, dateType);
+ const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), end - start);
NUdf::TUnboxedValue item;
for (size_t i = 0; i < end - start; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -112,13 +112,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = 150;
i64 step = 86400000001LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestWrongIntervalForDatetime) {
@@ -128,13 +128,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui32 end = 150;
i64 step = 1000003LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestWrongStartType) {
@@ -143,11 +143,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto value0 = ui32(1000000);
const auto start = pb.NewDataLiteral<ui32>(value0);
-
+
const auto value1 = ui32(1000005);
const auto end = pb.NewDataLiteral<NUdf::EDataSlot::Datetime>(
NUdf::TStringRef((const char*)&value1, sizeof(value1)));
-
+
const auto value2 = i64(1000001LL);
const auto step = pb.NewDataLiteral<NUdf::EDataSlot::Interval>(
NUdf::TStringRef((const char*)&value2, sizeof(value2)));
@@ -161,10 +161,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto value0 = ui32(1000000);
const auto start = pb.NewDataLiteral<NUdf::EDataSlot::Datetime>(
NUdf::TStringRef((const char*)&value0, sizeof(value0)));
-
+
const auto value1 = ui32(1000005);
const auto end = pb.NewDataLiteral<ui32>(value1);
-
+
const auto value2 = i64(1000001LL);
const auto step = pb.NewDataLiteral<NUdf::EDataSlot::Interval>(
NUdf::TStringRef((const char*)&value2, sizeof(value2)));
@@ -178,11 +178,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto value0 = ui32(1000000);
const auto start = pb.NewDataLiteral<NUdf::EDataSlot::Datetime>(
NUdf::TStringRef((const char*)&value0, sizeof(value0)));
-
+
const auto value1 = ui32(1000005);
const auto end = pb.NewDataLiteral<NUdf::EDataSlot::Datetime>(
NUdf::TStringRef((const char*)&value1, sizeof(value1)));
-
+
const auto value2 = i64(1000001LL);
const auto step = pb.NewDataLiteral<ui32>(value2);
@@ -195,13 +195,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = 144;
i64 step = 86400000000LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 0);
UNIT_ASSERT(!iterator.Next(item));
}
Y_UNIT_TEST_LLVM(TestWrongStartEndTypes) {
@@ -211,11 +211,11 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto value0 = ui16(140);
const auto start = pb.NewDataLiteral<NUdf::EDataSlot::Date>(
NUdf::TStringRef((const char*)&value0, sizeof(value0)));
-
+
const auto value1 = ui32(140 * 60 * 60 * 24 + 5);
const auto end = pb.NewDataLiteral<NUdf::EDataSlot::Datetime>(
NUdf::TStringRef((const char*)&value1, sizeof(value1)));
-
+
const auto value2 = i64(2000000LL); // 2 Seconds
const auto step = pb.NewDataLiteral<NUdf::EDataSlot::Interval>(
NUdf::TStringRef((const char*)&value2, sizeof(value2)));
@@ -229,13 +229,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = 0;
i64 step = -518400000000LL; // -6 days
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -247,13 +247,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui32 end = 0;
i64 step = -10000000LL; // -10 seconds
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -265,13 +265,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui64 end = 10;
i64 step = -110LL; // -110 microseconds
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Timestamp, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -284,13 +284,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui16 end = NYql::NUdf::MAX_DATE - 1;
i64 step = (NYql::NUdf::MAX_DATE - 1) * 24LL * 60 * 60 * 1000000;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Date, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -298,18 +298,18 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
Y_UNIT_TEST_LLVM(TestMaxOverflowForDatetime) {
TSetup<LLVM> setup;
TProgramBuilder& pb = *setup.PgmBuilder;
-
+
ui32 start = NYql::NUdf::MAX_DATETIME - 123;
ui32 end = NYql::NUdf::MAX_DATETIME - 1;
i64 step = (NYql::NUdf::MAX_DATETIME - 1) * 1000000LL;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Datetime, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -322,13 +322,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
ui64 end = NYql::NUdf::MAX_TIMESTAMP - 1;
i64 step = NYql::NUdf::MAX_TIMESTAMP - 1;
const auto dateType = pb.NewDataType(NUdf::EDataSlot::Timestamp, true);
-
+
const auto dates = MakeList(setup, start, end, step, dateType);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 1);
UNIT_ASSERT(iterator.Next(item));
UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), start);
UNIT_ASSERT(!iterator.Next(item));
@@ -351,9 +351,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto dates = pb.ListFromRange(date1, date2, step);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
NUdf::TUnboxedValue item;
for (size_t i = 123; i < 123 + 5; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -378,9 +378,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto dates = pb.ListFromRange(date1, date2, step);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
NUdf::TUnboxedValue item;
for (size_t i = 123; i < 123 + 5; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -406,9 +406,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto dates = pb.ListFromRange(date1, date2, step);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
NUdf::TUnboxedValue item;
for (size_t i = 123; i < 123 + 5; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -434,9 +434,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
const auto dates = pb.ListFromRange(date1, date2, step);
const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- const auto iterator = list.GetListIterator();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
+ const auto list = graph->GetValue();
+ const auto iterator = list.GetListIterator();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5);
NUdf::TUnboxedValue item;
for (size_t i = 123; i < 123 + 5; i++) {
UNIT_ASSERT(iterator.Next(item));
@@ -444,26 +444,26 @@ Y_UNIT_TEST_SUITE(TMiniKQLListFromRangeTest) {
UNIT_ASSERT_VALUES_EQUAL(item.GetTimezoneId(), 459U);
}
}
-
- Y_UNIT_TEST_LLVM(TestResverseUnsignedShorts) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto from = pb.NewDataLiteral<ui16>(60000U);
- const auto to = pb.NewDataLiteral<ui16>(59990U);
- const auto step = pb.NewDataLiteral<i16>(-2);
-
- const auto dates = pb.Collect(pb.ToFlow(pb.ListFromRange(from, to, step)));
-
- const auto graph = setup.BuildGraph(dates);
- const auto list = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5UL);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0U).template Get<ui16>(), 60000U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1U).template Get<ui16>(), 59998U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2U).template Get<ui16>(), 59996U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(3U).template Get<ui16>(), 59994U);
- UNIT_ASSERT_VALUES_EQUAL(list.GetElement(4U).template Get<ui16>(), 59992U);
- }
+
+ Y_UNIT_TEST_LLVM(TestResverseUnsignedShorts) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto from = pb.NewDataLiteral<ui16>(60000U);
+ const auto to = pb.NewDataLiteral<ui16>(59990U);
+ const auto step = pb.NewDataLiteral<i16>(-2);
+
+ const auto dates = pb.Collect(pb.ToFlow(pb.ListFromRange(from, to, step)));
+
+ const auto graph = setup.BuildGraph(dates);
+ const auto list = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(list.GetListLength(), 5UL);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(0U).template Get<ui16>(), 60000U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(1U).template Get<ui16>(), 59998U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(2U).template Get<ui16>(), 59996U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(3U).template Get<ui16>(), 59994U);
+ UNIT_ASSERT_VALUES_EQUAL(list.GetElement(4U).template Get<ui16>(), 59992U);
+ }
+}
}
}
-}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_map_join_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
index fe8ec867af..437567fd6d 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
@@ -1,1075 +1,1075 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLMapJoinCoreTest) {
- Y_UNIT_TEST_LLVM(TestInner) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(3);
- const auto key4 = pb.NewDataLiteral<ui32>(4);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, false,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestInnerMulti) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
-
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeft) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(3);
- const auto key4 = pb.NewDataLiteral<ui32>(4);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, false,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftMulti) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftSemi) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftSemi, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "B");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "C");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftOnly) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftOnly, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "A");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftSemiWithNullKey) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id, true)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload3),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftSemi, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "B");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "C");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftOnlyWithNullKey) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto structType = pb.NewStructType({
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id, true)},
- {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
- });
- const auto list1 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
- });
-
- const auto list2 = pb.NewList(structType, {
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload3),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
- pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Member(item, "Key");
- },
- [&](TRuntimeNode item) {
- return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
- });
-
- const auto resultType = pb.NewFlowType(pb.NewStructType({
- {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
- {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
- }));
-
- const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftOnly, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT(!tuple.GetElement(0));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 1);
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "A");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideMapJoinCoreTest) {
- Y_UNIT_TEST_LLVM(TestInner) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(4);
- const auto key4 = pb.NewDataLiteral<ui32>(4);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, false,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestInnerMulti) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeft) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(3);
- const auto key4 = pb.NewDataLiteral<ui32>(4);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, false,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftMulti) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftSemi) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<ui32>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::LeftSemi, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftOnly) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key1 = pb.NewDataLiteral<ui32>(1);
- const auto key2 = pb.NewDataLiteral<ui32>(2);
- const auto key3 = pb.NewDataLiteral<ui32>(2);
- const auto key4 = pb.NewDataLiteral<ui32>(3);
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<ui32>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::LeftOnly, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftSemiWithNullKey) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id, true),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key0, payload4}),
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key0, payload3}),
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<ui32>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::LeftSemi, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-
- Y_UNIT_TEST_LLVM(TestLeftOnlyWithNullKey) {
- for (ui32 pass = 0; pass < 1; ++pass) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
- const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
- const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
- const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
- const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
- const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
- const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
- const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
-
- const auto tupleType = pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui32>::Id, true),
- pb.NewDataType(NUdf::TDataType<char*>::Id)
- });
-
- const auto list1 = pb.NewList(tupleType, {
- pb.NewTuple({key0, payload4}),
- pb.NewTuple({key1, payload1}),
- pb.NewTuple({key2, payload2}),
- pb.NewTuple({key3, payload3})
- });
-
- const auto list2 = pb.NewList(tupleType, {
- pb.NewTuple({key0, payload3}),
- pb.NewTuple({key2, payload4}),
- pb.NewTuple({key3, payload5}),
- pb.NewTuple({key4, payload6})
- });
-
- const auto dict2 = pb.ToHashedDict(list2, true,
- [&](TRuntimeNode item) {
- return pb.Nth(item, 0U);
- },
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Nth(item, 1U)});
- });
-
- const auto resultType = pb.NewFlowType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<char*>::Id),
- pb.NewDataType(NUdf::TDataType<ui32>::Id)
- }));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- dict2, EJoinKind::LeftOnly, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue tuple;
-
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "X");
- UNIT_ASSERT(!tuple.GetElement(1));
- UNIT_ASSERT(iterator.Next(tuple));
- UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
- UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 1);
- UNIT_ASSERT(!iterator.Next(tuple));
- UNIT_ASSERT(!iterator.Next(tuple));
- }
- }
-}
-#endif
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLMapJoinCoreTest) {
+ Y_UNIT_TEST_LLVM(TestInner) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(3);
+ const auto key4 = pb.NewDataLiteral<ui32>(4);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, false,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestInnerMulti) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeft) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(3);
+ const auto key4 = pb.NewDataLiteral<ui32>(4);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, false,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftMulti) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Right", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftSemi) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftSemi, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "B");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "C");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftOnly) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftOnly, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 1);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "A");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftSemiWithNullKey) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id, true)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload3),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftSemi, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "B");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 2);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "C");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftOnlyWithNullKey) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto structType = pb.NewStructType({
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id, true)},
+ {"Payload", pb.NewDataType(NUdf::TDataType<char*>::Id)}
+ });
+ const auto list1 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key1), "Payload", payload1),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload2),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload3)
+ });
+
+ const auto list2 = pb.NewList(structType, {
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key0), "Payload", payload3),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key2), "Payload", payload4),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key3), "Payload", payload5),
+ pb.AddMember(pb.AddMember(pb.NewEmptyStruct(), "Key", key4), "Payload", payload6)
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Member(item, "Key");
+ },
+ [&](TRuntimeNode item) {
+ return pb.AddMember(pb.NewEmptyStruct(), "Payload", pb.Member(item, "Payload"));
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewStructType({
+ {"Left", pb.NewDataType(NUdf::TDataType<char*>::Id)},
+ {"Key", pb.NewDataType(NUdf::TDataType<ui32>::Id)},
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.MapJoinCore(pb.ToFlow(list1), dict2, EJoinKind::LeftOnly, {0U}, {1U, 1U, 0U, 0U}, {}, resultType));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT(!tuple.GetElement(0));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(0).Get<ui32>(), 1);
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "A");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+}
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideMapJoinCoreTest) {
+ Y_UNIT_TEST_LLVM(TestInner) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(4);
+ const auto key4 = pb.NewDataLiteral<ui32>(4);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, false,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestInnerMulti) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::Inner, {0U}, {1U, 0U}, {0U, 1U}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeft) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(3);
+ const auto key4 = pb.NewDataLiteral<ui32>(4);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, false,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftMulti) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::Left, {0U}, {1U, 0U}, {0U, 1U}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "X");
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(1), "Y");
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftSemi) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<ui32>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::LeftSemi, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftOnly) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key1 = pb.NewDataLiteral<ui32>(1);
+ const auto key2 = pb.NewDataLiteral<ui32>(2);
+ const auto key3 = pb.NewDataLiteral<ui32>(2);
+ const auto key4 = pb.NewDataLiteral<ui32>(3);
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<ui32>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::LeftOnly, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 1);
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftSemiWithNullKey) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id, true),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key0, payload4}),
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key0, payload3}),
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<ui32>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::LeftSemi, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "B");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "C");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 2);
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestLeftOnlyWithNullKey) {
+ for (ui32 pass = 0; pass < 1; ++pass) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewDataType(NUdf::TDataType<ui32>::Id, true));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<ui32>(1));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key3 = pb.NewOptional(pb.NewDataLiteral<ui32>(2));
+ const auto key4 = pb.NewOptional(pb.NewDataLiteral<ui32>(3));
+ const auto payload1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("A");
+ const auto payload2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("B");
+ const auto payload3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("C");
+ const auto payload4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("X");
+ const auto payload5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Y");
+ const auto payload6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("Z");
+
+ const auto tupleType = pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui32>::Id, true),
+ pb.NewDataType(NUdf::TDataType<char*>::Id)
+ });
+
+ const auto list1 = pb.NewList(tupleType, {
+ pb.NewTuple({key0, payload4}),
+ pb.NewTuple({key1, payload1}),
+ pb.NewTuple({key2, payload2}),
+ pb.NewTuple({key3, payload3})
+ });
+
+ const auto list2 = pb.NewList(tupleType, {
+ pb.NewTuple({key0, payload3}),
+ pb.NewTuple({key2, payload4}),
+ pb.NewTuple({key3, payload5}),
+ pb.NewTuple({key4, payload6})
+ });
+
+ const auto dict2 = pb.ToHashedDict(list2, true,
+ [&](TRuntimeNode item) {
+ return pb.Nth(item, 0U);
+ },
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Nth(item, 1U)});
+ });
+
+ const auto resultType = pb.NewFlowType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<char*>::Id),
+ pb.NewDataType(NUdf::TDataType<ui32>::Id)
+ }));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.MapJoinCore(pb.ExpandMap(pb.ToFlow(list1),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ dict2, EJoinKind::LeftOnly, {0U}, {1U, 0U, 0U, 1U}, {}, resultType),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); })
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue tuple;
+
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "X");
+ UNIT_ASSERT(!tuple.GetElement(1));
+ UNIT_ASSERT(iterator.Next(tuple));
+ UNBOXED_VALUE_STR_EQUAL(tuple.GetElement(0), "A");
+ UNIT_ASSERT_VALUES_EQUAL(tuple.GetElement(1).Get<ui32>(), 1);
+ UNIT_ASSERT(!iterator.Next(tuple));
+ UNIT_ASSERT(!iterator.Next(tuple));
+ }
+ }
+}
+#endif
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_multihopping_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_multihopping_ut.cpp
index 627817dd45..719ba1f6ea 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_multihopping_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_multihopping_ut.cpp
@@ -114,7 +114,7 @@ namespace {
, FetchCallback(fetchCallback) {}
private:
- TUnboxedValueVector Items;
+ TUnboxedValueVector Items;
ui32 Index;
std::function<void()> FetchCallback;
@@ -140,11 +140,11 @@ namespace {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto structType = pgmBuilder.NewEmptyStructType();
- structType = pgmBuilder.NewStructType(structType, "key",
+ structType = pgmBuilder.NewStructType(structType, "key",
pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
- structType = pgmBuilder.NewStructType(structType, "time",
+ structType = pgmBuilder.NewStructType(structType, "time",
pgmBuilder.NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id));
- structType = pgmBuilder.NewStructType(structType, "sum",
+ structType = pgmBuilder.NewStructType(structType, "sum",
pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
auto keyIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("key");
auto timeIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("time");
@@ -158,44 +158,44 @@ namespace {
auto pgmReturn = pgmBuilder.MultiHoppingCore(
TRuntimeNode(streamNode, false),
[&](TRuntimeNode item) { // keyExtractor
- return pgmBuilder.Member(item, "key");
+ return pgmBuilder.Member(item, "key");
},
[&](TRuntimeNode item) { // timeExtractor
- return pgmBuilder.Member(item, "time");
+ return pgmBuilder.Member(item, "time");
},
[&](TRuntimeNode item) { // init
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", pgmBuilder.Member(item, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", pgmBuilder.Member(item, "sum"));
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode item, TRuntimeNode state) { // update
auto add = pgmBuilder.AggrAdd(
- pgmBuilder.Member(item, "sum"),
- pgmBuilder.Member(state, "sum"));
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", add);
+ pgmBuilder.Member(item, "sum"),
+ pgmBuilder.Member(state, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", add);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode state) { // save
- return pgmBuilder.Member(state, "sum");
+ return pgmBuilder.Member(state, "sum");
},
[&](TRuntimeNode savedState) { // load
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", savedState);
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", savedState);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode state1, TRuntimeNode state2) { // merge
auto add = pgmBuilder.AggrAdd(
- pgmBuilder.Member(state1, "sum"),
- pgmBuilder.Member(state2, "sum"));
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", add);
+ pgmBuilder.Member(state1, "sum"),
+ pgmBuilder.Member(state2, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", add);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode key, TRuntimeNode state, TRuntimeNode time) { // finish
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("key", key);
- members.emplace_back("sum", pgmBuilder.Member(state, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("key", key);
+ members.emplace_back("sum", pgmBuilder.Member(state, "sum"));
members.emplace_back("time", time);
return pgmBuilder.NewStruct(members);
},
@@ -207,7 +207,7 @@ namespace {
auto graph = setup.BuildGraph(pgmReturn, {streamNode});
- TUnboxedValueVector streamItems;
+ TUnboxedValueVector streamItems;
for (size_t i = 0; i < items.size(); ++i) {
NUdf::TUnboxedValue* itemsPtr;
auto structValues = graph->GetHolderFactory().CreateDirectArrayHolder(3, itemsPtr);
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_multimap_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
index 81c034de93..0c88e86c04 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
@@ -1,171 +1,171 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLMultiMapTest) {
- Y_UNIT_TEST_LLVM(TestOverList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto pgmReturn = pb.MultiMap(list,
- [&](TRuntimeNode item) {
- return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverLazyList) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto pgmReturn = pb.MultiMap(pb.LazyList(list),
- [&](TRuntimeNode item) {
- return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestOverFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<ui32>(2);
- const auto data3 = pb.NewDataLiteral<ui32>(3);
- const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto list = pb.NewList(dataType, {data1, data2, data3});
- const auto pgmReturn = pb.Collect(pb.MultiMap(pb.ToFlow(list),
- [&](TRuntimeNode item) {
- return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
- Y_UNIT_TEST_LLVM(TestFlattenByNarrow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMultiMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[2U], items[1U], items[0U] }; }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-#endif
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLMultiMapTest) {
+ Y_UNIT_TEST_LLVM(TestOverList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto pgmReturn = pb.MultiMap(list,
+ [&](TRuntimeNode item) {
+ return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverLazyList) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto pgmReturn = pb.MultiMap(pb.LazyList(list),
+ [&](TRuntimeNode item) {
+ return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestOverFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<ui32>(2);
+ const auto data3 = pb.NewDataLiteral<ui32>(3);
+ const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto list = pb.NewList(dataType, {data1, data2, data3});
+ const auto pgmReturn = pb.Collect(pb.MultiMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) {
+ return TRuntimeNode::TList{pb.Add(item, data1), item, pb.Mul(item, data2)};
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 6);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+ Y_UNIT_TEST_LLVM(TestFlattenByNarrow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMultiMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[2U], items[1U], items[0U] }; }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+#endif
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_safe_circular_buffer_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_safe_circular_buffer_ut.cpp
index aec4ce091b..9df6d01d4e 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_safe_circular_buffer_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_safe_circular_buffer_ut.cpp
@@ -12,35 +12,35 @@ Y_UNIT_TEST_SUITE(TMiniKQLSafeCircularBuffer) {
typedef TSafeCircularBuffer<TUnboxedValue> TBufUnboxed;
Y_UNIT_TEST(TestUnboxedNoFailOnEmpty) {
- TBufUnboxed bufferOptional(1, TUnboxedValuePod());
+ TBufUnboxed bufferOptional(1, TUnboxedValuePod());
TBufUnboxed buffer(1, TUnboxedValue::Void());
- UNIT_ASSERT(buffer.Get(0));
- UNIT_ASSERT(buffer.Get(1));
- UNIT_ASSERT(buffer.Get(3));
- UNIT_ASSERT(buffer.Get(-1));
+ UNIT_ASSERT(buffer.Get(0));
+ UNIT_ASSERT(buffer.Get(1));
+ UNIT_ASSERT(buffer.Get(3));
+ UNIT_ASSERT(buffer.Get(-1));
for (auto i = 0; i < 5; ++i) {
buffer.PopFront();
}
}
Y_UNIT_TEST(TestUnboxedNormalUsage) {
- TBufUnboxed buffer(5, TUnboxedValuePod());
- buffer.PushBack(TUnboxedValue::Embedded("It"));
+ TBufUnboxed buffer(5, TUnboxedValuePod());
+ buffer.PushBack(TUnboxedValue::Embedded("It"));
UNIT_ASSERT_EQUAL(buffer.Get(0).AsStringRef(), "It");
- buffer.PushBack(TUnboxedValue::Embedded("is"));
+ buffer.PushBack(TUnboxedValue::Embedded("is"));
UNIT_ASSERT_EQUAL(buffer.Get(0).AsStringRef(), "It");
- buffer.PushBack(TUnboxedValue::Embedded("funny"));
+ buffer.PushBack(TUnboxedValue::Embedded("funny"));
UNIT_ASSERT_EQUAL(buffer.UsedSize(), 3);
UNIT_ASSERT_EQUAL(buffer.Get(0).AsStringRef(), "It");
UNIT_ASSERT_EQUAL(buffer.Get(2).AsStringRef(), "funny");
- UNIT_ASSERT(!buffer.Get(3));
+ UNIT_ASSERT(!buffer.Get(3));
buffer.PopFront();
UNIT_ASSERT_EQUAL(buffer.Get(0).AsStringRef(), "is");
UNIT_ASSERT_EQUAL(buffer.Get(1).AsStringRef(), "funny");
- buffer.PushBack(TUnboxedValue::Embedded("bunny"));
+ buffer.PushBack(TUnboxedValue::Embedded("bunny"));
UNIT_ASSERT_EQUAL(buffer.Get(1).AsStringRef(), "funny");
UNIT_ASSERT_EQUAL(buffer.Get(2).AsStringRef(), "bunny");
- UNIT_ASSERT(!buffer.Get(3));
+ UNIT_ASSERT(!buffer.Get(3));
buffer.PopFront();
UNIT_ASSERT_EQUAL(buffer.Get(0).AsStringRef(), "funny");
UNIT_ASSERT_EQUAL(buffer.Get(1).AsStringRef(), "bunny");
@@ -51,7 +51,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSafeCircularBuffer) {
for (auto i = 0; i < 3; ++i) {
buffer.PopFront();
UNIT_ASSERT_EQUAL(buffer.UsedSize(), 0);
- UNIT_ASSERT(!buffer.Get(0));
+ UNIT_ASSERT(!buffer.Get(0));
}
}
@@ -115,12 +115,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLSafeCircularBuffer) {
const auto multPopLevel = 0.5;
const auto initSize = 10;
const auto iterationCount = 4;
- TBufUnboxed buffer(initSize, NUdf::TUnboxedValuePod());
+ TBufUnboxed buffer(initSize, NUdf::TUnboxedValuePod());
unsigned lastDirectIndex = 0;
unsigned lastChecked = 0;
for (unsigned iteration = 0; iteration < iterationCount; ++iteration) {
for (auto i = 0; i < multFillLevel * initSize; ++i) {
- buffer.PushBack(NUdf::TUnboxedValuePod(++lastDirectIndex));
+ buffer.PushBack(NUdf::TUnboxedValuePod(++lastDirectIndex));
}
UNIT_ASSERT(buffer.UsedSize() > 0);
UNIT_ASSERT_EQUAL(buffer.Get(buffer.UsedSize() - 1).Get<unsigned>(), lastDirectIndex);
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_sort_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_sort_ut.cpp
index 68b57eaad9..2457baabc0 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_sort_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_sort_ut.cpp
@@ -6,22 +6,22 @@
#include <ydb/library/yql/minikql/mkql_program_builder.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
+
+#include <random>
+#include <ctime>
+#include <algorithm>
-#include <random>
-#include <ctime>
-#include <algorithm>
-
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template <bool LLVM>
-TRuntimeNode MakeStream(TSetup<LLVM>& setup) {
+template <bool LLVM>
+TRuntimeNode MakeStream(TSetup<LLVM>& setup) {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
- TCallableBuilder callableBuilder(*setup.Env, "TestYieldStream",
+ TCallableBuilder callableBuilder(*setup.Env, "TestYieldStream",
pgmBuilder.NewStreamType(
pgmBuilder.NewStructType({
{TStringBuf("a"), pgmBuilder.NewDataType(NUdf::EDataSlot::Uint64)},
@@ -33,10 +33,10 @@ TRuntimeNode MakeStream(TSetup<LLVM>& setup) {
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode StreamToString(TProgramBuilder& pgmBuilder, TRuntimeNode stream) {
- return pgmBuilder.Condense(stream,
+TRuntimeNode StreamToString(TProgramBuilder& pgmBuilder, TRuntimeNode stream) {
+ return pgmBuilder.Condense(stream,
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("|"),
- [&] (TRuntimeNode, TRuntimeNode) { return pgmBuilder.NewDataLiteral<bool>(false); },
+ [&] (TRuntimeNode, TRuntimeNode) { return pgmBuilder.NewDataLiteral<bool>(false); },
[&] (TRuntimeNode item, TRuntimeNode state) {
auto str = pgmBuilder.Concat(
pgmBuilder.Concat(
@@ -48,25 +48,25 @@ TRuntimeNode StreamToString(TProgramBuilder& pgmBuilder, TRuntimeNode stream) {
return pgmBuilder.Concat(pgmBuilder.Concat(state, str),
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("|"));
- }
- );
+ }
+ );
}
} // namespace
Y_UNIT_TEST_SUITE(TMiniKQLSortTest) {
- Y_UNIT_TEST_LLVM(TestStreamSort) {
- TSetup<LLVM> setup;
+ Y_UNIT_TEST_LLVM(TestStreamSort) {
+ TSetup<LLVM> setup;
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto stream = MakeStream(setup);
- std::vector<TRuntimeNode> order {
+ std::vector<TRuntimeNode> order {
pgmBuilder.NewDataLiteral<bool>(true),
pgmBuilder.NewDataLiteral<bool>(false)
};
auto sort = pgmBuilder.Sort(stream, pgmBuilder.NewTuple(order),
[&pgmBuilder](TRuntimeNode item) {
- std::vector<TRuntimeNode> keys {
+ std::vector<TRuntimeNode> keys {
pgmBuilder.Member(item, "a"),
pgmBuilder.Member(item, "b")
};
@@ -74,14 +74,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLSortTest) {
return pgmBuilder.NewTuple(keys);
});
- auto pgmResult = StreamToString(pgmBuilder, sort);
+ auto pgmResult = StreamToString(pgmBuilder, sort);
auto graph = setup.BuildGraph(pgmResult);
auto value = graph->GetValue();
NUdf::TUnboxedValue result;
- auto yieldCount = 0U;
+ auto yieldCount = 0U;
auto status = NUdf::EFetchStatus::Ok;
while (status != NUdf::EFetchStatus::Finish) {
status = value.Fetch(result);
@@ -91,431 +91,431 @@ Y_UNIT_TEST_SUITE(TMiniKQLSortTest) {
}
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
- UNIT_ASSERT_EQUAL(yieldCount, 3U);
+ UNIT_ASSERT_EQUAL(yieldCount, 3U);
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()),
"|0-8|0-4|0-11|0-0|1-9|1-6|1-13|1-1|2-7|2-2|2-14|2-10|");
}
-
- Y_UNIT_TEST_LLVM(TestFlowSortByLambdaComparator) {
- TSetup<LLVM> setup;
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- const auto stream = MakeStream(setup);
-
- const auto sort =
- pgmBuilder.FromFlow(pgmBuilder.FlatMap(
- pgmBuilder.Condense1(pgmBuilder.ToFlow(stream),
- [&](TRuntimeNode item) { return pgmBuilder.AsList(item); },
- [&](TRuntimeNode, TRuntimeNode) { return pgmBuilder.NewDataLiteral<bool>(false); },
- [&](TRuntimeNode item, TRuntimeNode state) { return pgmBuilder.Append(state, item); }
- ),
- [&](TRuntimeNode list) {
- return pgmBuilder.StableSort(list,
- [&](TRuntimeNode left, TRuntimeNode right) {
- return pgmBuilder.Or({
- pgmBuilder.AggrLess(pgmBuilder.Member(left, "a"), pgmBuilder.Member(right, "a")),
- pgmBuilder.And({
- pgmBuilder.AggrEquals(pgmBuilder.Member(left, "a"), pgmBuilder.Member(right, "a")),
- pgmBuilder.AggrGreater(pgmBuilder.Member(left, "b"), pgmBuilder.Member(right, "b"))
- })
- });
- }
- );
- }
- ));
-
- const auto pgmResult = StreamToString(pgmBuilder, sort);
-
- const auto graph = setup.BuildGraph(pgmResult);
- const auto value = graph->GetValue();
-
-
- NUdf::TUnboxedValue result;
- auto yieldCount = 0U;
- auto status = NUdf::EFetchStatus::Ok;
- while (status != NUdf::EFetchStatus::Finish) {
- status = value.Fetch(result);
- if (status == NUdf::EFetchStatus::Yield) {
- ++yieldCount;
- }
- }
-
- UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
- UNIT_ASSERT_EQUAL(yieldCount, 3U);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()),
- "|0-8|0-4|0-11|0-0|1-9|1-6|1-13|1-1|2-7|2-2|2-14|2-10|");
- }
-
- Y_UNIT_TEST_LLVM(TestListSort) {
- const std::array<double, 10U> xxx = {{9E9, -HUGE_VAL, 0.003, HUGE_VAL, +3.1415, -0.003, -7898.8, -3.1415, 3673.0, 0.003}};
-
- TSetup<LLVM> setup;
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::array<TRuntimeNode, 10U> data;
- std::transform(xxx.cbegin(), xxx.cend(), data.begin(),
- std::bind(&TProgramBuilder::NewDataLiteral<double>, std::ref(pgmBuilder), std::placeholders::_1 ));
-
- const auto type = pgmBuilder.NewDataType(NUdf::TDataType<double>::Id);
- const auto list = pgmBuilder.NewList(type, data);
-
- const auto pgmReturn = pgmBuilder.Sort(list, pgmBuilder.NewDataLiteral<bool>(false),
- std::bind(&TProgramBuilder::Abs, std::ref(pgmBuilder), std::placeholders::_1 ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& result = graph->GetValue();
-
- UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
-
- auto copy = xxx;
- std::stable_sort(copy.begin(), copy.end(), [](double l, double r){ return std::abs(l) > std::abs(r); });
-
- for (auto i = 0U; i < copy.size(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
- }
- }
-
- Y_UNIT_TEST_LLVM(TestListTop) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<double> unifd(-999.0, +999.0);
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 999ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<std::pair<double, ui64>> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false), pgmBuilder.NewDataLiteral<bool>(true)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.Top(list, limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), n);
-
- const auto& iter = value.GetListIterator();
-
- auto copy = test;
-
- const auto comp = [](const auto& l, const auto& r){ return l.second > r.second || (l.second == r.second && std::abs(l.first) < std::abs(r.first)); };
- std::nth_element(copy.begin(), copy.begin() + n - 1ULL, copy.end(), comp);
- copy.resize(n);
-
- std::vector<std::pair<double, ui64>> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; iter.Next(item);) {
- res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
- }
-
- std::sort(copy.begin(), copy.end());
- std::sort(res.begin(), res.end());
- UNIT_ASSERT(copy == res);
- }
-
- Y_UNIT_TEST_LLVM(TestStreamZeroTop) {
- TSetup<LLVM> setup;
-
- constexpr ui64 total = 9ULL;
-
- std::array<TRuntimeNode, total> data;
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(data.begin(), total, [&]() {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(42ULL)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 0U)}); };
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(0ULL);
-
- const auto pgmReturn = pgmBuilder.Top(pgmBuilder.Iterator(list, {}), limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
- NUdf::TUnboxedValue stub;
- UNIT_ASSERT_VALUES_EQUAL(value.Fetch(stub), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestListTopSort) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<double> unifd(-999.0, +999.0);
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 999ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<std::pair<double, ui64>> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false), pgmBuilder.NewDataLiteral<bool>(true)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.TopSort(list, limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), n);
-
- const auto& iter = value.GetListIterator();
-
- auto copy = test;
-
- const auto comp = [](const auto& l, const auto& r){ return l.second > r.second || (l.second == r.second && std::abs(l.first) < std::abs(r.first)); };
- std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), comp);
- copy.resize(n);
-
- std::vector<std::pair<double, ui64>> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; iter.Next(item);) {
- res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
- }
-
- UNIT_ASSERT(copy == res);
- }
-
- Y_UNIT_TEST_LLVM(TestStreamTop) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<double> unifd(-999.0, +999.0);
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 999ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<std::pair<double, ui64>> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(true), pgmBuilder.NewDataLiteral<bool>(false)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.Top(pgmBuilder.Iterator(list, {}), limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
-
- auto copy = test;
-
- const auto comp = [](const auto& l, const auto& r){ return l.second < r.second || (l.second == r.second && std::abs(l.first) > std::abs(r.first)); };
- std::nth_element(copy.begin(), copy.begin() + n - 1ULL, copy.end(), comp);
- copy.resize(n);
-
- std::vector<std::pair<double, ui64>> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
- res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
-
- std::sort(copy.begin(), copy.end());
- std::sort(res.begin(), res.end());
- UNIT_ASSERT(copy == res);
- }
-
- Y_UNIT_TEST_LLVM(TestStreamTopSort) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<double> unifd(-999.0, +999.0);
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 999ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<std::pair<double, ui64>> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(true), pgmBuilder.NewDataLiteral<bool>(false)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.TopSort(pgmBuilder.Iterator(list, {}), limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
-
- auto copy = test;
-
- const auto comp = [](const auto& l, const auto& r){ return l.second < r.second || (l.second == r.second && std::abs(l.first) > std::abs(r.first)); };
- std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), comp);
- copy.resize(n);
-
- std::vector<std::pair<double, ui64>> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
- res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
- UNIT_ASSERT(copy == res);
- }
-
- Y_UNIT_TEST_LLVM(TestStreamTopSortBySingleField) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 999ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<ui64> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return unifi(eng) % 100ULL; });
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const ui64& v) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(v)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false)});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 0U)}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.TopSort(pgmBuilder.Iterator(list, {}), limit, order, extractor);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
-
- auto copy = test;
-
- std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), std::greater<ui64>());
- copy.resize(n);
-
- std::vector<ui64> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
- res.emplace_back(item.GetElement(0U).template Get<ui64>());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
- UNIT_ASSERT(copy == res);
- }
-
- Y_UNIT_TEST_LLVM(TestFlowTopSortWithoutKey) {
- TSetup<LLVM> setup;
-
- std::default_random_engine eng;
- eng.seed(std::time(nullptr));
-
- std::uniform_real_distribution<ui64> unifi;
-
- constexpr ui64 total = 99ULL;
-
- std::array<TRuntimeNode, total> data;
- std::vector<ui64> test;
- test.reserve(total);
-
- TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
-
- std::generate_n(std::back_inserter(test), total, [&]() { return unifi(eng) % 100ULL; });
-
- std::transform(test.cbegin(), test.cend(), data.begin(), [&](const ui64& v) {
- return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(v)});
- });
-
- const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
- const auto order = pgmBuilder.NewTuple({});
- const auto list = pgmBuilder.NewList(tupleType, data);
- const auto extractor = [&pgmBuilder](TRuntimeNode) { return pgmBuilder.NewTuple({}); };
- const auto n = 17ULL;
- const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
-
- const auto pgmReturn = pgmBuilder.FromFlow(pgmBuilder.TopSort(pgmBuilder.ToFlow(list), limit, order, extractor));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto& value = graph->GetValue();
-
- auto copy = test;
- copy.resize(n);
-
- std::vector<ui64> res;
- res.reserve(n);
-
- for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
- res.emplace_back(item.GetElement(0U).template Get<ui64>());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
- UNIT_ASSERT(copy == res);
- }
+
+ Y_UNIT_TEST_LLVM(TestFlowSortByLambdaComparator) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ const auto stream = MakeStream(setup);
+
+ const auto sort =
+ pgmBuilder.FromFlow(pgmBuilder.FlatMap(
+ pgmBuilder.Condense1(pgmBuilder.ToFlow(stream),
+ [&](TRuntimeNode item) { return pgmBuilder.AsList(item); },
+ [&](TRuntimeNode, TRuntimeNode) { return pgmBuilder.NewDataLiteral<bool>(false); },
+ [&](TRuntimeNode item, TRuntimeNode state) { return pgmBuilder.Append(state, item); }
+ ),
+ [&](TRuntimeNode list) {
+ return pgmBuilder.StableSort(list,
+ [&](TRuntimeNode left, TRuntimeNode right) {
+ return pgmBuilder.Or({
+ pgmBuilder.AggrLess(pgmBuilder.Member(left, "a"), pgmBuilder.Member(right, "a")),
+ pgmBuilder.And({
+ pgmBuilder.AggrEquals(pgmBuilder.Member(left, "a"), pgmBuilder.Member(right, "a")),
+ pgmBuilder.AggrGreater(pgmBuilder.Member(left, "b"), pgmBuilder.Member(right, "b"))
+ })
+ });
+ }
+ );
+ }
+ ));
+
+ const auto pgmResult = StreamToString(pgmBuilder, sort);
+
+ const auto graph = setup.BuildGraph(pgmResult);
+ const auto value = graph->GetValue();
+
+
+ NUdf::TUnboxedValue result;
+ auto yieldCount = 0U;
+ auto status = NUdf::EFetchStatus::Ok;
+ while (status != NUdf::EFetchStatus::Finish) {
+ status = value.Fetch(result);
+ if (status == NUdf::EFetchStatus::Yield) {
+ ++yieldCount;
+ }
+ }
+
+ UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
+ UNIT_ASSERT_EQUAL(yieldCount, 3U);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()),
+ "|0-8|0-4|0-11|0-0|1-9|1-6|1-13|1-1|2-7|2-2|2-14|2-10|");
+ }
+
+ Y_UNIT_TEST_LLVM(TestListSort) {
+ const std::array<double, 10U> xxx = {{9E9, -HUGE_VAL, 0.003, HUGE_VAL, +3.1415, -0.003, -7898.8, -3.1415, 3673.0, 0.003}};
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::array<TRuntimeNode, 10U> data;
+ std::transform(xxx.cbegin(), xxx.cend(), data.begin(),
+ std::bind(&TProgramBuilder::NewDataLiteral<double>, std::ref(pgmBuilder), std::placeholders::_1 ));
+
+ const auto type = pgmBuilder.NewDataType(NUdf::TDataType<double>::Id);
+ const auto list = pgmBuilder.NewList(type, data);
+
+ const auto pgmReturn = pgmBuilder.Sort(list, pgmBuilder.NewDataLiteral<bool>(false),
+ std::bind(&TProgramBuilder::Abs, std::ref(pgmBuilder), std::placeholders::_1 ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& result = graph->GetValue();
+
+ UNIT_ASSERT_VALUES_EQUAL(result.GetListLength(), xxx.size());
+
+ auto copy = xxx;
+ std::stable_sort(copy.begin(), copy.end(), [](double l, double r){ return std::abs(l) > std::abs(r); });
+
+ for (auto i = 0U; i < copy.size(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(copy[i], result.GetElement(i).template Get<double>());
+ }
+ }
+
+ Y_UNIT_TEST_LLVM(TestListTop) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<double> unifd(-999.0, +999.0);
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 999ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<std::pair<double, ui64>> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false), pgmBuilder.NewDataLiteral<bool>(true)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.Top(list, limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), n);
+
+ const auto& iter = value.GetListIterator();
+
+ auto copy = test;
+
+ const auto comp = [](const auto& l, const auto& r){ return l.second > r.second || (l.second == r.second && std::abs(l.first) < std::abs(r.first)); };
+ std::nth_element(copy.begin(), copy.begin() + n - 1ULL, copy.end(), comp);
+ copy.resize(n);
+
+ std::vector<std::pair<double, ui64>> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; iter.Next(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
+ }
+
+ std::sort(copy.begin(), copy.end());
+ std::sort(res.begin(), res.end());
+ UNIT_ASSERT(copy == res);
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamZeroTop) {
+ TSetup<LLVM> setup;
+
+ constexpr ui64 total = 9ULL;
+
+ std::array<TRuntimeNode, total> data;
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(data.begin(), total, [&]() {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(42ULL)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 0U)}); };
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(0ULL);
+
+ const auto pgmReturn = pgmBuilder.Top(pgmBuilder.Iterator(list, {}), limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+ NUdf::TUnboxedValue stub;
+ UNIT_ASSERT_VALUES_EQUAL(value.Fetch(stub), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestListTopSort) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<double> unifd(-999.0, +999.0);
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 999ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<std::pair<double, ui64>> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false), pgmBuilder.NewDataLiteral<bool>(true)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.TopSort(list, limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), n);
+
+ const auto& iter = value.GetListIterator();
+
+ auto copy = test;
+
+ const auto comp = [](const auto& l, const auto& r){ return l.second > r.second || (l.second == r.second && std::abs(l.first) < std::abs(r.first)); };
+ std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), comp);
+ copy.resize(n);
+
+ std::vector<std::pair<double, ui64>> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; iter.Next(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
+ }
+
+ UNIT_ASSERT(copy == res);
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamTop) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<double> unifd(-999.0, +999.0);
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 999ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<std::pair<double, ui64>> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(true), pgmBuilder.NewDataLiteral<bool>(false)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.Top(pgmBuilder.Iterator(list, {}), limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+
+ auto copy = test;
+
+ const auto comp = [](const auto& l, const auto& r){ return l.second < r.second || (l.second == r.second && std::abs(l.first) > std::abs(r.first)); };
+ std::nth_element(copy.begin(), copy.begin() + n - 1ULL, copy.end(), comp);
+ copy.resize(n);
+
+ std::vector<std::pair<double, ui64>> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
+
+ std::sort(copy.begin(), copy.end());
+ std::sort(res.begin(), res.end());
+ UNIT_ASSERT(copy == res);
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamTopSort) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<double> unifd(-999.0, +999.0);
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 999ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<std::pair<double, ui64>> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return std::make_pair(unifd(eng), unifi(eng) % 100U);});
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const auto& pair) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<double>(pair.first), pgmBuilder.NewDataLiteral<ui64>(pair.second)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<double>::Id), pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(true), pgmBuilder.NewDataLiteral<bool>(false)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 1U), pgmBuilder.Abs(pgmBuilder.Nth(item, 0U))}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.TopSort(pgmBuilder.Iterator(list, {}), limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+
+ auto copy = test;
+
+ const auto comp = [](const auto& l, const auto& r){ return l.second < r.second || (l.second == r.second && std::abs(l.first) > std::abs(r.first)); };
+ std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), comp);
+ copy.resize(n);
+
+ std::vector<std::pair<double, ui64>> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<double>(), item.GetElement(1U).template Get<ui64>());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
+ UNIT_ASSERT(copy == res);
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamTopSortBySingleField) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 999ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<ui64> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return unifi(eng) % 100ULL; });
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const ui64& v) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(v)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<bool>(false)});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode item) { return pgmBuilder.NewTuple({pgmBuilder.Nth(item, 0U)}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.TopSort(pgmBuilder.Iterator(list, {}), limit, order, extractor);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+
+ auto copy = test;
+
+ std::partial_sort(copy.begin(), copy.begin() + n, copy.end(), std::greater<ui64>());
+ copy.resize(n);
+
+ std::vector<ui64> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<ui64>());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
+ UNIT_ASSERT(copy == res);
+ }
+
+ Y_UNIT_TEST_LLVM(TestFlowTopSortWithoutKey) {
+ TSetup<LLVM> setup;
+
+ std::default_random_engine eng;
+ eng.seed(std::time(nullptr));
+
+ std::uniform_real_distribution<ui64> unifi;
+
+ constexpr ui64 total = 99ULL;
+
+ std::array<TRuntimeNode, total> data;
+ std::vector<ui64> test;
+ test.reserve(total);
+
+ TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
+
+ std::generate_n(std::back_inserter(test), total, [&]() { return unifi(eng) % 100ULL; });
+
+ std::transform(test.cbegin(), test.cend(), data.begin(), [&](const ui64& v) {
+ return pgmBuilder.NewTuple({pgmBuilder.NewDataLiteral<ui64>(v)});
+ });
+
+ const auto tupleType = pgmBuilder.NewTupleType({pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)});
+ const auto order = pgmBuilder.NewTuple({});
+ const auto list = pgmBuilder.NewList(tupleType, data);
+ const auto extractor = [&pgmBuilder](TRuntimeNode) { return pgmBuilder.NewTuple({}); };
+ const auto n = 17ULL;
+ const auto limit = pgmBuilder.NewDataLiteral<ui64>(n);
+
+ const auto pgmReturn = pgmBuilder.FromFlow(pgmBuilder.TopSort(pgmBuilder.ToFlow(list), limit, order, extractor));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto& value = graph->GetValue();
+
+ auto copy = test;
+ copy.resize(n);
+
+ std::vector<ui64> res;
+ res.reserve(n);
+
+ for (NUdf::TUnboxedValue item; NUdf::EFetchStatus::Ok == value.Fetch(item);) {
+ res.emplace_back(item.GetElement(0U).template Get<ui64>());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(res.size(), n);
+ UNIT_ASSERT(copy == res);
+ }
}
} // NMiniKQL
} // NKikimr
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_switch_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_switch_ut.cpp
index 6d015114cd..37472db9d6 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_switch_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_switch_ut.cpp
@@ -1,276 +1,276 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLSwitchTest) {
- Y_UNIT_TEST_LLVM(TestStreamOfVariantsSwap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto data3 = pb.NewDataLiteral<ui32>(3U);
-
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
-
- const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
-
- const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
-
- const auto var1 = pb.NewVariant(data1, 0U, varInType);
- const auto var2 = pb.NewVariant(data2, 0U, varInType);
- const auto var3 = pb.NewVariant(data3, 0U, varInType);
- const auto var4 = pb.NewVariant(data4, 1U, varInType);
- const auto var5 = pb.NewVariant(data5, 1U, varInType);
- const auto var6 = pb.NewVariant(data6, 1U, varInType);
-
- const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
-
- const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
-
- const auto pgmReturn = pb.Switch(pb.Iterator(list, {}),
- {{{0U}, pb.NewStreamType(intType), std::nullopt}, {{1U}, pb.NewStreamType(strType), std::nullopt}},
- [&](ui32 index, TRuntimeNode stream) {
- switch (index) {
- case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.ToString(item), 0U, varOutType); });
- case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
- }
- Y_FAIL("Wrong case!");
- },
- 0ULL,
- pb.NewStreamType(varOutType)
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "1");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "2");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "3");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestStreamOfVariantsTwoInOne) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto data3 = pb.NewDataLiteral<ui32>(3U);
-
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
-
- const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
-
- const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
-
- const auto var1 = pb.NewVariant(data1, 0U, varInType);
- const auto var2 = pb.NewVariant(data2, 0U, varInType);
- const auto var3 = pb.NewVariant(data3, 0U, varInType);
- const auto var4 = pb.NewVariant(data4, 1U, varInType);
- const auto var5 = pb.NewVariant(data5, 1U, varInType);
- const auto var6 = pb.NewVariant(data6, 1U, varInType);
-
- const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
-
- const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
-
- const auto pgmReturn = pb.Switch(pb.Iterator(list, {}),
- {{{0U}, pb.NewStreamType(intType), 1U}, {{1U}, pb.NewStreamType(strType), std::nullopt}},
- [&](ui32 index, TRuntimeNode stream) {
- switch (index) {
- case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return item; });
- case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
- }
- Y_FAIL("Wrong case!");
- },
- 0ULL,
- pb.NewStreamType(varOutType)
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 2U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 3U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFlowOfVariantsSwap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto data3 = pb.NewDataLiteral<ui32>(3U);
-
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
-
- const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
-
- const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
-
- const auto var1 = pb.NewVariant(data1, 0U, varInType);
- const auto var2 = pb.NewVariant(data2, 0U, varInType);
- const auto var3 = pb.NewVariant(data3, 0U, varInType);
- const auto var4 = pb.NewVariant(data4, 1U, varInType);
- const auto var5 = pb.NewVariant(data5, 1U, varInType);
- const auto var6 = pb.NewVariant(data6, 1U, varInType);
-
- const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
-
- const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
-
- const auto pgmReturn = pb.FromFlow(pb.Switch(pb.ToFlow(list),
- {{{0U}, pb.NewFlowType(intType), std::nullopt}, {{1U}, pb.NewFlowType(strType), std::nullopt}},
- [&](ui32 index, TRuntimeNode stream) {
- switch (index) {
- case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.ToString(item), 0U, varOutType); });
- case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
- }
- Y_FAIL("Wrong case!");
- },
- 0ULL,
- pb.NewFlowType(varOutType)
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "1");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "2");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
- UNBOXED_VALUE_STR_EQUAL(item, "3");
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFlowOfVariantsTwoInOne) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1U);
- const auto data2 = pb.NewDataLiteral<ui32>(2U);
- const auto data3 = pb.NewDataLiteral<ui32>(3U);
-
- const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
- const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
- const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
-
- const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
-
- const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
-
- const auto var1 = pb.NewVariant(data1, 0U, varInType);
- const auto var2 = pb.NewVariant(data2, 0U, varInType);
- const auto var3 = pb.NewVariant(data3, 0U, varInType);
- const auto var4 = pb.NewVariant(data4, 1U, varInType);
- const auto var5 = pb.NewVariant(data5, 1U, varInType);
- const auto var6 = pb.NewVariant(data6, 1U, varInType);
-
- const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
-
- const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
-
- const auto pgmReturn = pb.FromFlow(pb.Switch(pb.ToFlow(list),
- {{{0U}, pb.NewFlowType(intType), 1U}, {{1U}, pb.NewFlowType(strType), std::nullopt}},
- [&](ui32 index, TRuntimeNode stream) {
- switch (index) {
- case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return item; });
- case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
- }
- Y_FAIL("Wrong case!");
- },
- 0ULL,
- pb.NewFlowType(varOutType)
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 2U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 3U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLSwitchTest) {
+ Y_UNIT_TEST_LLVM(TestStreamOfVariantsSwap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto data3 = pb.NewDataLiteral<ui32>(3U);
+
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
+
+ const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+
+ const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
+
+ const auto var1 = pb.NewVariant(data1, 0U, varInType);
+ const auto var2 = pb.NewVariant(data2, 0U, varInType);
+ const auto var3 = pb.NewVariant(data3, 0U, varInType);
+ const auto var4 = pb.NewVariant(data4, 1U, varInType);
+ const auto var5 = pb.NewVariant(data5, 1U, varInType);
+ const auto var6 = pb.NewVariant(data6, 1U, varInType);
+
+ const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
+
+ const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
+
+ const auto pgmReturn = pb.Switch(pb.Iterator(list, {}),
+ {{{0U}, pb.NewStreamType(intType), std::nullopt}, {{1U}, pb.NewStreamType(strType), std::nullopt}},
+ [&](ui32 index, TRuntimeNode stream) {
+ switch (index) {
+ case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.ToString(item), 0U, varOutType); });
+ case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
+ }
+ Y_FAIL("Wrong case!");
+ },
+ 0ULL,
+ pb.NewStreamType(varOutType)
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "1");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "2");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "3");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestStreamOfVariantsTwoInOne) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto data3 = pb.NewDataLiteral<ui32>(3U);
+
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
+
+ const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+
+ const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
+
+ const auto var1 = pb.NewVariant(data1, 0U, varInType);
+ const auto var2 = pb.NewVariant(data2, 0U, varInType);
+ const auto var3 = pb.NewVariant(data3, 0U, varInType);
+ const auto var4 = pb.NewVariant(data4, 1U, varInType);
+ const auto var5 = pb.NewVariant(data5, 1U, varInType);
+ const auto var6 = pb.NewVariant(data6, 1U, varInType);
+
+ const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
+
+ const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
+
+ const auto pgmReturn = pb.Switch(pb.Iterator(list, {}),
+ {{{0U}, pb.NewStreamType(intType), 1U}, {{1U}, pb.NewStreamType(strType), std::nullopt}},
+ [&](ui32 index, TRuntimeNode stream) {
+ switch (index) {
+ case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return item; });
+ case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
+ }
+ Y_FAIL("Wrong case!");
+ },
+ 0ULL,
+ pb.NewStreamType(varOutType)
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 2U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 3U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFlowOfVariantsSwap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto data3 = pb.NewDataLiteral<ui32>(3U);
+
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
+
+ const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+
+ const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
+
+ const auto var1 = pb.NewVariant(data1, 0U, varInType);
+ const auto var2 = pb.NewVariant(data2, 0U, varInType);
+ const auto var3 = pb.NewVariant(data3, 0U, varInType);
+ const auto var4 = pb.NewVariant(data4, 1U, varInType);
+ const auto var5 = pb.NewVariant(data5, 1U, varInType);
+ const auto var6 = pb.NewVariant(data6, 1U, varInType);
+
+ const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
+
+ const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
+
+ const auto pgmReturn = pb.FromFlow(pb.Switch(pb.ToFlow(list),
+ {{{0U}, pb.NewFlowType(intType), std::nullopt}, {{1U}, pb.NewFlowType(strType), std::nullopt}},
+ [&](ui32 index, TRuntimeNode stream) {
+ switch (index) {
+ case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.ToString(item), 0U, varOutType); });
+ case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
+ }
+ Y_FAIL("Wrong case!");
+ },
+ 0ULL,
+ pb.NewFlowType(varOutType)
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "1");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "2");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0U);
+ UNBOXED_VALUE_STR_EQUAL(item, "3");
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFlowOfVariantsTwoInOne) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1U);
+ const auto data2 = pb.NewDataLiteral<ui32>(2U);
+ const auto data3 = pb.NewDataLiteral<ui32>(3U);
+
+ const auto data4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("123");
+ const auto data5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("456");
+ const auto data6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("789");
+
+ const auto intType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto strType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+
+ const auto varInType = pb.NewVariantType(pb.NewTupleType({intType, strType}));
+
+ const auto var1 = pb.NewVariant(data1, 0U, varInType);
+ const auto var2 = pb.NewVariant(data2, 0U, varInType);
+ const auto var3 = pb.NewVariant(data3, 0U, varInType);
+ const auto var4 = pb.NewVariant(data4, 1U, varInType);
+ const auto var5 = pb.NewVariant(data5, 1U, varInType);
+ const auto var6 = pb.NewVariant(data6, 1U, varInType);
+
+ const auto varOutType = pb.NewVariantType(pb.NewTupleType({strType, intType}));
+
+ const auto list = pb.NewList(varInType, {var1, var2, var3, var4, var5, var6});
+
+ const auto pgmReturn = pb.FromFlow(pb.Switch(pb.ToFlow(list),
+ {{{0U}, pb.NewFlowType(intType), 1U}, {{1U}, pb.NewFlowType(strType), std::nullopt}},
+ [&](ui32 index, TRuntimeNode stream) {
+ switch (index) {
+ case 0U: return pb.Map(stream, [&](TRuntimeNode item) { return item; });
+ case 1U: return pb.Map(stream, [&](TRuntimeNode item) { return pb.NewVariant(pb.StrictFromString(item, intType), 1U, varOutType); });
+ }
+ Y_FAIL("Wrong case!");
+ },
+ 0ULL,
+ pb.NewFlowType(varOutType)
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 2U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 3U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 123U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 456U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1U);
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), 789U);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_todict_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_todict_ut.cpp
index 6d20619e0e..5a5cd7e2de 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_todict_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_todict_ut.cpp
@@ -161,59 +161,59 @@ Y_UNIT_TEST_SUITE(TMiniKQLToDictTest) {
}
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 23u
- Y_UNIT_TEST_LLVM(TestNarrowSqueezeToDict) {
- auto test = [](bool hashed, bool multi, bool compact, bool withPayload) {
- Cerr << "TestNarrowSqueezeToDict [type: " << (hashed ? "hashed" : "sorted") << ", multi: " << multi
- << ", compact: " << compact << ", payload: " << withPayload << "]" << Endl;
-
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- TVector<TRuntimeNode> items;
- for (auto s : data) {
- items.push_back(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(s));
- }
- Shuffle(items.begin(), items.end());
-
- auto dataType = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
- auto list = pb.NewList(dataType, items);
- auto input = pb.ExpandMap(pb.ToFlow(list), [](TRuntimeNode n) ->TRuntimeNode::TList { return {n}; });
- auto pgmReturn = hashed
- ? pb.NarrowSqueezeToHashedDict(input, multi, [](TRuntimeNode::TList n) { return n.front(); },
- [&pb, withPayload](TRuntimeNode::TList n) { return withPayload ? n.back() : pb.NewVoid(); }, compact)
- : pb.NarrowSqueezeToSortedDict(input, multi, [](TRuntimeNode::TList n) { return n.front(); },
- [&pb, withPayload](TRuntimeNode::TList n) { return withPayload ? n.back() : pb.NewVoid(); }, compact);
- pgmReturn = pb.FromFlow(pgmReturn);
-
- auto graph = setup.BuildGraph(pgmReturn);
- NUdf::TUnboxedValue res = graph->GetValue();
- UNIT_ASSERT(!res.IsSpecial());
-
- NUdf::TUnboxedValue v;
- auto status = res.Fetch(v);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, status);
-
- for (auto s : data) {
- UNIT_ASSERT_C(v.Contains(NUdf::TUnboxedValue(MakeString(s))), s);
- }
- UNIT_ASSERT(!v.Contains(NUdf::TUnboxedValue(MakeString("green cucumber"))));
-
- status = res.Fetch(v);
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
- };
-
- for (auto hashed : {true, false}) {
- for (auto multi : {true, false}) {
- for (auto compact : {true, false}) {
- for (auto withPayload : {true, false}) {
- test(hashed, multi, compact, withPayload);
- }
- }
- }
- }
- }
-#endif
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 23u
+ Y_UNIT_TEST_LLVM(TestNarrowSqueezeToDict) {
+ auto test = [](bool hashed, bool multi, bool compact, bool withPayload) {
+ Cerr << "TestNarrowSqueezeToDict [type: " << (hashed ? "hashed" : "sorted") << ", multi: " << multi
+ << ", compact: " << compact << ", payload: " << withPayload << "]" << Endl;
+
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ TVector<TRuntimeNode> items;
+ for (auto s : data) {
+ items.push_back(pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(s));
+ }
+ Shuffle(items.begin(), items.end());
+
+ auto dataType = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
+ auto list = pb.NewList(dataType, items);
+ auto input = pb.ExpandMap(pb.ToFlow(list), [](TRuntimeNode n) ->TRuntimeNode::TList { return {n}; });
+ auto pgmReturn = hashed
+ ? pb.NarrowSqueezeToHashedDict(input, multi, [](TRuntimeNode::TList n) { return n.front(); },
+ [&pb, withPayload](TRuntimeNode::TList n) { return withPayload ? n.back() : pb.NewVoid(); }, compact)
+ : pb.NarrowSqueezeToSortedDict(input, multi, [](TRuntimeNode::TList n) { return n.front(); },
+ [&pb, withPayload](TRuntimeNode::TList n) { return withPayload ? n.back() : pb.NewVoid(); }, compact);
+ pgmReturn = pb.FromFlow(pgmReturn);
+
+ auto graph = setup.BuildGraph(pgmReturn);
+ NUdf::TUnboxedValue res = graph->GetValue();
+ UNIT_ASSERT(!res.IsSpecial());
+
+ NUdf::TUnboxedValue v;
+ auto status = res.Fetch(v);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, status);
+
+ for (auto s : data) {
+ UNIT_ASSERT_C(v.Contains(NUdf::TUnboxedValue(MakeString(s))), s);
+ }
+ UNIT_ASSERT(!v.Contains(NUdf::TUnboxedValue(MakeString("green cucumber"))));
+
+ status = res.Fetch(v);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
+ };
+
+ for (auto hashed : {true, false}) {
+ for (auto multi : {true, false}) {
+ for (auto compact : {true, false}) {
+ for (auto withPayload : {true, false}) {
+ test(hashed, multi, compact, withPayload);
+ }
+ }
+ }
+ }
+ }
+#endif
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_variant_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_variant_ut.cpp
index 9930b31ca3..2a52f73ef3 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_variant_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_variant_ut.cpp
@@ -1,526 +1,526 @@
-#include "mkql_computation_node_ut.h"
-
+#include "mkql_computation_node_ut.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-Y_UNIT_TEST_SUITE(TMiniKQLVariantTest) {
- Y_UNIT_TEST_LLVM(TestGuessTuple) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- std::vector<TRuntimeNode> tupleItems;
- tupleItems.push_back(pb.Guess(var1, 0));
- tupleItems.push_back(pb.Guess(var1, 1));
- tupleItems.push_back(pb.Guess(var2, 0));
- tupleItems.push_back(pb.Guess(var2, 1));
- const auto pgmReturn = pb.NewTuple(tupleItems);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNIT_ASSERT(res.GetElement(0));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+Y_UNIT_TEST_SUITE(TMiniKQLVariantTest) {
+ Y_UNIT_TEST_LLVM(TestGuessTuple) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ std::vector<TRuntimeNode> tupleItems;
+ tupleItems.push_back(pb.Guess(var1, 0));
+ tupleItems.push_back(pb.Guess(var1, 1));
+ tupleItems.push_back(pb.Guess(var2, 0));
+ tupleItems.push_back(pb.Guess(var2, 1));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNIT_ASSERT(res.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
- UNIT_ASSERT(!res.GetElement(1));
- UNIT_ASSERT(!res.GetElement(2));
- UNIT_ASSERT(res.GetElement(3));
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
+ UNIT_ASSERT(!res.GetElement(1));
+ UNIT_ASSERT(!res.GetElement(2));
+ UNIT_ASSERT(res.GetElement(3));
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
}
- Y_UNIT_TEST_LLVM(TestGuessTupleOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- const auto jvar1 = pb.NewOptional(var1);
- const auto jvar2 = pb.NewOptional(var2);
- const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
-
- std::vector<TRuntimeNode> tupleItems;
- tupleItems.push_back(pb.Guess(jvar1, 0));
- tupleItems.push_back(pb.Guess(jvar1, 1));
- tupleItems.push_back(pb.Guess(jvar2, 0));
- tupleItems.push_back(pb.Guess(jvar2, 1));
- tupleItems.push_back(pb.Guess(nothing, 0));
- tupleItems.push_back(pb.Guess(nothing, 1));
- const auto pgmReturn = pb.NewTuple(tupleItems);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNIT_ASSERT(res.GetElement(0));
+ Y_UNIT_TEST_LLVM(TestGuessTupleOpt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ const auto jvar1 = pb.NewOptional(var1);
+ const auto jvar2 = pb.NewOptional(var2);
+ const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
+
+ std::vector<TRuntimeNode> tupleItems;
+ tupleItems.push_back(pb.Guess(jvar1, 0));
+ tupleItems.push_back(pb.Guess(jvar1, 1));
+ tupleItems.push_back(pb.Guess(jvar2, 0));
+ tupleItems.push_back(pb.Guess(jvar2, 1));
+ tupleItems.push_back(pb.Guess(nothing, 0));
+ tupleItems.push_back(pb.Guess(nothing, 1));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNIT_ASSERT(res.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
- UNIT_ASSERT(!res.GetElement(1));
- UNIT_ASSERT(!res.GetElement(2));
- UNIT_ASSERT(res.GetElement(3));
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
- UNIT_ASSERT(!res.GetElement(4));
- UNIT_ASSERT(!res.GetElement(5));
+ UNIT_ASSERT(!res.GetElement(1));
+ UNIT_ASSERT(!res.GetElement(2));
+ UNIT_ASSERT(res.GetElement(3));
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
+ UNIT_ASSERT(!res.GetElement(4));
+ UNIT_ASSERT(!res.GetElement(5));
}
- Y_UNIT_TEST_LLVM(TestGuessStruct) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- std::vector<TRuntimeNode> tupleItems;
- tupleItems.push_back(pb.Guess(var1, "x"));
- tupleItems.push_back(pb.Guess(var1, "y"));
- tupleItems.push_back(pb.Guess(var2, "x"));
- tupleItems.push_back(pb.Guess(var2, "y"));
- const auto pgmReturn = pb.NewTuple(tupleItems);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNIT_ASSERT(res.GetElement(0));
+ Y_UNIT_TEST_LLVM(TestGuessStruct) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ std::vector<TRuntimeNode> tupleItems;
+ tupleItems.push_back(pb.Guess(var1, "x"));
+ tupleItems.push_back(pb.Guess(var1, "y"));
+ tupleItems.push_back(pb.Guess(var2, "x"));
+ tupleItems.push_back(pb.Guess(var2, "y"));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNIT_ASSERT(res.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
- UNIT_ASSERT(!res.GetElement(1));
- UNIT_ASSERT(!res.GetElement(2));
- UNIT_ASSERT(res.GetElement(3));
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
+ UNIT_ASSERT(!res.GetElement(1));
+ UNIT_ASSERT(!res.GetElement(2));
+ UNIT_ASSERT(res.GetElement(3));
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
}
- Y_UNIT_TEST_LLVM(TestGuessStructOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto jvar1 = pb.NewOptional(var1);
- const auto jvar2 = pb.NewOptional(var2);
- const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
-
- std::vector<TRuntimeNode> tupleItems;
- tupleItems.push_back(pb.Guess(jvar1, "x"));
- tupleItems.push_back(pb.Guess(jvar1, "y"));
- tupleItems.push_back(pb.Guess(jvar2, "x"));
- tupleItems.push_back(pb.Guess(jvar2, "y"));
- tupleItems.push_back(pb.Guess(nothing, "x"));
- tupleItems.push_back(pb.Guess(nothing, "y"));
- const auto pgmReturn = pb.NewTuple(tupleItems);
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNIT_ASSERT(res.GetElement(0));
+ Y_UNIT_TEST_LLVM(TestGuessStructOpt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto jvar1 = pb.NewOptional(var1);
+ const auto jvar2 = pb.NewOptional(var2);
+ const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
+
+ std::vector<TRuntimeNode> tupleItems;
+ tupleItems.push_back(pb.Guess(jvar1, "x"));
+ tupleItems.push_back(pb.Guess(jvar1, "y"));
+ tupleItems.push_back(pb.Guess(jvar2, "x"));
+ tupleItems.push_back(pb.Guess(jvar2, "y"));
+ tupleItems.push_back(pb.Guess(nothing, "x"));
+ tupleItems.push_back(pb.Guess(nothing, "y"));
+ const auto pgmReturn = pb.NewTuple(tupleItems);
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNIT_ASSERT(res.GetElement(0));
UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
- UNIT_ASSERT(!res.GetElement(1));
- UNIT_ASSERT(!res.GetElement(2));
- UNIT_ASSERT(res.GetElement(3));
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
- UNIT_ASSERT(!res.GetElement(4));
- UNIT_ASSERT(!res.GetElement(5));
+ UNIT_ASSERT(!res.GetElement(1));
+ UNIT_ASSERT(!res.GetElement(2));
+ UNIT_ASSERT(res.GetElement(3));
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
+ UNIT_ASSERT(!res.GetElement(4));
+ UNIT_ASSERT(!res.GetElement(5));
+ }
+
+ Y_UNIT_TEST_LLVM(TestVisitAllTuple) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ const auto list = pb.NewList(varType, {var1, var2});
+ const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
+ return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
+ if (!index) {
+ return pb.Concat(at, pb.ToString(item));
+ } else {
+ return pb.Concat(at, item);
+ }
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
+ }
+
+ Y_UNIT_TEST_LLVM(TestVisitAllStruct) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto list = pb.NewList(varType, {var1, var2});
+
+ const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
+ const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
+ return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
+ if (xIndex == index) {
+ return pb.Concat(at, pb.ToString(item));
+ } else {
+ return pb.Concat(at, item);
+ }
+ });
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
+ UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
+ }
+
+ Y_UNIT_TEST_LLVM(TestVisitAllTupleFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
+ const auto data1 = pb.NewDataLiteral<ui64>(3ULL);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui64>::Id), pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ const auto list = pb.NewList(varType, {var1, var2});
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
+ return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
+ if (!index) {
+ return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
+ } else {
+ return pb.ToFlow(pb.NewOptional(item));
+ }
+ });
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "abc");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
}
- Y_UNIT_TEST_LLVM(TestVisitAllTuple) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- const auto list = pb.NewList(varType, {var1, var2});
- const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
- return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
- if (!index) {
- return pb.Concat(at, pb.ToString(item));
- } else {
- return pb.Concat(at, item);
- }
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
+ Y_UNIT_TEST_LLVM(TestVisitAllStructFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
+ const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto list = pb.NewList(varType, {var2, var1, var2});
+
+ const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
+ const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
+ return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
+ if (xIndex == index) {
+ return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
+ } else {
+ return pb.ToFlow(pb.NewOptional(item));
+ }
+ });
+ }));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "abc");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "@");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item, "abc");
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
}
- Y_UNIT_TEST_LLVM(TestVisitAllStruct) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto list = pb.NewList(varType, {var1, var2});
-
- const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
- const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
- return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
- if (xIndex == index) {
- return pb.Concat(at, pb.ToString(item));
- } else {
- return pb.Concat(at, item);
- }
- });
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
- UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
+ Y_UNIT_TEST_LLVM(TestVisitAllStructWideFlow) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
+ const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto list = pb.NewList(varType, {var2, var1, var2});
+
+ const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
+ return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
+ if (xIndex == index) {
+ return pb.ExpandMap(pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(i32(index))}; });
+ } else {
+ return pb.ExpandMap(pb.ToFlow(pb.NewOptional(item)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(-i32(index))}; });
+ }
+ });
+ }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto res = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
+ UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
+ UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
}
- Y_UNIT_TEST_LLVM(TestVisitAllTupleFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
- const auto data1 = pb.NewDataLiteral<ui64>(3ULL);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui64>::Id), pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- const auto list = pb.NewList(varType, {var1, var2});
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
- return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
- if (!index) {
- return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
- } else {
- return pb.ToFlow(pb.NewOptional(item));
- }
- });
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "abc");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestVisitAllStructFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
- const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto list = pb.NewList(varType, {var2, var1, var2});
-
- const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
- const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
- return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
- if (xIndex == index) {
- return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
- } else {
- return pb.ToFlow(pb.NewOptional(item));
- }
- });
- }));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "abc");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "@");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item, "abc");
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestVisitAllStructWideFlow) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
- const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto list = pb.NewList(varType, {var2, var1, var2});
-
- const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
- return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
- if (xIndex == index) {
- return pb.ExpandMap(pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(i32(index))}; });
- } else {
- return pb.ExpandMap(pb.ToFlow(pb.NewOptional(item)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(-i32(index))}; });
- }
- });
- }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto res = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
- UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestWayTuple) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- const auto list = pb.NewList(varType, {var2, var1});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) { return pb.Way(item); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWayTupleOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
- const auto varType = pb.NewVariantType(tupleType);
- const auto var1 = pb.NewVariant(data1, 0, varType);
- const auto var2 = pb.NewVariant(data2, 1, varType);
- const auto jvar1 = pb.NewOptional(var1);
- const auto jvar2 = pb.NewOptional(var2);
- const auto optType = pb.NewOptionalType(varType);
- const auto nothing = pb.NewEmptyOptional(optType);
- const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) { return pb.Way(item); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWayStruct) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto list = pb.NewList(varType, {var2, var1});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) { return pb.Way(item); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "y");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "x");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWayStructOpt) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data1 = pb.NewDataLiteral<ui32>(1);
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
- const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
- const auto varType = pb.NewVariantType(structType);
- const auto var1 = pb.NewVariant(data1, "x", varType);
- const auto var2 = pb.NewVariant(data2, "y", varType);
- const auto jvar1 = pb.NewOptional(var1);
- const auto jvar2 = pb.NewOptional(var2);
- const auto optType = pb.NewOptionalType(varType);
- const auto nothing = pb.NewEmptyOptional(optType);
- const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) { return pb.Way(item); }
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
-
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "y");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "x");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestItemInMap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
-
- const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
- const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
- const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
- const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
- const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
- const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
- const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.VariantItem(item);
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 77);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "abc");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "DEF");
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1267);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestGuessInMap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
-
- const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
- const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
- const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
- const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
- const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
- const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
- const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
-
- const auto pgmReturn = pb.Map(list,
- [&](TRuntimeNode item) {
- return pb.NewTuple({pb.Guess(item, 0), pb.Guess(item, 2)});
- });
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 77);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), false);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), true);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1267);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
+ Y_UNIT_TEST_LLVM(TestWayTuple) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ const auto list = pb.NewList(varType, {var2, var1});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) { return pb.Way(item); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWayTupleOpt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
+ const auto varType = pb.NewVariantType(tupleType);
+ const auto var1 = pb.NewVariant(data1, 0, varType);
+ const auto var2 = pb.NewVariant(data2, 1, varType);
+ const auto jvar1 = pb.NewOptional(var1);
+ const auto jvar2 = pb.NewOptional(var2);
+ const auto optType = pb.NewOptionalType(varType);
+ const auto nothing = pb.NewEmptyOptional(optType);
+ const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) { return pb.Way(item); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWayStruct) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto list = pb.NewList(varType, {var2, var1});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) { return pb.Way(item); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "y");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "x");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWayStructOpt) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data1 = pb.NewDataLiteral<ui32>(1);
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
+ const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
+ const auto varType = pb.NewVariantType(structType);
+ const auto var1 = pb.NewVariant(data1, "x", varType);
+ const auto var2 = pb.NewVariant(data2, "y", varType);
+ const auto jvar1 = pb.NewOptional(var1);
+ const auto jvar2 = pb.NewOptional(var2);
+ const auto optType = pb.NewOptionalType(varType);
+ const auto nothing = pb.NewEmptyOptional(optType);
+ const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) { return pb.Way(item); }
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "y");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "x");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestItemInMap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
+
+ const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
+ const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
+ const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
+ const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
+ const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
+ const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
+ const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.VariantItem(item);
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 77);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "abc");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "DEF");
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1267);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestGuessInMap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
+
+ const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
+ const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
+ const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
+ const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
+ const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
+ const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
+ const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
+
+ const auto pgmReturn = pb.Map(list,
+ [&](TRuntimeNode item) {
+ return pb.NewTuple({pb.Guess(item, 0), pb.Guess(item, 2)});
+ });
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 77);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), false);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), true);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1267);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
}
}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chain_map_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chain_map_ut.cpp
index 31a3496aac..e5ac540ca0 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chain_map_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chain_map_ut.cpp
@@ -1,316 +1,316 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 23u
-Y_UNIT_TEST_SUITE(TMiniKQLWideChain1MapTest) {
- Y_UNIT_TEST_LLVM(TestThinLambda) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [&](TRuntimeNode::TList inputs) { return inputs; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList outputs) { return outputs; }),
- [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSimpleSwap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) { return inputs; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList { return {inputs.back(), outputs[1U], inputs.front()}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSimpleChain) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-6))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-7))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-8))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-9))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {pb.Add(inputs.front(), inputs[1U]), pb.NewEmptyOptional(dataType), pb.Sub(inputs.back(), inputs[1U])}; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
- return {pb.AggrAdd(outputs.back(), inputs[1U]), outputs.front(), pb.Decrement(outputs[1])};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -5);
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -6);
- UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
- UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestAgrregateWithPrevious) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(5)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], inputs[2U], inputs[0U]}; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
- return {pb.AggrMin(inputs[0U], outputs[1U]), pb.AggrMax(inputs[1U], outputs[2U]), pb.AggrAdd(outputs[0U], inputs[2U])};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestPasstroughtFieldSplitAsIs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-6)), pb.NewOptional(pb.NewDataLiteral<i32>(-5))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(0))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], pb.Mul(inputs.front(), inputs.back()), inputs[1U]}; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
- return {inputs[1U], pb.Mul(outputs[1U], pb.Add(inputs.back(), inputs.front())), inputs[1U]};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -6);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -6);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 10);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 0);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFieldBothWayPasstroughtAndArg) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-6))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-7))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-8))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-9))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], pb.Sub(inputs.front(), inputs.back()), pb.Minus(inputs[1U])}; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
- return {inputs[1U], pb.Sub(outputs[1U], pb.Add(inputs.back(), inputs.front())), pb.Minus(inputs[1U])};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 5);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 12);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 17);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 22);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
- const auto null = pb.NewEmptyOptional(dataType);
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("Veszély! Aknák!");
-
- const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs.back(), pb.Unwrap(inputs[1U], landmine, __FILE__, __LINE__, 0), inputs.front()}; },
- [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
- return {pb.Mul(outputs.front(), inputs.back()), pb.Unwrap(inputs[1U], landmine, __FILE__, __LINE__, 0), pb.Add(inputs.front(), outputs.back())};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 6);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -6);
- UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 10);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 24);
- UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
- UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
- }
-}
-#endif
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 23u
+Y_UNIT_TEST_SUITE(TMiniKQLWideChain1MapTest) {
+ Y_UNIT_TEST_LLVM(TestThinLambda) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [&](TRuntimeNode::TList inputs) { return inputs; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList outputs) { return outputs; }),
+ [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSimpleSwap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) { return inputs; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList { return {inputs.back(), outputs[1U], inputs.front()}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSimpleChain) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-6))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-7))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-8))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-9))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {pb.Add(inputs.front(), inputs[1U]), pb.NewEmptyOptional(dataType), pb.Sub(inputs.back(), inputs[1U])}; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
+ return {pb.AggrAdd(outputs.back(), inputs[1U]), outputs.front(), pb.Decrement(outputs[1])};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -5);
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -6);
+ UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
+ UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestAgrregateWithPrevious) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(5)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], inputs[2U], inputs[0U]}; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
+ return {pb.AggrMin(inputs[0U], outputs[1U]), pb.AggrMax(inputs[1U], outputs[2U]), pb.AggrAdd(outputs[0U], inputs[2U])};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestPasstroughtFieldSplitAsIs) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-6)), pb.NewOptional(pb.NewDataLiteral<i32>(-5))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(0))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], pb.Mul(inputs.front(), inputs.back()), inputs[1U]}; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
+ return {inputs[1U], pb.Mul(outputs[1U], pb.Add(inputs.back(), inputs.front())), inputs[1U]};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -6);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -6);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 0);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFieldBothWayPasstroughtAndArg) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-6))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-7))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-8))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-9))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs[1U], pb.Sub(inputs.front(), inputs.back()), pb.Minus(inputs[1U])}; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
+ return {inputs[1U], pb.Sub(outputs[1U], pb.Add(inputs.back(), inputs.front())), pb.Minus(inputs[1U])};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 5);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 12);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 17);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 22);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+ const auto null = pb.NewEmptyOptional(dataType);
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), null, pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("Veszély! Aknák!");
+
+ const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.WideChain1Map(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList inputs) -> TRuntimeNode::TList { return {inputs.back(), pb.Unwrap(inputs[1U], landmine, __FILE__, __LINE__, 0), inputs.front()}; },
+ [&](TRuntimeNode::TList inputs, TRuntimeNode::TList outputs) -> TRuntimeNode::TList {
+ return {pb.Mul(outputs.front(), inputs.back()), pb.Unwrap(inputs[1U], landmine, __FILE__, __LINE__, 0), pb.Add(inputs.front(), outputs.back())};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 6);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -6);
+ UNIT_ASSERT(NUdf::EFetchStatus::Ok == iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 10);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 24);
+ UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
+ UNIT_ASSERT(NUdf::EFetchStatus::Finish == iterator.Fetch(item));
+ }
+}
+#endif
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
index 558b2c701e..b2865328e8 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
@@ -1,474 +1,474 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideChopperTest) {
- Y_UNIT_TEST_LLVM(TestConcatKeyToItems) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {pb.Substring(items.front(), pb.Sub(pb.Size(items.front()), pb.NewDataLiteral<ui32>(4U)), pb.NewDataLiteral<ui32>(4U))};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- return pb.AggrNotEquals(keys.front(), items.front());
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode input) {
- return pb.WideMap(input, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {pb.AggrConcat(items.back(), keys.front())};
- });
- }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 5 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 6 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 7 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 two");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCollectKeysOnly) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.front()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- return pb.AggrNotEquals(keys.front(), items.front());
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode) {
- return pb.ExpandMap(pb.ToFlow(pb.NewOptional(keys.front())), [&](TRuntimeNode item) -> TRuntimeNode::TList {
- return {item};
- } );
- }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key two");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestGetPart) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
- const auto data5 = pb.NewTuple(tupleType, {longKeyOne, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyOne, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyOne, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyOne, value8});
-
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.front()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- return pb.AggrNotEquals(keys.front(), items.front());
- },
- [&](TRuntimeNode::TList, TRuntimeNode input) {
- return pb.Take(pb.Skip(input, pb.NewDataLiteral<ui64>(1ULL)), pb.NewDataLiteral<ui64>(3ULL));
- }),
- [&](TRuntimeNode::TList items) { return items.back(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 3");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 5");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 6");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 7");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSwitchByBoolFieldAndDontUseKey) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
- const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
-
- const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
-
- const auto trueVal = pb.NewDataLiteral<bool>(true);
- const auto falseVal = pb.NewDataLiteral<bool>(false);
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {key0, value1, trueVal});
- const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
- const auto data3 = pb.NewTuple(tupleType, {key2, value3, falseVal});
- const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
- const auto data5 = pb.NewTuple(tupleType, {key1, value5, falseVal});
- const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
- const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
- const auto data8 = pb.NewTuple(tupleType, {key1, value8, falseVal});
- const auto data9 = pb.NewTuple(tupleType, {key2, value9, trueVal});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {pb.Unwrap(items.front(), landmine, __FILE__, __LINE__, 0)};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) {
- return items.back();
- },
- [&](TRuntimeNode::TList, TRuntimeNode input) {
- return pb.Take(input, pb.NewDataLiteral<ui64>(2ULL));
- }),
- [&](TRuntimeNode::TList items) { return items[1U]; }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 1");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 2");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 5");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 9");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCollectKeysIfPresent) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
- const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
-
- const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
-
- const auto trueVal = pb.NewDataLiteral<bool>(true);
- const auto falseVal = pb.NewDataLiteral<bool>(false);
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
- const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
- const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
- const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
- const auto data5 = pb.NewTuple(tupleType, {key0, value5, falseVal});
- const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
- const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
- const auto data8 = pb.NewTuple(tupleType, {key0, value8, falseVal});
- const auto data9 = pb.NewTuple(tupleType, {key0, value9, trueVal});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.front()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- return pb.AggrNotEquals(keys.front(), items.front());
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode part) {
- return pb.IfPresent(keys,
- [&](TRuntimeNode::TList keys) { return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, keys)), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ); },
- pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
- }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 5");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 7");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 8");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 9");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestConditionalByKeyPart) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
- const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
-
- const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
-
- const auto trueVal = pb.NewDataLiteral<bool>(true);
- const auto falseVal = pb.NewDataLiteral<bool>(false);
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
- const auto data2 = pb.NewTuple(tupleType, {key1, value2, trueVal});
- const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
- const auto data4 = pb.NewTuple(tupleType, {key1, value4, falseVal});
- const auto data5 = pb.NewTuple(tupleType, {key2, value5, falseVal});
- const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
- const auto data7 = pb.NewTuple(tupleType, {key2, value7, trueVal});
- const auto data8 = pb.NewTuple(tupleType, {key0, value8, trueVal});
- const auto data9 = pb.NewTuple(tupleType, {key0, value9, falseVal});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.front(), items.back()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- return pb.Or({pb.AggrNotEquals(keys.front(), items.front()), pb.AggrNotEquals(keys.back(), items.back())});
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode part) {
- return pb.If(keys.back(),
- pb.ExpandMap(pb.ToFlow(keys.front()), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ),
- pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
- }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 3");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 5");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 6");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 9");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto tupleType = pb.NewTupleType({});
-
-
- const auto data = pb.NewTuple({});
-
- const auto list = pb.NewList(tupleType, {data, data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
- [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [](TRuntimeNode::TList items) { return items; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList) { return pb.NewDataLiteral<bool>(true); },
- [&](TRuntimeNode::TList, TRuntimeNode input) { return pb.WideMap(input, [](TRuntimeNode::TList items) { return items; }); }),
- [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#endif
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideChopperTest) {
+ Y_UNIT_TEST_LLVM(TestConcatKeyToItems) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {pb.Substring(items.front(), pb.Sub(pb.Size(items.front()), pb.NewDataLiteral<ui32>(4U)), pb.NewDataLiteral<ui32>(4U))};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ return pb.AggrNotEquals(keys.front(), items.front());
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode input) {
+ return pb.WideMap(input, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {pb.AggrConcat(items.back(), keys.front())};
+ });
+ }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 5 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 6 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 7 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 two");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCollectKeysOnly) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.front()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ return pb.AggrNotEquals(keys.front(), items.front());
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode) {
+ return pb.ExpandMap(pb.ToFlow(pb.NewOptional(keys.front())), [&](TRuntimeNode item) -> TRuntimeNode::TList {
+ return {item};
+ } );
+ }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key two");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestGetPart) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+ const auto data5 = pb.NewTuple(tupleType, {longKeyOne, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyOne, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyOne, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyOne, value8});
+
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.front()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ return pb.AggrNotEquals(keys.front(), items.front());
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode input) {
+ return pb.Take(pb.Skip(input, pb.NewDataLiteral<ui64>(1ULL)), pb.NewDataLiteral<ui64>(3ULL));
+ }),
+ [&](TRuntimeNode::TList items) { return items.back(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 3");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 5");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 6");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 7");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSwitchByBoolFieldAndDontUseKey) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
+
+ const auto trueVal = pb.NewDataLiteral<bool>(true);
+ const auto falseVal = pb.NewDataLiteral<bool>(false);
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {key0, value1, trueVal});
+ const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
+ const auto data3 = pb.NewTuple(tupleType, {key2, value3, falseVal});
+ const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
+ const auto data5 = pb.NewTuple(tupleType, {key1, value5, falseVal});
+ const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
+ const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
+ const auto data8 = pb.NewTuple(tupleType, {key1, value8, falseVal});
+ const auto data9 = pb.NewTuple(tupleType, {key2, value9, trueVal});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {pb.Unwrap(items.front(), landmine, __FILE__, __LINE__, 0)};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) {
+ return items.back();
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode input) {
+ return pb.Take(input, pb.NewDataLiteral<ui64>(2ULL));
+ }),
+ [&](TRuntimeNode::TList items) { return items[1U]; }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 1");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 2");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 5");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 9");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCollectKeysIfPresent) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
+
+ const auto trueVal = pb.NewDataLiteral<bool>(true);
+ const auto falseVal = pb.NewDataLiteral<bool>(false);
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
+ const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
+ const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
+ const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
+ const auto data5 = pb.NewTuple(tupleType, {key0, value5, falseVal});
+ const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
+ const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
+ const auto data8 = pb.NewTuple(tupleType, {key0, value8, falseVal});
+ const auto data9 = pb.NewTuple(tupleType, {key0, value9, trueVal});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.front()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ return pb.AggrNotEquals(keys.front(), items.front());
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode part) {
+ return pb.IfPresent(keys,
+ [&](TRuntimeNode::TList keys) { return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, keys)), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ); },
+ pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
+ }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 5");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 7");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 8");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 9");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestConditionalByKeyPart) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
+
+ const auto trueVal = pb.NewDataLiteral<bool>(true);
+ const auto falseVal = pb.NewDataLiteral<bool>(false);
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
+ const auto data2 = pb.NewTuple(tupleType, {key1, value2, trueVal});
+ const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
+ const auto data4 = pb.NewTuple(tupleType, {key1, value4, falseVal});
+ const auto data5 = pb.NewTuple(tupleType, {key2, value5, falseVal});
+ const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
+ const auto data7 = pb.NewTuple(tupleType, {key2, value7, trueVal});
+ const auto data8 = pb.NewTuple(tupleType, {key0, value8, trueVal});
+ const auto data9 = pb.NewTuple(tupleType, {key0, value9, falseVal});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.front(), items.back()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ return pb.Or({pb.AggrNotEquals(keys.front(), items.front()), pb.AggrNotEquals(keys.back(), items.back())});
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode part) {
+ return pb.If(keys.back(),
+ pb.ExpandMap(pb.ToFlow(keys.front()), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ),
+ pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
+ }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 3");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 5");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 6");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 9");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto tupleType = pb.NewTupleType({});
+
+
+ const auto data = pb.NewTuple({});
+
+ const auto list = pb.NewList(tupleType, {data, data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
+ [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [](TRuntimeNode::TList items) { return items; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList) { return pb.NewDataLiteral<bool>(true); },
+ [&](TRuntimeNode::TList, TRuntimeNode input) { return pb.WideMap(input, [](TRuntimeNode::TList items) { return items; }); }),
+ [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#endif
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
index f499f68e42..1f566e6412 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
@@ -1,1699 +1,1699 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
-
-#include <cstring>
-#include <random>
-#include <algorithm>
-
-namespace NKikimr {
-namespace NMiniKQL {
-namespace {
-const auto border = 9124596000000000ULL;
-}
-
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerTest) {
- Y_UNIT_TEST_LLVM(TestLongStringsRefCounting) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {pb.NewOptional(items.back()), pb.NewOptional(keys.front()), pb.NewEmptyOptional(optionalType), pb.NewEmptyOptional(optionalType)};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.NewOptional(items.back()), state.front(), state[1U], state[2U]};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- state.erase(state.cbegin());
- return {pb.FlatMap(pb.NewList(optionalType, state), [&](TRuntimeNode item) { return item; } )};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(items.front(),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 / very long value 7 / very long value 6");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 / key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestLongStringsPasstroughtRefCounting) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), items.back(), items.front()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), state[2U], state.back()};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return state;
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(pb.NewList(dataType, items),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 / very long key two / very long value 5 / very long key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 / key two / very long value 2 / key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 / very long key one / very long value 4 / very long key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 / key one / very long value 1 / key one");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedInput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
-
- const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
-
- const auto none = pb.NewEmptyOptional(optionalType);
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
- const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
- const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
- const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Unwrap(pb.Nth(item, 1U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 2U)}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), empty, empty};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {items.back(), state.front(), state[1U], state[2U]};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- state.insert(state.cbegin(), keys.cbegin(), keys.cend());
- return {pb.NewList(dataType, state)};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(items.front(),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two / value 4 / value 3 / value 3 / value 2");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one / value 2 / value 1 / value 5 / value 4");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedOutput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
-
- const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
-
- const auto none = pb.NewEmptyOptional(optionalType);
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
- const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
- const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
- const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items[1U], items.back()};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.Concat(state.front(), items[1U]), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.Unwrap(state.front(), landmine, __FILE__, __LINE__, 0), pb.AggrConcat(pb.AggrConcat(keys.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), state.back())};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two: value 2, value 3, value 3, value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one: value 1, value 4, value 5, value 1, value 2");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto tupleType = pb.NewTupleType({});
- const auto data = pb.NewTuple({});
-
- const auto list = pb.NewList(tupleType, {data, data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
- [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }), 0ULL,
- [](TRuntimeNode::TList items) { return items; },
- [](TRuntimeNode::TList, TRuntimeNode::TList items) { return items; },
- [](TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList state) { return state; },
- [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state; }),
- [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-
-Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerPerfTest) {
- Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
- TSetup<LLVM> setup;
-
- double positive = 0.0, negative = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- (sample.second > 0.0 ? positive : negative) += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return items; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.front())}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto first = value.GetElement(0);
- const auto second = value.GetElement(1);
- const auto t2 = TInstant::Now();
-
- if (first.template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
- TSetup<LLVM> setup;
-
- double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- if (sample.second > 0.0) {
- pSum += sample.second;
- pMax = std::max(pMax, sample.second);
- pMin = std::min(pMin, sample.second);
- } else {
- nSum += sample.second;
- nMax = std::max(nMax, sample.second);
- nMin = std::min(nMin, sample.second);
- }
- }
-
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items.front(), items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.AggrAdd(state.front(), items.front()), pb.AggrMin(state[1U], items.front()), pb.AggrMax(state.back(), items.back()) };
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto first = value.GetElement(0);
- const auto second = value.GetElement(1);
- const auto t2 = TInstant::Now();
-
- if (first.GetElement(0).template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
- TSetup<LLVM> setup;
-
- std::unordered_map<i8, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
- TSetup<LLVM> setup;
-
- std::unordered_map<i8, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::pair<ui32, std::string>, double>> pairSamples(Ui16Samples.size());
- std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairSamples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
-
- struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (const auto sample : pairSamples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(pb.Nth(item, 0U), 0U), pb.Nth(pb.Nth(item, 0U), 1U), pb.Nth(item, 1U) }; }), 0ULL,
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items[1U]}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back()) };
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), keys.back(), state.front(), state[1U], state.back()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple({pb.NewTuple({items[0U], items[1U]}), items[2U], items[3U], items[4U]}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairSamples.size(), items));
- for (const auto sample : pairSamples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- NUdf::TUnboxedValue* keys = nullptr;
- pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
- keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
- keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestTpch) {
- TSetup<LLVM> setup;
-
- struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (auto& sample : TpchSamples) {
- if (std::get<0U>(sample) <= border) {
- const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
- auto& item = ins.first->second;
- ++item.first;
- std::get<0U>(item.second) += std::get<3U>(sample);
- std::get<1U>(item.second) += std::get<5U>(sample);
- std::get<2U>(item.second) += std::get<6U>(sample);
- const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
- std::get<3U>(item.second) += v;
- std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
- }
- }
- for (auto& item : expects) {
- std::get<1U>(item.second.second) /= item.second.first;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui64>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id)
- }));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(
- pb.WideFilter(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U), pb.Nth(item, 4U), pb.Nth(item, 5U), pb.Nth(item, 6U)}; }),
- [&](TRuntimeNode::TList items) { return pb.AggrLessOrEqual(items.front(), pb.NewDataLiteral<ui64>(border)); }
- ), 0ULL,
- [&](TRuntimeNode::TList item) -> TRuntimeNode::TList { return {item[1U], item[2U]}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- const auto price = items[3U];
- const auto disco = items[5U];
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return {pb.NewDataLiteral<ui64>(1ULL), price, disco, items[6U], v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U]))};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- const auto price = items[3U];
- const auto disco = items[5U];
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return {pb.Increment(state[0U]), pb.AggrAdd(state[1U], price), pb.AggrAdd(state[2U], disco), pb.AggrAdd(state[3U], items[6U]), pb.AggrAdd(state[4U], v), pb.AggrAdd(state[5U], pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U])))};
- },
- [&](TRuntimeNode::TList key, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {key.front(), key.back(), state[0U], state[1U], pb.Div(state[2U], state[0U]), state[3U], state[4U], state[5U]}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
- for (const auto sample : TpchSamples) {
- NUdf::TUnboxedValue* elements = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
- elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
- elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
- elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
- elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
- elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
- elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
- elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-}
-#endif
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 29u
-Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
- Y_UNIT_TEST_LLVM(TestLongStringsRefCounting) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {pb.NewOptional(items.back()), pb.NewOptional(keys.front()), pb.NewEmptyOptional(optionalType), pb.NewEmptyOptional(optionalType)};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.NewOptional(items.back()), state.front(), state[1U], state[2U]};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- state.erase(state.cbegin());
- return {pb.FlatMap(pb.NewList(optionalType, state), [&](TRuntimeNode item) { return item; } )};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(items.front(),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 / very long value 7 / very long value 6");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 / key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestLongStringsPasstroughtRefCounting) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), items.back(), items.front()};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), state[2U], state.back()};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return state;
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(pb.NewList(dataType, items),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 / very long key two / very long value 5 / very long key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 / key two / very long value 2 / key two");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 / very long key one / very long value 4 / very long key one");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 / key one / very long value 1 / key one");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedInput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
-
- const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
-
- const auto none = pb.NewEmptyOptional(optionalType);
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
- const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
- const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
- const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Unwrap(pb.Nth(item, 1U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.back(), keys.front(), empty, empty};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {items.back(), state.front(), state[1U], state[2U]};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- state.insert(state.cbegin(), keys.cbegin(), keys.cend());
- return {pb.NewList(dataType, state)};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- return pb.Fold1(items.front(),
- [&](TRuntimeNode item) { return item; },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
- }
- );
- }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two / value 4 / value 3 / value 3 / value 2");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one / value 2 / value 1 / value 5 / value 4");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedOutput) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto optionalType = pb.NewOptionalType(dataType);
- const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
-
- const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
-
- const auto none = pb.NewEmptyOptional(optionalType);
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
- const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
- const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
- const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
- const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
- const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items[1U], items.back()};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.Concat(state.front(), items[1U]), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.Unwrap(state.front(), landmine, __FILE__, __LINE__, 0), pb.AggrConcat(pb.AggrConcat(keys.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), state.back())};
- }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two: value 2, value 3, value 3, value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one: value 1, value 4, value 5, value 1, value 2");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto tupleType = pb.NewTupleType({});
- const auto data = pb.NewTuple({});
-
- const auto list = pb.NewList(tupleType, {data, data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
- [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [](TRuntimeNode::TList items) { return items; },
- [](TRuntimeNode::TList, TRuntimeNode::TList items) { return items; },
- [](TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList state) { return state; },
- [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state; }),
- [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-
-Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerPerfTest) {
- Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
- TSetup<LLVM> setup;
-
- double positive = 0.0, negative = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- (sample.second > 0.0 ? positive : negative) += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return items; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.front())}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto first = value.GetElement(0);
- const auto second = value.GetElement(1);
- const auto t2 = TInstant::Now();
-
- if (first.template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
- UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
- TSetup<LLVM> setup;
-
- double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- if (sample.second > 0.0) {
- pSum += sample.second;
- pMax = std::max(pMax, sample.second);
- pMin = std::min(pMin, sample.second);
- } else {
- nSum += sample.second;
- nMax = std::max(nMax, sample.second);
- nMin = std::min(nMin, sample.second);
- }
- }
-
- const auto cppTime = TInstant::Now() - t;
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items.front(), items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.AggrAdd(state.front(), items.front()), pb.AggrMin(state[1U], items.front()), pb.AggrMax(state.back(), items.back()) };
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto first = value.GetElement(0);
- const auto second = value.GetElement(1);
- const auto t2 = TInstant::Now();
-
- if (first.GetElement(0).template Get<double>() > 0.0) {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
- } else {
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
- UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
-
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
- UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
- }
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
- TSetup<LLVM> setup;
-
- std::unordered_map<i8, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
- TSetup<LLVM> setup;
-
- std::unordered_map<i8, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : I8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
- for (const auto sample : I8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, double> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- expects.emplace(sample.first, 0.0).first->second += sample.second;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, double>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
- std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
-
- std::unordered_map<std::string, std::array<double, 3U>> expects(201);
- const auto t = TInstant::Now();
- for (const auto sample : stringI8Samples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
- for (const auto sample : stringI8Samples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
- TSetup<LLVM> setup;
-
- std::vector<std::pair<std::pair<ui32, std::string>, double>> pairSamples(Ui16Samples.size());
- std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairSamples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
-
- struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (const auto sample : pairSamples) {
- auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
- std::get<0U>(item) += sample.second;
- std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
- std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(pb.Nth(item, 0U), 0U), pb.Nth(pb.Nth(item, 0U), 1U), pb.Nth(item, 1U) }; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items[1U]}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back()) };
- },
- [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), keys.back(), state.front(), state[1U], state.back()}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple({pb.NewTuple({items[0U], items[1U]}), items[2U], items[3U], items[4U]}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairSamples.size(), items));
- for (const auto sample : pairSamples) {
- NUdf::TUnboxedValue* pair = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
- pair[1] = NUdf::TUnboxedValuePod(sample.second);
- NUdf::TUnboxedValue* keys = nullptr;
- pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
- keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
- keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-
- Y_UNIT_TEST_LLVM(TestTpch) {
- TSetup<LLVM> setup;
-
- struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
-
- std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
- const auto t = TInstant::Now();
- for (auto& sample : TpchSamples) {
- if (std::get<0U>(sample) <= border) {
- const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
- auto& item = ins.first->second;
- ++item.first;
- std::get<0U>(item.second) += std::get<3U>(sample);
- std::get<1U>(item.second) += std::get<5U>(sample);
- std::get<2U>(item.second) += std::get<6U>(sample);
- const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
- std::get<3U>(item.second) += v;
- std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
- }
- }
- for (auto& item : expects) {
- std::get<1U>(item.second.second) /= item.second.first;
- }
- const auto cppTime = TInstant::Now() - t;
-
- std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
- one.reserve(expects.size());
- two.reserve(expects.size());
-
- one.insert(one.cend(), expects.cbegin(), expects.cend());
- std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
-
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto listType = pb.NewListType(pb.NewTupleType({
- pb.NewDataType(NUdf::TDataType<ui64>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<const char*>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id),
- pb.NewDataType(NUdf::TDataType<double>::Id)
- }));
- const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(
- pb.WideFilter(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U), pb.Nth(item, 4U), pb.Nth(item, 5U), pb.Nth(item, 6U)}; }),
- [&](TRuntimeNode::TList items) { return pb.AggrLessOrEqual(items.front(), pb.NewDataLiteral<ui64>(border)); }
- ),
- [&](TRuntimeNode::TList item) -> TRuntimeNode::TList { return {item[1U], item[2U]}; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
- const auto price = items[3U];
- const auto disco = items[5U];
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return {pb.NewDataLiteral<ui64>(1ULL), price, disco, items[6U], v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U]))};
- },
- [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- const auto price = items[3U];
- const auto disco = items[5U];
- const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
- return {pb.Increment(state[0U]), pb.AggrAdd(state[1U], price), pb.AggrAdd(state[2U], disco), pb.AggrAdd(state[3U], items[6U]), pb.AggrAdd(state[4U], v), pb.AggrAdd(state[5U], pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U])))};
- },
- [&](TRuntimeNode::TList key, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {key.front(), key.back(), state[0U], state[1U], pb.Div(state[2U], state[0U]), state[3U], state[4U], state[5U]}; }),
- [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn, {list});
- NUdf::TUnboxedValue* items = nullptr;
- graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
- for (const auto sample : TpchSamples) {
- NUdf::TUnboxedValue* elements = nullptr;
- *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
- elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
- elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
- elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
- elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
- elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
- elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
- elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
- }
-
- const auto t1 = TInstant::Now();
- const auto& value = graph->GetValue();
- const auto t2 = TInstant::Now();
-
- UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
-
- const auto ptr = value.GetElements();
- for (size_t i = 0ULL; i < expects.size(); ++i) {
- const auto elements = ptr[i].GetElements();
- two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
- }
-
- std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
- UNIT_ASSERT_VALUES_EQUAL(one, two);
-
- Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
- }
-}
-#endif
-}
-}
+
+#include <cstring>
+#include <random>
+#include <algorithm>
+
+namespace NKikimr {
+namespace NMiniKQL {
+namespace {
+const auto border = 9124596000000000ULL;
+}
+
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerTest) {
+ Y_UNIT_TEST_LLVM(TestLongStringsRefCounting) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {pb.NewOptional(items.back()), pb.NewOptional(keys.front()), pb.NewEmptyOptional(optionalType), pb.NewEmptyOptional(optionalType)};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.NewOptional(items.back()), state.front(), state[1U], state[2U]};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ state.erase(state.cbegin());
+ return {pb.FlatMap(pb.NewList(optionalType, state), [&](TRuntimeNode item) { return item; } )};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(items.front(),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 / very long value 7 / very long value 6");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 / key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestLongStringsPasstroughtRefCounting) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), items.back(), items.front()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), state[2U], state.back()};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return state;
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(pb.NewList(dataType, items),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 / very long key two / very long value 5 / very long key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 / key two / very long value 2 / key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 / very long key one / very long value 4 / very long key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 / key one / very long value 1 / key one");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedInput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+
+ const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+
+ const auto none = pb.NewEmptyOptional(optionalType);
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
+ const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
+ const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
+ const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Unwrap(pb.Nth(item, 1U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 2U)}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), empty, empty};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {items.back(), state.front(), state[1U], state[2U]};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ state.insert(state.cbegin(), keys.cbegin(), keys.cend());
+ return {pb.NewList(dataType, state)};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(items.front(),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two / value 4 / value 3 / value 3 / value 2");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one / value 2 / value 1 / value 5 / value 4");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedOutput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+
+ const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+
+ const auto none = pb.NewEmptyOptional(optionalType);
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
+ const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
+ const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
+ const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items[1U], items.back()};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.Concat(state.front(), items[1U]), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.Unwrap(state.front(), landmine, __FILE__, __LINE__, 0), pb.AggrConcat(pb.AggrConcat(keys.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), state.back())};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two: value 2, value 3, value 3, value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one: value 1, value 4, value 5, value 1, value 2");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto tupleType = pb.NewTupleType({});
+ const auto data = pb.NewTuple({});
+
+ const auto list = pb.NewList(tupleType, {data, data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }), 0ULL,
+ [](TRuntimeNode::TList items) { return items; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList items) { return items; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList state) { return state; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state; }),
+ [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+
+Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerPerfTest) {
+ Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
+ TSetup<LLVM> setup;
+
+ double positive = 0.0, negative = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ (sample.second > 0.0 ? positive : negative) += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return items; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.front())}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto first = value.GetElement(0);
+ const auto second = value.GetElement(1);
+ const auto t2 = TInstant::Now();
+
+ if (first.template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
+ TSetup<LLVM> setup;
+
+ double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ if (sample.second > 0.0) {
+ pSum += sample.second;
+ pMax = std::max(pMax, sample.second);
+ pMin = std::min(pMin, sample.second);
+ } else {
+ nSum += sample.second;
+ nMax = std::max(nMax, sample.second);
+ nMin = std::min(nMin, sample.second);
+ }
+ }
+
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items.front(), items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.AggrAdd(state.front(), items.front()), pb.AggrMin(state[1U], items.front()), pb.AggrMax(state.back(), items.back()) };
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto first = value.GetElement(0);
+ const auto second = value.GetElement(1);
+ const auto t2 = TInstant::Now();
+
+ if (first.GetElement(0).template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
+ TSetup<LLVM> setup;
+
+ std::unordered_map<i8, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
+ TSetup<LLVM> setup;
+
+ std::unordered_map<i8, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, double>> pairSamples(Ui16Samples.size());
+ std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairSamples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
+
+ struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (const auto sample : pairSamples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(pb.Nth(item, 0U), 0U), pb.Nth(pb.Nth(item, 0U), 1U), pb.Nth(item, 1U) }; }), 0ULL,
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items[1U]}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back()) };
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), keys.back(), state.front(), state[1U], state.back()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple({pb.NewTuple({items[0U], items[1U]}), items[2U], items[3U], items[4U]}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairSamples.size(), items));
+ for (const auto sample : pairSamples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ NUdf::TUnboxedValue* keys = nullptr;
+ pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
+ keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
+ keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestTpch) {
+ TSetup<LLVM> setup;
+
+ struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (auto& sample : TpchSamples) {
+ if (std::get<0U>(sample) <= border) {
+ const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
+ auto& item = ins.first->second;
+ ++item.first;
+ std::get<0U>(item.second) += std::get<3U>(sample);
+ std::get<1U>(item.second) += std::get<5U>(sample);
+ std::get<2U>(item.second) += std::get<6U>(sample);
+ const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
+ std::get<3U>(item.second) += v;
+ std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
+ }
+ }
+ for (auto& item : expects) {
+ std::get<1U>(item.second.second) /= item.second.first;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui64>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id)
+ }));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCombiner(
+ pb.WideFilter(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U), pb.Nth(item, 4U), pb.Nth(item, 5U), pb.Nth(item, 6U)}; }),
+ [&](TRuntimeNode::TList items) { return pb.AggrLessOrEqual(items.front(), pb.NewDataLiteral<ui64>(border)); }
+ ), 0ULL,
+ [&](TRuntimeNode::TList item) -> TRuntimeNode::TList { return {item[1U], item[2U]}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ const auto price = items[3U];
+ const auto disco = items[5U];
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return {pb.NewDataLiteral<ui64>(1ULL), price, disco, items[6U], v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U]))};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ const auto price = items[3U];
+ const auto disco = items[5U];
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return {pb.Increment(state[0U]), pb.AggrAdd(state[1U], price), pb.AggrAdd(state[2U], disco), pb.AggrAdd(state[3U], items[6U]), pb.AggrAdd(state[4U], v), pb.AggrAdd(state[5U], pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U])))};
+ },
+ [&](TRuntimeNode::TList key, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {key.front(), key.back(), state[0U], state[1U], pb.Div(state[2U], state[0U]), state[3U], state[4U], state[5U]}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
+ for (const auto sample : TpchSamples) {
+ NUdf::TUnboxedValue* elements = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
+ elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
+ elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
+ elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
+ elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
+ elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
+ elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
+ elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+}
+#endif
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 29u
+Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
+ Y_UNIT_TEST_LLVM(TestLongStringsRefCounting) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {pb.NewOptional(items.back()), pb.NewOptional(keys.front()), pb.NewEmptyOptional(optionalType), pb.NewEmptyOptional(optionalType)};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.NewOptional(items.back()), state.front(), state[1U], state[2U]};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ state.erase(state.cbegin());
+ return {pb.FlatMap(pb.NewList(optionalType, state), [&](TRuntimeNode item) { return item; } )};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(items.front(),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 / very long value 7 / very long value 6");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 / key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestLongStringsPasstroughtRefCounting) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), items.back(), items.front()};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), state[2U], state.back()};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return state;
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(pb.NewList(dataType, items),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 / very long key two / very long value 5 / very long key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 / key two / very long value 2 / key two");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 / very long key one / very long value 4 / very long key one");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 / key one / very long value 1 / key one");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedInput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+
+ const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+
+ const auto none = pb.NewEmptyOptional(optionalType);
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
+ const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
+ const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
+ const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Unwrap(pb.Nth(item, 1U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.back(), keys.front(), empty, empty};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {items.back(), state.front(), state[1U], state[2U]};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ state.insert(state.cbegin(), keys.cbegin(), keys.cend());
+ return {pb.NewList(dataType, state)};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ return pb.Fold1(items.front(),
+ [&](TRuntimeNode item) { return item; },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return pb.AggrConcat(pb.AggrConcat(state, pb.NewDataLiteral<NUdf::EDataSlot::String>(" / ")), item);
+ }
+ );
+ }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two / value 4 / value 3 / value 3 / value 2");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one / value 2 / value 1 / value 5 / value 4");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoNotCalculateUnusedOutput) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto optionalType = pb.NewOptionalType(dataType);
+ const auto tupleType = pb.NewTupleType({dataType, optionalType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+
+ const auto empty = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
+
+ const auto none = pb.NewEmptyOptional(optionalType);
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, none, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data4 = pb.NewTuple(tupleType, {keyOne, none, value4});
+ const auto data5 = pb.NewTuple(tupleType, {keyOne, none, value5});
+ const auto data6 = pb.NewTuple(tupleType, {keyOne, none, value1});
+ const auto data7 = pb.NewTuple(tupleType, {keyOne, none, value2});
+ const auto data8 = pb.NewTuple(tupleType, {keyTwo, none, value3});
+ const auto data9 = pb.NewTuple(tupleType, {keyTwo, none, value4});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items[1U], items.back()};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.Concat(state.front(), items[1U]), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.Unwrap(state.front(), landmine, __FILE__, __LINE__, 0), pb.AggrConcat(pb.AggrConcat(keys.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), state.back())};
+ }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two: value 2, value 3, value 3, value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one: value 1, value 4, value 5, value 1, value 2");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto tupleType = pb.NewTupleType({});
+ const auto data = pb.NewTuple({});
+
+ const auto list = pb.NewList(tupleType, {data, data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(list),
+ [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [](TRuntimeNode::TList items) { return items; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList items) { return items; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList state) { return state; },
+ [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state; }),
+ [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+
+Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerPerfTest) {
+ Y_UNIT_TEST_LLVM(TestSumDoubleBooleanKeys) {
+ TSetup<LLVM> setup;
+
+ double positive = 0.0, negative = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ (sample.second > 0.0 ? positive : negative) += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return items; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.front())}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto first = value.GetElement(0);
+ const auto second = value.GetElement(1);
+ const auto t2 = TInstant::Now();
+
+ if (first.template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), positive);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), negative);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.template Get<double>(), negative);
+ UNIT_ASSERT_VALUES_EQUAL(second.template Get<double>(), positive);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleBooleanKeys) {
+ TSetup<LLVM> setup;
+
+ double pSum = 0.0, nSum = 0.0, pMax = 0.0, nMax = -1000.0, pMin = 1000.0, nMin = 0.0;
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ if (sample.second > 0.0) {
+ pSum += sample.second;
+ pMax = std::max(pMax, sample.second);
+ pMin = std::min(pMin, sample.second);
+ } else {
+ nSum += sample.second;
+ nMax = std::max(nMax, sample.second);
+ nMin = std::min(nMin, sample.second);
+ }
+ }
+
+ const auto cppTime = TInstant::Now() - t;
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewDataType(NUdf::TDataType<double>::Id));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrGreater(items.front(), pb.NewDataLiteral(0.0))}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items.front(), items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.AggrAdd(state.front(), items.front()), pb.AggrMin(state[1U], items.front()), pb.AggrMax(state.back(), items.back()) };
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList state) -> TRuntimeNode::TList { return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), items, [](const std::pair<i8, double> s){ return ToValue<double>(s.second); });
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto first = value.GetElement(0);
+ const auto second = value.GetElement(1);
+ const auto t2 = TInstant::Now();
+
+ if (first.GetElement(0).template Get<double>() > 0.0) {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), pMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), nMax);
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(0).template Get<double>(), nSum);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(1).template Get<double>(), nMin);
+ UNIT_ASSERT_VALUES_EQUAL(first.GetElement(2).template Get<double>(), nMax);
+
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(0).template Get<double>(), pSum);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(1).template Get<double>(), pMin);
+ UNIT_ASSERT_VALUES_EQUAL(second.GetElement(2).template Get<double>(), pMax);
+ }
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleSmallKey) {
+ TSetup<LLVM> setup;
+
+ std::unordered_map<i8, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, double> l, const std::pair<i8, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleSmallKey) {
+ TSetup<LLVM> setup;
+
+ std::unordered_map<i8, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : I8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, std::numeric_limits<double>::max(), std::numeric_limits<double>::min()}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<i8, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i8>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(I8Samples.size(), items));
+ for (const auto sample : I8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElement(0).template Get<i8>(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<i8, std::array<double, 3U>> l, const std::pair<i8, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestSumDoubleStringKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, double> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ expects.emplace(sample.first, 0.0).first->second += sample.second;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, double>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), state.front()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), ptr[i].GetElement(1).template Get<double>());
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, double> l, const std::pair<std::string_view, double> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumDoubleStringKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::string, double>> stringI8Samples(I8Samples.size());
+ std::transform(I8Samples.cbegin(), I8Samples.cend(), stringI8Samples.begin(), [](std::pair<i8, double> src){ return std::make_pair(ToString(src.first), src.second); });
+
+ std::unordered_map<std::string, std::array<double, 3U>> expects(201);
+ const auto t = TInstant::Now();
+ for (const auto sample : stringI8Samples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::string_view, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<const char*>::Id), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(item, 0U), pb.Nth(item, 1U) }; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back())}; },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { state.insert(state.cbegin(), keys.front()); return state; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(stringI8Samples.size(), items));
+ for (const auto sample : stringI8Samples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[0] = NUdf::TUnboxedValuePod::Embedded(sample.first);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ two.emplace_back(ptr[i].GetElements()->AsStringRef(), std::array<double, 3U>{ptr[i].GetElement(1).template Get<double>(), ptr[i].GetElement(2).template Get<double>(), ptr[i].GetElement(3).template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::string_view, std::array<double, 3U>> l, const std::pair<std::string_view, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestMinMaxSumTupleKey) {
+ TSetup<LLVM> setup;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, double>> pairSamples(Ui16Samples.size());
+ std::transform(Ui16Samples.cbegin(), Ui16Samples.cend(), pairSamples.begin(), [](std::pair<ui16, double> src){ return std::make_pair(std::make_pair(ui32(src.first / 10U % 100U), ToString(src.first % 10U)), src.second); });
+
+ struct TPairHash { size_t operator()(const std::pair<ui32, std::string>& p) const { return CombineHashes(std::hash<ui32>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<ui32, std::string>, std::array<double, 3U>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (const auto sample : pairSamples) {
+ auto& item = expects.emplace(sample.first, std::array<double, 3U>{0.0, +1E7, -1E7}).first->second;
+ std::get<0U>(item) += sample.second;
+ std::get<1U>(item) = std::min(std::get<1U>(item), sample.second);
+ std::get<2U>(item) = std::max(std::get<2U>(item), sample.second);
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<ui32, std::string>, std::array<double, 3U>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<const char*>::Id)}), pb.NewDataType(NUdf::TDataType<double>::Id)}));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return { pb.Nth(pb.Nth(item, 0U), 0U), pb.Nth(pb.Nth(item, 0U), 1U), pb.Nth(item, 1U) }; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front(), items[1U]}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.back(), items.back(), items.back()}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.AggrAdd(state.front(), items.back()), pb.AggrMin(state[1U], items.back()), pb.AggrMax(state.back(), items.back()) };
+ },
+ [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {keys.front(), keys.back(), state.front(), state[1U], state.back()}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple({pb.NewTuple({items[0U], items[1U]}), items[2U], items[3U], items[4U]}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(pairSamples.size(), items));
+ for (const auto sample : pairSamples) {
+ NUdf::TUnboxedValue* pair = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(2U, pair);
+ pair[1] = NUdf::TUnboxedValuePod(sample.second);
+ NUdf::TUnboxedValue* keys = nullptr;
+ pair[0] = graph->GetHolderFactory().CreateDirectArrayHolder(2U, keys);
+ keys[0] = NUdf::TUnboxedValuePod(sample.first.first);
+ keys[1] = NUdf::TUnboxedValuePod::Embedded(sample.first.second);
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].GetElement(0).template Get<ui32>(), (elements[0].GetElements()[1]).AsStringRef()), std::array<double, 3U>{elements[1].template Get<double>(), elements[2].template Get<double>(), elements[3].template Get<double>()});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> l, const std::pair<std::pair<ui32, std::string_view>, std::array<double, 3U>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+
+ Y_UNIT_TEST_LLVM(TestTpch) {
+ TSetup<LLVM> setup;
+
+ struct TPairHash { size_t operator()(const std::pair<std::string_view, std::string_view>& p) const { return CombineHashes(std::hash<std::string_view>()(p.first), std::hash<std::string_view>()(p.second)); } };
+
+ std::unordered_map<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>, TPairHash> expects;
+ const auto t = TInstant::Now();
+ for (auto& sample : TpchSamples) {
+ if (std::get<0U>(sample) <= border) {
+ const auto& ins = expects.emplace(std::pair<std::string_view, std::string_view>{std::get<1U>(sample), std::get<2U>(sample)}, std::pair<ui64, std::array<double, 5U>>{0ULL, {0., 0., 0., 0., 0.}});
+ auto& item = ins.first->second;
+ ++item.first;
+ std::get<0U>(item.second) += std::get<3U>(sample);
+ std::get<1U>(item.second) += std::get<5U>(sample);
+ std::get<2U>(item.second) += std::get<6U>(sample);
+ const auto v = std::get<3U>(sample) * (1. - std::get<5U>(sample));
+ std::get<3U>(item.second) += v;
+ std::get<4U>(item.second) += v * (1. + std::get<4U>(sample));
+ }
+ }
+ for (auto& item : expects) {
+ std::get<1U>(item.second.second) /= item.second.first;
+ }
+ const auto cppTime = TInstant::Now() - t;
+
+ std::vector<std::pair<std::pair<std::string, std::string>, std::pair<ui64, std::array<double, 5U>>>> one, two;
+ one.reserve(expects.size());
+ two.reserve(expects.size());
+
+ one.insert(one.cend(), expects.cbegin(), expects.cend());
+ std::sort(one.begin(), one.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto listType = pb.NewListType(pb.NewTupleType({
+ pb.NewDataType(NUdf::TDataType<ui64>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<const char*>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id),
+ pb.NewDataType(NUdf::TDataType<double>::Id)
+ }));
+ const auto list = TCallableBuilder(pb.GetTypeEnvironment(), "TestList", listType).Build();
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideLastCombiner(
+ pb.WideFilter(pb.ExpandMap(pb.ToFlow(TRuntimeNode(list, false)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U), pb.Nth(item, 3U), pb.Nth(item, 4U), pb.Nth(item, 5U), pb.Nth(item, 6U)}; }),
+ [&](TRuntimeNode::TList items) { return pb.AggrLessOrEqual(items.front(), pb.NewDataLiteral<ui64>(border)); }
+ ),
+ [&](TRuntimeNode::TList item) -> TRuntimeNode::TList { return {item[1U], item[2U]}; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ const auto price = items[3U];
+ const auto disco = items[5U];
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return {pb.NewDataLiteral<ui64>(1ULL), price, disco, items[6U], v, pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U]))};
+ },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ const auto price = items[3U];
+ const auto disco = items[5U];
+ const auto v = pb.Mul(price, pb.Sub(pb.NewDataLiteral<double>(1.), disco));
+ return {pb.Increment(state[0U]), pb.AggrAdd(state[1U], price), pb.AggrAdd(state[2U], disco), pb.AggrAdd(state[3U], items[6U]), pb.AggrAdd(state[4U], v), pb.AggrAdd(state[5U], pb.Mul(v, pb.Add(pb.NewDataLiteral<double>(1.), items[4U])))};
+ },
+ [&](TRuntimeNode::TList key, TRuntimeNode::TList state) -> TRuntimeNode::TList { return {key.front(), key.back(), state[0U], state[1U], pb.Div(state[2U], state[0U]), state[3U], state[4U], state[5U]}; }),
+ [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn, {list});
+ NUdf::TUnboxedValue* items = nullptr;
+ graph->GetEntryPoint(0, true)->SetValue(graph->GetContext(), graph->GetHolderFactory().CreateDirectArrayHolder(TpchSamples.size(), items));
+ for (const auto sample : TpchSamples) {
+ NUdf::TUnboxedValue* elements = nullptr;
+ *items++ = graph->GetHolderFactory().CreateDirectArrayHolder(7U, elements);
+ elements[0] = NUdf::TUnboxedValuePod(std::get<0U>(sample));
+ elements[1] = NUdf::TUnboxedValuePod::Embedded(std::get<1U>(sample));
+ elements[2] = NUdf::TUnboxedValuePod::Embedded(std::get<2U>(sample));
+ elements[3] = NUdf::TUnboxedValuePod(std::get<3U>(sample));
+ elements[4] = NUdf::TUnboxedValuePod(std::get<4U>(sample));
+ elements[5] = NUdf::TUnboxedValuePod(std::get<5U>(sample));
+ elements[6] = NUdf::TUnboxedValuePod(std::get<6U>(sample));
+ }
+
+ const auto t1 = TInstant::Now();
+ const auto& value = graph->GetValue();
+ const auto t2 = TInstant::Now();
+
+ UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), expects.size());
+
+ const auto ptr = value.GetElements();
+ for (size_t i = 0ULL; i < expects.size(); ++i) {
+ const auto elements = ptr[i].GetElements();
+ two.emplace_back(std::make_pair(elements[0].AsStringRef(), elements[1].AsStringRef()), std::pair<ui64, std::array<double, 5U>>{elements[2].template Get<ui64>(), {elements[3].template Get<double>(), elements[4].template Get<double>(), elements[5].template Get<double>(), elements[6].template Get<double>(), elements[7].template Get<double>()}});
+ }
+
+ std::sort(two.begin(), two.end(), [](const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> l, const std::pair<std::pair<std::string_view, std::string_view>, std::pair<ui64, std::array<double, 5U>>> r){ return l.first < r.first; });
+ UNIT_ASSERT_VALUES_EQUAL(one, two);
+
+ Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
+ }
+}
+#endif
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
index 232b78d25d..f7fdc9e0d4 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
@@ -1,173 +1,173 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideCondense1Test) {
- Y_UNIT_TEST_LLVM(TestConcatItemsToKey) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
- const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
-
- const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
- const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
-
- const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
- const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
-
- const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
-
- const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
- const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
- const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
- const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
- const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items.front(), pb.AggrConcat(pb.AggrConcat(items.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), items.back())};
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
- return pb.AggrNotEquals(items.front(), state.front());
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {state.front(), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
- }),
- [&](TRuntimeNode::TList items) { return items.back(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key one: very long value 1");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "key two: very long value 2, very long value 3");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key one: very long value 4");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "very long key two: very long value 5, very long value 6, very long value 7, very long value 8, very long value 9");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSwitchByBoolFieldAndDontUseKey) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
- const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
- const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
-
- const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
- const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
- const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
-
- const auto trueVal = pb.NewDataLiteral<bool>(true);
- const auto falseVal = pb.NewDataLiteral<bool>(false);
-
- const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
- const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
- const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
- const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
- const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
- const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
- const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
- const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
- const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
-
- const auto data1 = pb.NewTuple(tupleType, {key0, value1, trueVal});
- const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
- const auto data3 = pb.NewTuple(tupleType, {key2, value3, falseVal});
- const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
- const auto data5 = pb.NewTuple(tupleType, {key1, value5, falseVal});
- const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
- const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
- const auto data8 = pb.NewTuple(tupleType, {key1, value8, falseVal});
- const auto data9 = pb.NewTuple(tupleType, {key2, value9, trueVal});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Unwrap(pb.Nth(item, 0U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
- return {items[1U]};
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList) {
- return items.back();
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
- return {pb.AggrConcat(pb.AggrConcat(state.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>("; ")), items[1U])};
- }),
- [&](TRuntimeNode::TList items) { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 1; value 2; value 3");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 4; value 5; value 6; value 7; value 8");
- UNIT_ASSERT(iterator.Next(item));
- UNBOXED_VALUE_STR_EQUAL(item, "value 9");
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto tupleType = pb.NewTupleType({});
-
- const auto data = pb.NewTuple({});
-
- const auto list = pb.NewList(tupleType, {data, data, data, data});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
- [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [](TRuntimeNode::TList items) { return items; },
- [&](TRuntimeNode::TList, TRuntimeNode::TList) { return pb.NewDataLiteral<bool>(true); },
- [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state;}),
- [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#endif
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideCondense1Test) {
+ Y_UNIT_TEST_LLVM(TestConcatItemsToKey) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
+ const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
+
+ const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
+ const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
+
+ const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
+ const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
+
+ const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
+
+ const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
+ const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
+ const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
+ const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
+ const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items.front(), pb.AggrConcat(pb.AggrConcat(items.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>(": ")), items.back())};
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
+ return pb.AggrNotEquals(items.front(), state.front());
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {state.front(), pb.AggrConcat(pb.AggrConcat(state.back(), pb.NewDataLiteral<NUdf::EDataSlot::String>(", ")), items.back())};
+ }),
+ [&](TRuntimeNode::TList items) { return items.back(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key one: very long value 1");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "key two: very long value 2, very long value 3");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key one: very long value 4");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "very long key two: very long value 5, very long value 6, very long value 7, very long value 8, very long value 9");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSwitchByBoolFieldAndDontUseKey) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
+ const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
+ const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
+
+ const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
+ const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
+ const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
+
+ const auto trueVal = pb.NewDataLiteral<bool>(true);
+ const auto falseVal = pb.NewDataLiteral<bool>(false);
+
+ const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
+ const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
+ const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
+ const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
+ const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
+ const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
+ const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
+ const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
+ const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
+
+ const auto data1 = pb.NewTuple(tupleType, {key0, value1, trueVal});
+ const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
+ const auto data3 = pb.NewTuple(tupleType, {key2, value3, falseVal});
+ const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
+ const auto data5 = pb.NewTuple(tupleType, {key1, value5, falseVal});
+ const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
+ const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
+ const auto data8 = pb.NewTuple(tupleType, {key1, value8, falseVal});
+ const auto data9 = pb.NewTuple(tupleType, {key2, value9, trueVal});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Unwrap(pb.Nth(item, 0U), landmine, __FILE__, __LINE__, 0), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
+ return {items[1U]};
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList) {
+ return items.back();
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) -> TRuntimeNode::TList {
+ return {pb.AggrConcat(pb.AggrConcat(state.front(), pb.NewDataLiteral<NUdf::EDataSlot::String>("; ")), items[1U])};
+ }),
+ [&](TRuntimeNode::TList items) { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 1; value 2; value 3");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 4; value 5; value 6; value 7; value 8");
+ UNIT_ASSERT(iterator.Next(item));
+ UNBOXED_VALUE_STR_EQUAL(item, "value 9");
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto tupleType = pb.NewTupleType({});
+
+ const auto data = pb.NewTuple({});
+
+ const auto list = pb.NewList(tupleType, {data, data, data, data});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideCondense1(pb.ExpandMap(pb.ToFlow(list),
+ [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [](TRuntimeNode::TList items) { return items; },
+ [&](TRuntimeNode::TList, TRuntimeNode::TList) { return pb.NewDataLiteral<bool>(true); },
+ [](TRuntimeNode::TList, TRuntimeNode::TList state) { return state;}),
+ [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#endif
+}
+}
+
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
index 7259242145..5d5a9e7aa7 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
@@ -1,386 +1,386 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideFilterTest) {
- Y_UNIT_TEST_LLVM(TestPredicateExpression) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(
- pb.NarrowMap(
- pb.WideFilter(
- pb.ExpandMap(
- pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }
- ),
- [&](TRuntimeNode::TList items) -> TRuntimeNode {
- const auto v = pb.If(
- pb.Exists(items.front()),
- pb.NewOptional(pb.NewDataLiteral<bool>(true)),
- pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id)
- );
- return pb.Coalesce(v, pb.NewDataLiteral<bool>(false));
- }
- ),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- )
- );
-
- const auto graph = setup.BuildGraph(pgmReturn);
- NUdf::TUnboxedValue value = graph->GetValue();
-
- NUdf::TUnboxedValue v;
- UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(v.GetElement(0).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(v.GetElement(1).template Get<i32>(), -2);
-
- UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Ok);
- UNIT_ASSERT_VALUES_EQUAL(v.GetElement(0).template Get<i32>(), 3);
- UNIT_ASSERT_VALUES_EQUAL(v.GetElement(1).template Get<i32>(), -3);
-
- UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Finish);
- }
-
- Y_UNIT_TEST_LLVM(TestCheckedFieldPasstrought) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestCheckedFieldUnusedAfter) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Unwrap(pb.Nth(item, 2U), landmine, __FILE__, __LINE__, 0)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWithLimitCheckedFieldUsedAfter) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(9)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(7)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(6)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- pb.NewDataLiteral<ui64>(2ULL), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrAdd(items.back(), items.front()); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 8);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWithLimitCheckedFieldUnusedAfter) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- pb.NewDataLiteral<ui64>(2ULL), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhile) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideTakeWhile(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeWhileInclusive) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideTakeWhileInclusive(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhile) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideSkipWhile(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrGreater(items.back(), pb.NewOptional(pb.NewDataLiteral<i32>(-3))); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestSkipWhileInclusive) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideSkipWhileInclusive(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrGreater(items.back(), pb.NewOptional(pb.NewDataLiteral<i32>(-3))); }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFilterByBooleanField) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, pb.NewDataType(NUdf::TDataType<bool>::Id), dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewDataLiteral(true), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewDataLiteral(false), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewDataLiteral(true), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewDataLiteral(false), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items[1U]; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +3);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#endif
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideFilterTest) {
+ Y_UNIT_TEST_LLVM(TestPredicateExpression) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(
+ pb.NarrowMap(
+ pb.WideFilter(
+ pb.ExpandMap(
+ pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }
+ ),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode {
+ const auto v = pb.If(
+ pb.Exists(items.front()),
+ pb.NewOptional(pb.NewDataLiteral<bool>(true)),
+ pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id)
+ );
+ return pb.Coalesce(v, pb.NewDataLiteral<bool>(false));
+ }
+ ),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ )
+ );
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ NUdf::TUnboxedValue value = graph->GetValue();
+
+ NUdf::TUnboxedValue v;
+ UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(v.GetElement(0).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(v.GetElement(1).template Get<i32>(), -2);
+
+ UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Ok);
+ UNIT_ASSERT_VALUES_EQUAL(v.GetElement(0).template Get<i32>(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(v.GetElement(1).template Get<i32>(), -3);
+
+ UNIT_ASSERT_VALUES_EQUAL(value.Fetch(v), NUdf::EFetchStatus::Finish);
+ }
+
+ Y_UNIT_TEST_LLVM(TestCheckedFieldPasstrought) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestCheckedFieldUnusedAfter) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Unwrap(pb.Nth(item, 2U), landmine, __FILE__, __LINE__, 0)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items[1U]); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWithLimitCheckedFieldUsedAfter) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(9)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(7)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(6)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ pb.NewDataLiteral<ui64>(2ULL), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrAdd(items.back(), items.front()); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 8);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWithLimitCheckedFieldUnusedAfter) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ pb.NewDataLiteral<ui64>(2ULL), [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.back(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhile) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideTakeWhile(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeWhileInclusive) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideTakeWhileInclusive(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.Exists(items.front()); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhile) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideSkipWhile(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrGreater(items.back(), pb.NewOptional(pb.NewDataLiteral<i32>(-3))); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipWhileInclusive) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideSkipWhileInclusive(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.AggrGreater(items.back(), pb.NewOptional(pb.NewDataLiteral<i32>(-3))); }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFilterByBooleanField) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, pb.NewDataType(NUdf::TDataType<bool>::Id), dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewDataLiteral(true), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewDataLiteral(false), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewDataLiteral(true), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewDataLiteral(false), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideFilter(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items[1U]; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +3);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#endif
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
index 5c3168526c..4add5f00ea 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
@@ -1,253 +1,253 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideMapTest) {
- Y_UNIT_TEST_LLVM(TestSimpleSwap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items[2U], items[1U], items[0U] }); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
- UNIT_ASSERT(!item.GetElement(1));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestThinLambda) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType)});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
- [&](TRuntimeNode::TList items) { return items; }),
- [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.NewTuple({}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestWideMap) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrMin(items[0], items[1]), pb.AggrMax(items[1], items[2]), pb.AggrAdd(items[0], items[2])}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -3);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 0);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(0)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.Mul(items.front(), items.back()), pb.Unwrap(items[1], landmine, __FILE__, __LINE__, 0), pb.Add(items.front(), items.back())}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -9);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -16);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestPasstroughtFieldSplitAsIs) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U], pb.Mul(items.front(), items.back()), items[1U]}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -5);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -9);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -16);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestFieldBothWayPasstroughtAndArg) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
- const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
-
- const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
- const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
- const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
- const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
-
- const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U], pb.Sub(items.front(), items.back()), pb.Minus(items[1U])}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 5);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 6);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 7);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT(!item.GetElement(0));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 8);
- UNIT_ASSERT(!item.GetElement(2));
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-}
-#endif
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideMapTest) {
+ Y_UNIT_TEST_LLVM(TestSimpleSwap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items[2U], items[1U], items[0U] }); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -3);
+ UNIT_ASSERT(!item.GetElement(1));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 3);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestThinLambda) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType)});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
+ [&](TRuntimeNode::TList items) { return items; }),
+ [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.NewTuple({}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestWideMap) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType)});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.AggrMin(items[0], items[1]), pb.AggrMax(items[1], items[2]), pb.AggrAdd(items[0], items[2])}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -2);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -3);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 0);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDotCalculateUnusedField) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(0)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.Mul(items.front(), items.back()), pb.Unwrap(items[1], landmine, __FILE__, __LINE__, 0), pb.Add(items.front(), items.back())}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -9);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -16);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestPasstroughtFieldSplitAsIs) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U], pb.Mul(items.front(), items.back()), items[1U]}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -5);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -9);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), -7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -16);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestFieldBothWayPasstroughtAndArg) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
+ const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
+
+ const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewOptional(pb.NewDataLiteral<i32>(-5)), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
+ const auto data2 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-4)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
+ const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewOptional(pb.NewDataLiteral<i32>(-7)), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
+ const auto data4 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(4)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-4))});
+
+ const auto list = pb.NewList(tupleType, {data1, data2, data3, data4});
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideMap(pb.ExpandMap(pb.ToFlow(list),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U], pb.Sub(items.front(), items.back()), pb.Minus(items[1U])}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple(items); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -5);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 5);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 4);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -7);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 6);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(2).template Get<i32>(), 7);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT(!item.GetElement(0));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), 8);
+ UNIT_ASSERT(!item.GetElement(2));
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+}
+#endif
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
index ea28b15b78..5adbf9c861 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
@@ -1,102 +1,102 @@
-#include "mkql_computation_node_ut.h"
+#include "mkql_computation_node_ut.h"
#include <ydb/library/yql/minikql/mkql_runtime_version.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
-Y_UNIT_TEST_SUITE(TMiniKQLWideNodesTest) {
- Y_UNIT_TEST_LLVM(TestDiscard) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
- const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
- const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
- const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
- const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
- const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
-
- const auto pgmReturn = pb.FromFlow(pb.Discard(pb.ExpandMap(pb.ToFlow(list), [](TRuntimeNode) { return TRuntimeNode::TList(); })));
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
- }
-
- Y_UNIT_TEST_LLVM(TestTakeOverSource) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Take(pb.Source(), pb.NewDataLiteral<ui64>(666ULL)), [&](TRuntimeNode::TList) { return pb.NewTuple({}); } ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 666ULL);
- }
-
- Y_UNIT_TEST_LLVM(TestSkipAndTake) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui32>(100U), pb.NewDataLiteral<ui32>(666U), pb.NewDataLiteral<ui32>(3U));
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Take(pb.Skip(pb.ExpandMap(pb.ToFlow(pb.Enumerate(list)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 1U), pb.Nth(item, 0U)}; }),
- pb.NewDataLiteral<ui64>(42ULL)), pb.NewDataLiteral<ui64>(4ULL)),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 42);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 226);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 43);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 229);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 44);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 232);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 45);
- UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 235);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
- Y_UNIT_TEST_LLVM(TestDoNotCalculateSkipped) {
- TSetup<LLVM> setup;
- TProgramBuilder& pb = *setup.PgmBuilder;
-
- const auto list = pb.ListFromRange(pb.NewDataLiteral<ui64>(100ULL), pb.NewDataLiteral<ui64>(135ULL), pb.NewDataLiteral<ui64>(5ULL));
-
- const auto trap = pb.NewDataLiteral<NUdf::EDataSlot::String>("IT'S A TRAP!");
-
- const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Skip(pb.WideMap(pb.ExpandMap(pb.ToFlow(pb.Enumerate(list)),
- [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 1U), pb.Nth(item, 0U)}; }),
- [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.Unwrap(pb.Div(items.front(), items.back()), trap, __FILE__, __LINE__, 0)}; }),
- pb.NewDataLiteral<ui64>(3ULL)),
- [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.front(); }
- ));
-
- const auto graph = setup.BuildGraph(pgmReturn);
- const auto iterator = graph->GetValue().GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 38ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 30ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 25ULL);
- UNIT_ASSERT(iterator.Next(item));
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
- UNIT_ASSERT(!iterator.Next(item));
- UNIT_ASSERT(!iterator.Next(item));
- }
-
-}
-#endif
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+Y_UNIT_TEST_SUITE(TMiniKQLWideNodesTest) {
+ Y_UNIT_TEST_LLVM(TestDiscard) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("000");
+ const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("100");
+ const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("200");
+ const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("300");
+ const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto list = pb.NewList(dataType, {data0, data1, data2, data3});
+
+ const auto pgmReturn = pb.FromFlow(pb.Discard(pb.ExpandMap(pb.ToFlow(list), [](TRuntimeNode) { return TRuntimeNode::TList(); })));
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestTakeOverSource) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Take(pb.Source(), pb.NewDataLiteral<ui64>(666ULL)), [&](TRuntimeNode::TList) { return pb.NewTuple({}); } ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ UNIT_ASSERT_VALUES_EQUAL(graph->GetValue().GetListLength(), 666ULL);
+ }
+
+ Y_UNIT_TEST_LLVM(TestSkipAndTake) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui32>(100U), pb.NewDataLiteral<ui32>(666U), pb.NewDataLiteral<ui32>(3U));
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Take(pb.Skip(pb.ExpandMap(pb.ToFlow(pb.Enumerate(list)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 1U), pb.Nth(item, 0U)}; }),
+ pb.NewDataLiteral<ui64>(42ULL)), pb.NewDataLiteral<ui64>(4ULL)),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.NewTuple({items.back(), items.front()}); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 42);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 226);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 43);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 229);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 44);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 232);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<ui64>(), 45);
+ UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<ui32>(), 235);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+ Y_UNIT_TEST_LLVM(TestDoNotCalculateSkipped) {
+ TSetup<LLVM> setup;
+ TProgramBuilder& pb = *setup.PgmBuilder;
+
+ const auto list = pb.ListFromRange(pb.NewDataLiteral<ui64>(100ULL), pb.NewDataLiteral<ui64>(135ULL), pb.NewDataLiteral<ui64>(5ULL));
+
+ const auto trap = pb.NewDataLiteral<NUdf::EDataSlot::String>("IT'S A TRAP!");
+
+ const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.Skip(pb.WideMap(pb.ExpandMap(pb.ToFlow(pb.Enumerate(list)),
+ [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 1U), pb.Nth(item, 0U)}; }),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {pb.Unwrap(pb.Div(items.front(), items.back()), trap, __FILE__, __LINE__, 0)}; }),
+ pb.NewDataLiteral<ui64>(3ULL)),
+ [&](TRuntimeNode::TList items) -> TRuntimeNode { return items.front(); }
+ ));
+
+ const auto graph = setup.BuildGraph(pgmReturn);
+ const auto iterator = graph->GetValue().GetListIterator();
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 38ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 30ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 25ULL);
+ UNIT_ASSERT(iterator.Next(item));
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui64>(), 21ULL);
+ UNIT_ASSERT(!iterator.Next(item));
+ UNIT_ASSERT(!iterator.Next(item));
+ }
+
+}
+#endif
+}
+}
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/ya.make b/ydb/library/yql/minikql/comp_nodes/ut/ya.make
index ee428056d1..dffda1318f 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/ya.make
+++ b/ydb/library/yql/minikql/comp_nodes/ut/ya.make
@@ -21,51 +21,51 @@ OWNER(
SRCS(
mkql_blocks_ut.cpp
mkql_combine_ut.cpp
- mkql_condense_ut.cpp
- mkql_decimal_ut.cpp
- mkql_chain_map_ut.cpp
- mkql_chopper_ut.cpp
- mkql_filters_ut.cpp
- mkql_flatmap_ut.cpp
+ mkql_condense_ut.cpp
+ mkql_decimal_ut.cpp
+ mkql_chain_map_ut.cpp
+ mkql_chopper_ut.cpp
+ mkql_filters_ut.cpp
+ mkql_flatmap_ut.cpp
mkql_multihopping_saveload_ut.cpp
mkql_multihopping_ut.cpp
- mkql_multimap_ut.cpp
- mkql_fold_ut.cpp
- mkql_heap_ut.cpp
- mkql_compare_ut.cpp
+ mkql_multimap_ut.cpp
+ mkql_fold_ut.cpp
+ mkql_heap_ut.cpp
+ mkql_compare_ut.cpp
mkql_computation_node_ut.cpp
mkql_group_ut.cpp
- mkql_dict_ut.cpp
- mkql_join_ut.cpp
- mkql_join_dict_ut.cpp
- mkql_map_join_ut.cpp
+ mkql_dict_ut.cpp
+ mkql_join_ut.cpp
+ mkql_join_dict_ut.cpp
+ mkql_map_join_ut.cpp
mkql_safe_circular_buffer_ut.cpp
mkql_sort_ut.cpp
- mkql_switch_ut.cpp
+ mkql_switch_ut.cpp
mkql_todict_ut.cpp
- mkql_variant_ut.cpp
- mkql_wide_chain_map_ut.cpp
- mkql_wide_chopper_ut.cpp
- mkql_wide_combine_ut.cpp
- mkql_wide_condense_ut.cpp
- mkql_wide_filter_ut.cpp
- mkql_wide_map_ut.cpp
- mkql_wide_nodes_ut.cpp
+ mkql_variant_ut.cpp
+ mkql_wide_chain_map_ut.cpp
+ mkql_wide_chopper_ut.cpp
+ mkql_wide_combine_ut.cpp
+ mkql_wide_condense_ut.cpp
+ mkql_wide_filter_ut.cpp
+ mkql_wide_map_ut.cpp
+ mkql_wide_nodes_ut.cpp
mkql_listfromrange_ut.cpp
)
-PEERDIR(
+PEERDIR(
ydb/library/yql/minikql/computation
ydb/library/yql/public/udf
ydb/library/yql/public/udf/service/exception_policy
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-IF (MKQL_RUNTIME_VERSION)
+IF (MKQL_RUNTIME_VERSION)
CFLAGS(
-DMKQL_RUNTIME_VERSION=$MKQL_RUNTIME_VERSION
)
-ENDIF()
-
+ENDIF()
+
END()
diff --git a/ydb/library/yql/minikql/comp_nodes/ya.make b/ydb/library/yql/minikql/comp_nodes/ya.make
index 00bb8d997e..55838c4012 100644
--- a/ydb/library/yql/minikql/comp_nodes/ya.make
+++ b/ydb/library/yql/minikql/comp_nodes/ya.make
@@ -20,14 +20,14 @@ SRCS(
mkql_blocks.cpp
mkql_callable.cpp
mkql_callable.h
- mkql_chain_map.cpp
- mkql_chain_map.h
- mkql_chain1_map.cpp
- mkql_chain1_map.h
+ mkql_chain_map.cpp
+ mkql_chain_map.h
+ mkql_chain1_map.cpp
+ mkql_chain1_map.h
mkql_check_args.cpp
mkql_check_args.h
- mkql_chopper.cpp
- mkql_chopper.h
+ mkql_chopper.cpp
+ mkql_chopper.h
mkql_coalesce.cpp
mkql_coalesce.h
mkql_collect.cpp
@@ -36,18 +36,18 @@ SRCS(
mkql_combine.h
mkql_contains.cpp
mkql_contains.h
- mkql_decimal_div.cpp
- mkql_decimal_div.h
- mkql_decimal_mod.cpp
- mkql_decimal_mod.h
- mkql_decimal_mul.cpp
- mkql_decimal_mul.h
+ mkql_decimal_div.cpp
+ mkql_decimal_div.h
+ mkql_decimal_mod.cpp
+ mkql_decimal_mod.h
+ mkql_decimal_mul.cpp
+ mkql_decimal_mul.h
mkql_dictitems.cpp
mkql_dictitems.h
mkql_discard.cpp
mkql_discard.h
- mkql_element.cpp
- mkql_element.h
+ mkql_element.cpp
+ mkql_element.h
mkql_ensure.h
mkql_ensure.cpp
mkql_enumerate.cpp
@@ -62,8 +62,8 @@ SRCS(
mkql_filter.h
mkql_flatmap.cpp
mkql_flatmap.h
- mkql_flow.cpp
- mkql_flow.h
+ mkql_flow.cpp
+ mkql_flow.h
mkql_fold.cpp
mkql_fold.h
mkql_fold1.cpp
@@ -80,8 +80,8 @@ SRCS(
mkql_guess.h
mkql_hasitems.cpp
mkql_hasitems.h
- mkql_heap.cpp
- mkql_heap.h
+ mkql_heap.cpp
+ mkql_heap.h
mkql_hopping.cpp
mkql_hopping.h
mkql_if.cpp
@@ -96,10 +96,10 @@ SRCS(
mkql_iterator.h
mkql_join.cpp
mkql_join.h
- mkql_join_dict.cpp
- mkql_join_dict.h
- mkql_lazy_list.cpp
- mkql_lazy_list.h
+ mkql_join_dict.cpp
+ mkql_join_dict.h
+ mkql_lazy_list.cpp
+ mkql_lazy_list.h
mkql_length.cpp
mkql_length.h
mkql_listfromrange.cpp
@@ -110,12 +110,12 @@ SRCS(
mkql_lookup.h
mkql_map.cpp
mkql_map.h
- mkql_map_join.cpp
- mkql_map_join.h
+ mkql_map_join.cpp
+ mkql_map_join.h
mkql_multihopping.cpp
mkql_multihopping.h
- mkql_multimap.cpp
- mkql_multimap.h
+ mkql_multimap.cpp
+ mkql_multimap.h
mkql_next_value.cpp
mkql_next_value.h
mkql_now.cpp
@@ -153,16 +153,16 @@ SRCS(
mkql_skip.h
mkql_sort.cpp
mkql_sort.h
- mkql_source.cpp
- mkql_source.h
- mkql_squeeze_state.cpp
- mkql_squeeze_state.h
- mkql_squeeze_to_list.cpp
- mkql_squeeze_to_list.h
- mkql_condense.cpp
- mkql_condense.h
- mkql_condense1.cpp
- mkql_condense1.h
+ mkql_source.cpp
+ mkql_source.h
+ mkql_squeeze_state.cpp
+ mkql_squeeze_state.h
+ mkql_squeeze_to_list.cpp
+ mkql_squeeze_to_list.h
+ mkql_condense.cpp
+ mkql_condense.h
+ mkql_condense1.cpp
+ mkql_condense1.h
mkql_switch.cpp
mkql_switch.h
mkql_take.cpp
@@ -191,20 +191,20 @@ SRCS(
mkql_way.h
mkql_weakmember.cpp
mkql_weakmember.h
- mkql_while.cpp
- mkql_while.h
- mkql_wide_chain_map.cpp
- mkql_wide_chain_map.h
- mkql_wide_chopper.cpp
- mkql_wide_chopper.h
- mkql_wide_combine.cpp
- mkql_wide_combine.h
- mkql_wide_condense.cpp
- mkql_wide_condense.h
- mkql_wide_filter.cpp
- mkql_wide_filter.h
- mkql_wide_map.cpp
- mkql_wide_map.h
+ mkql_while.cpp
+ mkql_while.h
+ mkql_wide_chain_map.cpp
+ mkql_wide_chain_map.h
+ mkql_wide_chopper.cpp
+ mkql_wide_chopper.h
+ mkql_wide_combine.cpp
+ mkql_wide_combine.h
+ mkql_wide_condense.cpp
+ mkql_wide_condense.h
+ mkql_wide_filter.cpp
+ mkql_wide_filter.h
+ mkql_wide_map.cpp
+ mkql_wide_map.h
mkql_zip.cpp
mkql_zip.h
)
@@ -222,19 +222,19 @@ NO_COMPILER_WARNINGS()
IF (NOT MKQL_DISABLE_CODEGEN)
PEERDIR(
ydb/library/yql/minikql/codegen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Transforms/IPO
)
ELSE()
CFLAGS(
-DMKQL_DISABLE_CODEGEN
)
ENDIF()
-
+
YQL_LAST_ABI_VERSION()
END()
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h b/ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h
index 1d7de9edcd..2b3b7fb886 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_list_adapter.h
@@ -11,14 +11,14 @@ class TVectorListAdapter : public TComputationValue<TVectorListAdapter<TVectorTy
public:
typedef typename TVectorType::value_type TItem;
typedef TVectorListAdapter<TVectorType> TSelf;
- typedef std::function<NUdf::TUnboxedValue(const TItem&)> TItemFactory;
+ typedef std::function<NUdf::TUnboxedValue(const TItem&)> TItemFactory;
typedef TComputationValue<TVectorListAdapter<TVectorType>> TBase;
- class TIterator: public TComputationValue<TIterator> {
+ class TIterator: public TComputationValue<TIterator> {
public:
TIterator(TMemoryUsageInfo* memInfo, const TVectorType& list, TItemFactory itemFactory, ui64 start, ui64 finish, bool reversed)
- : TComputationValue<TIterator>(memInfo)
- , List(list)
+ : TComputationValue<TIterator>(memInfo)
+ , List(list)
, ItemFactory(itemFactory)
, Start(start)
, Finish(finish)
@@ -27,28 +27,28 @@ public:
Index = Reversed ? Finish : (Start - 1);
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Skip())
- return false;
- value = ItemFactory(List[Index]);
- return true;
- }
-
- bool Skip() override {
- if (!Reversed) {
- if (Index + 1 >= Finish)
- return false;
- ++Index;
- } else {
- if (Index < Start + 1)
- return false;
- --Index;
- }
-
- return true;
- }
-
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Skip())
+ return false;
+ value = ItemFactory(List[Index]);
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Reversed) {
+ if (Index + 1 >= Finish)
+ return false;
+ ++Index;
+ } else {
+ if (Index < Start + 1)
+ return false;
+ --Index;
+ }
+
+ return true;
+ }
+
const TVectorType& List;
const TItemFactory ItemFactory;
const ui64 Start;
@@ -57,42 +57,42 @@ public:
ui64 Index;
};
- class TDictIterator : public TComputationValue<TDictIterator> {
+ class TDictIterator : public TComputationValue<TDictIterator> {
public:
- TDictIterator(TMemoryUsageInfo* memInfo, TIterator iter)
- : TComputationValue<TDictIterator>(memInfo)
- , Iter(iter)
+ TDictIterator(TMemoryUsageInfo* memInfo, TIterator iter)
+ : TComputationValue<TDictIterator>(memInfo)
+ , Iter(iter)
, Index(Max<ui64>())
{}
- private:
- bool Next(NUdf::TUnboxedValue& key) override {
- if (NUdf::TBoxedValueAccessor::Skip(Iter)) {
- key = NUdf::TUnboxedValuePod(++Index);
- return true;
- }
-
- return false;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (NUdf::TBoxedValueAccessor::Next(Iter, payload)) {
- key = NUdf::TUnboxedValuePod(++Index);
- return true;
- }
-
- return false;
- }
-
- bool Skip() override {
- if (NUdf::TBoxedValueAccessor::Skip(Iter)) {
- ++Index;
- return true;
- }
-
- return false;
- }
-
+ private:
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (NUdf::TBoxedValueAccessor::Skip(Iter)) {
+ key = NUdf::TUnboxedValuePod(++Index);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (NUdf::TBoxedValueAccessor::Next(Iter, payload)) {
+ key = NUdf::TUnboxedValuePod(++Index);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Skip() override {
+ if (NUdf::TBoxedValueAccessor::Skip(Iter)) {
+ ++Index;
+ return true;
+ }
+
+ return false;
+ }
+
TIterator Iter;
ui64 Index;
};
@@ -113,7 +113,7 @@ public:
Y_VERIFY(Start <= Finish && Finish <= List.size());
}
-private:
+private:
bool HasFastListLength() const override {
return true;
}
@@ -132,27 +132,27 @@ private:
NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
Y_UNUSED(builder);
- return new TSelf(this->GetMemInfo(), List, ItemFactory, Start, Finish, !Reversed);
+ return new TSelf(this->GetMemInfo(), List, ItemFactory, Start, Finish, !Reversed);
}
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
- Y_UNUSED(builder);
+ Y_UNUSED(builder);
const ui64 newStart = Min(Start + count, Finish);
if (newStart == Start) {
return const_cast<TVectorListAdapter*>(this);
}
- return new TSelf(this->GetMemInfo(), List, ItemFactory, newStart, Finish, Reversed);
+ return new TSelf(this->GetMemInfo(), List, ItemFactory, newStart, Finish, Reversed);
}
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
- Y_UNUSED(builder);
+ Y_UNUSED(builder);
const ui64 newFinish = Min(Start + count, Finish);
if (newFinish == Finish) {
return const_cast<TVectorListAdapter*>(this);
}
- return new TSelf(this->GetMemInfo(), List, ItemFactory, Start, newFinish, Reversed);
+ return new TSelf(this->GetMemInfo(), List, ItemFactory, Start, newFinish, Reversed);
}
NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
@@ -160,37 +160,37 @@ private:
return const_cast<TVectorListAdapter*>(this);
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed));
- }
-
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- const ui64 index = key.Get<ui64>();
- return (index < GetListLength());
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- const ui64 index = key.Get<ui64>();
- if (index >= GetListLength()) {
- return NUdf::TUnboxedValuePod();
- }
-
- const ui64 realIndex = Reversed ? (Finish - 1 - index) : (Start + index);
- return ItemFactory(List[realIndex]).Release().MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TDictIterator(this->GetMemInfo(), TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed)));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TDictIterator(this->GetMemInfo(), TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed)));
- }
-
- ui64 GetDictLength() const override {
- return GetListLength();
- }
-
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed));
+ }
+
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ const ui64 index = key.Get<ui64>();
+ return (index < GetListLength());
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ const ui64 index = key.Get<ui64>();
+ if (index >= GetListLength()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ const ui64 realIndex = Reversed ? (Finish - 1 - index) : (Start + index);
+ return ItemFactory(List[realIndex]).Release().MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TDictIterator(this->GetMemInfo(), TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed)));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TDictIterator(this->GetMemInfo(), TIterator(this->GetMemInfo(), List, ItemFactory, Start, Finish, Reversed)));
+ }
+
+ ui64 GetDictLength() const override {
+ return GetListLength();
+ }
+
bool HasDictItems() const override {
return Finish != Start;
}
@@ -219,7 +219,7 @@ public:
ui64 start, ui64 finish,
bool reversed)
: TVectorType(std::move(list))
- , TAdapterBase(memInfo, *this, itemFactory, start, finish, reversed) {}
+ , TAdapterBase(memInfo, *this, itemFactory, start, finish, reversed) {}
TOwningVectorListAdapter(
TMemoryUsageInfo* memInfo,
@@ -228,11 +228,11 @@ public:
ui64 start, ui64 finish,
bool reversed)
: TVectorType(list)
- , TAdapterBase(memInfo, *this, itemFactory, start, finish, reversed) {}
+ , TAdapterBase(memInfo, *this, itemFactory, start, finish, reversed) {}
};
template<typename TVectorType>
-NUdf::TUnboxedValue CreateOwningVectorListAdapter(
+NUdf::TUnboxedValue CreateOwningVectorListAdapter(
TVectorType&& list,
typename TVectorListAdapter<std::remove_reference_t<TVectorType>>::TItemFactory itemFactory,
ui64 start, ui64 finish,
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node.cpp
index 20f57d9333..aa2e27f028 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node.cpp
@@ -31,12 +31,12 @@ TComputationContext::TComputationContext(const THolderFactory& holderFactory,
TComputationOptsFull& opts,
const TComputationMutables& mutables,
arrow::MemoryPool& arrowMemoryPool)
- : TComputationContextLLVM{holderFactory, opts.Stats, std::make_unique<NUdf::TUnboxedValue[]>(mutables.CurValueIndex), builder}
+ : TComputationContextLLVM{holderFactory, opts.Stats, std::make_unique<NUdf::TUnboxedValue[]>(mutables.CurValueIndex), builder}
, RandomProvider(opts.RandomProvider)
, TimeProvider(opts.TimeProvider)
, ArrowMemoryPool(arrowMemoryPool)
{
- std::fill_n(MutableValues.get(), mutables.CurValueIndex, NUdf::TUnboxedValue(NUdf::TUnboxedValuePod::Invalid()));
+ std::fill_n(MutableValues.get(), mutables.CurValueIndex, NUdf::TUnboxedValue(NUdf::TUnboxedValuePod::Invalid()));
}
TComputationContext::~TComputationContext() {
@@ -65,10 +65,10 @@ void TComputationContext::UpdateUsageAdjustor(ui64 memLimit) {
if (auto peakAlloc = HolderFactory.GetPagePool().GetPeakAllocated()) {
if (rss - InitRss > memLimit && rss - LastRss > (memLimit / 4)) {
- UsageAdjustor = std::max(1.f, float(rss - InitRss) / float(peakAlloc));
+ UsageAdjustor = std::max(1.f, float(rss - InitRss) / float(peakAlloc));
LastRss = rss;
#ifndef NDEBUG
- printUsage = UsageAdjustor > 1.f;
+ printUsage = UsageAdjustor > 1.f;
#endif
}
}
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node.h b/ydb/library/yql/minikql/computation/mkql_computation_node.h
index 6f53d69b80..a5d11b180b 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node.h
@@ -18,16 +18,16 @@
#include <library/cpp/random_provider/random_provider.h>
#include <library/cpp/time_provider/time_provider.h>
-#include <map>
-#include <unordered_set>
-#include <unordered_map>
-#include <vector>
+#include <map>
+#include <unordered_set>
+#include <unordered_map>
+#include <vector>
namespace NKikimr {
namespace NMiniKQL {
-inline const TDefaultListRepresentation* GetDefaultListRepresentation(const NUdf::TUnboxedValuePod& value) {
- return reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*value.AsBoxed()));
+inline const TDefaultListRepresentation* GetDefaultListRepresentation(const NUdf::TUnboxedValuePod& value) {
+ return reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*value.AsBoxed()));
}
enum class EGraphPerProcess {
@@ -39,8 +39,8 @@ struct TComputationOpts {
TComputationOpts(IStatsRegistry* stats)
: Stats(stats)
{}
-
- IStatsRegistry *const Stats;
+
+ IStatsRegistry *const Stats;
};
struct TComputationOptsFull: public TComputationOpts {
@@ -61,27 +61,27 @@ struct TComputationOptsFull: public TComputationOpts {
};
struct TComputationMutables {
- ui32 CurValueIndex = 0U;
+ ui32 CurValueIndex = 0U;
std::vector<ui32> SerializableValues; // Indices of values that need to be saved in IComputationGraph::SaveGraphState() and restored in IComputationGraph::LoadGraphState().
};
-class THolderFactory;
-
-// Do not reorder: used in LLVM!
-struct TComputationContextLLVM {
+class THolderFactory;
+
+// Do not reorder: used in LLVM!
+struct TComputationContextLLVM {
const THolderFactory& HolderFactory;
- IStatsRegistry *const Stats;
- const std::unique_ptr<NUdf::TUnboxedValue[]> MutableValues;
- const NUdf::IValueBuilder *const Builder;
- float UsageAdjustor = 1.f;
- ui32 RssCounter = 0U;
- const NUdf::TSourcePosition* CalleePosition = nullptr;
-};
-
-struct TComputationContext : public TComputationContextLLVM {
+ IStatsRegistry *const Stats;
+ const std::unique_ptr<NUdf::TUnboxedValue[]> MutableValues;
+ const NUdf::IValueBuilder *const Builder;
+ float UsageAdjustor = 1.f;
+ ui32 RssCounter = 0U;
+ const NUdf::TSourcePosition* CalleePosition = nullptr;
+};
+
+struct TComputationContext : public TComputationContextLLVM {
IRandomProvider& RandomProvider;
ITimeProvider& TimeProvider;
- bool ExecuteLLVM = true;
+ bool ExecuteLLVM = true;
arrow::MemoryPool& ArrowMemoryPool;
TComputationContext(const THolderFactory& holderFactory,
@@ -94,12 +94,12 @@ struct TComputationContext : public TComputationContextLLVM {
// Returns true if current usage delta exceeds the memory limit
// The function automatically adjusts memory limit taking into account RSS delta between calls
template<bool TrackRss>
- inline bool CheckAdjustedMemLimit(ui64 memLimit, ui64 initMemUsage);
+ inline bool CheckAdjustedMemLimit(ui64 memLimit, ui64 initMemUsage);
- void UpdateUsageAdjustor(ui64 memLimit);
+ void UpdateUsageAdjustor(ui64 memLimit);
private:
- ui64 InitRss = 0ULL;
- ui64 LastRss = 0ULL;
+ ui64 InitRss = 0ULL;
+ ui64 LastRss = 0ULL;
#ifndef NDEBUG
TInstant LastPrintUsage;
#endif
@@ -107,33 +107,33 @@ private:
class IComputationNode {
public:
- typedef TIntrusivePtr<IComputationNode> TPtr;
- typedef std::map<ui32, EValueRepresentation> TIndexesMap;
-
+ typedef TIntrusivePtr<IComputationNode> TPtr;
+ typedef std::map<ui32, EValueRepresentation> TIndexesMap;
+
virtual ~IComputationNode() {}
virtual void InitNode(TComputationContext&) const = 0;
virtual NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const = 0;
-
- virtual IComputationNode* AddDependence(const IComputationNode* node) = 0;
-
- virtual const IComputationNode* GetSource() const = 0;
-
- virtual void RegisterDependencies() const = 0;
-
- virtual ui32 GetIndex() const = 0;
- virtual void CollectDependentIndexes(const IComputationNode* owner, TIndexesMap& dependencies) const = 0;
- virtual ui32 GetDependencyWeight() const = 0;
- virtual ui32 GetDependencesCount() const = 0;
-
- virtual bool IsTemporaryValue() const = 0;
-
- virtual EValueRepresentation GetRepresentation() const = 0;
-
- virtual void PrepareStageOne() = 0;
- virtual void PrepareStageTwo() = 0;
-
+
+ virtual IComputationNode* AddDependence(const IComputationNode* node) = 0;
+
+ virtual const IComputationNode* GetSource() const = 0;
+
+ virtual void RegisterDependencies() const = 0;
+
+ virtual ui32 GetIndex() const = 0;
+ virtual void CollectDependentIndexes(const IComputationNode* owner, TIndexesMap& dependencies) const = 0;
+ virtual ui32 GetDependencyWeight() const = 0;
+ virtual ui32 GetDependencesCount() const = 0;
+
+ virtual bool IsTemporaryValue() const = 0;
+
+ virtual EValueRepresentation GetRepresentation() const = 0;
+
+ virtual void PrepareStageOne() = 0;
+ virtual void PrepareStageTwo() = 0;
+
virtual TString DebugString() const = 0;
virtual void Ref() = 0;
@@ -141,63 +141,63 @@ public:
virtual ui32 RefCount() const = 0;
};
-class IComputationExternalNode : public IComputationNode {
-public:
- virtual NUdf::TUnboxedValue& RefValue(TComputationContext& compCtx) const = 0;
- virtual void SetValue(TComputationContext& compCtx, NUdf::TUnboxedValue&& newValue) const = 0;
- virtual void SetOwner(const IComputationNode* node) = 0;
-
- using TGetter = std::function<NUdf::TUnboxedValue(TComputationContext&)>;
- virtual void SetGetter(TGetter&& getter) = 0;
- virtual void InvalidateValue(TComputationContext& compCtx) const = 0;
-};
-
-enum class EFetchResult : i32 {
- Finish = -1,
- Yield = 0,
- One = 1
-};
-
-class IComputationWideFlowNode : public IComputationNode {
-public:
- virtual EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const = 0;
-};
-
-class IComputationWideFlowProxyNode : public IComputationWideFlowNode {
-public:
- using TFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*const*)>;
- virtual void SetFetcher(TFetcher&& fetcher) = 0;
- virtual void SetOwner(const IComputationNode* node) = 0;
- virtual void InvalidateValue(TComputationContext& compCtx) const = 0;
-};
-
-using TComputationNodePtrVector = std::vector<IComputationNode*, TMKQLAllocator<IComputationNode*>>;
-using TComputationWideFlowNodePtrVector = std::vector<IComputationWideFlowNode*, TMKQLAllocator<IComputationWideFlowNode*>>;
-using TComputationExternalNodePtrVector = std::vector<IComputationExternalNode*, TMKQLAllocator<IComputationExternalNode*>>;
-using TConstComputationNodePtrVector = std::vector<const IComputationNode*, TMKQLAllocator<const IComputationNode*>>;
-using TComputationNodePtrDeque = std::deque<IComputationNode::TPtr, TMKQLAllocator<IComputationNode::TPtr>>;
-using TComputationNodeOnNodeMap = std::unordered_map<const IComputationNode*, IComputationNode*, std::hash<const IComputationNode*>, std::equal_to<const IComputationNode*>, TMKQLAllocator<std::pair<const IComputationNode *const, IComputationNode*>>>;
-
+class IComputationExternalNode : public IComputationNode {
+public:
+ virtual NUdf::TUnboxedValue& RefValue(TComputationContext& compCtx) const = 0;
+ virtual void SetValue(TComputationContext& compCtx, NUdf::TUnboxedValue&& newValue) const = 0;
+ virtual void SetOwner(const IComputationNode* node) = 0;
+
+ using TGetter = std::function<NUdf::TUnboxedValue(TComputationContext&)>;
+ virtual void SetGetter(TGetter&& getter) = 0;
+ virtual void InvalidateValue(TComputationContext& compCtx) const = 0;
+};
+
+enum class EFetchResult : i32 {
+ Finish = -1,
+ Yield = 0,
+ One = 1
+};
+
+class IComputationWideFlowNode : public IComputationNode {
+public:
+ virtual EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const = 0;
+};
+
+class IComputationWideFlowProxyNode : public IComputationWideFlowNode {
+public:
+ using TFetcher = std::function<EFetchResult(TComputationContext&, NUdf::TUnboxedValue*const*)>;
+ virtual void SetFetcher(TFetcher&& fetcher) = 0;
+ virtual void SetOwner(const IComputationNode* node) = 0;
+ virtual void InvalidateValue(TComputationContext& compCtx) const = 0;
+};
+
+using TComputationNodePtrVector = std::vector<IComputationNode*, TMKQLAllocator<IComputationNode*>>;
+using TComputationWideFlowNodePtrVector = std::vector<IComputationWideFlowNode*, TMKQLAllocator<IComputationWideFlowNode*>>;
+using TComputationExternalNodePtrVector = std::vector<IComputationExternalNode*, TMKQLAllocator<IComputationExternalNode*>>;
+using TConstComputationNodePtrVector = std::vector<const IComputationNode*, TMKQLAllocator<const IComputationNode*>>;
+using TComputationNodePtrDeque = std::deque<IComputationNode::TPtr, TMKQLAllocator<IComputationNode::TPtr>>;
+using TComputationNodeOnNodeMap = std::unordered_map<const IComputationNode*, IComputationNode*, std::hash<const IComputationNode*>, std::equal_to<const IComputationNode*>, TMKQLAllocator<std::pair<const IComputationNode *const, IComputationNode*>>>;
+
class IComputationGraph {
public:
virtual ~IComputationGraph() {}
virtual void Prepare() = 0;
- virtual NUdf::TUnboxedValue GetValue() = 0;
+ virtual NUdf::TUnboxedValue GetValue() = 0;
virtual TComputationContext& GetContext() = 0;
- virtual IComputationExternalNode* GetEntryPoint(size_t index, bool require) = 0;
- virtual const TComputationNodePtrDeque& GetNodes() const = 0;
+ virtual IComputationExternalNode* GetEntryPoint(size_t index, bool require) = 0;
+ virtual const TComputationNodePtrDeque& GetNodes() const = 0;
virtual void Invalidate() = 0;
virtual TMemoryUsageInfo& GetMemInfo() const = 0;
virtual const THolderFactory& GetHolderFactory() const = 0;
- virtual ITerminator* GetTerminator() const = 0;
- virtual bool SetExecuteLLVM(bool value) = 0;
+ virtual ITerminator* GetTerminator() const = 0;
+ virtual bool SetExecuteLLVM(bool value) = 0;
virtual TString SaveGraphState() = 0;
virtual void LoadGraphState(TStringBuf state) = 0;
};
class TNodeFactory;
-typedef std::function<IComputationNode* (TNode* node, bool pop)> TNodeLocator;
-typedef std::function<void (IComputationNode*)> TNodePushBack;
+typedef std::function<IComputationNode* (TNode* node, bool pop)> TNodeLocator;
+typedef std::function<void (IComputationNode*)> TNodePushBack;
struct TComputationNodeFactoryContext {
TNodeLocator NodeLocator;
@@ -208,13 +208,13 @@ struct TComputationNodeFactoryContext {
const NUdf::ISecureParamsProvider* SecureParamsProvider;
const TNodeFactory& NodeFactory;
const THolderFactory& HolderFactory;
- const NUdf::IValueBuilder *const Builder;
+ const NUdf::IValueBuilder *const Builder;
NUdf::EValidateMode ValidateMode;
NUdf::EValidatePolicy ValidatePolicy;
EGraphPerProcess GraphPerProcess;
TComputationMutables& Mutables;
- TComputationNodeOnNodeMap& ElementsCache;
- const TNodePushBack NodePushBack;
+ TComputationNodeOnNodeMap& ElementsCache;
+ const TNodePushBack NodePushBack;
TComputationNodeFactoryContext(
const TNodeLocator& nodeLocator,
@@ -225,13 +225,13 @@ struct TComputationNodeFactoryContext {
const NUdf::ISecureParamsProvider* secureParamsProvider,
const TNodeFactory& nodeFactory,
const THolderFactory& holderFactory,
- const NUdf::IValueBuilder* builder,
+ const NUdf::IValueBuilder* builder,
NUdf::EValidateMode validateMode,
NUdf::EValidatePolicy validatePolicy,
EGraphPerProcess graphPerProcess,
- TComputationMutables& mutables,
- TComputationNodeOnNodeMap& elementsCache,
- TNodePushBack&& nodePushBack
+ TComputationMutables& mutables,
+ TComputationNodeOnNodeMap& elementsCache,
+ TNodePushBack&& nodePushBack
)
: NodeLocator(nodeLocator)
, FunctionRegistry(functionRegistry)
@@ -241,18 +241,18 @@ struct TComputationNodeFactoryContext {
, SecureParamsProvider(secureParamsProvider)
, NodeFactory(nodeFactory)
, HolderFactory(holderFactory)
- , Builder(builder)
+ , Builder(builder)
, ValidateMode(validateMode)
, ValidatePolicy(validatePolicy)
, GraphPerProcess(graphPerProcess)
, Mutables(mutables)
- , ElementsCache(elementsCache)
- , NodePushBack(std::move(nodePushBack))
+ , ElementsCache(elementsCache)
+ , NodePushBack(std::move(nodePushBack))
{}
};
using TComputationNodeFactory = std::function<IComputationNode* (TCallable&, const TComputationNodeFactoryContext&)>;
-using TStreamEmitter = std::function<void(NUdf::TUnboxedValue&&)>;
+using TStreamEmitter = std::function<void(NUdf::TUnboxedValue&&)>;
struct TComputationPatternOpts {
TComputationPatternOpts(const std::shared_ptr<TInjectedAlloc>& cacheAlloc, const std::shared_ptr<TTypeEnvironment>& cacheEnv)
@@ -274,7 +274,7 @@ struct TComputationPatternOpts {
const IFunctionRegistry* functionRegistry,
NUdf::EValidateMode validateMode,
NUdf::EValidatePolicy validatePolicy,
- const TString& optLLVM,
+ const TString& optLLVM,
EGraphPerProcess graphPerProcess,
IStatsRegistry* stats = nullptr,
NUdf::ICountersProvider* countersProvider = nullptr)
@@ -284,7 +284,7 @@ struct TComputationPatternOpts {
, FunctionRegistry(functionRegistry)
, ValidateMode(validateMode)
, ValidatePolicy(validatePolicy)
- , OptLLVM(optLLVM)
+ , OptLLVM(optLLVM)
, GraphPerProcess(graphPerProcess)
, Stats(stats)
, CountersProvider(countersProvider)
@@ -298,7 +298,7 @@ struct TComputationPatternOpts {
FunctionRegistry = functionRegistry;
ValidateMode = validateMode;
ValidatePolicy = validatePolicy;
- OptLLVM = optLLVM;
+ OptLLVM = optLLVM;
GraphPerProcess = graphPerProcess;
Stats = stats;
CountersProvider = counters;
@@ -314,7 +314,7 @@ struct TComputationPatternOpts {
const IFunctionRegistry* FunctionRegistry = nullptr;
NUdf::EValidateMode ValidateMode = NUdf::EValidateMode::None;
NUdf::EValidatePolicy ValidatePolicy = NUdf::EValidatePolicy::Fail;
- TString OptLLVM;
+ TString OptLLVM;
EGraphPerProcess GraphPerProcess = EGraphPerProcess::Multi;
IStatsRegistry* Stats = nullptr;
NUdf::ICountersProvider* CountersProvider = nullptr;
@@ -339,7 +339,7 @@ IComputationPattern::TPtr MakeComputationPattern(
TExploringNodeVisitor& explorer,
const TRuntimeNode& root,
const std::vector<TNode*>& entryPoints,
- const TComputationPatternOpts& opts);
+ const TComputationPatternOpts& opts);
class IComputationPatternCache {
public:
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.cpp
index 1bd996ed44..563f820bf6 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.cpp
@@ -1,1817 +1,1817 @@
-#include "mkql_computation_node_codegen.h"
-#include "mkql_computation_node_holders.h"
-
+#include "mkql_computation_node_codegen.h"
+#include "mkql_computation_node_holders.h"
+
#include <ydb/library/yql/minikql/codegen/codegen.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
-
+
#include <util/string/cast.h>
-#ifndef MKQL_DISABLE_CODEGEN
-
-extern "C" void DeleteBoxed(NKikimr::NUdf::IBoxedValue *const boxed) {
- delete boxed;
-}
-
+#ifndef MKQL_DISABLE_CODEGEN
+
+extern "C" void DeleteBoxed(NKikimr::NUdf::IBoxedValue *const boxed) {
+ delete boxed;
+}
+
extern "C" void DeleteString(void* strData) {
auto& str = *(NKikimr::NUdf::TStringValue*)(&strData);
UdfFreeWithSize(strData, 16 + str.Capacity());
}
-namespace NKikimr {
-namespace NMiniKQL {
-
-constexpr bool EnableStaticRefcount = true;
-
-size_t GetMethodPtrIndex(uintptr_t ptr)
-{
-#ifdef _win_
- Y_ENSURE(memcmp((void*)ptr, "\x48\x8B\x01\xFF", 4) == 0);
- size_t offset;
- if (*(ui8*)(ptr + 4) == 0x60) {
- offset = *(ui8*)(ptr + 5);
- }
- else if (*(ui8*)(ptr + 4) == 0xa0) {
- offset = *(ui32*)(ptr + 5);
- }
- else {
- ythrow yexception() << "Unsupported code";
- }
-
- return offset / 8;
-#else
- return ptr >> 3;
-#endif
-}
-
-using namespace llvm;
-
-Type* GetCompContextType(LLVMContext &context) {
- const auto ptrValueType = PointerType::getUnqual(Type::getInt128Ty(context));
- const auto structPtrType = PointerType::getUnqual(StructType::get(context));
- const auto stringRefType = StructType::get(context, {
- Type::getInt8PtrTy(context),
- Type::getInt32Ty(context),
- Type::getInt32Ty(context)
- });
- const auto sourcePosType = StructType::get(context, {
- Type::getInt32Ty(context),
- Type::getInt32Ty(context),
- stringRefType
- });
- return StructType::get(context, {
- structPtrType, // factory
- structPtrType, // stats
- ptrValueType, // mutables
- structPtrType, // builder
- Type::getFloatTy(context), // ddjustor
- Type::getInt32Ty(context), // rsscounter
- PointerType::getUnqual(sourcePosType)
- });
-}
-
-Value* TCodegenContext::GetFactory() const {
- if (!Factory) {
- const auto indexType = Type::getInt32Ty(Codegen->GetContext());
- if (Func->getEntryBlock().empty()) {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "factory_ptr", &Func->getEntryBlock());
- const_cast<Value*&>(Factory) = new LoadInst(ptr, "factory", &Func->getEntryBlock());
- } else {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "factory_ptr", &Func->getEntryBlock().front());
- const_cast<Value*&>(Factory) = new LoadInst(ptr, "factory", &Func->getEntryBlock().back());
- }
- }
- return Factory;
-}
-
-Value* TCodegenContext::GetStat() const {
- if (!Stat) {
- const auto indexType = Type::getInt32Ty(Codegen->GetContext());
- if (Func->getEntryBlock().empty()) {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "stat_ptr", &Func->getEntryBlock());
- const_cast<Value*&>(Stat) = new LoadInst(ptr, "stat", &Func->getEntryBlock());
- } else {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "stat_ptr", &Func->getEntryBlock().front());
- const_cast<Value*&>(Stat) = new LoadInst(ptr, "stat", &Func->getEntryBlock().back());
- }
- }
- return Stat;
-}
-
-Value* TCodegenContext::GetMutables() const {
- if (!Mutables) {
- const auto indexType = Type::getInt32Ty(Codegen->GetContext());
- if (Func->getEntryBlock().empty()) {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 2)}, "mutables_ptr", &Func->getEntryBlock());
- const_cast<Value*&>(Mutables) = new LoadInst(ptr, "mutables", &Func->getEntryBlock());
- } else {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 2)}, "mutables_ptr", &Func->getEntryBlock().front());
- const_cast<Value*&>(Mutables) = new LoadInst(ptr, "mutables", &Func->getEntryBlock().back());
- }
- }
- return Mutables;
-}
-
-Value* TCodegenContext::GetBuilder() const {
- if (!Builder) {
- const auto indexType = Type::getInt32Ty(Codegen->GetContext());
- if (Func->getEntryBlock().empty()) {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "builder_ptr", &Func->getEntryBlock());
- const_cast<Value*&>(Builder) = new LoadInst(ptr, "builder", &Func->getEntryBlock());
- } else {
- const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "builder_ptr", &Func->getEntryBlock().front());
- const_cast<Value*&>(Builder) = new LoadInst(ptr, "builder", &Func->getEntryBlock().back());
- }
- }
- return Builder;
-}
-
-Function* GenerateCompareFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare) {
- auto& module = codegen->GetModule();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto codegenLeft = dynamic_cast<ICodegeneratorExternalNode*>(left);
- const auto codegenRight = dynamic_cast<ICodegeneratorExternalNode*>(right);
- MKQL_ENSURE(codegenLeft, "Left must be codegenerator node.");
- MKQL_ENSURE(codegenRight, "Right must be codegenerator node.");
-
- auto& context = codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
- const auto returnType = Type::getInt1Ty(context);
- const auto contextType = GetCompContextType(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(returnType, {PointerType::getUnqual(contextType), valueType, valueType}, false):
- FunctionType::get(returnType, {PointerType::getUnqual(contextType), ptrType, ptrType}, false);
-
- TCodegenContext ctx(codegen);
- ctx.AlwaysInline = true;
+namespace NKikimr {
+namespace NMiniKQL {
+
+constexpr bool EnableStaticRefcount = true;
+
+size_t GetMethodPtrIndex(uintptr_t ptr)
+{
+#ifdef _win_
+ Y_ENSURE(memcmp((void*)ptr, "\x48\x8B\x01\xFF", 4) == 0);
+ size_t offset;
+ if (*(ui8*)(ptr + 4) == 0x60) {
+ offset = *(ui8*)(ptr + 5);
+ }
+ else if (*(ui8*)(ptr + 4) == 0xa0) {
+ offset = *(ui32*)(ptr + 5);
+ }
+ else {
+ ythrow yexception() << "Unsupported code";
+ }
+
+ return offset / 8;
+#else
+ return ptr >> 3;
+#endif
+}
+
+using namespace llvm;
+
+Type* GetCompContextType(LLVMContext &context) {
+ const auto ptrValueType = PointerType::getUnqual(Type::getInt128Ty(context));
+ const auto structPtrType = PointerType::getUnqual(StructType::get(context));
+ const auto stringRefType = StructType::get(context, {
+ Type::getInt8PtrTy(context),
+ Type::getInt32Ty(context),
+ Type::getInt32Ty(context)
+ });
+ const auto sourcePosType = StructType::get(context, {
+ Type::getInt32Ty(context),
+ Type::getInt32Ty(context),
+ stringRefType
+ });
+ return StructType::get(context, {
+ structPtrType, // factory
+ structPtrType, // stats
+ ptrValueType, // mutables
+ structPtrType, // builder
+ Type::getFloatTy(context), // ddjustor
+ Type::getInt32Ty(context), // rsscounter
+ PointerType::getUnqual(sourcePosType)
+ });
+}
+
+Value* TCodegenContext::GetFactory() const {
+ if (!Factory) {
+ const auto indexType = Type::getInt32Ty(Codegen->GetContext());
+ if (Func->getEntryBlock().empty()) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "factory_ptr", &Func->getEntryBlock());
+ const_cast<Value*&>(Factory) = new LoadInst(ptr, "factory", &Func->getEntryBlock());
+ } else {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 0)}, "factory_ptr", &Func->getEntryBlock().front());
+ const_cast<Value*&>(Factory) = new LoadInst(ptr, "factory", &Func->getEntryBlock().back());
+ }
+ }
+ return Factory;
+}
+
+Value* TCodegenContext::GetStat() const {
+ if (!Stat) {
+ const auto indexType = Type::getInt32Ty(Codegen->GetContext());
+ if (Func->getEntryBlock().empty()) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "stat_ptr", &Func->getEntryBlock());
+ const_cast<Value*&>(Stat) = new LoadInst(ptr, "stat", &Func->getEntryBlock());
+ } else {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 1)}, "stat_ptr", &Func->getEntryBlock().front());
+ const_cast<Value*&>(Stat) = new LoadInst(ptr, "stat", &Func->getEntryBlock().back());
+ }
+ }
+ return Stat;
+}
+
+Value* TCodegenContext::GetMutables() const {
+ if (!Mutables) {
+ const auto indexType = Type::getInt32Ty(Codegen->GetContext());
+ if (Func->getEntryBlock().empty()) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 2)}, "mutables_ptr", &Func->getEntryBlock());
+ const_cast<Value*&>(Mutables) = new LoadInst(ptr, "mutables", &Func->getEntryBlock());
+ } else {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 2)}, "mutables_ptr", &Func->getEntryBlock().front());
+ const_cast<Value*&>(Mutables) = new LoadInst(ptr, "mutables", &Func->getEntryBlock().back());
+ }
+ }
+ return Mutables;
+}
+
+Value* TCodegenContext::GetBuilder() const {
+ if (!Builder) {
+ const auto indexType = Type::getInt32Ty(Codegen->GetContext());
+ if (Func->getEntryBlock().empty()) {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "builder_ptr", &Func->getEntryBlock());
+ const_cast<Value*&>(Builder) = new LoadInst(ptr, "builder", &Func->getEntryBlock());
+ } else {
+ const auto ptr = GetElementPtrInst::CreateInBounds(Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 3)}, "builder_ptr", &Func->getEntryBlock().front());
+ const_cast<Value*&>(Builder) = new LoadInst(ptr, "builder", &Func->getEntryBlock().back());
+ }
+ }
+ return Builder;
+}
+
+Function* GenerateCompareFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, IComputationExternalNode* left, IComputationExternalNode* right, IComputationNode* compare) {
+ auto& module = codegen->GetModule();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto codegenLeft = dynamic_cast<ICodegeneratorExternalNode*>(left);
+ const auto codegenRight = dynamic_cast<ICodegeneratorExternalNode*>(right);
+ MKQL_ENSURE(codegenLeft, "Left must be codegenerator node.");
+ MKQL_ENSURE(codegenRight, "Right must be codegenerator node.");
+
+ auto& context = codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+ const auto returnType = Type::getInt1Ty(context);
+ const auto contextType = GetCompContextType(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(returnType, {PointerType::getUnqual(contextType), valueType, valueType}, false):
+ FunctionType::get(returnType, {PointerType::getUnqual(contextType), ptrType, ptrType}, false);
+
+ TCodegenContext ctx(codegen);
+ ctx.AlwaysInline = true;
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- ctx.Ctx = &*args;
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto lv = &*++args;
- const auto rv = &*++args;
-
- codegenLeft->SetTemporaryValue(lv);
- codegenRight->SetTemporaryValue(rv);
-
- codegenLeft->CreateInvalidate(ctx, block);
- codegenRight->CreateInvalidate(ctx, block);
-
- const auto res = GetNodeValue(compare, ctx, block);
- const auto cast = CastInst::Create(Instruction::Trunc, res, returnType, "bool", block);
- ReturnInst::Create(context, cast, block);
-
- codegenLeft->SetTemporaryValue(nullptr);
- codegenRight->SetTemporaryValue(nullptr);
-
- return ctx.Func;
-}
-
-Value* GetterFor(NUdf::EDataSlot slot, Value* value, LLVMContext &context, BasicBlock* block) {
- switch (slot) {
- case NUdf::EDataSlot::Bool: return GetterFor<bool>(value, context, block);
- case NUdf::EDataSlot::Decimal: return GetterForInt128(value, block);
- case NUdf::EDataSlot::Float: return GetterFor<float>(value, context, block);
- case NUdf::EDataSlot::Double: return GetterFor<double>(value, context, block);
- default: break;
- }
-
- const auto trunc = CastInst::Create(Instruction::Trunc, value, IntegerType::get(context, NUdf::GetDataTypeInfo(slot).FixedSize << 3U), "trunc", block);
- return trunc;
-}
-
-namespace {
-
-Value* GetMarkFromUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock* block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto type8 = Type::getInt8Ty(context);
- if (value->getType()->isPointerTy()) {
- const auto ptrType = PointerType::getUnqual(StructType::get(context, {PointerType::getUnqual(StructType::get(context)), ArrayType::get(type8, 8U)}));
- const auto cast = CastInst::Create(Instruction::BitCast, value, ptrType, "cast", block);
- const auto type32 = Type::getInt32Ty(context);
- const auto metaptr = GetElementPtrInst::CreateInBounds(cast, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1), ConstantInt::get(type32, 7)}, "metaptr", block);
- const auto meta = new LoadInst(metaptr, "meta", block);
- const auto mark = BinaryOperator::CreateAnd(meta, ConstantInt::get(meta->getType(), 3), "mark", block);
- return mark;
- } else {
- const auto lshr = BinaryOperator::CreateLShr(value, ConstantInt::get(value->getType(), 120), "lshr", block);
- const auto meta = CastInst::Create(Instruction::Trunc, lshr, type8, "meta", block);
- const auto mark = BinaryOperator::CreateAnd(ConstantInt::get(meta->getType(), 3), meta, "mark", block);
- return mark;
- }
-
-}
-
-template<bool BoxedOrString>
-Value* GetPointerFromUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock* block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto type32 = Type::getInt32Ty(context);
- const auto type64 = Type::getInt64Ty(context);
- const auto type = PointerType::getUnqual(BoxedOrString ?
- StructType::get(context, {PointerType::getUnqual(StructType::get(context)), type32, Type::getInt16Ty(context)}):
- StructType::get(context, {type32, type32, type32, type32})
- );
- if (value->getType()->isPointerTy()) {
- const auto ptrType = PointerType::getUnqual(StructType::get(context, {type, type64}));
- const auto cast = CastInst::Create(Instruction::BitCast, value, ptrType, "cast", block);
- const auto ptr = GetElementPtrInst::CreateInBounds(cast, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 0)}, "ptr", block);
- const auto pointer = new LoadInst(ptr, "pointer", block);
- return pointer;
- } else {
- const auto half = CastInst::Create(Instruction::Trunc, value, type64, "half", block);
- const auto pointer = CastInst::Create(Instruction::IntToPtr, half, type, "pointer", block);
- return pointer;
- }
-}
-
-bool MyEquteStrings(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) {
- return NUdf::EquateStrings(lhs, rhs);
-}
-
-NUdf::THashType MyHashString(NUdf::TUnboxedValuePod val) {
- return NUdf::GetStringHash(val);
-}
-
-template <bool IsOptional>
-Value* GenEqualsFunction(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block);
-
-template <>
-Value* GenEqualsFunction<false>(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto& info = NUdf::GetDataTypeInfo(slot);
-
- if ((info.Features & NUdf::EDataTypeFeatures::CommonType) && (info.Features & NUdf::EDataTypeFeatures::StringType || NUdf::EDataSlot::Uuid == slot || NUdf::EDataSlot::DyNumber == slot)) {
- return CallBinaryUnboxedValueFunction(&MyEquteStrings, Type::getInt1Ty(context), lv, rv, ctx.Codegen, block);
- }
-
- const auto lhs = GetterFor(slot, lv, context, block);
- const auto rhs = GetterFor(slot, rv, context, block);
-
- if (info.Features & (NUdf::EDataTypeFeatures::IntegralType | NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TimeIntervalType | NUdf::EDataTypeFeatures::DecimalType) || NUdf::EDataSlot::Bool == slot) {
- const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equal", block);
- return equal;
- }
-
- if (info.Features & NUdf::EDataTypeFeatures::FloatType) {
- const auto ueq = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UEQ, lhs, rhs, "equals", block);
- const auto lord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "lord", block);
- const auto runo = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "runo", block);
- const auto once = BinaryOperator::CreateXor(lord, runo, "xor", block);
- return BinaryOperator::CreateAnd(ueq, once, "and", block);
- }
-
- if (info.Features & NUdf::EDataTypeFeatures::TzDateType) {
- const auto ltz = GetterForTimezone(context, lv, block);
- const auto rtz = GetterForTimezone(context, rv, block);
-
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "one", block);
- const auto two = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, ltz, rtz, "two", block);
-
- return BinaryOperator::CreateAnd(one, two, "and", block);
- }
-
- return nullptr;
-}
-
-template <>
-Value* GenEqualsFunction<true>(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto tiny = BasicBlock::Create(context, "tiny", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto res = PHINode::Create(Type::getInt1Ty(context), 2U, "result", done);
-
- const auto le = IsEmpty(lv, block);
- const auto re = IsEmpty(rv, block);
-
- const auto any = BinaryOperator::CreateOr(le, re, "or", block);
-
- BranchInst::Create(tiny, test, any, block);
-
- block = tiny;
-
- const auto both = BinaryOperator::CreateAnd(le, re, "and", block);
- res->addIncoming(both, block);
- BranchInst::Create(done, block);
-
- block = test;
-
- const auto comp = GenEqualsFunction<false>(slot, lv, rv, ctx, block);
- res->addIncoming(comp, block);
- BranchInst::Create(done, block);
-
- block = done;
- return res;
-}
-
-Value* GenEqualsFunction(NUdf::EDataSlot slot, bool isOptional, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
- return isOptional ? GenEqualsFunction<true>(slot, lv, rv, ctx, block) : GenEqualsFunction<false>(slot, lv, rv, ctx, block);
-}
-
-Value* GenCombineHashes(Value* first, Value* second, BasicBlock* block) {
-// key += ~(key << 32);
- const auto x01 = BinaryOperator::CreateShl(first, ConstantInt::get(first->getType(), 32), "x01", block);
- const auto x02 = BinaryOperator::CreateXor(x01, ConstantInt::get(x01->getType(), ~0), "x02", block);
- const auto x03 = BinaryOperator::CreateAdd(x02, first, "x03", block);
-// key ^= (key >> 22);
- const auto x04 = BinaryOperator::CreateLShr(x03, ConstantInt::get(x03->getType(), 22), "x04", block);
- const auto x05 = BinaryOperator::CreateXor(x04, x03, "x05", block);
-// key += ~(key << 13);
- const auto x06 = BinaryOperator::CreateShl(x05, ConstantInt::get(x05->getType(), 13), "x06", block);
- const auto x07 = BinaryOperator::CreateXor(x06, ConstantInt::get(x06->getType(), ~0), "x07", block);
- const auto x08 = BinaryOperator::CreateAdd(x05, x07, "x08", block);
-// key ^= (key >> 8);
- const auto x09 = BinaryOperator::CreateLShr(x08, ConstantInt::get(x08->getType(), 8), "x09", block);
- const auto x10 = BinaryOperator::CreateXor(x08, x09, "x10", block);
-// key += (key << 3);
- const auto x11 = BinaryOperator::CreateShl(x10, ConstantInt::get(x10->getType(), 3), "x11", block);
- const auto x12 = BinaryOperator::CreateAdd(x10, x11, "x12", block);
-// key ^= (key >> 15);
- const auto x13 = BinaryOperator::CreateLShr(x12, ConstantInt::get(x12->getType(), 15), "x13", block);
- const auto x14 = BinaryOperator::CreateXor(x13, x12, "x14", block);
-// key += ~(key << 27);
- const auto x15 = BinaryOperator::CreateShl(x14, ConstantInt::get(x14->getType(), 27), "x15", block);
- const auto x16 = BinaryOperator::CreateXor(x15, ConstantInt::get(x15->getType(), ~0), "x16", block);
- const auto x17 = BinaryOperator::CreateAdd(x14, x16, "x17", block);
-// key ^= (key >> 31);
- const auto x18 = BinaryOperator::CreateLShr(x17, ConstantInt::get(x17->getType(), 31), "x18", block);
- const auto x19 = BinaryOperator::CreateXor(x17, x18, "x19", block);
-
- return BinaryOperator::CreateXor(x19, second, "both", block);
-}
-
-template <bool IsOptional>
-Value* GenHashFunction(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block);
-
-template <>
-Value* GenHashFunction<false>(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto& info = NUdf::GetDataTypeInfo(slot);
-
- if ((info.Features & NUdf::EDataTypeFeatures::CommonType) && (info.Features & NUdf::EDataTypeFeatures::StringType || NUdf::EDataSlot::Uuid == slot || NUdf::EDataSlot::DyNumber == slot)) {
- return CallUnaryUnboxedValueFunction(&MyHashString, Type::getInt64Ty(context), value, ctx.Codegen, block);
- }
-
- const auto val = GetterFor(slot, value, context, block);
- const auto hashType = Type::getInt64Ty(context);
-
- if (info.Features & (NUdf::EDataTypeFeatures::IntegralType | NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TimeIntervalType) || NUdf::EDataSlot::Bool == slot) {
- if (val->getType() == hashType) {
- return val;
- }
- const auto ext = CastInst::Create(Instruction::ZExt, val, hashType, "ext", block);
- return ext;
- }
-
- if (info.Features & NUdf::EDataTypeFeatures::FloatType) {
- const auto nan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, val, val, "nan", block);
- const auto zero = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OEQ, val, ConstantFP::get(val->getType(), 0), "zero", block);
- if (NUdf::EDataSlot::Float == slot) {
- const auto cast = CastInst::Create(Instruction::BitCast, val, Type::getInt32Ty(context), "cast", block);
- const auto ext = CastInst::Create(Instruction::ZExt, cast, hashType, "ext", block);
- const auto first = SelectInst::Create(nan, ConstantInt::get(hashType, ~0), ext, "first", block);
- const auto second = SelectInst::Create(zero, ConstantInt::get(hashType, 0), first, "second", block);
- return second;
- } else {
- const auto cast = CastInst::Create(Instruction::BitCast, val, hashType, "cast", block);
- const auto first = SelectInst::Create(nan, ConstantInt::get(hashType, ~0), cast, "first", block);
- const auto second = SelectInst::Create(zero, ConstantInt::get(hashType, 0), first, "second", block);
- return second;
- }
- }
-
- if (info.Features & NUdf::EDataTypeFeatures::TzDateType) {
- const auto tz = GetterForTimezone(context, value, block);
- const auto ext = val->getType() == hashType ? val : CastInst::Create(Instruction::ZExt, val, hashType, "ext", block);
- const auto etz = CastInst::Create(Instruction::ZExt, tz, hashType, "etz", block);
-
- return GenCombineHashes(ext, etz, block);
- }
-
- if (info.Features & NUdf::EDataTypeFeatures::DecimalType) {
- const auto low = CastInst::Create(Instruction::Trunc, val, hashType, "low", block);
- const auto lshr = BinaryOperator::CreateLShr(val, ConstantInt::get(val->getType(), 64), "lshr", block);
- const auto high = CastInst::Create(Instruction::Trunc, lshr, hashType, "high", block);
- return GenCombineHashes(low, high, block);
- }
-
- return nullptr;
-}
-
-template <>
-Value* GenHashFunction<true>(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto tiny = BasicBlock::Create(context, "tiny", ctx.Func);
- const auto test = BasicBlock::Create(context, "test", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto res = PHINode::Create(Type::getInt64Ty(context), 2U, "result", done);
-
- BranchInst::Create(tiny, test, IsEmpty(value, block), block);
-
- block = tiny;
-
- res->addIncoming(ConstantInt::get(Type::getInt64Ty(context), ~0ULL), block);
- BranchInst::Create(done, block);
-
- block = test;
-
- const auto comp = GenHashFunction<false>(slot, value, ctx, block);
- res->addIncoming(comp, block);
- BranchInst::Create(done, block);
-
- block = done;
- return res;
-}
-
-Value* GenHashFunction(NUdf::EDataSlot slot, bool isOptional, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
- return isOptional ? GenHashFunction<true>(slot, value, ctx, block) : GenHashFunction<false>(slot, value, ctx, block);
-}
-
-Value* LoadIfPointer(Value* value, BasicBlock* block) {
- return value->getType()->isPointerTy() ? new LoadInst(value, "load_value", block) : value;
-}
-
-}
-
-Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types) {
- auto& module = codegen->GetModule();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- auto& context = codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
- const auto returnType = Type::getInt1Ty(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(returnType, {valueType, valueType}, false):
- FunctionType::get(returnType, {ptrType, ptrType}, false);
-
- TCodegenContext ctx(codegen);
- ctx.AlwaysInline = true;
+
+ auto args = ctx.Func->arg_begin();
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ ctx.Ctx = &*args;
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto lv = &*++args;
+ const auto rv = &*++args;
+
+ codegenLeft->SetTemporaryValue(lv);
+ codegenRight->SetTemporaryValue(rv);
+
+ codegenLeft->CreateInvalidate(ctx, block);
+ codegenRight->CreateInvalidate(ctx, block);
+
+ const auto res = GetNodeValue(compare, ctx, block);
+ const auto cast = CastInst::Create(Instruction::Trunc, res, returnType, "bool", block);
+ ReturnInst::Create(context, cast, block);
+
+ codegenLeft->SetTemporaryValue(nullptr);
+ codegenRight->SetTemporaryValue(nullptr);
+
+ return ctx.Func;
+}
+
+Value* GetterFor(NUdf::EDataSlot slot, Value* value, LLVMContext &context, BasicBlock* block) {
+ switch (slot) {
+ case NUdf::EDataSlot::Bool: return GetterFor<bool>(value, context, block);
+ case NUdf::EDataSlot::Decimal: return GetterForInt128(value, block);
+ case NUdf::EDataSlot::Float: return GetterFor<float>(value, context, block);
+ case NUdf::EDataSlot::Double: return GetterFor<double>(value, context, block);
+ default: break;
+ }
+
+ const auto trunc = CastInst::Create(Instruction::Trunc, value, IntegerType::get(context, NUdf::GetDataTypeInfo(slot).FixedSize << 3U), "trunc", block);
+ return trunc;
+}
+
+namespace {
+
+Value* GetMarkFromUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock* block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto type8 = Type::getInt8Ty(context);
+ if (value->getType()->isPointerTy()) {
+ const auto ptrType = PointerType::getUnqual(StructType::get(context, {PointerType::getUnqual(StructType::get(context)), ArrayType::get(type8, 8U)}));
+ const auto cast = CastInst::Create(Instruction::BitCast, value, ptrType, "cast", block);
+ const auto type32 = Type::getInt32Ty(context);
+ const auto metaptr = GetElementPtrInst::CreateInBounds(cast, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1), ConstantInt::get(type32, 7)}, "metaptr", block);
+ const auto meta = new LoadInst(metaptr, "meta", block);
+ const auto mark = BinaryOperator::CreateAnd(meta, ConstantInt::get(meta->getType(), 3), "mark", block);
+ return mark;
+ } else {
+ const auto lshr = BinaryOperator::CreateLShr(value, ConstantInt::get(value->getType(), 120), "lshr", block);
+ const auto meta = CastInst::Create(Instruction::Trunc, lshr, type8, "meta", block);
+ const auto mark = BinaryOperator::CreateAnd(ConstantInt::get(meta->getType(), 3), meta, "mark", block);
+ return mark;
+ }
+
+}
+
+template<bool BoxedOrString>
+Value* GetPointerFromUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock* block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto type32 = Type::getInt32Ty(context);
+ const auto type64 = Type::getInt64Ty(context);
+ const auto type = PointerType::getUnqual(BoxedOrString ?
+ StructType::get(context, {PointerType::getUnqual(StructType::get(context)), type32, Type::getInt16Ty(context)}):
+ StructType::get(context, {type32, type32, type32, type32})
+ );
+ if (value->getType()->isPointerTy()) {
+ const auto ptrType = PointerType::getUnqual(StructType::get(context, {type, type64}));
+ const auto cast = CastInst::Create(Instruction::BitCast, value, ptrType, "cast", block);
+ const auto ptr = GetElementPtrInst::CreateInBounds(cast, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 0)}, "ptr", block);
+ const auto pointer = new LoadInst(ptr, "pointer", block);
+ return pointer;
+ } else {
+ const auto half = CastInst::Create(Instruction::Trunc, value, type64, "half", block);
+ const auto pointer = CastInst::Create(Instruction::IntToPtr, half, type, "pointer", block);
+ return pointer;
+ }
+}
+
+bool MyEquteStrings(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) {
+ return NUdf::EquateStrings(lhs, rhs);
+}
+
+NUdf::THashType MyHashString(NUdf::TUnboxedValuePod val) {
+ return NUdf::GetStringHash(val);
+}
+
+template <bool IsOptional>
+Value* GenEqualsFunction(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block);
+
+template <>
+Value* GenEqualsFunction<false>(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto& info = NUdf::GetDataTypeInfo(slot);
+
+ if ((info.Features & NUdf::EDataTypeFeatures::CommonType) && (info.Features & NUdf::EDataTypeFeatures::StringType || NUdf::EDataSlot::Uuid == slot || NUdf::EDataSlot::DyNumber == slot)) {
+ return CallBinaryUnboxedValueFunction(&MyEquteStrings, Type::getInt1Ty(context), lv, rv, ctx.Codegen, block);
+ }
+
+ const auto lhs = GetterFor(slot, lv, context, block);
+ const auto rhs = GetterFor(slot, rv, context, block);
+
+ if (info.Features & (NUdf::EDataTypeFeatures::IntegralType | NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TimeIntervalType | NUdf::EDataTypeFeatures::DecimalType) || NUdf::EDataSlot::Bool == slot) {
+ const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equal", block);
+ return equal;
+ }
+
+ if (info.Features & NUdf::EDataTypeFeatures::FloatType) {
+ const auto ueq = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UEQ, lhs, rhs, "equals", block);
+ const auto lord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "lord", block);
+ const auto runo = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "runo", block);
+ const auto once = BinaryOperator::CreateXor(lord, runo, "xor", block);
+ return BinaryOperator::CreateAnd(ueq, once, "and", block);
+ }
+
+ if (info.Features & NUdf::EDataTypeFeatures::TzDateType) {
+ const auto ltz = GetterForTimezone(context, lv, block);
+ const auto rtz = GetterForTimezone(context, rv, block);
+
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "one", block);
+ const auto two = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, ltz, rtz, "two", block);
+
+ return BinaryOperator::CreateAnd(one, two, "and", block);
+ }
+
+ return nullptr;
+}
+
+template <>
+Value* GenEqualsFunction<true>(NUdf::EDataSlot slot, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto tiny = BasicBlock::Create(context, "tiny", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto res = PHINode::Create(Type::getInt1Ty(context), 2U, "result", done);
+
+ const auto le = IsEmpty(lv, block);
+ const auto re = IsEmpty(rv, block);
+
+ const auto any = BinaryOperator::CreateOr(le, re, "or", block);
+
+ BranchInst::Create(tiny, test, any, block);
+
+ block = tiny;
+
+ const auto both = BinaryOperator::CreateAnd(le, re, "and", block);
+ res->addIncoming(both, block);
+ BranchInst::Create(done, block);
+
+ block = test;
+
+ const auto comp = GenEqualsFunction<false>(slot, lv, rv, ctx, block);
+ res->addIncoming(comp, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return res;
+}
+
+Value* GenEqualsFunction(NUdf::EDataSlot slot, bool isOptional, Value* lv, Value* rv, TCodegenContext& ctx, BasicBlock*& block) {
+ return isOptional ? GenEqualsFunction<true>(slot, lv, rv, ctx, block) : GenEqualsFunction<false>(slot, lv, rv, ctx, block);
+}
+
+Value* GenCombineHashes(Value* first, Value* second, BasicBlock* block) {
+// key += ~(key << 32);
+ const auto x01 = BinaryOperator::CreateShl(first, ConstantInt::get(first->getType(), 32), "x01", block);
+ const auto x02 = BinaryOperator::CreateXor(x01, ConstantInt::get(x01->getType(), ~0), "x02", block);
+ const auto x03 = BinaryOperator::CreateAdd(x02, first, "x03", block);
+// key ^= (key >> 22);
+ const auto x04 = BinaryOperator::CreateLShr(x03, ConstantInt::get(x03->getType(), 22), "x04", block);
+ const auto x05 = BinaryOperator::CreateXor(x04, x03, "x05", block);
+// key += ~(key << 13);
+ const auto x06 = BinaryOperator::CreateShl(x05, ConstantInt::get(x05->getType(), 13), "x06", block);
+ const auto x07 = BinaryOperator::CreateXor(x06, ConstantInt::get(x06->getType(), ~0), "x07", block);
+ const auto x08 = BinaryOperator::CreateAdd(x05, x07, "x08", block);
+// key ^= (key >> 8);
+ const auto x09 = BinaryOperator::CreateLShr(x08, ConstantInt::get(x08->getType(), 8), "x09", block);
+ const auto x10 = BinaryOperator::CreateXor(x08, x09, "x10", block);
+// key += (key << 3);
+ const auto x11 = BinaryOperator::CreateShl(x10, ConstantInt::get(x10->getType(), 3), "x11", block);
+ const auto x12 = BinaryOperator::CreateAdd(x10, x11, "x12", block);
+// key ^= (key >> 15);
+ const auto x13 = BinaryOperator::CreateLShr(x12, ConstantInt::get(x12->getType(), 15), "x13", block);
+ const auto x14 = BinaryOperator::CreateXor(x13, x12, "x14", block);
+// key += ~(key << 27);
+ const auto x15 = BinaryOperator::CreateShl(x14, ConstantInt::get(x14->getType(), 27), "x15", block);
+ const auto x16 = BinaryOperator::CreateXor(x15, ConstantInt::get(x15->getType(), ~0), "x16", block);
+ const auto x17 = BinaryOperator::CreateAdd(x14, x16, "x17", block);
+// key ^= (key >> 31);
+ const auto x18 = BinaryOperator::CreateLShr(x17, ConstantInt::get(x17->getType(), 31), "x18", block);
+ const auto x19 = BinaryOperator::CreateXor(x17, x18, "x19", block);
+
+ return BinaryOperator::CreateXor(x19, second, "both", block);
+}
+
+template <bool IsOptional>
+Value* GenHashFunction(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block);
+
+template <>
+Value* GenHashFunction<false>(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto& info = NUdf::GetDataTypeInfo(slot);
+
+ if ((info.Features & NUdf::EDataTypeFeatures::CommonType) && (info.Features & NUdf::EDataTypeFeatures::StringType || NUdf::EDataSlot::Uuid == slot || NUdf::EDataSlot::DyNumber == slot)) {
+ return CallUnaryUnboxedValueFunction(&MyHashString, Type::getInt64Ty(context), value, ctx.Codegen, block);
+ }
+
+ const auto val = GetterFor(slot, value, context, block);
+ const auto hashType = Type::getInt64Ty(context);
+
+ if (info.Features & (NUdf::EDataTypeFeatures::IntegralType | NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TimeIntervalType) || NUdf::EDataSlot::Bool == slot) {
+ if (val->getType() == hashType) {
+ return val;
+ }
+ const auto ext = CastInst::Create(Instruction::ZExt, val, hashType, "ext", block);
+ return ext;
+ }
+
+ if (info.Features & NUdf::EDataTypeFeatures::FloatType) {
+ const auto nan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, val, val, "nan", block);
+ const auto zero = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OEQ, val, ConstantFP::get(val->getType(), 0), "zero", block);
+ if (NUdf::EDataSlot::Float == slot) {
+ const auto cast = CastInst::Create(Instruction::BitCast, val, Type::getInt32Ty(context), "cast", block);
+ const auto ext = CastInst::Create(Instruction::ZExt, cast, hashType, "ext", block);
+ const auto first = SelectInst::Create(nan, ConstantInt::get(hashType, ~0), ext, "first", block);
+ const auto second = SelectInst::Create(zero, ConstantInt::get(hashType, 0), first, "second", block);
+ return second;
+ } else {
+ const auto cast = CastInst::Create(Instruction::BitCast, val, hashType, "cast", block);
+ const auto first = SelectInst::Create(nan, ConstantInt::get(hashType, ~0), cast, "first", block);
+ const auto second = SelectInst::Create(zero, ConstantInt::get(hashType, 0), first, "second", block);
+ return second;
+ }
+ }
+
+ if (info.Features & NUdf::EDataTypeFeatures::TzDateType) {
+ const auto tz = GetterForTimezone(context, value, block);
+ const auto ext = val->getType() == hashType ? val : CastInst::Create(Instruction::ZExt, val, hashType, "ext", block);
+ const auto etz = CastInst::Create(Instruction::ZExt, tz, hashType, "etz", block);
+
+ return GenCombineHashes(ext, etz, block);
+ }
+
+ if (info.Features & NUdf::EDataTypeFeatures::DecimalType) {
+ const auto low = CastInst::Create(Instruction::Trunc, val, hashType, "low", block);
+ const auto lshr = BinaryOperator::CreateLShr(val, ConstantInt::get(val->getType(), 64), "lshr", block);
+ const auto high = CastInst::Create(Instruction::Trunc, lshr, hashType, "high", block);
+ return GenCombineHashes(low, high, block);
+ }
+
+ return nullptr;
+}
+
+template <>
+Value* GenHashFunction<true>(NUdf::EDataSlot slot, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto tiny = BasicBlock::Create(context, "tiny", ctx.Func);
+ const auto test = BasicBlock::Create(context, "test", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto res = PHINode::Create(Type::getInt64Ty(context), 2U, "result", done);
+
+ BranchInst::Create(tiny, test, IsEmpty(value, block), block);
+
+ block = tiny;
+
+ res->addIncoming(ConstantInt::get(Type::getInt64Ty(context), ~0ULL), block);
+ BranchInst::Create(done, block);
+
+ block = test;
+
+ const auto comp = GenHashFunction<false>(slot, value, ctx, block);
+ res->addIncoming(comp, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return res;
+}
+
+Value* GenHashFunction(NUdf::EDataSlot slot, bool isOptional, Value* value, TCodegenContext& ctx, BasicBlock*& block) {
+ return isOptional ? GenHashFunction<true>(slot, value, ctx, block) : GenHashFunction<false>(slot, value, ctx, block);
+}
+
+Value* LoadIfPointer(Value* value, BasicBlock* block) {
+ return value->getType()->isPointerTy() ? new LoadInst(value, "load_value", block) : value;
+}
+
+}
+
+Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types) {
+ auto& module = codegen->GetModule();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ auto& context = codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+ const auto returnType = Type::getInt1Ty(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(returnType, {valueType, valueType}, false):
+ FunctionType::get(returnType, {ptrType, ptrType}, false);
+
+ TCodegenContext ctx(codegen);
+ ctx.AlwaysInline = true;
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto lv = LoadIfPointer(&*args, block);
- const auto rv = LoadIfPointer(&*++args, block);
-
- if (isTuple) {
- if (types.empty()) {
- ReturnInst::Create(context, ConstantInt::getTrue(context), block);
- return ctx.Func;
- }
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
-
- const auto elementsType = PointerType::getUnqual(ArrayType::get(valueType, types.size()));
- const auto elementsPtrOne = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, lv, ctx.Codegen, block);
- const auto elementsPtrTwo = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, rv, ctx.Codegen, block);
-
- const auto goodOne = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elementsPtrOne, ConstantPointerNull::get(elementsType), "good_one", block);
- const auto goodTwo = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elementsPtrTwo, ConstantPointerNull::get(elementsType), "good_two", block);
- const auto good = BinaryOperator::CreateAnd(goodOne, goodTwo, "good", block);
-
- BranchInst::Create(fast, slow, good, block);
-
- const auto last = types.size() - 1U;
-
- {
- block = fast;
-
- const auto elementsOne = new LoadInst(elementsPtrOne, "elements_one", block);
- const auto elementsTwo = new LoadInst(elementsPtrTwo, "elements_two", block);
-
- for (ui32 i = 0U; i < last; ++i) {
- const auto nextOne = ExtractValueInst::Create(elementsOne, i, (TString("next_one_") += ToString(i)).c_str(), block);
- const auto nextTwo = ExtractValueInst::Create(elementsTwo, i, (TString("next_two_") += ToString(i)).c_str(), block);
-
- const auto step = BasicBlock::Create(context, (TString("step") += ToString(i)).c_str(), ctx.Func);
-
- const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
-
- BranchInst::Create(step, stop, test, block);
-
- block = step;
- }
-
- const auto backOne = ExtractValueInst::Create(elementsOne, last, "back_one", block);
- const auto backTwo = ExtractValueInst::Create(elementsTwo, last, "back_two", block);
-
- const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
- ReturnInst::Create(context, result, block);
- }
-
- {
- block = slow;
-
- const auto elementOne = new AllocaInst(valueType, 0U, "element_one", block);
- const auto elementTwo = new AllocaInst(valueType, 0U, "element_two", block);
-
- const auto indexType = Type::getInt32Ty(context);
-
- for (ui32 i = 0U; i < last; ++i) {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementOne, lv, ctx.Codegen, block, ConstantInt::get(indexType, i));
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementTwo, rv, ctx.Codegen, block, ConstantInt::get(indexType, i));
-
- const auto nextOne = new LoadInst(elementOne, (TString("next_one_") += ToString(i)).c_str(), block);
- const auto nextTwo = new LoadInst(elementTwo, (TString("next_two_") += ToString(i)).c_str(), block);
-
- if (NUdf::GetDataTypeInfo(types[i].first).Features & NUdf::EDataTypeFeatures::StringType) {
- ValueRelease(EValueRepresentation::String, nextOne, ctx, block);
- ValueRelease(EValueRepresentation::String, nextTwo, ctx, block);
- }
-
- const auto step = BasicBlock::Create(context, (TString("step") += ToString(i)).c_str(), ctx.Func);
- const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
-
- BranchInst::Create(step, stop, test, block);
-
- block = step;
- }
-
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementOne, lv, ctx.Codegen, block, ConstantInt::get(indexType, last));
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementTwo, rv, ctx.Codegen, block, ConstantInt::get(indexType, last));
-
- const auto backOne = new LoadInst(elementOne, "back_one", block);
- const auto backTwo = new LoadInst(elementTwo, "back_two", block);
-
- if (NUdf::GetDataTypeInfo(types.back().first).Features & NUdf::EDataTypeFeatures::StringType) {
- ValueRelease(EValueRepresentation::String, backOne, ctx, block);
- ValueRelease(EValueRepresentation::String, backTwo, ctx, block);
- }
-
- const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
- ReturnInst::Create(context, result, block);
- }
-
- block = stop;
- ReturnInst::Create(context, ConstantInt::getFalse(context), block);
-
- } else {
- const auto result = GenEqualsFunction(types.front().first, types.front().second, lv, rv, ctx, block);
- ReturnInst::Create(context, result, block);
- }
-
- return ctx.Func;
-}
-
-Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types) {
- auto& module = codegen->GetModule();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- auto& context = codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(valueType);
- const auto returnType = Type::getInt64Ty(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(returnType, {valueType}, false):
- FunctionType::get(returnType, {ptrType}, false);
-
- TCodegenContext ctx(codegen);
- ctx.AlwaysInline = true;
+
+ auto args = ctx.Func->arg_begin();
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto lv = LoadIfPointer(&*args, block);
+ const auto rv = LoadIfPointer(&*++args, block);
+
+ if (isTuple) {
+ if (types.empty()) {
+ ReturnInst::Create(context, ConstantInt::getTrue(context), block);
+ return ctx.Func;
+ }
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+
+ const auto elementsType = PointerType::getUnqual(ArrayType::get(valueType, types.size()));
+ const auto elementsPtrOne = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, lv, ctx.Codegen, block);
+ const auto elementsPtrTwo = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, rv, ctx.Codegen, block);
+
+ const auto goodOne = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elementsPtrOne, ConstantPointerNull::get(elementsType), "good_one", block);
+ const auto goodTwo = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, elementsPtrTwo, ConstantPointerNull::get(elementsType), "good_two", block);
+ const auto good = BinaryOperator::CreateAnd(goodOne, goodTwo, "good", block);
+
+ BranchInst::Create(fast, slow, good, block);
+
+ const auto last = types.size() - 1U;
+
+ {
+ block = fast;
+
+ const auto elementsOne = new LoadInst(elementsPtrOne, "elements_one", block);
+ const auto elementsTwo = new LoadInst(elementsPtrTwo, "elements_two", block);
+
+ for (ui32 i = 0U; i < last; ++i) {
+ const auto nextOne = ExtractValueInst::Create(elementsOne, i, (TString("next_one_") += ToString(i)).c_str(), block);
+ const auto nextTwo = ExtractValueInst::Create(elementsTwo, i, (TString("next_two_") += ToString(i)).c_str(), block);
+
+ const auto step = BasicBlock::Create(context, (TString("step") += ToString(i)).c_str(), ctx.Func);
+
+ const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
+
+ BranchInst::Create(step, stop, test, block);
+
+ block = step;
+ }
+
+ const auto backOne = ExtractValueInst::Create(elementsOne, last, "back_one", block);
+ const auto backTwo = ExtractValueInst::Create(elementsTwo, last, "back_two", block);
+
+ const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
+ ReturnInst::Create(context, result, block);
+ }
+
+ {
+ block = slow;
+
+ const auto elementOne = new AllocaInst(valueType, 0U, "element_one", block);
+ const auto elementTwo = new AllocaInst(valueType, 0U, "element_two", block);
+
+ const auto indexType = Type::getInt32Ty(context);
+
+ for (ui32 i = 0U; i < last; ++i) {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementOne, lv, ctx.Codegen, block, ConstantInt::get(indexType, i));
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementTwo, rv, ctx.Codegen, block, ConstantInt::get(indexType, i));
+
+ const auto nextOne = new LoadInst(elementOne, (TString("next_one_") += ToString(i)).c_str(), block);
+ const auto nextTwo = new LoadInst(elementTwo, (TString("next_two_") += ToString(i)).c_str(), block);
+
+ if (NUdf::GetDataTypeInfo(types[i].first).Features & NUdf::EDataTypeFeatures::StringType) {
+ ValueRelease(EValueRepresentation::String, nextOne, ctx, block);
+ ValueRelease(EValueRepresentation::String, nextTwo, ctx, block);
+ }
+
+ const auto step = BasicBlock::Create(context, (TString("step") += ToString(i)).c_str(), ctx.Func);
+ const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
+
+ BranchInst::Create(step, stop, test, block);
+
+ block = step;
+ }
+
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementOne, lv, ctx.Codegen, block, ConstantInt::get(indexType, last));
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(elementTwo, rv, ctx.Codegen, block, ConstantInt::get(indexType, last));
+
+ const auto backOne = new LoadInst(elementOne, "back_one", block);
+ const auto backTwo = new LoadInst(elementTwo, "back_two", block);
+
+ if (NUdf::GetDataTypeInfo(types.back().first).Features & NUdf::EDataTypeFeatures::StringType) {
+ ValueRelease(EValueRepresentation::String, backOne, ctx, block);
+ ValueRelease(EValueRepresentation::String, backTwo, ctx, block);
+ }
+
+ const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
+ ReturnInst::Create(context, result, block);
+ }
+
+ block = stop;
+ ReturnInst::Create(context, ConstantInt::getFalse(context), block);
+
+ } else {
+ const auto result = GenEqualsFunction(types.front().first, types.front().second, lv, rv, ctx, block);
+ ReturnInst::Create(context, result, block);
+ }
+
+ return ctx.Func;
+}
+
+Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types) {
+ auto& module = codegen->GetModule();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ auto& context = codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(valueType);
+ const auto returnType = Type::getInt64Ty(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(returnType, {valueType}, false):
+ FunctionType::get(returnType, {ptrType}, false);
+
+ TCodegenContext ctx(codegen);
+ ctx.AlwaysInline = true;
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto arg = LoadIfPointer(&*ctx.Func->arg_begin(), block);
-
- if (isTuple) {
- if (types.empty()) {
- ReturnInst::Create(context, ConstantInt::get(returnType, 0), block);
- return ctx.Func;
- }
-
- const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
- const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
-
- const auto elementsType = PointerType::getUnqual(ArrayType::get(valueType, types.size()));
- const auto elementsPtr = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, arg, ctx.Codegen, block);
-
- const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elementsPtr, ConstantPointerNull::get(elementsType), "null", block);
-
- BranchInst::Create(slow, fast, null, block);
-
- {
- block = fast;
-
- const auto elements = new LoadInst(elementsPtr, "elements", block);
-
- auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
-
- for (auto i = 0U; i < types.size(); ++i) {
- const auto next = ExtractValueInst::Create(elements, i, (TString("next_") += ToString(i)).c_str(), block);
-
- const auto plus = GenHashFunction(types[i].first, types[i].second, next, ctx, block);
-
- result = GenCombineHashes(result, plus, block);
- }
-
- ReturnInst::Create(context, result, block);
- }
-
- {
- block = slow;
-
- const auto element = new AllocaInst(valueType, 0U, "element", block);
-
- auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
-
- for (auto i = 0U; i < types.size(); ++i) {
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(element, arg, ctx.Codegen, block, ConstantInt::get(Type::getInt32Ty(context), i));
-
- const auto next = new LoadInst(element, (TString("next_") += ToString(i)).c_str(), block);
- if (NUdf::GetDataTypeInfo(types[i].first).Features & NUdf::EDataTypeFeatures::StringType) {
- ValueRelease(EValueRepresentation::String, next, ctx, block);
- }
-
- const auto plus = GenHashFunction(types[i].first, types[i].second, next, ctx, block);
-
- result = GenCombineHashes(result, plus, block);
- }
-
- ReturnInst::Create(context, result, block);
- }
-
- } else {
- const auto result = GenHashFunction(types.front().first, types.front().second, arg, ctx, block);
- ReturnInst::Create(context, result, block);
- }
-
- return ctx.Func;
-}
-
-Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types) {
- auto& module = codegen->GetModule();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- auto& context = codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto elementsType = ArrayType::get(valueType, types.size());
- const auto ptrType = PointerType::getUnqual(elementsType);
- const auto returnType = Type::getInt1Ty(context);
-
- const auto funcType = FunctionType::get(returnType, {ptrType, ptrType}, false);
-
- TCodegenContext ctx(codegen);
- ctx.AlwaysInline = true;
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto arg = LoadIfPointer(&*ctx.Func->arg_begin(), block);
+
+ if (isTuple) {
+ if (types.empty()) {
+ ReturnInst::Create(context, ConstantInt::get(returnType, 0), block);
+ return ctx.Func;
+ }
+
+ const auto fast = BasicBlock::Create(context, "fast", ctx.Func);
+ const auto slow = BasicBlock::Create(context, "slow", ctx.Func);
+
+ const auto elementsType = PointerType::getUnqual(ArrayType::get(valueType, types.size()));
+ const auto elementsPtr = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElements>(elementsType, arg, ctx.Codegen, block);
+
+ const auto null = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, elementsPtr, ConstantPointerNull::get(elementsType), "null", block);
+
+ BranchInst::Create(slow, fast, null, block);
+
+ {
+ block = fast;
+
+ const auto elements = new LoadInst(elementsPtr, "elements", block);
+
+ auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
+
+ for (auto i = 0U; i < types.size(); ++i) {
+ const auto next = ExtractValueInst::Create(elements, i, (TString("next_") += ToString(i)).c_str(), block);
+
+ const auto plus = GenHashFunction(types[i].first, types[i].second, next, ctx, block);
+
+ result = GenCombineHashes(result, plus, block);
+ }
+
+ ReturnInst::Create(context, result, block);
+ }
+
+ {
+ block = slow;
+
+ const auto element = new AllocaInst(valueType, 0U, "element", block);
+
+ auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
+
+ for (auto i = 0U; i < types.size(); ++i) {
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetElement>(element, arg, ctx.Codegen, block, ConstantInt::get(Type::getInt32Ty(context), i));
+
+ const auto next = new LoadInst(element, (TString("next_") += ToString(i)).c_str(), block);
+ if (NUdf::GetDataTypeInfo(types[i].first).Features & NUdf::EDataTypeFeatures::StringType) {
+ ValueRelease(EValueRepresentation::String, next, ctx, block);
+ }
+
+ const auto plus = GenHashFunction(types[i].first, types[i].second, next, ctx, block);
+
+ result = GenCombineHashes(result, plus, block);
+ }
+
+ ReturnInst::Create(context, result, block);
+ }
+
+ } else {
+ const auto result = GenHashFunction(types.front().first, types.front().second, arg, ctx, block);
+ ReturnInst::Create(context, result, block);
+ }
+
+ return ctx.Func;
+}
+
+Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types) {
+ auto& module = codegen->GetModule();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ auto& context = codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto elementsType = ArrayType::get(valueType, types.size());
+ const auto ptrType = PointerType::getUnqual(elementsType);
+ const auto returnType = Type::getInt1Ty(context);
+
+ const auto funcType = FunctionType::get(returnType, {ptrType, ptrType}, false);
+
+ TCodegenContext ctx(codegen);
+ ctx.AlwaysInline = true;
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- const auto lv = &*args;
- const auto rv = &*++args;
-
- if (types.empty()) {
- ReturnInst::Create(context, ConstantInt::getTrue(context), block);
- return ctx.Func;
- }
-
- const auto elementsOne = new LoadInst(lv, "elements_one", block);
- const auto elementsTwo = new LoadInst(rv, "elements_two", block);
-
- const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
- ReturnInst::Create(context, ConstantInt::getFalse(context), stop);
-
- const auto last = types.size() - 1U;
- for (ui32 i = 0U; i < last; ++i) {
- const auto nextOne = ExtractValueInst::Create(elementsOne, i, (TString("next_one_") += ToString(i)).c_str(), block);
- const auto nextTwo = ExtractValueInst::Create(elementsTwo, i, (TString("next_two_") += ToString(i)).c_str(), block);
-
- const auto step = BasicBlock::Create(context, (TString("step_") += ToString(i)).c_str(), ctx.Func);
-
- const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
-
- BranchInst::Create(step, stop, test, block);
-
- block = step;
- }
-
- const auto backOne = ExtractValueInst::Create(elementsOne, last, "back_one", block);
- const auto backTwo = ExtractValueInst::Create(elementsTwo, last, "back_two", block);
-
- const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
- ReturnInst::Create(context, result, block);
-
- return ctx.Func;
-}
-
-Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types) {
- auto& module = codegen->GetModule();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- auto& context = codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto elementsType = ArrayType::get(valueType, types.size());
- const auto ptrType = PointerType::getUnqual(elementsType);
- const auto returnType = Type::getInt64Ty(context);
-
- const auto funcType = FunctionType::get(returnType, {ptrType}, false);
-
- TCodegenContext ctx(codegen);
- ctx.AlwaysInline = true;
+
+ auto args = ctx.Func->arg_begin();
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ const auto lv = &*args;
+ const auto rv = &*++args;
+
+ if (types.empty()) {
+ ReturnInst::Create(context, ConstantInt::getTrue(context), block);
+ return ctx.Func;
+ }
+
+ const auto elementsOne = new LoadInst(lv, "elements_one", block);
+ const auto elementsTwo = new LoadInst(rv, "elements_two", block);
+
+ const auto stop = BasicBlock::Create(context, "stop", ctx.Func);
+ ReturnInst::Create(context, ConstantInt::getFalse(context), stop);
+
+ const auto last = types.size() - 1U;
+ for (ui32 i = 0U; i < last; ++i) {
+ const auto nextOne = ExtractValueInst::Create(elementsOne, i, (TString("next_one_") += ToString(i)).c_str(), block);
+ const auto nextTwo = ExtractValueInst::Create(elementsTwo, i, (TString("next_two_") += ToString(i)).c_str(), block);
+
+ const auto step = BasicBlock::Create(context, (TString("step_") += ToString(i)).c_str(), ctx.Func);
+
+ const auto test = GenEqualsFunction(types[i].first, types[i].second, nextOne, nextTwo, ctx, block);
+
+ BranchInst::Create(step, stop, test, block);
+
+ block = step;
+ }
+
+ const auto backOne = ExtractValueInst::Create(elementsOne, last, "back_one", block);
+ const auto backTwo = ExtractValueInst::Create(elementsTwo, last, "back_two", block);
+
+ const auto result = GenEqualsFunction(types.back().first, types.back().second, backOne, backTwo, ctx, block);
+ ReturnInst::Create(context, result, block);
+
+ return ctx.Func;
+}
+
+Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types) {
+ auto& module = codegen->GetModule();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ auto& context = codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto elementsType = ArrayType::get(valueType, types.size());
+ const auto ptrType = PointerType::getUnqual(elementsType);
+ const auto returnType = Type::getInt64Ty(context);
+
+ const auto funcType = FunctionType::get(returnType, {ptrType}, false);
+
+ TCodegenContext ctx(codegen);
+ ctx.AlwaysInline = true;
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- const auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto block = main;
-
- if (types.empty()) {
- ReturnInst::Create(context, ConstantInt::get(returnType, 0), block);
- return ctx.Func;
- }
-
- const auto arg = &*ctx.Func->arg_begin();
- const auto elements = new LoadInst(arg, "elements", block);
-
- if (types.size() > 1U) {
- auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
-
- for (auto i = 0U; i < types.size(); ++i) {
- const auto item = ExtractValueInst::Create(elements, i, (TString("item_") += ToString(i)).c_str(), block);
-
- const auto plus = GenHashFunction(types[i].first, types[i].second, item, ctx, block);
-
- result = GenCombineHashes(result, plus, block);
- }
-
- ReturnInst::Create(context, result, block);
- } else {
- const auto value = ExtractValueInst::Create(elements, 0, "value", block);
- const auto result = GenHashFunction(types.front().first, types.front().second, value, ctx, block);
- ReturnInst::Create(context, result, block);
- }
-
- return ctx.Func;
-}
-
-void GenInvalidate(const TCodegenContext& ctx, const std::vector<std::pair<ui32, EValueRepresentation>>& invalidationSet, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto values = ctx.GetMutables();
- const auto invv = ConstantInt::get(Type::getInt128Ty(context), 0xFFFFFFFFFFFFFFFFULL);
-
- for (const auto index : invalidationSet) {
- const auto invPtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, index.first)}, "inv_ptr", block);
- ValueUnRef(index.second, invPtr, ctx, block);
- new StoreInst(invv, invPtr, block);
- }
-}
-
-TUnboxedImmutableCodegeneratorNode::TUnboxedImmutableCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
- : TUnboxedImmutableComputationNode(memInfo, std::move(value))
-{}
-
-Value* TUnboxedImmutableCodegeneratorNode::CreateGetValue(const TCodegenContext& ctx, BasicBlock*&) const {
- return ConstantInt::get(Type::getInt128Ty(ctx.Codegen->GetContext()), APInt(128, 2, reinterpret_cast<const uint64_t*>(&UnboxedValue)));
-}
-
+
+ const auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto block = main;
+
+ if (types.empty()) {
+ ReturnInst::Create(context, ConstantInt::get(returnType, 0), block);
+ return ctx.Func;
+ }
+
+ const auto arg = &*ctx.Func->arg_begin();
+ const auto elements = new LoadInst(arg, "elements", block);
+
+ if (types.size() > 1U) {
+ auto result = static_cast<Value*>(ConstantInt::get(returnType, 0));
+
+ for (auto i = 0U; i < types.size(); ++i) {
+ const auto item = ExtractValueInst::Create(elements, i, (TString("item_") += ToString(i)).c_str(), block);
+
+ const auto plus = GenHashFunction(types[i].first, types[i].second, item, ctx, block);
+
+ result = GenCombineHashes(result, plus, block);
+ }
+
+ ReturnInst::Create(context, result, block);
+ } else {
+ const auto value = ExtractValueInst::Create(elements, 0, "value", block);
+ const auto result = GenHashFunction(types.front().first, types.front().second, value, ctx, block);
+ ReturnInst::Create(context, result, block);
+ }
+
+ return ctx.Func;
+}
+
+void GenInvalidate(const TCodegenContext& ctx, const std::vector<std::pair<ui32, EValueRepresentation>>& invalidationSet, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto values = ctx.GetMutables();
+ const auto invv = ConstantInt::get(Type::getInt128Ty(context), 0xFFFFFFFFFFFFFFFFULL);
+
+ for (const auto index : invalidationSet) {
+ const auto invPtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, index.first)}, "inv_ptr", block);
+ ValueUnRef(index.second, invPtr, ctx, block);
+ new StoreInst(invv, invPtr, block);
+ }
+}
+
+TUnboxedImmutableCodegeneratorNode::TUnboxedImmutableCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
+ : TUnboxedImmutableComputationNode(memInfo, std::move(value))
+{}
+
+Value* TUnboxedImmutableCodegeneratorNode::CreateGetValue(const TCodegenContext& ctx, BasicBlock*&) const {
+ return ConstantInt::get(Type::getInt128Ty(ctx.Codegen->GetContext()), APInt(128, 2, reinterpret_cast<const uint64_t*>(&UnboxedValue)));
+}
+
TUnboxedImmutableRunCodegeneratorNode::TUnboxedImmutableRunCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
: TUnboxedImmutableComputationNode(memInfo, std::move(value))
{}
-TExternalCodegeneratorNode::TExternalCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TExternalComputationNode(mutables, kind)
-{}
-
-TExternalCodegeneratorRootNode::TExternalCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TExternalCodegeneratorNode(mutables, kind)
-{}
-
+TExternalCodegeneratorNode::TExternalCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TExternalComputationNode(mutables, kind)
+{}
+
+TExternalCodegeneratorRootNode::TExternalCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TExternalCodegeneratorNode(mutables, kind)
+{}
+
NUdf::TUnboxedValue TExternalCodegeneratorRootNode::GetValue(TComputationContext& compCtx) const {
- if (compCtx.ExecuteLLVM && GetFunction)
+ if (compCtx.ExecuteLLVM && GetFunction)
return GetFunction(&compCtx);
return TExternalComputationNode::GetValue(compCtx);
-}
-
+}
+
void TExternalCodegeneratorRootNode::SetValue(TComputationContext& compCtx, NUdf::TUnboxedValue&& newValue) const {
- if (compCtx.ExecuteLLVM && SetFunction)
+ if (compCtx.ExecuteLLVM && SetFunction)
return SetFunction(&compCtx, newValue.Release());
-
+
TExternalComputationNode::SetValue(compCtx, std::move(newValue));
-}
-
-TString TExternalCodegeneratorRootNode::MakeName(const TString& method) const {
- TStringStream out;
- out << DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
-}
-
-void TExternalCodegeneratorRootNode::FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) {
- if (GetValueFunc)
- GetFunction = reinterpret_cast<TGetPtr>(codegen->GetPointerToFunction(GetValueFunc));
-
- if (SetValueFunc)
- SetFunction = reinterpret_cast<TSetPtr>(codegen->GetPointerToFunction(SetValueFunc));
-}
-
-void TExternalCodegeneratorRootNode::GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) {
- GetValueFunc = GenerateGetValue(codegen);
- SetValueFunc = GenerateSetValue(codegen);
+}
+
+TString TExternalCodegeneratorRootNode::MakeName(const TString& method) const {
+ TStringStream out;
+ out << DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+}
+
+void TExternalCodegeneratorRootNode::FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ if (GetValueFunc)
+ GetFunction = reinterpret_cast<TGetPtr>(codegen->GetPointerToFunction(GetValueFunc));
+
+ if (SetValueFunc)
+ SetFunction = reinterpret_cast<TSetPtr>(codegen->GetPointerToFunction(SetValueFunc));
+}
+
+void TExternalCodegeneratorRootNode::GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ GetValueFunc = GenerateGetValue(codegen);
+ SetValueFunc = GenerateSetValue(codegen);
codegen->ExportSymbol(GetValueFunc);
codegen->ExportSymbol(SetValueFunc);
-}
-
-Function* TExternalCodegeneratorRootNode::GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
- const auto& name = MakeName("Get");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto contextType = GetCompContextType(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(valueType, {PointerType::getUnqual(contextType)}, false):
- FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType)}, false);
-
- TCodegenContext ctx(codegen);
+}
+
+Function* TExternalCodegeneratorRootNode::GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+ const auto& name = MakeName("Get");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto contextType = GetCompContextType(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(valueType, {PointerType::getUnqual(contextType)}, false):
+ FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
- if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
- auto& firstArg = *args++;
- firstArg.addAttr(Attribute::StructRet);
- firstArg.addAttr(Attribute::NoAlias);
- }
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*args;
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto get = CreateGetValue(ctx, main);
-
- if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- ReturnInst::Create(context, get, main);
- } else {
- new StoreInst(get, &*--args, main);
- ReturnInst::Create(context, main);
- }
-
- return ctx.Func;
-}
-
-Function* TExternalCodegeneratorRootNode::GenerateSetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
- const auto& name = MakeName("Set");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto intType = Type::getInt128Ty(context);
- const auto contextType = GetCompContextType(context);
- const auto valueType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
- (Type*)PointerType::getUnqual(intType) : (Type*)intType;
-
- const auto funcType = FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(contextType), valueType}, false);
- TCodegenContext ctx(codegen);
+
+ auto args = ctx.Func->arg_begin();
+ if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
+ auto& firstArg = *args++;
+ firstArg.addAttr(Attribute::StructRet);
+ firstArg.addAttr(Attribute::NoAlias);
+ }
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*args;
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto get = CreateGetValue(ctx, main);
+
+ if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ ReturnInst::Create(context, get, main);
+ } else {
+ new StoreInst(get, &*--args, main);
+ ReturnInst::Create(context, main);
+ }
+
+ return ctx.Func;
+}
+
+Function* TExternalCodegeneratorRootNode::GenerateSetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+ const auto& name = MakeName("Set");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto intType = Type::getInt128Ty(context);
+ const auto contextType = GetCompContextType(context);
+ const auto valueType = codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows ?
+ (Type*)PointerType::getUnqual(intType) : (Type*)intType;
+
+ const auto funcType = FunctionType::get(Type::getVoidTy(context), {PointerType::getUnqual(contextType), valueType}, false);
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*args;
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto valueArg = &*++args;
-
- if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
- const auto value = new LoadInst(valueArg, "load_value", main);
- CreateSetValue(ctx, main, value);
- } else {
- CreateSetValue(ctx, main, valueArg);
- }
- ReturnInst::Create(context, main);
- return ctx.Func;
-}
-
-Value* TExternalCodegeneratorNode::CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- if (ValueGetter) {
- return CallInst::Create(ValueGetter, {ctx.Ctx}, "getter", block);
- }
-
- if (TemporaryValue) {
- return LoadIfPointer(TemporaryValue, block);
- }
-
- MKQL_ENSURE(!Getter, "Wrong LLVM function generation order.");
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
- const auto value = new LoadInst(valuePtr, "value", block);
- return value;
-}
-
-Value* TExternalCodegeneratorNode::CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- CreateInvalidate(ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto values = ctx.GetMutables();
- const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
- return valuePtr;
-}
-
-void TExternalCodegeneratorNode::CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const {
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto values = ctx.GetMutables();
- const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
-
-
- if (value->getType()->isPointerTy()) {
- ValueUnRef(RepresentationKind, valuePtr, ctx, block);
- const auto load = new LoadInst(value, "value", block);
- new StoreInst(load, valuePtr, block);
- new StoreInst(ConstantInt::get(load->getType(), 0), value, block);
- } else {
- if (EValueRepresentation::Embedded == RepresentationKind) {
- new StoreInst(value, valuePtr, block);
- } else {
- const auto load = new LoadInst(valuePtr, "value", block);
- const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, load, "equal", block);
-
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto refs = BasicBlock::Create(context, "refs", ctx.Func);
- BranchInst::Create(skip, refs, equal, block);
-
- block = refs;
- ValueUnRef(RepresentationKind, valuePtr, ctx, block);
- new StoreInst(value, valuePtr, block);
- ValueAddRef(RepresentationKind, valuePtr, ctx, block);
-
- BranchInst::Create(skip, block);
- block = skip;
- }
-
- }
- CreateInvalidate(ctx, block);
-}
-
-Value* TExternalCodegeneratorNode::CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const {
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto values = ctx.GetMutables();
- const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
- const auto output = new LoadInst(valuePtr, "output", block);
- ValueRelease(RepresentationKind, output, ctx, block);
-
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- new StoreInst(load, valuePtr, block);
- new StoreInst(ConstantInt::get(load->getType(), 0), value, block);
- } else {
- ValueAddRef(RepresentationKind, value, ctx, block);
- new StoreInst(value, valuePtr, block);
- }
-
- CreateInvalidate(ctx, block);
- return output;
-}
-
-void TExternalCodegeneratorNode::CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const {
- GenInvalidate(ctx, InvalidationSet, block);
-}
-
-void TExternalCodegeneratorNode::SetTemporaryValue(Value* value) { TemporaryValue = value; }
-void TExternalCodegeneratorNode::SetValueGetter(Function* function) { ValueGetter = function; }
-
-void TWideFlowProxyCodegeneratorNode::CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const {
- GenInvalidate(ctx, InvalidationSet, block);
-}
-
-void TWideFlowProxyCodegeneratorNode::SetGenerator(TGenerator&& generator) {
- Generator = std::move(generator);
-}
-
-ICodegeneratorInlineWideNode::TGenerateResult
-TWideFlowProxyCodegeneratorNode::GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
- return Generator(ctx, block);
-}
-
-Value* GetOptionalValue(LLVMContext& context, Value* value, BasicBlock* block) {
- const auto type = Type::getInt128Ty(context);
- const auto data = ConstantInt::get(type, 0xFFFFFFFFFFFFFFFFULL);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, value, data, "check", block);
- const auto decr = BinaryOperator::CreateSub(value, ConstantInt::get(type, 1), "decr", block);
- const auto result = SelectInst::Create(check, value, decr, "result", block);
- return result;
-}
-
-Value* MakeOptional(LLVMContext& context, Value* value, BasicBlock* block) {
- const auto type = Type::getInt128Ty(context);
- const auto data = ConstantInt::get(type, 0xFFFFFFFFFFFFFFFFULL);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, value, data, "check", block);
- const auto incr = BinaryOperator::CreateAdd(value, ConstantInt::get(type, 1), "incr", block);
- const auto result = SelectInst::Create(check, value, incr, "result", block);
- return result;
-}
-
-ConstantInt* GetTrue(LLVMContext &context) {
- const uint64_t init[] = {1ULL, 0x100000000000000ULL};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-ConstantInt* GetFalse(LLVMContext &context) {
- const uint64_t init[] = {0ULL, 0x100000000000000ULL};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-ConstantInt* GetDecimalPlusInf(LLVMContext &context) {
- const auto& pair = NYql::NDecimal::MakePair(+NYql::NDecimal::Inf());
- const uint64_t init[] = {pair.first, pair.second};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-ConstantInt* GetDecimalMinusInf(LLVMContext &context) {
- const auto& pair = NYql::NDecimal::MakePair(-NYql::NDecimal::Inf());
- const uint64_t init[] = {pair.first, pair.second};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-ConstantInt* GetDecimalNan(LLVMContext &context) {
- const auto& pair = NYql::NDecimal::MakePair(NYql::NDecimal::Nan());
- const uint64_t init[] = {pair.first, pair.second};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-
-ConstantInt* GetDecimalMinusNan(LLVMContext &context) {
- const auto& pair = NYql::NDecimal::MakePair(-NYql::NDecimal::Nan());
- const uint64_t init[] = {pair.first, pair.second};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-static constexpr ui64 InvalidData = std::numeric_limits<ui64>::max();
-static constexpr ui64 FinishData = InvalidData - 1ULL;
-static constexpr ui64 YieldData = InvalidData;
-
-ConstantInt* GetEmpty(LLVMContext &context) {
- return ConstantInt::get(Type::getInt128Ty(context), 0ULL);
-}
-
-ConstantInt* GetInvalid(LLVMContext &context) {
- return ConstantInt::get(Type::getInt128Ty(context), InvalidData);
-}
-
-ConstantInt* GetFinish(LLVMContext &context) {
- return ConstantInt::get(Type::getInt128Ty(context), FinishData);
-}
-
-ConstantInt* GetYield(LLVMContext &context) {
- return ConstantInt::get(Type::getInt128Ty(context), YieldData);
-}
-
-ConstantInt* GetConstant(ui64 value, LLVMContext &context) {
- const uint64_t init[] = {value, 0x100000000000000ULL};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-Value* IsExists(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, v, ConstantInt::get(v->getType(), 0ULL), "exists", block);
-}
-
-Value* IsEmpty(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), 0ULL), "empty", block);
-}
-
-Value* IsInvalid(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), InvalidData), "invalid", block);
-}
-
-Value* IsValid(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, v, ConstantInt::get(v->getType(), InvalidData), "valid", block);
-}
-
-Value* IsFinish(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), FinishData), "finish", block);
-}
-
-Value* IsYield(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), YieldData), "yield", block);
-}
-
-Value* IsSpecial(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return BinaryOperator::CreateOr(IsFinish(v, block), IsYield(v, block), "special", block);
-}
-
-Value* HasValue(Value* value, BasicBlock* block) {
- const auto v = LoadIfPointer(value, block);
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, v, ConstantInt::get(v->getType(), InvalidData), "has", block);
-}
-
-Value* MakeBoolean(Value* boolean , LLVMContext &context, BasicBlock* block) {
- return SelectInst::Create(boolean, GetTrue(context), GetFalse(context), "result", block);
-}
-
-Value* SetterForInt128(Value* value, BasicBlock* block) {
- const uint64_t mask[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL};
- const auto drop = ConstantInt::get(value->getType(), APInt(128, 2, mask));
- const auto data = BinaryOperator::CreateAnd(value, drop, "and", block);
- const uint64_t init[] = {0ULL, 0x100000000000000ULL}; // Embedded
- const auto meta = ConstantInt::get(value->getType(), APInt(128, 2, init));
- const auto full = BinaryOperator::CreateOr(data, meta, "or", block);
- return full;
-}
-
-Value* GetterForInt128(Value* value, BasicBlock* block) {
- const uint64_t init[] = {0ULL, 0x80000000000000ULL};
- const auto test = ConstantInt::get(value->getType(), APInt(128, 2, init));
- const auto sign = BinaryOperator::CreateAnd(value, test, "and", block);
-
- const uint64_t fill[] = {0ULL, 0xFF00000000000000ULL};
- const auto sext = ConstantInt::get(value->getType(), APInt(128, 2, fill));
- const auto minus = BinaryOperator::CreateOr(value, sext, "or", block);
-
- const uint64_t mask[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL};
- const auto trun = ConstantInt::get(value->getType(), APInt(128, 2, mask));
- const auto plus = BinaryOperator::CreateAnd(value, trun, "and", block);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, sign, ConstantInt::get(sign->getType(), 0), "check", block);
- const auto result = SelectInst::Create(check, plus, minus, "result", block);
- return result;
-}
-
-Value* GetterForTimezone(LLVMContext& context, Value* value, BasicBlock* block) {
- const auto lshr = BinaryOperator::CreateLShr(value, ConstantInt::get(value->getType(), 64ULL), "lshr", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, lshr, Type::getInt16Ty(context), "trunc", block);
- return trunc;
-}
-
-template<> Type* GetTypeFor<bool>(LLVMContext &context) { return Type::getInt1Ty(context); }
-template<> Type* GetTypeFor<ui8>(LLVMContext &context) { return Type::getInt8Ty(context); }
-template<> Type* GetTypeFor<i8>(LLVMContext &context) { return Type::getInt8Ty(context); }
-
-template<> Type* GetTypeFor<i16>(LLVMContext &context) { return Type::getInt16Ty(context); }
-template<> Type* GetTypeFor<ui16>(LLVMContext &context) { return Type::getInt16Ty(context); }
-
-template<> Type* GetTypeFor<i32>(LLVMContext &context) { return Type::getInt32Ty(context); }
-template<> Type* GetTypeFor<ui32>(LLVMContext &context) { return Type::getInt32Ty(context); }
-
-template<> Type* GetTypeFor<i64>(LLVMContext &context) { return Type::getInt64Ty(context); }
-template<> Type* GetTypeFor<ui64>(LLVMContext &context) { return Type::getInt64Ty(context); }
-
-template<> Type* GetTypeFor<float>(LLVMContext &context) { return Type::getFloatTy(context); }
-template<> Type* GetTypeFor<double>(LLVMContext &context) { return Type::getDoubleTy(context); }
-
-void AddRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
- const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
- const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
- const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
- const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
- const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
- const auto refs = new LoadInst(cntptr, "refs", block);
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if constexpr (EnableStaticRefcount) {
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
- const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
- BranchInst::Create(skip, work, magic, block);
-
- block = work;
- const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
- new StoreInst(incr, cntptr, block);
- BranchInst::Create(skip, block);
-
- block = skip;
- } else {
- const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
- new StoreInst(incr, cntptr, block);
- }
-#else
- const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
- new StoreInst(incr, cntptr, block);
-#endif
-}
-
-void UnRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
- const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
- const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
- const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
- const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
- const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
- const auto refs = new LoadInst(cntptr, "refs", block);
-
- const auto live = BasicBlock::Create(context, "live", ctx.Func);
-
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if constexpr (EnableStaticRefcount) {
- const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(live, work, magic, block);
-
- block = work;
- }
-#endif
-
- const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
- new StoreInst(decr, cntptr, block);
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0), "many", block);
-
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
-
- BranchInst::Create(live, kill, test, block);
-
- block = kill;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
- const auto name = "DeleteBoxed";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
+
+ auto args = ctx.Func->arg_begin();
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*args;
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto valueArg = &*++args;
+
+ if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
+ const auto value = new LoadInst(valueArg, "load_value", main);
+ CreateSetValue(ctx, main, value);
+ } else {
+ CreateSetValue(ctx, main, valueArg);
+ }
+ ReturnInst::Create(context, main);
+ return ctx.Func;
+}
+
+Value* TExternalCodegeneratorNode::CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ if (ValueGetter) {
+ return CallInst::Create(ValueGetter, {ctx.Ctx}, "getter", block);
+ }
+
+ if (TemporaryValue) {
+ return LoadIfPointer(TemporaryValue, block);
+ }
+
+ MKQL_ENSURE(!Getter, "Wrong LLVM function generation order.");
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
+ const auto value = new LoadInst(valuePtr, "value", block);
+ return value;
+}
+
+Value* TExternalCodegeneratorNode::CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ CreateInvalidate(ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto values = ctx.GetMutables();
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
+ return valuePtr;
+}
+
+void TExternalCodegeneratorNode::CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto values = ctx.GetMutables();
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
+
+
+ if (value->getType()->isPointerTy()) {
+ ValueUnRef(RepresentationKind, valuePtr, ctx, block);
+ const auto load = new LoadInst(value, "value", block);
+ new StoreInst(load, valuePtr, block);
+ new StoreInst(ConstantInt::get(load->getType(), 0), value, block);
+ } else {
+ if (EValueRepresentation::Embedded == RepresentationKind) {
+ new StoreInst(value, valuePtr, block);
+ } else {
+ const auto load = new LoadInst(valuePtr, "value", block);
+ const auto equal = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, load, "equal", block);
+
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto refs = BasicBlock::Create(context, "refs", ctx.Func);
+ BranchInst::Create(skip, refs, equal, block);
+
+ block = refs;
+ ValueUnRef(RepresentationKind, valuePtr, ctx, block);
+ new StoreInst(value, valuePtr, block);
+ ValueAddRef(RepresentationKind, valuePtr, ctx, block);
+
+ BranchInst::Create(skip, block);
+ block = skip;
+ }
+
+ }
+ CreateInvalidate(ctx, block);
+}
+
+Value* TExternalCodegeneratorNode::CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto values = ctx.GetMutables();
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(indexType, ValueIndex)}, "value_ptr", block);
+ const auto output = new LoadInst(valuePtr, "output", block);
+ ValueRelease(RepresentationKind, output, ctx, block);
+
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ new StoreInst(load, valuePtr, block);
+ new StoreInst(ConstantInt::get(load->getType(), 0), value, block);
+ } else {
+ ValueAddRef(RepresentationKind, value, ctx, block);
+ new StoreInst(value, valuePtr, block);
+ }
+
+ CreateInvalidate(ctx, block);
+ return output;
+}
+
+void TExternalCodegeneratorNode::CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const {
+ GenInvalidate(ctx, InvalidationSet, block);
+}
+
+void TExternalCodegeneratorNode::SetTemporaryValue(Value* value) { TemporaryValue = value; }
+void TExternalCodegeneratorNode::SetValueGetter(Function* function) { ValueGetter = function; }
+
+void TWideFlowProxyCodegeneratorNode::CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const {
+ GenInvalidate(ctx, InvalidationSet, block);
+}
+
+void TWideFlowProxyCodegeneratorNode::SetGenerator(TGenerator&& generator) {
+ Generator = std::move(generator);
+}
+
+ICodegeneratorInlineWideNode::TGenerateResult
+TWideFlowProxyCodegeneratorNode::GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const {
+ return Generator(ctx, block);
+}
+
+Value* GetOptionalValue(LLVMContext& context, Value* value, BasicBlock* block) {
+ const auto type = Type::getInt128Ty(context);
+ const auto data = ConstantInt::get(type, 0xFFFFFFFFFFFFFFFFULL);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, value, data, "check", block);
+ const auto decr = BinaryOperator::CreateSub(value, ConstantInt::get(type, 1), "decr", block);
+ const auto result = SelectInst::Create(check, value, decr, "result", block);
+ return result;
+}
+
+Value* MakeOptional(LLVMContext& context, Value* value, BasicBlock* block) {
+ const auto type = Type::getInt128Ty(context);
+ const auto data = ConstantInt::get(type, 0xFFFFFFFFFFFFFFFFULL);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, value, data, "check", block);
+ const auto incr = BinaryOperator::CreateAdd(value, ConstantInt::get(type, 1), "incr", block);
+ const auto result = SelectInst::Create(check, value, incr, "result", block);
+ return result;
+}
+
+ConstantInt* GetTrue(LLVMContext &context) {
+ const uint64_t init[] = {1ULL, 0x100000000000000ULL};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+ConstantInt* GetFalse(LLVMContext &context) {
+ const uint64_t init[] = {0ULL, 0x100000000000000ULL};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+ConstantInt* GetDecimalPlusInf(LLVMContext &context) {
+ const auto& pair = NYql::NDecimal::MakePair(+NYql::NDecimal::Inf());
+ const uint64_t init[] = {pair.first, pair.second};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+ConstantInt* GetDecimalMinusInf(LLVMContext &context) {
+ const auto& pair = NYql::NDecimal::MakePair(-NYql::NDecimal::Inf());
+ const uint64_t init[] = {pair.first, pair.second};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+ConstantInt* GetDecimalNan(LLVMContext &context) {
+ const auto& pair = NYql::NDecimal::MakePair(NYql::NDecimal::Nan());
+ const uint64_t init[] = {pair.first, pair.second};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+
+ConstantInt* GetDecimalMinusNan(LLVMContext &context) {
+ const auto& pair = NYql::NDecimal::MakePair(-NYql::NDecimal::Nan());
+ const uint64_t init[] = {pair.first, pair.second};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+static constexpr ui64 InvalidData = std::numeric_limits<ui64>::max();
+static constexpr ui64 FinishData = InvalidData - 1ULL;
+static constexpr ui64 YieldData = InvalidData;
+
+ConstantInt* GetEmpty(LLVMContext &context) {
+ return ConstantInt::get(Type::getInt128Ty(context), 0ULL);
+}
+
+ConstantInt* GetInvalid(LLVMContext &context) {
+ return ConstantInt::get(Type::getInt128Ty(context), InvalidData);
+}
+
+ConstantInt* GetFinish(LLVMContext &context) {
+ return ConstantInt::get(Type::getInt128Ty(context), FinishData);
+}
+
+ConstantInt* GetYield(LLVMContext &context) {
+ return ConstantInt::get(Type::getInt128Ty(context), YieldData);
+}
+
+ConstantInt* GetConstant(ui64 value, LLVMContext &context) {
+ const uint64_t init[] = {value, 0x100000000000000ULL};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+Value* IsExists(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, v, ConstantInt::get(v->getType(), 0ULL), "exists", block);
+}
+
+Value* IsEmpty(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), 0ULL), "empty", block);
+}
+
+Value* IsInvalid(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), InvalidData), "invalid", block);
+}
+
+Value* IsValid(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, v, ConstantInt::get(v->getType(), InvalidData), "valid", block);
+}
+
+Value* IsFinish(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), FinishData), "finish", block);
+}
+
+Value* IsYield(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, v, ConstantInt::get(v->getType(), YieldData), "yield", block);
+}
+
+Value* IsSpecial(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return BinaryOperator::CreateOr(IsFinish(v, block), IsYield(v, block), "special", block);
+}
+
+Value* HasValue(Value* value, BasicBlock* block) {
+ const auto v = LoadIfPointer(value, block);
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, v, ConstantInt::get(v->getType(), InvalidData), "has", block);
+}
+
+Value* MakeBoolean(Value* boolean , LLVMContext &context, BasicBlock* block) {
+ return SelectInst::Create(boolean, GetTrue(context), GetFalse(context), "result", block);
+}
+
+Value* SetterForInt128(Value* value, BasicBlock* block) {
+ const uint64_t mask[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL};
+ const auto drop = ConstantInt::get(value->getType(), APInt(128, 2, mask));
+ const auto data = BinaryOperator::CreateAnd(value, drop, "and", block);
+ const uint64_t init[] = {0ULL, 0x100000000000000ULL}; // Embedded
+ const auto meta = ConstantInt::get(value->getType(), APInt(128, 2, init));
+ const auto full = BinaryOperator::CreateOr(data, meta, "or", block);
+ return full;
+}
+
+Value* GetterForInt128(Value* value, BasicBlock* block) {
+ const uint64_t init[] = {0ULL, 0x80000000000000ULL};
+ const auto test = ConstantInt::get(value->getType(), APInt(128, 2, init));
+ const auto sign = BinaryOperator::CreateAnd(value, test, "and", block);
+
+ const uint64_t fill[] = {0ULL, 0xFF00000000000000ULL};
+ const auto sext = ConstantInt::get(value->getType(), APInt(128, 2, fill));
+ const auto minus = BinaryOperator::CreateOr(value, sext, "or", block);
+
+ const uint64_t mask[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL};
+ const auto trun = ConstantInt::get(value->getType(), APInt(128, 2, mask));
+ const auto plus = BinaryOperator::CreateAnd(value, trun, "and", block);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, sign, ConstantInt::get(sign->getType(), 0), "check", block);
+ const auto result = SelectInst::Create(check, plus, minus, "result", block);
+ return result;
+}
+
+Value* GetterForTimezone(LLVMContext& context, Value* value, BasicBlock* block) {
+ const auto lshr = BinaryOperator::CreateLShr(value, ConstantInt::get(value->getType(), 64ULL), "lshr", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, lshr, Type::getInt16Ty(context), "trunc", block);
+ return trunc;
+}
+
+template<> Type* GetTypeFor<bool>(LLVMContext &context) { return Type::getInt1Ty(context); }
+template<> Type* GetTypeFor<ui8>(LLVMContext &context) { return Type::getInt8Ty(context); }
+template<> Type* GetTypeFor<i8>(LLVMContext &context) { return Type::getInt8Ty(context); }
+
+template<> Type* GetTypeFor<i16>(LLVMContext &context) { return Type::getInt16Ty(context); }
+template<> Type* GetTypeFor<ui16>(LLVMContext &context) { return Type::getInt16Ty(context); }
+
+template<> Type* GetTypeFor<i32>(LLVMContext &context) { return Type::getInt32Ty(context); }
+template<> Type* GetTypeFor<ui32>(LLVMContext &context) { return Type::getInt32Ty(context); }
+
+template<> Type* GetTypeFor<i64>(LLVMContext &context) { return Type::getInt64Ty(context); }
+template<> Type* GetTypeFor<ui64>(LLVMContext &context) { return Type::getInt64Ty(context); }
+
+template<> Type* GetTypeFor<float>(LLVMContext &context) { return Type::getFloatTy(context); }
+template<> Type* GetTypeFor<double>(LLVMContext &context) { return Type::getDoubleTy(context); }
+
+void AddRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
+ const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
+ const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
+ const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
+ const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
+ const auto refs = new LoadInst(cntptr, "refs", block);
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if constexpr (EnableStaticRefcount) {
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+ const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
+ BranchInst::Create(skip, work, magic, block);
+
+ block = work;
+ const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
+ new StoreInst(incr, cntptr, block);
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ } else {
+ const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
+ new StoreInst(incr, cntptr, block);
+ }
+#else
+ const auto incr = BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block);
+ new StoreInst(incr, cntptr, block);
+#endif
+}
+
+void UnRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
+ const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
+ const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
+ const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
+ const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
+ const auto refs = new LoadInst(cntptr, "refs", block);
+
+ const auto live = BasicBlock::Create(context, "live", ctx.Func);
+
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if constexpr (EnableStaticRefcount) {
+ const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(live, work, magic, block);
+
+ block = work;
+ }
+#endif
+
+ const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
+ new StoreInst(decr, cntptr, block);
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, decr, ConstantInt::get(decr->getType(), 0), "many", block);
+
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+
+ BranchInst::Create(live, kill, test, block);
+
+ block = kill;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
+ const auto name = "DeleteBoxed";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {boxptr}, "", block);
-
- BranchInst::Create(live, block);
- block = live;
-}
-
-void CleanupBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
- const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
- const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
- const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
- const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
- const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
- const auto refs = new LoadInst(cntptr, "refs", block);
- const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, refs, ConstantInt::get(refs->getType(), 0), "many", block);
-
- const auto live = BasicBlock::Create(context, "live", ctx.Func);
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
-
- BranchInst::Create(live, kill, test, block);
-
- block = kill;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
- const auto name = "DeleteBoxed";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
+ CallInst::Create(func, {boxptr}, "", block);
+
+ BranchInst::Create(live, block);
+ block = live;
+}
+
+void CleanupBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto load = value->getType()->isPointerTy() ? new LoadInst(value, "load", block) : value;
+ const auto half = CastInst::Create(Instruction::Trunc, load, Type::getInt64Ty(context), "half", block);
+ const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
+ const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
+ const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
+ const auto refs = new LoadInst(cntptr, "refs", block);
+ const auto test = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, refs, ConstantInt::get(refs->getType(), 0), "many", block);
+
+ const auto live = BasicBlock::Create(context, "live", ctx.Func);
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+
+ BranchInst::Create(live, kill, test, block);
+
+ block = kill;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
+ const auto name = "DeleteBoxed";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {boxptr}, "", block);
-
- BranchInst::Create(live, block);
- block = live;
-}
-
-
-template<bool IncOrDec>
-void ChangeRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto type8 = Type::getInt8Ty(context);
- const auto type32 = Type::getInt32Ty(context);
-
- const auto mark = GetMarkFromUnboxed(value, ctx, block);
-
- const auto boxb = BasicBlock::Create(context, "boxb", ctx.Func);
- const auto strb = BasicBlock::Create(context, "strb", ctx.Func);
- const auto doit = BasicBlock::Create(context, "doit", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto refsptr = PHINode::Create(PointerType::getUnqual(type32), 2U, "refsptr", doit);
-
- const auto choise = SwitchInst::Create(mark, done, 2U, block);
- choise->addCase(ConstantInt::get(type8, 2), strb);
- choise->addCase(ConstantInt::get(type8, 3), boxb);
-
- {
- block = strb;
-
- const auto strptr = GetPointerFromUnboxed<false>(value, ctx, block);
- const auto elemptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "elemptr", block);
- refsptr->addIncoming(elemptr, block);
- BranchInst::Create(doit, block);
- }
-
- {
- block = boxb;
-
- const auto boxptr = GetPointerFromUnboxed<true>(value, ctx, block);;
- const auto elemptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "elemptr", block);
- refsptr->addIncoming(elemptr, block);
- BranchInst::Create(doit, block);
- }
-
- block = doit;
-
- const auto refs = new LoadInst(refsptr, "refs", block);
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if constexpr (EnableStaticRefcount) {
- const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(done, work, magic, block);
-
- block = work;
- }
-#endif
- const auto next = IncOrDec ?
- BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block):
- BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
- new StoreInst(next, refsptr, block);
- BranchInst::Create(done, block);
-
- block = done;
-}
-
-template<bool Decrement>
-void CheckRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto type8 = Type::getInt8Ty(context);
- const auto type32 = Type::getInt32Ty(context);
-
- const auto mark = GetMarkFromUnboxed(value, ctx, block);
-
- const auto boxb = BasicBlock::Create(context, "boxb", ctx.Func);
- const auto strb = BasicBlock::Create(context, "strb", ctx.Func);
- const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
-
- const auto choise = SwitchInst::Create(mark, nope, 2U, block);
- choise->addCase(ConstantInt::get(type8, 2), strb);
- choise->addCase(ConstantInt::get(type8, 3), boxb);
-
- {
- block = strb;
-
- const auto strptr = GetPointerFromUnboxed<false>(value, ctx, block);
- const auto refptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "refptr", block);
- const auto refs = new LoadInst(refptr, "refs", block);
-
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if constexpr (EnableStaticRefcount) {
- const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(nope, work, magic, block);
-
- block = work;
- }
-#endif
- Value* test = refs;
-
- if constexpr (Decrement) {
- const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
- new StoreInst(decr, refptr, block);
- test = decr;
- }
-
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, test, ConstantInt::get(test->getType(), 0), "test", block);
-
- const auto free = BasicBlock::Create(context, "free", ctx.Func);
-
- BranchInst::Create(nope, free, good, block);
-
- block = free;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {strptr->getType()}, false);
+ CallInst::Create(func, {boxptr}, "", block);
+
+ BranchInst::Create(live, block);
+ block = live;
+}
+
+
+template<bool IncOrDec>
+void ChangeRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto type8 = Type::getInt8Ty(context);
+ const auto type32 = Type::getInt32Ty(context);
+
+ const auto mark = GetMarkFromUnboxed(value, ctx, block);
+
+ const auto boxb = BasicBlock::Create(context, "boxb", ctx.Func);
+ const auto strb = BasicBlock::Create(context, "strb", ctx.Func);
+ const auto doit = BasicBlock::Create(context, "doit", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto refsptr = PHINode::Create(PointerType::getUnqual(type32), 2U, "refsptr", doit);
+
+ const auto choise = SwitchInst::Create(mark, done, 2U, block);
+ choise->addCase(ConstantInt::get(type8, 2), strb);
+ choise->addCase(ConstantInt::get(type8, 3), boxb);
+
+ {
+ block = strb;
+
+ const auto strptr = GetPointerFromUnboxed<false>(value, ctx, block);
+ const auto elemptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "elemptr", block);
+ refsptr->addIncoming(elemptr, block);
+ BranchInst::Create(doit, block);
+ }
+
+ {
+ block = boxb;
+
+ const auto boxptr = GetPointerFromUnboxed<true>(value, ctx, block);;
+ const auto elemptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "elemptr", block);
+ refsptr->addIncoming(elemptr, block);
+ BranchInst::Create(doit, block);
+ }
+
+ block = doit;
+
+ const auto refs = new LoadInst(refsptr, "refs", block);
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if constexpr (EnableStaticRefcount) {
+ const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(done, work, magic, block);
+
+ block = work;
+ }
+#endif
+ const auto next = IncOrDec ?
+ BinaryOperator::CreateAdd(refs, ConstantInt::get(refs->getType(), 1), "incr", block):
+ BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
+ new StoreInst(next, refsptr, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+}
+
+template<bool Decrement>
+void CheckRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto type8 = Type::getInt8Ty(context);
+ const auto type32 = Type::getInt32Ty(context);
+
+ const auto mark = GetMarkFromUnboxed(value, ctx, block);
+
+ const auto boxb = BasicBlock::Create(context, "boxb", ctx.Func);
+ const auto strb = BasicBlock::Create(context, "strb", ctx.Func);
+ const auto nope = BasicBlock::Create(context, "nope", ctx.Func);
+
+ const auto choise = SwitchInst::Create(mark, nope, 2U, block);
+ choise->addCase(ConstantInt::get(type8, 2), strb);
+ choise->addCase(ConstantInt::get(type8, 3), boxb);
+
+ {
+ block = strb;
+
+ const auto strptr = GetPointerFromUnboxed<false>(value, ctx, block);
+ const auto refptr = GetElementPtrInst::CreateInBounds(strptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "refptr", block);
+ const auto refs = new LoadInst(refptr, "refs", block);
+
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if constexpr (EnableStaticRefcount) {
+ const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(nope, work, magic, block);
+
+ block = work;
+ }
+#endif
+ Value* test = refs;
+
+ if constexpr (Decrement) {
+ const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
+ new StoreInst(decr, refptr, block);
+ test = decr;
+ }
+
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, test, ConstantInt::get(test->getType(), 0), "test", block);
+
+ const auto free = BasicBlock::Create(context, "free", ctx.Func);
+
+ BranchInst::Create(nope, free, good, block);
+
+ block = free;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {strptr->getType()}, false);
const auto name = "DeleteString";
ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteString));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
- CallInst::Create(func, {strptr}, "", block);
- BranchInst::Create(nope, block);
- }
-
- {
- block = boxb;
-
- const auto boxptr = GetPointerFromUnboxed<true>(value, ctx, block);;
- const auto refptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "cntptr", block);
- const auto refs = new LoadInst(refptr, "refs", block);
-
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if constexpr (EnableStaticRefcount) {
- const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
-
- const auto work = BasicBlock::Create(context, "work", ctx.Func);
- BranchInst::Create(nope, work, magic, block);
-
- block = work;
- }
-#endif
-
- Value* test = refs;
-
- if constexpr (Decrement) {
- const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
- new StoreInst(decr, refptr, block);
- test = decr;
- }
-
- const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, test, ConstantInt::get(test->getType(), 0), "test", block);
-
- const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
-
- BranchInst::Create(nope, kill, good, block);
-
- block = kill;
-
- const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
- const auto name = "DeleteBoxed";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
+ CallInst::Create(func, {strptr}, "", block);
+ BranchInst::Create(nope, block);
+ }
+
+ {
+ block = boxb;
+
+ const auto boxptr = GetPointerFromUnboxed<true>(value, ctx, block);;
+ const auto refptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(type32, 0), ConstantInt::get(type32, 1)}, "cntptr", block);
+ const auto refs = new LoadInst(refptr, "refs", block);
+
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if constexpr (EnableStaticRefcount) {
+ const auto magic = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, refs, ConstantInt::get(refs->getType(), 0), "magic", block);
+
+ const auto work = BasicBlock::Create(context, "work", ctx.Func);
+ BranchInst::Create(nope, work, magic, block);
+
+ block = work;
+ }
+#endif
+
+ Value* test = refs;
+
+ if constexpr (Decrement) {
+ const auto decr = BinaryOperator::CreateSub(refs, ConstantInt::get(refs->getType(), 1), "decr", block);
+ new StoreInst(decr, refptr, block);
+ test = decr;
+ }
+
+ const auto good = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, test, ConstantInt::get(test->getType(), 0), "test", block);
+
+ const auto kill = BasicBlock::Create(context, "kill", ctx.Func);
+
+ BranchInst::Create(nope, kill, good, block);
+
+ block = kill;
+
+ const auto fnType = FunctionType::get(Type::getVoidTy(context), {boxptr->getType()}, false);
+ const auto name = "DeleteBoxed";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(&DeleteBoxed));
const auto func = ctx.Codegen->GetModule().getOrInsertFunction(name, fnType).getCallee();
-
- CallInst::Create(func, {boxptr}, "", block);
- BranchInst::Create(nope, block);
- }
-
- block = nope;
-}
-#ifdef MAKE_UNBOXED_VALUE_LLVM_REFCOUNTION_FUNCTIONS
-Function* GenRefCountFunction(const char* label, void (*func)(Value*, const TCodegenContext&, BasicBlock*&), Type* type, const NYql::NCodegen::ICodegen::TPtr& codegen) {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
- const auto name = TString(label) += (type->isPointerTy() ? "Ptr" : "Val");
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto funcType = FunctionType::get(Type::getVoidTy(context), {type}, false);
-
- TCodegenContext ctx(codegen);
+
+ CallInst::Create(func, {boxptr}, "", block);
+ BranchInst::Create(nope, block);
+ }
+
+ block = nope;
+}
+#ifdef MAKE_UNBOXED_VALUE_LLVM_REFCOUNTION_FUNCTIONS
+Function* GenRefCountFunction(const char* label, void (*func)(Value*, const TCodegenContext&, BasicBlock*&), Type* type, const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+ const auto name = TString(label) += (type->isPointerTy() ? "Ptr" : "Val");
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto funcType = FunctionType::get(Type::getVoidTy(context), {type}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee()).getCallee();
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- auto value = &*ctx.Func->arg_begin();
-
- func(value, ctx, main);
- ReturnInst::Create(context, main);
- return ctx.Func;
-}
-
-void AddRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- CallInst::Create(GenRefCountFunction(__func__, &ChangeRefUnboxed<true>, value->getType(), ctx.Codegen), {value}, "", block);
-}
-
-void ReleaseUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- CallInst::Create(GenRefCountFunction(__func__, &ChangeRefUnboxed<false>, value->getType(), ctx.Codegen), {value}, "", block);
-}
-
-void UnRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- CallInst::Create(GenRefCountFunction(__func__, &CheckRefUnboxed<true>, value->getType(), ctx.Codegen), {value}, "", block);
-}
-
-void CleanupUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- CallInst::Create(GenRefCountFunction(__func__, &CheckRefUnboxed<false>, value->getType(), ctx.Codegen), {value}, "", block);
-}
-#else
-void AddRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- return ChangeRefUnboxed<true>(value, ctx, block);
-}
-
-void ReleaseUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- return ChangeRefUnboxed<false>(value, ctx, block);
-}
-
-void UnRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- return CheckRefUnboxed<true>(value, ctx, block);
-}
-
-void CleanupUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
- return CheckRefUnboxed<false>(value, ctx, block);
-}
-#endif
-
-void SafeUnRefUnboxed(Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
- UnRefUnboxed(pointer, ctx, block);
- new StoreInst(ConstantInt::get(pointer->getType()->getPointerElementType(), 0), pointer, block);
-}
-
-void ValueAddRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
- switch (kind) {
- case EValueRepresentation::Embedded: return;
- case EValueRepresentation::Boxed: // TODO
- case EValueRepresentation::String: // TODO
- case EValueRepresentation::Any: return AddRefUnboxed(pointer, ctx, block);
- }
-}
-
-void ValueUnRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
- switch (kind) {
- case EValueRepresentation::Embedded: return;
- case EValueRepresentation::Boxed: // TODO
- case EValueRepresentation::String: // TODO
- case EValueRepresentation::Any: return UnRefUnboxed(pointer, ctx, block);
- }
-}
-
-void ValueCleanup(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
- switch (kind) {
- case EValueRepresentation::Embedded: return;
- case EValueRepresentation::Boxed: // TODO
- case EValueRepresentation::String: // TODO
- case EValueRepresentation::Any: return CleanupUnboxed(pointer, ctx, block);
- }
-}
-
-void ValueRelease(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
- switch (kind) {
- case EValueRepresentation::Embedded: return;
- case EValueRepresentation::Boxed: // TODO
- case EValueRepresentation::String: // TODO
- case EValueRepresentation::Any: return ReleaseUnboxed(pointer, ctx, block);
- }
-}
-
-std::pair<Value*, Value*> GetVariantParts(Value* variant, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto type = Type::getInt32Ty(context);
- const auto lshr = BinaryOperator::CreateLShr(variant, ConstantInt::get(variant->getType(), 122), "lshr", block);
- const auto trunc = CastInst::Create(Instruction::Trunc, lshr, type, "trunc", block);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(type , 0), "check", block);
-
- const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
- const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto index = PHINode::Create(type, 2U, "index", done);
- const auto item = PHINode::Create(variant->getType(), 2U, "index", done);
-
- BranchInst::Create(embed, boxed, check, block);
-
- {
- block = embed;
-
- const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
- const auto mask = ConstantInt::get(variant->getType(), APInt(128, 2, init));
- const auto clean = BinaryOperator::CreateAnd(variant, mask, "clean", block);
-
- const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(type, 1), "dec", block);
- index->addIncoming(dec, block);
- item->addIncoming(clean, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = boxed;
-
- const auto place = new AllocaInst(item->getType(), 0U, "place", &ctx.Func->getEntryBlock().back());
- const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(type, variant, ctx.Codegen, block);
- CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(place, variant, ctx.Codegen, block);
- const auto clean = new LoadInst(place, "clean", block);
- ValueRelease(EValueRepresentation::Any, clean, ctx, block);
- index->addIncoming(idx, block);
- item->addIncoming(clean, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return std::make_pair(index, item);
-}
-
-Value* MakeVariant(Value* item, Value* variant, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
- const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(item->getType(), 1U, "index", done);
-
- const auto offset = ConstantInt::get(item->getType(), 122);
- const auto lshr = BinaryOperator::CreateLShr(item, offset, "lshr", block);
-
- const auto checkItem = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lshr, ConstantInt::get(lshr->getType(), 0), "check_item", block);
- const auto checkIndex = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, variant, ConstantInt::get(variant->getType(), (1U << 6U) - 1U), "check_index", block);
- const auto check = BinaryOperator::CreateAnd(checkItem, checkIndex, "and", block);
-
- BranchInst::Create(embed, boxed, check, block);
-
- {
- block = embed;
-
- const auto index = BinaryOperator::CreateAdd(variant, ConstantInt::get(variant->getType(), 1), "index", block);
- const auto extend = CastInst::Create(Instruction::ZExt, index, item->getType(), "extend", block);
- const auto shift = BinaryOperator::CreateShl(extend, offset, "shift", block);
- const auto output = BinaryOperator::CreateOr(item, shift, "output", block);
- result->addIncoming(output, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = boxed;
-
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateBoxedVariantHolder));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto signature = FunctionType::get(item->getType(), {factory->getType(), item->getType(), variant->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- const auto output = CallInst::Create(creator, {factory, item, variant}, "output", block);
- result->addIncoming(output, block);
- } else {
- const auto place = new AllocaInst(item->getType(), 0U, "place", block);
- new StoreInst(item, place, block);
- const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType(), variant->getType()}, false);
- const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
- CallInst::Create(creator, {factory, place, place, variant}, "", block);
- const auto output = new LoadInst(place, "output", block);
- result->addIncoming(output, block);
- }
-
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
-}
-
-Value* GetNodeValue(IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
- if (const auto codegen = dynamic_cast<ICodegeneratorInlineNode*>(node))
- return codegen->CreateGetValue(ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
- const auto ptr = ConstantInt::get(Type::getInt64Ty(context), intptr_t(node));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto nodeThis = CastInst::Create(Instruction::IntToPtr, ptr, ptrType, "node_this", block);
-
- const auto retPtr = new AllocaInst(Type::getInt128Ty(context), 0U, "return_ptr", &ctx.Func->getEntryBlock().back());
- const auto funType = ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ auto value = &*ctx.Func->arg_begin();
+
+ func(value, ctx, main);
+ ReturnInst::Create(context, main);
+ return ctx.Func;
+}
+
+void AddRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ CallInst::Create(GenRefCountFunction(__func__, &ChangeRefUnboxed<true>, value->getType(), ctx.Codegen), {value}, "", block);
+}
+
+void ReleaseUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ CallInst::Create(GenRefCountFunction(__func__, &ChangeRefUnboxed<false>, value->getType(), ctx.Codegen), {value}, "", block);
+}
+
+void UnRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ CallInst::Create(GenRefCountFunction(__func__, &CheckRefUnboxed<true>, value->getType(), ctx.Codegen), {value}, "", block);
+}
+
+void CleanupUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ CallInst::Create(GenRefCountFunction(__func__, &CheckRefUnboxed<false>, value->getType(), ctx.Codegen), {value}, "", block);
+}
+#else
+void AddRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ return ChangeRefUnboxed<true>(value, ctx, block);
+}
+
+void ReleaseUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ return ChangeRefUnboxed<false>(value, ctx, block);
+}
+
+void UnRefUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ return CheckRefUnboxed<true>(value, ctx, block);
+}
+
+void CleanupUnboxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block) {
+ return CheckRefUnboxed<false>(value, ctx, block);
+}
+#endif
+
+void SafeUnRefUnboxed(Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
+ UnRefUnboxed(pointer, ctx, block);
+ new StoreInst(ConstantInt::get(pointer->getType()->getPointerElementType(), 0), pointer, block);
+}
+
+void ValueAddRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
+ switch (kind) {
+ case EValueRepresentation::Embedded: return;
+ case EValueRepresentation::Boxed: // TODO
+ case EValueRepresentation::String: // TODO
+ case EValueRepresentation::Any: return AddRefUnboxed(pointer, ctx, block);
+ }
+}
+
+void ValueUnRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
+ switch (kind) {
+ case EValueRepresentation::Embedded: return;
+ case EValueRepresentation::Boxed: // TODO
+ case EValueRepresentation::String: // TODO
+ case EValueRepresentation::Any: return UnRefUnboxed(pointer, ctx, block);
+ }
+}
+
+void ValueCleanup(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
+ switch (kind) {
+ case EValueRepresentation::Embedded: return;
+ case EValueRepresentation::Boxed: // TODO
+ case EValueRepresentation::String: // TODO
+ case EValueRepresentation::Any: return CleanupUnboxed(pointer, ctx, block);
+ }
+}
+
+void ValueRelease(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block) {
+ switch (kind) {
+ case EValueRepresentation::Embedded: return;
+ case EValueRepresentation::Boxed: // TODO
+ case EValueRepresentation::String: // TODO
+ case EValueRepresentation::Any: return ReleaseUnboxed(pointer, ctx, block);
+ }
+}
+
+std::pair<Value*, Value*> GetVariantParts(Value* variant, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto type = Type::getInt32Ty(context);
+ const auto lshr = BinaryOperator::CreateLShr(variant, ConstantInt::get(variant->getType(), 122), "lshr", block);
+ const auto trunc = CastInst::Create(Instruction::Trunc, lshr, type, "trunc", block);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, trunc, ConstantInt::get(type , 0), "check", block);
+
+ const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
+ const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto index = PHINode::Create(type, 2U, "index", done);
+ const auto item = PHINode::Create(variant->getType(), 2U, "index", done);
+
+ BranchInst::Create(embed, boxed, check, block);
+
+ {
+ block = embed;
+
+ const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFULL};
+ const auto mask = ConstantInt::get(variant->getType(), APInt(128, 2, init));
+ const auto clean = BinaryOperator::CreateAnd(variant, mask, "clean", block);
+
+ const auto dec = BinaryOperator::CreateSub(trunc, ConstantInt::get(type, 1), "dec", block);
+ index->addIncoming(dec, block);
+ item->addIncoming(clean, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = boxed;
+
+ const auto place = new AllocaInst(item->getType(), 0U, "place", &ctx.Func->getEntryBlock().back());
+ const auto idx = CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantIndex>(type, variant, ctx.Codegen, block);
+ CallBoxedValueVirtualMethod<NUdf::TBoxedValueAccessor::EMethod::GetVariantItem>(place, variant, ctx.Codegen, block);
+ const auto clean = new LoadInst(place, "clean", block);
+ ValueRelease(EValueRepresentation::Any, clean, ctx, block);
+ index->addIncoming(idx, block);
+ item->addIncoming(clean, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return std::make_pair(index, item);
+}
+
+Value* MakeVariant(Value* item, Value* variant, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto boxed = BasicBlock::Create(context, "boxed", ctx.Func);
+ const auto embed = BasicBlock::Create(context, "embed", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(item->getType(), 1U, "index", done);
+
+ const auto offset = ConstantInt::get(item->getType(), 122);
+ const auto lshr = BinaryOperator::CreateLShr(item, offset, "lshr", block);
+
+ const auto checkItem = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lshr, ConstantInt::get(lshr->getType(), 0), "check_item", block);
+ const auto checkIndex = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, variant, ConstantInt::get(variant->getType(), (1U << 6U) - 1U), "check_index", block);
+ const auto check = BinaryOperator::CreateAnd(checkItem, checkIndex, "and", block);
+
+ BranchInst::Create(embed, boxed, check, block);
+
+ {
+ block = embed;
+
+ const auto index = BinaryOperator::CreateAdd(variant, ConstantInt::get(variant->getType(), 1), "index", block);
+ const auto extend = CastInst::Create(Instruction::ZExt, index, item->getType(), "extend", block);
+ const auto shift = BinaryOperator::CreateShl(extend, offset, "shift", block);
+ const auto output = BinaryOperator::CreateOr(item, shift, "output", block);
+ result->addIncoming(output, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = boxed;
+
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateBoxedVariantHolder));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto signature = FunctionType::get(item->getType(), {factory->getType(), item->getType(), variant->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ const auto output = CallInst::Create(creator, {factory, item, variant}, "output", block);
+ result->addIncoming(output, block);
+ } else {
+ const auto place = new AllocaInst(item->getType(), 0U, "place", block);
+ new StoreInst(item, place, block);
+ const auto signature = FunctionType::get(Type::getVoidTy(context), {factory->getType(), place->getType(), place->getType(), variant->getType()}, false);
+ const auto creator = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(signature), "creator", block);
+ CallInst::Create(creator, {factory, place, place, variant}, "", block);
+ const auto output = new LoadInst(place, "output", block);
+ result->addIncoming(output, block);
+ }
+
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
+}
+
+Value* GetNodeValue(IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
+ if (const auto codegen = dynamic_cast<ICodegeneratorInlineNode*>(node))
+ return codegen->CreateGetValue(ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+ const auto ptr = ConstantInt::get(Type::getInt64Ty(context), intptr_t(node));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto nodeThis = CastInst::Create(Instruction::IntToPtr, ptr, ptrType, "node_this", block);
+
+ const auto retPtr = new AllocaInst(Type::getInt128Ty(context), 0U, "return_ptr", &ctx.Func->getEntryBlock().back());
+ const auto funType = ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
FunctionType::get(Type::getVoidTy(context), {retPtr->getType(), nodeThis->getType(), ctx.Ctx->getType()}, false):
FunctionType::get(Type::getVoidTy(context), {nodeThis->getType(), retPtr->getType(), ctx.Ctx->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto nodeVTable = CastInst::Create(Instruction::IntToPtr, ptr, ptrTableType, "node_vtable", block);
-
- const auto table = new LoadInst(nodeVTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodIndex(&IComputationNode::GetValue))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto nodeVTable = CastInst::Create(Instruction::IntToPtr, ptr, ptrTableType, "node_vtable", block);
+
+ const auto table = new LoadInst(nodeVTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodIndex(&IComputationNode::GetValue))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
CallInst::Create(func, {retPtr, nodeThis, ctx.Ctx}, "", block);
- } else {
+ } else {
CallInst::Create(func, {nodeThis, retPtr, ctx.Ctx}, "", block);
- }
-
- ValueRelease(node->GetRepresentation(), retPtr, ctx, block);
- const auto result = new LoadInst(retPtr, "return", false, block);
- return result;
-}
-
-void GetNodeValue(Value* value, IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
- if (const auto codegen = dynamic_cast<ICodegeneratorInlineNode*>(node)) {
- const auto v = codegen->CreateGetValue(ctx, block);
- new StoreInst(v, value, block);
- ValueAddRef(node->GetRepresentation(), value, ctx, block);
- return;
- }
-
- auto& context = ctx.Codegen->GetContext();
- const auto ptr = ConstantInt::get(Type::getInt64Ty(context), intptr_t(node));
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
- const auto nodeThis = CastInst::Create(Instruction::IntToPtr, ptr, ptrType, "node_this", block);
-
- const auto funType = ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ }
+
+ ValueRelease(node->GetRepresentation(), retPtr, ctx, block);
+ const auto result = new LoadInst(retPtr, "return", false, block);
+ return result;
+}
+
+void GetNodeValue(Value* value, IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
+ if (const auto codegen = dynamic_cast<ICodegeneratorInlineNode*>(node)) {
+ const auto v = codegen->CreateGetValue(ctx, block);
+ new StoreInst(v, value, block);
+ ValueAddRef(node->GetRepresentation(), value, ctx, block);
+ return;
+ }
+
+ auto& context = ctx.Codegen->GetContext();
+ const auto ptr = ConstantInt::get(Type::getInt64Ty(context), intptr_t(node));
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
+ const auto nodeThis = CastInst::Create(Instruction::IntToPtr, ptr, ptrType, "node_this", block);
+
+ const auto funType = ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
FunctionType::get(Type::getVoidTy(context), {value->getType(), nodeThis->getType(), ctx.Ctx->getType()}, false):
FunctionType::get(Type::getVoidTy(context), {nodeThis->getType(), value->getType(), ctx.Ctx->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto nodeVTable = CastInst::Create(Instruction::IntToPtr, ptr, ptrTableType, "node_vtable", block);
-
- const auto table = new LoadInst(nodeVTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodIndex(&IComputationNode::GetValue))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto nodeVTable = CastInst::Create(Instruction::IntToPtr, ptr, ptrTableType, "node_vtable", block);
+
+ const auto table = new LoadInst(nodeVTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodIndex(&IComputationNode::GetValue))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
CallInst::Create(func, {value, nodeThis, ctx.Ctx}, "", block);
- } else {
+ } else {
CallInst::Create(func, {nodeThis, value, ctx.Ctx}, "", block);
- }
-}
-
-ICodegeneratorInlineWideNode::TGenerateResult GetNodeValues(IComputationWideFlowNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
- if (const auto codegen = dynamic_cast<ICodegeneratorInlineWideNode*>(node))
- return codegen->GenGetValues(ctx, block);
- return {nullptr, {}};
-}
-
-Value* GenNewArray(const TCodegenContext& ctx, Value* size, Value* items, BasicBlock* block) {
- auto& context = ctx.Codegen->GetContext();
- const auto fact = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateDirectArrayHolder));
- const auto valueType = Type::getInt128Ty(context);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {fact->getType(), size->getType(), items->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- return CallInst::Create(funcPtr, {fact, size, items}, "array", block);
- } else {
- const auto resultPtr = new AllocaInst(valueType, 0U, "return", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), resultPtr->getType(), size->getType(), items->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {fact, resultPtr, size, items}, "", block);
- return new LoadInst(resultPtr, "array", block);
- }
-}
-
-Value* GetMemoryUsed(ui64 limit, const TCodegenContext& ctx, BasicBlock* block) {
- if (!limit) {
- return nullptr;
- }
-
- auto& context = ctx.Codegen->GetContext();
- const auto fact = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetMemoryUsed));
- const auto funType = FunctionType::get(Type::getInt64Ty(context), {fact->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "get_used", block);
- return CallInst::Create(funcPtr, {fact}, "mem_used", block);
-}
-
-template <bool TrackRss>
-Value* CheckAdjustedMemLimit(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
-
- if (!limit || !init) {
- return ConstantInt::getFalse(context);
- }
-
- const auto indexType = Type::getInt32Ty(context);
-
- if (TrackRss) {
- const auto rssPtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 5)}, "rss_ptr", block);
- const auto rss = new LoadInst(rssPtr, "adjustor", block);
- const auto inc = BinaryOperator::CreateAdd(rss, ConstantInt::get(rss->getType(), 1), "inc", block);
- new StoreInst(inc, rssPtr, block);
- const auto mod = BinaryOperator::CreateURem(rss, ConstantInt::get(rss->getType(), STEP_FOR_RSS_CHECK), "mod", block);
- const auto now = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, ConstantInt::get(mod->getType() , 0), "now", block);
-
- const auto call = BasicBlock::Create(context, "call", ctx.Func);
- const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
-
- BranchInst::Create(call, skip, now, block);
-
- block = call;
- const auto fact = ctx.Ctx;
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TComputationContext::UpdateUsageAdjustor));
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ctx.Ctx->getType(), Type::getInt64Ty(context)}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "update", block);
- CallInst::Create(funcPtr, {ctx.Ctx, ConstantInt::get(init->getType(), limit)}, "", block);
-
- BranchInst::Create(skip, block);
-
- block = skip;
- }
-
- const auto adjPtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 4)}, "adj_ptr", block);
- const auto adjustor = new LoadInst(adjPtr, "adjustor", block);
-
- const auto curr = GetMemoryUsed(limit, ctx, block);
- const auto cast = CastInst::Create(Instruction::UIToFP, curr, adjustor->getType(), "cast", block);
- const auto used = BinaryOperator::CreateFMul(cast, adjustor, "used", block);
- const auto add = BinaryOperator::CreateAdd(init, ConstantInt::get(init->getType(), limit), "add", block);
- const auto upper = CastInst::Create(Instruction::UIToFP, add, adjustor->getType(), "upper", block);
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, used, upper, "enough", block);
-}
-
-template Value* CheckAdjustedMemLimit<false>(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
-template Value* CheckAdjustedMemLimit<true>(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
-
-Value* WrapArgumentForWindows(Value* arg, const TCodegenContext& ctx, BasicBlock* block) {
- if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- return arg;
- }
-
- const auto newArg = new AllocaInst(arg->getType(), 0, "argument", block);
- new StoreInst(arg, newArg, block);
- return newArg;
-}
-
-}
-}
-#endif
+ }
+}
+
+ICodegeneratorInlineWideNode::TGenerateResult GetNodeValues(IComputationWideFlowNode* node, const TCodegenContext& ctx, BasicBlock*& block) {
+ if (const auto codegen = dynamic_cast<ICodegeneratorInlineWideNode*>(node))
+ return codegen->GenGetValues(ctx, block);
+ return {nullptr, {}};
+}
+
+Value* GenNewArray(const TCodegenContext& ctx, Value* size, Value* items, BasicBlock* block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto fact = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateDirectArrayHolder));
+ const auto valueType = Type::getInt128Ty(context);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {fact->getType(), size->getType(), items->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ return CallInst::Create(funcPtr, {fact, size, items}, "array", block);
+ } else {
+ const auto resultPtr = new AllocaInst(valueType, 0U, "return", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), resultPtr->getType(), size->getType(), items->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {fact, resultPtr, size, items}, "", block);
+ return new LoadInst(resultPtr, "array", block);
+ }
+}
+
+Value* GetMemoryUsed(ui64 limit, const TCodegenContext& ctx, BasicBlock* block) {
+ if (!limit) {
+ return nullptr;
+ }
+
+ auto& context = ctx.Codegen->GetContext();
+ const auto fact = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetMemoryUsed));
+ const auto funType = FunctionType::get(Type::getInt64Ty(context), {fact->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "get_used", block);
+ return CallInst::Create(funcPtr, {fact}, "mem_used", block);
+}
+
+template <bool TrackRss>
+Value* CheckAdjustedMemLimit(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+
+ if (!limit || !init) {
+ return ConstantInt::getFalse(context);
+ }
+
+ const auto indexType = Type::getInt32Ty(context);
+
+ if (TrackRss) {
+ const auto rssPtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 5)}, "rss_ptr", block);
+ const auto rss = new LoadInst(rssPtr, "adjustor", block);
+ const auto inc = BinaryOperator::CreateAdd(rss, ConstantInt::get(rss->getType(), 1), "inc", block);
+ new StoreInst(inc, rssPtr, block);
+ const auto mod = BinaryOperator::CreateURem(rss, ConstantInt::get(rss->getType(), STEP_FOR_RSS_CHECK), "mod", block);
+ const auto now = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mod, ConstantInt::get(mod->getType() , 0), "now", block);
+
+ const auto call = BasicBlock::Create(context, "call", ctx.Func);
+ const auto skip = BasicBlock::Create(context, "skip", ctx.Func);
+
+ BranchInst::Create(call, skip, now, block);
+
+ block = call;
+ const auto fact = ctx.Ctx;
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TComputationContext::UpdateUsageAdjustor));
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ctx.Ctx->getType(), Type::getInt64Ty(context)}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "update", block);
+ CallInst::Create(funcPtr, {ctx.Ctx, ConstantInt::get(init->getType(), limit)}, "", block);
+
+ BranchInst::Create(skip, block);
+
+ block = skip;
+ }
+
+ const auto adjPtr = GetElementPtrInst::CreateInBounds(ctx.Ctx, {ConstantInt::get(indexType, 0), ConstantInt::get(indexType, 4)}, "adj_ptr", block);
+ const auto adjustor = new LoadInst(adjPtr, "adjustor", block);
+
+ const auto curr = GetMemoryUsed(limit, ctx, block);
+ const auto cast = CastInst::Create(Instruction::UIToFP, curr, adjustor->getType(), "cast", block);
+ const auto used = BinaryOperator::CreateFMul(cast, adjustor, "used", block);
+ const auto add = BinaryOperator::CreateAdd(init, ConstantInt::get(init->getType(), limit), "add", block);
+ const auto upper = CastInst::Create(Instruction::UIToFP, add, adjustor->getType(), "upper", block);
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, used, upper, "enough", block);
+}
+
+template Value* CheckAdjustedMemLimit<false>(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
+template Value* CheckAdjustedMemLimit<true>(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
+
+Value* WrapArgumentForWindows(Value* arg, const TCodegenContext& ctx, BasicBlock* block) {
+ if (ctx.Codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ return arg;
+ }
+
+ const auto newArg = new AllocaInst(arg->getType(), 0, "argument", block);
+ new StoreInst(arg, newArg, block);
+ return newArg;
+}
+
+}
+}
+#endif
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h
index 5a78155e64..d9feede204 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h
@@ -1,1204 +1,1204 @@
-#pragma once
-
-#include "mkql_computation_node_impl.h"
-#include "mkql_custom_list.h"
-
+#pragma once
+
+#include "mkql_computation_node_impl.h"
+#include "mkql_custom_list.h"
+
#include <ydb/library/yql/minikql/codegen/codegen.h>
-#include <type_traits>
-
+#include <type_traits>
+
#ifdef MKQL_DISABLE_CODEGEN
-namespace NKikimr {
-namespace NMiniKQL {
-
-using TUnboxedImmutableCodegeneratorNode = TUnboxedImmutableComputationNode;
+namespace NKikimr {
+namespace NMiniKQL {
+
+using TUnboxedImmutableCodegeneratorNode = TUnboxedImmutableComputationNode;
using TUnboxedImmutableRunCodegeneratorNode = TUnboxedImmutableComputationNode;
-using TExternalCodegeneratorNode = TExternalComputationNode;
-using TWideFlowProxyCodegeneratorNode = TWideFlowProxyComputationNode;
-
-template <typename TDerived>
-using TDecoratorCodegeneratorNode = TDecoratorComputationNode<TDerived>;
-
-template <typename TDerived>
+using TExternalCodegeneratorNode = TExternalComputationNode;
+using TWideFlowProxyCodegeneratorNode = TWideFlowProxyComputationNode;
+
+template <typename TDerived>
+using TDecoratorCodegeneratorNode = TDecoratorComputationNode<TDerived>;
+
+template <typename TDerived>
using TBinaryCodegeneratorNode = TBinaryComputationNode<TDerived>;
-
-template <typename TDerived>
-using TMutableCodegeneratorNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TMutableCodegeneratorPtrNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TMutableCodegeneratorFallbackNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TMutableCodegeneratorRootNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TCustomValueCodegeneratorNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TBothWaysCodegeneratorNode = TMutableComputationNode<TDerived>;
-
-template <typename TDerived>
-using TStatelessFlowCodegeneratorNode = TStatelessFlowComputationNode<TDerived>;
-
-template <typename TDerived>
-using TStatelessWideFlowCodegeneratorNode = TStatelessWideFlowComputationNode<TDerived>;
-
+
+template <typename TDerived>
+using TMutableCodegeneratorNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TMutableCodegeneratorPtrNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TMutableCodegeneratorFallbackNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TMutableCodegeneratorRootNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TCustomValueCodegeneratorNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TBothWaysCodegeneratorNode = TMutableComputationNode<TDerived>;
+
+template <typename TDerived>
+using TStatelessFlowCodegeneratorNode = TStatelessFlowComputationNode<TDerived>;
+
+template <typename TDerived>
+using TStatelessWideFlowCodegeneratorNode = TStatelessWideFlowComputationNode<TDerived>;
+
template <typename TDerived, bool SerializableState = false>
using TStatefulWideFlowCodegeneratorNode = TStatefulWideFlowComputationNode<TDerived, SerializableState>;
-
-template <typename TDerived>
-using TPairStateWideFlowCodegeneratorNode = TPairStateWideFlowComputationNode<TDerived>;
-
-template <typename TDerived>
-using TStatelessFlowCodegeneratorRootNode = TStatelessFlowComputationNode<TDerived>;
-
+
+template <typename TDerived>
+using TPairStateWideFlowCodegeneratorNode = TPairStateWideFlowComputationNode<TDerived>;
+
+template <typename TDerived>
+using TStatelessFlowCodegeneratorRootNode = TStatelessFlowComputationNode<TDerived>;
+
template <typename TDerived, bool SerializableState = false>
using TStatefulFlowCodegeneratorNode = TStatefulFlowComputationNode<TDerived, SerializableState>;
-
-template <typename TDerived>
-using TPairStateFlowCodegeneratorNode = TPairStateFlowComputationNode<TDerived>;
-
-template <typename TDerived>
-using TFlowSourceCodegeneratorNode = TFlowSourceComputationNode<TDerived>;
-
-}
-}
-#else
-#include <llvm/IR/Value.h>
-#include <llvm/IR/BasicBlock.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Instructions.h>
-#include <llvm/IR/Constants.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-using namespace llvm;
-
-Type* GetCompContextType(LLVMContext &context);
-
-struct TCodegenContext {
- TCodegenContext(const NYql::NCodegen::ICodegen::TPtr& codegen) : Codegen(codegen) {}
-
- const NYql::NCodegen::ICodegen::TPtr& Codegen;
- Function* Func = nullptr;
- Argument* Ctx = nullptr;
- bool AlwaysInline = false;
-
- Value* GetFactory() const;
- Value* GetStat() const;
- Value* GetMutables() const;
- Value* GetBuilder() const;
-
-private:
- Value * Factory = nullptr;
- Value * Stat = nullptr;
- Value * Mutables = nullptr;
- Value * Builder = nullptr;
-};
-
-using TGeneratorPtr = Value* (*)(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block);
-
-class ICodegeneratorRootNode {
-public:
+
+template <typename TDerived>
+using TPairStateFlowCodegeneratorNode = TPairStateFlowComputationNode<TDerived>;
+
+template <typename TDerived>
+using TFlowSourceCodegeneratorNode = TFlowSourceComputationNode<TDerived>;
+
+}
+}
+#else
+#include <llvm/IR/Value.h>
+#include <llvm/IR/BasicBlock.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/Constants.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+using namespace llvm;
+
+Type* GetCompContextType(LLVMContext &context);
+
+struct TCodegenContext {
+ TCodegenContext(const NYql::NCodegen::ICodegen::TPtr& codegen) : Codegen(codegen) {}
+
+ const NYql::NCodegen::ICodegen::TPtr& Codegen;
+ Function* Func = nullptr;
+ Argument* Ctx = nullptr;
+ bool AlwaysInline = false;
+
+ Value* GetFactory() const;
+ Value* GetStat() const;
+ Value* GetMutables() const;
+ Value* GetBuilder() const;
+
+private:
+ Value * Factory = nullptr;
+ Value * Stat = nullptr;
+ Value * Mutables = nullptr;
+ Value * Builder = nullptr;
+};
+
+using TGeneratorPtr = Value* (*)(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block);
+
+class ICodegeneratorRootNode {
+public:
virtual ~ICodegeneratorRootNode() {}
- virtual void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) = 0;
- virtual void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) = 0;
-};
-
-class ICodegeneratorInlineNode {
-public:
+ virtual void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) = 0;
+ virtual void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) = 0;
+};
+
+class ICodegeneratorInlineNode {
+public:
virtual ~ICodegeneratorInlineNode() {}
- virtual Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
-};
-
-class ICodegeneratorInlineWideNode {
-public:
- virtual ~ICodegeneratorInlineWideNode() {}
-
- using TGettersList = std::vector<std::function<Value*(const TCodegenContext& ctx, BasicBlock*&)>>;
- using TGenerateResult = std::pair<Value*, TGettersList>;
-
- virtual TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
-};
-
-class IWideFlowProxyCodegeneratorNode: public ICodegeneratorInlineWideNode
-{
-public:
- using TGenerator = std::function<TGenerateResult(const TCodegenContext&, BasicBlock*&)>;
-
- virtual void SetGenerator(TGenerator&& generator) = 0;
-
- virtual void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
-};
-
-class ICodegeneratorExternalNode : public ICodegeneratorInlineNode {
-public:
- virtual Value* CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
- virtual void CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const = 0;
- virtual Value* CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const = 0;
- virtual void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
- virtual void SetTemporaryValue(Value* value) = 0;
- virtual void SetValueGetter(Function* value) = 0;
-};
-
+ virtual Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
+};
+
+class ICodegeneratorInlineWideNode {
+public:
+ virtual ~ICodegeneratorInlineWideNode() {}
+
+ using TGettersList = std::vector<std::function<Value*(const TCodegenContext& ctx, BasicBlock*&)>>;
+ using TGenerateResult = std::pair<Value*, TGettersList>;
+
+ virtual TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
+};
+
+class IWideFlowProxyCodegeneratorNode: public ICodegeneratorInlineWideNode
+{
+public:
+ using TGenerator = std::function<TGenerateResult(const TCodegenContext&, BasicBlock*&)>;
+
+ virtual void SetGenerator(TGenerator&& generator) = 0;
+
+ virtual void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
+};
+
+class ICodegeneratorExternalNode : public ICodegeneratorInlineNode {
+public:
+ virtual Value* CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
+ virtual void CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const = 0;
+ virtual Value* CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const = 0;
+ virtual void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const = 0;
+ virtual void SetTemporaryValue(Value* value) = 0;
+ virtual void SetValueGetter(Function* value) = 0;
+};
+
class ICodegeneratorRunNode {
public:
virtual ~ICodegeneratorRunNode() {}
- virtual void CreateRun(const TCodegenContext& ctx, BasicBlock*& block, Value* result, Value* args) const = 0;
+ virtual void CreateRun(const TCodegenContext& ctx, BasicBlock*& block, Value* result, Value* args) const = 0;
};
-size_t GetMethodPtrIndex(uintptr_t ptr);
-
-template<typename Method>
-inline size_t GetMethodIndex(Method method) {
- uintptr_t ptr;
- std::memcpy(&ptr, &method, sizeof(uintptr_t));
+size_t GetMethodPtrIndex(uintptr_t ptr);
+
+template<typename Method>
+inline size_t GetMethodIndex(Method method) {
+ uintptr_t ptr;
+ std::memcpy(&ptr, &method, sizeof(uintptr_t));
return GetMethodPtrIndex(ptr);
-}
-
-template<typename Method>
-inline uintptr_t GetMethodPtr(Method method) {
- uintptr_t ptr;
- std::memcpy(&ptr, &method, sizeof(uintptr_t));
- return ptr;
-}
-
-Value* WrapArgumentForWindows(Value* arg, const TCodegenContext& ctx, BasicBlock* block);
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = FunctionType::get(returnType, {boxed->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- const auto call = CallInst::Create(func, {boxed}, returnType->isVoidTy() ? "" : "return", block);
- return call;
-}
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
- FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType()}, false):
- FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- CallInst::Create(func, {output, boxed}, "", block);
- } else {
- CallInst::Create(func, {boxed, output}, "", block);
- }
-}
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* argument) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
- FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType(), argument->getType()}, false):
- FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType(), argument->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- CallInst::Create(func, {output, boxed, argument}, "", block);
- } else {
- CallInst::Create(func, {boxed, output, argument}, "", block);
- }
-}
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* argument) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = FunctionType::get(returnType, {boxed->getType(), argument->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- const auto call = CallInst::Create(func, {boxed, argument}, returnType->isVoidTy() ? "" : "return", block);
- return call;
-}
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* arg1, Value* arg2) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
- FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType(), arg1->getType(), arg2->getType()}, false):
- FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType(), arg1->getType(), arg2->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- CallInst::Create(func, {output, boxed, arg1, arg2}, "", block);
- } else {
- CallInst::Create(func, {boxed, output, arg1, arg2}, "", block);
- }
-}
-
-template<NUdf::TBoxedValueAccessor::EMethod Method>
-Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* arg1, Value* arg2) {
- auto& context = codegen->GetContext();
-
- const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
- const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
- const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
-
- const auto funType = FunctionType::get(returnType, {boxed->getType(), arg1->getType(), arg2->getType()}, false);
- const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
- const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
-
- const auto table = new LoadInst(vTable, "table", false, block);
- const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
- const auto func = new LoadInst(elem, "func", false, block);
-
- const auto call = CallInst::Create(func, {boxed, arg1, arg2}, returnType->isVoidTy() ? "" : "return", block);
- return call;
-}
-
-template<typename Method>
-Value* CallUnaryUnboxedValueFunction(Method method, Type* result, Value* arg, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block)
-{
- auto& context = codegen->GetContext();
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(method));
- if (NYql::NCodegen::ETarget::Windows != codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(result, {arg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- const auto call = CallInst::Create(funcPtr, {arg}, "call", block);
- return call;
- } else {
- const auto ptrArg = new AllocaInst(arg->getType(), 0U, "arg", block);
- new StoreInst(arg, ptrArg, block);
-
- if (Type::getInt128Ty(context) == result) {
- const auto ptrResult = new AllocaInst(result, 0U, "result", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- CallInst::Create(funcPtr, {ptrResult, ptrArg}, "", block);
- const auto res = new LoadInst(ptrResult, "res", block);
- return res;
- } else {
- const auto funType = FunctionType::get(result, {ptrArg->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- const auto call = CallInst::Create(funcPtr, {ptrArg}, "call", block);
- return call;
- }
- }
-}
-
-template<typename Method>
-Value* CallBinaryUnboxedValueFunction(Method method, Type* result, Value* left, Value* right, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block)
-{
- auto& context = codegen->GetContext();
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(method));
- if (NYql::NCodegen::ETarget::Windows != codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(result, {left->getType(), right->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- const auto call = CallInst::Create(funcPtr, {left, right}, "call", block);
- return call;
- } else {
- const auto ptrLeft = new AllocaInst(left->getType(), 0U, "left", block);
- const auto ptrRight = new AllocaInst(right->getType(), 0U, "right", block);
- new StoreInst(left, ptrLeft, block);
- new StoreInst(right, ptrRight, block);
-
- if (Type::getInt128Ty(context) == result) {
- const auto ptrResult = new AllocaInst(result, 0U, "result", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrLeft->getType(), ptrRight->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- CallInst::Create(funcPtr, {ptrResult, ptrLeft, ptrRight}, "", block);
- const auto res = new LoadInst(ptrResult, "res", block);
- return res;
- } else {
- const auto funType = FunctionType::get(result, {ptrLeft->getType(), ptrRight->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
- const auto call = CallInst::Create(funcPtr, {ptrLeft, ptrRight}, "call", block);
- return call;
- }
- }
-}
-
-void AddRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
-void UnRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
-void CleanupBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
-
-void SafeUnRefUnboxed(Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
-
-void ValueAddRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
-void ValueUnRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
-void ValueCleanup(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
-void ValueRelease(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
-
-std::pair<Value*, Value*> GetVariantParts(Value* variant, const TCodegenContext& ctx, BasicBlock*& block);
-Value* MakeVariant(Value* item, Value* variant, const TCodegenContext& ctx, BasicBlock*& block);
-
-Value* GetNodeValue(IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block);
-void GetNodeValue(Value* value, IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block);
-
-ICodegeneratorInlineWideNode::TGenerateResult GetNodeValues(IComputationWideFlowNode* node, const TCodegenContext& ctx, BasicBlock*& block);
-
-Function* GenerateCompareFunction(
- const NYql::NCodegen::ICodegen::TPtr& codegen,
- const TString& name,
- IComputationExternalNode* left,
- IComputationExternalNode* right,
- IComputationNode* compare
-);
-
-Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types);
-Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types);
-
-Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types);
-Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types);
-
-template <typename TDerived>
-class TDecoratorCodegeneratorNode: public TDecoratorComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TDecoratorComputationNode<TDerived>;
-protected:
- TDecoratorCodegeneratorNode(IComputationNode* node, EValueRepresentation kind)
- : TBase(node, kind)
- {}
-
- TDecoratorCodegeneratorNode(IComputationNode* node)
- : TBase(node)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- const auto arg = GetNodeValue(this->Node, ctx, block);
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, arg, block);
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- ValueRelease(this->Node->GetRepresentation(), load, ctx, block);
- return load;
- } else {
- return value;
- }
- }
-};
-
-template <typename TDerived>
-class TStatelessFlowCodegeneratorNode: public TStatelessFlowComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TStatelessFlowComputationNode<TDerived>;
-protected:
- TStatelessFlowCodegeneratorNode(const IComputationNode* source, EValueRepresentation kind)
- : TBase(source, kind)
- {}
-
- TStatelessFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind)
- : TBase(mutables, source, kind)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
- return load;
- } else {
- return value;
- }
- }
-};
-
-template <typename TDerived>
-class TStatelessWideFlowCodegeneratorNode: public TStatelessWideFlowComputationNode<TDerived>, public ICodegeneratorInlineWideNode
-{
-using TBase = TStatelessWideFlowCodegeneratorNode<TDerived>;
-protected:
- TStatelessWideFlowCodegeneratorNode(const IComputationNode* source)
- : TStatelessWideFlowComputationNode<TDerived>(source)
- {}
-
- TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
- return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, block);
- }
-};
-
-template <typename TDerived>
-class TFlowSourceCodegeneratorNode: public TFlowSourceComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TFlowSourceComputationNode<TDerived>;
-protected:
- TFlowSourceCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind, EValueRepresentation stateKind)
- : TBase(mutables, kind, stateKind)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- auto& context = ctx.Codegen->GetContext();
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
-
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, statePtr, block);
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
- return load;
- } else {
- return value;
- }
- }
-};
-
+}
+
+template<typename Method>
+inline uintptr_t GetMethodPtr(Method method) {
+ uintptr_t ptr;
+ std::memcpy(&ptr, &method, sizeof(uintptr_t));
+ return ptr;
+}
+
+Value* WrapArgumentForWindows(Value* arg, const TCodegenContext& ctx, BasicBlock* block);
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = FunctionType::get(returnType, {boxed->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ const auto call = CallInst::Create(func, {boxed}, returnType->isVoidTy() ? "" : "return", block);
+ return call;
+}
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
+ FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType()}, false):
+ FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ CallInst::Create(func, {output, boxed}, "", block);
+ } else {
+ CallInst::Create(func, {boxed, output}, "", block);
+ }
+}
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* argument) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
+ FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType(), argument->getType()}, false):
+ FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType(), argument->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ CallInst::Create(func, {output, boxed, argument}, "", block);
+ } else {
+ CallInst::Create(func, {boxed, output, argument}, "", block);
+ }
+}
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* argument) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = FunctionType::get(returnType, {boxed->getType(), argument->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ const auto call = CallInst::Create(func, {boxed, argument}, returnType->isVoidTy() ? "" : "return", block);
+ return call;
+}
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+void CallBoxedValueVirtualMethod(Value* output, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* arg1, Value* arg2) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) ?
+ FunctionType::get(Type::getVoidTy(context), {output->getType(), boxed->getType(), arg1->getType(), arg2->getType()}, false):
+ FunctionType::get(Type::getVoidTy(context), {boxed->getType(), output->getType(), arg1->getType(), arg2->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ CallInst::Create(func, {output, boxed, arg1, arg2}, "", block);
+ } else {
+ CallInst::Create(func, {boxed, output, arg1, arg2}, "", block);
+ }
+}
+
+template<NUdf::TBoxedValueAccessor::EMethod Method>
+Value* CallBoxedValueVirtualMethod(Type* returnType, Value* value, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block, Value* arg1, Value* arg2) {
+ auto& context = codegen->GetContext();
+
+ const auto data = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "data", block);
+ const auto ptrStructType = PointerType::getUnqual(StructType::get(context));
+ const auto boxed = CastInst::Create(Instruction::IntToPtr, data, ptrStructType, "boxed", block);
+
+ const auto funType = FunctionType::get(returnType, {boxed->getType(), arg1->getType(), arg2->getType()}, false);
+ const auto ptrTableType = PointerType::getUnqual(PointerType::getUnqual(PointerType::getUnqual(funType)));
+ const auto vTable = CastInst::Create(Instruction::IntToPtr, data, ptrTableType, "vtable", block);
+
+ const auto table = new LoadInst(vTable, "table", false, block);
+ const auto elem = GetElementPtrInst::CreateInBounds(table, {ConstantInt::get(Type::getInt64Ty(context), GetMethodPtrIndex(NUdf::TBoxedValueAccessor::GetMethodPtr<Method>()))}, "element", block);
+ const auto func = new LoadInst(elem, "func", false, block);
+
+ const auto call = CallInst::Create(func, {boxed, arg1, arg2}, returnType->isVoidTy() ? "" : "return", block);
+ return call;
+}
+
+template<typename Method>
+Value* CallUnaryUnboxedValueFunction(Method method, Type* result, Value* arg, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block)
+{
+ auto& context = codegen->GetContext();
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(method));
+ if (NYql::NCodegen::ETarget::Windows != codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(result, {arg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ const auto call = CallInst::Create(funcPtr, {arg}, "call", block);
+ return call;
+ } else {
+ const auto ptrArg = new AllocaInst(arg->getType(), 0U, "arg", block);
+ new StoreInst(arg, ptrArg, block);
+
+ if (Type::getInt128Ty(context) == result) {
+ const auto ptrResult = new AllocaInst(result, 0U, "result", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ CallInst::Create(funcPtr, {ptrResult, ptrArg}, "", block);
+ const auto res = new LoadInst(ptrResult, "res", block);
+ return res;
+ } else {
+ const auto funType = FunctionType::get(result, {ptrArg->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ const auto call = CallInst::Create(funcPtr, {ptrArg}, "call", block);
+ return call;
+ }
+ }
+}
+
+template<typename Method>
+Value* CallBinaryUnboxedValueFunction(Method method, Type* result, Value* left, Value* right, const NYql::NCodegen::ICodegen::TPtr& codegen, BasicBlock* block)
+{
+ auto& context = codegen->GetContext();
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(method));
+ if (NYql::NCodegen::ETarget::Windows != codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(result, {left->getType(), right->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ const auto call = CallInst::Create(funcPtr, {left, right}, "call", block);
+ return call;
+ } else {
+ const auto ptrLeft = new AllocaInst(left->getType(), 0U, "left", block);
+ const auto ptrRight = new AllocaInst(right->getType(), 0U, "right", block);
+ new StoreInst(left, ptrLeft, block);
+ new StoreInst(right, ptrRight, block);
+
+ if (Type::getInt128Ty(context) == result) {
+ const auto ptrResult = new AllocaInst(result, 0U, "result", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrLeft->getType(), ptrRight->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ CallInst::Create(funcPtr, {ptrResult, ptrLeft, ptrRight}, "", block);
+ const auto res = new LoadInst(ptrResult, "res", block);
+ return res;
+ } else {
+ const auto funType = FunctionType::get(result, {ptrLeft->getType(), ptrRight->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "ptr", block);
+ const auto call = CallInst::Create(funcPtr, {ptrLeft, ptrRight}, "call", block);
+ return call;
+ }
+ }
+}
+
+void AddRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
+void UnRefBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
+void CleanupBoxed(Value* value, const TCodegenContext& ctx, BasicBlock*& block);
+
+void SafeUnRefUnboxed(Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
+
+void ValueAddRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
+void ValueUnRef(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
+void ValueCleanup(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
+void ValueRelease(EValueRepresentation kind, Value* pointer, const TCodegenContext& ctx, BasicBlock*& block);
+
+std::pair<Value*, Value*> GetVariantParts(Value* variant, const TCodegenContext& ctx, BasicBlock*& block);
+Value* MakeVariant(Value* item, Value* variant, const TCodegenContext& ctx, BasicBlock*& block);
+
+Value* GetNodeValue(IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block);
+void GetNodeValue(Value* value, IComputationNode* node, const TCodegenContext& ctx, BasicBlock*& block);
+
+ICodegeneratorInlineWideNode::TGenerateResult GetNodeValues(IComputationWideFlowNode* node, const TCodegenContext& ctx, BasicBlock*& block);
+
+Function* GenerateCompareFunction(
+ const NYql::NCodegen::ICodegen::TPtr& codegen,
+ const TString& name,
+ IComputationExternalNode* left,
+ IComputationExternalNode* right,
+ IComputationNode* compare
+);
+
+Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types);
+Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, bool isTuple, const TKeyTypes& types);
+
+Function* GenerateEqualsFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types);
+Function* GenerateHashFunction(const NYql::NCodegen::ICodegen::TPtr& codegen, const TString& name, const TKeyTypes& types);
+
+template <typename TDerived>
+class TDecoratorCodegeneratorNode: public TDecoratorComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TDecoratorComputationNode<TDerived>;
+protected:
+ TDecoratorCodegeneratorNode(IComputationNode* node, EValueRepresentation kind)
+ : TBase(node, kind)
+ {}
+
+ TDecoratorCodegeneratorNode(IComputationNode* node)
+ : TBase(node)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ const auto arg = GetNodeValue(this->Node, ctx, block);
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, arg, block);
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ ValueRelease(this->Node->GetRepresentation(), load, ctx, block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
+template <typename TDerived>
+class TStatelessFlowCodegeneratorNode: public TStatelessFlowComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TStatelessFlowComputationNode<TDerived>;
+protected:
+ TStatelessFlowCodegeneratorNode(const IComputationNode* source, EValueRepresentation kind)
+ : TBase(source, kind)
+ {}
+
+ TStatelessFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind)
+ : TBase(mutables, source, kind)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
+template <typename TDerived>
+class TStatelessWideFlowCodegeneratorNode: public TStatelessWideFlowComputationNode<TDerived>, public ICodegeneratorInlineWideNode
+{
+using TBase = TStatelessWideFlowCodegeneratorNode<TDerived>;
+protected:
+ TStatelessWideFlowCodegeneratorNode(const IComputationNode* source)
+ : TStatelessWideFlowComputationNode<TDerived>(source)
+ {}
+
+ TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, block);
+ }
+};
+
+template <typename TDerived>
+class TFlowSourceCodegeneratorNode: public TFlowSourceComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TFlowSourceComputationNode<TDerived>;
+protected:
+ TFlowSourceCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind, EValueRepresentation stateKind)
+ : TBase(mutables, kind, stateKind)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ auto& context = ctx.Codegen->GetContext();
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, statePtr, block);
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
template <typename TDerived, bool SerializableState = false>
class TStatefulFlowCodegeneratorNode: public TStatefulFlowComputationNode<TDerived, SerializableState>, public ICodegeneratorInlineNode
-{
+{
using TBase = TStatefulFlowComputationNode<TDerived, SerializableState>;
-protected:
- TStatefulFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation stateKind = EValueRepresentation::Any)
- : TBase(mutables, source, kind, stateKind)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- auto& context = ctx.Codegen->GetContext();
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
-
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, statePtr, block);
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
- return load;
- } else {
- return value;
- }
- }
-};
-
+protected:
+ TStatefulFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation stateKind = EValueRepresentation::Any)
+ : TBase(mutables, source, kind, stateKind)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ auto& context = ctx.Codegen->GetContext();
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, statePtr, block);
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
template <typename TDerived, bool SerializableState = false>
class TStatefulWideFlowCodegeneratorNode: public TStatefulWideFlowComputationNode<TDerived, SerializableState>, public ICodegeneratorInlineWideNode
-{
+{
using TBase = TStatefulWideFlowComputationNode<TDerived, SerializableState>;
-protected:
- TStatefulWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation stateKind)
- : TBase(mutables, source, stateKind)
- {}
-
- TStatefulWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation, EValueRepresentation stateKind)
- : TBase(mutables, source, stateKind)
- {}
-
- TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
- auto& context = ctx.Codegen->GetContext();
- const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
- return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, statePtr, block);
- }
-};
-
-template <typename TDerived>
-class TPairStateWideFlowCodegeneratorNode: public TPairStateWideFlowComputationNode<TDerived>, public ICodegeneratorInlineWideNode
-{
-using TBase = TPairStateWideFlowComputationNode<TDerived>;
-protected:
- TPairStateWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation firstKind, EValueRepresentation secondKind)
- : TBase(mutables, source, firstKind, secondKind)
- {}
-
- TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
- auto& context = ctx.Codegen->GetContext();
- auto idx = static_cast<const IComputationNode*>(this)->GetIndex();
- const auto firstPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "first_ptr", block);
- const auto secondPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), ++idx)}, "second_ptr", block);
- return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, firstPtr, secondPtr, block);
- }
-};
-
-template <typename TDerived>
-class TPairStateFlowCodegeneratorNode: public TPairStateFlowComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TPairStateFlowComputationNode<TDerived>;
-protected:
- TPairStateFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation firstKind = EValueRepresentation::Any, EValueRepresentation secondKind = EValueRepresentation::Any)
- : TBase(mutables, source, kind, firstKind, secondKind)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- auto& context = ctx.Codegen->GetContext();
- auto idx = static_cast<const IComputationNode*>(this)->GetIndex();
- const auto firstPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "first_ptr", block);
- const auto secondPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), ++idx)}, "second_ptr", block);
-
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, firstPtr, secondPtr, block);
- if (value->getType()->isPointerTy()) {
- const auto load = new LoadInst(value, "load", block);
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
- return load;
- } else {
- return value;
- }
- }
-};
-
-template <typename TDerived>
-class TBinaryCodegeneratorNode: public TBinaryComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TBinaryComputationNode<TDerived>;
-protected:
- TBinaryCodegeneratorNode(IComputationNode* left, IComputationNode* right, const EValueRepresentation kind)
- : TBase(left, right, kind)
- {}
-
- TBinaryCodegeneratorNode(TComputationMutables&, EValueRepresentation kind, IComputationNode* left, IComputationNode* right)
- : TBase(left, right, kind)
- {}
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
- if (value->getType()->isPointerTy()) {
- ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
- const auto load = new LoadInst(value, "load", block);
- return load;
- } else {
- return value;
- }
- }
-};
-
-template <typename TDerived>
-class TMutableCodegeneratorNode: public TMutableComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TMutableComputationNode<TDerived>;
-protected:
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::internal_Get_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- TMutableCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TBase(mutables, kind)
- {}
-
- Function* GenerateInternalGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
- const auto& name = MakeName();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto funcType = FunctionType::get(Type::getInt128Ty(context), {PointerType::getUnqual(GetCompContextType(context))}, false);
-
- TCodegenContext ctx(codegen);
+protected:
+ TStatefulWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation stateKind)
+ : TBase(mutables, source, stateKind)
+ {}
+
+ TStatefulWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation, EValueRepresentation stateKind)
+ : TBase(mutables, source, stateKind)
+ {}
+
+ TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ auto& context = ctx.Codegen->GetContext();
+ const auto statePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), static_cast<const IComputationNode*>(this)->GetIndex())}, "state_ptr", block);
+ return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, statePtr, block);
+ }
+};
+
+template <typename TDerived>
+class TPairStateWideFlowCodegeneratorNode: public TPairStateWideFlowComputationNode<TDerived>, public ICodegeneratorInlineWideNode
+{
+using TBase = TPairStateWideFlowComputationNode<TDerived>;
+protected:
+ TPairStateWideFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation firstKind, EValueRepresentation secondKind)
+ : TBase(mutables, source, firstKind, secondKind)
+ {}
+
+ TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ auto& context = ctx.Codegen->GetContext();
+ auto idx = static_cast<const IComputationNode*>(this)->GetIndex();
+ const auto firstPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "first_ptr", block);
+ const auto secondPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), ++idx)}, "second_ptr", block);
+ return static_cast<const TDerived*>(this)->DoGenGetValues(ctx, firstPtr, secondPtr, block);
+ }
+};
+
+template <typename TDerived>
+class TPairStateFlowCodegeneratorNode: public TPairStateFlowComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TPairStateFlowComputationNode<TDerived>;
+protected:
+ TPairStateFlowCodegeneratorNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation firstKind = EValueRepresentation::Any, EValueRepresentation secondKind = EValueRepresentation::Any)
+ : TBase(mutables, source, kind, firstKind, secondKind)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ auto& context = ctx.Codegen->GetContext();
+ auto idx = static_cast<const IComputationNode*>(this)->GetIndex();
+ const auto firstPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), idx)}, "first_ptr", block);
+ const auto secondPtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(Type::getInt32Ty(context), ++idx)}, "second_ptr", block);
+
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, firstPtr, secondPtr, block);
+ if (value->getType()->isPointerTy()) {
+ const auto load = new LoadInst(value, "load", block);
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), load, ctx, block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
+template <typename TDerived>
+class TBinaryCodegeneratorNode: public TBinaryComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TBinaryComputationNode<TDerived>;
+protected:
+ TBinaryCodegeneratorNode(IComputationNode* left, IComputationNode* right, const EValueRepresentation kind)
+ : TBase(left, right, kind)
+ {}
+
+ TBinaryCodegeneratorNode(TComputationMutables&, EValueRepresentation kind, IComputationNode* left, IComputationNode* right)
+ : TBase(left, right, kind)
+ {}
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ const auto value = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
+ if (value->getType()->isPointerTy()) {
+ ValueRelease(static_cast<const IComputationNode*>(this)->GetRepresentation(), value, ctx, block);
+ const auto load = new LoadInst(value, "load", block);
+ return load;
+ } else {
+ return value;
+ }
+ }
+};
+
+template <typename TDerived>
+class TMutableCodegeneratorNode: public TMutableComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TMutableComputationNode<TDerived>;
+protected:
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::internal_Get_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ TMutableCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TBase(mutables, kind)
+ {}
+
+ Function* GenerateInternalGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+ const auto& name = MakeName();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto funcType = FunctionType::get(Type::getInt128Ty(context), {PointerType::getUnqual(GetCompContextType(context))}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*ctx.Func->arg_begin();
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto get = this->MakeGetValueBody(ctx, main);
-
- ReturnInst::Create(context, get, main);
- return ctx.Func;
- }
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*ctx.Func->arg_begin();
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto get = this->MakeGetValueBody(ctx, main);
+
+ ReturnInst::Create(context, get, main);
+ return ctx.Func;
+ }
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
if (*this->Stateless) {
- const auto newValue = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
- if (newValue->getType()->isPointerTy()) {
- ValueRelease(this->GetRepresentation(), newValue, ctx, block);
- const auto load = new LoadInst(newValue, "load", block);
- return load;
- } else {
- return newValue;
- }
- }
-
- return ctx.AlwaysInline ? MakeGetValueBody(ctx, block) :
- CallInst::Create(GenerateInternalGetValue(ctx.Codegen), {ctx.Ctx}, "getter", block);
- }
-
- Value* MakeGetValueBody(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, this->ValueIndex)}, "value_ptr", block);
- const auto value = new LoadInst(valuePtr, "value", block);
-
- const auto invv = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, invv, "check", block);
-
- const auto comp = BasicBlock::Create(context, "comp", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(comp, done, check, block);
-
- block = comp;
-
- const auto newValue = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
-
- if (newValue->getType()->isPointerTy()) {
- const auto load = new LoadInst(newValue, "value", block);
- new StoreInst(load, valuePtr, block);
- new StoreInst(ConstantInt::get(load->getType(), 0), newValue, block);
- } else {
- new StoreInst(newValue, valuePtr, block);
- ValueAddRef(this->RepresentationKind, valuePtr, ctx, block);
- }
-
- BranchInst::Create(done, block);
- block = done;
-
- const auto result = new LoadInst(valuePtr, "result", false, block);
- return result;
- }
-};
-
-template <typename TDerived>
-class TMutableCodegeneratorPtrNode: public TMutableComputationNode<TDerived>, public ICodegeneratorInlineNode
-{
-using TBase = TMutableComputationNode<TDerived>;
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::internal_Get_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
-protected:
- TMutableCodegeneratorPtrNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TBase(mutables, kind)
- {}
-
- Function* GenerateInternalGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
- const auto& name = MakeName();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto contextType = GetCompContextType(context);
-
- const auto funcType = FunctionType::get(Type::getInt128Ty(context), {PointerType::getUnqual(contextType)}, false);
-
- TCodegenContext ctx(codegen);
+ const auto newValue = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
+ if (newValue->getType()->isPointerTy()) {
+ ValueRelease(this->GetRepresentation(), newValue, ctx, block);
+ const auto load = new LoadInst(newValue, "load", block);
+ return load;
+ } else {
+ return newValue;
+ }
+ }
+
+ return ctx.AlwaysInline ? MakeGetValueBody(ctx, block) :
+ CallInst::Create(GenerateInternalGetValue(ctx.Codegen), {ctx.Ctx}, "getter", block);
+ }
+
+ Value* MakeGetValueBody(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, this->ValueIndex)}, "value_ptr", block);
+ const auto value = new LoadInst(valuePtr, "value", block);
+
+ const auto invv = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, invv, "check", block);
+
+ const auto comp = BasicBlock::Create(context, "comp", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(comp, done, check, block);
+
+ block = comp;
+
+ const auto newValue = static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, block);
+
+ if (newValue->getType()->isPointerTy()) {
+ const auto load = new LoadInst(newValue, "value", block);
+ new StoreInst(load, valuePtr, block);
+ new StoreInst(ConstantInt::get(load->getType(), 0), newValue, block);
+ } else {
+ new StoreInst(newValue, valuePtr, block);
+ ValueAddRef(this->RepresentationKind, valuePtr, ctx, block);
+ }
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ const auto result = new LoadInst(valuePtr, "result", false, block);
+ return result;
+ }
+};
+
+template <typename TDerived>
+class TMutableCodegeneratorPtrNode: public TMutableComputationNode<TDerived>, public ICodegeneratorInlineNode
+{
+using TBase = TMutableComputationNode<TDerived>;
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::internal_Get_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+protected:
+ TMutableCodegeneratorPtrNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TBase(mutables, kind)
+ {}
+
+ Function* GenerateInternalGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) const {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+ const auto& name = MakeName();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto contextType = GetCompContextType(context);
+
+ const auto funcType = FunctionType::get(Type::getInt128Ty(context), {PointerType::getUnqual(contextType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*ctx.Func->arg_begin();
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto get = this->MakeGetValueBody(ctx, main);
-
- ReturnInst::Create(context, get, main);
- return ctx.Func;
- }
-
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
- if (*this->Stateless) {
- const auto type = Type::getInt128Ty(ctx.Codegen->GetContext());
- const auto pointer = ctx.Func->getEntryBlock().empty() ?
- new AllocaInst(type, 0U, "output", &ctx.Func->getEntryBlock()):
- new AllocaInst(type, 0U, "output", &ctx.Func->getEntryBlock().back());
-
- static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, pointer, block);
- ValueRelease(this->GetRepresentation(), pointer, ctx, block);
- const auto load = new LoadInst(pointer, "load", block);
- return load;
- }
-
- return ctx.AlwaysInline ? MakeGetValueBody(ctx, block) :
- CallInst::Create(GenerateInternalGetValue(ctx.Codegen), {ctx.Ctx}, "getter", block);
- }
-
- Value* MakeGetValueBody(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto indexType = Type::getInt32Ty(context);
- const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, this->ValueIndex)}, "value_ptr", block);
- const auto value = new LoadInst(valuePtr, "value", block);
-
- const auto invv = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
-
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, invv, "check", block);
-
- const auto comp = BasicBlock::Create(context, "comp", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- BranchInst::Create(comp, done, check, block);
-
- block = comp;
-
- static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, valuePtr, block);
-
- BranchInst::Create(done, block);
- block = done;
-
- const auto result = new LoadInst(valuePtr, "result", false, block);
- return result;
- }
-};
-
-template <typename TDerived>
-class TMutableCodegeneratorFallbackNode: public TMutableCodegeneratorNode<TDerived>
-{
-using TBase = TMutableCodegeneratorNode<TDerived>;
-
-protected:
- TMutableCodegeneratorFallbackNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TBase(mutables, kind)
- {}
-
-public:
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto type = Type::getInt128Ty(context);
- const auto ptrType = PointerType::getUnqual(StructType::get(context));
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*ctx.Func->arg_begin();
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto get = this->MakeGetValueBody(ctx, main);
+
+ ReturnInst::Create(context, get, main);
+ return ctx.Func;
+ }
+
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final {
+ if (*this->Stateless) {
+ const auto type = Type::getInt128Ty(ctx.Codegen->GetContext());
+ const auto pointer = ctx.Func->getEntryBlock().empty() ?
+ new AllocaInst(type, 0U, "output", &ctx.Func->getEntryBlock()):
+ new AllocaInst(type, 0U, "output", &ctx.Func->getEntryBlock().back());
+
+ static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, pointer, block);
+ ValueRelease(this->GetRepresentation(), pointer, ctx, block);
+ const auto load = new LoadInst(pointer, "load", block);
+ return load;
+ }
+
+ return ctx.AlwaysInline ? MakeGetValueBody(ctx, block) :
+ CallInst::Create(GenerateInternalGetValue(ctx.Codegen), {ctx.Ctx}, "getter", block);
+ }
+
+ Value* MakeGetValueBody(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto indexType = Type::getInt32Ty(context);
+ const auto valuePtr = GetElementPtrInst::CreateInBounds(ctx.GetMutables(), {ConstantInt::get(indexType, this->ValueIndex)}, "value_ptr", block);
+ const auto value = new LoadInst(valuePtr, "value", block);
+
+ const auto invv = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
+
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, value, invv, "check", block);
+
+ const auto comp = BasicBlock::Create(context, "comp", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ BranchInst::Create(comp, done, check, block);
+
+ block = comp;
+
+ static_cast<const TDerived*>(this)->DoGenerateGetValue(ctx, valuePtr, block);
+
+ BranchInst::Create(done, block);
+ block = done;
+
+ const auto result = new LoadInst(valuePtr, "result", false, block);
+ return result;
+ }
+};
+
+template <typename TDerived>
+class TMutableCodegeneratorFallbackNode: public TMutableCodegeneratorNode<TDerived>
+{
+using TBase = TMutableCodegeneratorNode<TDerived>;
+
+protected:
+ TMutableCodegeneratorFallbackNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TBase(mutables, kind)
+ {}
+
+public:
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto type = Type::getInt128Ty(context);
+ const auto ptrType = PointerType::getUnqual(StructType::get(context));
static_assert(std::is_same<std::invoke_result_t<decltype(&TDerived::DoCalculate), TDerived, TComputationContext&>, NUdf::TUnboxedValuePod>(), "DoCalculate must return pod!");
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDerived::DoCalculate));
- const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(type, {self->getType(), ctx.Ctx->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx}, "value", block);
- return value;
- } else {
- const auto resultPtr = new AllocaInst(type, 0U, "return", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType()}, false);
- const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx}, "", block);
- const auto value = new LoadInst(resultPtr, "value", block);
- return value;
- }
- }
-};
-
-template <typename TDerived, bool PreventReGeneration = false>
-class TCodegeneratorRootNode: public TDerived, public ICodegeneratorRootNode
-{
-using TBase = TDerived;
-public:
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&TDerived::DoCalculate));
+ const auto self = CastInst::Create(Instruction::IntToPtr, ConstantInt::get(Type::getInt64Ty(context), uintptr_t(this)), ptrType, "self", block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(type, {self->getType(), ctx.Ctx->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ const auto value = CallInst::Create(doFuncPtr, {self, ctx.Ctx}, "value", block);
+ return value;
+ } else {
+ const auto resultPtr = new AllocaInst(type, 0U, "return", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {self->getType(), resultPtr->getType(), ctx.Ctx->getType()}, false);
+ const auto doFuncPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(doFuncPtr, {self, resultPtr, ctx.Ctx}, "", block);
+ const auto value = new LoadInst(resultPtr, "value", block);
+ return value;
+ }
+ }
+};
+
+template <typename TDerived, bool PreventReGeneration = false>
+class TCodegeneratorRootNode: public TDerived, public ICodegeneratorRootNode
+{
+using TBase = TDerived;
+public:
NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
- if (compCtx.ExecuteLLVM && GetFunction)
+ if (compCtx.ExecuteLLVM && GetFunction)
return GetFunction(&compCtx);
-
+
return TBase::GetValue(compCtx);
- }
-
-protected:
- TCodegeneratorRootNode(EValueRepresentation kind)
- : TBase(kind)
- {}
-
- TCodegeneratorRootNode(const IComputationNode* source, EValueRepresentation kind)
- : TBase(source, kind)
- {}
-
- TCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TBase(mutables, kind)
- {}
-
-private:
- TString MakeName() const {
- TStringStream out;
- out << this->DebugString() << "::Get_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-
- Function* GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
- auto& module = codegen->GetModule();
- auto& context = codegen->GetContext();
-
- if constexpr (PreventReGeneration) {
- if (const auto& name = TDerived::MakeName(); module.getFunction(name.c_str()))
- return nullptr;
- }
-
- const auto& name = MakeName();
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto contextType = GetCompContextType(context);
-
- const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
- FunctionType::get(valueType, {PointerType::getUnqual(contextType)}, false):
- FunctionType::get(Type::getVoidTy(context) , {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType)}, false);
-
- TCodegenContext ctx(codegen);
+ }
+
+protected:
+ TCodegeneratorRootNode(EValueRepresentation kind)
+ : TBase(kind)
+ {}
+
+ TCodegeneratorRootNode(const IComputationNode* source, EValueRepresentation kind)
+ : TBase(source, kind)
+ {}
+
+ TCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TBase(mutables, kind)
+ {}
+
+private:
+ TString MakeName() const {
+ TStringStream out;
+ out << this->DebugString() << "::Get_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+
+ Function* GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen) {
+ auto& module = codegen->GetModule();
+ auto& context = codegen->GetContext();
+
+ if constexpr (PreventReGeneration) {
+ if (const auto& name = TDerived::MakeName(); module.getFunction(name.c_str()))
+ return nullptr;
+ }
+
+ const auto& name = MakeName();
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto contextType = GetCompContextType(context);
+
+ const auto funcType = codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows ?
+ FunctionType::get(valueType, {PointerType::getUnqual(contextType)}, false):
+ FunctionType::get(Type::getVoidTy(context) , {PointerType::getUnqual(valueType), PointerType::getUnqual(contextType)}, false);
+
+ TCodegenContext ctx(codegen);
ctx.Func = cast<Function>(module.getOrInsertFunction(name.c_str(), funcType).getCallee());
-
- auto args = ctx.Func->arg_begin();
- if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
- auto& firstArg = *args++;
- firstArg.addAttr(Attribute::StructRet);
- firstArg.addAttr(Attribute::NoAlias);
- }
-
- auto main = BasicBlock::Create(context, "main", ctx.Func);
- ctx.Ctx = &*args;
- ctx.Ctx->addAttr(Attribute::NonNull);
-
- const auto get = this->CreateGetValue(ctx, main);
-
- if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
- ReturnInst::Create(context, get, main);
- } else {
- new StoreInst(get, &*--args, main);
- ReturnInst::Create(context, main);
- }
-
- return ctx.Func;
- }
-protected:
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) override {
- if (GetFunc)
- GetFunction = reinterpret_cast<TGetPtr>(codegen->GetPointerToFunction(GetFunc));
- }
-
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) override {
- if (GetFunc = GenerateGetValue(codegen))
- codegen->ExportSymbol(GetFunc);
- }
-private:
- using TGetPtr = NUdf::TUnboxedValuePod (*)(TComputationContext* ctx);
-
- Function* GetFunc = nullptr;
- TGetPtr GetFunction = nullptr;
-};
-
-template <typename TDerived>
-using TMutableCodegeneratorRootNode = TCodegeneratorRootNode<TMutableCodegeneratorNode<TDerived>, true>;
-
-template <typename TDerived>
-using TStatelessFlowCodegeneratorRootNode = TCodegeneratorRootNode<TStatelessFlowCodegeneratorNode<TDerived>>;
-
-class TUnboxedImmutableCodegeneratorNode: public TUnboxedImmutableComputationNode, public ICodegeneratorInlineNode
-{
-public:
- TUnboxedImmutableCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value);
-
-private:
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*&) const final;
-};
-
+
+ auto args = ctx.Func->arg_begin();
+ if (codegen->GetEffectiveTarget() == NYql::NCodegen::ETarget::Windows) {
+ auto& firstArg = *args++;
+ firstArg.addAttr(Attribute::StructRet);
+ firstArg.addAttr(Attribute::NoAlias);
+ }
+
+ auto main = BasicBlock::Create(context, "main", ctx.Func);
+ ctx.Ctx = &*args;
+ ctx.Ctx->addAttr(Attribute::NonNull);
+
+ const auto get = this->CreateGetValue(ctx, main);
+
+ if (codegen->GetEffectiveTarget() != NYql::NCodegen::ETarget::Windows) {
+ ReturnInst::Create(context, get, main);
+ } else {
+ new StoreInst(get, &*--args, main);
+ ReturnInst::Create(context, main);
+ }
+
+ return ctx.Func;
+ }
+protected:
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) override {
+ if (GetFunc)
+ GetFunction = reinterpret_cast<TGetPtr>(codegen->GetPointerToFunction(GetFunc));
+ }
+
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) override {
+ if (GetFunc = GenerateGetValue(codegen))
+ codegen->ExportSymbol(GetFunc);
+ }
+private:
+ using TGetPtr = NUdf::TUnboxedValuePod (*)(TComputationContext* ctx);
+
+ Function* GetFunc = nullptr;
+ TGetPtr GetFunction = nullptr;
+};
+
+template <typename TDerived>
+using TMutableCodegeneratorRootNode = TCodegeneratorRootNode<TMutableCodegeneratorNode<TDerived>, true>;
+
+template <typename TDerived>
+using TStatelessFlowCodegeneratorRootNode = TCodegeneratorRootNode<TStatelessFlowCodegeneratorNode<TDerived>>;
+
+class TUnboxedImmutableCodegeneratorNode: public TUnboxedImmutableComputationNode, public ICodegeneratorInlineNode
+{
+public:
+ TUnboxedImmutableCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value);
+
+private:
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*&) const final;
+};
+
class TUnboxedImmutableRunCodegeneratorNode: public TUnboxedImmutableComputationNode, public ICodegeneratorRunNode
{
public:
TUnboxedImmutableRunCodegeneratorNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value);
};
-class TExternalCodegeneratorNode: public TExternalComputationNode, public ICodegeneratorExternalNode
-{
-public:
- TExternalCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind);
-protected:
- Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final;
- Value* CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const final;
- void CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const final;
- Value* CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const final;
- void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const final;
- void SetTemporaryValue(Value* value) final;
- void SetValueGetter(Function* getter) final;
-private:
- Function* ValueGetter = nullptr;
- Value* TemporaryValue = nullptr;
-};
-
-class TExternalCodegeneratorRootNode: public TExternalCodegeneratorNode, public ICodegeneratorRootNode
-{
-public:
- TExternalCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind);
-
-private:
+class TExternalCodegeneratorNode: public TExternalComputationNode, public ICodegeneratorExternalNode
+{
+public:
+ TExternalCodegeneratorNode(TComputationMutables& mutables, EValueRepresentation kind);
+protected:
+ Value* CreateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const final;
+ Value* CreateRefValue(const TCodegenContext& ctx, BasicBlock*& block) const final;
+ void CreateSetValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const final;
+ Value* CreateSwapValue(const TCodegenContext& ctx, BasicBlock*& block, Value* value) const final;
+ void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const final;
+ void SetTemporaryValue(Value* value) final;
+ void SetValueGetter(Function* getter) final;
+private:
+ Function* ValueGetter = nullptr;
+ Value* TemporaryValue = nullptr;
+};
+
+class TExternalCodegeneratorRootNode: public TExternalCodegeneratorNode, public ICodegeneratorRootNode
+{
+public:
+ TExternalCodegeneratorRootNode(TComputationMutables& mutables, EValueRepresentation kind);
+
+private:
NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final;
-
+
void SetValue(TComputationContext& compCtx, NUdf::TUnboxedValue&& newValue) const final;
-
- TString MakeName(const TString& method) const;
-
- void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final;
- void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final;
-
- Function* GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen);
- Function* GenerateSetValue(const NYql::NCodegen::ICodegen::TPtr& codegen);
-
- using TGetPtr = NUdf::TUnboxedValuePod (*)(TComputationContext* ctx);
-
- Function* GetValueFunc = nullptr;
- TGetPtr GetFunction = nullptr;
-
- using TSetPtr = void (*)(TComputationContext* ctx, NUdf::TUnboxedValuePod);
-
- Function* SetValueFunc = nullptr;
- TSetPtr SetFunction = nullptr;
-};
-
-
-class TWideFlowProxyCodegeneratorNode: public TWideFlowProxyComputationNode, public IWideFlowProxyCodegeneratorNode
-{
-public:
- TWideFlowProxyCodegeneratorNode() = default;
-private:
- void SetGenerator(TGenerator&& generator) final;
-
- void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const final;
-
- TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final;
-
- TGenerator Generator;
-};
-
-class TCodegenIterator : public TComputationValue<TCodegenIterator> {
-public:
- using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
- TCodegenIterator(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator)
- : TComputationValue<TCodegenIterator>(memInfo)
- , Ctx(ctx)
- , NextFunc(next)
- , Iterator(std::move(iterator))
- {}
-
-protected:
- bool Next(NUdf::TUnboxedValue& value) override {
- return NextFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
- }
-
+
+ TString MakeName(const TString& method) const;
+
+ void FinalizeFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final;
+ void GenerateFunctions(const NYql::NCodegen::ICodegen::TPtr& codegen) final;
+
+ Function* GenerateGetValue(const NYql::NCodegen::ICodegen::TPtr& codegen);
+ Function* GenerateSetValue(const NYql::NCodegen::ICodegen::TPtr& codegen);
+
+ using TGetPtr = NUdf::TUnboxedValuePod (*)(TComputationContext* ctx);
+
+ Function* GetValueFunc = nullptr;
+ TGetPtr GetFunction = nullptr;
+
+ using TSetPtr = void (*)(TComputationContext* ctx, NUdf::TUnboxedValuePod);
+
+ Function* SetValueFunc = nullptr;
+ TSetPtr SetFunction = nullptr;
+};
+
+
+class TWideFlowProxyCodegeneratorNode: public TWideFlowProxyComputationNode, public IWideFlowProxyCodegeneratorNode
+{
+public:
+ TWideFlowProxyCodegeneratorNode() = default;
+private:
+ void SetGenerator(TGenerator&& generator) final;
+
+ void CreateInvalidate(const TCodegenContext& ctx, BasicBlock*& block) const final;
+
+ TGenerateResult GenGetValues(const TCodegenContext& ctx, BasicBlock*& block) const final;
+
+ TGenerator Generator;
+};
+
+class TCodegenIterator : public TComputationValue<TCodegenIterator> {
+public:
+ using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
+ TCodegenIterator(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator)
+ : TComputationValue<TCodegenIterator>(memInfo)
+ , Ctx(ctx)
+ , NextFunc(next)
+ , Iterator(std::move(iterator))
+ {}
+
+protected:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ return NextFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
+ }
+
TComputationContext* const Ctx;
- const TNextPtr NextFunc;
- const NUdf::TUnboxedValue Iterator;
-};
-
-template <typename TState = NUdf::TUnboxedValue>
-class TCodegenStatefulIterator : public TComputationValue<TCodegenStatefulIterator<TState>> {
-public:
- using TStateType = TState;
- using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, TStateType&, NUdf::TUnboxedValuePod&);
-
- TCodegenStatefulIterator(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator, const TStateType& init = TStateType())
- : TComputationValue<TCodegenStatefulIterator>(memInfo)
- , Ctx(ctx)
- , NextFunc(next)
- , Iterator(std::move(iterator))
- , State(init)
- {}
-
-protected:
- bool Next(NUdf::TUnboxedValue& value) override {
- return NextFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), State, value);
- }
-
+ const TNextPtr NextFunc;
+ const NUdf::TUnboxedValue Iterator;
+};
+
+template <typename TState = NUdf::TUnboxedValue>
+class TCodegenStatefulIterator : public TComputationValue<TCodegenStatefulIterator<TState>> {
+public:
+ using TStateType = TState;
+ using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, TStateType&, NUdf::TUnboxedValuePod&);
+
+ TCodegenStatefulIterator(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator, const TStateType& init = TStateType())
+ : TComputationValue<TCodegenStatefulIterator>(memInfo)
+ , Ctx(ctx)
+ , NextFunc(next)
+ , Iterator(std::move(iterator))
+ , State(init)
+ {}
+
+protected:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ return NextFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), State, value);
+ }
+
TComputationContext* const Ctx;
- const TNextPtr NextFunc;
- const NUdf::TUnboxedValue Iterator;
- TStateType State;
-};
-
-class TCustomListCodegenValue : public TCustomListValue {
-public:
- using TIterator = TCodegenIterator;
- using TNextPtr = typename TIterator::TNextPtr;
-
- TCustomListCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
- : TCustomListValue(memInfo)
- , Ctx(ctx)
- , NextFunc(next)
- , List(std::move(list))
- {}
-
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator()));
- }
-
+ const TNextPtr NextFunc;
+ const NUdf::TUnboxedValue Iterator;
+ TStateType State;
+};
+
+class TCustomListCodegenValue : public TCustomListValue {
+public:
+ using TIterator = TCodegenIterator;
+ using TNextPtr = typename TIterator::TNextPtr;
+
+ TCustomListCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
+ : TCustomListValue(memInfo)
+ , Ctx(ctx)
+ , NextFunc(next)
+ , List(std::move(list))
+ {}
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator()));
+ }
+
TComputationContext* const Ctx;
- const TNextPtr NextFunc;
- const NUdf::TUnboxedValue List;
-};
-
-template <class TIterator = TCodegenStatefulIterator<>>
-class TCustomListCodegenStatefulValueT : public TCustomListValue {
-public:
- using TStateType = typename TIterator::TStateType;
- using TNextPtr = typename TIterator::TNextPtr;
-
- TCustomListCodegenStatefulValueT(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list, TStateType&& init = TStateType())
- : TCustomListValue(memInfo)
- , Ctx(ctx)
- , NextFunc(next)
- , List(std::move(list))
- , Init(std::move(init))
- {}
-
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator(), Init));
- }
-
- TComputationContext* const Ctx;
- const TNextPtr NextFunc;
- const NUdf::TUnboxedValue List;
- const TStateType Init;
-};
-
-using TCustomListCodegenStatefulValue = TCustomListCodegenStatefulValueT<>;
-
-class TListCodegenValue : public TComputationValue<TListCodegenValue> {
-public:
- using TNextPtr = TCodegenIterator::TNextPtr;
-
- TListCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
- : TComputationValue<TListCodegenValue>(memInfo)
- , Ctx(ctx)
- , NextFunc(next)
- , List(std::move(list))
- {}
-
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TUnboxedValuePod(new TCodegenIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator()));
- }
-
- ui64 GetListLength() const final {
- return List.GetListLength();
- }
-
- bool HasListItems() const final {
- return List.HasListItems();
- }
-
- bool HasFastListLength() const final {
- return List.HasFastListLength();
- }
-
+ const TNextPtr NextFunc;
+ const NUdf::TUnboxedValue List;
+};
+
+template <class TIterator = TCodegenStatefulIterator<>>
+class TCustomListCodegenStatefulValueT : public TCustomListValue {
+public:
+ using TStateType = typename TIterator::TStateType;
+ using TNextPtr = typename TIterator::TNextPtr;
+
+ TCustomListCodegenStatefulValueT(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list, TStateType&& init = TStateType())
+ : TCustomListValue(memInfo)
+ , Ctx(ctx)
+ , NextFunc(next)
+ , List(std::move(list))
+ , Init(std::move(init))
+ {}
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator(), Init));
+ }
+
+ TComputationContext* const Ctx;
+ const TNextPtr NextFunc;
+ const NUdf::TUnboxedValue List;
+ const TStateType Init;
+};
+
+using TCustomListCodegenStatefulValue = TCustomListCodegenStatefulValueT<>;
+
+class TListCodegenValue : public TComputationValue<TListCodegenValue> {
+public:
+ using TNextPtr = TCodegenIterator::TNextPtr;
+
+ TListCodegenValue(TMemoryUsageInfo* memInfo, TNextPtr next, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
+ : TComputationValue<TListCodegenValue>(memInfo)
+ , Ctx(ctx)
+ , NextFunc(next)
+ , List(std::move(list))
+ {}
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TUnboxedValuePod(new TCodegenIterator(GetMemInfo(), NextFunc, Ctx, List.GetListIterator()));
+ }
+
+ ui64 GetListLength() const final {
+ return List.GetListLength();
+ }
+
+ bool HasListItems() const final {
+ return List.HasListItems();
+ }
+
+ bool HasFastListLength() const final {
+ return List.HasFastListLength();
+ }
+
TComputationContext* const Ctx;
- const TNextPtr NextFunc;
- const NUdf::TUnboxedValue List;
-};
-
-class TCodegenIteratorOne : public TComputationValue<TCodegenIteratorOne> {
-public:
- using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
- TCodegenIteratorOne(TMemoryUsageInfo* memInfo, TNextPtr nextOne, TNextPtr nextTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator)
- : TComputationValue<TCodegenIteratorOne>(memInfo)
- , NextFuncOne(nextOne)
- , NextFuncTwo(nextTwo)
- , Ctx(ctx)
- , Iterator(std::move(iterator))
- {}
-
-private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (FirstCall) {
- FirstCall = false;
- return NextFuncOne(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
- } else {
- return NextFuncTwo(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
- }
- }
-
- const TNextPtr NextFuncOne;
- const TNextPtr NextFuncTwo;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Iterator;
- bool FirstCall = true;
-};
-
-class TListCodegenValueOne : public TComputationValue<TListCodegenValueOne> {
-public:
- using TNextPtr = TCodegenIteratorOne::TNextPtr;
-
- TListCodegenValueOne(TMemoryUsageInfo* memInfo, TNextPtr nextOne, TNextPtr nextTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
- : TComputationValue<TListCodegenValueOne>(memInfo)
- , NextFuncOne(nextOne)
- , NextFuncTwo(nextTwo)
- , Ctx(ctx)
- , List(std::move(list))
- {}
-
-private:
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TUnboxedValuePod(new TCodegenIteratorOne(GetMemInfo(), NextFuncOne, NextFuncTwo, Ctx, List.GetListIterator()));
- }
-
- ui64 GetListLength() const final {
- return List.GetListLength();
- }
-
- bool HasListItems() const final {
- return List.HasListItems();
- }
-
- bool HasFastListLength() const final {
- return List.HasFastListLength();
- }
-
- const TNextPtr NextFuncOne;
- const TNextPtr NextFuncTwo;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue List;
-};
-
+ const TNextPtr NextFunc;
+ const NUdf::TUnboxedValue List;
+};
+
+class TCodegenIteratorOne : public TComputationValue<TCodegenIteratorOne> {
+public:
+ using TNextPtr = bool (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
+ TCodegenIteratorOne(TMemoryUsageInfo* memInfo, TNextPtr nextOne, TNextPtr nextTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& iterator)
+ : TComputationValue<TCodegenIteratorOne>(memInfo)
+ , NextFuncOne(nextOne)
+ , NextFuncTwo(nextTwo)
+ , Ctx(ctx)
+ , Iterator(std::move(iterator))
+ {}
+
+private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (FirstCall) {
+ FirstCall = false;
+ return NextFuncOne(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
+ } else {
+ return NextFuncTwo(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Iterator), value);
+ }
+ }
+
+ const TNextPtr NextFuncOne;
+ const TNextPtr NextFuncTwo;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Iterator;
+ bool FirstCall = true;
+};
+
+class TListCodegenValueOne : public TComputationValue<TListCodegenValueOne> {
+public:
+ using TNextPtr = TCodegenIteratorOne::TNextPtr;
+
+ TListCodegenValueOne(TMemoryUsageInfo* memInfo, TNextPtr nextOne, TNextPtr nextTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& list)
+ : TComputationValue<TListCodegenValueOne>(memInfo)
+ , NextFuncOne(nextOne)
+ , NextFuncTwo(nextTwo)
+ , Ctx(ctx)
+ , List(std::move(list))
+ {}
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TUnboxedValuePod(new TCodegenIteratorOne(GetMemInfo(), NextFuncOne, NextFuncTwo, Ctx, List.GetListIterator()));
+ }
+
+ ui64 GetListLength() const final {
+ return List.GetListLength();
+ }
+
+ bool HasListItems() const final {
+ return List.HasListItems();
+ }
+
+ bool HasFastListLength() const final {
+ return List.HasFastListLength();
+ }
+
+ const TNextPtr NextFuncOne;
+ const TNextPtr NextFuncTwo;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue List;
+};
+
class TStreamCodegenValueStateless : public TComputationValue<TStreamCodegenValueStateless> {
-public:
+public:
using TBase = TComputationValue<TStreamCodegenValueStateless>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
TStreamCodegenValueStateless(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream)
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- {}
-
-protected:
- ui32 GetTraverseCount() const final {
- return 1;
- }
-
- NUdf::TUnboxedValue GetTraverseItem(ui32) const final {
- return Stream;
- }
-
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ {}
+
+protected:
+ ui32 GetTraverseCount() const final {
+ return 1;
+ }
+
+ NUdf::TUnboxedValue GetTraverseItem(ui32) const final {
+ return Stream;
+ }
+
NUdf::TUnboxedValue Save() const override {
return NUdf::TUnboxedValue::Zero();
}
@@ -1207,256 +1207,256 @@ protected:
Y_UNUSED(state);
}
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
-};
-
-class TStreamCodegenValueOne : public TComputationValue<TStreamCodegenValueOne> {
-public:
- using TBase = TComputationValue<TStreamCodegenValueOne>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
-
- TStreamCodegenValueOne(TMemoryUsageInfo* memInfo, TFetchPtr fetchOne, TFetchPtr fetchTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& stream)
- : TBase(memInfo)
- , FetchFuncOne(fetchOne)
- , FetchFuncTwo(fetchTwo)
- , Ctx(ctx)
- , Stream(std::move(stream))
- {}
-
-private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- if (FirstCall) {
- FirstCall = false;
- return FetchFuncOne(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
- } else {
- return FetchFuncTwo(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
- }
- }
-
- const TFetchPtr FetchFuncOne;
- const TFetchPtr FetchFuncTwo;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
- bool FirstCall = true;
-};
-
-template <typename TState = NUdf::TUnboxedValue>
-class TStreamCodegenStatefulValueT : public TComputationValue<TStreamCodegenStatefulValueT<TState>> {
-public:
- using TBase = TComputationValue<TStreamCodegenStatefulValueT<TState>>;
-
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState&, NUdf::TUnboxedValuePod&);
-
- TStreamCodegenStatefulValueT(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TState&& init = TState())
- : TBase(memInfo)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- , State(std::move(init))
- {}
-
-protected:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), State, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
- TState State;
-};
-
-using TStreamCodegenStatefulValue = TStreamCodegenStatefulValueT<>;
-
-template <class StateType>
-class TStreamCodegenSelfStateValue : public StateType {
-using TState = StateType;
-public:
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState* state, NUdf::TUnboxedValuePod&);
-
- template <typename...TArgs>
- TStreamCodegenSelfStateValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TArgs&&...args)
- : TState(memInfo, std::forward<TArgs>(args)...)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- {}
-
-private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), this, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
-};
-
-template <class StateType>
-class TStreamCodegenSelfStatePlusValue : public StateType {
-using TState = StateType;
-public:
- using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState* state, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&);
-
- template <typename...TArgs>
- TStreamCodegenSelfStatePlusValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TArgs&&...args)
- : TState(memInfo, std::forward<TArgs>(args)...)
- , FetchFunc(fetch)
- , Ctx(ctx)
- , Stream(std::move(stream))
- {}
-
-private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), this, State, result);
- }
-
- const TFetchPtr FetchFunc;
- TComputationContext* const Ctx;
- const NUdf::TUnboxedValue Stream;
- NUdf::TUnboxedValue State;
-};
-
-template <typename TDerived>
-class TCustomValueCodegeneratorNode: public TMutableCodegeneratorFallbackNode<TDerived>, public ICodegeneratorRootNode
-{
-using TBase = TMutableCodegeneratorFallbackNode<TDerived>;
-
-protected:
- TCustomValueCodegeneratorNode(TComputationMutables& mutables)
- : TBase(mutables, EValueRepresentation::Boxed)
- {}
-
- TString MakeName(const TString& method) const {
- TStringStream out;
- out << this->DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-};
-
-template <typename TDerived>
-class TBothWaysCodegeneratorNode: public TMutableCodegeneratorRootNode<TDerived>
-{
-using TBase = TMutableCodegeneratorRootNode<TDerived>;
-
-protected:
- TBothWaysCodegeneratorNode(TComputationMutables& mutables)
- : TBase(mutables, EValueRepresentation::Boxed)
- {}
-
- TString MakeName(const TString& method) const {
- TStringStream out;
- out << this->DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
- return out.Str();
- }
-};
-
-template<typename T> Type* GetTypeFor(LLVMContext &context);
-
-template<typename T> inline Value* GetterFor(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto trunc = CastInst::Create(Instruction::Trunc, value, std::is_same<T, bool>() ? Type::getInt1Ty(context) : IntegerType::get(context, sizeof(T) << 3U), "trunc", block);
- if (std::is_integral<T>::value)
- return trunc;
- return CastInst::Create(Instruction::BitCast, trunc, GetTypeFor<T>(context), "bitcast", block);
-}
-
-template<typename T> inline
-Value* SetterFor(Value* value, LLVMContext &context, BasicBlock* block) {
- if (value->getType()->isFloatingPointTy())
- value = CastInst::Create(Instruction::BitCast, value, IntegerType::get(context, sizeof(T) << 3U), "bitcast", block);
-
- const auto type = Type::getInt128Ty(context);
- const auto zext = CastInst::Create(Instruction::ZExt, value, type, "zext", block);
- const uint64_t init[] = {0ULL, 0x100000000000000ULL}; // Embedded
- const auto meta = ConstantInt::get(context, APInt(128, 2, init));
- const auto full = BinaryOperator::CreateOr(zext, meta, "or", block);
- return full;
-}
-
-Value* SetterForInt128(Value* value, BasicBlock* block);
-Value* GetterForInt128(Value* value, BasicBlock* block);
-
-Value* GetterForTimezone(LLVMContext& context, Value* value, BasicBlock* block);
-
-template<typename TSrc, typename TDst> inline
-Value* StaticCast(Value* value, LLVMContext &context, BasicBlock* block) {
- if (std::is_same<TSrc, TDst>())
- return value;
-
- if (std::is_integral<TSrc>() == std::is_integral<TDst>()) {
- if (std::is_integral<TSrc>()) {
- if (sizeof(TSrc) > sizeof(TDst)) {
- if (std::is_same<TDst, bool>())
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, value, ConstantInt::get(value->getType(), 0), "test", block);
- else
- return CastInst::Create(Instruction::Trunc, value, GetTypeFor<TDst>(context), "trunc", block);
- } else if ((sizeof(TSrc) < sizeof(TDst))) {
- return CastInst::Create(std::is_signed<TSrc>() ? Instruction::SExt : Instruction::ZExt, value, GetTypeFor<TDst>(context), "ext", block);
- } else {
- return value;
- }
- } else {
- if (sizeof(TSrc) > sizeof(TDst)) {
- return CastInst::Create(Instruction::FPTrunc, value, GetTypeFor<TDst>(context), "fptrunc", block);
- } else if ((sizeof(TSrc) < sizeof(TDst))) {
- return CastInst::Create(Instruction::FPExt, value, GetTypeFor<TDst>(context), "fpext", block);
- } else {
- return value;
- }
- }
- } else {
- constexpr auto instruction = std::is_integral<TSrc>() ?
- std::is_signed<TSrc>() ? Instruction::SIToFP : Instruction::UIToFP:
- std::is_signed<TDst>() ? Instruction::FPToSI : Instruction::FPToUI;
- return CastInst::Create(instruction, value, GetTypeFor<TDst>(context), std::is_integral<TSrc>() ? "int_to_float" : "float_to_int", block);
- }
-}
-
-Value* GetOptionalValue(LLVMContext& context, Value* value, BasicBlock* block);
-Value* MakeOptional(LLVMContext& context, Value* value, BasicBlock* block);
-
-Value* MakeBoolean(Value* boolean, LLVMContext &context, BasicBlock* block);
-
-ConstantInt* GetEmpty(LLVMContext &context);
-
-ConstantInt* GetTrue(LLVMContext &context);
-ConstantInt* GetFalse(LLVMContext &context);
-
-ConstantInt* GetDecimalPlusInf(LLVMContext &context);
-ConstantInt* GetDecimalMinusInf(LLVMContext &context);
-
-ConstantInt* GetDecimalNan(LLVMContext &context);
-ConstantInt* GetDecimalMinusNan(LLVMContext &context);
-
-ConstantInt* GetInvalid(LLVMContext &context);
-ConstantInt* GetFinish(LLVMContext &context);
-ConstantInt* GetYield(LLVMContext &context);
-
-ConstantInt* GetConstant(ui64 value, LLVMContext &context);
-
-Value* IsExists(Value* value, BasicBlock* block);
-Value* IsEmpty(Value* value, BasicBlock* block);
-Value* IsInvalid(Value* value, BasicBlock* block);
-Value* IsValid(Value* value, BasicBlock* block);
-Value* IsFinish(Value* value, BasicBlock* block);
-Value* IsYield(Value* value, BasicBlock* block);
-Value* IsSpecial(Value* value, BasicBlock* block);
-Value* HasValue(Value* value, BasicBlock* block);
-
-Value* GenNewArray(const TCodegenContext& ctx, Value* size, Value* items, BasicBlock* block);
-
-Value* GetMemoryUsed(ui64 limit, const TCodegenContext& ctx, BasicBlock* block);
-
-template <bool TrackRss>
-Value* CheckAdjustedMemLimit(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
-
-}
-}
-#endif
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+};
+
+class TStreamCodegenValueOne : public TComputationValue<TStreamCodegenValueOne> {
+public:
+ using TBase = TComputationValue<TStreamCodegenValueOne>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, NUdf::TUnboxedValuePod&);
+
+ TStreamCodegenValueOne(TMemoryUsageInfo* memInfo, TFetchPtr fetchOne, TFetchPtr fetchTwo, TComputationContext* ctx, NUdf::TUnboxedValue&& stream)
+ : TBase(memInfo)
+ , FetchFuncOne(fetchOne)
+ , FetchFuncTwo(fetchTwo)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ {}
+
+private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ if (FirstCall) {
+ FirstCall = false;
+ return FetchFuncOne(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
+ } else {
+ return FetchFuncTwo(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), result);
+ }
+ }
+
+ const TFetchPtr FetchFuncOne;
+ const TFetchPtr FetchFuncTwo;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+ bool FirstCall = true;
+};
+
+template <typename TState = NUdf::TUnboxedValue>
+class TStreamCodegenStatefulValueT : public TComputationValue<TStreamCodegenStatefulValueT<TState>> {
+public:
+ using TBase = TComputationValue<TStreamCodegenStatefulValueT<TState>>;
+
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState&, NUdf::TUnboxedValuePod&);
+
+ TStreamCodegenStatefulValueT(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TState&& init = TState())
+ : TBase(memInfo)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ , State(std::move(init))
+ {}
+
+protected:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), State, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+ TState State;
+};
+
+using TStreamCodegenStatefulValue = TStreamCodegenStatefulValueT<>;
+
+template <class StateType>
+class TStreamCodegenSelfStateValue : public StateType {
+using TState = StateType;
+public:
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState* state, NUdf::TUnboxedValuePod&);
+
+ template <typename...TArgs>
+ TStreamCodegenSelfStateValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TArgs&&...args)
+ : TState(memInfo, std::forward<TArgs>(args)...)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ {}
+
+private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), this, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+};
+
+template <class StateType>
+class TStreamCodegenSelfStatePlusValue : public StateType {
+using TState = StateType;
+public:
+ using TFetchPtr = NUdf::EFetchStatus (*)(TComputationContext*, NUdf::TUnboxedValuePod, TState* state, NUdf::TUnboxedValuePod&, NUdf::TUnboxedValuePod&);
+
+ template <typename...TArgs>
+ TStreamCodegenSelfStatePlusValue(TMemoryUsageInfo* memInfo, TFetchPtr fetch, TComputationContext* ctx, NUdf::TUnboxedValue&& stream, TArgs&&...args)
+ : TState(memInfo, std::forward<TArgs>(args)...)
+ , FetchFunc(fetch)
+ , Ctx(ctx)
+ , Stream(std::move(stream))
+ {}
+
+private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
+ return FetchFunc(Ctx, static_cast<const NUdf::TUnboxedValuePod&>(Stream), this, State, result);
+ }
+
+ const TFetchPtr FetchFunc;
+ TComputationContext* const Ctx;
+ const NUdf::TUnboxedValue Stream;
+ NUdf::TUnboxedValue State;
+};
+
+template <typename TDerived>
+class TCustomValueCodegeneratorNode: public TMutableCodegeneratorFallbackNode<TDerived>, public ICodegeneratorRootNode
+{
+using TBase = TMutableCodegeneratorFallbackNode<TDerived>;
+
+protected:
+ TCustomValueCodegeneratorNode(TComputationMutables& mutables)
+ : TBase(mutables, EValueRepresentation::Boxed)
+ {}
+
+ TString MakeName(const TString& method) const {
+ TStringStream out;
+ out << this->DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+};
+
+template <typename TDerived>
+class TBothWaysCodegeneratorNode: public TMutableCodegeneratorRootNode<TDerived>
+{
+using TBase = TMutableCodegeneratorRootNode<TDerived>;
+
+protected:
+ TBothWaysCodegeneratorNode(TComputationMutables& mutables)
+ : TBase(mutables, EValueRepresentation::Boxed)
+ {}
+
+ TString MakeName(const TString& method) const {
+ TStringStream out;
+ out << this->DebugString() << "::" << method << "_(" << static_cast<const void*>(this) << ").";
+ return out.Str();
+ }
+};
+
+template<typename T> Type* GetTypeFor(LLVMContext &context);
+
+template<typename T> inline Value* GetterFor(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto trunc = CastInst::Create(Instruction::Trunc, value, std::is_same<T, bool>() ? Type::getInt1Ty(context) : IntegerType::get(context, sizeof(T) << 3U), "trunc", block);
+ if (std::is_integral<T>::value)
+ return trunc;
+ return CastInst::Create(Instruction::BitCast, trunc, GetTypeFor<T>(context), "bitcast", block);
+}
+
+template<typename T> inline
+Value* SetterFor(Value* value, LLVMContext &context, BasicBlock* block) {
+ if (value->getType()->isFloatingPointTy())
+ value = CastInst::Create(Instruction::BitCast, value, IntegerType::get(context, sizeof(T) << 3U), "bitcast", block);
+
+ const auto type = Type::getInt128Ty(context);
+ const auto zext = CastInst::Create(Instruction::ZExt, value, type, "zext", block);
+ const uint64_t init[] = {0ULL, 0x100000000000000ULL}; // Embedded
+ const auto meta = ConstantInt::get(context, APInt(128, 2, init));
+ const auto full = BinaryOperator::CreateOr(zext, meta, "or", block);
+ return full;
+}
+
+Value* SetterForInt128(Value* value, BasicBlock* block);
+Value* GetterForInt128(Value* value, BasicBlock* block);
+
+Value* GetterForTimezone(LLVMContext& context, Value* value, BasicBlock* block);
+
+template<typename TSrc, typename TDst> inline
+Value* StaticCast(Value* value, LLVMContext &context, BasicBlock* block) {
+ if (std::is_same<TSrc, TDst>())
+ return value;
+
+ if (std::is_integral<TSrc>() == std::is_integral<TDst>()) {
+ if (std::is_integral<TSrc>()) {
+ if (sizeof(TSrc) > sizeof(TDst)) {
+ if (std::is_same<TDst, bool>())
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, value, ConstantInt::get(value->getType(), 0), "test", block);
+ else
+ return CastInst::Create(Instruction::Trunc, value, GetTypeFor<TDst>(context), "trunc", block);
+ } else if ((sizeof(TSrc) < sizeof(TDst))) {
+ return CastInst::Create(std::is_signed<TSrc>() ? Instruction::SExt : Instruction::ZExt, value, GetTypeFor<TDst>(context), "ext", block);
+ } else {
+ return value;
+ }
+ } else {
+ if (sizeof(TSrc) > sizeof(TDst)) {
+ return CastInst::Create(Instruction::FPTrunc, value, GetTypeFor<TDst>(context), "fptrunc", block);
+ } else if ((sizeof(TSrc) < sizeof(TDst))) {
+ return CastInst::Create(Instruction::FPExt, value, GetTypeFor<TDst>(context), "fpext", block);
+ } else {
+ return value;
+ }
+ }
+ } else {
+ constexpr auto instruction = std::is_integral<TSrc>() ?
+ std::is_signed<TSrc>() ? Instruction::SIToFP : Instruction::UIToFP:
+ std::is_signed<TDst>() ? Instruction::FPToSI : Instruction::FPToUI;
+ return CastInst::Create(instruction, value, GetTypeFor<TDst>(context), std::is_integral<TSrc>() ? "int_to_float" : "float_to_int", block);
+ }
+}
+
+Value* GetOptionalValue(LLVMContext& context, Value* value, BasicBlock* block);
+Value* MakeOptional(LLVMContext& context, Value* value, BasicBlock* block);
+
+Value* MakeBoolean(Value* boolean, LLVMContext &context, BasicBlock* block);
+
+ConstantInt* GetEmpty(LLVMContext &context);
+
+ConstantInt* GetTrue(LLVMContext &context);
+ConstantInt* GetFalse(LLVMContext &context);
+
+ConstantInt* GetDecimalPlusInf(LLVMContext &context);
+ConstantInt* GetDecimalMinusInf(LLVMContext &context);
+
+ConstantInt* GetDecimalNan(LLVMContext &context);
+ConstantInt* GetDecimalMinusNan(LLVMContext &context);
+
+ConstantInt* GetInvalid(LLVMContext &context);
+ConstantInt* GetFinish(LLVMContext &context);
+ConstantInt* GetYield(LLVMContext &context);
+
+ConstantInt* GetConstant(ui64 value, LLVMContext &context);
+
+Value* IsExists(Value* value, BasicBlock* block);
+Value* IsEmpty(Value* value, BasicBlock* block);
+Value* IsInvalid(Value* value, BasicBlock* block);
+Value* IsValid(Value* value, BasicBlock* block);
+Value* IsFinish(Value* value, BasicBlock* block);
+Value* IsYield(Value* value, BasicBlock* block);
+Value* IsSpecial(Value* value, BasicBlock* block);
+Value* HasValue(Value* value, BasicBlock* block);
+
+Value* GenNewArray(const TCodegenContext& ctx, Value* size, Value* items, BasicBlock* block);
+
+Value* GetMemoryUsed(ui64 limit, const TCodegenContext& ctx, BasicBlock* block);
+
+template <bool TrackRss>
+Value* CheckAdjustedMemLimit(ui64 limit, Value* init, const TCodegenContext& ctx, BasicBlock*& block);
+
+}
+}
+#endif
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
index c0f477e711..f2b188ae47 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
@@ -1,19 +1,19 @@
#include "mkql_computation_node_holders.h"
-#include "mkql_value_builder.h"
-#include "mkql_computation_node_codegen.h"
+#include "mkql_value_builder.h"
+#include "mkql_computation_node_codegen.h"
#include <ydb/library/yql/minikql/arrow/mkql_memory_pool.h>
#include <ydb/library/yql/minikql/comp_nodes/mkql_saveload.h>
#include <ydb/library/yql/minikql/mkql_type_builder.h>
#include <ydb/library/yql/minikql/mkql_terminator.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
-#include <util/system/env.h>
+#include <util/system/env.h>
#include <util/system/mutex.h>
#include <util/digest/city.h>
-#ifndef MKQL_DISABLE_CODEGEN
-#include <llvm/Support/raw_ostream.h>
-#endif
-
+#ifndef MKQL_DISABLE_CODEGEN
+#include <llvm/Support/raw_ostream.h>
+#endif
+
namespace NKikimr {
namespace NMiniKQL {
@@ -49,26 +49,26 @@ const static TStatKey CodeGen_FinalizeTime("CodeGen_FinalizeTime", true);
const static TStatKey Mkql_TotalNodes("Mkql_TotalNodes", true);
const static TStatKey Mkql_CodegenFunctions("Mkql_CodegenFunctions", true);
-
+
class TDependencyScanVisitor : public TEmptyNodeVisitor {
public:
- void Walk(TNode* root, const TTypeEnvironment& env) {
- Stack = &env.GetNodeStack();
- Stack->clear();
- Stack->push_back(root);
- while (!Stack->empty()) {
- auto top = Stack->back();
- Stack->pop_back();
- if (top->GetCookie() != IS_NODE_REACHABLE) {
- top->SetCookie(IS_NODE_REACHABLE);
- top->Accept(*this);
- }
- }
-
- Stack = nullptr;
- }
-
-private:
+ void Walk(TNode* root, const TTypeEnvironment& env) {
+ Stack = &env.GetNodeStack();
+ Stack->clear();
+ Stack->push_back(root);
+ while (!Stack->empty()) {
+ auto top = Stack->back();
+ Stack->pop_back();
+ if (top->GetCookie() != IS_NODE_REACHABLE) {
+ top->SetCookie(IS_NODE_REACHABLE);
+ top->Accept(*this);
+ }
+ }
+
+ Stack = nullptr;
+ }
+
+private:
using TEmptyNodeVisitor::Visit;
void Visit(TStructLiteral& node) override {
@@ -129,7 +129,7 @@ private:
}
}
- std::vector<TNode*>* Stack = nullptr;
+ std::vector<TNode*>* Stack = nullptr;
};
class TPatternNodes: public TAtomicRefCount<TPatternNodes> {
@@ -164,8 +164,8 @@ public:
}
IComputationNode* GetComputationNode(TNode* node, bool pop = false, bool require = true) {
- const auto cookie = node->GetCookie();
- const auto result = reinterpret_cast<IComputationNode*>(cookie);
+ const auto cookie = node->GetCookie();
+ const auto result = reinterpret_cast<IComputationNode*>(cookie);
if (cookie <= IS_NODE_REACHABLE) {
MKQL_ENSURE(!require, "Computation graph builder, node not found, type:"
@@ -180,7 +180,7 @@ public:
return result;
}
- IComputationExternalNode* GetEntryPoint(size_t index, bool require) {
+ IComputationExternalNode* GetEntryPoint(size_t index, bool require) {
MKQL_ENSURE(index < Runtime2Computation.size() && (!require || Runtime2Computation[index]),
"Pattern nodes can not get computation node by index: " << index << ", require: " << require);
return Runtime2Computation[index];
@@ -197,12 +197,12 @@ private:
TAllocState& AllocState;
TIntrusivePtr<TMemoryUsageInfo> MemInfo;
THolder<THolderFactory> HolderFactory;
- THolder<TDefaultValueBuilder> ValueBuilder;
+ THolder<TDefaultValueBuilder> ValueBuilder;
TComputationMutables Mutables;
TComputationNodePtrDeque ComputationNodesList;
IComputationNode* RootNode = nullptr;
- TComputationExternalNodePtrVector Runtime2Computation;
- TComputationNodeOnNodeMap ElementsCache;
+ TComputationExternalNodePtrVector Runtime2Computation;
+ TComputationNodeOnNodeMap ElementsCache;
};
class TComputationGraphBuildingVisitor:
@@ -223,8 +223,8 @@ public:
, PatternNodes(MakeIntrusive<TPatternNodes>(opts.AllocState))
, ExternalAlloc(opts.CacheAlloc)
{
- PatternNodes->HolderFactory = MakeHolder<THolderFactory>(opts.AllocState, *PatternNodes->MemInfo, &FunctionRegistry);
- PatternNodes->ValueBuilder = MakeHolder<TDefaultValueBuilder>(*PatternNodes->HolderFactory, ValidatePolicy);
+ PatternNodes->HolderFactory = MakeHolder<THolderFactory>(opts.AllocState, *PatternNodes->MemInfo, &FunctionRegistry);
+ PatternNodes->ValueBuilder = MakeHolder<TDefaultValueBuilder>(*PatternNodes->HolderFactory, ValidatePolicy);
PatternNodes->ValueBuilder->SetSecureParamsProvider(opts.SecureParamsProvider);
NodeFactory = MakeHolder<TNodeFactory>(*PatternNodes->MemInfo, PatternNodes->Mutables);
}
@@ -240,10 +240,10 @@ public:
return FunctionRegistry;
}
-private:
+private:
template <typename T>
void VisitType(T& node) {
- AddNode(node, NodeFactory->CreateTypeNode(&node));
+ AddNode(node, NodeFactory->CreateTypeNode(&node));
}
void Visit(TTypeType& node) override {
@@ -282,10 +282,10 @@ private:
VisitType<TStreamType>(node);
}
- void Visit(TFlowType& node) override {
- VisitType<TFlowType>(node);
- }
-
+ void Visit(TFlowType& node) override {
+ VisitType<TFlowType>(node);
+ }
+
void Visit(TBlockType& node) override {
VisitType<TBlockType>(node);
}
@@ -323,7 +323,7 @@ private:
}
void Visit(TVoid& node) override {
- AddNode(node, NodeFactory->CreateImmutableNode(NUdf::TUnboxedValue::Void()));
+ AddNode(node, NodeFactory->CreateImmutableNode(NUdf::TUnboxedValue::Void()));
}
void Visit(TNull& node) override {
@@ -339,18 +339,18 @@ private:
}
void Visit(TDataLiteral& node) override {
- auto value = node.AsValue();
- NUdf::TDataTypeId typeId = node.GetType()->GetSchemeType();
- if (typeId != 0x101) { // TODO remove
- const auto slot = NUdf::GetDataSlot(typeId);
- MKQL_ENSURE(IsValidValue(slot, value),
- "Bad data literal for type: " << NUdf::GetDataTypeInfo(slot).Name << ", " << value);
- }
-
+ auto value = node.AsValue();
+ NUdf::TDataTypeId typeId = node.GetType()->GetSchemeType();
+ if (typeId != 0x101) { // TODO remove
+ const auto slot = NUdf::GetDataSlot(typeId);
+ MKQL_ENSURE(IsValidValue(slot, value),
+ "Bad data literal for type: " << NUdf::GetDataTypeInfo(slot).Name << ", " << value);
+ }
+
NUdf::TUnboxedValue externalValue;
if (ExternalAlloc) {
if (value.IsString()) {
- externalValue = MakeString(value.AsStringRef());
+ externalValue = MakeString(value.AsStringRef());
}
}
if (!externalValue) {
@@ -367,7 +367,7 @@ private:
values.push_back(GetComputationNode(node.GetValue(i).GetNode()));
}
- AddNode(node, NodeFactory->CreateArrayNode(std::move(values)));
+ AddNode(node, NodeFactory->CreateArrayNode(std::move(values)));
}
void Visit(TListLiteral& node) override {
@@ -377,7 +377,7 @@ private:
items.push_back(GetComputationNode(node.GetItems()[i].GetNode()));
}
- AddNode(node, NodeFactory->CreateArrayNode(std::move(items)));
+ AddNode(node, NodeFactory->CreateArrayNode(std::move(items)));
}
void Visit(TOptionalLiteral& node) override {
@@ -392,7 +392,7 @@ private:
bool encoded;
GetDictionaryKeyTypes(keyType, types, isTuple, encoded);
- std::vector<std::pair<IComputationNode*, IComputationNode*>> items;
+ std::vector<std::pair<IComputationNode*, IComputationNode*>> items;
items.reserve(node.GetItemsCount());
for (ui32 i = 0, e = node.GetItemsCount(); i < e; ++i) {
auto item = node.GetItem(i);
@@ -426,14 +426,14 @@ private:
SecureParamsProvider,
*NodeFactory,
*PatternNodes->HolderFactory,
- PatternNodes->ValueBuilder.Get(),
+ PatternNodes->ValueBuilder.Get(),
ValidateMode,
ValidatePolicy,
GraphPerProcess,
- PatternNodes->Mutables,
- PatternNodes->ElementsCache,
- std::bind(&TComputationGraphBuildingVisitor::PushBackNode, this, std::placeholders::_1));
- const auto computationNode = Factory(node, ctx);
+ PatternNodes->Mutables,
+ PatternNodes->ElementsCache,
+ std::bind(&TComputationGraphBuildingVisitor::PushBackNode, this, std::placeholders::_1));
+ const auto computationNode = Factory(node, ctx);
if (!computationNode) {
THROW yexception()
@@ -458,7 +458,7 @@ private:
values.push_back(GetComputationNode(node.GetValue(i).GetNode()));
}
- AddNode(node, NodeFactory->CreateArrayNode(std::move(values)));
+ AddNode(node, NodeFactory->CreateArrayNode(std::move(values)));
}
void Visit(TVariantLiteral& node) override {
@@ -466,7 +466,7 @@ private:
AddNode(node, NodeFactory->CreateVariantNode(item, node.GetIndex()));
}
-public:
+public:
IComputationNode* GetComputationNode(TNode* node, bool pop = false, bool require = true) {
return PatternNodes->GetComputationNode(node, pop, require);
}
@@ -491,21 +491,21 @@ public:
PatternNodes->RootNode = rootNode;
}
- void PreserveEntryPoints(TComputationExternalNodePtrVector&& runtime2Computation) {
+ void PreserveEntryPoints(TComputationExternalNodePtrVector&& runtime2Computation) {
PatternNodes->Runtime2Computation = std::move(runtime2Computation);
}
private:
void PushBackNode(const IComputationNode::TPtr& computationNode) {
- computationNode->RegisterDependencies();
+ computationNode->RegisterDependencies();
PatternNodes->ComputationNodesList.push_back(computationNode);
}
void AddNode(TNode& node, const IComputationNode::TPtr& computationNode) {
- PushBackNode(computationNode);
+ PushBackNode(computationNode);
node.SetCookie((ui64)computationNode.Get());
- }
-
+ }
+
private:
const TTypeEnvironment& Env;
NUdf::ITypeInfoHelper::TPtr TypeInfoHelper;
@@ -533,7 +533,7 @@ public:
CompOpts.AllocState.ActiveMemInfo.emplace(MemInfo.Get(), MemInfo);
#endif
HolderFactory = MakeHolder<THolderFactory>(CompOpts.AllocState, *MemInfo, patternNodes->HolderFactory->GetFunctionRegistry());
- ValueBuilder = MakeHolder<TDefaultValueBuilder>(*HolderFactory.Get(), compOpts.ValidatePolicy);
+ ValueBuilder = MakeHolder<TDefaultValueBuilder>(*HolderFactory.Get(), compOpts.ValidatePolicy);
ValueBuilder->SetSecureParamsProvider(CompOpts.SecureParamsProvider);
ArrowMemoryPool = MakeArrowMemoryPool(CompOpts.AllocState);
}
@@ -558,7 +558,7 @@ public:
CompOpts,
PatternNodes->GetMutables(),
*ArrowMemoryPool));
- ValueBuilder->SetCalleePositionHolder(Ctx->CalleePosition);
+ ValueBuilder->SetCalleePositionHolder(Ctx->CalleePosition);
for (auto& node : PatternNodes->GetNodes()) {
node->InitNode(*Ctx);
}
@@ -571,12 +571,12 @@ public:
return *Ctx;
}
- NUdf::TUnboxedValue GetValue() override {
+ NUdf::TUnboxedValue GetValue() override {
Prepare();
return PatternNodes->GetRoot()->GetValue(*Ctx);
}
- IComputationExternalNode* GetEntryPoint(size_t index, bool require) override {
+ IComputationExternalNode* GetEntryPoint(size_t index, bool require) override {
Prepare();
return PatternNodes->GetEntryPoint(index, require);
}
@@ -585,7 +585,7 @@ public:
std::fill_n(Ctx->MutableValues.get(), PatternNodes->GetMutables().CurValueIndex, NUdf::TUnboxedValue(NUdf::TUnboxedValuePod::Invalid()));
}
- const TComputationNodePtrDeque& GetNodes() const override {
+ const TComputationNodePtrDeque& GetNodes() const override {
return PatternNodes->GetNodes();
}
@@ -593,20 +593,20 @@ public:
return *MemInfo;
}
- const THolderFactory& GetHolderFactory() const override {
+ const THolderFactory& GetHolderFactory() const override {
return *HolderFactory;
}
- ITerminator* GetTerminator() const override {
- return ValueBuilder.Get();
- }
-
- bool SetExecuteLLVM(bool value) override {
- const bool old = Ctx->ExecuteLLVM;
- Ctx->ExecuteLLVM = value;
- return old;
- }
-
+ ITerminator* GetTerminator() const override {
+ return ValueBuilder.Get();
+ }
+
+ bool SetExecuteLLVM(bool value) override {
+ const bool old = Ctx->ExecuteLLVM;
+ Ctx->ExecuteLLVM = value;
+ return old;
+ }
+
TString SaveGraphState() override {
Prepare();
@@ -646,10 +646,10 @@ public:
}
private:
- const TPatternNodes::TPtr PatternNodes;
- const TIntrusivePtr<TMemoryUsageInfo> MemInfo;
+ const TPatternNodes::TPtr PatternNodes;
+ const TIntrusivePtr<TMemoryUsageInfo> MemInfo;
THolder<THolderFactory> HolderFactory;
- THolder<TDefaultValueBuilder> ValueBuilder;
+ THolder<TDefaultValueBuilder> ValueBuilder;
std::unique_ptr<arrow::MemoryPool> ArrowMemoryPool;
THolder<TComputationContext> Ctx;
TComputationOptsFull CompOpts;
@@ -665,44 +665,44 @@ public:
: Codegen()
#elif defined(MKQL_FORCE_USE_CODEGEN)
: Codegen(NYql::NCodegen::ICodegen::Make(NYql::NCodegen::ETarget::Native))
-#else
- : Codegen(opts.OptLLVM != "OFF" || GetEnv(TString("MKQL_FORCE_USE_LLVM")) ? NYql::NCodegen::ICodegen::Make(NYql::NCodegen::ETarget::Native) : NYql::NCodegen::ICodegen::TPtr())
-#endif
- {
- const auto& nodes = builder->GetNodes();
- for (const auto& node : nodes)
- node->PrepareStageOne();
- for (const auto& node : nodes)
- node->PrepareStageTwo();
- MKQL_ADD_STAT(opts.Stats, Mkql_TotalNodes, nodes.size());
+#else
+ : Codegen(opts.OptLLVM != "OFF" || GetEnv(TString("MKQL_FORCE_USE_LLVM")) ? NYql::NCodegen::ICodegen::Make(NYql::NCodegen::ETarget::Native) : NYql::NCodegen::ICodegen::TPtr())
+#endif
+ {
+ const auto& nodes = builder->GetNodes();
+ for (const auto& node : nodes)
+ node->PrepareStageOne();
+ for (const auto& node : nodes)
+ node->PrepareStageTwo();
+ MKQL_ADD_STAT(opts.Stats, Mkql_TotalNodes, nodes.size());
#ifndef MKQL_DISABLE_CODEGEN
- if (Codegen) {
+ if (Codegen) {
TStatTimer timerFull(CodeGen_FullTime);
timerFull.Acquire();
bool hasCode = false;
- {
- TStatTimer timerGen(CodeGen_GenerateTime);
- timerGen.Acquire();
- for (auto it = nodes.crbegin(); nodes.crend() != it; ++it) {
- if (const auto codegen = dynamic_cast<ICodegeneratorRootNode*>(it->Get())) {
- codegen->GenerateFunctions(Codegen);
- hasCode = true;
- }
+ {
+ TStatTimer timerGen(CodeGen_GenerateTime);
+ timerGen.Acquire();
+ for (auto it = nodes.crbegin(); nodes.crend() != it; ++it) {
+ if (const auto codegen = dynamic_cast<ICodegeneratorRootNode*>(it->Get())) {
+ codegen->GenerateFunctions(Codegen);
+ hasCode = true;
+ }
}
- timerGen.Release();
- timerGen.Report(opts.Stats);
- }
+ timerGen.Release();
+ timerGen.Report(opts.Stats);
+ }
if (hasCode) {
- if (opts.OptLLVM.Contains("--dump-generated")) {
- Cerr << "############### Begin generated module ###############" << Endl;
- Codegen->GetModule().print(llvm::errs(), nullptr);
- Cerr << "################ End generated module ################" << Endl;
- }
-
- TStatTimer timerComp(CodeGen_CompileTime);
- timerComp.Acquire();
-
+ if (opts.OptLLVM.Contains("--dump-generated")) {
+ Cerr << "############### Begin generated module ###############" << Endl;
+ Codegen->GetModule().print(llvm::errs(), nullptr);
+ Cerr << "################ End generated module ################" << Endl;
+ }
+
+ TStatTimer timerComp(CodeGen_CompileTime);
+ timerComp.Acquire();
+
NYql::NCodegen::TCodegenStats codegenStats;
Codegen->GetStats(codegenStats);
MKQL_ADD_STAT(opts.Stats, CodeGen_TotalFunctions, codegenStats.TotalFunctions);
@@ -713,7 +713,7 @@ public:
Cerr << "TotalInstructions: " << codegenStats.TotalInstructions << Endl;
Cerr << "MaxFunctionInstructions: " << codegenStats.MaxFunctionInstructions << Endl;
}
-
+
if (opts.OptLLVM.Contains("--dump-perf-map")) {
Codegen->TogglePerfJITEventListener();
}
@@ -730,16 +730,16 @@ public:
MKQL_ADD_STAT(opts.Stats, CodeGen_FinalizeTime, compileStats.FinalizeTime);
}
- timerComp.Release();
- timerComp.Report(opts.Stats);
-
+ timerComp.Release();
+ timerComp.Report(opts.Stats);
+
if (Codegen) {
if (opts.OptLLVM.Contains("--dump-compiled")) {
Cerr << "############### Begin compiled module ###############" << Endl;
Codegen->GetModule().print(llvm::errs(), nullptr);
Cerr << "################ End compiled module ################" << Endl;
}
-
+
if (opts.OptLLVM.Contains("--asm-compiled")) {
Cerr << "############### Begin compiled asm ###############" << Endl;
Codegen->ShowGeneratedFunctions(&Cerr);
@@ -752,20 +752,20 @@ public:
codegen->FinalizeFunctions(Codegen);
++count;
}
- }
+ }
if (count)
MKQL_ADD_STAT(opts.Stats, Mkql_CodegenFunctions, count);
}
- }
+ }
timerFull.Release();
timerFull.Report(opts.Stats);
- }
-#endif
+ }
+#endif
PatternNodes = builder->GetPatternNodes();
- }
-
+ }
+
~TComputationPatternImpl() {
if (Alloc) {
Alloc->Acquire();
@@ -812,26 +812,26 @@ TIntrusivePtr<TComputationPatternImpl> MakeComputationPatternImpl(TExploringNode
depScanner.Walk(root.GetNode(), opts.Env);
auto builder = MakeHolder<TComputationGraphBuildingVisitor>(opts);
- for (const auto& node : explorer.GetNodes()) {
+ for (const auto& node : explorer.GetNodes()) {
Y_VERIFY(node->GetCookie() <= IS_NODE_REACHABLE, "TNode graph should not be reused");
if (node->GetCookie() == IS_NODE_REACHABLE) {
node->Accept(*builder);
}
}
- const auto rootNode = builder->GetComputationNode(root.GetNode());
-
- TComputationExternalNodePtrVector runtime2Computation;
+ const auto rootNode = builder->GetComputationNode(root.GetNode());
+
+ TComputationExternalNodePtrVector runtime2Computation;
runtime2Computation.resize(entryPoints.size(), nullptr);
- for (const auto& node : explorer.GetNodes()) {
+ for (const auto& node : explorer.GetNodes()) {
for (auto iter = std::find(entryPoints.cbegin(), entryPoints.cend(), node); entryPoints.cend() != iter; iter = std::find(iter + 1, entryPoints.cend(), node)) {
- runtime2Computation[iter - entryPoints.begin()] = dynamic_cast<IComputationExternalNode*>(builder->GetComputationNode(node));
- }
+ runtime2Computation[iter - entryPoints.begin()] = dynamic_cast<IComputationExternalNode*>(builder->GetComputationNode(node));
+ }
node->SetCookie(0);
- }
+ }
builder->PreserveRoot(rootNode);
builder->PreserveEntryPoints(std::move(runtime2Computation));
-
+
return MakeIntrusive<TComputationPatternImpl>(std::move(builder), opts);
}
@@ -882,5 +882,5 @@ IComputationPattern::TPtr TComputationPatternCache::EmplacePattern(const TString
}
}
-} // namespace NMiniKQL
-} // namespace NKikimr
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_graph_saveload_ut.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_graph_saveload_ut.cpp
index c339d38c11..cc734e11d6 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_graph_saveload_ut.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_graph_saveload_ut.cpp
@@ -48,7 +48,7 @@ namespace {
Explorer.Walk(pgm.GetNode(), *Env);
TComputationPatternOpts opts(Alloc.Ref(), *Env, GetAuxCallableFactory(),
FunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "OFF", EGraphPerProcess::Multi);
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "OFF", EGraphPerProcess::Multi);
Pattern = MakeComputationPattern(Explorer, pgm, entryPoints, opts);
TComputationOptsFull compOpts = opts.ToComputationOptions(*RandomProvider, *TimeProvider);
return Pattern->Clone(compOpts);
@@ -67,14 +67,14 @@ namespace {
};
struct TStreamWithYield : public NUdf::TBoxedValue {
- TStreamWithYield(const TUnboxedValueVector& items, ui32 yieldPos, ui32 index)
+ TStreamWithYield(const TUnboxedValueVector& items, ui32 yieldPos, ui32 index)
: Items(items)
, YieldPos(yieldPos)
, Index(index)
{}
private:
- TUnboxedValueVector Items;
+ TUnboxedValueVector Items;
ui32 YieldPos;
ui32 Index;
@@ -107,7 +107,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
Y_UNIT_TEST(TestSqueezeSaveLoad) {
TScopedAlloc alloc;
- const std::vector<ui32> items = {2, 3, 4, 5, 6, 7, 8};
+ const std::vector<ui32> items = {2, 3, 4, 5, 6, 7, 8};
auto buildGraph = [&items] (TSetup& setup, ui32 yieldPos, ui32 startIndex) -> THolder<IComputationGraph> {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
@@ -131,7 +131,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
return state;
});
- TUnboxedValueVector streamItems;
+ TUnboxedValueVector streamItems;
for (auto item : items) {
streamItems.push_back(NUdf::TUnboxedValuePod(item));
}
@@ -146,9 +146,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
TSetup setup1(alloc);
auto graph1 = buildGraph(setup1, yieldPos, 0);
- auto root1 = graph1->GetValue();
+ auto root1 = graph1->GetValue();
NUdf::TUnboxedValue res;
- auto status = root1.Fetch(res);
+ auto status = root1.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Yield);
TString graphState;
@@ -158,13 +158,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
auto graph2 = buildGraph(setup2, -1, yieldPos);
auto root2 = graph2->GetValue();
- LoadGraphState(&root2, 1, 0ULL, graphState);
+ LoadGraphState(&root2, 1, 0ULL, graphState);
- status = root2.Fetch(res);
+ status = root2.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Ok);
UNIT_ASSERT_EQUAL(res.Get<ui32>(), 36);
- status = root2.Fetch(res);
+ status = root2.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
}
}
@@ -172,7 +172,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
Y_UNIT_TEST(TestSqueeze1SaveLoad) {
TScopedAlloc alloc;
- const std::vector<ui32> items = {1, 2, 3, 4, 5, 6, 7, 8};
+ const std::vector<ui32> items = {1, 2, 3, 4, 5, 6, 7, 8};
auto buildGraph = [&items] (TSetup& setup, ui32 yieldPos, ui32 startIndex) -> THolder<IComputationGraph> {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
@@ -198,7 +198,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
return state;
});
- TUnboxedValueVector streamItems;
+ TUnboxedValueVector streamItems;
for (auto item : items) {
streamItems.push_back(NUdf::TUnboxedValuePod(item));
}
@@ -213,10 +213,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
TSetup setup1(alloc);
auto graph1 = buildGraph(setup1, yieldPos, 0);
- auto root1 = graph1->GetValue();
-
+ auto root1 = graph1->GetValue();
+
NUdf::TUnboxedValue res;
- auto status = root1.Fetch(res);
+ auto status = root1.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Yield);
TString graphState;
@@ -226,13 +226,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
auto graph2 = buildGraph(setup2, -1, yieldPos);
auto root2 = graph2->GetValue();
- LoadGraphState(&root2, 1, 0ULL, graphState);
+ LoadGraphState(&root2, 1, 0ULL, graphState);
- status = root2.Fetch(res);
+ status = root2.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Ok);
UNIT_ASSERT_EQUAL(res.Get<ui32>(), 36);
- status = root2.Fetch(res);
+ status = root2.Fetch(res);
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
}
}
@@ -240,7 +240,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
Y_UNIT_TEST(TestHoppingSaveLoad) {
TScopedAlloc alloc;
- const std::vector<std::pair<i64, ui32>> items = {
+ const std::vector<std::pair<i64, ui32>> items = {
{1, 2},
{2, 3},
{15, 4},
@@ -260,9 +260,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
TProgramBuilder& pgmBuilder = *setup.PgmBuilder;
auto structType = pgmBuilder.NewEmptyStructType();
- structType = pgmBuilder.NewStructType(structType, "time",
+ structType = pgmBuilder.NewStructType(structType, "time",
pgmBuilder.NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id));
- structType = pgmBuilder.NewStructType(structType, "sum",
+ structType = pgmBuilder.NewStructType(structType, "sum",
pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
auto timeIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("time");
auto sumIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("sum");
@@ -277,41 +277,41 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
auto pgmReturn = pgmBuilder.HoppingCore(
TRuntimeNode(streamNode, false),
[&](TRuntimeNode item) { // timeExtractor
- return pgmBuilder.Member(item, "time");
+ return pgmBuilder.Member(item, "time");
},
[&](TRuntimeNode item) { // init
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", pgmBuilder.Member(item, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", pgmBuilder.Member(item, "sum"));
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode item, TRuntimeNode state) { // update
auto add = pgmBuilder.AggrAdd(
- pgmBuilder.Member(item, "sum"),
- pgmBuilder.Member(state, "sum"));
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", add);
+ pgmBuilder.Member(item, "sum"),
+ pgmBuilder.Member(state, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", add);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode state) { // save
- return pgmBuilder.Member(state, "sum");
+ return pgmBuilder.Member(state, "sum");
},
[&](TRuntimeNode savedState) { // load
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", savedState);
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", savedState);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode state1, TRuntimeNode state2) { // merge
auto add = pgmBuilder.AggrAdd(
- pgmBuilder.Member(state1, "sum"),
- pgmBuilder.Member(state2, "sum"));
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", add);
+ pgmBuilder.Member(state1, "sum"),
+ pgmBuilder.Member(state2, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", add);
return pgmBuilder.NewStruct(members);
},
[&](TRuntimeNode state, TRuntimeNode time) { // finish
Y_UNUSED(time);
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.emplace_back("sum", pgmBuilder.Member(state, "sum"));
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.emplace_back("sum", pgmBuilder.Member(state, "sum"));
return pgmBuilder.NewStruct(members);
},
pgmBuilder.NewDataLiteral<NUdf::EDataSlot::Interval>(NUdf::TStringRef((const char*)&hop, sizeof(hop))), // hop
@@ -321,7 +321,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
auto graph = setup.BuildGraph(pgmReturn, {streamNode});
- TUnboxedValueVector streamItems;
+ TUnboxedValueVector streamItems;
for (size_t i = 0; i < items.size(); ++i) {
NUdf::TUnboxedValue* itemsPtr;
auto structValues = graph->GetHolderFactory().CreateDirectArrayHolder(2, itemsPtr);
@@ -336,7 +336,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
};
for (ui32 yieldPos = 0; yieldPos < items.size(); ++yieldPos) {
- std::vector<ui32> result;
+ std::vector<ui32> result;
TSetup setup1(alloc);
auto graph1 = buildGraph(setup1, yieldPos, 0);
@@ -358,7 +358,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
TSetup setup2(alloc);
auto graph2 = buildGraph(setup2, -1, yieldPos);
auto root2 = graph2->GetValue();
- LoadGraphState(&root2, 1, 0ULL, graphState);
+ LoadGraphState(&root2, 1, 0ULL, graphState);
status = NUdf::EFetchStatus::Ok;
while (status == NUdf::EFetchStatus::Ok) {
@@ -370,7 +370,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLSaveLoadTest) {
}
UNIT_ASSERT_EQUAL(status, NUdf::EFetchStatus::Finish);
- const std::vector<ui32> resultCompare = {5, 9, 27, 22, 21, 11, 11, 8, 8, 8, 8};
+ const std::vector<ui32> resultCompare = {5, 9, 27, 22, 21, 11, 11, 8, 8, 8, 8};
UNIT_ASSERT_EQUAL(result, resultCompare);
}
}
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_holders.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_holders.cpp
index 293c19141e..67a7cfb302 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_holders.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_holders.cpp
@@ -1,10 +1,10 @@
#include "mkql_computation_node_holders.h"
-#include "mkql_computation_node_codegen.h"
+#include "mkql_computation_node_codegen.h"
#include "mkql_computation_node_pack.h"
-#include "mkql_custom_list.h"
+#include "mkql_custom_list.h"
#include "mkql_value_builder.h"
#include "presort.h"
-
+
#include <ydb/library/yql/minikql/mkql_node_builder.h>
#include <ydb/library/yql/minikql/mkql_utils.h>
#include <ydb/library/yql/minikql/mkql_alloc.h>
@@ -24,128 +24,128 @@ class TValueDataHolder: public TComputationValue<TValueDataHolder> {
public:
TValueDataHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
: TComputationValue(memInfo)
- , Value(std::move(value))
- {}
+ , Value(std::move(value))
+ {}
private:
- const NUdf::TUnboxedValue Value;
+ const NUdf::TUnboxedValue Value;
};
class TDirectListHolder: public TComputationValue<TDirectListHolder> {
public:
- class TIterator: public TComputationValue<TIterator> {
+ class TIterator: public TComputationValue<TIterator> {
public:
- TIterator(const TDirectListHolder* parent)
- : TComputationValue(parent->GetMemInfo())
- , Parent(const_cast<TDirectListHolder*>(parent))
- , Iterator(parent->Items)
+ TIterator(const TDirectListHolder* parent)
+ : TComputationValue(parent->GetMemInfo())
+ , Parent(const_cast<TDirectListHolder*>(parent))
+ , Iterator(parent->Items)
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- } else {
- if (Iterator.AtEnd()) {
- return false;
- }
-
- Iterator.Next();
- }
-
- return !Iterator.AtEnd();
- }
-
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Skip())
- return false;
- value = Iterator.Current();
- return true;
- }
-
- const NUdf::TRefCountedPtr<TDirectListHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ } else {
+ if (Iterator.AtEnd()) {
+ return false;
+ }
+
+ Iterator.Next();
+ }
+
+ return !Iterator.AtEnd();
+ }
+
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Skip())
+ return false;
+ value = Iterator.Current();
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<TDirectListHolder> Parent;
TDefaultListRepresentation::TIterator Iterator;
bool AtStart;
};
- class TDictIterator: public TComputationValue<TDictIterator> {
+ class TDictIterator: public TComputationValue<TDictIterator> {
public:
- TDictIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter)
- : TComputationValue(memInfo)
- , Iter(std::move(iter))
+ TDictIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter)
+ : TComputationValue(memInfo)
+ , Iter(std::move(iter))
, Index(Max<ui64>())
{}
- private:
- bool Next(NUdf::TUnboxedValue& key) override {
- if (Iter.Skip()) {
- key = NUdf::TUnboxedValuePod(++Index);
- return true;
- }
-
- return false;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (Iter.Next(payload)) {
- key = NUdf::TUnboxedValuePod(++Index);
- return true;
- }
-
- return false;
- }
-
- bool Skip() override {
- if (Iter.Skip()) {
- ++Index;
- return true;
- }
-
- return false;
- }
-
- const NUdf::TUnboxedValue Iter;
+ private:
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (Iter.Skip()) {
+ key = NUdf::TUnboxedValuePod(++Index);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (Iter.Next(payload)) {
+ key = NUdf::TUnboxedValuePod(++Index);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool Skip() override {
+ if (Iter.Skip()) {
+ ++Index;
+ return true;
+ }
+
+ return false;
+ }
+
+ const NUdf::TUnboxedValue Iter;
ui64 Index;
};
- TDirectListHolder(TMemoryUsageInfo* memInfo, TDefaultListRepresentation&& items)
+ TDirectListHolder(TMemoryUsageInfo* memInfo, TDefaultListRepresentation&& items)
: TComputationValue(memInfo)
- , Items(std::move(items))
- {}
-
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- const ui64 index = key.Get<ui64>();
- return (index < GetListLength());
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- const ui64 index = key.Get<ui64>();
- if (index >= GetListLength()) {
- return NUdf::TUnboxedValuePod();
- }
-
- return Items.GetItemByIndex(index).Release().MakeOptional();
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
+ , Items(std::move(items))
+ {}
+
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ const ui64 index = key.Get<ui64>();
+ return (index < GetListLength());
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ const ui64 index = key.Get<ui64>();
+ if (index >= GetListLength()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return Items.GetItemByIndex(index).Release().MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
bool HasFastListLength() const override {
return true;
}
@@ -167,18 +167,18 @@ private:
}
NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
- switch (Items.GetLength()) {
- case 0U: return builder.NewEmptyList().Release().AsBoxed();
- case 1U: return const_cast<TDirectListHolder*>(this);
- default: break;
+ switch (Items.GetLength()) {
+ case 0U: return builder.NewEmptyList().Release().AsBoxed();
+ case 1U: return const_cast<TDirectListHolder*>(this);
+ default: break;
}
TDefaultListRepresentation result;
for (auto it = Items.GetReverseIterator(); !it.AtEnd(); it.Next()) {
- result = result.Append(NUdf::TUnboxedValue(it.Current()));
+ result = result.Append(NUdf::TUnboxedValue(it.Current()));
}
- return new TDirectListHolder(GetMemInfo(), std::move(result));
+ return new TDirectListHolder(GetMemInfo(), std::move(result));
}
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
@@ -186,21 +186,21 @@ private:
return const_cast<TDirectListHolder*>(this);
if (count >= Items.GetLength())
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
auto result = Items.SkipFromBegin(static_cast<size_t>(count));
- return new TDirectListHolder(GetMemInfo(), std::move(result));
+ return new TDirectListHolder(GetMemInfo(), std::move(result));
}
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
if (count == 0)
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
if (count >= Items.GetLength())
return const_cast<TDirectListHolder*>(this);
auto result = Items.SkipFromEnd(static_cast<size_t>(Items.GetLength() - count));
- return new TDirectListHolder(GetMemInfo(), std::move(result));
+ return new TDirectListHolder(GetMemInfo(), std::move(result));
}
NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
@@ -216,14 +216,14 @@ private:
return Items.GetLength() != 0;
}
- NUdf::TUnboxedValue GetElement(ui32 index) const final {
- return Items.GetItemByIndex(index);
- }
-
- const NUdf::TUnboxedValue* GetElements() const final {
- return Items.GetItems();
- }
-
+ NUdf::TUnboxedValue GetElement(ui32 index) const final {
+ return Items.GetItemByIndex(index);
+ }
+
+ const NUdf::TUnboxedValue* GetElements() const final {
+ return Items.GetItems();
+ }
+
bool IsSortedDict() const override {
return true;
}
@@ -231,26 +231,26 @@ private:
TDefaultListRepresentation Items;
};
-class TOptionalNode: public TDecoratorCodegeneratorNode<TOptionalNode> {
- typedef TDecoratorCodegeneratorNode<TOptionalNode> TBaseComputation;
+class TOptionalNode: public TDecoratorCodegeneratorNode<TOptionalNode> {
+ typedef TDecoratorCodegeneratorNode<TOptionalNode> TBaseComputation;
public:
- TOptionalNode(IComputationNode* itemNode)
- : TBaseComputation(itemNode)
- {}
+ TOptionalNode(IComputationNode* itemNode)
+ : TBaseComputation(itemNode)
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
- return value.MakeOptional();
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext&, const NUdf::TUnboxedValuePod& value) const {
+ return value.MakeOptional();
}
#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
- return MakeOptional(ctx.Codegen->GetContext(), arg, block);
- }
-#endif
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, Value* arg, BasicBlock*& block) const {
+ return MakeOptional(ctx.Codegen->GetContext(), arg, block);
+ }
+#endif
};
-class TDirectArrayHolderInplace : public TComputationValue<TDirectArrayHolderInplace> {
-public:
+class TDirectArrayHolderInplace : public TComputationValue<TDirectArrayHolderInplace> {
+public:
void* operator new(size_t sz) = delete;
void* operator new[](size_t sz) = delete;
void operator delete(void *mem, std::size_t sz) {
@@ -260,188 +260,188 @@ public:
void operator delete[](void *mem, std::size_t sz) = delete;
- TDirectArrayHolderInplace(TMemoryUsageInfo* memInfo, ui32 size)
- : TComputationValue(memInfo)
- , Size(size)
- {
- MKQL_ENSURE(Size > 0U, "Can't create empty array holder.");
- MKQL_MEM_TAKE(GetMemInfo(), GetPtr(), Size * sizeof(NUdf::TUnboxedValue));
- std::memset(GetPtr(), 0, Size * sizeof(NUdf::TUnboxedValue));
- }
-
- ~TDirectArrayHolderInplace() {
- for (ui32 i = 0U; i < Size; ++i) {
- (GetPtr() + i)->~TUnboxedValue();
- }
- MKQL_MEM_RETURN(GetMemInfo(), GetPtr(), Size * sizeof(NUdf::TUnboxedValue));
- }
-
- ui32 GetSize() const {
- return Size;
- }
-
- NUdf::TUnboxedValue* GetPtr() const {
- return (NUdf::TUnboxedValue*)(this + 1);
- }
-
-private:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(const TDirectArrayHolderInplace* parent)
- : TComputationValue(parent->GetMemInfo()), Parent(const_cast<TDirectArrayHolderInplace*>(parent))
- {}
-
- private:
- bool Skip() final {
- return ++Current < Parent->GetSize();
- }
-
- bool Next(NUdf::TUnboxedValue& value) final {
- if (!Skip())
- return false;
- value = Parent->GetPtr()[Current];
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
- if (!Next(payload))
- return false;
- key = NUdf::TUnboxedValuePod(Current);
- return true;
- }
-
- const NUdf::TRefCountedPtr<TDirectArrayHolderInplace> Parent;
- ui32 Current = ~0U;
- };
-
- class TKeysIterator : public TComputationValue<TKeysIterator> {
- public:
- TKeysIterator(const TDirectArrayHolderInplace& parent)
- : TComputationValue(parent.GetMemInfo()), Size(parent.GetSize())
- {}
- private:
- bool Skip() final {
- return ++Current < Size;
- }
-
- bool Next(NUdf::TUnboxedValue& key) final {
- if (!Skip())
- return false;
- key = NUdf::TUnboxedValuePod(Current);
- return true;
- }
-
- const ui64 Size;
- ui64 Current = ~0ULL;
- };
-
- bool HasListItems() const final {
- return true;
- }
-
- bool HasDictItems() const final {
- return true;
- }
-
- bool HasFastListLength() const final {
- return true;
- }
-
- ui64 GetListLength() const final {
- return Size;
- }
-
- ui64 GetDictLength() const final {
- return Size;
- }
-
- ui64 GetEstimatedListLength() const final {
- return Size;
- }
-
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const final {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const final {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const final {
- return NUdf::TUnboxedValuePod(new TKeysIterator(*this));
- }
-
+ TDirectArrayHolderInplace(TMemoryUsageInfo* memInfo, ui32 size)
+ : TComputationValue(memInfo)
+ , Size(size)
+ {
+ MKQL_ENSURE(Size > 0U, "Can't create empty array holder.");
+ MKQL_MEM_TAKE(GetMemInfo(), GetPtr(), Size * sizeof(NUdf::TUnboxedValue));
+ std::memset(GetPtr(), 0, Size * sizeof(NUdf::TUnboxedValue));
+ }
+
+ ~TDirectArrayHolderInplace() {
+ for (ui32 i = 0U; i < Size; ++i) {
+ (GetPtr() + i)->~TUnboxedValue();
+ }
+ MKQL_MEM_RETURN(GetMemInfo(), GetPtr(), Size * sizeof(NUdf::TUnboxedValue));
+ }
+
+ ui32 GetSize() const {
+ return Size;
+ }
+
+ NUdf::TUnboxedValue* GetPtr() const {
+ return (NUdf::TUnboxedValue*)(this + 1);
+ }
+
+private:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(const TDirectArrayHolderInplace* parent)
+ : TComputationValue(parent->GetMemInfo()), Parent(const_cast<TDirectArrayHolderInplace*>(parent))
+ {}
+
+ private:
+ bool Skip() final {
+ return ++Current < Parent->GetSize();
+ }
+
+ bool Next(NUdf::TUnboxedValue& value) final {
+ if (!Skip())
+ return false;
+ value = Parent->GetPtr()[Current];
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
+ if (!Next(payload))
+ return false;
+ key = NUdf::TUnboxedValuePod(Current);
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<TDirectArrayHolderInplace> Parent;
+ ui32 Current = ~0U;
+ };
+
+ class TKeysIterator : public TComputationValue<TKeysIterator> {
+ public:
+ TKeysIterator(const TDirectArrayHolderInplace& parent)
+ : TComputationValue(parent.GetMemInfo()), Size(parent.GetSize())
+ {}
+ private:
+ bool Skip() final {
+ return ++Current < Size;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) final {
+ if (!Skip())
+ return false;
+ key = NUdf::TUnboxedValuePod(Current);
+ return true;
+ }
+
+ const ui64 Size;
+ ui64 Current = ~0ULL;
+ };
+
+ bool HasListItems() const final {
+ return true;
+ }
+
+ bool HasDictItems() const final {
+ return true;
+ }
+
+ bool HasFastListLength() const final {
+ return true;
+ }
+
+ ui64 GetListLength() const final {
+ return Size;
+ }
+
+ ui64 GetDictLength() const final {
+ return Size;
+ }
+
+ ui64 GetEstimatedListLength() const final {
+ return Size;
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const final {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const final {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const final {
+ return NUdf::TUnboxedValuePod(new TKeysIterator(*this));
+ }
+
NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const final {
- if (1U >= Size)
- return const_cast<TDirectArrayHolderInplace*>(this);
-
- NUdf::TUnboxedValue* items = nullptr;
- auto result = builder.NewArray(Size, items);
- std::reverse_copy(GetPtr(), GetPtr() + Size, items);
- return result.Release().AsBoxed();
- }
-
+ if (1U >= Size)
+ return const_cast<TDirectArrayHolderInplace*>(this);
+
+ NUdf::TUnboxedValue* items = nullptr;
+ auto result = builder.NewArray(Size, items);
+ std::reverse_copy(GetPtr(), GetPtr() + Size, items);
+ return result.Release().AsBoxed();
+ }
+
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
- if (!count)
- return const_cast<TDirectArrayHolderInplace*>(this);
-
- if (count >= Size)
- return builder.NewEmptyList().Release().AsBoxed();
-
- const auto newSize = Size - ui32(count);
- NUdf::TUnboxedValue* items = nullptr;
- auto result = builder.NewArray(newSize, items);
- std::copy_n(GetPtr() + count, newSize, items);
- return result.Release().AsBoxed();
- }
-
+ if (!count)
+ return const_cast<TDirectArrayHolderInplace*>(this);
+
+ if (count >= Size)
+ return builder.NewEmptyList().Release().AsBoxed();
+
+ const auto newSize = Size - ui32(count);
+ NUdf::TUnboxedValue* items = nullptr;
+ auto result = builder.NewArray(newSize, items);
+ std::copy_n(GetPtr() + count, newSize, items);
+ return result.Release().AsBoxed();
+ }
+
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
- if (!count)
- return builder.NewEmptyList().Release().AsBoxed();
-
- if (count >= Size)
- return const_cast<TDirectArrayHolderInplace*>(this);
-
- const auto newSize = ui32(count);
- NUdf::TUnboxedValue* items = nullptr;
- auto result = builder.NewArray(newSize, items);
- std::copy_n(GetPtr(), newSize, items);
- return result.Release().AsBoxed();
- }
-
+ if (!count)
+ return builder.NewEmptyList().Release().AsBoxed();
+
+ if (count >= Size)
+ return const_cast<TDirectArrayHolderInplace*>(this);
+
+ const auto newSize = ui32(count);
+ NUdf::TUnboxedValue* items = nullptr;
+ auto result = builder.NewArray(newSize, items);
+ std::copy_n(GetPtr(), newSize, items);
+ return result.Release().AsBoxed();
+ }
+
NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder&) const final {
- return const_cast<TDirectArrayHolderInplace*>(this);
- }
-
- bool Contains(const NUdf::TUnboxedValuePod& key) const final {
- return key.Get<ui64>() < Size;
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
- const auto index = key.Get<ui64>();
- return index < Size ? GetPtr()[index].MakeOptional() : NUdf::TUnboxedValuePod();
- }
-
- NUdf::TUnboxedValue GetElement(ui32 index) const final {
- Y_VERIFY_DEBUG(index < Size);
- return GetPtr()[index];
- }
-
- const NUdf::TUnboxedValue* GetElements() const final {
- return GetPtr();
- }
-
+ return const_cast<TDirectArrayHolderInplace*>(this);
+ }
+
+ bool Contains(const NUdf::TUnboxedValuePod& key) const final {
+ return key.Get<ui64>() < Size;
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
+ const auto index = key.Get<ui64>();
+ return index < Size ? GetPtr()[index].MakeOptional() : NUdf::TUnboxedValuePod();
+ }
+
+ NUdf::TUnboxedValue GetElement(ui32 index) const final {
+ Y_VERIFY_DEBUG(index < Size);
+ return GetPtr()[index];
+ }
+
+ const NUdf::TUnboxedValue* GetElements() const final {
+ return GetPtr();
+ }
+
bool IsSortedDict() const override {
return true;
}
- const ui32 Size;
-};
-
+ const ui32 Size;
+};
+
class TFlatDataBlockImpl : public TComputationValue<TFlatDataBlockImpl, NUdf::TFlatDataBlock> {
public:
TFlatDataBlockImpl(TMemoryUsageInfo* memInfo, ui32 initialSize, ui32 initialCapacity)
@@ -552,19 +552,19 @@ public:
}
};
-class TArrayNode: public TMutableCodegeneratorFallbackNode<TArrayNode> {
- typedef TMutableCodegeneratorFallbackNode<TArrayNode> TBaseComputation;
+class TArrayNode: public TMutableCodegeneratorFallbackNode<TArrayNode> {
+ typedef TMutableCodegeneratorFallbackNode<TArrayNode> TBaseComputation;
public:
TArrayNode(TComputationMutables& mutables, TComputationNodePtrVector&& valueNodes)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
, ValueNodes(std::move(valueNodes))
, Cache(mutables)
{
}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- NUdf::TUnboxedValue *items = nullptr;
- const auto result = Cache.NewArray(ctx, ValueNodes.size(), items);
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto result = Cache.NewArray(ctx, ValueNodes.size(), items);
if (!ValueNodes.empty()) {
Y_VERIFY(items);
for (const auto& node : ValueNodes) {
@@ -572,167 +572,167 @@ public:
}
}
- return result;
+ return result;
}
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- if (ValueNodes.size() > CodegenArraysFallbackLimit)
- return TBaseComputation::DoGenerateGetValue(ctx, block);
-
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto idxType = Type::getInt32Ty(context);
- const auto type = ArrayType::get(valType, ValueNodes.size());
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ if (ValueNodes.size() > CodegenArraysFallbackLimit)
+ return TBaseComputation::DoGenerateGetValue(ctx, block);
+
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto idxType = Type::getInt32Ty(context);
+ const auto type = ArrayType::get(valType, ValueNodes.size());
/// TODO: how to get computation context or other workaround
- const auto itms = *Stateless || ctx.AlwaysInline ?
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
- new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
- const auto result = Cache.GenNewArray(ValueNodes.size(), itms, ctx, block);
- const auto itemsPtr = new LoadInst(itms, "items", block);
-
- ui32 i = 0U;
- for (const auto node : ValueNodes) {
- const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i++)}, "item", block);
- GetNodeValue(itemPtr, node, ctx, block);
- }
- return result;
- }
-#endif
-private:
- void RegisterDependencies() const final {
- std::for_each(ValueNodes.cbegin(), ValueNodes.cend(), std::bind(&TArrayNode::DependsOn, this, std::placeholders::_1));
- }
-
- const TComputationNodePtrVector ValueNodes;
- const TContainerCacheOnContext Cache;
+ const auto itms = *Stateless || ctx.AlwaysInline ?
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", &ctx.Func->getEntryBlock().back()):
+ new AllocaInst(PointerType::getUnqual(type), 0U, "itms", block);
+ const auto result = Cache.GenNewArray(ValueNodes.size(), itms, ctx, block);
+ const auto itemsPtr = new LoadInst(itms, "items", block);
+
+ ui32 i = 0U;
+ for (const auto node : ValueNodes) {
+ const auto itemPtr = GetElementPtrInst::CreateInBounds(itemsPtr, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i++)}, "item", block);
+ GetNodeValue(itemPtr, node, ctx, block);
+ }
+ return result;
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ std::for_each(ValueNodes.cbegin(), ValueNodes.cend(), std::bind(&TArrayNode::DependsOn, this, std::placeholders::_1));
+ }
+
+ const TComputationNodePtrVector ValueNodes;
+ const TContainerCacheOnContext Cache;
};
-class TEmptyNode : public TMutableCodegeneratorNode<TEmptyNode> {
- typedef TMutableCodegeneratorNode<TEmptyNode> TBaseComputation;
+class TEmptyNode : public TMutableCodegeneratorNode<TEmptyNode> {
+ typedef TMutableCodegeneratorNode<TEmptyNode> TBaseComputation;
public:
TEmptyNode(TComputationMutables& mutables)
- : TBaseComputation(mutables, EValueRepresentation::Boxed)
+ : TBaseComputation(mutables, EValueRepresentation::Boxed)
{}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- return ctx.HolderFactory.GetEmptyContainer();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto factory = ctx.GetFactory();
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetEmptyContainer));
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {factory->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto res = CallInst::Create(funcPtr, {factory}, "res", block);
- return res;
- } else {
- const auto retPtr = new AllocaInst(valueType, 0U, "ret_ptr", block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {factory, retPtr}, "", block);
- const auto res = new LoadInst(retPtr, "res", block);
- return res;
- }
- }
-#endif
-private:
- void RegisterDependencies() const final {}
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ return ctx.HolderFactory.GetEmptyContainer();
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto factory = ctx.GetFactory();
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::GetEmptyContainer));
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {factory->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto res = CallInst::Create(funcPtr, {factory}, "res", block);
+ return res;
+ } else {
+ const auto retPtr = new AllocaInst(valueType, 0U, "ret_ptr", block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {factory->getType(), retPtr->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {factory, retPtr}, "", block);
+ const auto res = new LoadInst(retPtr, "res", block);
+ return res;
+ }
+ }
+#endif
+private:
+ void RegisterDependencies() const final {}
};
-class TEmptyContainerHolder: public TComputationValue<TEmptyContainerHolder> {
+class TEmptyContainerHolder: public TComputationValue<TEmptyContainerHolder> {
public:
- TEmptyContainerHolder(TMemoryUsageInfo* memInfo)
- : TComputationValue(memInfo), None()
- {}
-
-private:
- bool Contains(const NUdf::TUnboxedValuePod&) const override {
- return false;
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod&) const override {
- return None;
- }
-
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue&) override {
- return NUdf::EFetchStatus::Finish;
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
- }
-
- bool Skip() final {
- return false;
- }
-
- bool Next(NUdf::TUnboxedValue&) final {
- return false;
- }
-
- bool NextPair(NUdf::TUnboxedValue&, NUdf::TUnboxedValue&) final {
- return false;
- }
-
+ TEmptyContainerHolder(TMemoryUsageInfo* memInfo)
+ : TComputationValue(memInfo), None()
+ {}
+
+private:
+ bool Contains(const NUdf::TUnboxedValuePod&) const override {
+ return false;
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod&) const override {
+ return None;
+ }
+
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue&) override {
+ return NUdf::EFetchStatus::Finish;
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
+ }
+
+ bool Skip() final {
+ return false;
+ }
+
+ bool Next(NUdf::TUnboxedValue&) final {
+ return false;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue&, NUdf::TUnboxedValue&) final {
+ return false;
+ }
+
const NUdf::TOpaqueListRepresentation* GetListRepresentation() const override {
return reinterpret_cast<const NUdf::TOpaqueListRepresentation*>(&List);
}
- bool HasFastListLength() const override {
- return true;
- }
-
- ui64 GetListLength() const override {
+ bool HasFastListLength() const override {
+ return true;
+ }
+
+ ui64 GetListLength() const override {
return 0;
}
- ui64 GetEstimatedListLength() const override {
- return 0;
+ ui64 GetEstimatedListLength() const override {
+ return 0;
}
- bool HasListItems() const override {
- return false;
+ bool HasListItems() const override {
+ return false;
}
- NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
+ NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
Y_UNUSED(builder);
- return const_cast<TEmptyContainerHolder*>(this);
+ return const_cast<TEmptyContainerHolder*>(this);
}
- NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
+ NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
Y_UNUSED(builder);
Y_UNUSED(count);
- return const_cast<TEmptyContainerHolder*>(this);
+ return const_cast<TEmptyContainerHolder*>(this);
}
- NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
+ NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
Y_UNUSED(builder);
Y_UNUSED(count);
- return const_cast<TEmptyContainerHolder*>(this);
+ return const_cast<TEmptyContainerHolder*>(this);
}
- NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
- Y_UNUSED(builder);
- return const_cast<TEmptyContainerHolder*>(this);
+ NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
+ Y_UNUSED(builder);
+ return const_cast<TEmptyContainerHolder*>(this);
}
ui64 GetDictLength() const override {
@@ -747,268 +747,268 @@ private:
return true;
}
- const NUdf::TUnboxedValue* GetElements() const override {
- return &None;
- }
-
- const NUdf::TUnboxedValue None;
- const TDefaultListRepresentation List;
+ const NUdf::TUnboxedValue* GetElements() const override {
+ return &None;
+ }
+
+ const NUdf::TUnboxedValue None;
+ const TDefaultListRepresentation List;
+};
+
+class TSortedSetHolder: public TComputationValue<TSortedSetHolder> {
+public:
+ typedef TUnboxedValueVector TItems;
+
+ template <bool NoSwap>
+ class TIterator: public TComputationValue<TIterator<NoSwap>> {
+ public:
+ TIterator(const TSortedSetHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<TSortedSetHolder*>(parent))
+ , Iterator(Parent->Items.begin())
+ , AtStart(true)
+ {
+ }
+
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ } else {
+ if (Iterator == Parent->Items.end())
+ return false;
+
+ ++Iterator;
+ }
+
+ return Iterator != Parent->Items.end();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ if (NoSwap) {
+ key = *Iterator;
+ if (Parent->Packer) {
+ key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
+ }
+ } else {
+ key = NUdf::TUnboxedValuePod::Void();
+ }
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ if (NoSwap) {
+ payload = NUdf::TUnboxedValuePod::Void();
+ } else {
+ payload = *Iterator;
+ if (Parent->Packer) {
+ payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
+ }
+ }
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<TSortedSetHolder> Parent;
+ TItems::const_iterator Iterator;
+ bool AtStart;
+ };
+
+ TSortedSetHolder(
+ TMemoryUsageInfo* memInfo,
+ TSortedSetFiller filler,
+ const TKeyTypes& types,
+ bool isTuple,
+ EDictSortMode mode,
+ bool eagerFill,
+ TType* encodedType,
+ const THolderFactory& holderFactory)
+ : TComputationValue(memInfo)
+ , Filler(filler)
+ , Types(types)
+ , IsTuple(isTuple)
+ , Mode(mode)
+ , IsBuilt(false)
+ , HolderFactory(holderFactory)
+ {
+ if (encodedType) {
+ Packer.emplace(encodedType);
+ }
+
+ if (eagerFill)
+ LazyBuildDict();
+ }
+
+ ~TSortedSetHolder() {
+ MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
+ }
+
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
+ NUdf::TUnboxedValue encodedKey;
+ if (Packer) {
+ encodedKey = MakeString(Packer->Encode(key, false));
+ }
+
+ return BinarySearch(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key),
+ TValueLess(Types, IsTuple));
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
+ NUdf::TUnboxedValue encodedKey;
+ if (Packer) {
+ encodedKey = MakeString(Packer->Encode(key, false));
+ }
+
+ const auto it = LowerBound(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key), TValueLess(Types, IsTuple));
+ if (it == Items.end() || !TValueEqual(Types, IsTuple)(*it, NUdf::TUnboxedValuePod(Packer ? encodedKey : key)))
+ return NUdf::TUnboxedValuePod();
+
+ return it->MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ LazyBuildDict();
+ return Items.size();
+ }
+
+ bool HasDictItems() const override {
+ LazyBuildDict();
+ return !Items.empty();
+ }
+
+ void LazyBuildDict() const {
+ if (IsBuilt)
+ return;
+
+ Filler(Items);
+ Filler = TSortedSetFiller();
+
+ switch (Mode) {
+ case EDictSortMode::RequiresSorting:
+ StableSort(Items.begin(), Items.end(), TValueLess(Types, IsTuple));
+ Items.erase(Unique(Items.begin(), Items.end(), TValueEqual(Types, IsTuple)), Items.end());
+ break;
+ case EDictSortMode::SortedUniqueAscending:
+ break;
+ case EDictSortMode::SortedUniqueDescening:
+ Reverse(Items.begin(), Items.end());
+ break;
+ default:
+ Y_FAIL();
+ }
+
+ Y_VERIFY_DEBUG(IsSortedUnique());
+ IsBuilt = true;
+
+ if (!Items.empty()) {
+ MKQL_MEM_TAKE(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
+ }
+ }
+
+ bool IsSortedUnique() const {
+ TValueLess less(Types, IsTuple);
+ for (size_t i = 1, e = Items.size(); i < e; ++i) {
+ if (!less(Items[i - 1], Items[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ bool IsSortedDict() const override {
+ return true;
+ }
+
+private:
+ mutable TSortedSetFiller Filler;
+ const TKeyTypes Types;
+ const bool IsTuple;
+ const EDictSortMode Mode;
+ mutable bool IsBuilt;
+ const THolderFactory& HolderFactory;
+ mutable TItems Items;
+ mutable std::optional<TGenericPresortEncoder> Packer;
};
-class TSortedSetHolder: public TComputationValue<TSortedSetHolder> {
-public:
- typedef TUnboxedValueVector TItems;
-
- template <bool NoSwap>
- class TIterator: public TComputationValue<TIterator<NoSwap>> {
- public:
- TIterator(const TSortedSetHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<TSortedSetHolder*>(parent))
- , Iterator(Parent->Items.begin())
- , AtStart(true)
- {
- }
-
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- } else {
- if (Iterator == Parent->Items.end())
- return false;
-
- ++Iterator;
- }
-
- return Iterator != Parent->Items.end();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- if (NoSwap) {
- key = *Iterator;
- if (Parent->Packer) {
- key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
- }
- } else {
- key = NUdf::TUnboxedValuePod::Void();
- }
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- if (NoSwap) {
- payload = NUdf::TUnboxedValuePod::Void();
- } else {
- payload = *Iterator;
- if (Parent->Packer) {
- payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
- }
- }
- return true;
- }
-
- const NUdf::TRefCountedPtr<TSortedSetHolder> Parent;
- TItems::const_iterator Iterator;
- bool AtStart;
- };
-
- TSortedSetHolder(
- TMemoryUsageInfo* memInfo,
- TSortedSetFiller filler,
- const TKeyTypes& types,
- bool isTuple,
- EDictSortMode mode,
- bool eagerFill,
- TType* encodedType,
- const THolderFactory& holderFactory)
- : TComputationValue(memInfo)
- , Filler(filler)
- , Types(types)
- , IsTuple(isTuple)
- , Mode(mode)
- , IsBuilt(false)
- , HolderFactory(holderFactory)
- {
- if (encodedType) {
- Packer.emplace(encodedType);
- }
-
- if (eagerFill)
- LazyBuildDict();
- }
-
- ~TSortedSetHolder() {
- MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
- }
-
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
- NUdf::TUnboxedValue encodedKey;
- if (Packer) {
- encodedKey = MakeString(Packer->Encode(key, false));
- }
-
- return BinarySearch(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key),
- TValueLess(Types, IsTuple));
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
- NUdf::TUnboxedValue encodedKey;
- if (Packer) {
- encodedKey = MakeString(Packer->Encode(key, false));
- }
-
- const auto it = LowerBound(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key), TValueLess(Types, IsTuple));
- if (it == Items.end() || !TValueEqual(Types, IsTuple)(*it, NUdf::TUnboxedValuePod(Packer ? encodedKey : key)))
- return NUdf::TUnboxedValuePod();
-
- return it->MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- LazyBuildDict();
- return Items.size();
- }
-
- bool HasDictItems() const override {
- LazyBuildDict();
- return !Items.empty();
- }
-
- void LazyBuildDict() const {
- if (IsBuilt)
- return;
-
- Filler(Items);
- Filler = TSortedSetFiller();
-
- switch (Mode) {
- case EDictSortMode::RequiresSorting:
- StableSort(Items.begin(), Items.end(), TValueLess(Types, IsTuple));
- Items.erase(Unique(Items.begin(), Items.end(), TValueEqual(Types, IsTuple)), Items.end());
- break;
- case EDictSortMode::SortedUniqueAscending:
- break;
- case EDictSortMode::SortedUniqueDescening:
- Reverse(Items.begin(), Items.end());
- break;
- default:
- Y_FAIL();
- }
-
- Y_VERIFY_DEBUG(IsSortedUnique());
- IsBuilt = true;
-
- if (!Items.empty()) {
- MKQL_MEM_TAKE(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
- }
- }
-
- bool IsSortedUnique() const {
- TValueLess less(Types, IsTuple);
- for (size_t i = 1, e = Items.size(); i < e; ++i) {
- if (!less(Items[i - 1], Items[i]))
- return false;
- }
-
- return true;
- }
-
- bool IsSortedDict() const override {
- return true;
- }
-
-private:
- mutable TSortedSetFiller Filler;
- const TKeyTypes Types;
- const bool IsTuple;
- const EDictSortMode Mode;
- mutable bool IsBuilt;
- const THolderFactory& HolderFactory;
- mutable TItems Items;
- mutable std::optional<TGenericPresortEncoder> Packer;
-};
-
class TSortedDictHolder: public TComputationValue<TSortedDictHolder> {
public:
typedef TKeyPayloadPairVector TItems;
- template <bool NoSwap>
- class TIterator: public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator: public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const TSortedDictHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<TSortedDictHolder*>(parent))
- , Iterator(Parent->Items.begin())
+ TIterator(const TSortedDictHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<TSortedDictHolder*>(parent))
+ , Iterator(Parent->Items.begin())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- } else {
- if (Iterator == Parent->Items.end())
- return false;
-
- ++Iterator;
- }
-
- return Iterator != Parent->Items.end();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- if (NoSwap) {
- key = Iterator->first;
- if (Parent->Packer) {
- key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
- }
- } else {
- key = Iterator->second;
- }
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- if (NoSwap) {
- payload = Iterator->second;
- } else {
- payload = Iterator->first;
- if (Parent->Packer) {
- payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
- }
- }
- return true;
- }
-
- const NUdf::TRefCountedPtr<TSortedDictHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ } else {
+ if (Iterator == Parent->Items.end())
+ return false;
+
+ ++Iterator;
+ }
+
+ return Iterator != Parent->Items.end();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ if (NoSwap) {
+ key = Iterator->first;
+ if (Parent->Packer) {
+ key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
+ }
+ } else {
+ key = Iterator->second;
+ }
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ if (NoSwap) {
+ payload = Iterator->second;
+ } else {
+ payload = Iterator->first;
+ if (Parent->Packer) {
+ payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
+ }
+ }
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<TSortedDictHolder> Parent;
TItems::const_iterator Iterator;
bool AtStart;
};
@@ -1031,7 +1031,7 @@ public:
, HolderFactory(holderFactory)
{
if (encodedType) {
- Packer.emplace(encodedType);
+ Packer.emplace(encodedType);
}
if (eagerFill)
@@ -1039,11 +1039,11 @@ public:
}
~TSortedDictHolder() {
- MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
- }
+ MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
+ }
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
@@ -1054,7 +1054,7 @@ private:
TKeyPayloadPairLess(Types, IsTuple));
}
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
@@ -1063,31 +1063,31 @@ private:
const auto it = LowerBound(Items.begin(), Items.end(), TItems::value_type(NUdf::TUnboxedValuePod(Packer ? encodedKey : key), NUdf::TUnboxedValue()), TKeyPayloadPairLess(Types, IsTuple));
if (it == Items.end() || !TKeyPayloadPairEqual(Types, IsTuple)({it->first, it->second}, TKeyPayloadPair(NUdf::TUnboxedValuePod(Packer ? encodedKey : key), {})))
- return NUdf::TUnboxedValuePod();
-
- return it->second.MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- LazyBuildDict();
- return Items.size();
- }
-
+ return NUdf::TUnboxedValuePod();
+
+ return it->second.MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ LazyBuildDict();
+ return Items.size();
+ }
+
bool HasDictItems() const override {
LazyBuildDict();
return !Items.empty();
@@ -1099,7 +1099,7 @@ private:
Filler(Items);
Filler = TSortedDictFiller();
-
+
switch (Mode) {
case EDictSortMode::RequiresSorting:
StableSort(Items.begin(), Items.end(), TKeyPayloadPairLess(Types, IsTuple));
@@ -1144,58 +1144,58 @@ private:
mutable bool IsBuilt;
const THolderFactory& HolderFactory;
mutable TItems Items;
- mutable std::optional<TGenericPresortEncoder> Packer;
+ mutable std::optional<TGenericPresortEncoder> Packer;
};
class THashedSetHolder : public TComputationValue<THashedSetHolder> {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedSetHolder* parent)
- : TComputationValue(parent->GetMemInfo())
- , Parent(const_cast<THashedSetHolder*>(parent))
- , Iterator(Parent->Set.begin())
- , End(Parent->Set.end())
+ TIterator(const THashedSetHolder* parent)
+ : TComputationValue(parent->GetMemInfo())
+ , Parent(const_cast<THashedSetHolder*>(parent))
+ , Iterator(Parent->Set.begin())
+ , End(Parent->Set.end())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (Iterator == End) {
- return false;
- }
-
- ++Iterator;
- }
-
- return Iterator != End;
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = *Iterator;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (Iterator == End) {
+ return false;
+ }
+
+ ++Iterator;
+ }
+
+ return Iterator != End;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = *Iterator;
if (Parent->Packer) {
key = Parent->Packer->Unpack(key.AsStringRef(), Parent->HolderFactory);
}
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NUdf::TUnboxedValuePod::Void();
- return true;
- }
-
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NUdf::TUnboxedValuePod::Void();
+ return true;
+ }
+
private:
- const NUdf::TRefCountedPtr<THashedSetHolder> Parent;
+ const NUdf::TRefCountedPtr<THashedSetHolder> Parent;
TValuesDictHashSet::const_iterator Iterator;
TValuesDictHashSet::const_iterator End;
bool AtStart;
@@ -1211,62 +1211,62 @@ public:
, HolderFactory(holderFactory)
{
if (encodedType) {
- Packer.emplace(true, encodedType);
+ Packer.emplace(true, encodedType);
}
if (eagerFill)
LazyBuildDict();
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
encodedKey = MakeString(Packer->Pack(key));
}
return Set.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key)) != Set.cend();
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
encodedKey = MakeString(Packer->Pack(key));
}
const auto it = Set.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key));
- if (it == Set.cend())
- return NUdf::TUnboxedValuePod();
- return NUdf::TUnboxedValuePod::Void();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- ui64 GetDictLength() const override {
- LazyBuildDict();
- return Set.size();
- }
-
+ if (it == Set.cend())
+ return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod::Void();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ ui64 GetDictLength() const override {
+ LazyBuildDict();
+ return Set.size();
+ }
+
bool HasDictItems() const override {
LazyBuildDict();
return !Set.empty();
@@ -1293,7 +1293,7 @@ private:
mutable TValuesDictHashSet Set;
mutable bool IsBuilt;
const THolderFactory& HolderFactory;
- mutable std::optional<TValuePacker> Packer;
+ mutable std::optional<TValuePacker> Packer;
};
template <typename T>
@@ -1301,90 +1301,90 @@ class THashedSingleFixedSetHolder : public TComputationValue<THashedSingleFixedS
public:
using TSetType = TValuesDictHashSingleFixedSet<T>;
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedSingleFixedSetHolder* parent)
- : TComputationValue<TIterator>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedSetHolder*>(parent))
- , Iterator(Parent->Set.begin())
- , End(Parent->Set.end())
+ TIterator(const THashedSingleFixedSetHolder* parent)
+ : TComputationValue<TIterator>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedSetHolder*>(parent))
+ , Iterator(Parent->Set.begin())
+ , End(Parent->Set.end())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (Iterator == End)
- return false;
- ++Iterator;
- }
-
- return Iterator != End;
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = NUdf::TUnboxedValuePod(*Iterator);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NUdf::TUnboxedValuePod::Void();
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedSetHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (Iterator == End)
+ return false;
+ ++Iterator;
+ }
+
+ return Iterator != End;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = NUdf::TUnboxedValuePod(*Iterator);
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NUdf::TUnboxedValuePod::Void();
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedSetHolder> Parent;
typename TSetType::const_iterator Iterator;
typename TSetType::const_iterator End;
bool AtStart;
};
THashedSingleFixedSetHolder(TMemoryUsageInfo* memInfo, TSetType&& set)
- : TComputationValue<THashedSingleFixedSetHolder>(memInfo)
+ : TComputationValue<THashedSingleFixedSetHolder>(memInfo)
, Set(std::move(set))
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- return Set.find(key.Get<T>()) != Set.cend();
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- const auto it = Set.find(key.Get<T>());
- if (it == Set.cend()) {
- return NUdf::TUnboxedValuePod();
- }
- return NUdf::TUnboxedValuePod::Void();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- ui64 GetDictLength() const override {
- return Set.size();
- }
-
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ return Set.find(key.Get<T>()) != Set.cend();
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ const auto it = Set.find(key.Get<T>());
+ if (it == Set.cend()) {
+ return NUdf::TUnboxedValuePod();
+ }
+ return NUdf::TUnboxedValuePod::Void();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ ui64 GetDictLength() const override {
+ return Set.size();
+ }
+
bool HasDictItems() const override {
return !Set.empty();
}
@@ -1393,7 +1393,7 @@ private:
return false;
}
- const TSetType Set;
+ const TSetType Set;
};
template <typename T>
@@ -1401,82 +1401,82 @@ class THashedSingleFixedCompactSetHolder : public TComputationValue<THashedSingl
public:
using TSetType = TValuesDictHashSingleFixedCompactSet<T>;
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedSingleFixedCompactSetHolder* parent)
- : TComputationValue<TIterator>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedCompactSetHolder*>(parent))
- , Iterator(Parent->Set.Iterate())
+ TIterator(const THashedSingleFixedCompactSetHolder* parent)
+ : TComputationValue<TIterator>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedCompactSetHolder*>(parent))
+ , Iterator(Parent->Set.Iterate())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (!Iterator.Ok())
- return false;
- ++Iterator;
- }
-
- return Iterator.Ok();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = NUdf::TUnboxedValuePod(*Iterator);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NUdf::TUnboxedValuePod::Void();
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedCompactSetHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (!Iterator.Ok())
+ return false;
+ ++Iterator;
+ }
+
+ return Iterator.Ok();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = NUdf::TUnboxedValuePod(*Iterator);
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NUdf::TUnboxedValuePod::Void();
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedCompactSetHolder> Parent;
typename TSetType::TIterator Iterator;
bool AtStart;
};
THashedSingleFixedCompactSetHolder(TMemoryUsageInfo* memInfo, TSetType&& set)
- : TComputationValue<THashedSingleFixedCompactSetHolder>(memInfo)
+ : TComputationValue<THashedSingleFixedCompactSetHolder>(memInfo)
, Set(std::move(set))
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- return Set.Has(key.Get<T>());
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- if (Set.Has(key.Get<T>()))
- return NUdf::TUnboxedValuePod::Void();
- return NUdf::TUnboxedValuePod();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ return Set.Has(key.Get<T>());
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ if (Set.Has(key.Get<T>()))
+ return NUdf::TUnboxedValuePod::Void();
+ return NUdf::TUnboxedValuePod();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
ui64 GetDictLength() const override {
return Set.Size();
}
@@ -1489,52 +1489,52 @@ private:
return false;
}
- const TSetType Set;
+ const TSetType Set;
};
class THashedCompactSetHolder : public TComputationValue<THashedCompactSetHolder> {
public:
using TSetType = TValuesDictHashCompactSet;
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedCompactSetHolder* parent)
- : TComputationValue(parent->GetMemInfo())
- , Parent(const_cast<THashedCompactSetHolder*>(parent))
- , Iterator(Parent->Set.Iterate())
+ TIterator(const THashedCompactSetHolder* parent)
+ : TComputationValue(parent->GetMemInfo())
+ , Parent(const_cast<THashedCompactSetHolder*>(parent))
+ , Iterator(Parent->Set.Iterate())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (!Iterator.Ok())
- return false;
- ++Iterator;
- }
-
- return Iterator.Ok();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = Parent->KeyPacker.Unpack(GetSmallValue(*Iterator), Parent->Ctx->HolderFactory);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NUdf::TUnboxedValuePod::Void();
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedCompactSetHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (!Iterator.Ok())
+ return false;
+ ++Iterator;
+ }
+
+ return Iterator.Ok();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = Parent->KeyPacker.Unpack(GetSmallValue(*Iterator), Parent->Ctx->HolderFactory);
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NUdf::TUnboxedValuePod::Void();
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedCompactSetHolder> Parent;
typename TSetType::TIterator Iterator;
bool AtStart;
};
@@ -1548,40 +1548,40 @@ public:
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- return Set.Has(smallValue);
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- if (Set.Has(smallValue))
- return NUdf::TUnboxedValuePod::Void();
- return NUdf::TUnboxedValuePod();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(this));
- }
-
- ui64 GetDictLength() const override {
- return Set.Size();
- }
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ return Set.Has(smallValue);
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ if (Set.Has(smallValue))
+ return NUdf::TUnboxedValuePod::Void();
+ return NUdf::TUnboxedValuePod();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(this));
+ }
+
+ ui64 GetDictLength() const override {
+ return Set.Size();
+ }
bool HasDictItems() const override {
return !Set.Empty();
@@ -1593,7 +1593,7 @@ private:
private:
TPagedArena Pool;
- const TSetType Set;
+ const TSetType Set;
mutable TValuePacker KeyPacker;
TComputationContext* Ctx;
};
@@ -1602,50 +1602,50 @@ class THashedCompactMapHolder : public TComputationValue<THashedCompactMapHolder
public:
using TMapType = TValuesDictHashCompactMap;
- template <bool NoSwap>
- class TIterator : public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator : public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedCompactMapHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedCompactMapHolder*>(parent))
- , Iterator(Parent->Map.Iterate())
+ TIterator(const THashedCompactMapHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedCompactMapHolder*>(parent))
+ , Iterator(Parent->Map.Iterate())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (!Iterator.Ok())
- return false;
- ++Iterator;
- }
-
- return Iterator.Ok();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = NoSwap ?
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (!Iterator.Ok())
+ return false;
+ ++Iterator;
+ }
+
+ return Iterator.Ok();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = NoSwap ?
Parent->KeyPacker.Unpack(GetSmallValue(Iterator.Get().first), Parent->Ctx->HolderFactory):
Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NoSwap ?
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NoSwap ?
Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory):
Parent->KeyPacker.Unpack(GetSmallValue(Iterator.Get().first), Parent->Ctx->HolderFactory);
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedCompactMapHolder> Parent;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedCompactMapHolder> Parent;
typename TMapType::TIterator Iterator;
bool AtStart;
};
@@ -1661,37 +1661,37 @@ public:
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- return Map.Has(smallValue);
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- auto it = Map.Find(smallValue);
- if (!it.Ok())
- return NUdf::TUnboxedValuePod();
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ return Map.Has(smallValue);
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ auto it = Map.Find(smallValue);
+ if (!it.Ok())
+ return NUdf::TUnboxedValuePod();
return PayloadPacker.Unpack(GetSmallValue(it.Get().second), Ctx->HolderFactory).Release().MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- return Map.Size();
- }
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ return Map.Size();
+ }
bool HasDictItems() const override {
return !Map.Empty();
@@ -1702,7 +1702,7 @@ private:
}
TPagedArena Pool;
- const TMapType Map;
+ const TMapType Map;
mutable TValuePacker KeyPacker;
mutable TValuePacker PayloadPacker;
TComputationContext* Ctx;
@@ -1715,121 +1715,121 @@ public:
class TPayloadList: public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedCompactMultiMapHolder* parent, TMapIterator from)
- : TComputationValue(parent->GetMemInfo())
- , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
+ TIterator(const THashedCompactMultiMapHolder* parent, TMapIterator from)
+ : TComputationValue(parent->GetMemInfo())
+ , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
, Iterator(from)
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
value = Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.GetValue()), Parent->CompCtx.HolderFactory);
- ++Iterator;
- return true;
- }
-
- bool Skip() override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- ++Iterator;
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
+ ++Iterator;
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ ++Iterator;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
TMapIterator Iterator;
};
TPayloadList(TMemoryUsageInfo* memInfo, const THashedCompactMultiMapHolder* parent, TMapIterator from)
: TCustomListValue(memInfo)
- , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
+ , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
, From(from)
{
Y_ASSERT(From.Ok());
}
- private:
+ private:
bool HasFastListLength() const override {
return true;
}
ui64 GetListLength() const override {
if (!Length) {
- Length = Parent->Map.Count(From.GetKey());
+ Length = Parent->Map.Count(From.GetKey());
}
- return *Length;
+ return *Length;
}
bool HasListItems() const override {
return true;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
- }
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
+ }
- const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
+ const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
TMapIterator From;
};
- template <bool NoSwap>
- class TIterator : public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator : public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedCompactMultiMapHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
+ TIterator(const THashedCompactMultiMapHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
, Iterator(parent->Map.Iterate())
{
}
- private:
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- if (NoSwap) {
- key = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
- payload = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
- } else {
- payload = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
- key = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
- }
+ private:
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ if (NoSwap) {
+ key = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
+ payload = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
+ } else {
+ payload = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
+ key = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
+ }
Iterator.NextKey();
- return true;
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- key = NoSwap ?
- Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory):
- NUdf::TUnboxedValue(Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter()));
+ return true;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ key = NoSwap ?
+ Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory):
+ NUdf::TUnboxedValue(Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter()));
Iterator.NextKey();
- return true;
- }
-
- bool Skip() override {
- if (!Iterator.Ok()) {
- return false;
- }
-
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
Iterator.NextKey();
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
TMapIterator Iterator;
};
@@ -1844,39 +1844,39 @@ public:
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- return Map.Has(smallValue);
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
- ui64 smallValue = AsSmallValue(serializedKey);
- auto it = Map.Find(smallValue);
- if (!it.Ok())
- return NUdf::TUnboxedValuePod();
-
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ return Map.Has(smallValue);
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
+ ui64 smallValue = AsSmallValue(serializedKey);
+ auto it = Map.Find(smallValue);
+ if (!it.Ok())
+ return NUdf::TUnboxedValuePod();
+
return CompCtx.HolderFactory.Create<TPayloadList>(this, it);
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
return Map.UniqSize();
- }
-
+ }
+
bool HasDictItems() const override {
return !Map.Empty();
}
@@ -1886,7 +1886,7 @@ private:
}
TPagedArena Pool;
- const TMapType Map;
+ const TMapType Map;
mutable TValuePacker KeyPacker;
mutable TValuePacker PayloadPacker;
TComputationContext& CompCtx;
@@ -1894,61 +1894,61 @@ private:
class THashedDictHolder: public TComputationValue<THashedDictHolder> {
public:
- template <bool NoSwap>
- class TIterator: public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator: public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedDictHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedDictHolder*>(parent))
- , Iterator(Parent->Map.begin())
- , End(Parent->Map.end())
+ TIterator(const THashedDictHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedDictHolder*>(parent))
+ , Iterator(Parent->Map.begin())
+ , End(Parent->Map.end())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- } else {
- if (Iterator == End)
- return false;
- ++Iterator;
- }
-
- return Iterator != End;
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- if (NoSwap) {
- key = Iterator->first;
- if (Parent->Packer) {
- key = Parent->Packer->Unpack(key.AsStringRef(), Parent->HolderFactory);
- }
- } else {
- key = Iterator->second;
- }
-
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- if (NoSwap) {
- payload = Iterator->second;
- } else {
- payload = Iterator->first;
- if (Parent->Packer) {
- payload = Parent->Packer->Unpack(payload.AsStringRef(), Parent->HolderFactory);
- }
- }
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedDictHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ } else {
+ if (Iterator == End)
+ return false;
+ ++Iterator;
+ }
+
+ return Iterator != End;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ if (NoSwap) {
+ key = Iterator->first;
+ if (Parent->Packer) {
+ key = Parent->Packer->Unpack(key.AsStringRef(), Parent->HolderFactory);
+ }
+ } else {
+ key = Iterator->second;
+ }
+
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ if (NoSwap) {
+ payload = Iterator->second;
+ } else {
+ payload = Iterator->first;
+ if (Parent->Packer) {
+ payload = Parent->Packer->Unpack(payload.AsStringRef(), Parent->HolderFactory);
+ }
+ }
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedDictHolder> Parent;
TValuesDictHashMap::const_iterator Iterator;
TValuesDictHashMap::const_iterator End;
bool AtStart;
@@ -1964,57 +1964,57 @@ public:
, HolderFactory(holderFactory)
{
if (encodedType) {
- Packer.emplace(true, encodedType);
+ Packer.emplace(true, encodedType);
}
if (eagerFill)
LazyBuildDict();
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
encodedKey = MakeString(Packer->Pack(key));
}
return Map.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key)) != Map.cend();
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- LazyBuildDict();
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ LazyBuildDict();
NUdf::TUnboxedValue encodedKey;
if (Packer) {
encodedKey = MakeString(Packer->Pack(key));
}
const auto it = Map.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key));
- if (it == Map.cend())
- return NUdf::TUnboxedValuePod();
- return it->second.MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- LazyBuildDict();
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- LazyBuildDict();
- return Map.size();
- }
-
+ if (it == Map.cend())
+ return NUdf::TUnboxedValuePod();
+ return it->second.MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ LazyBuildDict();
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ LazyBuildDict();
+ return Map.size();
+ }
+
bool HasDictItems() const override {
LazyBuildDict();
return !Map.empty();
@@ -2040,7 +2040,7 @@ private:
mutable TValuesDictHashMap Map;
mutable bool IsBuilt;
const THolderFactory& HolderFactory;
- std::optional<TValuePacker> Packer;
+ std::optional<TValuePacker> Packer;
};
template <typename T>
@@ -2048,87 +2048,87 @@ class THashedSingleFixedMapHolder : public TComputationValue<THashedSingleFixedM
public:
using TMapType = TValuesDictHashSingleFixedMap<T>;
- template <bool NoSwap>
- class TIterator : public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator : public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedSingleFixedMapHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedMapHolder*>(parent))
- , Iterator(Parent->Map.begin())
- , End(Parent->Map.end())
+ TIterator(const THashedSingleFixedMapHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedMapHolder*>(parent))
+ , Iterator(Parent->Map.begin())
+ , End(Parent->Map.end())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else {
- if (Iterator == End) {
- return false;
- }
- ++Iterator;
- }
-
- return Iterator != End;
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = NoSwap ? NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first)) : Iterator->second;
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NoSwap ? Iterator->second : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first));
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedMapHolder> Parent;
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else {
+ if (Iterator == End) {
+ return false;
+ }
+ ++Iterator;
+ }
+
+ return Iterator != End;
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = NoSwap ? NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first)) : Iterator->second;
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NoSwap ? Iterator->second : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first));
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedMapHolder> Parent;
typename TMapType::const_iterator Iterator;
typename TMapType::const_iterator End;
bool AtStart;
};
- THashedSingleFixedMapHolder(TMemoryUsageInfo* memInfo, TValuesDictHashSingleFixedMap<T>&& map)
- : TComputationValue<THashedSingleFixedMapHolder>(memInfo)
+ THashedSingleFixedMapHolder(TMemoryUsageInfo* memInfo, TValuesDictHashSingleFixedMap<T>&& map)
+ : TComputationValue<THashedSingleFixedMapHolder>(memInfo)
, Map(std::move(map))
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- return Map.find(key.Get<T>()) != Map.end();
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- const auto it = Map.find(key.Get<T>());
- if (it == Map.end())
- return NUdf::TUnboxedValuePod();
- return it->second.MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- return Map.size();
- }
-
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ return Map.find(key.Get<T>()) != Map.end();
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ const auto it = Map.find(key.Get<T>());
+ if (it == Map.end())
+ return NUdf::TUnboxedValuePod();
+ return it->second.MakeOptional();
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ return Map.size();
+ }
+
bool HasDictItems() const override {
return !Map.empty();
}
@@ -2137,63 +2137,63 @@ private:
return false;
}
- const TMapType Map;
+ const TMapType Map;
};
template <typename T>
class THashedSingleFixedCompactMapHolder : public TComputationValue<THashedSingleFixedCompactMapHolder<T>> {
public:
using TMapType = TValuesDictHashSingleFixedCompactMap<T>;
-
- template <bool NoSwap>
- class TIterator : public TComputationValue<TIterator<NoSwap>> {
+
+ template <bool NoSwap>
+ class TIterator : public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedSingleFixedCompactMapHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedCompactMapHolder*>(parent))
- , Iterator(Parent->Map.Iterate())
+ TIterator(const THashedSingleFixedCompactMapHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedCompactMapHolder*>(parent))
+ , Iterator(Parent->Map.Iterate())
, AtStart(true)
{
}
- private:
- bool Skip() override {
- if (AtStart) {
- AtStart = false;
- }
- else if (Iterator.Ok()) {
- ++Iterator;
- }
-
- return Iterator.Ok();
- }
-
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Skip())
- return false;
- key = NoSwap ?
+ private:
+ bool Skip() override {
+ if (AtStart) {
+ AtStart = false;
+ }
+ else if (Iterator.Ok()) {
+ ++Iterator;
+ }
+
+ return Iterator.Ok();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Skip())
+ return false;
+ key = NoSwap ?
NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator.Get().first)):
Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Next(key))
- return false;
- payload = NoSwap ?
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Next(key))
+ return false;
+ payload = NoSwap ?
Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory):
NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator.Get().first));
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedCompactMapHolder> Parent;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedCompactMapHolder> Parent;
typename TMapType::TIterator Iterator;
bool AtStart;
};
THashedSingleFixedCompactMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, TPagedArena&& pool,
TType* payloadType, TComputationContext* ctx)
- : TComputationValue<THashedSingleFixedCompactMapHolder>(memInfo)
+ : TComputationValue<THashedSingleFixedCompactMapHolder>(memInfo)
, Pool(std::move(pool))
, Map(std::move(map))
, PayloadPacker(false, payloadType)
@@ -2201,34 +2201,34 @@ public:
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- return Map.Has(key.Get<T>());
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- auto it = Map.Find(key.Get<T>());
- if (!it.Ok())
- return NUdf::TUnboxedValuePod();
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ return Map.Has(key.Get<T>());
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ auto it = Map.Find(key.Get<T>());
+ if (!it.Ok())
+ return NUdf::TUnboxedValuePod();
return PayloadPacker.Unpack(GetSmallValue(it.Get().second), Ctx->HolderFactory).Release().MakeOptional();
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
- return Map.Size();
- }
-
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
+ return Map.Size();
+ }
+
bool HasDictItems() const override {
return !Map.Empty();
}
@@ -2239,7 +2239,7 @@ private:
private:
TPagedArena Pool;
- const TMapType Map;
+ const TMapType Map;
mutable TValuePacker PayloadPacker;
TComputationContext* Ctx;
};
@@ -2252,42 +2252,42 @@ public:
class TPayloadList: public TCustomListValue {
public:
- class TIterator : public TComputationValue<TIterator> {
+ class TIterator : public TComputationValue<TIterator> {
public:
- TIterator(const THashedSingleFixedCompactMultiMapHolder* parent, TMapIterator from)
- : TComputationValue<TIterator>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
+ TIterator(const THashedSingleFixedCompactMultiMapHolder* parent, TMapIterator from)
+ : TComputationValue<TIterator>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
, Iterator(from)
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- value = Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.GetValue()), Parent->Ctx->HolderFactory);
- ++Iterator;
- return true;
- }
-
- bool Skip() override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- ++Iterator;
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ value = Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.GetValue()), Parent->Ctx->HolderFactory);
+ ++Iterator;
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ ++Iterator;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
TMapIterator Iterator;
};
TPayloadList(TMemoryUsageInfo* memInfo, const THashedSingleFixedCompactMultiMapHolder* parent, TMapIterator from)
: TCustomListValue(memInfo)
- , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
+ , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
, From(from)
{
Y_ASSERT(From.Ok());
@@ -2299,79 +2299,79 @@ public:
ui64 GetListLength() const override {
if (!Length) {
- Length = Parent->Map.Count(From.GetKey());
+ Length = Parent->Map.Count(From.GetKey());
}
- return *Length;
+ return *Length;
}
bool HasListItems() const override {
return true;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
TMapIterator From;
};
- template <bool NoSwap>
- class TIterator : public TComputationValue<TIterator<NoSwap>> {
+ template <bool NoSwap>
+ class TIterator : public TComputationValue<TIterator<NoSwap>> {
public:
- TIterator(const THashedSingleFixedCompactMultiMapHolder* parent)
- : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
- , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
+ TIterator(const THashedSingleFixedCompactMultiMapHolder* parent)
+ : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
+ , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
, Iterator(parent->Map.Iterate())
{
}
- private:
- bool Next(NUdf::TUnboxedValue& key) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- key = NoSwap ?
- NUdf::TUnboxedValuePod(Iterator.GetKey()):
- Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
+ private:
+ bool Next(NUdf::TUnboxedValue& key) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ key = NoSwap ?
+ NUdf::TUnboxedValuePod(Iterator.GetKey()):
+ Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
Iterator.NextKey();
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
- if (!Iterator.Ok()) {
- return false;
- }
-
- if (NoSwap) {
- key = NUdf::TUnboxedValuePod(Iterator.GetKey());
- payload = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
- } else {
- payload = NUdf::TUnboxedValuePod(Iterator.GetKey());
- key = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
- }
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
+ if (NoSwap) {
+ key = NUdf::TUnboxedValuePod(Iterator.GetKey());
+ payload = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
+ } else {
+ payload = NUdf::TUnboxedValuePod(Iterator.GetKey());
+ key = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
+ }
Iterator.NextKey();
- return true;
- }
-
- bool Skip() override {
- if (!Iterator.Ok()) {
- return false;
- }
-
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Iterator.Ok()) {
+ return false;
+ }
+
Iterator.NextKey();
- return true;
- }
-
- const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
+ return true;
+ }
+
+ const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
TMapIterator Iterator;
};
THashedSingleFixedCompactMultiMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, TPagedArena&& pool,
TType* payloadType, TComputationContext* ctx)
- : TComputationValue<THashedSingleFixedCompactMultiMapHolder>(memInfo)
+ : TComputationValue<THashedSingleFixedCompactMultiMapHolder>(memInfo)
, Pool(std::move(pool))
, Map(std::move(map))
, PayloadPacker(false, payloadType)
@@ -2379,34 +2379,34 @@ public:
{
}
-private:
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- return Map.Has(key.Get<T>());
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- const auto it = Map.Find(key.Get<T>());
- if (!it.Ok())
- return NUdf::TUnboxedValuePod();
- return Ctx->HolderFactory.Create<TPayloadList>(this, it);
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<true>(this));
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator<false>(this));
- }
-
- ui64 GetDictLength() const override {
+private:
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ return Map.Has(key.Get<T>());
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ const auto it = Map.Find(key.Get<T>());
+ if (!it.Ok())
+ return NUdf::TUnboxedValuePod();
+ return Ctx->HolderFactory.Create<TPayloadList>(this, it);
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<true>(this));
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator<false>(this));
+ }
+
+ ui64 GetDictLength() const override {
return Map.UniqSize();
- }
-
+ }
+
bool HasDictItems() const override {
return !Map.Empty();
}
@@ -2417,7 +2417,7 @@ private:
private:
TPagedArena Pool;
- const TMapType Map;
+ const TMapType Map;
mutable TValuePacker PayloadPacker;
TComputationContext* Ctx;
};
@@ -2426,25 +2426,25 @@ class TDictNode: public TMutableComputationNode<TDictNode> {
typedef TMutableComputationNode<TDictNode> TBaseComputation;
public:
TDictNode(TComputationMutables& mutables,
- std::vector<std::pair<IComputationNode*, IComputationNode*>>&& itemNodes,
+ std::vector<std::pair<IComputationNode*, IComputationNode*>>&& itemNodes,
const TKeyTypes& types, bool isTuple, TType* encodedType)
: TBaseComputation(mutables)
, ItemNodes(std::move(itemNodes))
, Types(types)
, IsTuple(isTuple)
, EncodedType(encodedType)
- {}
+ {}
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- TKeyPayloadPairVector items;
- items.reserve(ItemNodes.size());
- for (const auto& node : ItemNodes) {
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ TKeyPayloadPairVector items;
+ items.reserve(ItemNodes.size());
+ for (const auto& node : ItemNodes) {
items.emplace_back(node.first->GetValue(ctx), node.second->GetValue(ctx));
}
- std::optional<TValuePacker> packer;
+ std::optional<TValuePacker> packer;
if (EncodedType) {
- packer.emplace(true, EncodedType);
+ packer.emplace(true, EncodedType);
}
THashedDictFiller filler =
@@ -2463,166 +2463,166 @@ public:
filler, Types, IsTuple, true, EncodedType);
}
-private:
- void RegisterDependencies() const final {
- for (const auto& itemNode : ItemNodes) {
- DependsOn(itemNode.first);
- DependsOn(itemNode.second);
+private:
+ void RegisterDependencies() const final {
+ for (const auto& itemNode : ItemNodes) {
+ DependsOn(itemNode.first);
+ DependsOn(itemNode.second);
}
}
- const std::vector<std::pair<IComputationNode*, IComputationNode*>> ItemNodes;
+ const std::vector<std::pair<IComputationNode*, IComputationNode*>> ItemNodes;
const TKeyTypes Types;
const bool IsTuple;
TType* EncodedType;
};
-class TVariantNode : public TMutableCodegeneratorNode<TVariantNode> {
- typedef TMutableCodegeneratorNode<TVariantNode> TBaseComputation;
+class TVariantNode : public TMutableCodegeneratorNode<TVariantNode> {
+ typedef TMutableCodegeneratorNode<TVariantNode> TBaseComputation;
public:
TVariantNode(TComputationMutables& mutables, IComputationNode* itemNode, ui32 index)
- : TBaseComputation(mutables, EValueRepresentation::Any)
+ : TBaseComputation(mutables, EValueRepresentation::Any)
, ItemNode(itemNode)
, Index(index)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- if (auto item = ItemNode->GetValue(ctx); item.TryMakeVariant(Index))
- return item.Release();
- else
- return ctx.HolderFactory.CreateBoxedVariantHolder(item.Release(), Index);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
- const auto value = GetNodeValue(ItemNode, ctx, block);
- return MakeVariant(value, ConstantInt::get(Type::getInt32Ty(ctx.Codegen->GetContext()), Index), ctx, block);
- }
-#endif
-private:
- void RegisterDependencies() const final {
- DependsOn(ItemNode);
- }
-
- IComputationNode *const ItemNode;
- const ui32 Index;
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ if (auto item = ItemNode->GetValue(ctx); item.TryMakeVariant(Index))
+ return item.Release();
+ else
+ return ctx.HolderFactory.CreateBoxedVariantHolder(item.Release(), Index);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ Value* DoGenerateGetValue(const TCodegenContext& ctx, BasicBlock*& block) const {
+ const auto value = GetNodeValue(ItemNode, ctx, block);
+ return MakeVariant(value, ConstantInt::get(Type::getInt32Ty(ctx.Codegen->GetContext()), Index), ctx, block);
+ }
+#endif
+private:
+ void RegisterDependencies() const final {
+ DependsOn(ItemNode);
+ }
+
+ IComputationNode *const ItemNode;
+ const ui32 Index;
};
class TVariantHolder : public TComputationValue<TVariantHolder> {
public:
- TVariantHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& item, ui32 index)
- : TComputationValue(memInfo)
+ TVariantHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& item, ui32 index)
+ : TComputationValue(memInfo)
, Item(std::move(item))
, Index(index)
{
}
-private:
- NUdf::TUnboxedValue GetVariantItem() const override {
- return Item;
- }
+private:
+ NUdf::TUnboxedValue GetVariantItem() const override {
+ return Item;
+ }
ui32 GetVariantIndex() const override {
return Index;
}
- const NUdf::TUnboxedValue Item;
- const ui32 Index;
+ const NUdf::TUnboxedValue Item;
+ const ui32 Index;
};
class TListIteratorHolder : public TComputationValue<TListIteratorHolder> {
public:
- TListIteratorHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& list)
- : TComputationValue(memInfo)
+ TListIteratorHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& list)
+ : TComputationValue(memInfo)
, List(std::move(list))
- , Iter(List.GetListIterator())
- {}
+ , Iter(List.GetListIterator())
+ {}
-private:
+private:
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
- return Iter.Next(result) ? NUdf::EFetchStatus::Ok : NUdf::EFetchStatus::Finish;
+ return Iter.Next(result) ? NUdf::EFetchStatus::Ok : NUdf::EFetchStatus::Finish;
}
- const NUdf::TUnboxedValue List;
- const NUdf::TUnboxedValue Iter;
+ const NUdf::TUnboxedValue List;
+ const NUdf::TUnboxedValue Iter;
};
class TLimitedList: public TComputationValue<TLimitedList> {
public:
- class TIterator: public TComputationValue<TIterator> {
+ class TIterator: public TComputationValue<TIterator> {
public:
- TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter, TMaybe<ui64> skip, TMaybe<ui64> take)
- : TComputationValue(memInfo)
- , Iter(std::move(iter))
- , Skip_(skip)
- , Take_(take)
+ TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter, TMaybe<ui64> skip, TMaybe<ui64> take)
+ : TComputationValue(memInfo)
+ , Iter(std::move(iter))
+ , Skip_(skip)
+ , Take_(take)
, Index(Max<ui64>())
{
}
- private:
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Iter) {
- return false;
- }
-
- if (Skip_) {
- while ((Index + 1) < Skip_.GetRef()) {
- if (!Iter.Skip()) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- ++Index;
- }
- }
-
- if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- if (!Iter.Next(value)) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- ++Index;
- return true;
- }
-
- bool Skip() override {
- if (!Iter) {
- return false;
- }
-
- if (Skip_) {
- while ((Index + 1) < Skip_.GetRef()) {
- if (!Iter.Skip()) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- ++Index;
- }
- }
-
- if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- if (!Iter.Skip()) {
- Iter = NUdf::TUnboxedValue();
- return false;
- }
-
- ++Index;
- return true;
- }
-
- NUdf::TUnboxedValue Iter;
- const TMaybe<ui64> Skip_;
- const TMaybe<ui64> Take_;
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Iter) {
+ return false;
+ }
+
+ if (Skip_) {
+ while ((Index + 1) < Skip_.GetRef()) {
+ if (!Iter.Skip()) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ ++Index;
+ }
+ }
+
+ if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ if (!Iter.Next(value)) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ ++Index;
+ return true;
+ }
+
+ bool Skip() override {
+ if (!Iter) {
+ return false;
+ }
+
+ if (Skip_) {
+ while ((Index + 1) < Skip_.GetRef()) {
+ if (!Iter.Skip()) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ ++Index;
+ }
+ }
+
+ if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ if (!Iter.Skip()) {
+ Iter = NUdf::TUnboxedValue();
+ return false;
+ }
+
+ ++Index;
+ return true;
+ }
+
+ NUdf::TUnboxedValue Iter;
+ const TMaybe<ui64> Skip_;
+ const TMaybe<ui64> Take_;
ui64 Index;
};
@@ -2634,7 +2634,7 @@ public:
{
}
-private:
+private:
bool HasFastListLength() const override {
return Length.Defined();
}
@@ -2674,13 +2674,13 @@ private:
return *HasItems;
}
- HasItems = GetListIterator().Skip();
+ HasItems = GetListIterator().Skip();
return *HasItems;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NUdf::TBoxedValueAccessor::GetListIterator(*Parent), Skip, Take));
- }
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NUdf::TBoxedValueAccessor::GetListIterator(*Parent), Skip, Take));
+ }
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
if (!count) {
@@ -2689,20 +2689,20 @@ private:
if (Length) {
if (count >= Length.GetRef()) {
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
}
}
ui64 prevSkip = Skip.GetOrElse(0);
if (count > Max<ui64>() - prevSkip) {
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
}
const ui64 newSkip = prevSkip + count;
TMaybe<ui64> newTake = Take;
if (newTake) {
if (count >= newTake.GetRef()) {
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
}
newTake = newTake.GetRef() - count;
@@ -2713,7 +2713,7 @@ private:
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
if (!count) {
- return builder.NewEmptyList().Release().AsBoxed();
+ return builder.NewEmptyList().Release().AsBoxed();
}
if (Length) {
@@ -2739,297 +2739,297 @@ private:
mutable TMaybe<bool> HasItems;
};
-class TLazyListDecorator : public TComputationValue<TLazyListDecorator> {
-public:
+class TLazyListDecorator : public TComputationValue<TLazyListDecorator> {
+public:
TLazyListDecorator(TMemoryUsageInfo* memInfo, NUdf::IBoxedValuePtr&& list)
- : TComputationValue(memInfo), List(std::move(list))
- {}
-
-private:
- bool HasListItems() const final {
- return NUdf::TBoxedValueAccessor::HasListItems(*List);
- }
-
- bool HasDictItems() const final {
- return NUdf::TBoxedValueAccessor::HasDictItems(*List);
- }
-
- bool HasFastListLength() const final {
- return NUdf::TBoxedValueAccessor::HasFastListLength(*List);
- }
-
- ui64 GetListLength() const final {
- return NUdf::TBoxedValueAccessor::GetListLength(*List);
- }
-
- ui64 GetDictLength() const final {
- return NUdf::TBoxedValueAccessor::GetDictLength(*List);
- }
-
- ui64 GetEstimatedListLength() const final {
- return NUdf::TBoxedValueAccessor::GetEstimatedListLength(*List);
- }
-
- NUdf::TUnboxedValue GetListIterator() const final {
- return NUdf::TBoxedValueAccessor::GetListIterator(*List);
- }
-
- NUdf::TUnboxedValue GetDictIterator() const final {
- return NUdf::TBoxedValueAccessor::GetDictIterator(*List);
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const final {
- return NUdf::TBoxedValueAccessor::GetPayloadsIterator(*List);
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const final {
- return NUdf::TBoxedValueAccessor::GetKeysIterator(*List);
- }
-
+ : TComputationValue(memInfo), List(std::move(list))
+ {}
+
+private:
+ bool HasListItems() const final {
+ return NUdf::TBoxedValueAccessor::HasListItems(*List);
+ }
+
+ bool HasDictItems() const final {
+ return NUdf::TBoxedValueAccessor::HasDictItems(*List);
+ }
+
+ bool HasFastListLength() const final {
+ return NUdf::TBoxedValueAccessor::HasFastListLength(*List);
+ }
+
+ ui64 GetListLength() const final {
+ return NUdf::TBoxedValueAccessor::GetListLength(*List);
+ }
+
+ ui64 GetDictLength() const final {
+ return NUdf::TBoxedValueAccessor::GetDictLength(*List);
+ }
+
+ ui64 GetEstimatedListLength() const final {
+ return NUdf::TBoxedValueAccessor::GetEstimatedListLength(*List);
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const final {
+ return NUdf::TBoxedValueAccessor::GetListIterator(*List);
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const final {
+ return NUdf::TBoxedValueAccessor::GetDictIterator(*List);
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const final {
+ return NUdf::TBoxedValueAccessor::GetPayloadsIterator(*List);
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const final {
+ return NUdf::TBoxedValueAccessor::GetKeysIterator(*List);
+ }
+
NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const final {
- return NUdf::TBoxedValueAccessor::ReverseListImpl(*List, builder);
- }
-
+ return NUdf::TBoxedValueAccessor::ReverseListImpl(*List, builder);
+ }
+
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
- return NUdf::TBoxedValueAccessor::SkipListImpl(*List, builder, count);
- }
-
+ return NUdf::TBoxedValueAccessor::SkipListImpl(*List, builder, count);
+ }
+
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
- return NUdf::TBoxedValueAccessor::TakeListImpl(*List, builder, count);
- }
-
+ return NUdf::TBoxedValueAccessor::TakeListImpl(*List, builder, count);
+ }
+
NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const final {
- return NUdf::TBoxedValueAccessor::ToIndexDictImpl(*List, builder);
- }
-
- bool Contains(const NUdf::TUnboxedValuePod& key) const final {
- return NUdf::TBoxedValueAccessor::Contains(*List, key);
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
- return NUdf::TBoxedValueAccessor::Lookup(*List, key);
- }
-
- NUdf::TUnboxedValue GetElement(ui32 index) const final {
- return NUdf::TBoxedValueAccessor::GetElement(*List, index);
- }
-
- const NUdf::TUnboxedValue* GetElements() const final {
- return nullptr;
- }
-
- bool IsSortedDict() const final {
- return NUdf::TBoxedValueAccessor::IsSortedDict(*List);
- }
-
+ return NUdf::TBoxedValueAccessor::ToIndexDictImpl(*List, builder);
+ }
+
+ bool Contains(const NUdf::TUnboxedValuePod& key) const final {
+ return NUdf::TBoxedValueAccessor::Contains(*List, key);
+ }
+
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
+ return NUdf::TBoxedValueAccessor::Lookup(*List, key);
+ }
+
+ NUdf::TUnboxedValue GetElement(ui32 index) const final {
+ return NUdf::TBoxedValueAccessor::GetElement(*List, index);
+ }
+
+ const NUdf::TUnboxedValue* GetElements() const final {
+ return nullptr;
+ }
+
+ bool IsSortedDict() const final {
+ return NUdf::TBoxedValueAccessor::IsSortedDict(*List);
+ }
+
const NUdf::IBoxedValuePtr List;
-};
-
+};
+
} // namespace
-///////////////////////////////////////////////////////////////////////////////
-// TDictValueBuilder
-///////////////////////////////////////////////////////////////////////////////
-class TDictValueBuilder: public NUdf::IDictValueBuilder
-{
-public:
- TDictValueBuilder(
- const THolderFactory& holderFactory,
- const TKeyTypes& types,
+///////////////////////////////////////////////////////////////////////////////
+// TDictValueBuilder
+///////////////////////////////////////////////////////////////////////////////
+class TDictValueBuilder: public NUdf::IDictValueBuilder
+{
+public:
+ TDictValueBuilder(
+ const THolderFactory& holderFactory,
+ const TKeyTypes& types,
bool isTuple,
ui32 dictFlags,
TType* encodeType)
- : HolderFactory_(holderFactory)
- , Types_(types)
+ : HolderFactory_(holderFactory)
+ , Types_(types)
, IsTuple_(isTuple)
- , DictFlags_(dictFlags)
+ , DictFlags_(dictFlags)
, EncodeType_(encodeType)
- {
- Items_.reserve(10);
- }
-
- NUdf::IDictValueBuilder& Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& value) override
- {
- Items_.emplace_back(std::move(key), std::move(value));
- return *this;
- }
-
- NUdf::TUnboxedValue Build() override {
- if (Items_.empty())
- return HolderFactory_.GetEmptyContainer();
-
- if (DictFlags_ & NUdf::TDictFlags::Hashed) {
- auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
- ? &TDictValueBuilder::PrepareMultiHasedDict
- : &TDictValueBuilder::PrepareHasedDict;
- THashedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
-
- return HolderFactory_.CreateDirectHashedDictHolder(
+ {
+ Items_.reserve(10);
+ }
+
+ NUdf::IDictValueBuilder& Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& value) override
+ {
+ Items_.emplace_back(std::move(key), std::move(value));
+ return *this;
+ }
+
+ NUdf::TUnboxedValue Build() override {
+ if (Items_.empty())
+ return HolderFactory_.GetEmptyContainer();
+
+ if (DictFlags_ & NUdf::TDictFlags::Hashed) {
+ auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
+ ? &TDictValueBuilder::PrepareMultiHasedDict
+ : &TDictValueBuilder::PrepareHasedDict;
+ THashedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
+
+ return HolderFactory_.CreateDirectHashedDictHolder(
filler, Types_, IsTuple_, true, EncodeType_);
- }
- else {
- auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
- ? &TDictValueBuilder::PrepareMultiSortedDict
- : &TDictValueBuilder::PrepareSortedDict;
- TSortedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
-
- EDictSortMode mode = (DictFlags_ & NUdf::TDictFlags::Multi)
- ? EDictSortMode::SortedUniqueAscending
- : EDictSortMode::RequiresSorting;
-
+ }
+ else {
+ auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
+ ? &TDictValueBuilder::PrepareMultiSortedDict
+ : &TDictValueBuilder::PrepareSortedDict;
+ TSortedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
+
+ EDictSortMode mode = (DictFlags_ & NUdf::TDictFlags::Multi)
+ ? EDictSortMode::SortedUniqueAscending
+ : EDictSortMode::RequiresSorting;
+
return HolderFactory_.CreateDirectSortedDictHolder(filler, Types_, IsTuple_, mode, true,
EncodeType_);
- }
- }
-
-private:
- void PrepareMultiHasedDict(TValuesDictHashMap& map) {
- TKeyPayloadPairVector localValues;
- localValues.swap(Items_);
- map.clear();
- std::optional<TValuePacker> packer;
+ }
+ }
+
+private:
+ void PrepareMultiHasedDict(TValuesDictHashMap& map) {
+ TKeyPayloadPairVector localValues;
+ localValues.swap(Items_);
+ map.clear();
+ std::optional<TValuePacker> packer;
if (EncodeType_) {
- packer.emplace(true, EncodeType_);
+ packer.emplace(true, EncodeType_);
}
-
- for (auto& value : localValues) {
+
+ for (auto& value : localValues) {
auto key = value.first;
if (packer) {
key = MakeString(packer->Pack(key));
}
auto it = map.find(key);
- if (it == map.end()) {
- TDefaultListRepresentation emptyList;
- auto newList = HolderFactory_.CreateDirectListHolder(
- emptyList.Append(std::move(value.second)));
+ if (it == map.end()) {
+ TDefaultListRepresentation emptyList;
+ auto newList = HolderFactory_.CreateDirectListHolder(
+ emptyList.Append(std::move(value.second)));
map.emplace(std::move(key), std::move(newList));
- } else {
- auto prevList = GetDefaultListRepresentation(it->second);
- auto newList = HolderFactory_.CreateDirectListHolder(
- prevList->Append(std::move(value.second)));
- it->second = std::move(newList);
- }
- }
- }
-
- void PrepareHasedDict(TValuesDictHashMap& map) {
- TKeyPayloadPairVector localValues;
- localValues.swap(Items_);
- map.clear();
- std::optional<TValuePacker> packer;
+ } else {
+ auto prevList = GetDefaultListRepresentation(it->second);
+ auto newList = HolderFactory_.CreateDirectListHolder(
+ prevList->Append(std::move(value.second)));
+ it->second = std::move(newList);
+ }
+ }
+ }
+
+ void PrepareHasedDict(TValuesDictHashMap& map) {
+ TKeyPayloadPairVector localValues;
+ localValues.swap(Items_);
+ map.clear();
+ std::optional<TValuePacker> packer;
if (EncodeType_) {
- packer.emplace(true, EncodeType_);
+ packer.emplace(true, EncodeType_);
}
- for (auto& value : localValues) {
+ for (auto& value : localValues) {
auto key = value.first;
if (packer) {
key = MakeString(packer->Pack(key));
}
map.emplace(std::move(key), std::move(value.second));
- }
- }
-
- void PrepareMultiSortedDict(TKeyPayloadPairVector& values) {
- TKeyPayloadPairVector localValues;
- localValues.swap(Items_);
- std::optional<TGenericPresortEncoder> packer;
+ }
+ }
+
+ void PrepareMultiSortedDict(TKeyPayloadPairVector& values) {
+ TKeyPayloadPairVector localValues;
+ localValues.swap(Items_);
+ std::optional<TGenericPresortEncoder> packer;
if (EncodeType_) {
- packer.emplace(EncodeType_);
+ packer.emplace(EncodeType_);
for (auto& x : localValues) {
x.first = MakeString(packer->Encode(x.first, false));
}
}
StableSort(localValues.begin(), localValues.end(), TKeyPayloadPairLess(Types_, IsTuple_));
-
- TKeyPayloadPairVector groups;
- groups.reserve(localValues.size());
- if (!localValues.empty()) {
- TDefaultListRepresentation currentList(std::move(localValues.begin()->second));
- auto lastKey = std::move(localValues.begin()->first);
+
+ TKeyPayloadPairVector groups;
+ groups.reserve(localValues.size());
+ if (!localValues.empty()) {
+ TDefaultListRepresentation currentList(std::move(localValues.begin()->second));
+ auto lastKey = std::move(localValues.begin()->first);
TValueEqual eqPredicate(Types_, IsTuple_);
- for (auto it = localValues.begin() + 1; it != localValues.end(); ++it) {
- if (eqPredicate(lastKey, it->first)) {
- currentList = currentList.Append(std::move(it->second));
- } else {
- auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
- groups.emplace_back(std::move(lastKey), std::move(payload));
- currentList = TDefaultListRepresentation(std::move(it->second));
- lastKey = std::move(it->first);
- }
- }
-
- auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
- groups.emplace_back(std::move(lastKey), std::move(payload));
- }
-
- values.swap(groups);
- }
-
- void PrepareSortedDict(TKeyPayloadPairVector& values) {
- Items_.swap(values);
- std::optional<TGenericPresortEncoder> packer;
+ for (auto it = localValues.begin() + 1; it != localValues.end(); ++it) {
+ if (eqPredicate(lastKey, it->first)) {
+ currentList = currentList.Append(std::move(it->second));
+ } else {
+ auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
+ groups.emplace_back(std::move(lastKey), std::move(payload));
+ currentList = TDefaultListRepresentation(std::move(it->second));
+ lastKey = std::move(it->first);
+ }
+ }
+
+ auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
+ groups.emplace_back(std::move(lastKey), std::move(payload));
+ }
+
+ values.swap(groups);
+ }
+
+ void PrepareSortedDict(TKeyPayloadPairVector& values) {
+ Items_.swap(values);
+ std::optional<TGenericPresortEncoder> packer;
if (EncodeType_) {
- packer.emplace(EncodeType_);
+ packer.emplace(EncodeType_);
for (auto& x : values) {
x.first = MakeString(packer->Encode(x.first, false));
}
}
- }
-
-private:
- const THolderFactory& HolderFactory_;
- const TKeyTypes Types_;
+ }
+
+private:
+ const THolderFactory& HolderFactory_;
+ const TKeyTypes Types_;
const bool IsTuple_;
- const ui32 DictFlags_;
+ const ui32 DictFlags_;
TType* const EncodeType_;
- TKeyPayloadPairVector Items_;
-};
-
-
+ TKeyPayloadPairVector Items_;
+};
+
+
//////////////////////////////////////////////////////////////////////////////
// THolderFactory
//////////////////////////////////////////////////////////////////////////////
THolderFactory::THolderFactory(
TAllocState& allocState,
TMemoryUsageInfo& memInfo,
- const IFunctionRegistry* functionRegistry)
- : CurrentAllocState(&allocState)
- , MemInfo(memInfo)
+ const IFunctionRegistry* functionRegistry)
+ : CurrentAllocState(&allocState)
+ , MemInfo(memInfo)
, FunctionRegistry(functionRegistry)
- , EmptyContainer(NUdf::TUnboxedValuePod(AllocateOn<TEmptyContainerHolder>(CurrentAllocState, &MemInfo)))
-{}
+ , EmptyContainer(NUdf::TUnboxedValuePod(AllocateOn<TEmptyContainerHolder>(CurrentAllocState, &MemInfo)))
+{}
-NUdf::TUnboxedValuePod THolderFactory::CreateTypeHolder(TType* type) const
+NUdf::TUnboxedValuePod THolderFactory::CreateTypeHolder(TType* type) const
{
- return NUdf::TUnboxedValuePod(AllocateOn<TTypeHolder>(CurrentAllocState, &MemInfo, type));
+ return NUdf::TUnboxedValuePod(AllocateOn<TTypeHolder>(CurrentAllocState, &MemInfo, type));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectListHolder(TDefaultListRepresentation&& items) const
-{
- if (!items.GetLength())
- return GetEmptyContainer();
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectListHolder(TDefaultListRepresentation&& items) const
+{
+ if (!items.GetLength())
+ return GetEmptyContainer();
- return NUdf::TUnboxedValuePod(AllocateOn<TDirectListHolder>(CurrentAllocState, &MemInfo, std::move(items)));
+ return NUdf::TUnboxedValuePod(AllocateOn<TDirectListHolder>(CurrentAllocState, &MemInfo, std::move(items)));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectArrayHolder(ui32 size, NUdf::TUnboxedValue*& itemsPtr) const {
- if (!size) {
- itemsPtr = nullptr;
- return GetEmptyContainer();
- }
-
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectArrayHolder(ui32 size, NUdf::TUnboxedValue*& itemsPtr) const {
+ if (!size) {
+ itemsPtr = nullptr;
+ return GetEmptyContainer();
+ }
+
const auto buffer = MKQLAllocFastWithSize(sizeof(TDirectArrayHolderInplace) + size * sizeof(NUdf::TUnboxedValue), CurrentAllocState);
- const auto h = ::new(buffer) TDirectArrayHolderInplace(&MemInfo, size);
-
- auto res = NUdf::TUnboxedValuePod(h);
- itemsPtr = h->GetPtr();
+ const auto h = ::new(buffer) TDirectArrayHolderInplace(&MemInfo, size);
+
+ auto res = NUdf::TUnboxedValuePod(h);
+ itemsPtr = h->GetPtr();
return res;
-}
-
+}
+
NUdf::TFlatDataBlockPtr THolderFactory::CreateFlatDataBlock(ui32 initialSize, ui32 initialCapacity) const {
return AllocateOn<TFlatDataBlockImpl>(CurrentAllocState, &MemInfo, initialSize, initialCapacity);
}
@@ -3046,69 +3046,69 @@ NUdf::TUnboxedValuePod THolderFactory::CreateArrowBlock(arrow::Datum&& datum) co
return Create<TArrowBlock>(std::move(datum));
}
-NUdf::TUnboxedValuePod THolderFactory::VectorAsArray(TUnboxedValueVector& values) const {
- if (values.empty())
- return GetEmptyContainer();
-
- NUdf::TUnboxedValue* itemsPtr = nullptr;
- auto tuple = CreateDirectArrayHolder(values.size(), itemsPtr);
- for (auto& value : values) {
- *itemsPtr++ = std::move(value);
+NUdf::TUnboxedValuePod THolderFactory::VectorAsArray(TUnboxedValueVector& values) const {
+ if (values.empty())
+ return GetEmptyContainer();
+
+ NUdf::TUnboxedValue* itemsPtr = nullptr;
+ auto tuple = CreateDirectArrayHolder(values.size(), itemsPtr);
+ for (auto& value : values) {
+ *itemsPtr++ = std::move(value);
}
return tuple;
}
-NUdf::TUnboxedValuePod THolderFactory::CloneArray(const NUdf::TUnboxedValuePod list, NUdf::TUnboxedValue*& items) const {
- if (const auto size = list.GetListLength()) {
- const auto ptr = list.GetElements();
- if (ptr && list.UniqueBoxed()) {
- items = const_cast<NUdf::TUnboxedValue*>(ptr);
- return list;
- } else {
- const auto array = CreateDirectArrayHolder(size, items);
- if (ptr) {
- std::copy(ptr, ptr + size, items);
- } else if (const auto& it = list.GetListIterator()) {
- for (auto out = items; it.Next(*out++);)
- continue;
- }
- list.DeleteUnreferenced();
- return array;
- }
- } else {
- items = nullptr;
- return GetEmptyContainer();
- }
-}
-
-NUdf::TUnboxedValuePod THolderFactory::Cloned(const NUdf::TUnboxedValuePod& it) const
-{
- TDefaultListRepresentation result;
- for (NUdf::TUnboxedValue item; it.Next(item);) {
- result = result.Append(std::move(item));
- }
-
- return CreateDirectListHolder(std::move(result));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::Reversed(const NUdf::TUnboxedValuePod& it) const
-{
- TDefaultListRepresentation result;
- for (NUdf::TUnboxedValue item; it.Next(item);) {
- result = result.Prepend(std::move(item));
- }
-
- return CreateDirectListHolder(std::move(result));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::CreateLimitedList(
+NUdf::TUnboxedValuePod THolderFactory::CloneArray(const NUdf::TUnboxedValuePod list, NUdf::TUnboxedValue*& items) const {
+ if (const auto size = list.GetListLength()) {
+ const auto ptr = list.GetElements();
+ if (ptr && list.UniqueBoxed()) {
+ items = const_cast<NUdf::TUnboxedValue*>(ptr);
+ return list;
+ } else {
+ const auto array = CreateDirectArrayHolder(size, items);
+ if (ptr) {
+ std::copy(ptr, ptr + size, items);
+ } else if (const auto& it = list.GetListIterator()) {
+ for (auto out = items; it.Next(*out++);)
+ continue;
+ }
+ list.DeleteUnreferenced();
+ return array;
+ }
+ } else {
+ items = nullptr;
+ return GetEmptyContainer();
+ }
+}
+
+NUdf::TUnboxedValuePod THolderFactory::Cloned(const NUdf::TUnboxedValuePod& it) const
+{
+ TDefaultListRepresentation result;
+ for (NUdf::TUnboxedValue item; it.Next(item);) {
+ result = result.Append(std::move(item));
+ }
+
+ return CreateDirectListHolder(std::move(result));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::Reversed(const NUdf::TUnboxedValuePod& it) const
+{
+ TDefaultListRepresentation result;
+ for (NUdf::TUnboxedValue item; it.Next(item);) {
+ result = result.Prepend(std::move(item));
+ }
+
+ return CreateDirectListHolder(std::move(result));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::CreateLimitedList(
NUdf::IBoxedValuePtr&& parent,
TMaybe<ui64> skip, TMaybe<ui64> take,
TMaybe<ui64> knownLength) const
{
if (take && !take.GetRef()) {
- return GetEmptyContainer();
+ return GetEmptyContainer();
}
if (skip && !skip.GetRef()) {
@@ -3117,7 +3117,7 @@ NUdf::TUnboxedValuePod THolderFactory::CreateLimitedList(
if (knownLength && skip) {
if (skip.GetRef() >= knownLength.GetRef()) {
- return GetEmptyContainer();
+ return GetEmptyContainer();
}
}
@@ -3128,70 +3128,70 @@ NUdf::TUnboxedValuePod THolderFactory::CreateLimitedList(
}
if (!skip && !take) {
- return NUdf::TUnboxedValuePod(std::move(parent));
+ return NUdf::TUnboxedValuePod(std::move(parent));
+ }
+
+ return NUdf::TUnboxedValuePod(AllocateOn<TLimitedList>(CurrentAllocState, &MemInfo, std::move(parent), skip, take));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::ReverseList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
+{
+ auto boxed = list.AsBoxed();
+ if (auto res = NUdf::TBoxedValueAccessor::ReverseListImpl(*boxed, *builder)) {
+ return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
+ }
+
+ return Reversed(list.GetListIterator());
+}
+
+NUdf::TUnboxedValuePod THolderFactory::SkipList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
+{
+ auto boxed = list.AsBoxed();
+ if (auto res = NUdf::TBoxedValueAccessor::SkipListImpl(*boxed, *builder, count)) {
+ return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
+ }
+
+ TMaybe<ui64> knownLength;
+ if (list.HasFastListLength()) {
+ knownLength = list.GetListLength();
+ }
+
+ return CreateLimitedList(std::move(boxed), count, TMaybe<ui64>(), knownLength);
+}
+
+NUdf::TUnboxedValuePod THolderFactory::TakeList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
+{
+ auto boxed = list.AsBoxed();
+ if (auto res = NUdf::TBoxedValueAccessor::TakeListImpl(*boxed, *builder, count)) {
+ return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
+ }
+
+ TMaybe<ui64> knownLength;
+ if (list.HasFastListLength()) {
+ knownLength = list.GetListLength();
+ }
+
+ return CreateLimitedList(std::move(boxed), TMaybe<ui64>(), count, knownLength);
+}
+
+NUdf::TUnboxedValuePod THolderFactory::ToIndexDict(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
+{
+ auto boxed = list.AsBoxed();
+ if (auto res = NUdf::TBoxedValueAccessor::ToIndexDictImpl(*boxed, *builder)) {
+ return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
}
- return NUdf::TUnboxedValuePod(AllocateOn<TLimitedList>(CurrentAllocState, &MemInfo, std::move(parent), skip, take));
+ return Cloned(list.GetListIterator());
}
-NUdf::TUnboxedValuePod THolderFactory::ReverseList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
-{
- auto boxed = list.AsBoxed();
- if (auto res = NUdf::TBoxedValueAccessor::ReverseListImpl(*boxed, *builder)) {
- return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
- }
-
- return Reversed(list.GetListIterator());
-}
-
-NUdf::TUnboxedValuePod THolderFactory::SkipList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
-{
- auto boxed = list.AsBoxed();
- if (auto res = NUdf::TBoxedValueAccessor::SkipListImpl(*boxed, *builder, count)) {
- return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
- }
-
- TMaybe<ui64> knownLength;
- if (list.HasFastListLength()) {
- knownLength = list.GetListLength();
- }
-
- return CreateLimitedList(std::move(boxed), count, TMaybe<ui64>(), knownLength);
-}
-
-NUdf::TUnboxedValuePod THolderFactory::TakeList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
-{
- auto boxed = list.AsBoxed();
- if (auto res = NUdf::TBoxedValueAccessor::TakeListImpl(*boxed, *builder, count)) {
- return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
- }
-
- TMaybe<ui64> knownLength;
- if (list.HasFastListLength()) {
- knownLength = list.GetListLength();
- }
-
- return CreateLimitedList(std::move(boxed), TMaybe<ui64>(), count, knownLength);
-}
-
-NUdf::TUnboxedValuePod THolderFactory::ToIndexDict(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
-{
- auto boxed = list.AsBoxed();
- if (auto res = NUdf::TBoxedValueAccessor::ToIndexDictImpl(*boxed, *builder)) {
- return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
- }
-
- return Cloned(list.GetListIterator());
-}
-
-template<bool IsStream>
-NUdf::TUnboxedValuePod THolderFactory::Collect(NUdf::TUnboxedValuePod list) const {
- const auto boxed = list.AsBoxed(); // Only for release on exit.
+template<bool IsStream>
+NUdf::TUnboxedValuePod THolderFactory::Collect(NUdf::TUnboxedValuePod list) const {
+ const auto boxed = list.AsBoxed(); // Only for release on exit.
if (!IsStream && list.HasFastListLength()) {
auto size = list.GetListLength();
NUdf::TUnboxedValue* items = nullptr;
const auto result = CreateDirectArrayHolder(size, items);
-
+
TThresher<IsStream>::DoForEachItem(list,
[&items] (NUdf::TUnboxedValue&& item) {
*items++ = std::move(item);
@@ -3200,7 +3200,7 @@ NUdf::TUnboxedValuePod THolderFactory::Collect(NUdf::TUnboxedValuePod list) cons
return result;
} else {
TDefaultListRepresentation res;
-
+
TThresher<IsStream>::DoForEachItem(list,
[&res] (NUdf::TUnboxedValue&& item) {
res = res.Append(std::move(item));
@@ -3209,167 +3209,167 @@ NUdf::TUnboxedValuePod THolderFactory::Collect(NUdf::TUnboxedValuePod list) cons
return CreateDirectListHolder(std::move(res));
}
-}
-
-template NUdf::TUnboxedValuePod THolderFactory::Collect<true>(NUdf::TUnboxedValuePod list) const;
-template NUdf::TUnboxedValuePod THolderFactory::Collect<false>(NUdf::TUnboxedValuePod list) const;
-
-NUdf::TUnboxedValuePod THolderFactory::LazyList(NUdf::TUnboxedValuePod list) const {
- return NUdf::TUnboxedValuePod(AllocateOn<TLazyListDecorator>(CurrentAllocState, &MemInfo, list.AsBoxed()));;
-}
-
-NUdf::TUnboxedValuePod THolderFactory::Append(NUdf::TUnboxedValuePod list, NUdf::TUnboxedValuePod last) const {
- const auto boxed = list.AsBoxed();
- TDefaultListRepresentation resList;
- if (const auto leftRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
- resList = std::move(*leftRepr);
- } else {
- TThresher<false>::DoForEachItem(list,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- }
-
- resList = resList.Append(std::move(last));
- return CreateDirectListHolder(std::move(resList));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::Prepend(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod list) const {
- const auto boxed = list.AsBoxed();
- TDefaultListRepresentation resList;
- if (const auto rightRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
- resList = *rightRepr;
- } else {
- TThresher<false>::DoForEachItem(list,
- [&resList] (NUdf::TUnboxedValue&& item) {
- resList = resList.Append(std::move(item));
- }
- );
- }
-
- resList = resList.Prepend(std::move(first));
- return CreateDirectListHolder(std::move(resList));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::ExtendStream(NUdf::TUnboxedValue* data, ui64 size) const {
- if (!data || !size) {
- return GetEmptyContainer();
- }
-
- TUnboxedValueVector values(size);
- std::move(data, data + size, values.begin());
- return Create<TExtendStreamValue>(std::move(values));
-}
-
-template<>
-NUdf::TUnboxedValuePod THolderFactory::ExtendList<true>(NUdf::TUnboxedValue* data, ui64 size) const {
- if (!data || !size) {
- return GetEmptyContainer();
- }
-
- TUnboxedValueVector values;
- values.reserve(size);
- std::transform(data, data + size, std::back_inserter(values), [this](NUdf::TUnboxedValue& stream){ return Create<TForwardListValue>(std::move(stream)); });
- return Create<TExtendListValue>(std::move(values));
-}
-
-template<>
-NUdf::TUnboxedValuePod THolderFactory::ExtendList<false>(NUdf::TUnboxedValue* data, ui64 size) const {
- if (!data || !size) {
- return GetEmptyContainer();
- }
-
- using TElementsAndSize = std::tuple<const NUdf::TUnboxedValuePod*, ui64, ui64>;
- TSmallVec<TElementsAndSize, TMKQLAllocator<TElementsAndSize>> elements;
- elements.reserve(size);
-
- for (ui64 i = 0ULL; i < size; ++i) {
- if (const auto ptr = data[i].GetElements()) {
- if (const auto length = data[i].GetListLength()) {
- elements.emplace_back(ptr, length, i);
- }
- } else {
- TUnboxedValueVector values(size);
- std::move(data, data + size, values.begin());
- return Create<TExtendListValue>(std::move(values));
- }
- }
-
- const auto total = std::accumulate(elements.cbegin(), elements.cend(), 0ULL, [](ui64 s, TElementsAndSize i) { return s + std::get<1U>(i); });
-
- if (!total) {
- std::fill_n(data, size, NUdf::TUnboxedValue());
- return GetEmptyContainer();
- }
-
- if (1U == elements.size()) {
- const auto result = data[std::get<2U>(elements.front())].Release();
- std::fill_n(data, size, NUdf::TUnboxedValue());
- return result;
- }
-
- auto it = elements.cbegin();
- if (const auto first = GetDefaultListRepresentation(data[std::get<2U>(*it++)])) {
- TDefaultListRepresentation list(*first);
- while (elements.cend() != it) {
- const auto& e = *it++;
- if (const auto repr = GetDefaultListRepresentation(data[std::get<2U>(e)])) {
- list = list.Extend(*repr);
- } else {
- std::for_each(std::get<0U>(e), std::get<0U>(e) + std::get<1U>(e),
- [&](NUdf::TUnboxedValue item) {
- list = list.Append(std::move(item));
- }
- );
- }
- }
- std::fill_n(data, size, NUdf::TUnboxedValue());
- return CreateDirectListHolder(std::move(list));
- } else {
- NUdf::TUnboxedValue *items = nullptr;
- const auto result = CreateDirectArrayHolder(total, items);
- for (const auto& i : elements) {
- std::copy_n(std::get<0U>(i), std::get<1U>(i), items);
- items += std::get<1U>(i);
- }
- std::fill_n(data, size, NUdf::TUnboxedValue());
- return result;
- }
-}
-
-NUdf::TUnboxedValuePod THolderFactory::CreateVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
+}
+
+template NUdf::TUnboxedValuePod THolderFactory::Collect<true>(NUdf::TUnboxedValuePod list) const;
+template NUdf::TUnboxedValuePod THolderFactory::Collect<false>(NUdf::TUnboxedValuePod list) const;
+
+NUdf::TUnboxedValuePod THolderFactory::LazyList(NUdf::TUnboxedValuePod list) const {
+ return NUdf::TUnboxedValuePod(AllocateOn<TLazyListDecorator>(CurrentAllocState, &MemInfo, list.AsBoxed()));;
+}
+
+NUdf::TUnboxedValuePod THolderFactory::Append(NUdf::TUnboxedValuePod list, NUdf::TUnboxedValuePod last) const {
+ const auto boxed = list.AsBoxed();
+ TDefaultListRepresentation resList;
+ if (const auto leftRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
+ resList = std::move(*leftRepr);
+ } else {
+ TThresher<false>::DoForEachItem(list,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ }
+
+ resList = resList.Append(std::move(last));
+ return CreateDirectListHolder(std::move(resList));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::Prepend(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod list) const {
+ const auto boxed = list.AsBoxed();
+ TDefaultListRepresentation resList;
+ if (const auto rightRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
+ resList = *rightRepr;
+ } else {
+ TThresher<false>::DoForEachItem(list,
+ [&resList] (NUdf::TUnboxedValue&& item) {
+ resList = resList.Append(std::move(item));
+ }
+ );
+ }
+
+ resList = resList.Prepend(std::move(first));
+ return CreateDirectListHolder(std::move(resList));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::ExtendStream(NUdf::TUnboxedValue* data, ui64 size) const {
+ if (!data || !size) {
+ return GetEmptyContainer();
+ }
+
+ TUnboxedValueVector values(size);
+ std::move(data, data + size, values.begin());
+ return Create<TExtendStreamValue>(std::move(values));
+}
+
+template<>
+NUdf::TUnboxedValuePod THolderFactory::ExtendList<true>(NUdf::TUnboxedValue* data, ui64 size) const {
+ if (!data || !size) {
+ return GetEmptyContainer();
+ }
+
+ TUnboxedValueVector values;
+ values.reserve(size);
+ std::transform(data, data + size, std::back_inserter(values), [this](NUdf::TUnboxedValue& stream){ return Create<TForwardListValue>(std::move(stream)); });
+ return Create<TExtendListValue>(std::move(values));
+}
+
+template<>
+NUdf::TUnboxedValuePod THolderFactory::ExtendList<false>(NUdf::TUnboxedValue* data, ui64 size) const {
+ if (!data || !size) {
+ return GetEmptyContainer();
+ }
+
+ using TElementsAndSize = std::tuple<const NUdf::TUnboxedValuePod*, ui64, ui64>;
+ TSmallVec<TElementsAndSize, TMKQLAllocator<TElementsAndSize>> elements;
+ elements.reserve(size);
+
+ for (ui64 i = 0ULL; i < size; ++i) {
+ if (const auto ptr = data[i].GetElements()) {
+ if (const auto length = data[i].GetListLength()) {
+ elements.emplace_back(ptr, length, i);
+ }
+ } else {
+ TUnboxedValueVector values(size);
+ std::move(data, data + size, values.begin());
+ return Create<TExtendListValue>(std::move(values));
+ }
+ }
+
+ const auto total = std::accumulate(elements.cbegin(), elements.cend(), 0ULL, [](ui64 s, TElementsAndSize i) { return s + std::get<1U>(i); });
+
+ if (!total) {
+ std::fill_n(data, size, NUdf::TUnboxedValue());
+ return GetEmptyContainer();
+ }
+
+ if (1U == elements.size()) {
+ const auto result = data[std::get<2U>(elements.front())].Release();
+ std::fill_n(data, size, NUdf::TUnboxedValue());
+ return result;
+ }
+
+ auto it = elements.cbegin();
+ if (const auto first = GetDefaultListRepresentation(data[std::get<2U>(*it++)])) {
+ TDefaultListRepresentation list(*first);
+ while (elements.cend() != it) {
+ const auto& e = *it++;
+ if (const auto repr = GetDefaultListRepresentation(data[std::get<2U>(e)])) {
+ list = list.Extend(*repr);
+ } else {
+ std::for_each(std::get<0U>(e), std::get<0U>(e) + std::get<1U>(e),
+ [&](NUdf::TUnboxedValue item) {
+ list = list.Append(std::move(item));
+ }
+ );
+ }
+ }
+ std::fill_n(data, size, NUdf::TUnboxedValue());
+ return CreateDirectListHolder(std::move(list));
+ } else {
+ NUdf::TUnboxedValue *items = nullptr;
+ const auto result = CreateDirectArrayHolder(total, items);
+ for (const auto& i : elements) {
+ std::copy_n(std::get<0U>(i), std::get<1U>(i), items);
+ items += std::get<1U>(i);
+ }
+ std::fill_n(data, size, NUdf::TUnboxedValue());
+ return result;
+ }
+}
+
+NUdf::TUnboxedValuePod THolderFactory::CreateVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
if (item.TryMakeVariant(index))
- return item;
+ return item;
+
+ return CreateBoxedVariantHolder(std::move(item), index);
+}
- return CreateBoxedVariantHolder(std::move(item), index);
-}
-
-NUdf::TUnboxedValuePod THolderFactory::CreateBoxedVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
- return NUdf::TUnboxedValuePod(AllocateOn<TVariantHolder>(CurrentAllocState, &MemInfo, std::move(item), index));
+NUdf::TUnboxedValuePod THolderFactory::CreateBoxedVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
+ return NUdf::TUnboxedValuePod(AllocateOn<TVariantHolder>(CurrentAllocState, &MemInfo, std::move(item), index));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateIteratorOverList(NUdf::TUnboxedValuePod list) const {
- return NUdf::TUnboxedValuePod(AllocateOn<TListIteratorHolder>(CurrentAllocState, &MemInfo, list));
+NUdf::TUnboxedValuePod THolderFactory::CreateIteratorOverList(NUdf::TUnboxedValuePod list) const {
+ return NUdf::TUnboxedValuePod(AllocateOn<TListIteratorHolder>(CurrentAllocState, &MemInfo, list));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::CreateForwardList(NUdf::TUnboxedValuePod stream) const {
+ return NUdf::TUnboxedValuePod(AllocateOn<TForwardListValue>(CurrentAllocState, &MemInfo, stream));
+}
+
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedSetHolder(
+ TSortedSetFiller filler,
+ const TKeyTypes& types,
+ bool isTuple,
+ EDictSortMode mode,
+ bool eagerFill,
+ TType* encodedType) const
+{
+ return NUdf::TUnboxedValuePod(AllocateOn<TSortedSetHolder>(CurrentAllocState, &MemInfo,
+ filler, types, isTuple, mode, eagerFill, encodedType, *this));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateForwardList(NUdf::TUnboxedValuePod stream) const {
- return NUdf::TUnboxedValuePod(AllocateOn<TForwardListValue>(CurrentAllocState, &MemInfo, stream));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedSetHolder(
- TSortedSetFiller filler,
- const TKeyTypes& types,
- bool isTuple,
- EDictSortMode mode,
- bool eagerFill,
- TType* encodedType) const
-{
- return NUdf::TUnboxedValuePod(AllocateOn<TSortedSetHolder>(CurrentAllocState, &MemInfo,
- filler, types, isTuple, mode, eagerFill, encodedType, *this));
-}
-
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedDictHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedDictHolder(
TSortedDictFiller filler,
const TKeyTypes& types,
bool isTuple,
@@ -3381,7 +3381,7 @@ NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedDictHolder(
filler, types, isTuple, mode, eagerFill, encodedType, *this));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedDictHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedDictHolder(
THashedDictFiller filler,
const TKeyTypes& types,
bool isTuple,
@@ -3392,7 +3392,7 @@ NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedDictHolder(
filler, types, isTuple, eagerFill, encodedType, *this));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSetHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSetHolder(
THashedSetFiller filler,
const TKeyTypes& types,
bool isTuple,
@@ -3403,90 +3403,90 @@ NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSetHolder(
}
template <typename T>
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder(
TValuesDictHashSingleFixedSet<T>&& set) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedSetHolder<T>>(CurrentAllocState, &MemInfo, std::move(set)));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedSetHolder<T>>(CurrentAllocState, &MemInfo, std::move(set)));
}
#define DEFINE_HASHED_SINGLE_FIXED_SET(xType) \
- template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder<xType> \
+ template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder<xType> \
(TValuesDictHashSingleFixedSet<xType>&& set) const;
KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_SET)
#undef DEFINE_HASHED_SINGLE_FIXED_SET
template <typename T>
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder(
TValuesDictHashSingleFixedCompactSet<T>&& set) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactSetHolder<T>>(CurrentAllocState, &MemInfo, std::move(set)));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactSetHolder<T>>(CurrentAllocState, &MemInfo, std::move(set)));
}
#define DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET(xType) \
- template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder<xType> \
+ template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder<xType> \
(TValuesDictHashSingleFixedCompactSet<xType>&& set) const;
KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET)
#undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET
template <typename T>
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder(
TValuesDictHashSingleFixedMap<T>&& map) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map)));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map)));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactSetHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactSetHolder(
TValuesDictHashCompactSet&& set, TPagedArena&& pool, TType* keyType, TComputationContext* ctx) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactSetHolder>(CurrentAllocState, &MemInfo, std::move(set), std::move(pool), keyType, ctx));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactSetHolder>(CurrentAllocState, &MemInfo, std::move(set), std::move(pool), keyType, ctx));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMapHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMapHolder(
TValuesDictHashCompactMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
TComputationContext* ctx) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
}
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMultiMapHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMultiMapHolder(
TValuesDictHashCompactMultiMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
TComputationContext* ctx) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMultiMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMultiMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
}
template <typename T>
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder(
TValuesDictHashSingleFixedCompactMap<T>&& map, TPagedArena&& pool, TType* payloadType,
TComputationContext* ctx) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), payloadType, ctx));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), payloadType, ctx));
}
template <typename T>
-NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder(
+NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder(
TValuesDictHashSingleFixedCompactMultiMap<T>&& map, TPagedArena&& pool, TType* payloadType,
TComputationContext* ctx) const {
- return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMultiMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), payloadType, ctx));
+ return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMultiMapHolder<T>>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), payloadType, ctx));
}
-NUdf::IDictValueBuilder::TPtr THolderFactory::NewDict(
- const NUdf::TType* dictType,
- ui32 flags) const
-{
- TType* type = const_cast<TType*>(static_cast<const TType*>(dictType));
- TType* keyType = AS_TYPE(TDictType, type)->GetKeyType();
- TKeyTypes types;
+NUdf::IDictValueBuilder::TPtr THolderFactory::NewDict(
+ const NUdf::TType* dictType,
+ ui32 flags) const
+{
+ TType* type = const_cast<TType*>(static_cast<const TType*>(dictType));
+ TType* keyType = AS_TYPE(TDictType, type)->GetKeyType();
+ TKeyTypes types;
bool encoded;
bool isTuple;
GetDictionaryKeyTypes(keyType, types, isTuple, encoded);
return new TDictValueBuilder(*this, types, isTuple, flags, encoded ? keyType : nullptr);
-}
-
+}
+
#define DEFINE_HASHED_SINGLE_FIXED_MAP(xType) \
- template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder<xType> \
+ template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder<xType> \
(TValuesDictHashSingleFixedMap<xType>&& map) const;
KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_MAP)
#undef DEFINE_HASHED_SINGLE_FIXED_MAP
#define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP(xType) \
- template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder<xType> \
+ template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder<xType> \
(TValuesDictHashSingleFixedCompactMap<xType>&& map, TPagedArena&& pool, TType* payloadType, \
TComputationContext* ctx) const;
@@ -3494,7 +3494,7 @@ KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP)
#undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP
#define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP(xType) \
- template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder<xType> \
+ template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder<xType> \
(TValuesDictHashSingleFixedCompactMultiMap<xType>&& map, TPagedArena&& pool, TType* payloadType, \
TComputationContext* ctx) const;
@@ -3504,23 +3504,23 @@ KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP)
//////////////////////////////////////////////////////////////////////////////
// TNodeFactory
//////////////////////////////////////////////////////////////////////////////
-TNodeFactory::TNodeFactory(TMemoryUsageInfo& memInfo, TComputationMutables& mutables)
- : MemInfo(memInfo)
- , Mutables(mutables)
-{
-}
-
-IComputationNode* TNodeFactory::CreateEmptyNode() const
+TNodeFactory::TNodeFactory(TMemoryUsageInfo& memInfo, TComputationMutables& mutables)
+ : MemInfo(memInfo)
+ , Mutables(mutables)
+{
+}
+
+IComputationNode* TNodeFactory::CreateEmptyNode() const
{
return new TEmptyNode(Mutables);
}
IComputationNode* TNodeFactory::CreateOptionalNode(IComputationNode* item) const
{
- return item ? new TOptionalNode(item) : CreateImmutableNode(NUdf::TUnboxedValuePod());
+ return item ? new TOptionalNode(item) : CreateImmutableNode(NUdf::TUnboxedValuePod());
}
-IComputationNode* TNodeFactory::CreateArrayNode(TComputationNodePtrVector&& values) const
+IComputationNode* TNodeFactory::CreateArrayNode(TComputationNodePtrVector&& values) const
{
if (values.empty()) {
return new TEmptyNode(Mutables);
@@ -3530,37 +3530,37 @@ IComputationNode* TNodeFactory::CreateArrayNode(TComputationNodePtrVector&& valu
}
IComputationNode* TNodeFactory::CreateDictNode(
- std::vector<std::pair<IComputationNode*, IComputationNode*>>&& items,
+ std::vector<std::pair<IComputationNode*, IComputationNode*>>&& items,
const TKeyTypes& types, bool isTuple, TType* encodedType) const
{
- if (items.empty()) {
+ if (items.empty()) {
return new TEmptyNode(Mutables);
}
return new TDictNode(Mutables, std::move(items), types, isTuple, encodedType);
}
-IComputationNode* TNodeFactory::CreateVariantNode(IComputationNode* item, ui32 index) const {
+IComputationNode* TNodeFactory::CreateVariantNode(IComputationNode* item, ui32 index) const {
return new TVariantNode(Mutables, item, index);
}
-IComputationNode* TNodeFactory::CreateTypeNode(TType* type) const {
- return CreateImmutableNode(NUdf::TUnboxedValuePod(new TTypeHolder(&MemInfo, type)));
-}
-
-IComputationNode* TNodeFactory::CreateImmutableNode(NUdf::TUnboxedValue&& value) const {
- return new TUnboxedImmutableCodegeneratorNode(&MemInfo, std::move(value));
-}
-
+IComputationNode* TNodeFactory::CreateTypeNode(TType* type) const {
+ return CreateImmutableNode(NUdf::TUnboxedValuePod(new TTypeHolder(&MemInfo, type)));
+}
+
+IComputationNode* TNodeFactory::CreateImmutableNode(NUdf::TUnboxedValue&& value) const {
+ return new TUnboxedImmutableCodegeneratorNode(&MemInfo, std::move(value));
+}
+
void GetDictionaryKeyTypes(TType* keyType, TKeyTypes& types, bool& isTuple, bool& encoded) {
isTuple = false;
encoded = false;
types.clear();
- const bool isOptional = keyType->IsOptional();
- if (isOptional) {
- keyType = AS_TYPE(TOptionalType, keyType)->GetItemType();
- }
-
+ const bool isOptional = keyType->IsOptional();
+ if (isOptional) {
+ keyType = AS_TYPE(TOptionalType, keyType)->GetItemType();
+ }
+
if (keyType->IsTuple()) {
auto tuple = AS_TYPE(TTupleType, keyType);
for (ui32 i = 0; i < tuple->GetElementsCount(); ++i) {
@@ -3577,10 +3577,10 @@ void GetDictionaryKeyTypes(TType* keyType, TKeyTypes& types, bool& isTuple, bool
if (!encoded) {
isTuple = true;
}
- } else if (keyType->IsData()) {
- types.emplace_back(*AS_TYPE(TDataType, keyType)->GetDataSlot(), isOptional);
+ } else if (keyType->IsData()) {
+ types.emplace_back(*AS_TYPE(TDataType, keyType)->GetDataSlot(), isOptional);
} else {
- encoded = true;
+ encoded = true;
}
if (encoded) {
@@ -3590,193 +3590,193 @@ void GetDictionaryKeyTypes(TType* keyType, TKeyTypes& types, bool& isTuple, bool
}
}
-TContainerCacheOnContext::TContainerCacheOnContext(TComputationMutables& mutables)
- : Index(mutables.CurValueIndex++)
-{
- ++++mutables.CurValueIndex;
-}
-
-NUdf::TUnboxedValuePod TContainerCacheOnContext::NewArray(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue*& items) const {
- if (!size)
- return ctx.HolderFactory.GetEmptyContainer();
-
- auto& index = ctx.MutableValues[Index];
- if (index.IsInvalid())
- index = NUdf::TUnboxedValuePod::Zero();
-
- {
- auto& val = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
- if (val.IsInvalid() || !val.UniqueBoxed()) {
- index = NUdf::TUnboxedValuePod(!index.Get<bool>());
- auto& value = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
- if (value.IsInvalid() || !value.UniqueBoxed()) {
- return value = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
- }
- }
- }
-
- auto& value = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
- items = static_cast<const TDirectArrayHolderInplace*>(value.AsBoxed().Get())->GetPtr();
- std::fill_n(items, size, NUdf::TUnboxedValue());
- return value;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-namespace {
-
-Value* GenerateCheckNotUniqueBoxed(Value* value, LLVMContext& context, Function* function, BasicBlock*& block) {
- const auto invalid = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
- const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, value, invalid, "empty", block);
-
- const auto have = BasicBlock::Create(context, "have", function);
- const auto done = BasicBlock::Create(context, "done", function);
- const auto result = PHINode::Create(empty->getType(), 2, "result", done);
- result->addIncoming(empty, block);
- BranchInst::Create(done, have, empty, block);
-
- block = have;
- const auto half = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "half", block);
- const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
- const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
- const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
- const auto refs = new LoadInst(cntptr, "refs", block);
- const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, refs, ConstantInt::get(refs->getType(), 1U), "many", block);
- result->addIncoming(many, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
-}
-
-}
-
-Value* TContainerCacheOnContext::GenNewArray(ui32 sz, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
- auto& context = ctx.Codegen->GetContext();
- const auto valueType = Type::getInt128Ty(context);
- const auto arrayType = ArrayType::get(valueType, sz);
- const auto pointerType = PointerType::getUnqual(arrayType);
-
- const auto idxType = Type::getInt32Ty(context);
-
- const auto values = ctx.GetMutables();
-
- const auto indexPtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(idxType, Index)}, "index_ptr", block);
-
- const auto raw = new LoadInst(indexPtr, "raw", block);
-
- const auto indb = GetterFor<bool>(raw, context, block);
- const auto indf = new ZExtInst(indb, idxType, "indf", block);
- const auto ind_one = BinaryOperator::CreateAdd(indf, ConstantInt::get(idxType, Index + 1U), "ind_one", block);
-
- const auto tpfirst = GetElementPtrInst::CreateInBounds(values, {ind_one}, "tpfirst", block);
-
- const auto tfirst = new LoadInst(tpfirst, "tfirst", block);
- const auto cfirst = GenerateCheckNotUniqueBoxed(tfirst, context, ctx.Func, block);
-
- const auto scnd = BasicBlock::Create(context, "scnd", ctx.Func);
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- const auto have = BasicBlock::Create(context, "have", ctx.Func);
- const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
- const auto result = PHINode::Create(valueType, 2, "result", exit);
-
- const auto has = PHINode::Create(tfirst->getType(), 2, "has", have);
- has->addIncoming(tfirst, block);
-
- BranchInst::Create(scnd, have, cfirst, block);
-
- block = scnd;
-
- const auto neg = BinaryOperator::CreateXor(indb, ConstantInt::get(indb->getType(), 1), "xor", block);
- const auto newInd = SetterFor<bool>(neg, context, block);
- new StoreInst(newInd, indexPtr, block);
-
- const auto inds = new ZExtInst(neg, idxType, "inds", block);
-
- const auto ind_two = BinaryOperator::CreateAdd(inds, ConstantInt::get(idxType, Index + 1U), "ind_two", block);
-
- const auto tpsecond = GetElementPtrInst::CreateInBounds(values, {ind_two}, "tpsecond", block);
- const auto tsecond = new LoadInst(tpsecond, "tsecond", block);
- const auto csecond = GenerateCheckNotUniqueBoxed(tsecond, context, ctx.Func, block);
- has->addIncoming(tsecond, block);
- BranchInst::Create(make, have, csecond, block);
-
- {
- block = make;
- ValueUnRef(EValueRepresentation::Boxed, tpsecond, ctx, block);
-
- const auto fact = ctx.GetFactory();
-
- const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateDirectArrayHolder));
- const auto size = ConstantInt::get(Type::getInt32Ty(context), sz);
-
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(valueType, {fact->getType(), size->getType(), items->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- const auto array = CallInst::Create(funcPtr, {fact, size, items}, "array", block);
- AddRefBoxed(array, ctx, block);
- result->addIncoming(array, block);
- new StoreInst(array, tpsecond, block);
- } else {
- const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), tpsecond->getType(), size->getType(), items->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
- CallInst::Create(funcPtr, {fact, tpsecond, size, items}, "", block);
- const auto array = new LoadInst(tpsecond, "array", block);
- AddRefBoxed(array, ctx, block);
- result->addIncoming(array, block);
- }
-
- BranchInst::Create(exit, block);
- }
-
- {
- block = have;
-
- const auto half = CastInst::Create(Instruction::Trunc, has, Type::getInt64Ty(context), "half", block);
-
- const auto offs = BinaryOperator::CreateAdd(half, ConstantInt::get(half->getType(), sizeof(TDirectArrayHolderInplace)), "offs", block);
-
- const auto itemsPtr = CastInst::Create(Instruction::IntToPtr, offs, pointerType, "items_ptr", block);
-
- for (ui32 i = 0; i < sz; ++i) {
- const auto itemp = GetElementPtrInst::CreateInBounds(itemsPtr, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i)}, "itemp", block);
- ValueUnRef(EValueRepresentation::Any, itemp, ctx, block);
- }
-
- result->addIncoming(has, block);
-
- new StoreInst(ConstantAggregateZero::get(arrayType), itemsPtr, block);
- new StoreInst(itemsPtr, items, block);
- BranchInst::Create(exit, block);
- }
-
- block = exit;
- return result;
-}
-#endif
-
+TContainerCacheOnContext::TContainerCacheOnContext(TComputationMutables& mutables)
+ : Index(mutables.CurValueIndex++)
+{
+ ++++mutables.CurValueIndex;
+}
+
+NUdf::TUnboxedValuePod TContainerCacheOnContext::NewArray(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue*& items) const {
+ if (!size)
+ return ctx.HolderFactory.GetEmptyContainer();
+
+ auto& index = ctx.MutableValues[Index];
+ if (index.IsInvalid())
+ index = NUdf::TUnboxedValuePod::Zero();
+
+ {
+ auto& val = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
+ if (val.IsInvalid() || !val.UniqueBoxed()) {
+ index = NUdf::TUnboxedValuePod(!index.Get<bool>());
+ auto& value = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
+ if (value.IsInvalid() || !value.UniqueBoxed()) {
+ return value = ctx.HolderFactory.CreateDirectArrayHolder(size, items);
+ }
+ }
+ }
+
+ auto& value = ctx.MutableValues[Index + (index.Get<bool>() ? 1U : 2U)];
+ items = static_cast<const TDirectArrayHolderInplace*>(value.AsBoxed().Get())->GetPtr();
+ std::fill_n(items, size, NUdf::TUnboxedValue());
+ return value;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+namespace {
+
+Value* GenerateCheckNotUniqueBoxed(Value* value, LLVMContext& context, Function* function, BasicBlock*& block) {
+ const auto invalid = ConstantInt::get(value->getType(), 0xFFFFFFFFFFFFFFFFULL);
+ const auto empty = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, value, invalid, "empty", block);
+
+ const auto have = BasicBlock::Create(context, "have", function);
+ const auto done = BasicBlock::Create(context, "done", function);
+ const auto result = PHINode::Create(empty->getType(), 2, "result", done);
+ result->addIncoming(empty, block);
+ BranchInst::Create(done, have, empty, block);
+
+ block = have;
+ const auto half = CastInst::Create(Instruction::Trunc, value, Type::getInt64Ty(context), "half", block);
+ const auto type = StructType::get(context, {PointerType::getUnqual(StructType::get(context)), Type::getInt32Ty(context), Type::getInt16Ty(context)});
+ const auto boxptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type), "boxptr", block);
+ const auto cntptr = GetElementPtrInst::CreateInBounds(boxptr, {ConstantInt::get(Type::getInt32Ty(context), 0), ConstantInt::get(Type::getInt32Ty(context), 1)}, "cntptr", block);
+ const auto refs = new LoadInst(cntptr, "refs", block);
+ const auto many = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, refs, ConstantInt::get(refs->getType(), 1U), "many", block);
+ result->addIncoming(many, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+}
+
+}
+
+Value* TContainerCacheOnContext::GenNewArray(ui32 sz, Value* items, const TCodegenContext& ctx, BasicBlock*& block) const {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valueType = Type::getInt128Ty(context);
+ const auto arrayType = ArrayType::get(valueType, sz);
+ const auto pointerType = PointerType::getUnqual(arrayType);
+
+ const auto idxType = Type::getInt32Ty(context);
+
+ const auto values = ctx.GetMutables();
+
+ const auto indexPtr = GetElementPtrInst::CreateInBounds(values, {ConstantInt::get(idxType, Index)}, "index_ptr", block);
+
+ const auto raw = new LoadInst(indexPtr, "raw", block);
+
+ const auto indb = GetterFor<bool>(raw, context, block);
+ const auto indf = new ZExtInst(indb, idxType, "indf", block);
+ const auto ind_one = BinaryOperator::CreateAdd(indf, ConstantInt::get(idxType, Index + 1U), "ind_one", block);
+
+ const auto tpfirst = GetElementPtrInst::CreateInBounds(values, {ind_one}, "tpfirst", block);
+
+ const auto tfirst = new LoadInst(tpfirst, "tfirst", block);
+ const auto cfirst = GenerateCheckNotUniqueBoxed(tfirst, context, ctx.Func, block);
+
+ const auto scnd = BasicBlock::Create(context, "scnd", ctx.Func);
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ const auto have = BasicBlock::Create(context, "have", ctx.Func);
+ const auto exit = BasicBlock::Create(context, "exit", ctx.Func);
+ const auto result = PHINode::Create(valueType, 2, "result", exit);
+
+ const auto has = PHINode::Create(tfirst->getType(), 2, "has", have);
+ has->addIncoming(tfirst, block);
+
+ BranchInst::Create(scnd, have, cfirst, block);
+
+ block = scnd;
+
+ const auto neg = BinaryOperator::CreateXor(indb, ConstantInt::get(indb->getType(), 1), "xor", block);
+ const auto newInd = SetterFor<bool>(neg, context, block);
+ new StoreInst(newInd, indexPtr, block);
+
+ const auto inds = new ZExtInst(neg, idxType, "inds", block);
+
+ const auto ind_two = BinaryOperator::CreateAdd(inds, ConstantInt::get(idxType, Index + 1U), "ind_two", block);
+
+ const auto tpsecond = GetElementPtrInst::CreateInBounds(values, {ind_two}, "tpsecond", block);
+ const auto tsecond = new LoadInst(tpsecond, "tsecond", block);
+ const auto csecond = GenerateCheckNotUniqueBoxed(tsecond, context, ctx.Func, block);
+ has->addIncoming(tsecond, block);
+ BranchInst::Create(make, have, csecond, block);
+
+ {
+ block = make;
+ ValueUnRef(EValueRepresentation::Boxed, tpsecond, ctx, block);
+
+ const auto fact = ctx.GetFactory();
+
+ const auto func = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(&THolderFactory::CreateDirectArrayHolder));
+ const auto size = ConstantInt::get(Type::getInt32Ty(context), sz);
+
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(valueType, {fact->getType(), size->getType(), items->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ const auto array = CallInst::Create(funcPtr, {fact, size, items}, "array", block);
+ AddRefBoxed(array, ctx, block);
+ result->addIncoming(array, block);
+ new StoreInst(array, tpsecond, block);
+ } else {
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {fact->getType(), tpsecond->getType(), size->getType(), items->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, func, PointerType::getUnqual(funType), "function", block);
+ CallInst::Create(funcPtr, {fact, tpsecond, size, items}, "", block);
+ const auto array = new LoadInst(tpsecond, "array", block);
+ AddRefBoxed(array, ctx, block);
+ result->addIncoming(array, block);
+ }
+
+ BranchInst::Create(exit, block);
+ }
+
+ {
+ block = have;
+
+ const auto half = CastInst::Create(Instruction::Trunc, has, Type::getInt64Ty(context), "half", block);
+
+ const auto offs = BinaryOperator::CreateAdd(half, ConstantInt::get(half->getType(), sizeof(TDirectArrayHolderInplace)), "offs", block);
+
+ const auto itemsPtr = CastInst::Create(Instruction::IntToPtr, offs, pointerType, "items_ptr", block);
+
+ for (ui32 i = 0; i < sz; ++i) {
+ const auto itemp = GetElementPtrInst::CreateInBounds(itemsPtr, {ConstantInt::get(idxType, 0), ConstantInt::get(idxType, i)}, "itemp", block);
+ ValueUnRef(EValueRepresentation::Any, itemp, ctx, block);
+ }
+
+ result->addIncoming(has, block);
+
+ new StoreInst(ConstantAggregateZero::get(arrayType), itemsPtr, block);
+ new StoreInst(itemsPtr, items, block);
+ BranchInst::Create(exit, block);
+ }
+
+ block = exit;
+ return result;
+}
+#endif
+
TPlainContainerCache::TPlainContainerCache() {
- Clear();
-}
-
-void TPlainContainerCache::Clear() {
- Cached.fill(NUdf::TUnboxedValue());
- CachedItems.fill(nullptr);
-}
-
-NUdf::TUnboxedValuePod TPlainContainerCache::NewArray(const THolderFactory& factory, ui32 size, NUdf::TUnboxedValue*& items) {
- if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
- CacheIndex ^= 1U;
- if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
- Cached[CacheIndex] = factory.CreateDirectArrayHolder(size, CachedItems[CacheIndex]);
- items = CachedItems[CacheIndex];
- return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
- }
- }
-
- items = CachedItems[CacheIndex];
- std::fill_n(items, size, NUdf::TUnboxedValue());
- return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
-}
-
+ Clear();
+}
+
+void TPlainContainerCache::Clear() {
+ Cached.fill(NUdf::TUnboxedValue());
+ CachedItems.fill(nullptr);
+}
+
+NUdf::TUnboxedValuePod TPlainContainerCache::NewArray(const THolderFactory& factory, ui32 size, NUdf::TUnboxedValue*& items) {
+ if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
+ CacheIndex ^= 1U;
+ if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
+ Cached[CacheIndex] = factory.CreateDirectArrayHolder(size, CachedItems[CacheIndex]);
+ items = CachedItems[CacheIndex];
+ return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
+ }
+ }
+
+ items = CachedItems[CacheIndex];
+ std::fill_n(items, size, NUdf::TUnboxedValue());
+ return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
+}
+
} // namespace NMiniKQL
} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_holders.h b/ydb/library/yql/minikql/computation/mkql_computation_node_holders.h
index 3cd4af300c..4486d6f43a 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_holders.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_holders.h
@@ -18,41 +18,41 @@
#include <unordered_map>
#include <unordered_set>
-#ifndef MKQL_DISABLE_CODEGEN
-namespace llvm {
- class Value;
- class BasicBlock;
-}
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+namespace llvm {
+ class Value;
+ class BasicBlock;
+}
+#endif
namespace NKikimr {
namespace NMiniKQL {
class TMemoryUsageInfo;
-#ifndef MKQL_DISABLE_CODEGEN
-struct TCodegenContext;
-#endif
-
-const ui32 CodegenArraysFallbackLimit = 1000u;
-
+#ifndef MKQL_DISABLE_CODEGEN
+struct TCodegenContext;
+#endif
+
+const ui32 CodegenArraysFallbackLimit = 1000u;
+
using TKeyTypes = std::vector<std::pair<NUdf::EDataSlot, bool>>;
-using TUnboxedValueVector = std::vector<NUdf::TUnboxedValue, TMKQLAllocator<NUdf::TUnboxedValue>>;
-using TUnboxedValueDeque = std::deque<NUdf::TUnboxedValue, TMKQLAllocator<NUdf::TUnboxedValue>>;
-using TKeyPayloadPair = std::pair<NUdf::TUnboxedValue, NUdf::TUnboxedValue>;
-using TKeyPayloadPairVector = std::vector<TKeyPayloadPair, TMKQLAllocator<TKeyPayloadPair>>;
+using TUnboxedValueVector = std::vector<NUdf::TUnboxedValue, TMKQLAllocator<NUdf::TUnboxedValue>>;
+using TUnboxedValueDeque = std::deque<NUdf::TUnboxedValue, TMKQLAllocator<NUdf::TUnboxedValue>>;
+using TKeyPayloadPair = std::pair<NUdf::TUnboxedValue, NUdf::TUnboxedValue>;
+using TKeyPayloadPairVector = std::vector<TKeyPayloadPair, TMKQLAllocator<TKeyPayloadPair>>;
inline int CompareValues(NUdf::EDataSlot type,
bool asc, bool isOptional, const NUdf::TUnboxedValuePod& lhs, const NUdf::TUnboxedValuePod& rhs) {
int cmp;
if (isOptional) {
- if (!lhs && !rhs) {
+ if (!lhs && !rhs) {
cmp = 0;
}
- else if (!lhs) {
+ else if (!lhs) {
cmp = -1;
}
- else if (!rhs) {
+ else if (!rhs) {
cmp = 1;
}
else {
@@ -72,21 +72,21 @@ inline int CompareValues(NUdf::EDataSlot type,
inline int CompareKeys(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right, const TKeyTypes& types, bool isTuple) {
if (isTuple) {
- if (left && right)
- for (ui32 i = 0; i < types.size(); ++i) {
- if (const auto cmp = CompareValues(types[i].first, true, types[i].second, left.GetElement(i), right.GetElement(i))) {
- return cmp;
- }
+ if (left && right)
+ for (ui32 i = 0; i < types.size(); ++i) {
+ if (const auto cmp = CompareValues(types[i].first, true, types[i].second, left.GetElement(i), right.GetElement(i))) {
+ return cmp;
+ }
}
- else if (!left && right)
- return -1;
- else if (left && !right)
- return 1;
+ else if (!left && right)
+ return -1;
+ else if (left && !right)
+ return 1;
return 0;
}
else {
- return CompareValues(types.front().first, true, types.front().second, left, right);
+ return CompareValues(types.front().first, true, types.front().second, left, right);
}
}
@@ -96,7 +96,7 @@ struct TKeyPayloadPairLess {
, IsTuple(isTuple)
{}
- bool operator()(const TKeyPayloadPair& left, const TKeyPayloadPair& right) const {
+ bool operator()(const TKeyPayloadPair& left, const TKeyPayloadPair& right) const {
return CompareKeys(left.first, right.first, *Types, IsTuple) < 0;
}
@@ -110,7 +110,7 @@ struct TKeyPayloadPairEqual {
, IsTuple(isTuple)
{}
- bool operator()(const TKeyPayloadPair& left, const TKeyPayloadPair& right) const {
+ bool operator()(const TKeyPayloadPair& left, const TKeyPayloadPair& right) const {
return CompareKeys(left.first, right.first, *Types, IsTuple) == 0;
}
@@ -124,7 +124,7 @@ struct TValueEqual {
, IsTuple(isTuple)
{}
- bool operator()(const NUdf::TUnboxedValue& left, const NUdf::TUnboxedValue& right) const {
+ bool operator()(const NUdf::TUnboxedValue& left, const NUdf::TUnboxedValue& right) const {
return CompareKeys(left, right, *Types, IsTuple) == 0;
}
@@ -132,77 +132,77 @@ struct TValueEqual {
bool IsTuple;
};
-struct TValueLess {
- TValueLess(const TKeyTypes& types, bool isTuple)
- : Types(&types)
- , IsTuple(isTuple)
- {}
-
- bool operator()(const NUdf::TUnboxedValue& left, const NUdf::TUnboxedValue& right) const {
- return CompareKeys(left, right, *Types, IsTuple) < 0;
- }
-
- const TKeyTypes* Types;
- bool IsTuple;
-};
-
-constexpr NUdf::THashType HashOfNull = ~0ULL;
-
+struct TValueLess {
+ TValueLess(const TKeyTypes& types, bool isTuple)
+ : Types(&types)
+ , IsTuple(isTuple)
+ {}
+
+ bool operator()(const NUdf::TUnboxedValue& left, const NUdf::TUnboxedValue& right) const {
+ return CompareKeys(left, right, *Types, IsTuple) < 0;
+ }
+
+ const TKeyTypes* Types;
+ bool IsTuple;
+};
+
+constexpr NUdf::THashType HashOfNull = ~0ULL;
+
struct TValueHasher {
TValueHasher(const TKeyTypes& types, bool isTuple)
: Types(&types)
, IsTuple(isTuple)
{}
- NUdf::THashType operator()(const NUdf::TUnboxedValuePod& value) const {
- if (!value)
- return HashOfNull;
+ NUdf::THashType operator()(const NUdf::TUnboxedValuePod& value) const {
+ if (!value)
+ return HashOfNull;
if (IsTuple) {
- NUdf::THashType hash = 0ULL;
- if (auto elements = value.GetElements())
- for (const auto& type : (*Types)) {
- if (const auto v = *elements++)
- hash = CombineHashes(hash, NUdf::GetValueHash(type.first, v));
- else
- hash = CombineHashes(hash, HashOfNull);
- }
- else
- for (auto i = 0U; i < Types->size(); ++i) {
- if (const auto v = value.GetElement(i))
- hash = CombineHashes(hash, NUdf::GetValueHash((*Types)[i].first, v));
- else
- hash = CombineHashes(hash, HashOfNull);
- }
+ NUdf::THashType hash = 0ULL;
+ if (auto elements = value.GetElements())
+ for (const auto& type : (*Types)) {
+ if (const auto v = *elements++)
+ hash = CombineHashes(hash, NUdf::GetValueHash(type.first, v));
+ else
+ hash = CombineHashes(hash, HashOfNull);
+ }
+ else
+ for (auto i = 0U; i < Types->size(); ++i) {
+ if (const auto v = value.GetElement(i))
+ hash = CombineHashes(hash, NUdf::GetValueHash((*Types)[i].first, v));
+ else
+ hash = CombineHashes(hash, HashOfNull);
+ }
return hash;
}
- return NUdf::GetValueHash((*Types).front().first, value);
+ return NUdf::GetValueHash((*Types).front().first, value);
}
const TKeyTypes* Types;
bool IsTuple;
};
-template<typename T>
-struct TFloatHash : private std::hash<T> {
- std::size_t operator()(T value) const {
- return std::isnan(value) ? ~0ULL : std::hash<T>::operator()(value);
- }
-};
-
-template<typename T>
-struct TFloatEquals {
- bool operator()(T l, T r) const {
- return std::isunordered(l, r) ? std::isnan(l) == std::isnan(r) : l == r;
- }
-};
-
-template <typename T>
-using TMyHash = std::conditional_t<std::is_floating_point<T>::value, TFloatHash<T>, std::hash<T>>;
-
-template <typename T>
-using TMyEquals = std::conditional_t<std::is_floating_point<T>::value, TFloatEquals<T>, std::equal_to<T>>;
-
+template<typename T>
+struct TFloatHash : private std::hash<T> {
+ std::size_t operator()(T value) const {
+ return std::isnan(value) ? ~0ULL : std::hash<T>::operator()(value);
+ }
+};
+
+template<typename T>
+struct TFloatEquals {
+ bool operator()(T l, T r) const {
+ return std::isunordered(l, r) ? std::isnan(l) == std::isnan(r) : l == r;
+ }
+};
+
+template <typename T>
+using TMyHash = std::conditional_t<std::is_floating_point<T>::value, TFloatHash<T>, std::hash<T>>;
+
+template <typename T>
+using TMyEquals = std::conditional_t<std::is_floating_point<T>::value, TFloatEquals<T>, std::equal_to<T>>;
+
constexpr float COMPACT_HASH_MAX_LOAD_FACTOR = 1.2f;
using TValuesDictHashMap = std::unordered_map<
@@ -245,7 +245,7 @@ inline ui64 AddSmallValue(TPagedArena& pool, const TStringBuf& value) {
if (value.size() <= 8) {
ui64 ret = 0;
memcpy((ui8*)&ret, value.data(), value.size());
- Y_VERIFY_DEBUG(IsSmallValueEmbedded(ret));
+ Y_VERIFY_DEBUG(IsSmallValueEmbedded(ret));
return ret;
}
else {
@@ -291,10 +291,10 @@ template <typename T>
using TValuesDictHashSingleFixedMap = std::unordered_map<T, NUdf::TUnboxedValue, NYql::TVaryingHash<T, TMyHash<T>>, TMyEquals<T>,
TMKQLAllocator<std::pair<const T, NUdf::TUnboxedValue>>>;
-using THashedDictFiller = std::function<void(TValuesDictHashMap&)>;
+using THashedDictFiller = std::function<void(TValuesDictHashMap&)>;
using THashedSetFiller = std::function<void(TValuesDictHashSet&)>;
using TSortedDictFiller = std::function<void(TKeyPayloadPairVector&)>;
-using TSortedSetFiller = std::function<void(TUnboxedValueVector&)>;
+using TSortedSetFiller = std::function<void(TUnboxedValueVector&)>;
enum class EDictSortMode {
RequiresSorting,
@@ -307,7 +307,7 @@ public:
TTypeHolder(TMemoryUsageInfo* memInfo, TType* type)
: TComputationValue(memInfo)
, Type(type)
- {}
+ {}
NUdf::TStringRef GetResourceTag() const override {
return NUdf::TStringRef::Of("TypeHolder");
@@ -358,27 +358,27 @@ public:
THolderFactory(
TAllocState& allocState,
TMemoryUsageInfo& memInfo,
- const IFunctionRegistry* functionRegistry = nullptr);
+ const IFunctionRegistry* functionRegistry = nullptr);
template <typename T, typename... TArgs>
- NUdf::TUnboxedValuePod Create(TArgs&&... args) const {
- return NUdf::TUnboxedValuePod(AllocateOn<T>(CurrentAllocState, &MemInfo, std::forward<TArgs>(args)...));
+ NUdf::TUnboxedValuePod Create(TArgs&&... args) const {
+ return NUdf::TUnboxedValuePod(AllocateOn<T>(CurrentAllocState, &MemInfo, std::forward<TArgs>(args)...));
}
- NUdf::TUnboxedValuePod CreateTypeHolder(TType* type) const;
+ NUdf::TUnboxedValuePod CreateTypeHolder(TType* type) const;
- NUdf::TUnboxedValuePod CreateDirectListHolder(TDefaultListRepresentation&& items) const;
+ NUdf::TUnboxedValuePod CreateDirectListHolder(TDefaultListRepresentation&& items) const;
+
+ NUdf::TUnboxedValuePod CreateDirectArrayHolder(ui32 size, NUdf::TUnboxedValue*& itemsPtr) const;
- NUdf::TUnboxedValuePod CreateDirectArrayHolder(ui32 size, NUdf::TUnboxedValue*& itemsPtr) const;
-
NUdf::TFlatDataBlockPtr CreateFlatDataBlock(ui32 initialSize, ui32 initialCapacity) const;
NUdf::TFlatArrayBlockPtr CreateFlatArrayBlock(ui32 count) const;
NUdf::TSingleBlockPtr CreateSingleBlock(const NUdf::TUnboxedValue& value) const;
NUdf::TUnboxedValuePod CreateArrowBlock(arrow::Datum&& datum) const;
- NUdf::TUnboxedValuePod VectorAsArray(TUnboxedValueVector& values) const;
-
+ NUdf::TUnboxedValuePod VectorAsArray(TUnboxedValueVector& values) const;
+
template <class TForwardIterator>
NUdf::TUnboxedValuePod RangeAsArray(TForwardIterator first, TForwardIterator last) const {
auto count = std::distance(first, last);
@@ -395,15 +395,15 @@ public:
return tuple;
}
- NUdf::TUnboxedValuePod CreateDirectSortedSetHolder(
- TSortedSetFiller filler,
- const TKeyTypes& types,
- bool isTuple,
- EDictSortMode mode,
- bool eagerFill,
- TType* encodedType) const;
-
- NUdf::TUnboxedValuePod CreateDirectSortedDictHolder(
+ NUdf::TUnboxedValuePod CreateDirectSortedSetHolder(
+ TSortedSetFiller filler,
+ const TKeyTypes& types,
+ bool isTuple,
+ EDictSortMode mode,
+ bool eagerFill,
+ TType* encodedType) const;
+
+ NUdf::TUnboxedValuePod CreateDirectSortedDictHolder(
TSortedDictFiller filler,
const TKeyTypes& types,
bool isTuple,
@@ -411,14 +411,14 @@ public:
bool eagerFill,
TType* encodedType) const;
- NUdf::TUnboxedValuePod CreateDirectHashedDictHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedDictHolder(
THashedDictFiller filler,
const TKeyTypes& types,
bool isTuple,
bool eagerFill,
TType* encodedType) const;
- NUdf::TUnboxedValuePod CreateDirectHashedSetHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedSetHolder(
THashedSetFiller filler,
const TKeyTypes& types,
bool isTuple,
@@ -426,76 +426,76 @@ public:
TType* encodedType) const;
template <typename T>
- NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedSetHolder(TValuesDictHashSingleFixedSet<T>&& set) const;
+ NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedSetHolder(TValuesDictHashSingleFixedSet<T>&& set) const;
template <typename T>
- NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactSetHolder(TValuesDictHashSingleFixedCompactSet<T>&& set) const;
+ NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactSetHolder(TValuesDictHashSingleFixedCompactSet<T>&& set) const;
template <typename T>
- NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedMapHolder(TValuesDictHashSingleFixedMap<T>&& map) const;
+ NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedMapHolder(TValuesDictHashSingleFixedMap<T>&& map) const;
- NUdf::TUnboxedValuePod CreateDirectHashedCompactSetHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedCompactSetHolder(
TValuesDictHashCompactSet&& set, TPagedArena&& pool, TType* keyType,
TComputationContext* ctx) const;
- NUdf::TUnboxedValuePod CreateDirectHashedCompactMapHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedCompactMapHolder(
TValuesDictHashCompactMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
TComputationContext* ctx) const;
- NUdf::TUnboxedValuePod CreateDirectHashedCompactMultiMapHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedCompactMultiMapHolder(
TValuesDictHashCompactMultiMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
TComputationContext* ctx) const;
template <typename T>
- NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactMapHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactMapHolder(
TValuesDictHashSingleFixedCompactMap<T>&& map, TPagedArena&& pool, TType* payloadType,
TComputationContext* ctx) const;
template <typename T>
- NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactMultiMapHolder(
+ NUdf::TUnboxedValuePod CreateDirectHashedSingleFixedCompactMultiMapHolder(
TValuesDictHashSingleFixedCompactMultiMap<T>&& map, TPagedArena&& pool, TType* payloadType,
TComputationContext* ctx) const;
- NUdf::IDictValueBuilder::TPtr NewDict(
- const NUdf::TType* dictType,
- ui32 flags) const;
-
- NUdf::TUnboxedValuePod Cloned(const NUdf::TUnboxedValuePod& it) const;
- NUdf::TUnboxedValuePod Reversed(const NUdf::TUnboxedValuePod& it) const;
+ NUdf::IDictValueBuilder::TPtr NewDict(
+ const NUdf::TType* dictType,
+ ui32 flags) const;
+
+ NUdf::TUnboxedValuePod Cloned(const NUdf::TUnboxedValuePod& it) const;
+ NUdf::TUnboxedValuePod Reversed(const NUdf::TUnboxedValuePod& it) const;
- NUdf::TUnboxedValuePod CreateLimitedList(
+ NUdf::TUnboxedValuePod CreateLimitedList(
NUdf::IBoxedValuePtr&& parent,
TMaybe<ui64> skip, TMaybe<ui64> take,
TMaybe<ui64> knownLength) const;
- NUdf::TUnboxedValuePod ReverseList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const;
- NUdf::TUnboxedValuePod SkipList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const;
- NUdf::TUnboxedValuePod TakeList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const;
- NUdf::TUnboxedValuePod ToIndexDict(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const;
-
- template<bool IsStream>
- NUdf::TUnboxedValuePod Collect(NUdf::TUnboxedValuePod list) const;
-
- NUdf::TUnboxedValuePod LazyList(NUdf::TUnboxedValuePod list) const;
-
- NUdf::TUnboxedValuePod Append(NUdf::TUnboxedValuePod list, NUdf::TUnboxedValuePod last) const;
- NUdf::TUnboxedValuePod Prepend(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod list) const;
-
- NUdf::TUnboxedValuePod CreateVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const;
- NUdf::TUnboxedValuePod CreateBoxedVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const;
- NUdf::TUnboxedValuePod CreateIteratorOverList(NUdf::TUnboxedValuePod list) const;
- NUdf::TUnboxedValuePod CreateForwardList(NUdf::TUnboxedValuePod stream) const;
-
- NUdf::TUnboxedValuePod CloneArray(const NUdf::TUnboxedValuePod list, NUdf::TUnboxedValue*& itemsPtr) const;
-
+ NUdf::TUnboxedValuePod ReverseList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const;
+ NUdf::TUnboxedValuePod SkipList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const;
+ NUdf::TUnboxedValuePod TakeList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const;
+ NUdf::TUnboxedValuePod ToIndexDict(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const;
+
+ template<bool IsStream>
+ NUdf::TUnboxedValuePod Collect(NUdf::TUnboxedValuePod list) const;
+
+ NUdf::TUnboxedValuePod LazyList(NUdf::TUnboxedValuePod list) const;
+
+ NUdf::TUnboxedValuePod Append(NUdf::TUnboxedValuePod list, NUdf::TUnboxedValuePod last) const;
+ NUdf::TUnboxedValuePod Prepend(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod list) const;
+
+ NUdf::TUnboxedValuePod CreateVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const;
+ NUdf::TUnboxedValuePod CreateBoxedVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const;
+ NUdf::TUnboxedValuePod CreateIteratorOverList(NUdf::TUnboxedValuePod list) const;
+ NUdf::TUnboxedValuePod CreateForwardList(NUdf::TUnboxedValuePod stream) const;
+
+ NUdf::TUnboxedValuePod CloneArray(const NUdf::TUnboxedValuePod list, NUdf::TUnboxedValue*& itemsPtr) const;
+
TMemoryUsageInfo& GetMemInfo() const {
return MemInfo;
}
- NUdf::TUnboxedValuePod GetEmptyContainer() const {
- return static_cast<const NUdf::TUnboxedValuePod&>(EmptyContainer);
- }
-
+ NUdf::TUnboxedValuePod GetEmptyContainer() const {
+ return static_cast<const NUdf::TUnboxedValuePod&>(EmptyContainer);
+ }
+
void CleanupModulesOnTerminate() const {
if (FunctionRegistry) {
FunctionRegistry->CleanupModulesOnTerminate();
@@ -506,62 +506,62 @@ public:
return *CurrentAllocState;
}
- ui64 GetMemoryUsed() const {
- return CurrentAllocState->GetUsed();
- }
-
+ ui64 GetMemoryUsed() const {
+ return CurrentAllocState->GetUsed();
+ }
+
const IFunctionRegistry* GetFunctionRegistry() const {
return FunctionRegistry;
}
- template<bool FromStreams>
- NUdf::TUnboxedValuePod ExtendList(NUdf::TUnboxedValue* data, ui64 size) const;
- NUdf::TUnboxedValuePod ExtendStream(NUdf::TUnboxedValue* data, ui64 size) const;
-
+ template<bool FromStreams>
+ NUdf::TUnboxedValuePod ExtendList(NUdf::TUnboxedValue* data, ui64 size) const;
+ NUdf::TUnboxedValuePod ExtendStream(NUdf::TUnboxedValue* data, ui64 size) const;
+
private:
TAllocState* const CurrentAllocState;
TMemoryUsageInfo& MemInfo;
const IFunctionRegistry* const FunctionRegistry;
- const NUdf::TUnboxedValue EmptyContainer;
+ const NUdf::TUnboxedValue EmptyContainer;
};
-constexpr const ui32 STEP_FOR_RSS_CHECK = 100U;
-
-// Returns true if current usage delta exceeds the memory limit
-// The function automatically adjusts memory limit taking into account RSS delta between calls
-template<bool TrackRss>
-inline bool TComputationContext::CheckAdjustedMemLimit(ui64 memLimit, ui64 initMemUsage) {
- if (!memLimit) {
- return false;
- }
-
- if (TrackRss && (RssCounter++ % STEP_FOR_RSS_CHECK == 0)) {
- UpdateUsageAdjustor(memLimit);
- }
- const auto currentMemUsage = HolderFactory.GetMemoryUsed();
- return currentMemUsage * UsageAdjustor >= initMemUsage + memLimit;
-}
-
+constexpr const ui32 STEP_FOR_RSS_CHECK = 100U;
+
+// Returns true if current usage delta exceeds the memory limit
+// The function automatically adjusts memory limit taking into account RSS delta between calls
+template<bool TrackRss>
+inline bool TComputationContext::CheckAdjustedMemLimit(ui64 memLimit, ui64 initMemUsage) {
+ if (!memLimit) {
+ return false;
+ }
+
+ if (TrackRss && (RssCounter++ % STEP_FOR_RSS_CHECK == 0)) {
+ UpdateUsageAdjustor(memLimit);
+ }
+ const auto currentMemUsage = HolderFactory.GetMemoryUsed();
+ return currentMemUsage * UsageAdjustor >= initMemUsage + memLimit;
+}
+
//////////////////////////////////////////////////////////////////////////////
// TNodeFactory
//////////////////////////////////////////////////////////////////////////////
class TNodeFactory: private TNonCopyable
{
public:
- TNodeFactory(TMemoryUsageInfo& memInfo, TComputationMutables& mutables);
+ TNodeFactory(TMemoryUsageInfo& memInfo, TComputationMutables& mutables);
+
+ IComputationNode* CreateTypeNode(TType* type) const;
- IComputationNode* CreateTypeNode(TType* type) const;
+ IComputationNode* CreateImmutableNode(NUdf::TUnboxedValue&& value) const;
- IComputationNode* CreateImmutableNode(NUdf::TUnboxedValue&& value) const;
+ IComputationNode* CreateEmptyNode() const;
- IComputationNode* CreateEmptyNode() const;
+ IComputationNode* CreateArrayNode(TComputationNodePtrVector&& items) const;
- IComputationNode* CreateArrayNode(TComputationNodePtrVector&& items) const;
-
IComputationNode* CreateOptionalNode(IComputationNode* item) const;
IComputationNode* CreateDictNode(
- std::vector<std::pair<IComputationNode*, IComputationNode*>>&& items,
+ std::vector<std::pair<IComputationNode*, IComputationNode*>>&& items,
const TKeyTypes& types, bool isTuple, TType* encodedType) const;
IComputationNode* CreateVariantNode(IComputationNode* item, ui32 index) const;
@@ -573,31 +573,31 @@ private:
void GetDictionaryKeyTypes(TType* keyType, TKeyTypes& types, bool& isTuple, bool& encoded);
-struct TContainerCacheOnContext : private TNonCopyable {
- TContainerCacheOnContext(TComputationMutables& mutables);
-
- NUdf::TUnboxedValuePod NewArray(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue*& items) const;
-#ifndef MKQL_DISABLE_CODEGEN
- llvm::Value* GenNewArray(ui32 sz, llvm::Value* items, const TCodegenContext& ctx, llvm::BasicBlock*& block) const;
-#endif
- const ui32 Index;
-};
-
+struct TContainerCacheOnContext : private TNonCopyable {
+ TContainerCacheOnContext(TComputationMutables& mutables);
+
+ NUdf::TUnboxedValuePod NewArray(TComputationContext& ctx, ui32 size, NUdf::TUnboxedValue*& items) const;
+#ifndef MKQL_DISABLE_CODEGEN
+ llvm::Value* GenNewArray(ui32 sz, llvm::Value* items, const TCodegenContext& ctx, llvm::BasicBlock*& block) const;
+#endif
+ const ui32 Index;
+};
+
class TPlainContainerCache {
public:
- TPlainContainerCache();
+ TPlainContainerCache();
TPlainContainerCache(const TPlainContainerCache&) = delete;
TPlainContainerCache& operator=(const TPlainContainerCache&) = delete;
- void Clear();
+ void Clear();
- NUdf::TUnboxedValuePod NewArray(const THolderFactory& factory, ui32 size, NUdf::TUnboxedValue*& items);
+ NUdf::TUnboxedValuePod NewArray(const THolderFactory& factory, ui32 size, NUdf::TUnboxedValue*& items);
private:
std::array<NUdf::TUnboxedValue, 2> Cached;
std::array<NUdf::TUnboxedValue*, 2> CachedItems;
- ui8 CacheIndex = 0U;
+ ui8 CacheIndex = 0U;
};
template<class TObject>
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_impl.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_impl.cpp
index a0e9266b10..15777c3288 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_impl.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_impl.cpp
@@ -1,42 +1,42 @@
-#include "mkql_computation_node_impl.h"
+#include "mkql_computation_node_impl.h"
#include "ydb/library/yql/minikql/mkql_string_util.h"
namespace NKikimr {
namespace NMiniKQL {
-template <class IComputationNodeInterface>
-void TRefCountedComputationNode<IComputationNodeInterface>::Ref() {
- ++Refs_;
-}
+template <class IComputationNodeInterface>
+void TRefCountedComputationNode<IComputationNodeInterface>::Ref() {
+ ++Refs_;
+}
-template <class IComputationNodeInterface>
-void TRefCountedComputationNode<IComputationNodeInterface>::UnRef() {
- Y_VERIFY(Refs_ > 0);
- if (--Refs_ == 0) {
- delete this;
+template <class IComputationNodeInterface>
+void TRefCountedComputationNode<IComputationNodeInterface>::UnRef() {
+ Y_VERIFY(Refs_ > 0);
+ if (--Refs_ == 0) {
+ delete this;
}
-}
-
-template <class IComputationNodeInterface>
-ui32 TRefCountedComputationNode<IComputationNodeInterface>::RefCount() const {
- return Refs_;
-}
-
-template class TRefCountedComputationNode<IComputationWideFlowNode>;
-template class TRefCountedComputationNode<IComputationWideFlowProxyNode>;
-
-TUnboxedImmutableComputationNode::TUnboxedImmutableComputationNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
- : MemInfo(memInfo)
- , UnboxedValue(std::move(value))
- , RepresentationKind(UnboxedValue.HasValue() ? (UnboxedValue.IsBoxed() ? EValueRepresentation::Boxed : (UnboxedValue.IsString() ? EValueRepresentation::String : EValueRepresentation::Embedded)) : EValueRepresentation::Embedded)
+}
+
+template <class IComputationNodeInterface>
+ui32 TRefCountedComputationNode<IComputationNodeInterface>::RefCount() const {
+ return Refs_;
+}
+
+template class TRefCountedComputationNode<IComputationWideFlowNode>;
+template class TRefCountedComputationNode<IComputationWideFlowProxyNode>;
+
+TUnboxedImmutableComputationNode::TUnboxedImmutableComputationNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
+ : MemInfo(memInfo)
+ , UnboxedValue(std::move(value))
+ , RepresentationKind(UnboxedValue.HasValue() ? (UnboxedValue.IsBoxed() ? EValueRepresentation::Boxed : (UnboxedValue.IsString() ? EValueRepresentation::String : EValueRepresentation::Embedded)) : EValueRepresentation::Embedded)
{
- MKQL_MEM_TAKE(MemInfo, this, sizeof(*this), "TOwnerType: " << DebugString());
-}
+ MKQL_MEM_TAKE(MemInfo, this, sizeof(*this), "TOwnerType: " << DebugString());
+}
-TUnboxedImmutableComputationNode::~TUnboxedImmutableComputationNode() {
- MKQL_MEM_RETURN(MemInfo, this, sizeof(*this));
-}
+TUnboxedImmutableComputationNode::~TUnboxedImmutableComputationNode() {
+ MKQL_MEM_RETURN(MemInfo, this, sizeof(*this));
+}
NUdf::TUnboxedValue TUnboxedImmutableComputationNode::GetValue(TComputationContext& compCtx) const {
Y_UNUSED(compCtx);
@@ -44,47 +44,47 @@ NUdf::TUnboxedValue TUnboxedImmutableComputationNode::GetValue(TComputationConte
/// TODO: YQL-4461
return MakeString(UnboxedValue.AsStringRef());
}
- return UnboxedValue;
-}
-
-const IComputationNode* TUnboxedImmutableComputationNode::GetSource() const { return nullptr; }
-
-IComputationNode* TUnboxedImmutableComputationNode::AddDependence(const IComputationNode*) { return nullptr; }
-
-void TUnboxedImmutableComputationNode::RegisterDependencies() const {}
-
-ui32 TUnboxedImmutableComputationNode::GetIndex() const {
- THROW yexception() << "Failed to get index.";
-}
-
-void TUnboxedImmutableComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const {
- THROW yexception() << "Failed to collect dependent indexes.";
-}
-
-ui32 TUnboxedImmutableComputationNode::GetDependencyWeight() const {
- THROW yexception() << "Can't get dependency weight from const node.";
-}
-
-ui32 TUnboxedImmutableComputationNode::GetDependencesCount() const {
- THROW yexception() << "Can't get dependences count from const node.";
-}
-
-bool TUnboxedImmutableComputationNode::IsTemporaryValue() const { return false; }
-
-void TUnboxedImmutableComputationNode::PrepareStageOne() {}
-void TUnboxedImmutableComputationNode::PrepareStageTwo() {}
-
-TString TUnboxedImmutableComputationNode::DebugString() const {
- return UnboxedValue ? (UnboxedValue.IsBoxed() ? "Boxed" : "Literal") : "Empty";
-}
-
-EValueRepresentation TUnboxedImmutableComputationNode::GetRepresentation() const {
- return RepresentationKind;
-}
-
+ return UnboxedValue;
+}
+
+const IComputationNode* TUnboxedImmutableComputationNode::GetSource() const { return nullptr; }
+
+IComputationNode* TUnboxedImmutableComputationNode::AddDependence(const IComputationNode*) { return nullptr; }
+
+void TUnboxedImmutableComputationNode::RegisterDependencies() const {}
+
+ui32 TUnboxedImmutableComputationNode::GetIndex() const {
+ THROW yexception() << "Failed to get index.";
+}
+
+void TUnboxedImmutableComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const {
+ THROW yexception() << "Failed to collect dependent indexes.";
+}
+
+ui32 TUnboxedImmutableComputationNode::GetDependencyWeight() const {
+ THROW yexception() << "Can't get dependency weight from const node.";
+}
+
+ui32 TUnboxedImmutableComputationNode::GetDependencesCount() const {
+ THROW yexception() << "Can't get dependences count from const node.";
+}
+
+bool TUnboxedImmutableComputationNode::IsTemporaryValue() const { return false; }
+
+void TUnboxedImmutableComputationNode::PrepareStageOne() {}
+void TUnboxedImmutableComputationNode::PrepareStageTwo() {}
+
+TString TUnboxedImmutableComputationNode::DebugString() const {
+ return UnboxedValue ? (UnboxedValue.IsBoxed() ? "Boxed" : "Literal") : "Empty";
+}
+
+EValueRepresentation TUnboxedImmutableComputationNode::GetRepresentation() const {
+ return RepresentationKind;
+}
+
template <class IComputationNodeInterface, bool SerializableState>
TStatefulComputationNode<IComputationNodeInterface, SerializableState>::TStatefulComputationNode(TComputationMutables& mutables, EValueRepresentation kind)
- : ValueIndex(mutables.CurValueIndex++), RepresentationKind(kind)
+ : ValueIndex(mutables.CurValueIndex++), RepresentationKind(kind)
{
if constexpr (SerializableState) {
mutables.SerializableValues.push_back(ValueIndex);
@@ -93,236 +93,236 @@ TStatefulComputationNode<IComputationNodeInterface, SerializableState>::TStatefu
template <class IComputationNodeInterface, bool SerializableState>
IComputationNode* TStatefulComputationNode<IComputationNodeInterface, SerializableState>::AddDependence(const IComputationNode* node) {
- Dependencies.emplace_back(node);
- return this;
-}
+ Dependencies.emplace_back(node);
+ return this;
+}
template <class IComputationNodeInterface, bool SerializableState>
EValueRepresentation TStatefulComputationNode<IComputationNodeInterface, SerializableState>::GetRepresentation() const {
- return RepresentationKind;
-}
-
+ return RepresentationKind;
+}
+
template <class IComputationNodeInterface, bool SerializableState>
ui32 TStatefulComputationNode<IComputationNodeInterface, SerializableState>::GetIndex() const { return ValueIndex; }
-
+
template <class IComputationNodeInterface, bool SerializableState>
ui32 TStatefulComputationNode<IComputationNodeInterface, SerializableState>::GetDependencesCount() const { return Dependencies.size(); }
-
+
template class TStatefulComputationNode<IComputationNode, false>;
template class TStatefulComputationNode<IComputationExternalNode, false>;
template class TStatefulComputationNode<IComputationNode, true>;
template class TStatefulComputationNode<IComputationExternalNode, true>;
-
-void TExternalComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap& map) const {
- map.emplace(ValueIndex, RepresentationKind);
-}
-
-TExternalComputationNode::TExternalComputationNode(TComputationMutables& mutables, EValueRepresentation kind)
- : TStatefulComputationNode(mutables, kind)
-{}
-
-NUdf::TUnboxedValue TExternalComputationNode::GetValue(TComputationContext& ctx) const {
- return Getter ? Getter(ctx) : ValueRef(ctx);
-}
-
-NUdf::TUnboxedValue& TExternalComputationNode::RefValue(TComputationContext& ctx) const {
- InvalidateValue(ctx);
- return ValueRef(ctx);
-}
-
-void TExternalComputationNode::SetValue(TComputationContext& ctx, NUdf::TUnboxedValue&& value) const {
- ValueRef(ctx) = std::move(value);
- InvalidateValue(ctx);
-}
-
-TString TExternalComputationNode::DebugString() const {
- return "External";
-}
-
-void TExternalComputationNode::RegisterDependencies() const {}
-
-void TExternalComputationNode::SetOwner(const IComputationNode* owner) {
- Y_VERIFY_DEBUG(!Owner);
- Owner = owner;
-}
-
-void TExternalComputationNode::PrepareStageOne() {
- std::sort(Dependencies.begin(), Dependencies.end());
- Dependencies.erase(std::unique(Dependencies.begin(), Dependencies.end()), Dependencies.cend());
- if (const auto it = std::find(Dependencies.cbegin(), Dependencies.cend(), Owner); Dependencies.cend() != it)
- Dependencies.erase(it);
-}
-
-void TExternalComputationNode::PrepareStageTwo() {
- TIndexesMap dependencies;
- std::for_each(Dependencies.cbegin(), Dependencies.cend(),
- std::bind(&IComputationNode::CollectDependentIndexes, std::placeholders::_1, Owner, std::ref(dependencies)));
- InvalidationSet.assign(dependencies.cbegin(), dependencies.cend());
-}
-
-const IComputationNode* TExternalComputationNode::GetSource() const { return nullptr; }
-
-ui32 TExternalComputationNode::GetDependencyWeight() const { return 0U; }
-
-bool TExternalComputationNode::IsTemporaryValue() const {
- return bool(Getter);
-}
-
-void TExternalComputationNode::SetGetter(TGetter&& getter) {
- Getter = std::move(getter);
-}
-
-void TExternalComputationNode::InvalidateValue(TComputationContext& ctx) const {
- for (const auto index : InvalidationSet) {
- ctx.MutableValues[index.first] = NUdf::TUnboxedValuePod::Invalid();
- }
-}
-
-TString TWideFlowProxyComputationNode::DebugString() const { return "WideFlowArg"; }
-
-EValueRepresentation TWideFlowProxyComputationNode::GetRepresentation() const {
- THROW yexception() << "Failed to get representation kind.";
-}
-
-NUdf::TUnboxedValue TWideFlowProxyComputationNode::GetValue(TComputationContext&) const {
- THROW yexception() << "Failed to get value from wide flow node.";
-}
-
-ui32 TWideFlowProxyComputationNode::GetIndex() const {
- THROW yexception() << "Failed to get proxy node index.";
-}
-
-ui32 TWideFlowProxyComputationNode::GetDependencyWeight() const {
- THROW yexception() << "Failed to get dependency weight.";
-}
-
-ui32 TWideFlowProxyComputationNode::GetDependencesCount() const {
- return Dependence ? 1U : 0U;
-}
-
-IComputationNode* TWideFlowProxyComputationNode::AddDependence(const IComputationNode* node) {
- Y_VERIFY_DEBUG(!Dependence);
- Dependence = node;
- return this;
-}
-
-const IComputationNode* TWideFlowProxyComputationNode::GetSource() const { return nullptr; }
-
-bool TWideFlowProxyComputationNode::IsTemporaryValue() const { return true; }
-
-void TWideFlowProxyComputationNode::RegisterDependencies() const {}
-
-void TWideFlowProxyComputationNode::PrepareStageOne() {}
-
-void TWideFlowProxyComputationNode::PrepareStageTwo() {
- if (Dependence) {
- TIndexesMap dependencies;
- Dependence->CollectDependentIndexes(Owner, dependencies);
- InvalidationSet.assign(dependencies.cbegin(), dependencies.cend());
- }
-}
-
-void TWideFlowProxyComputationNode::SetOwner(const IComputationNode* owner) {
- Y_VERIFY_DEBUG(!Owner);
- Owner = owner;
-}
-
-void TWideFlowProxyComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const {
- THROW yexception() << "Failed to collect dependent indexes.";
-}
-
-void TWideFlowProxyComputationNode::InvalidateValue(TComputationContext& ctx) const {
- for (const auto index : InvalidationSet) {
- ctx.MutableValues[index.first] = NUdf::TUnboxedValuePod::Invalid();
- }
-}
-
-void TWideFlowProxyComputationNode::SetFetcher(TFetcher&& fetcher) {
- Fetcher = std::move(fetcher);
-}
-
-EFetchResult TWideFlowProxyComputationNode::FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* values) const {
- return Fetcher(ctx, values);
-}
-
-IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop) {
- return nodeLocator(callable.GetInput(index).GetNode(), pop);
-}
-
-IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TNode& node, bool pop) {
- return nodeLocator(&node, pop);
-}
-
-IComputationExternalNode* LocateExternalNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop) {
- return dynamic_cast<IComputationExternalNode*>(LocateNode(nodeLocator, callable, index, pop));
-}
-
-TPasstroughtMap GetPasstroughtMap(const TComputationExternalNodePtrVector& args, const TComputationNodePtrVector& roots) {
- TPasstroughtMap map(args.size());
- for (size_t i = 0U; i < map.size(); ++i) {
- for (size_t j = 0U; j < roots.size(); ++j) {
- if (args[i] == roots[j]) {
- map[i].emplace(j);
- break;
- }
- }
- }
- return map;
-}
-
-TPasstroughtMap GetPasstroughtMap(const TComputationNodePtrVector& roots, const TComputationExternalNodePtrVector& args) {
- TPasstroughtMap map(roots.size());
- for (size_t i = 0U; i < map.size(); ++i) {
- for (size_t j = 0U; j < args.size(); ++j) {
- if (roots[i] == args[j]) {
- map[i].emplace(j);
- break;
- }
- }
- }
- return map;
-}
-
-std::optional<size_t> IsPasstrought(const IComputationNode* root, const TComputationExternalNodePtrVector& args) {
- for (size_t i = 0U; i < args.size(); ++i)
- if (root == args[i])
- return {i};
- return std::nullopt;
-}
-
-TPasstroughtMap MergePasstroughtMaps(const TPasstroughtMap& lhs, const TPasstroughtMap& rhs) {
- TPasstroughtMap map(std::min(lhs.size(), rhs.size()));
- auto i = 0U;
- for (auto& item : map) {
- if (const auto l = lhs[i], r = rhs[i]; l && r && *l == *r) {
- item.emplace(*l);
- }
- ++i;
- }
- return map;
-}
-
-void ApplyChanges(const NUdf::TUnboxedValue& list, NUdf::IApplyContext& applyCtx) {
- TThresher<false>::DoForEachItem(list,
- [&applyCtx] (const NUdf::TUnboxedValue& item) {
- if (item.IsBoxed())
- item.Apply(applyCtx);
- }
- );
-}
-
-const IComputationNode* GetCommonSource(const IComputationNode* first, const IComputationNode* second, const IComputationNode* common) {
- const auto f = first->GetSource();
- const auto s = second->GetSource();
- if (f && s) {
- return f == s ? f : common;
- } else if (f) {
- return f;
- } else if (s) {
- return s;
- }
- return common;
-}
-
-}
-}
+
+void TExternalComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap& map) const {
+ map.emplace(ValueIndex, RepresentationKind);
+}
+
+TExternalComputationNode::TExternalComputationNode(TComputationMutables& mutables, EValueRepresentation kind)
+ : TStatefulComputationNode(mutables, kind)
+{}
+
+NUdf::TUnboxedValue TExternalComputationNode::GetValue(TComputationContext& ctx) const {
+ return Getter ? Getter(ctx) : ValueRef(ctx);
+}
+
+NUdf::TUnboxedValue& TExternalComputationNode::RefValue(TComputationContext& ctx) const {
+ InvalidateValue(ctx);
+ return ValueRef(ctx);
+}
+
+void TExternalComputationNode::SetValue(TComputationContext& ctx, NUdf::TUnboxedValue&& value) const {
+ ValueRef(ctx) = std::move(value);
+ InvalidateValue(ctx);
+}
+
+TString TExternalComputationNode::DebugString() const {
+ return "External";
+}
+
+void TExternalComputationNode::RegisterDependencies() const {}
+
+void TExternalComputationNode::SetOwner(const IComputationNode* owner) {
+ Y_VERIFY_DEBUG(!Owner);
+ Owner = owner;
+}
+
+void TExternalComputationNode::PrepareStageOne() {
+ std::sort(Dependencies.begin(), Dependencies.end());
+ Dependencies.erase(std::unique(Dependencies.begin(), Dependencies.end()), Dependencies.cend());
+ if (const auto it = std::find(Dependencies.cbegin(), Dependencies.cend(), Owner); Dependencies.cend() != it)
+ Dependencies.erase(it);
+}
+
+void TExternalComputationNode::PrepareStageTwo() {
+ TIndexesMap dependencies;
+ std::for_each(Dependencies.cbegin(), Dependencies.cend(),
+ std::bind(&IComputationNode::CollectDependentIndexes, std::placeholders::_1, Owner, std::ref(dependencies)));
+ InvalidationSet.assign(dependencies.cbegin(), dependencies.cend());
+}
+
+const IComputationNode* TExternalComputationNode::GetSource() const { return nullptr; }
+
+ui32 TExternalComputationNode::GetDependencyWeight() const { return 0U; }
+
+bool TExternalComputationNode::IsTemporaryValue() const {
+ return bool(Getter);
+}
+
+void TExternalComputationNode::SetGetter(TGetter&& getter) {
+ Getter = std::move(getter);
+}
+
+void TExternalComputationNode::InvalidateValue(TComputationContext& ctx) const {
+ for (const auto index : InvalidationSet) {
+ ctx.MutableValues[index.first] = NUdf::TUnboxedValuePod::Invalid();
+ }
+}
+
+TString TWideFlowProxyComputationNode::DebugString() const { return "WideFlowArg"; }
+
+EValueRepresentation TWideFlowProxyComputationNode::GetRepresentation() const {
+ THROW yexception() << "Failed to get representation kind.";
+}
+
+NUdf::TUnboxedValue TWideFlowProxyComputationNode::GetValue(TComputationContext&) const {
+ THROW yexception() << "Failed to get value from wide flow node.";
+}
+
+ui32 TWideFlowProxyComputationNode::GetIndex() const {
+ THROW yexception() << "Failed to get proxy node index.";
+}
+
+ui32 TWideFlowProxyComputationNode::GetDependencyWeight() const {
+ THROW yexception() << "Failed to get dependency weight.";
+}
+
+ui32 TWideFlowProxyComputationNode::GetDependencesCount() const {
+ return Dependence ? 1U : 0U;
+}
+
+IComputationNode* TWideFlowProxyComputationNode::AddDependence(const IComputationNode* node) {
+ Y_VERIFY_DEBUG(!Dependence);
+ Dependence = node;
+ return this;
+}
+
+const IComputationNode* TWideFlowProxyComputationNode::GetSource() const { return nullptr; }
+
+bool TWideFlowProxyComputationNode::IsTemporaryValue() const { return true; }
+
+void TWideFlowProxyComputationNode::RegisterDependencies() const {}
+
+void TWideFlowProxyComputationNode::PrepareStageOne() {}
+
+void TWideFlowProxyComputationNode::PrepareStageTwo() {
+ if (Dependence) {
+ TIndexesMap dependencies;
+ Dependence->CollectDependentIndexes(Owner, dependencies);
+ InvalidationSet.assign(dependencies.cbegin(), dependencies.cend());
+ }
+}
+
+void TWideFlowProxyComputationNode::SetOwner(const IComputationNode* owner) {
+ Y_VERIFY_DEBUG(!Owner);
+ Owner = owner;
+}
+
+void TWideFlowProxyComputationNode::CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const {
+ THROW yexception() << "Failed to collect dependent indexes.";
+}
+
+void TWideFlowProxyComputationNode::InvalidateValue(TComputationContext& ctx) const {
+ for (const auto index : InvalidationSet) {
+ ctx.MutableValues[index.first] = NUdf::TUnboxedValuePod::Invalid();
+ }
+}
+
+void TWideFlowProxyComputationNode::SetFetcher(TFetcher&& fetcher) {
+ Fetcher = std::move(fetcher);
+}
+
+EFetchResult TWideFlowProxyComputationNode::FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* values) const {
+ return Fetcher(ctx, values);
+}
+
+IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop) {
+ return nodeLocator(callable.GetInput(index).GetNode(), pop);
+}
+
+IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TNode& node, bool pop) {
+ return nodeLocator(&node, pop);
+}
+
+IComputationExternalNode* LocateExternalNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop) {
+ return dynamic_cast<IComputationExternalNode*>(LocateNode(nodeLocator, callable, index, pop));
+}
+
+TPasstroughtMap GetPasstroughtMap(const TComputationExternalNodePtrVector& args, const TComputationNodePtrVector& roots) {
+ TPasstroughtMap map(args.size());
+ for (size_t i = 0U; i < map.size(); ++i) {
+ for (size_t j = 0U; j < roots.size(); ++j) {
+ if (args[i] == roots[j]) {
+ map[i].emplace(j);
+ break;
+ }
+ }
+ }
+ return map;
+}
+
+TPasstroughtMap GetPasstroughtMap(const TComputationNodePtrVector& roots, const TComputationExternalNodePtrVector& args) {
+ TPasstroughtMap map(roots.size());
+ for (size_t i = 0U; i < map.size(); ++i) {
+ for (size_t j = 0U; j < args.size(); ++j) {
+ if (roots[i] == args[j]) {
+ map[i].emplace(j);
+ break;
+ }
+ }
+ }
+ return map;
+}
+
+std::optional<size_t> IsPasstrought(const IComputationNode* root, const TComputationExternalNodePtrVector& args) {
+ for (size_t i = 0U; i < args.size(); ++i)
+ if (root == args[i])
+ return {i};
+ return std::nullopt;
+}
+
+TPasstroughtMap MergePasstroughtMaps(const TPasstroughtMap& lhs, const TPasstroughtMap& rhs) {
+ TPasstroughtMap map(std::min(lhs.size(), rhs.size()));
+ auto i = 0U;
+ for (auto& item : map) {
+ if (const auto l = lhs[i], r = rhs[i]; l && r && *l == *r) {
+ item.emplace(*l);
+ }
+ ++i;
+ }
+ return map;
+}
+
+void ApplyChanges(const NUdf::TUnboxedValue& list, NUdf::IApplyContext& applyCtx) {
+ TThresher<false>::DoForEachItem(list,
+ [&applyCtx] (const NUdf::TUnboxedValue& item) {
+ if (item.IsBoxed())
+ item.Apply(applyCtx);
+ }
+ );
+}
+
+const IComputationNode* GetCommonSource(const IComputationNode* first, const IComputationNode* second, const IComputationNode* common) {
+ const auto f = first->GetSource();
+ const auto s = second->GetSource();
+ if (f && s) {
+ return f == s ? f : common;
+ } else if (f) {
+ return f;
+ } else if (s) {
+ return s;
+ }
+ return common;
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_impl.h b/ydb/library/yql/minikql/computation/mkql_computation_node_impl.h
index 5894339683..0a63ca9d34 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_impl.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_impl.h
@@ -21,190 +21,190 @@ enum class EContainerOptMode {
OptAdd
};
-template <class IComputationNodeInterface>
-class TRefCountedComputationNode : public IComputationNodeInterface {
-private:
- void Ref() final;
+template <class IComputationNodeInterface>
+class TRefCountedComputationNode : public IComputationNodeInterface {
+private:
+ void Ref() final;
- void UnRef() final;
+ void UnRef() final;
- ui32 RefCount() const final;
+ ui32 RefCount() const final;
private:
ui32 Refs_ = 0;
};
-class TUnboxedImmutableComputationNode: public TRefCountedComputationNode<IComputationNode>
+class TUnboxedImmutableComputationNode: public TRefCountedComputationNode<IComputationNode>
{
public:
- TUnboxedImmutableComputationNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value);
+ TUnboxedImmutableComputationNode(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value);
- ~TUnboxedImmutableComputationNode();
+ ~TUnboxedImmutableComputationNode();
-private:
+private:
void InitNode(TComputationContext&) const override {}
NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final;
- const IComputationNode* GetSource() const final;
-
- IComputationNode* AddDependence(const IComputationNode*) final;
-
- void RegisterDependencies() const final;
-
- ui32 GetIndex() const final;
-
- void CollectDependentIndexes(const IComputationNode* owner, TIndexesMap&) const final;
-
- ui32 GetDependencyWeight() const final;
-
- ui32 GetDependencesCount() const final;
-
- bool IsTemporaryValue() const final;
-
- void PrepareStageOne() final;
- void PrepareStageTwo() final;
-
- TString DebugString() const final;
-
- EValueRepresentation GetRepresentation() const final;
-
- TMemoryUsageInfo *const MemInfo;
-protected:
- const NUdf::TUnboxedValue UnboxedValue;
- const EValueRepresentation RepresentationKind;
+ const IComputationNode* GetSource() const final;
+
+ IComputationNode* AddDependence(const IComputationNode*) final;
+
+ void RegisterDependencies() const final;
+
+ ui32 GetIndex() const final;
+
+ void CollectDependentIndexes(const IComputationNode* owner, TIndexesMap&) const final;
+
+ ui32 GetDependencyWeight() const final;
+
+ ui32 GetDependencesCount() const final;
+
+ bool IsTemporaryValue() const final;
+
+ void PrepareStageOne() final;
+ void PrepareStageTwo() final;
+
+ TString DebugString() const final;
+
+ EValueRepresentation GetRepresentation() const final;
+
+ TMemoryUsageInfo *const MemInfo;
+protected:
+ const NUdf::TUnboxedValue UnboxedValue;
+ const EValueRepresentation RepresentationKind;
};
template <class IComputationNodeInterface, bool SerializableState = false>
-class TStatefulComputationNode: public TRefCountedComputationNode<IComputationNodeInterface>
-{
-protected:
- TStatefulComputationNode(TComputationMutables& mutables, EValueRepresentation kind);
-
+class TStatefulComputationNode: public TRefCountedComputationNode<IComputationNodeInterface>
+{
+protected:
+ TStatefulComputationNode(TComputationMutables& mutables, EValueRepresentation kind);
+
protected:
void InitNode(TComputationContext&) const override {}
- IComputationNode* AddDependence(const IComputationNode* node) final;
-
- EValueRepresentation GetRepresentation() const override;
-
+ IComputationNode* AddDependence(const IComputationNode* node) final;
+
+ EValueRepresentation GetRepresentation() const override;
+
NUdf::TUnboxedValue& ValueRef(TComputationContext& compCtx) const {
return compCtx.MutableValues[ValueIndex];
}
- ui32 GetIndex() const final;
-
+ ui32 GetIndex() const final;
+
TConstComputationNodePtrVector Dependencies;
const ui32 ValueIndex;
- const EValueRepresentation RepresentationKind;
-private:
- ui32 GetDependencesCount() const final;
-};
-
-class TExternalComputationNode: public TStatefulComputationNode<IComputationExternalNode>
+ const EValueRepresentation RepresentationKind;
+private:
+ ui32 GetDependencesCount() const final;
+};
+
+class TExternalComputationNode: public TStatefulComputationNode<IComputationExternalNode>
{
public:
- TExternalComputationNode(TComputationMutables& mutables, EValueRepresentation kind = EValueRepresentation::Any);
+ TExternalComputationNode(TComputationMutables& mutables, EValueRepresentation kind = EValueRepresentation::Any);
-protected:
+protected:
NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const override;
- NUdf::TUnboxedValue& RefValue(TComputationContext& compCtx) const override;
+ NUdf::TUnboxedValue& RefValue(TComputationContext& compCtx) const override;
void SetValue(TComputationContext& compCtx, NUdf::TUnboxedValue&& value) const override;
- TString DebugString() const final;
-private:
- ui32 GetDependencyWeight() const final;
-
- void RegisterDependencies() const final;
-
- void SetOwner(const IComputationNode* owner) final;
-
- void PrepareStageOne() final;
- void PrepareStageTwo() final;
-
+ TString DebugString() const final;
+private:
+ ui32 GetDependencyWeight() const final;
+
+ void RegisterDependencies() const final;
+
+ void SetOwner(const IComputationNode* owner) final;
+
+ void PrepareStageOne() final;
+ void PrepareStageTwo() final;
+
void CollectDependentIndexes(const IComputationNode* owner, TIndexesMap& dependencies) const final;
-
- bool IsTemporaryValue() const final;
-
- const IComputationNode* Owner = nullptr;
-
- void SetGetter(TGetter&& getter) final;
-
- void InvalidateValue(TComputationContext& compCtx) const final;
-
- const IComputationNode* GetSource() const final;
-protected:
- std::vector<std::pair<ui32, EValueRepresentation>> InvalidationSet;
- TGetter Getter;
+
+ bool IsTemporaryValue() const final;
+
+ const IComputationNode* Owner = nullptr;
+
+ void SetGetter(TGetter&& getter) final;
+
+ void InvalidateValue(TComputationContext& compCtx) const final;
+
+ const IComputationNode* GetSource() const final;
+protected:
+ std::vector<std::pair<ui32, EValueRepresentation>> InvalidationSet;
+ TGetter Getter;
};
template <typename TDerived, bool SerializableState = false>
class TStatefulSourceComputationNode: public TStatefulComputationNode<IComputationNode, SerializableState>
{
using TStatefulComputationNode = TStatefulComputationNode<IComputationNode, SerializableState>;
-private:
- bool IsTemporaryValue() const final {
- return *Stateless;
- }
-
- ui32 GetDependencyWeight() const final {
- return Sources.size();
- }
-
- void PrepareStageOne() final {
+private:
+ bool IsTemporaryValue() const final {
+ return *Stateless;
+ }
+
+ ui32 GetDependencyWeight() const final {
+ return Sources.size();
+ }
+
+ void PrepareStageOne() final {
if (!Stateless) {
Stateless = std::accumulate(this->Dependencies.cbegin(), this->Dependencies.cend(), 0,
- std::bind(std::plus<i32>(), std::placeholders::_1, std::bind(&IComputationNode::GetDependencyWeight, std::placeholders::_2))) <= 1;
+ std::bind(std::plus<i32>(), std::placeholders::_1, std::bind(&IComputationNode::GetDependencyWeight, std::placeholders::_2))) <= 1;
}
- }
-
- void PrepareStageTwo() final {}
-
+ }
+
+ void PrepareStageTwo() final {}
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
if (const auto ins = dependencies.emplace(this->ValueIndex, this->RepresentationKind); ins.second) {
std::for_each(this->Dependencies.cbegin(), this->Dependencies.cend(), std::bind(&IComputationNode::CollectDependentIndexes, std::placeholders::_1, owner, std::ref(dependencies)));
-
- if (*Stateless) {
+
+ if (*Stateless) {
dependencies.erase(ins.first);
- }
- }
- }
-
- const IComputationNode* GetSource() const final { return this; }
+ }
+ }
+ }
+
+ const IComputationNode* GetSource() const final { return this; }
protected:
TStatefulSourceComputationNode(TComputationMutables& mutables, EValueRepresentation kind = EValueRepresentation::Any)
- : TStatefulComputationNode(mutables, kind)
+ : TStatefulComputationNode(mutables, kind)
{}
- void DependsOn(IComputationNode* node) const {
- if (node) {
- if (const auto source = node->AddDependence(this)) {
- Sources.emplace(source);
- }
+ void DependsOn(IComputationNode* node) const {
+ if (node) {
+ if (const auto source = node->AddDependence(this)) {
+ Sources.emplace(source);
+ }
}
- }
-
- void Own(IComputationExternalNode* node) const {
+ }
+
+ void Own(IComputationExternalNode* node) const {
if (node) {
node->SetOwner(this);
}
}
- TString DebugString() const override {
+ TString DebugString() const override {
return TypeName<TDerived>();
}
-
- mutable std::unordered_set<const IComputationNode*> Sources; // TODO: remove const and mutable.
- std::optional<bool> Stateless;
+
+ mutable std::unordered_set<const IComputationNode*> Sources; // TODO: remove const and mutable.
+ std::optional<bool> Stateless;
};
-template <typename TDerived>
+template <typename TDerived>
class TMutableComputationNode: public TStatefulSourceComputationNode<TDerived> {
protected:
using TStatefulSourceComputationNode<TDerived>::TStatefulSourceComputationNode;
@@ -222,573 +222,573 @@ protected:
};
template <typename TDerived>
-class TFlowSourceComputationNode: public TStatefulComputationNode<IComputationNode>
-{
-protected:
- TFlowSourceComputationNode(TComputationMutables& mutables, EValueRepresentation kind, EValueRepresentation stateKind)
- : TStatefulComputationNode<IComputationNode>(mutables, stateKind), RepresentationKind(kind)
- {}
-
- TString DebugString() const override {
- return TypeName<TDerived>();
- }
-
- void DependsOn(IComputationNode* node) const {
- if (node) {
- if (const auto source = node->AddDependence(this)) {
- Sources.emplace(source);
- }
- }
- }
-
- void Own(IComputationExternalNode* node) const {
- if (node) {
- node->SetOwner(this);
- }
- }
-private:
- bool IsTemporaryValue() const final {
- return true;
- }
-
- ui32 GetDependencyWeight() const final {
- return this->Dependencies.size() + Sources.size();
- }
-
+class TFlowSourceComputationNode: public TStatefulComputationNode<IComputationNode>
+{
+protected:
+ TFlowSourceComputationNode(TComputationMutables& mutables, EValueRepresentation kind, EValueRepresentation stateKind)
+ : TStatefulComputationNode<IComputationNode>(mutables, stateKind), RepresentationKind(kind)
+ {}
+
+ TString DebugString() const override {
+ return TypeName<TDerived>();
+ }
+
+ void DependsOn(IComputationNode* node) const {
+ if (node) {
+ if (const auto source = node->AddDependence(this)) {
+ Sources.emplace(source);
+ }
+ }
+ }
+
+ void Own(IComputationExternalNode* node) const {
+ if (node) {
+ node->SetOwner(this);
+ }
+ }
+private:
+ bool IsTemporaryValue() const final {
+ return true;
+ }
+
+ ui32 GetDependencyWeight() const final {
+ return this->Dependencies.size() + Sources.size();
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationExternalNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
if (dependencies.emplace(TStatefulComputationNode<IComputationNode>::ValueIndex, TStatefulComputationNode<IComputationNode>::RepresentationKind).second) {
std::for_each(this->Dependencies.cbegin(), this->Dependencies.cend(), std::bind(&IComputationNode::CollectDependentIndexes, std::placeholders::_1, owner, std::ref(dependencies)));
- }
- }
-
- void PrepareStageOne() final {}
- void PrepareStageTwo() final {}
-
- EValueRepresentation GetRepresentation() const final {
- return RepresentationKind;
- }
-
- NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(this->ValueRef(compCtx), compCtx);
- }
-
- const IComputationNode* GetSource() const final { return this; }
-
- const EValueRepresentation RepresentationKind;
- mutable std::unordered_set<const IComputationNode*> Sources; // TODO: remove const and mutable.
-};
-
-template <typename TDerived, typename IFlowInterface>
-class TFlowBaseComputationNode: public TRefCountedComputationNode<IFlowInterface>
-{
-protected:
- TFlowBaseComputationNode(const IComputationNode* source) : Source(source) {}
-
+ }
+ }
+
+ void PrepareStageOne() final {}
+ void PrepareStageTwo() final {}
+
+ EValueRepresentation GetRepresentation() const final {
+ return RepresentationKind;
+ }
+
+ NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(this->ValueRef(compCtx), compCtx);
+ }
+
+ const IComputationNode* GetSource() const final { return this; }
+
+ const EValueRepresentation RepresentationKind;
+ mutable std::unordered_set<const IComputationNode*> Sources; // TODO: remove const and mutable.
+};
+
+template <typename TDerived, typename IFlowInterface>
+class TFlowBaseComputationNode: public TRefCountedComputationNode<IFlowInterface>
+{
+protected:
+ TFlowBaseComputationNode(const IComputationNode* source) : Source(source) {}
+
void InitNode(TComputationContext&) const override {}
- TString DebugString() const override {
- return TypeName<TDerived>();
- }
-
- IComputationNode* FlowDependsOn(IComputationNode* node) const {
- if (node) {
- if (const auto source = node->AddDependence(this); dynamic_cast<IComputationExternalNode*>(source) || dynamic_cast<IComputationWideFlowProxyNode*>(source))
- return const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this)); // TODO: remove const in RegisterDependencies.
- else
- return source;
- }
- return nullptr;
- }
-
- IComputationNode* FlowDependsOnBoth(IComputationNode* one, IComputationNode* two) const {
- const auto flowOne = FlowDependsOn(one);
- const auto flowTwo = FlowDependsOn(two);
- if (flowOne && flowTwo) {
- if (flowOne == flowTwo)
- return flowOne;
- const auto flow = const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this));
- DependsOn(flow, flowOne);
- DependsOn(flow, flowTwo);
- return flow;
- } else if (flowOne) {
- return flowOne;
- } else if (flowTwo) {
- return flowTwo;
- }
-
- return nullptr;
- }
-
- IComputationNode* FlowDependsOnAll(const std::vector<IFlowInterface*, TMKQLAllocator<IFlowInterface*>>& sources) const {
- std::unordered_set<IComputationNode*> flows(sources.size());
- for (const auto& source : sources)
- if (const auto flow = FlowDependsOn(source))
- flows.emplace(flow);
-
- if (flows.size() > 1U) {
- const auto flow = const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this));
- std::for_each(flows.cbegin(), flows.cend(), std::bind(&TFlowBaseComputationNode::DependsOn, flow, std::placeholders::_1));
- return flow;
- }
-
- return flows.empty() ? nullptr : *flows.cbegin();
- }
-
- static void DependsOn(IComputationNode* source, IComputationNode* node) {
- if (node && source && node != source) {
- node->AddDependence(source);
- }
- }
-
- static void Own(IComputationNode* source, IComputationExternalNode* node) {
- if (node && source && node != source) {
- node->SetOwner(source);
- }
- }
-
- static void OwnProxy(IComputationNode* source, IComputationWideFlowProxyNode* node) {
- if (node && source && node != source) {
- node->SetOwner(source);
- }
- }
-private:
- ui32 GetDependencyWeight() const final { return 42U; }
-
- ui32 GetDependencesCount() const final {
- return Dependence ? 1U : 0U;
- }
-
- IComputationNode* AddDependence(const IComputationNode* node) final {
- if (!Dependence) {
- Dependence = node;
- }
- return this;
- }
-
- bool IsTemporaryValue() const final {
- return true;
- }
-
- void PrepareStageOne() final {}
- void PrepareStageTwo() final {}
-
- const IComputationNode* GetSource() const final {
- if (Source && Source != this)
- if (const auto s = Source->GetSource())
- return s;
- return this;
- }
-protected:
- const IComputationNode *const Source;
- const IComputationNode *Dependence = nullptr;
-};
-
-template <typename TDerived>
-class TBaseFlowBaseComputationNode: public TFlowBaseComputationNode<TDerived, IComputationNode>
-{
-protected:
- TBaseFlowBaseComputationNode(const IComputationNode* source, EValueRepresentation kind)
- : TFlowBaseComputationNode<TDerived, IComputationNode>(source), RepresentationKind(kind)
- {}
-private:
- EValueRepresentation GetRepresentation() const final {
- return RepresentationKind;
- }
-
- const EValueRepresentation RepresentationKind;
-};
-
-template <typename TDerived>
-class TStatelessFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
-{
-protected:
- TStatelessFlowComputationNode(const IComputationNode* source, EValueRepresentation kind)
- : TBaseFlowBaseComputationNode<TDerived>(source, kind)
- {}
-
- TStatelessFlowComputationNode(TComputationMutables&, const IComputationNode* source, EValueRepresentation kind)
- : TBaseFlowBaseComputationNode<TDerived>(source, kind)
- {}
-
- NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const override {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx);
- }
-private:
- ui32 GetIndex() const final {
- THROW yexception() << "Failed to get stateless node index.";
- }
-
+ TString DebugString() const override {
+ return TypeName<TDerived>();
+ }
+
+ IComputationNode* FlowDependsOn(IComputationNode* node) const {
+ if (node) {
+ if (const auto source = node->AddDependence(this); dynamic_cast<IComputationExternalNode*>(source) || dynamic_cast<IComputationWideFlowProxyNode*>(source))
+ return const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this)); // TODO: remove const in RegisterDependencies.
+ else
+ return source;
+ }
+ return nullptr;
+ }
+
+ IComputationNode* FlowDependsOnBoth(IComputationNode* one, IComputationNode* two) const {
+ const auto flowOne = FlowDependsOn(one);
+ const auto flowTwo = FlowDependsOn(two);
+ if (flowOne && flowTwo) {
+ if (flowOne == flowTwo)
+ return flowOne;
+ const auto flow = const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this));
+ DependsOn(flow, flowOne);
+ DependsOn(flow, flowTwo);
+ return flow;
+ } else if (flowOne) {
+ return flowOne;
+ } else if (flowTwo) {
+ return flowTwo;
+ }
+
+ return nullptr;
+ }
+
+ IComputationNode* FlowDependsOnAll(const std::vector<IFlowInterface*, TMKQLAllocator<IFlowInterface*>>& sources) const {
+ std::unordered_set<IComputationNode*> flows(sources.size());
+ for (const auto& source : sources)
+ if (const auto flow = FlowDependsOn(source))
+ flows.emplace(flow);
+
+ if (flows.size() > 1U) {
+ const auto flow = const_cast<IComputationNode*>(static_cast<const IComputationNode*>(this));
+ std::for_each(flows.cbegin(), flows.cend(), std::bind(&TFlowBaseComputationNode::DependsOn, flow, std::placeholders::_1));
+ return flow;
+ }
+
+ return flows.empty() ? nullptr : *flows.cbegin();
+ }
+
+ static void DependsOn(IComputationNode* source, IComputationNode* node) {
+ if (node && source && node != source) {
+ node->AddDependence(source);
+ }
+ }
+
+ static void Own(IComputationNode* source, IComputationExternalNode* node) {
+ if (node && source && node != source) {
+ node->SetOwner(source);
+ }
+ }
+
+ static void OwnProxy(IComputationNode* source, IComputationWideFlowProxyNode* node) {
+ if (node && source && node != source) {
+ node->SetOwner(source);
+ }
+ }
+private:
+ ui32 GetDependencyWeight() const final { return 42U; }
+
+ ui32 GetDependencesCount() const final {
+ return Dependence ? 1U : 0U;
+ }
+
+ IComputationNode* AddDependence(const IComputationNode* node) final {
+ if (!Dependence) {
+ Dependence = node;
+ }
+ return this;
+ }
+
+ bool IsTemporaryValue() const final {
+ return true;
+ }
+
+ void PrepareStageOne() final {}
+ void PrepareStageTwo() final {}
+
+ const IComputationNode* GetSource() const final {
+ if (Source && Source != this)
+ if (const auto s = Source->GetSource())
+ return s;
+ return this;
+ }
+protected:
+ const IComputationNode *const Source;
+ const IComputationNode *Dependence = nullptr;
+};
+
+template <typename TDerived>
+class TBaseFlowBaseComputationNode: public TFlowBaseComputationNode<TDerived, IComputationNode>
+{
+protected:
+ TBaseFlowBaseComputationNode(const IComputationNode* source, EValueRepresentation kind)
+ : TFlowBaseComputationNode<TDerived, IComputationNode>(source), RepresentationKind(kind)
+ {}
+private:
+ EValueRepresentation GetRepresentation() const final {
+ return RepresentationKind;
+ }
+
+ const EValueRepresentation RepresentationKind;
+};
+
+template <typename TDerived>
+class TStatelessFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
+{
+protected:
+ TStatelessFlowComputationNode(const IComputationNode* source, EValueRepresentation kind)
+ : TBaseFlowBaseComputationNode<TDerived>(source, kind)
+ {}
+
+ TStatelessFlowComputationNode(TComputationMutables&, const IComputationNode* source, EValueRepresentation kind)
+ : TBaseFlowBaseComputationNode<TDerived>(source, kind)
+ {}
+
+ NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const override {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx);
+ }
+private:
+ ui32 GetIndex() const final {
+ THROW yexception() << "Failed to get stateless node index.";
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
- if (this->Dependence) {
+ if (this == owner)
+ return;
+
+ if (this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-};
-
+ }
+ }
+};
+
template <typename TDerived, bool SerializableState = false>
-class TStatefulFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
-{
-protected:
- TStatefulFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation stateKind)
- : TBaseFlowBaseComputationNode<TDerived>(source, kind), StateIndex(mutables.CurValueIndex++), StateKind(stateKind)
+class TStatefulFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
+{
+protected:
+ TStatefulFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation stateKind)
+ : TBaseFlowBaseComputationNode<TDerived>(source, kind), StateIndex(mutables.CurValueIndex++), StateKind(stateKind)
{
if constexpr (SerializableState) {
mutables.SerializableValues.push_back(StateIndex);
}
}
-
- NUdf::TUnboxedValue& RefState(TComputationContext& compCtx) const {
- return compCtx.MutableValues[GetIndex()];
- }
-
-private:
- ui32 GetIndex() const final {
- return StateIndex;
- }
-
- NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx);
- }
-
+
+ NUdf::TUnboxedValue& RefState(TComputationContext& compCtx) const {
+ return compCtx.MutableValues[GetIndex()];
+ }
+
+private:
+ ui32 GetIndex() const final {
+ return StateIndex;
+ }
+
+ NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx);
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
const auto ins = dependencies.emplace(StateIndex, StateKind);
- if (ins.second && this->Dependence) {
+ if (ins.second && this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-
- const ui32 StateIndex;
- const EValueRepresentation StateKind;
-};
-
-const IComputationNode* GetCommonSource(const IComputationNode* first, const IComputationNode* second, const IComputationNode* common);
-
-template <typename TDerived>
-class TPairStateFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
-{
-protected:
- TPairStateFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation firstKind = EValueRepresentation::Any, EValueRepresentation secondKind = EValueRepresentation::Any)
- : TBaseFlowBaseComputationNode<TDerived>(source, kind), StateIndex(mutables.CurValueIndex++), FirstKind(firstKind), SecondKind(secondKind)
- {
- ++mutables.CurValueIndex;
- }
-
-private:
- NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx.MutableValues[StateIndex + 1U], compCtx);
- }
-
- ui32 GetIndex() const final {
- return StateIndex;
- }
-
+ }
+ }
+
+ const ui32 StateIndex;
+ const EValueRepresentation StateKind;
+};
+
+const IComputationNode* GetCommonSource(const IComputationNode* first, const IComputationNode* second, const IComputationNode* common);
+
+template <typename TDerived>
+class TPairStateFlowComputationNode: public TBaseFlowBaseComputationNode<TDerived>
+{
+protected:
+ TPairStateFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation kind, EValueRepresentation firstKind = EValueRepresentation::Any, EValueRepresentation secondKind = EValueRepresentation::Any)
+ : TBaseFlowBaseComputationNode<TDerived>(source, kind), StateIndex(mutables.CurValueIndex++), FirstKind(firstKind), SecondKind(secondKind)
+ {
+ ++mutables.CurValueIndex;
+ }
+
+private:
+ NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx.MutableValues[StateIndex + 1U], compCtx);
+ }
+
+ ui32 GetIndex() const final {
+ return StateIndex;
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
const auto ins1 = dependencies.emplace(StateIndex, FirstKind);
const auto ins2 = dependencies.emplace(StateIndex + 1U, SecondKind);
- if (ins1.second && ins2.second && this->Dependence) {
+ if (ins1.second && ins2.second && this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-
- const ui32 StateIndex;
- const EValueRepresentation FirstKind, SecondKind;
-};
-
-class TWideFlowProxyComputationNode: public TRefCountedComputationNode<IComputationWideFlowProxyNode>
-{
-protected:
- TWideFlowProxyComputationNode() = default;
-
- TString DebugString() const final;
-
-private:
+ }
+ }
+
+ const ui32 StateIndex;
+ const EValueRepresentation FirstKind, SecondKind;
+};
+
+class TWideFlowProxyComputationNode: public TRefCountedComputationNode<IComputationWideFlowProxyNode>
+{
+protected:
+ TWideFlowProxyComputationNode() = default;
+
+ TString DebugString() const final;
+
+private:
void InitNode(TComputationContext&) const override {}
- EValueRepresentation GetRepresentation() const final;
-
- NUdf::TUnboxedValue GetValue(TComputationContext&) const final;
-
- ui32 GetIndex() const final;
-
- ui32 GetDependencyWeight() const final;
-
- ui32 GetDependencesCount() const final;
-
- const IComputationNode* GetSource() const final;
-
- IComputationNode* AddDependence(const IComputationNode* node) final;
-
- bool IsTemporaryValue() const final;
-
- void RegisterDependencies() const final;
-
- void PrepareStageOne() final;
-
- void PrepareStageTwo() final;
-
- void SetOwner(const IComputationNode* owner) final;
-
- void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final;
-
- void InvalidateValue(TComputationContext& ctx) const final;
-
- void SetFetcher(TFetcher&& fetcher) final;
-
- EFetchResult FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* values) const final;
-
-protected:
- const IComputationNode* Dependence = nullptr;
- const IComputationNode* Owner = nullptr;
- std::vector<std::pair<ui32, EValueRepresentation>> InvalidationSet;
- TFetcher Fetcher;
-};
-
-template <typename TDerived>
-class TWideFlowBaseComputationNode: public TFlowBaseComputationNode<TDerived, IComputationWideFlowNode>
-{
-protected:
- TWideFlowBaseComputationNode(const IComputationNode* source)
- : TFlowBaseComputationNode<TDerived, IComputationWideFlowNode>(source)
- {}
-private:
- EValueRepresentation GetRepresentation() const final {
- THROW yexception() << "Failed to get representation kind.";
- }
-
+ EValueRepresentation GetRepresentation() const final;
+
+ NUdf::TUnboxedValue GetValue(TComputationContext&) const final;
+
+ ui32 GetIndex() const final;
+
+ ui32 GetDependencyWeight() const final;
+
+ ui32 GetDependencesCount() const final;
+
+ const IComputationNode* GetSource() const final;
+
+ IComputationNode* AddDependence(const IComputationNode* node) final;
+
+ bool IsTemporaryValue() const final;
+
+ void RegisterDependencies() const final;
+
+ void PrepareStageOne() final;
+
+ void PrepareStageTwo() final;
+
+ void SetOwner(const IComputationNode* owner) final;
+
+ void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final;
+
+ void InvalidateValue(TComputationContext& ctx) const final;
+
+ void SetFetcher(TFetcher&& fetcher) final;
+
+ EFetchResult FetchValues(TComputationContext& ctx, NUdf::TUnboxedValue*const* values) const final;
+
+protected:
+ const IComputationNode* Dependence = nullptr;
+ const IComputationNode* Owner = nullptr;
+ std::vector<std::pair<ui32, EValueRepresentation>> InvalidationSet;
+ TFetcher Fetcher;
+};
+
+template <typename TDerived>
+class TWideFlowBaseComputationNode: public TFlowBaseComputationNode<TDerived, IComputationWideFlowNode>
+{
+protected:
+ TWideFlowBaseComputationNode(const IComputationNode* source)
+ : TFlowBaseComputationNode<TDerived, IComputationWideFlowNode>(source)
+ {}
+private:
+ EValueRepresentation GetRepresentation() const final {
+ THROW yexception() << "Failed to get representation kind.";
+ }
+
NUdf::TUnboxedValue GetValue(TComputationContext&) const {
- THROW yexception() << "Failed to get value from wide flow node.";
- }
-};
-
-template <typename TDerived>
-class TStatelessWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
-{
-protected:
- TStatelessWideFlowComputationNode(const IComputationNode* source)
- :TWideFlowBaseComputationNode<TDerived>(source)
- {}
-
-private:
- EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx, values);
- }
-
- ui32 GetIndex() const final {
- THROW yexception() << "Failed to get stateless node index.";
- }
-
+ THROW yexception() << "Failed to get value from wide flow node.";
+ }
+};
+
+template <typename TDerived>
+class TStatelessWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
+{
+protected:
+ TStatelessWideFlowComputationNode(const IComputationNode* source)
+ :TWideFlowBaseComputationNode<TDerived>(source)
+ {}
+
+private:
+ EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx, values);
+ }
+
+ ui32 GetIndex() const final {
+ THROW yexception() << "Failed to get stateless node index.";
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
- if (this->Dependence) {
+ if (this == owner)
+ return;
+
+ if (this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-};
-
+ }
+ }
+};
+
template <typename TDerived, bool SerializableState = false>
-class TStatefulWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
-{
-protected:
- TStatefulWideFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation stateKind)
- : TWideFlowBaseComputationNode<TDerived>(source), StateIndex(mutables.CurValueIndex++), StateKind(stateKind)
+class TStatefulWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
+{
+protected:
+ TStatefulWideFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation stateKind)
+ : TWideFlowBaseComputationNode<TDerived>(source), StateIndex(mutables.CurValueIndex++), StateKind(stateKind)
{
if constexpr (SerializableState) {
mutables.SerializableValues.push_back(StateIndex);
}
}
-
- NUdf::TUnboxedValue& RefState(TComputationContext& compCtx) const {
- return compCtx.MutableValues[GetIndex()];
- }
-private:
- EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx, values);
- }
-
- ui32 GetIndex() const final {
- return StateIndex;
- }
-
+
+ NUdf::TUnboxedValue& RefState(TComputationContext& compCtx) const {
+ return compCtx.MutableValues[GetIndex()];
+ }
+private:
+ EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx, values);
+ }
+
+ ui32 GetIndex() const final {
+ return StateIndex;
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
const auto ins = dependencies.emplace(StateIndex, StateKind);
- if (ins.second && this->Dependence) {
+ if (ins.second && this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-
- const ui32 StateIndex;
- const EValueRepresentation StateKind;
-};
-
-template <typename TDerived>
-class TPairStateWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
-{
-protected:
- TPairStateWideFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation firstKind, EValueRepresentation secondKind)
- : TWideFlowBaseComputationNode<TDerived>(source), StateIndex(mutables.CurValueIndex++), FirstKind(firstKind), SecondKind(secondKind)
- {
- ++mutables.CurValueIndex;
- }
-
-private:
- EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx.MutableValues[StateIndex + 1U], compCtx, values);
- }
-
- ui32 GetIndex() const final {
- return StateIndex;
- }
-
+ }
+ }
+
+ const ui32 StateIndex;
+ const EValueRepresentation StateKind;
+};
+
+template <typename TDerived>
+class TPairStateWideFlowComputationNode: public TWideFlowBaseComputationNode<TDerived>
+{
+protected:
+ TPairStateWideFlowComputationNode(TComputationMutables& mutables, const IComputationNode* source, EValueRepresentation firstKind, EValueRepresentation secondKind)
+ : TWideFlowBaseComputationNode<TDerived>(source), StateIndex(mutables.CurValueIndex++), FirstKind(firstKind), SecondKind(secondKind)
+ {
+ ++mutables.CurValueIndex;
+ }
+
+private:
+ EFetchResult FetchValues(TComputationContext& compCtx, NUdf::TUnboxedValue*const* values) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx.MutableValues[StateIndex], compCtx.MutableValues[StateIndex + 1U], compCtx, values);
+ }
+
+ ui32 GetIndex() const final {
+ return StateIndex;
+ }
+
void CollectDependentIndexes(const IComputationNode* owner, IComputationNode::TIndexesMap& dependencies) const final {
- if (this == owner)
- return;
-
+ if (this == owner)
+ return;
+
const auto ins1 = dependencies.emplace(StateIndex, FirstKind);
const auto ins2 = dependencies.emplace(StateIndex + 1U, SecondKind);
- if (ins1.second && ins2.second && this->Dependence) {
+ if (ins1.second && ins2.second && this->Dependence) {
this->Dependence->CollectDependentIndexes(owner, dependencies);
- }
- }
-
- const ui32 StateIndex;
- const EValueRepresentation FirstKind, SecondKind;
-};
-
-template <typename TDerived>
-class TDecoratorComputationNode: public TRefCountedComputationNode<IComputationNode>
-{
-private:
- void InitNode(TComputationContext&) const final {}
-
- const IComputationNode* GetSource() const final { return Node; }
-
- IComputationNode* AddDependence(const IComputationNode* node) final {
- return Node->AddDependence(node);
- }
-
- EValueRepresentation GetRepresentation() const final { return Kind; }
- bool IsTemporaryValue() const final { return true; }
-
- void PrepareStageOne() final {}
- void PrepareStageTwo() final {}
-
- void RegisterDependencies() const final { Node->AddDependence(this); }
-
- void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final {}
-
- ui32 GetDependencyWeight() const final { return 0U; }
-
- ui32 GetDependencesCount() const final {
- return Node->GetDependencesCount();
- }
-
- ui32 GetIndex() const final {
- THROW yexception() << "Can't get index from decorator node.";
- }
-
+ }
+ }
+
+ const ui32 StateIndex;
+ const EValueRepresentation FirstKind, SecondKind;
+};
+
+template <typename TDerived>
+class TDecoratorComputationNode: public TRefCountedComputationNode<IComputationNode>
+{
+private:
+ void InitNode(TComputationContext&) const final {}
+
+ const IComputationNode* GetSource() const final { return Node; }
+
+ IComputationNode* AddDependence(const IComputationNode* node) final {
+ return Node->AddDependence(node);
+ }
+
+ EValueRepresentation GetRepresentation() const final { return Kind; }
+ bool IsTemporaryValue() const final { return true; }
+
+ void PrepareStageOne() final {}
+ void PrepareStageTwo() final {}
+
+ void RegisterDependencies() const final { Node->AddDependence(this); }
+
+ void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final {}
+
+ ui32 GetDependencyWeight() const final { return 0U; }
+
+ ui32 GetDependencesCount() const final {
+ return Node->GetDependencesCount();
+ }
+
+ ui32 GetIndex() const final {
+ THROW yexception() << "Can't get index from decorator node.";
+ }
+
NUdf::TUnboxedValue GetValue(TComputationContext& compCtx) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(compCtx, Node->GetValue(compCtx));
+ return static_cast<const TDerived*>(this)->DoCalculate(compCtx, Node->GetValue(compCtx));
}
protected:
- TDecoratorComputationNode(IComputationNode* node, EValueRepresentation kind)
- : Node(node), Kind(kind)
- {}
-
+ TDecoratorComputationNode(IComputationNode* node, EValueRepresentation kind)
+ : Node(node), Kind(kind)
+ {}
+
TDecoratorComputationNode(IComputationNode* node)
- : Node(node), Kind(node->GetRepresentation())
+ : Node(node), Kind(node->GetRepresentation())
{}
-
+
TString DebugString() const override {
return TypeName<TDerived>() += "(" + Node->DebugString() + ")";
}
- IComputationNode *const Node;
- const EValueRepresentation Kind;
+ IComputationNode *const Node;
+ const EValueRepresentation Kind;
};
template <typename TDerived>
-class TBinaryComputationNode: public TRefCountedComputationNode<IComputationNode>
-{
-private:
- NUdf::TUnboxedValue GetValue(TComputationContext& ctx) const final {
- return static_cast<const TDerived*>(this)->DoCalculate(ctx);
- }
-
- const IComputationNode* GetSource() const final {
- return GetCommonSource(Left, Right, this);
- }
-
- void InitNode(TComputationContext&) const final {}
-protected:
- TString DebugString() const override {
- return TypeName<TDerived>() += "(" + Left->DebugString() + "," + Right->DebugString() + ")";
- }
-
- IComputationNode* AddDependence(const IComputationNode* node) final {
- const auto l = Left->AddDependence(node);
- const auto r = Right->AddDependence(node);
-
- if (!l) return r;
- if (!r) return l;
-
- return this;
- }
-
- EValueRepresentation GetRepresentation() const final {
- return Kind;
- }
-
- bool IsTemporaryValue() const final { return true; }
-
- void PrepareStageOne() final {}
- void PrepareStageTwo() final {}
-
- void RegisterDependencies() const final {
- Left->AddDependence(this);
- Right->AddDependence(this);
- }
-
- void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final {}
-
- ui32 GetDependencyWeight() const final { return 0U; }
-
- ui32 GetDependencesCount() const final {
- return Left->GetDependencesCount() + Right->GetDependencesCount();
- }
-
- ui32 GetIndex() const final {
- THROW yexception() << "Can't get index from decorator node.";
- }
-
- TBinaryComputationNode(IComputationNode* left, IComputationNode* right, const EValueRepresentation kind)
- : Left(left), Right(right), Kind(kind)
- {
- }
-
- IComputationNode *const Left;
- IComputationNode *const Right;
- const EValueRepresentation Kind;
-};
-
+class TBinaryComputationNode: public TRefCountedComputationNode<IComputationNode>
+{
+private:
+ NUdf::TUnboxedValue GetValue(TComputationContext& ctx) const final {
+ return static_cast<const TDerived*>(this)->DoCalculate(ctx);
+ }
+
+ const IComputationNode* GetSource() const final {
+ return GetCommonSource(Left, Right, this);
+ }
+
+ void InitNode(TComputationContext&) const final {}
+protected:
+ TString DebugString() const override {
+ return TypeName<TDerived>() += "(" + Left->DebugString() + "," + Right->DebugString() + ")";
+ }
+
+ IComputationNode* AddDependence(const IComputationNode* node) final {
+ const auto l = Left->AddDependence(node);
+ const auto r = Right->AddDependence(node);
+
+ if (!l) return r;
+ if (!r) return l;
+
+ return this;
+ }
+
+ EValueRepresentation GetRepresentation() const final {
+ return Kind;
+ }
+
+ bool IsTemporaryValue() const final { return true; }
+
+ void PrepareStageOne() final {}
+ void PrepareStageTwo() final {}
+
+ void RegisterDependencies() const final {
+ Left->AddDependence(this);
+ Right->AddDependence(this);
+ }
+
+ void CollectDependentIndexes(const IComputationNode*, TIndexesMap&) const final {}
+
+ ui32 GetDependencyWeight() const final { return 0U; }
+
+ ui32 GetDependencesCount() const final {
+ return Left->GetDependencesCount() + Right->GetDependencesCount();
+ }
+
+ ui32 GetIndex() const final {
+ THROW yexception() << "Can't get index from decorator node.";
+ }
+
+ TBinaryComputationNode(IComputationNode* left, IComputationNode* right, const EValueRepresentation kind)
+ : Left(left), Right(right), Kind(kind)
+ {
+ }
+
+ IComputationNode *const Left;
+ IComputationNode *const Right;
+ const EValueRepresentation Kind;
+};
+
template <typename TDerived, typename TBase = NUdf::IBoxedValue>
class TComputationValue: public TBase, public TWithMiniKQLAlloc
{
@@ -806,24 +806,24 @@ public:
MKQL_MEM_RETURN(GetMemInfo(), this, sizeof(TDerived));
}
-private:
+private:
bool HasFastListLength() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return false;
}
ui64 GetListLength() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return 0;
}
ui64 GetEstimatedListLength() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return 0;
}
bool HasListItems() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return false;
}
@@ -854,140 +854,140 @@ private:
}
ui64 GetDictLength() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return 0;
}
- bool HasDictItems() const override {
- ThrowNotSupported(__func__);
+ bool HasDictItems() const override {
+ ThrowNotSupported(__func__);
+ return false;
+ }
+
+ NUdf::TStringRef GetResourceTag() const override {
+ ThrowNotSupported(__func__);
+ return NUdf::TStringRef();
+ }
+
+ void* GetResource() override {
+ ThrowNotSupported(__func__);
+ return nullptr;
+ }
+
+ void Apply(NUdf::IApplyContext& applyCtx) const override {
+ Y_UNUSED(applyCtx);
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ ThrowNotSupported(__func__);
+ return {};
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ ThrowNotSupported(__func__);
+ return {};
+ }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ ThrowNotSupported(__func__);
+ return {};
+ }
+
+ NUdf::TUnboxedValue GetPayloadsIterator() const override {
+ ThrowNotSupported(__func__);
+ return {};
+ }
+
+ bool Contains(const NUdf::TUnboxedValuePod& key) const override {
+ Y_UNUSED(key);
+ ThrowNotSupported(__func__);
return false;
}
- NUdf::TStringRef GetResourceTag() const override {
- ThrowNotSupported(__func__);
- return NUdf::TStringRef();
- }
-
- void* GetResource() override {
- ThrowNotSupported(__func__);
- return nullptr;
- }
-
- void Apply(NUdf::IApplyContext& applyCtx) const override {
- Y_UNUSED(applyCtx);
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- ThrowNotSupported(__func__);
- return {};
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- ThrowNotSupported(__func__);
- return {};
- }
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- ThrowNotSupported(__func__);
- return {};
- }
-
- NUdf::TUnboxedValue GetPayloadsIterator() const override {
- ThrowNotSupported(__func__);
- return {};
- }
-
- bool Contains(const NUdf::TUnboxedValuePod& key) const override {
- Y_UNUSED(key);
- ThrowNotSupported(__func__);
- return false;
- }
-
- NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
- Y_UNUSED(key);
- ThrowNotSupported(__func__);
- return NUdf::TUnboxedValuePod();
- }
-
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- Y_UNUSED(index);
- ThrowNotSupported(__func__);
- return {};
- }
-
- const NUdf::TUnboxedValue* GetElements() const override {
- return nullptr;
- }
-
- NUdf::TUnboxedValue Run(
+ NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
+ Y_UNUSED(key);
+ ThrowNotSupported(__func__);
+ return NUdf::TUnboxedValuePod();
+ }
+
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ Y_UNUSED(index);
+ ThrowNotSupported(__func__);
+ return {};
+ }
+
+ const NUdf::TUnboxedValue* GetElements() const override {
+ return nullptr;
+ }
+
+ NUdf::TUnboxedValue Run(
const NUdf::IValueBuilder* valueBuilder,
- const NUdf::TUnboxedValuePod* args) const override
+ const NUdf::TUnboxedValuePod* args) const override
{
Y_UNUSED(valueBuilder);
Y_UNUSED(args);
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return {};
}
-
- bool Skip() override {
- NUdf::TUnboxedValue stub;
- return Next(stub);
- }
-
- bool Next(NUdf::TUnboxedValue&) override {
- ThrowNotSupported(__func__);
- return false;
- }
-
- bool NextPair(NUdf::TUnboxedValue&, NUdf::TUnboxedValue&) override {
- ThrowNotSupported(__func__);
- return false;
- }
-
- ui32 GetVariantIndex() const override {
- ThrowNotSupported(__func__);
- return 0;
- }
-
+
+ bool Skip() override {
+ NUdf::TUnboxedValue stub;
+ return Next(stub);
+ }
+
+ bool Next(NUdf::TUnboxedValue&) override {
+ ThrowNotSupported(__func__);
+ return false;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue&, NUdf::TUnboxedValue&) override {
+ ThrowNotSupported(__func__);
+ return false;
+ }
+
+ ui32 GetVariantIndex() const override {
+ ThrowNotSupported(__func__);
+ return 0;
+ }
+
NUdf::TUnboxedValue GetVariantItem() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return {};
}
NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
Y_UNUSED(result);
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return NUdf::EFetchStatus::Finish;
}
-
+
ui32 GetTraverseCount() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return 0;
}
NUdf::TUnboxedValue GetTraverseItem(ui32 index) const override {
Y_UNUSED(index);
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return {};
}
NUdf::TUnboxedValue Save() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return NUdf::TUnboxedValue::Zero();
}
void Load(const NUdf::TStringRef& state) override {
Y_UNUSED(state);
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
}
void Push(const NUdf::TUnboxedValuePod& value) override {
Y_UNUSED(value);
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
}
bool IsSortedDict() const override {
- ThrowNotSupported(__func__);
+ ThrowNotSupported(__func__);
return false;
}
@@ -1019,7 +1019,7 @@ private:
ThrowNotSupported(__func__);
}
-public:
+public:
TString DebugString() const {
return TypeName<TDerived>();
}
@@ -1029,61 +1029,61 @@ protected:
return static_cast<TMemoryUsageInfo*>(M_.MemInfo);
}
- [[noreturn]] void ThrowNotSupported(const char* func) const {
+ [[noreturn]] void ThrowNotSupported(const char* func) const {
THROW yexception() << "Unsupported access to '" << func << "' method of: " << TypeName(*this);
}
-
+
private:
- struct {
- void* MemInfo; // used for tracking memory usage during execution
- } M_;
+ struct {
+ void* MemInfo; // used for tracking memory usage during execution
+ } M_;
+};
+
+template<bool IsStream>
+struct TThresher;
+
+template<>
+struct TThresher<true> {
+ template<class Handler>
+ static void DoForEachItem(const NUdf::TUnboxedValuePod& stream, const Handler& handler) {
+ for (NUdf::TUnboxedValue item;; handler(std::move(item))) {
+ const auto status = stream.Fetch(item);
+ MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status!");
+ if (status == NUdf::EFetchStatus::Finish)
+ break;
+ }
+ }
+};
+
+template<>
+struct TThresher<false> {
+ template<class Handler>
+ static void DoForEachItem(const NUdf::TUnboxedValuePod& list, const Handler& handler) {
+ if (auto ptr = list.GetElements()) {
+ if (auto size = list.GetListLength()) do {
+ handler(NUdf::TUnboxedValue(*ptr++));
+ } while (--size);
+ } else if (const auto& iter = list.GetListIterator()) {
+ for (NUdf::TUnboxedValue item; iter.Next(item); handler(std::move(item)))
+ continue;
+ }
+ }
};
-template<bool IsStream>
-struct TThresher;
-
-template<>
-struct TThresher<true> {
- template<class Handler>
- static void DoForEachItem(const NUdf::TUnboxedValuePod& stream, const Handler& handler) {
- for (NUdf::TUnboxedValue item;; handler(std::move(item))) {
- const auto status = stream.Fetch(item);
- MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status!");
- if (status == NUdf::EFetchStatus::Finish)
- break;
- }
- }
-};
-
-template<>
-struct TThresher<false> {
- template<class Handler>
- static void DoForEachItem(const NUdf::TUnboxedValuePod& list, const Handler& handler) {
- if (auto ptr = list.GetElements()) {
- if (auto size = list.GetListLength()) do {
- handler(NUdf::TUnboxedValue(*ptr++));
- } while (--size);
- } else if (const auto& iter = list.GetListIterator()) {
- for (NUdf::TUnboxedValue item; iter.Next(item); handler(std::move(item)))
- continue;
- }
- }
-};
-
IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop = false);
IComputationNode* LocateNode(const TNodeLocator& nodeLocator, TNode& node, bool pop = false);
-IComputationExternalNode* LocateExternalNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop = true);
-
-using TPasstroughtMap = std::vector<std::optional<size_t>>;
-
-TPasstroughtMap GetPasstroughtMap(const TComputationExternalNodePtrVector& args, const TComputationNodePtrVector& roots);
-TPasstroughtMap GetPasstroughtMap(const TComputationNodePtrVector& roots, const TComputationExternalNodePtrVector& args);
-
-std::optional<size_t> IsPasstrought(const IComputationNode* root, const TComputationExternalNodePtrVector& args);
-
-TPasstroughtMap MergePasstroughtMaps(const TPasstroughtMap& lhs, const TPasstroughtMap& rhs);
-
-void ApplyChanges(const NUdf::TUnboxedValue& value, NUdf::IApplyContext& applyCtx);
+IComputationExternalNode* LocateExternalNode(const TNodeLocator& nodeLocator, TCallable& callable, ui32 index, bool pop = true);
+
+using TPasstroughtMap = std::vector<std::optional<size_t>>;
+
+TPasstroughtMap GetPasstroughtMap(const TComputationExternalNodePtrVector& args, const TComputationNodePtrVector& roots);
+TPasstroughtMap GetPasstroughtMap(const TComputationNodePtrVector& roots, const TComputationExternalNodePtrVector& args);
+
+std::optional<size_t> IsPasstrought(const IComputationNode* root, const TComputationExternalNodePtrVector& args);
+
+TPasstroughtMap MergePasstroughtMaps(const TPasstroughtMap& lhs, const TPasstroughtMap& rhs);
+
+void ApplyChanges(const NUdf::TUnboxedValue& value, NUdf::IApplyContext& applyCtx);
}
}
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_list.h b/ydb/library/yql/minikql/computation/mkql_computation_node_list.h
index eff4c93007..d87fe871bf 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_list.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_list.h
@@ -8,10 +8,10 @@
namespace NKikimr {
namespace NMiniKQL {
- template <typename T>
+ template <typename T>
struct TListChunk {
private:
- using TSelf = TListChunk<T>;
+ using TSelf = TListChunk<T>;
static void PlacementNew(T* ptr, ui64 count) {
T* end = ptr + count;
@@ -27,8 +27,8 @@ namespace NKikimr {
}
static TSelf* AllocateChunk(ui64 length) {
- const auto block = MKQLAllocWithSize(length * sizeof(T) + sizeof(TListChunk));
- const auto ptr = new (block) TListChunk(length);
+ const auto block = MKQLAllocWithSize(length * sizeof(T) + sizeof(TListChunk));
+ const auto ptr = new (block) TListChunk(length);
PlacementNew(reinterpret_cast<T*>(ptr + 1), length);
return ptr;
}
@@ -45,7 +45,7 @@ namespace NKikimr {
for (auto it = DataBegin(); it != DataEnd(); it++) {
it->~T();
}
- MKQLFreeWithSize(static_cast<void*>(this), sizeof(TListChunk) + sizeof(T) * (DataEnd() - DataBegin()));
+ MKQLFreeWithSize(static_cast<void*>(this), sizeof(TListChunk) + sizeof(T) * (DataEnd() - DataBegin()));
}
inline T* DataBegin() {
@@ -83,11 +83,11 @@ namespace NKikimr {
};
- template <typename T, ui64 MinChunkSize = 48>
+ template <typename T, ui64 MinChunkSize = 48>
class TListRepresentation {
public:
- using TSelf = TListRepresentation<T, MinChunkSize>;
- using TChunk = TListChunk<T>;
+ using TSelf = TListRepresentation<T, MinChunkSize>;
+ using TChunk = TListChunk<T>;
private:
enum Type {
@@ -289,24 +289,24 @@ namespace NKikimr {
other.Type_ = Type::Freezed;
}
- inline void FromSingleElement(T&& element) {
+ inline void FromSingleElement(T&& element) {
Type_ = Type::Normal;
ui64 chunkLength = (MinChunkSize + sizeof(T) - 1) / sizeof(T);
Chunk_ = TChunk::AllocateChunk(chunkLength);
Begin_ = Chunk_->DataBegin() + (chunkLength >> 2);
End_ = Begin_ + 1;
- *Begin_ = std::move(element);
+ *Begin_ = std::move(element);
}
- TListRepresentation(T&& element)
+ TListRepresentation(T&& element)
{
- FromSingleElement(std::move(element));
+ FromSingleElement(std::move(element));
}
- TListRepresentation(T&& element, const TSelf& that)
+ TListRepresentation(T&& element, const TSelf& that)
{
if (!that.Chunk_) {
- FromSingleElement(std::move(element));
+ FromSingleElement(std::move(element));
return;
}
if ((that.Type_ == Type::Normal) && (that.Begin_ != that.Chunk_->DataBegin())) {
@@ -316,16 +316,16 @@ namespace NKikimr {
Chunk_->Ref();
Begin_ = that.Begin_;
End_ = that.End_;
- *(--Begin_) = std::move(element);
+ *(--Begin_) = std::move(element);
} else {
NewNormal(&element, &element + 1, that.Begin_, that.End_);
}
}
- TListRepresentation(const TSelf& that, T&& element)
+ TListRepresentation(const TSelf& that, T&& element)
{
if (!that.Chunk_) {
- FromSingleElement(std::move(element));
+ FromSingleElement(std::move(element));
return;
}
if ((that.Type_ == Type::Normal) && (that.End_ != that.Chunk_->DataEnd())) {
@@ -335,7 +335,7 @@ namespace NKikimr {
Chunk_->Ref();
Begin_ = that.Begin_;
End_ = that.End_ + 1;
- *(that.End_) = std::move(element);
+ *(that.End_) = std::move(element);
} else {
NewNormal(that.Begin_, that.End_, &element, &element + 1);
}
@@ -353,12 +353,12 @@ namespace NKikimr {
return TReverseIterator(*this);
}
- TSelf Append(T&& right) const {
- return TSelf(*this, std::move(right));
+ TSelf Append(T&& right) const {
+ return TSelf(*this, std::move(right));
}
- TSelf Prepend(T&& left) const {
- return TSelf(std::move(left), *this);
+ TSelf Prepend(T&& left) const {
+ return TSelf(std::move(left), *this);
}
TSelf MassPrepend(T* begin, T* end) const {
@@ -417,10 +417,10 @@ namespace NKikimr {
return Begin_[index];
}
- T* GetItems() const {
- return Begin_;
- }
-
+ T* GetItems() const {
+ return Begin_;
+ }
+
private:
TChunk* Chunk_;
T* Begin_;
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_list_ut.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_list_ut.cpp
index 1d8c7b7640..f8a90d60fe 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_list_ut.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_list_ut.cpp
@@ -1,126 +1,126 @@
-#include "mkql_computation_node_list.h"
-
+#include "mkql_computation_node_list.h"
+
#include <ydb/library/yql/minikql/mkql_function_registry.h>
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-Y_UNIT_TEST_SUITE(TestListRepresentation) {
- Y_UNIT_TEST(Test) {
+
+namespace NKikimr {
+namespace NMiniKQL {
+Y_UNIT_TEST_SUITE(TestListRepresentation) {
+ Y_UNIT_TEST(Test) {
TMemoryUsageInfo memInfo(TStringBuf("test"));
- TScopedAlloc alloc;
- using TListType = TListRepresentation<ui32, 256>;
- TListType list1;
- auto it1 = list1.GetIterator();
- UNIT_ASSERT(it1.AtEnd());
-
- TListType list2(list1, 0);
- auto it2 = list2.GetIterator();
- UNIT_ASSERT(!it2.AtEnd());
- UNIT_ASSERT_VALUES_EQUAL(it2.Current(), 0);
- it2.Next();
- UNIT_ASSERT(it2.AtEnd());
-
- TVector<TListType> lists;
- lists.push_back(list1);
- const ui32 n = 100;
- for (ui32 i = 0; i < n; ++i) {
- auto c = i;
- lists.push_back(TListType(lists.back(), std::move(c)));
- }
-
- for (ui32 i = 0; i < n; ++i) {
- auto list = lists[i];
- auto it = list.GetIterator();
- ui32 expected = 0;
- while (!it.AtEnd()) {
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
- ++expected;
- it.Next();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(expected, i);
- }
-
- for (ui32 i = 0; i < n; ++i) {
- auto list = lists[i];
- auto it = list.GetReverseIterator();
- ui32 expected = i;
- while (!it.AtEnd()) {
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), --expected);
- it.Next();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(expected, 0);
- }
-
- TVector<TListType> rlists;
- rlists.push_back(list1);
- for (ui32 i = 0; i < n; ++i) {
- auto c = i;
- rlists.push_back(TListType(std::move(c), rlists.back()));
- }
-
- for (ui32 i = 0; i < n; ++i) {
- auto list = rlists[i];
- auto it = list.GetIterator();
- ui32 expected = i;
- while (!it.AtEnd()) {
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), --expected);
- it.Next();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(expected, 0);
- }
-
- for (ui32 i = 0; i < n; ++i) {
- auto list = rlists[i];
- auto it = list.GetReverseIterator();
- ui32 expected = 0;
- while (!it.AtEnd()) {
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
- ++expected;
- it.Next();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(expected, i);
- }
-
- TVector<TListType> zlists;
- zlists.push_back(list1);
- for (ui32 i = 0; i < n; ++i) {
- zlists.push_back(zlists.back().Append(2 * i));
- zlists.push_back(zlists.back().Prepend(2 * i + 1));
- }
-
- for (ui32 i = 0; i < 2 * n; ++i) {
- ui32 k = (i + 1) / 2;
- auto list = zlists[i];
- auto it = list.GetIterator();
- ui32 expected = 2 * k + 1;
- if ((i % 2))
- expected -= 2;
-
- if (i >= 2) {
- while (!it.AtEnd()) {
- expected -= 2;
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
- it.Next();
- if (expected == 1)
- break;
- }
- }
-
- expected = 0;
- while (!it.AtEnd()) {
- UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
- expected += 2;
- it.Next();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(expected, 2 * k);
- }
- }
-}
-}
-}
+ TScopedAlloc alloc;
+ using TListType = TListRepresentation<ui32, 256>;
+ TListType list1;
+ auto it1 = list1.GetIterator();
+ UNIT_ASSERT(it1.AtEnd());
+
+ TListType list2(list1, 0);
+ auto it2 = list2.GetIterator();
+ UNIT_ASSERT(!it2.AtEnd());
+ UNIT_ASSERT_VALUES_EQUAL(it2.Current(), 0);
+ it2.Next();
+ UNIT_ASSERT(it2.AtEnd());
+
+ TVector<TListType> lists;
+ lists.push_back(list1);
+ const ui32 n = 100;
+ for (ui32 i = 0; i < n; ++i) {
+ auto c = i;
+ lists.push_back(TListType(lists.back(), std::move(c)));
+ }
+
+ for (ui32 i = 0; i < n; ++i) {
+ auto list = lists[i];
+ auto it = list.GetIterator();
+ ui32 expected = 0;
+ while (!it.AtEnd()) {
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
+ ++expected;
+ it.Next();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(expected, i);
+ }
+
+ for (ui32 i = 0; i < n; ++i) {
+ auto list = lists[i];
+ auto it = list.GetReverseIterator();
+ ui32 expected = i;
+ while (!it.AtEnd()) {
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), --expected);
+ it.Next();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(expected, 0);
+ }
+
+ TVector<TListType> rlists;
+ rlists.push_back(list1);
+ for (ui32 i = 0; i < n; ++i) {
+ auto c = i;
+ rlists.push_back(TListType(std::move(c), rlists.back()));
+ }
+
+ for (ui32 i = 0; i < n; ++i) {
+ auto list = rlists[i];
+ auto it = list.GetIterator();
+ ui32 expected = i;
+ while (!it.AtEnd()) {
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), --expected);
+ it.Next();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(expected, 0);
+ }
+
+ for (ui32 i = 0; i < n; ++i) {
+ auto list = rlists[i];
+ auto it = list.GetReverseIterator();
+ ui32 expected = 0;
+ while (!it.AtEnd()) {
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
+ ++expected;
+ it.Next();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(expected, i);
+ }
+
+ TVector<TListType> zlists;
+ zlists.push_back(list1);
+ for (ui32 i = 0; i < n; ++i) {
+ zlists.push_back(zlists.back().Append(2 * i));
+ zlists.push_back(zlists.back().Prepend(2 * i + 1));
+ }
+
+ for (ui32 i = 0; i < 2 * n; ++i) {
+ ui32 k = (i + 1) / 2;
+ auto list = zlists[i];
+ auto it = list.GetIterator();
+ ui32 expected = 2 * k + 1;
+ if ((i % 2))
+ expected -= 2;
+
+ if (i >= 2) {
+ while (!it.AtEnd()) {
+ expected -= 2;
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
+ it.Next();
+ if (expected == 1)
+ break;
+ }
+ }
+
+ expected = 0;
+ while (!it.AtEnd()) {
+ UNIT_ASSERT_VALUES_EQUAL(it.Current(), expected);
+ expected += 2;
+ it.Next();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(expected, 2 * k);
+ }
+ }
+}
+}
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_pack.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_pack.cpp
index ab7d824344..625a269eaf 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_pack.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_pack.cpp
@@ -12,13 +12,13 @@
#include <ydb/library/yql/utils/fp_bits.h>
#ifndef MKQL_DISABLE_CODEGEN
-#include <llvm/IR/Constants.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Instructions.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
+#include <llvm/IR/Constants.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
#endif
-
+
#include <util/system/yassert.h>
#include <util/system/sanitizers.h>
@@ -26,9 +26,9 @@ namespace NKikimr {
namespace NMiniKQL {
#ifndef MKQL_DISABLE_CODEGEN
-using namespace llvm;
+using namespace llvm;
#endif
-
+
namespace NDetails {
void PackUInt64(ui64 val, TBuffer& buf) {
@@ -114,31 +114,31 @@ T GetRawData(TStringBuf& buf) {
} // NDetails
-namespace {
+namespace {
#ifndef MKQL_DISABLE_CODEGEN
TString MakeName(const TStringBuf& common, const TType* type) {
- TStringStream out;
- out << common << intptr_t(type);
- return out.Str();
- }
-
- BasicBlock* CreatePackBlock(const TType* type, bool useTopLength, const Module &module, LLVMContext &context, Function* pack, BasicBlock* block, Value* value, Value* buffer, Value* mask) {
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
-
- switch (type->GetKind()) {
- case TType::EKind::Data: {
- const auto dataType = static_cast<const TDataType*>(type);
+ TStringStream out;
+ out << common << intptr_t(type);
+ return out.Str();
+ }
+
+ BasicBlock* CreatePackBlock(const TType* type, bool useTopLength, const Module &module, LLVMContext &context, Function* pack, BasicBlock* block, Value* value, Value* buffer, Value* mask) {
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+
+ switch (type->GetKind()) {
+ case TType::EKind::Data: {
+ const auto dataType = static_cast<const TDataType*>(type);
switch (*dataType->GetDataSlot()) {
case NUdf::EDataSlot::Bool:
- CallInst::Create(module.getFunction("PackBool"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackBool"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Int8:
Y_FAIL("Not impl");
break;
case NUdf::EDataSlot::Uint8:
- CallInst::Create(module.getFunction("PackByte"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackByte"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Int16:
Y_FAIL("Not impl");
break;
@@ -146,231 +146,231 @@ namespace {
Y_FAIL("Not impl");
break;
case NUdf::EDataSlot::Int32:
- CallInst::Create(module.getFunction("PackInt32"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackInt32"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Uint32:
- CallInst::Create(module.getFunction("PackUInt32"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackUInt32"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Int64:
- CallInst::Create(module.getFunction("PackInt64"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackInt64"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Uint64:
- CallInst::Create(module.getFunction("PackUInt64"), {value, buffer}, "", block);
- break;
+ CallInst::Create(module.getFunction("PackUInt64"), {value, buffer}, "", block);
+ break;
case NUdf::EDataSlot::Float:
CallInst::Create(module.getFunction("PackFloat"), { value, buffer }, "", block);
break;
case NUdf::EDataSlot::Double:
CallInst::Create(module.getFunction("PackDouble"), { value, buffer }, "", block);
break;
- default:
- CallInst::Create(module.getFunction(useTopLength ? "PackStringData" : "PackString"), {value, buffer}, "", block);
- break;
- }
-
- return block;
- }
- case TType::EKind::Optional: {
- const auto optType = static_cast<const TOptionalType*>(type);
-
+ default:
+ CallInst::Create(module.getFunction(useTopLength ? "PackStringData" : "PackString"), {value, buffer}, "", block);
+ break;
+ }
+
+ return block;
+ }
+ case TType::EKind::Optional: {
+ const auto optType = static_cast<const TOptionalType*>(type);
+
const auto item = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "item", block);
- const auto hasi = CallInst::Create(module.getFunction("GetOptionalValue"), {value, item, mask}, "has", block);
-
- const auto done = BasicBlock::Create(context, "done", pack);
- const auto fill = BasicBlock::Create(context, "fill", pack);
-
- const auto zero = ConstantInt::getFalse(context);
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, hasi, zero, "cond", block);
-
- BranchInst::Create(done, fill, icmp, block);
-
- const auto next = CreatePackBlock(optType->GetItemType(), useTopLength, module, context, pack, fill, item, buffer, mask);
- BranchInst::Create(done, next);
- return done;
- }
- case TType::EKind::Struct: {
- const auto structType = static_cast<const TStructType*>(type);
- const auto getter = module.getFunction("GetElement");
+ const auto hasi = CallInst::Create(module.getFunction("GetOptionalValue"), {value, item, mask}, "has", block);
+
+ const auto done = BasicBlock::Create(context, "done", pack);
+ const auto fill = BasicBlock::Create(context, "fill", pack);
+
+ const auto zero = ConstantInt::getFalse(context);
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, hasi, zero, "cond", block);
+
+ BranchInst::Create(done, fill, icmp, block);
+
+ const auto next = CreatePackBlock(optType->GetItemType(), useTopLength, module, context, pack, fill, item, buffer, mask);
+ BranchInst::Create(done, next);
+ return done;
+ }
+ case TType::EKind::Struct: {
+ const auto structType = static_cast<const TStructType*>(type);
+ const auto getter = module.getFunction("GetElement");
const auto member = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "member", block);
- auto curr = block;
- for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
- const auto index = ConstantInt::get(Type::getInt32Ty(context), i);
- CallInst::Create(getter, {value, index, member}, "", curr);
- curr = CreatePackBlock(structType->GetMemberType(i), useTopLength, module, context, pack, curr, member, buffer, mask);
- }
- return curr;
- }
-
- case TType::EKind::Tuple: {
- const auto tupleType = static_cast<const TTupleType*>(type);
- const auto getter = module.getFunction("GetElement");
+ auto curr = block;
+ for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
+ const auto index = ConstantInt::get(Type::getInt32Ty(context), i);
+ CallInst::Create(getter, {value, index, member}, "", curr);
+ curr = CreatePackBlock(structType->GetMemberType(i), useTopLength, module, context, pack, curr, member, buffer, mask);
+ }
+ return curr;
+ }
+
+ case TType::EKind::Tuple: {
+ const auto tupleType = static_cast<const TTupleType*>(type);
+ const auto getter = module.getFunction("GetElement");
const auto element = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "item", block);
- auto curr = block;
- for (ui32 i = 0; i < tupleType->GetElementsCount(); ++i) {
- const auto index = ConstantInt::get(Type::getInt32Ty(context), i);
- CallInst::Create(getter, {value, index, element}, "", curr);
- curr = CreatePackBlock(tupleType->GetElementType(i), useTopLength, module, context, pack, curr, element, buffer, mask);
- }
- return curr;
- }
- case TType::EKind::Variant: {
- const auto variantType = static_cast<const TVariantType*>(type);
- const auto innerType = variantType->GetUnderlyingType();
-
- std::function<const TType* (ui32)> typeGetter;
- ui32 size = 0U;
-
- if (innerType->IsStruct()) {
- const auto structType = static_cast<const TStructType*>(innerType);
- typeGetter = std::bind(&TStructType::GetMemberType, structType, std::placeholders::_1);
- size = structType->GetMembersCount();
- } else if (innerType->IsTuple()) {
- const auto tupleType = static_cast<const TTupleType*>(innerType);
- typeGetter = std::bind(&TTupleType::GetElementType, tupleType, std::placeholders::_1);
- size = tupleType->GetElementsCount();
- } else {
- THROW yexception() << "Unexpected underlying variant type: " << innerType->GetKindAsStr();
- }
-
+ auto curr = block;
+ for (ui32 i = 0; i < tupleType->GetElementsCount(); ++i) {
+ const auto index = ConstantInt::get(Type::getInt32Ty(context), i);
+ CallInst::Create(getter, {value, index, element}, "", curr);
+ curr = CreatePackBlock(tupleType->GetElementType(i), useTopLength, module, context, pack, curr, element, buffer, mask);
+ }
+ return curr;
+ }
+ case TType::EKind::Variant: {
+ const auto variantType = static_cast<const TVariantType*>(type);
+ const auto innerType = variantType->GetUnderlyingType();
+
+ std::function<const TType* (ui32)> typeGetter;
+ ui32 size = 0U;
+
+ if (innerType->IsStruct()) {
+ const auto structType = static_cast<const TStructType*>(innerType);
+ typeGetter = std::bind(&TStructType::GetMemberType, structType, std::placeholders::_1);
+ size = structType->GetMembersCount();
+ } else if (innerType->IsTuple()) {
+ const auto tupleType = static_cast<const TTupleType*>(innerType);
+ typeGetter = std::bind(&TTupleType::GetElementType, tupleType, std::placeholders::_1);
+ size = tupleType->GetElementsCount();
+ } else {
+ THROW yexception() << "Unexpected underlying variant type: " << innerType->GetKindAsStr();
+ }
+
const auto variant = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "variant", block);
- const auto index = CallInst::Create(module.getFunction("GetVariantItem"), {value, variant, buffer}, "index", block);
-
- const auto exit = BasicBlock::Create(context, "exit", pack);
- const auto choise = SwitchInst::Create(index, exit, size, block);
-
- for (ui32 i = 0; i < size; ++i) {
+ const auto index = CallInst::Create(module.getFunction("GetVariantItem"), {value, variant, buffer}, "index", block);
+
+ const auto exit = BasicBlock::Create(context, "exit", pack);
+ const auto choise = SwitchInst::Create(index, exit, size, block);
+
+ for (ui32 i = 0; i < size; ++i) {
const auto var = BasicBlock::Create(context, (TString("case_") += ToString(i)).c_str(), pack);
- choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
- const auto done = CreatePackBlock(typeGetter(i), useTopLength, module, context, pack, var, variant, buffer, mask);
- BranchInst::Create(exit, done);
- }
-
- return exit;
- }
-
- case TType::EKind::List: {
- const auto listType = static_cast<const TListType*>(type);
-
- const auto iterType = Type::getInt64PtrTy(context);
- const auto zero = ConstantInt::getFalse(context);
+ choise->addCase(ConstantInt::get(Type::getInt32Ty(context), i), var);
+ const auto done = CreatePackBlock(typeGetter(i), useTopLength, module, context, pack, var, variant, buffer, mask);
+ BranchInst::Create(exit, done);
+ }
+
+ return exit;
+ }
+
+ case TType::EKind::List: {
+ const auto listType = static_cast<const TListType*>(type);
+
+ const auto iterType = Type::getInt64PtrTy(context);
+ const auto zero = ConstantInt::getFalse(context);
const auto iter = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "iter", block);
-
- const auto begin = CallInst::Create(module.getFunction("GetListIterator"), {value, iter, buffer}, "iterator", block);
+
+ const auto begin = CallInst::Create(module.getFunction("GetListIterator"), {value, iter, buffer}, "iterator", block);
const auto item = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "item", block);
-
- const auto loop = BasicBlock::Create(context, "loop", pack);
- BranchInst::Create(loop, block);
-
- const auto next = CallInst::Create(module.getFunction("NextListItem"), {iter, item}, "next", loop);
-
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, next, zero, "cond", loop);
- const auto exit = BasicBlock::Create(context, "exit", pack);
- const auto good = BasicBlock::Create(context, "good", pack);
-
- BranchInst::Create(exit, good, icmp, loop);
-
- const auto done = CreatePackBlock(listType->GetItemType(), useTopLength, module, context, pack, good, item, buffer, mask);
- BranchInst::Create(loop, done);
- return exit;
- }
-
- case TType::EKind::Dict: {
- const auto dictType = static_cast<const TDictType*>(type);
-
- const auto iterType = Type::getInt64PtrTy(context);
- const auto zero = ConstantInt::getFalse(context);
+
+ const auto loop = BasicBlock::Create(context, "loop", pack);
+ BranchInst::Create(loop, block);
+
+ const auto next = CallInst::Create(module.getFunction("NextListItem"), {iter, item}, "next", loop);
+
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, next, zero, "cond", loop);
+ const auto exit = BasicBlock::Create(context, "exit", pack);
+ const auto good = BasicBlock::Create(context, "good", pack);
+
+ BranchInst::Create(exit, good, icmp, loop);
+
+ const auto done = CreatePackBlock(listType->GetItemType(), useTopLength, module, context, pack, good, item, buffer, mask);
+ BranchInst::Create(loop, done);
+ return exit;
+ }
+
+ case TType::EKind::Dict: {
+ const auto dictType = static_cast<const TDictType*>(type);
+
+ const auto iterType = Type::getInt64PtrTy(context);
+ const auto zero = ConstantInt::getFalse(context);
const auto iter = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "iter", block);
-
- const auto begin = CallInst::Create(module.getFunction("GetDictIterator"), {value, iter, buffer}, "iterator", block);
+
+ const auto begin = CallInst::Create(module.getFunction("GetDictIterator"), {value, iter, buffer}, "iterator", block);
const auto first = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "first", block);
const auto second = new AllocaInst(valueType, 0U, nullptr, llvm::Align(16), "second", block);
-
- const auto loop = BasicBlock::Create(context, "loop", pack);
- BranchInst::Create(loop, block);
-
- const auto next = CallInst::Create(module.getFunction("NextDictItem"), {iter, first, second}, "next", loop);
-
- const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, next, zero, "cond", loop);
- const auto exit = BasicBlock::Create(context, "exit", pack);
- const auto good = BasicBlock::Create(context, "good", pack);
-
- BranchInst::Create(exit, good, icmp, loop);
-
- const auto one = CreatePackBlock(dictType->GetKeyType(), useTopLength, module, context, pack, good, first, buffer, mask);
- const auto two = CreatePackBlock(dictType->GetPayloadType(), useTopLength, module, context, pack, one, second, buffer, mask);
-
- BranchInst::Create(loop, two);
- return exit;
- }
- }
+
+ const auto loop = BasicBlock::Create(context, "loop", pack);
+ BranchInst::Create(loop, block);
+
+ const auto next = CallInst::Create(module.getFunction("NextDictItem"), {iter, first, second}, "next", loop);
+
+ const auto icmp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, next, zero, "cond", loop);
+ const auto exit = BasicBlock::Create(context, "exit", pack);
+ const auto good = BasicBlock::Create(context, "good", pack);
+
+ BranchInst::Create(exit, good, icmp, loop);
+
+ const auto one = CreatePackBlock(dictType->GetKeyType(), useTopLength, module, context, pack, good, first, buffer, mask);
+ const auto two = CreatePackBlock(dictType->GetPayloadType(), useTopLength, module, context, pack, one, second, buffer, mask);
+
+ BranchInst::Create(loop, two);
+ return exit;
+ }
+ }
Y_UNREACHABLE();
- }
-
- Function* CreatePackFunction(const TType* type, bool useTopLength, Module &module, LLVMContext &context) {
- const auto& name = MakeName("Pack:", type);
- if (const auto f = module.getFunction(name.c_str()))
- return f;
-
- const auto valueType = Type::getInt128Ty(context);
- const auto ptrValueType = PointerType::getUnqual(valueType);
- const auto packFuncType = FunctionType::get(Type::getVoidTy(context), {ptrValueType, Type::getInt64PtrTy(context), Type::getInt64PtrTy(context)}, false);
+ }
+
+ Function* CreatePackFunction(const TType* type, bool useTopLength, Module &module, LLVMContext &context) {
+ const auto& name = MakeName("Pack:", type);
+ if (const auto f = module.getFunction(name.c_str()))
+ return f;
+
+ const auto valueType = Type::getInt128Ty(context);
+ const auto ptrValueType = PointerType::getUnqual(valueType);
+ const auto packFuncType = FunctionType::get(Type::getVoidTy(context), {ptrValueType, Type::getInt64PtrTy(context), Type::getInt64PtrTy(context)}, false);
const auto pack = cast<Function>(module.getOrInsertFunction(name.c_str(), packFuncType).getCallee());
-
- auto argsIt = pack->arg_begin();
- const auto value = argsIt;
- const auto buffer = ++argsIt;
- const auto mask = ++argsIt;
-
- value->setName("Value");
- buffer->setName("Buffer");
- mask->setName("Mask");
-
- const auto main = BasicBlock::Create(context, "main", pack);
- const auto last = CreatePackBlock(type, useTopLength, module, context, pack, main, &*value, &*buffer, &*mask);
- ReturnInst::Create(context, last);
-
-// pack->addFnAttr("target-cpu", "x86-64");
-// pack->addFnAttr("target-features", "+sse,+sse2,+sse3");
-
- return pack;
- }
+
+ auto argsIt = pack->arg_begin();
+ const auto value = argsIt;
+ const auto buffer = ++argsIt;
+ const auto mask = ++argsIt;
+
+ value->setName("Value");
+ buffer->setName("Buffer");
+ mask->setName("Mask");
+
+ const auto main = BasicBlock::Create(context, "main", pack);
+ const auto last = CreatePackBlock(type, useTopLength, module, context, pack, main, &*value, &*buffer, &*mask);
+ ReturnInst::Create(context, last);
+
+// pack->addFnAttr("target-cpu", "x86-64");
+// pack->addFnAttr("target-features", "+sse,+sse2,+sse3");
+
+ return pack;
+ }
#endif
-}
-
+}
+
TValuePacker::TValuePacker(bool stable, const TType* type, bool tryUseCodegen)
#ifndef MKQL_DISABLE_CODEGEN
-#ifdef __llvm__
- : Codegen(tryUseCodegen ? NYql::NCodegen::ICodegen::Make(NYql::NCodegen::ETarget::Native) : NYql::NCodegen::ICodegen::TPtr())
-#else
- : Codegen()
-#endif
+#ifdef __llvm__
+ : Codegen(tryUseCodegen ? NYql::NCodegen::ICodegen::Make(NYql::NCodegen::ETarget::Native) : NYql::NCodegen::ICodegen::TPtr())
+#else
+ : Codegen()
+#endif
, Stable(stable)
#else
: Stable(stable)
#endif
, Type(type)
- , Properties(ScanTypeProperties(Type))
- , OptionalMaskReserve(Properties.Test(EProps::UseOptionalMask) ? 1 : 0)
- , PackFunc(MakePackFunction())
-{
+ , Properties(ScanTypeProperties(Type))
+ , OptionalMaskReserve(Properties.Test(EProps::UseOptionalMask) ? 1 : 0)
+ , PackFunc(MakePackFunction())
+{
#ifndef MKQL_DISABLE_CODEGEN
- if (Codegen) {
- Codegen->Verify();
- Codegen->Compile();
- }
+ if (Codegen) {
+ Codegen->Verify();
+ Codegen->Compile();
+ }
#else
Y_UNUSED(tryUseCodegen);
#endif
-}
-
-TValuePacker::TValuePacker(const TValuePacker& other)
+}
+
+TValuePacker::TValuePacker(const TValuePacker& other)
: Stable(other.Stable)
, Type(other.Type)
- , Properties(other.Properties)
- , OptionalMaskReserve(other.OptionalMaskReserve)
- , PackFunc(other.PackFunc)
-{}
-
+ , Properties(other.Properties)
+ , OptionalMaskReserve(other.OptionalMaskReserve)
+ , PackFunc(other.PackFunc)
+{}
+
std::pair<ui32, bool> TValuePacker::SkipEmbeddedLength(TStringBuf& buf) {
ui32 length = 0;
bool emptySingleOptional = false;
@@ -397,16 +397,16 @@ NUdf::TUnboxedValue TValuePacker::Unpack(TStringBuf buf, const THolderFactory& h
if (Properties.Test(EProps::UseOptionalMask)) {
OptionalUsageMask.Reset(buf);
}
- NUdf::TUnboxedValue res;
+ NUdf::TUnboxedValue res;
if (Properties.Test(EProps::SingleOptional) && emptySingleOptional) {
- res = NUdf::TUnboxedValuePod();
+ res = NUdf::TUnboxedValuePod();
} else if (Type->IsStruct()) {
- auto structType = static_cast<const TStructType*>(Type);
- NUdf::TUnboxedValue * items = nullptr;
- res = TopStruct.NewArray(holderFactory, structType->GetMembersCount(), items);
+ auto structType = static_cast<const TStructType*>(Type);
+ NUdf::TUnboxedValue * items = nullptr;
+ res = TopStruct.NewArray(holderFactory, structType->GetMembersCount(), items);
for (ui32 index = 0; index < structType->GetMembersCount(); ++index) {
auto memberType = structType->GetMemberType(index);
- *items++ = UnpackImpl(memberType, buf, length, holderFactory);
+ *items++ = UnpackImpl(memberType, buf, length, holderFactory);
}
} else {
res = UnpackImpl(Type, buf, length, holderFactory);
@@ -416,12 +416,12 @@ NUdf::TUnboxedValue TValuePacker::Unpack(TStringBuf buf, const THolderFactory& h
return res;
}
-NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf, ui32 topLength,
+NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf, ui32 topLength,
const THolderFactory& holderFactory) const
{
switch (type->GetKind()) {
case TType::EKind::Void:
- return NUdf::TUnboxedValuePod::Void();
+ return NUdf::TUnboxedValuePod::Void();
case TType::EKind::Null:
return NUdf::TUnboxedValuePod();
case TType::EKind::EmptyList:
@@ -430,30 +430,30 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
return holderFactory.GetEmptyContainer();
case TType::EKind::Data: {
- auto dataType = static_cast<const TDataType*>(type);
+ auto dataType = static_cast<const TDataType*>(type);
switch (*dataType->GetDataSlot()) {
case NUdf::EDataSlot::Bool:
- return NUdf::TUnboxedValuePod(NDetails::GetRawData<bool>(buf));
+ return NUdf::TUnboxedValuePod(NDetails::GetRawData<bool>(buf));
case NUdf::EDataSlot::Int8:
return NUdf::TUnboxedValuePod(NDetails::GetRawData<i8>(buf));
case NUdf::EDataSlot::Uint8:
- return NUdf::TUnboxedValuePod(NDetails::GetRawData<ui8>(buf));
+ return NUdf::TUnboxedValuePod(NDetails::GetRawData<ui8>(buf));
case NUdf::EDataSlot::Int16:
return NUdf::TUnboxedValuePod(NDetails::UnpackInt16(buf));
case NUdf::EDataSlot::Uint16:
return NUdf::TUnboxedValuePod(NDetails::UnpackUInt16(buf));
case NUdf::EDataSlot::Int32:
- return NUdf::TUnboxedValuePod(NDetails::UnpackInt32(buf));
+ return NUdf::TUnboxedValuePod(NDetails::UnpackInt32(buf));
case NUdf::EDataSlot::Uint32:
- return NUdf::TUnboxedValuePod(NDetails::UnpackUInt32(buf));
+ return NUdf::TUnboxedValuePod(NDetails::UnpackUInt32(buf));
case NUdf::EDataSlot::Int64:
- return NUdf::TUnboxedValuePod(NDetails::UnpackInt64(buf));
+ return NUdf::TUnboxedValuePod(NDetails::UnpackInt64(buf));
case NUdf::EDataSlot::Uint64:
- return NUdf::TUnboxedValuePod(NDetails::UnpackUInt64(buf));
+ return NUdf::TUnboxedValuePod(NDetails::UnpackUInt64(buf));
case NUdf::EDataSlot::Float:
- return NUdf::TUnboxedValuePod(NDetails::GetRawData<float>(buf));
+ return NUdf::TUnboxedValuePod(NDetails::GetRawData<float>(buf));
case NUdf::EDataSlot::Double:
- return NUdf::TUnboxedValuePod(NDetails::GetRawData<double>(buf));
+ return NUdf::TUnboxedValuePod(NDetails::GetRawData<double>(buf));
case NUdf::EDataSlot::Date:
return NUdf::TUnboxedValuePod(NDetails::UnpackUInt16(buf));
case NUdf::EDataSlot::Datetime:
@@ -491,9 +491,9 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
}
case NUdf::EDataSlot::Decimal: {
const auto des = NYql::NDecimal::Deserialize(buf.data());
- MKQL_ENSURE(!NYql::NDecimal::IsError(des.first), "Bad packed data: invalid decimal.");
- buf.Skip(des.second);
- return NUdf::TUnboxedValuePod(des.first);
+ MKQL_ENSURE(!NYql::NDecimal::IsError(des.first), "Bad packed data: invalid decimal.");
+ buf.Skip(des.second);
+ return NUdf::TUnboxedValuePod(des.first);
}
default:
ui32 size = 0;
@@ -505,57 +505,57 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
MKQL_ENSURE(size <= buf.size(), "Bad packed data. Buffer too small");
const char* ptr = buf.data();
buf.Skip(size);
- return MakeString(NUdf::TStringRef(ptr, size));
+ return MakeString(NUdf::TStringRef(ptr, size));
}
break;
}
case TType::EKind::Optional: {
- auto optionalType = static_cast<const TOptionalType*>(type);
+ auto optionalType = static_cast<const TOptionalType*>(type);
if (!OptionalUsageMask.IsNextEmptyOptional()) {
- return UnpackImpl(optionalType->GetItemType(), buf, topLength, holderFactory).Release().MakeOptional();
+ return UnpackImpl(optionalType->GetItemType(), buf, topLength, holderFactory).Release().MakeOptional();
}
else {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
}
case TType::EKind::List: {
- auto listType = static_cast<const TListType*>(type);
+ auto listType = static_cast<const TListType*>(type);
auto itemType = listType->GetItemType();
- const auto len = NDetails::UnpackUInt64(buf);
- NUdf::TUnboxedValue *items = nullptr;
- auto list = holderFactory.CreateDirectArrayHolder(len, items);
+ const auto len = NDetails::UnpackUInt64(buf);
+ NUdf::TUnboxedValue *items = nullptr;
+ auto list = holderFactory.CreateDirectArrayHolder(len, items);
for (ui64 i = 0; i < len; ++i) {
- *items++ = UnpackImpl(itemType, buf, topLength, holderFactory);
+ *items++ = UnpackImpl(itemType, buf, topLength, holderFactory);
}
- return std::move(list);
+ return std::move(list);
}
case TType::EKind::Struct: {
- auto structType = static_cast<const TStructType*>(type);
+ auto structType = static_cast<const TStructType*>(type);
NUdf::TUnboxedValue* itemsPtr = nullptr;
- auto res = holderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), itemsPtr);
+ auto res = holderFactory.CreateDirectArrayHolder(structType->GetMembersCount(), itemsPtr);
for (ui32 index = 0; index < structType->GetMembersCount(); ++index) {
auto memberType = structType->GetMemberType(index);
itemsPtr[index] = UnpackImpl(memberType, buf, topLength, holderFactory);
}
- return std::move(res);
+ return std::move(res);
}
case TType::EKind::Tuple: {
- auto tupleType = static_cast<const TTupleType*>(type);
+ auto tupleType = static_cast<const TTupleType*>(type);
NUdf::TUnboxedValue* itemsPtr = nullptr;
- auto res = holderFactory.CreateDirectArrayHolder(tupleType->GetElementsCount(), itemsPtr);
+ auto res = holderFactory.CreateDirectArrayHolder(tupleType->GetElementsCount(), itemsPtr);
for (ui32 index = 0; index < tupleType->GetElementsCount(); ++index) {
auto elementType = tupleType->GetElementType(index);
itemsPtr[index] = UnpackImpl(elementType, buf, topLength, holderFactory);
}
- return std::move(res);
+ return std::move(res);
}
case TType::EKind::Dict: {
- auto dictType = static_cast<const TDictType*>(type);
+ auto dictType = static_cast<const TDictType*>(type);
auto keyType = dictType->GetKeyType();
auto payloadType = dictType->GetPayloadType();
auto dictBuilder = holderFactory.NewDict(dictType, NUdf::TDictFlags::EDictKind::Hashed);
@@ -564,13 +564,13 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
for (ui64 i = 0; i < len; ++i) {
auto key = UnpackImpl(keyType, buf, topLength, holderFactory);
auto payload = UnpackImpl(payloadType, buf, topLength, holderFactory);
- dictBuilder->Add(std::move(key), std::move(payload));
+ dictBuilder->Add(std::move(key), std::move(payload));
}
return dictBuilder->Build();
}
case TType::EKind::Variant: {
- auto variantType = static_cast<const TVariantType*>(type);
+ auto variantType = static_cast<const TVariantType*>(type);
ui32 variantIndex = NDetails::UnpackUInt32(buf);
TType* innerType = variantType->GetUnderlyingType();
if (innerType->IsStruct()) {
@@ -579,7 +579,7 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
MKQL_ENSURE(innerType->IsTuple(), "Unexpected underlying variant type: " << innerType->GetKindAsStr());
innerType = static_cast<TTupleType*>(innerType)->GetElementType(variantIndex);
}
- return holderFactory.CreateVariantHolder(UnpackImpl(innerType, buf, topLength, holderFactory).Release(), variantIndex);
+ return holderFactory.CreateVariantHolder(UnpackImpl(innerType, buf, topLength, holderFactory).Release(), variantIndex);
}
case TType::EKind::Tagged: {
@@ -594,20 +594,20 @@ NUdf::TUnboxedValue TValuePacker::UnpackImpl(const TType* type, TStringBuf& buf,
TStringBuf TValuePacker::Pack(const NUdf::TUnboxedValuePod& value) const {
OptionalUsageMask.Reset();
- const size_t lengthReserve = sizeof(ui32);
+ const size_t lengthReserve = sizeof(ui32);
Buffer.Proceed(lengthReserve + OptionalMaskReserve);
- if (PackFunc)
- PackFunc(reinterpret_cast<const TRawUV*>(&value), reinterpret_cast<ui64*>(&Buffer), reinterpret_cast<ui64*>(&OptionalUsageMask));
- else
- PackImpl(Type, value);
-
+ if (PackFunc)
+ PackFunc(reinterpret_cast<const TRawUV*>(&value), reinterpret_cast<ui64*>(&Buffer), reinterpret_cast<ui64*>(&OptionalUsageMask));
+ else
+ PackImpl(Type, value);
+
size_t delta = 0;
size_t len = Buffer.Size();
if (Properties.Test(EProps::UseOptionalMask)) {
// Prepend optional mask
- const size_t actualOptionalMaskSize = OptionalUsageMask.CalcSerializedSize();
+ const size_t actualOptionalMaskSize = OptionalUsageMask.CalcSerializedSize();
if (actualOptionalMaskSize > OptionalMaskReserve) {
TBuffer buf(Buffer.Size() + actualOptionalMaskSize - OptionalMaskReserve);
@@ -625,7 +625,7 @@ TStringBuf TValuePacker::Pack(const NUdf::TUnboxedValuePod& value) const {
// Prepend length
if (len - delta - lengthReserve > 7) {
- const ui32 length = len - delta - lengthReserve;
+ const ui32 length = len - delta - lengthReserve;
Buffer.Proceed(delta);
Buffer.Append((const char*)&length, sizeof(length));
// Long length always singnals non-empty optional. So, don't check EProps::SingleOptional here
@@ -655,7 +655,7 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
break;
case TType::EKind::Data: {
- auto dataType = static_cast<const TDataType*>(type);
+ auto dataType = static_cast<const TDataType*>(type);
switch (*dataType->GetDataSlot()) {
case NUdf::EDataSlot::Bool:
NDetails::PutRawData(value.Get<bool>(), Buffer);
@@ -735,8 +735,8 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
break;
}
case NUdf::EDataSlot::Decimal: {
- char buff[0x10U];
- Buffer.Append(buff, NYql::NDecimal::Serialize(value.GetInt128(), buff));
+ char buff[0x10U];
+ Buffer.Append(buff, NYql::NDecimal::Serialize(value.GetInt128(), buff));
break;
}
default: {
@@ -751,35 +751,35 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
}
case TType::EKind::Optional: {
- auto optionalType = static_cast<const TOptionalType*>(type);
- OptionalUsageMask.SetNextEmptyOptional(!value);
- if (value) {
+ auto optionalType = static_cast<const TOptionalType*>(type);
+ OptionalUsageMask.SetNextEmptyOptional(!value);
+ if (value) {
PackImpl(optionalType->GetItemType(), value.GetOptionalValue());
}
break;
}
case TType::EKind::List: {
- auto listType = static_cast<const TListType*>(type);
+ auto listType = static_cast<const TListType*>(type);
auto itemType = listType->GetItemType();
if (value.HasFastListLength()) {
- auto len = value.GetListLength();
- NDetails::PackUInt64(len, Buffer);
- if (len) {
- if (auto p = value.GetElements()) {
- value.GetListIterator();
- do PackImpl(itemType, *p++);
- while (--len);
- } else if (const auto iter = value.GetListIterator()) {
- for (NUdf::TUnboxedValue item; iter.Next(item); PackImpl(itemType, item))
- continue;
- }
+ auto len = value.GetListLength();
+ NDetails::PackUInt64(len, Buffer);
+ if (len) {
+ if (auto p = value.GetElements()) {
+ value.GetListIterator();
+ do PackImpl(itemType, *p++);
+ while (--len);
+ } else if (const auto iter = value.GetListIterator()) {
+ for (NUdf::TUnboxedValue item; iter.Next(item); PackImpl(itemType, item))
+ continue;
+ }
}
} else {
- TUnboxedValueVector items;
- const auto iter = value.GetListIterator();
- for (NUdf::TUnboxedValue item; iter.Next(item);) {
- items.emplace_back(std::move(item));
+ TUnboxedValueVector items;
+ const auto iter = value.GetListIterator();
+ for (NUdf::TUnboxedValue item; iter.Next(item);) {
+ items.emplace_back(std::move(item));
}
NDetails::PackUInt64(items.size(), Buffer);
@@ -791,31 +791,31 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
}
case TType::EKind::Struct: {
- auto structType = static_cast<const TStructType*>(type);
+ auto structType = static_cast<const TStructType*>(type);
for (ui32 index = 0; index < structType->GetMembersCount(); ++index) {
auto memberType = structType->GetMemberType(index);
- PackImpl(memberType, value.GetElement(index));
+ PackImpl(memberType, value.GetElement(index));
}
break;
}
case TType::EKind::Tuple: {
- auto tupleType = static_cast<const TTupleType*>(type);
+ auto tupleType = static_cast<const TTupleType*>(type);
for (ui32 index = 0; index < tupleType->GetElementsCount(); ++index) {
auto elementType = tupleType->GetElementType(index);
- PackImpl(elementType, value.GetElement(index));
+ PackImpl(elementType, value.GetElement(index));
}
break;
}
case TType::EKind::Dict: {
- auto dictType = static_cast<const TDictType*>(type);
+ auto dictType = static_cast<const TDictType*>(type);
auto keyType = dictType->GetKeyType();
auto payloadType = dictType->GetPayloadType();
auto length = value.GetDictLength();
NDetails::PackUInt64(length, Buffer);
- const auto iter = value.GetDictIterator();
+ const auto iter = value.GetDictIterator();
if (Stable && !value.IsSortedDict()) {
// no key duplicates here
TKeyTypes types;
@@ -876,7 +876,7 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
}
case TType::EKind::Variant: {
- auto variantType = static_cast<const TVariantType*>(type);
+ auto variantType = static_cast<const TVariantType*>(type);
ui32 variantIndex = value.GetVariantIndex();
TType* innerType = variantType->GetUnderlyingType();
if (innerType->IsStruct()) {
@@ -895,15 +895,15 @@ void TValuePacker::PackImpl(const TType* type, const NUdf::TUnboxedValuePod& val
}
}
-
-
-TValuePacker::TProperties TValuePacker::ScanTypeProperties(const TType* type) {
+
+
+TValuePacker::TProperties TValuePacker::ScanTypeProperties(const TType* type) {
TProperties props;
if (HasOptionalFields(type)) {
props.Set(EProps::UseOptionalMask);
}
if (type->GetKind() == TType::EKind::Optional) {
- type = static_cast<const TOptionalType*>(type)->GetItemType();
+ type = static_cast<const TOptionalType*>(type)->GetItemType();
if (!HasOptionalFields(type)) {
props.Set(EProps::SingleOptional);
props.Reset(EProps::UseOptionalMask);
@@ -912,7 +912,7 @@ TValuePacker::TProperties TValuePacker::ScanTypeProperties(const TType* type) {
// Here and after the type is unwrapped!!
if (type->GetKind() == TType::EKind::Data) {
- auto dataType = static_cast<const TDataType*>(type);
+ auto dataType = static_cast<const TDataType*>(type);
switch (*dataType->GetDataSlot()) {
case NUdf::EDataSlot::String:
case NUdf::EDataSlot::Json:
@@ -929,7 +929,7 @@ TValuePacker::TProperties TValuePacker::ScanTypeProperties(const TType* type) {
return props;
}
-bool TValuePacker::HasOptionalFields(const TType* type) {
+bool TValuePacker::HasOptionalFields(const TType* type) {
switch (type->GetKind()) {
case TType::EKind::Void:
case TType::EKind::Null:
@@ -942,10 +942,10 @@ bool TValuePacker::HasOptionalFields(const TType* type) {
return true;
case TType::EKind::List:
- return HasOptionalFields(static_cast<const TListType*>(type)->GetItemType());
+ return HasOptionalFields(static_cast<const TListType*>(type)->GetItemType());
case TType::EKind::Struct: {
- auto structType = static_cast<const TStructType*>(type);
+ auto structType = static_cast<const TStructType*>(type);
for (ui32 index = 0; index < structType->GetMembersCount(); ++index) {
if (HasOptionalFields(structType->GetMemberType(index))) {
return true;
@@ -955,7 +955,7 @@ bool TValuePacker::HasOptionalFields(const TType* type) {
}
case TType::EKind::Tuple: {
- auto tupleType = static_cast<const TTupleType*>(type);
+ auto tupleType = static_cast<const TTupleType*>(type);
for (ui32 index = 0; index < tupleType->GetElementsCount(); ++index) {
if (HasOptionalFields(tupleType->GetElementType(index))) {
return true;
@@ -965,12 +965,12 @@ bool TValuePacker::HasOptionalFields(const TType* type) {
}
case TType::EKind::Dict: {
- auto dictType = static_cast<const TDictType*>(type);
+ auto dictType = static_cast<const TDictType*>(type);
return HasOptionalFields(dictType->GetKeyType()) || HasOptionalFields(dictType->GetPayloadType());
}
case TType::EKind::Variant: {
- auto variantType = static_cast<const TVariantType*>(type);
+ auto variantType = static_cast<const TVariantType*>(type);
return HasOptionalFields(variantType->GetUnderlyingType());
}
@@ -984,19 +984,19 @@ bool TValuePacker::HasOptionalFields(const TType* type) {
}
}
-TValuePacker::TPackFunction
-TValuePacker::MakePackFunction() {
+TValuePacker::TPackFunction
+TValuePacker::MakePackFunction() {
#ifdef MKQL_DISABLE_CODEGEN
return nullptr;
#else
- if (!Codegen)
- return nullptr;
-
- Codegen->LoadBitCode(NResource::Find("/llvm_bc/mkql_pack.bc"), "mkql_pack");
- return reinterpret_cast<TPackFunction>(Codegen->GetPointerToFunction(CreatePackFunction(Type, Properties.Test(EProps::UseTopLength), Codegen->GetModule(), Codegen->GetContext())));
+ if (!Codegen)
+ return nullptr;
+
+ Codegen->LoadBitCode(NResource::Find("/llvm_bc/mkql_pack.bc"), "mkql_pack");
+ return reinterpret_cast<TPackFunction>(Codegen->GetPointerToFunction(CreatePackFunction(Type, Properties.Test(EProps::UseTopLength), Codegen->GetModule(), Codegen->GetContext())));
#endif
-}
-
+}
+
TValuePackerBoxed::TValuePackerBoxed(TMemoryUsageInfo* memInfo, bool stable, const TType* type, bool tryUseCodegen)
: TBase(memInfo)
, TValuePacker(stable, type, tryUseCodegen)
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_pack.h b/ydb/library/yql/minikql/computation/mkql_computation_node_pack.h
index a93039d8e6..c69f4467a3 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_pack.h
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_pack.h
@@ -2,7 +2,7 @@
#include "mkql_computation_node.h"
#include "mkql_computation_node_holders.h"
-#include "mkql_optional_usage_mask.h"
+#include "mkql_optional_usage_mask.h"
#include <ydb/library/yql/public/udf/udf_value.h>
@@ -15,7 +15,7 @@
#ifndef MKQL_DISABLE_CODEGEN
#include <ydb/library/yql/minikql/codegen/codegen.h>
#endif
-
+
#include <utility>
namespace NKikimr {
@@ -33,7 +33,7 @@ private:
using TProperties = TEnumBitSet<EProps, EProps::Begin, EProps::End>;
public:
TValuePacker(bool stable, const TType* type, bool tryUseCodegen = false);
- TValuePacker(const TValuePacker& other);
+ TValuePacker(const TValuePacker& other);
// Returned buffer is temporary and should be copied before next Pack() call
TStringBuf Pack(const NUdf::TUnboxedValuePod& value) const;
@@ -42,18 +42,18 @@ public:
private:
void PackImpl(const TType* type, const NUdf::TUnboxedValuePod& value) const;
NUdf::TUnboxedValue UnpackImpl(const TType* type, TStringBuf& buf, ui32 topLength, const THolderFactory& holderFactory) const;
- static TProperties ScanTypeProperties(const TType* type);
- static bool HasOptionalFields(const TType* type);
+ static TProperties ScanTypeProperties(const TType* type);
+ static bool HasOptionalFields(const TType* type);
// Returns length and empty single optional flag
static std::pair<ui32, bool> SkipEmbeddedLength(TStringBuf& buf);
- typedef void(*TPackFunction)(const TRawUV*, ui64*, ui64*);
- TPackFunction MakePackFunction();
+ typedef void(*TPackFunction)(const TRawUV*, ui64*, ui64*);
+ TPackFunction MakePackFunction();
#ifndef MKQL_DISABLE_CODEGEN
- const NYql::NCodegen::ICodegen::TPtr Codegen;
+ const NYql::NCodegen::ICodegen::TPtr Codegen;
#endif
const bool Stable;
- const TType* Type;
+ const TType* Type;
// TODO: real thread safety with external state
mutable TBuffer Buffer;
TProperties Properties;
@@ -62,9 +62,9 @@ private:
mutable TPlainContainerCache TopStruct;
mutable TVector<TVector<std::pair<NUdf::TUnboxedValue, NUdf::TUnboxedValue>>> DictBuffers;
mutable TVector<TVector<std::tuple<NUdf::TUnboxedValue, NUdf::TUnboxedValue, NUdf::TUnboxedValue>>> EncodedDictBuffers;
- TPackFunction PackFunc = nullptr;
-
- friend struct TValuePackerDetails;
+ TPackFunction PackFunc = nullptr;
+
+ friend struct TValuePackerDetails;
};
class TValuePackerBoxed : public TComputationValue<TValuePackerBoxed>, public TValuePacker {
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_pack_ut.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_pack_ut.cpp
index 3ff13cbcbc..6a47b51829 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_pack_ut.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_pack_ut.cpp
@@ -17,7 +17,7 @@
#include <util/generic/maybe.h>
#include <util/string/cast.h>
#include <util/string/builder.h>
-#include <util/system/hp_timer.h>
+#include <util/system/hp_timer.h>
#include <util/system/sanitizers.h>
namespace NKikimr {
@@ -29,16 +29,16 @@ constexpr static size_t PERFORMANCE_COUNT = 0x1000;
constexpr static size_t PERFORMANCE_COUNT = NSan::PlainOrUnderSanitizer(0x4000000, 0x1000);
#endif
-template<bool UseCodegen>
+template<bool UseCodegen>
class TMiniKQLComputationNodePackTest: public TTestBase {
-protected:
+protected:
TMiniKQLComputationNodePackTest()
- : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
+ : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
, RandomProvider(CreateDefaultRandomProvider())
, Env(Alloc)
, PgmBuilder(Env, *FunctionRegistry)
, MemInfo("Memory")
- , HolderFactory(Alloc.Ref(), MemInfo, FunctionRegistry.Get())
+ , HolderFactory(Alloc.Ref(), MemInfo, FunctionRegistry.Get())
{
}
@@ -81,17 +81,17 @@ protected:
void TestListType() {
TDefaultListRepresentation listValues;
for (ui32 val: xrange(0, 10)) {
- listValues = listValues.Append(NUdf::TUnboxedValuePod(val));
+ listValues = listValues.Append(NUdf::TUnboxedValuePod(val));
}
TType* listType = PgmBuilder.NewListType(PgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
- const NUdf::TUnboxedValue value = HolderFactory.CreateDirectListHolder(std::move(listValues));
- const auto uValue = TestPackUnpack(listType, value, "Type:List(ui32)");
+ const NUdf::TUnboxedValue value = HolderFactory.CreateDirectListHolder(std::move(listValues));
+ const auto uValue = TestPackUnpack(listType, value, "Type:List(ui32)");
UNIT_ASSERT_VALUES_EQUAL(uValue.GetListLength(), 10);
ui32 i = 0;
- const auto iter = uValue.GetListIterator();
- for (NUdf::TUnboxedValue item; iter.Next(item); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), i);
+ const auto iter = uValue.GetListIterator();
+ for (NUdf::TUnboxedValue item; iter.Next(item); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), i);
}
UNIT_ASSERT_VALUES_EQUAL(i, 10);
}
@@ -99,32 +99,32 @@ protected:
void TestListOfOptionalsType() {
TDefaultListRepresentation listValues;
for (ui32 i: xrange(0, 10)) {
- NUdf::TUnboxedValue uVal = NUdf::TUnboxedValuePod();
+ NUdf::TUnboxedValue uVal = NUdf::TUnboxedValuePod();
if (i % 2) {
- uVal = MakeString(TString(i * 2, '0' + i));
+ uVal = MakeString(TString(i * 2, '0' + i));
}
- listValues = listValues.Append(std::move(uVal));
+ listValues = listValues.Append(std::move(uVal));
}
TType* listType = PgmBuilder.NewListType(PgmBuilder.NewOptionalType(PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)));
- const NUdf::TUnboxedValue value = HolderFactory.CreateDirectListHolder(std::move(listValues));
- const auto uValue = TestPackUnpack(listType, value, "Type:List(Optional(utf8))");
+ const NUdf::TUnboxedValue value = HolderFactory.CreateDirectListHolder(std::move(listValues));
+ const auto uValue = TestPackUnpack(listType, value, "Type:List(Optional(utf8))");
UNIT_ASSERT_VALUES_EQUAL(uValue.GetListLength(), 10);
ui32 i = 0;
- const auto iter = uValue.GetListIterator();
- for (NUdf::TUnboxedValue uVal; iter.Next(uVal); ++i) {
+ const auto iter = uValue.GetListIterator();
+ for (NUdf::TUnboxedValue uVal; iter.Next(uVal); ++i) {
if (i % 2) {
- UNIT_ASSERT(uVal);
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(uVal.AsStringRef()), TString(i * 2, '0' + i));
+ UNIT_ASSERT(uVal);
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(uVal.AsStringRef()), TString(i * 2, '0' + i));
} else {
- UNIT_ASSERT(!uVal);
+ UNIT_ASSERT(!uVal);
}
}
UNIT_ASSERT_VALUES_EQUAL(i, 10);
}
void TestTupleType() {
- std::vector<TType*> tupleElemenTypes;
+ std::vector<TType*> tupleElemenTypes;
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id));
tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
@@ -134,91 +134,91 @@ protected:
TType* tupleType = PgmBuilder.NewTupleType(tupleElemenTypes);
TUnboxedValueVector tupleElemens;
- tupleElemens.push_back(MakeString("01234567890123456789"));
- tupleElemens.push_back(MakeString("01234567890"));
- tupleElemens.push_back(NUdf::TUnboxedValuePod());
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
- tupleElemens.push_back(NUdf::TUnboxedValuePod());
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+ tupleElemens.push_back(MakeString("01234567890123456789"));
+ tupleElemens.push_back(MakeString("01234567890"));
+ tupleElemens.push_back(NUdf::TUnboxedValuePod());
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+ tupleElemens.push_back(NUdf::TUnboxedValuePod());
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
- const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
- const auto uValue = TestPackUnpack(tupleType, value, "Type:Tuple");
+ const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
+ const auto uValue = TestPackUnpack(tupleType, value, "Type:Tuple");
{
- auto e = uValue.GetElement(0);
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
+ auto e = uValue.GetElement(0);
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
}
{
- auto e = uValue.GetElement(1);
- UNIT_ASSERT(e);
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890");
+ auto e = uValue.GetElement(1);
+ UNIT_ASSERT(e);
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890");
}
{
- auto e = uValue.GetElement(2);
- UNIT_ASSERT(!e);
+ auto e = uValue.GetElement(2);
+ UNIT_ASSERT(!e);
}
{
- auto e = uValue.GetElement(3);
- UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
+ auto e = uValue.GetElement(3);
+ UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
}
{
- auto e = uValue.GetElement(4);
- UNIT_ASSERT(!e);
+ auto e = uValue.GetElement(4);
+ UNIT_ASSERT(!e);
}
{
- auto e = uValue.GetElement(5);
- UNIT_ASSERT(e);
- UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
+ auto e = uValue.GetElement(5);
+ UNIT_ASSERT(e);
+ UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
}
}
void TestStructType() {
- const std::vector<std::pair<std::string_view, TType*>> structElemenTypes = {
- {"a", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)},
- {"b", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
- {"c", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
- {"d", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)},
- {"e", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id, true)},
- {"f", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id, true)}
- };
+ const std::vector<std::pair<std::string_view, TType*>> structElemenTypes = {
+ {"a", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)},
+ {"b", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
+ {"c", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
+ {"d", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)},
+ {"e", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id, true)},
+ {"f", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id, true)}
+ };
TType* structType = PgmBuilder.NewStructType(structElemenTypes);
TUnboxedValueVector structElemens;
- structElemens.push_back(MakeString("01234567890123456789"));
- structElemens.push_back(MakeString("01234567890"));
- structElemens.push_back(NUdf::TUnboxedValuePod());
- structElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
- structElemens.push_back(NUdf::TUnboxedValuePod());
- structElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+ structElemens.push_back(MakeString("01234567890123456789"));
+ structElemens.push_back(MakeString("01234567890"));
+ structElemens.push_back(NUdf::TUnboxedValuePod());
+ structElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+ structElemens.push_back(NUdf::TUnboxedValuePod());
+ structElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
- const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(structElemens);
- const auto uValue = TestPackUnpack(structType, value, "Type:Struct");
+ const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(structElemens);
+ const auto uValue = TestPackUnpack(structType, value, "Type:Struct");
{
- auto e = uValue.GetElement(0);
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
+ auto e = uValue.GetElement(0);
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
}
{
- auto e = uValue.GetElement(1);
- UNIT_ASSERT(e);
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890");
+ auto e = uValue.GetElement(1);
+ UNIT_ASSERT(e);
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890");
}
{
- auto e = uValue.GetElement(2);
- UNIT_ASSERT(!e);
+ auto e = uValue.GetElement(2);
+ UNIT_ASSERT(!e);
}
{
- auto e = uValue.GetElement(3);
- UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
+ auto e = uValue.GetElement(3);
+ UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
}
{
- auto e = uValue.GetElement(4);
- UNIT_ASSERT(!e);
+ auto e = uValue.GetElement(4);
+ UNIT_ASSERT(!e);
}
{
- auto e = uValue.GetElement(5);
- UNIT_ASSERT(e);
- UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
+ auto e = uValue.GetElement(5);
+ UNIT_ASSERT(e);
+ UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345);
}
}
@@ -228,27 +228,27 @@ protected:
type = PgmBuilder.NewOptionalType(type);
type = PgmBuilder.NewOptionalType(type);
- NUdf::TUnboxedValue uValue = NUdf::TUnboxedValuePod();
+ NUdf::TUnboxedValue uValue = NUdf::TUnboxedValuePod();
uValue = TestPackUnpack(type, uValue, "Type:Optional, Value:null");
- UNIT_ASSERT(!uValue);
+ UNIT_ASSERT(!uValue);
- uValue = NUdf::TUnboxedValuePod(ui64(123));
+ uValue = NUdf::TUnboxedValuePod(ui64(123));
uValue = TestPackUnpack(type, uValue, "Type:Optional, Value:opt(opt(opt(123)))");
UNIT_ASSERT_VALUES_EQUAL(uValue.Get<ui64>(), 123);
- uValue = NUdf::TUnboxedValuePod().MakeOptional().MakeOptional();
+ uValue = NUdf::TUnboxedValuePod().MakeOptional().MakeOptional();
uValue = TestPackUnpack(type, uValue, "Type:Optional, Value:opt(opt(null))");
- UNIT_ASSERT(uValue);
+ UNIT_ASSERT(uValue);
uValue = uValue.GetOptionalValue();
- UNIT_ASSERT(uValue);
+ UNIT_ASSERT(uValue);
uValue = uValue.GetOptionalValue();
- UNIT_ASSERT(!uValue);
+ UNIT_ASSERT(!uValue);
- uValue = NUdf::TUnboxedValuePod().MakeOptional();
+ uValue = NUdf::TUnboxedValuePod().MakeOptional();
uValue = TestPackUnpack(type, uValue, "Type:Optional, Value:opt(null)");
- UNIT_ASSERT(uValue);
+ UNIT_ASSERT(uValue);
uValue = uValue.GetOptionalValue();
- UNIT_ASSERT(!uValue);
+ UNIT_ASSERT(!uValue);
}
void TestDictType() {
@@ -257,32 +257,32 @@ protected:
TType* dictType = PgmBuilder.NewDictType(keyType, payloadType, false);
TValuesDictHashSingleFixedMap<ui32> map;
- map[4] = NUdf::TUnboxedValuePod::Embedded("4");
- map[10] = NUdf::TUnboxedValuePod::Embedded("10");
- map[1] = NUdf::TUnboxedValuePod::Embedded("1");
- const NUdf::TUnboxedValue value = HolderFactory.CreateDirectHashedSingleFixedMapHolder<ui32>(std::move(map));
+ map[4] = NUdf::TUnboxedValuePod::Embedded("4");
+ map[10] = NUdf::TUnboxedValuePod::Embedded("10");
+ map[1] = NUdf::TUnboxedValuePod::Embedded("1");
+ const NUdf::TUnboxedValue value = HolderFactory.CreateDirectHashedSingleFixedMapHolder<ui32>(std::move(map));
- const auto uValue = TestPackUnpack(dictType, value, "Type:Dict");
+ const auto uValue = TestPackUnpack(dictType, value, "Type:Dict");
UNIT_ASSERT_VALUES_EQUAL(uValue.GetDictLength(), 3);
- const auto it = uValue.GetDictIterator();
- for (NUdf::TUnboxedValue key, payload; it.NextPair(key, payload);) {
- UNIT_ASSERT_VALUES_EQUAL(ToString(key.template Get<ui32>()), std::string_view(payload.AsStringRef()));
+ const auto it = uValue.GetDictIterator();
+ for (NUdf::TUnboxedValue key, payload; it.NextPair(key, payload);) {
+ UNIT_ASSERT_VALUES_EQUAL(ToString(key.template Get<ui32>()), std::string_view(payload.AsStringRef()));
}
}
void TestVariantTypeOverStruct() {
- const std::vector<std::pair<std::string_view, TType*>> structElemenTypes = {
- {"a", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)},
- {"b", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
- {"d", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)}
- };
+ const std::vector<std::pair<std::string_view, TType*>> structElemenTypes = {
+ {"a", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)},
+ {"b", PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id, true)},
+ {"d", PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id)}
+ };
TType* structType = PgmBuilder.NewStructType(structElemenTypes);
TestVariantTypeImpl(PgmBuilder.NewVariantType(structType));
}
void TestVariantTypeOverTuple() {
- std::vector<TType*> tupleElemenTypes;
+ std::vector<TType*> tupleElemenTypes;
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id));
tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id));
@@ -298,17 +298,17 @@ protected:
}
}
- void TestPackPerformance(TType* type, const NUdf::TUnboxedValuePod& uValue)
- {
+ void TestPackPerformance(TType* type, const NUdf::TUnboxedValuePod& uValue)
+ {
TValuePacker packer(false, type, UseCodegen);
- const THPTimer timer;
+ const THPTimer timer;
for (size_t i = 0U; i < PERFORMANCE_COUNT; ++i)
- packer.Pack(uValue);
- Cout << timer.Passed() << Endl;
- }
-
- NUdf::TUnboxedValue TestPackUnpack(TValuePacker& packer, const NUdf::TUnboxedValuePod& uValue,
- const TString& additionalMsg, const std::optional<ui32>& expectedLength = {})
+ packer.Pack(uValue);
+ Cout << timer.Passed() << Endl;
+ }
+
+ NUdf::TUnboxedValue TestPackUnpack(TValuePacker& packer, const NUdf::TUnboxedValuePod& uValue,
+ const TString& additionalMsg, const std::optional<ui32>& expectedLength = {})
{
TStringBuf packedValue = packer.Pack(uValue);
if (expectedLength) {
@@ -318,8 +318,8 @@ protected:
return packer.Unpack(packedValue, HolderFactory);
}
- NUdf::TUnboxedValue TestPackUnpack(TType* type, const NUdf::TUnboxedValuePod& uValue, const TString& additionalMsg,
- const std::optional<ui32>& expectedLength = {})
+ NUdf::TUnboxedValue TestPackUnpack(TType* type, const NUdf::TUnboxedValuePod& uValue, const TString& additionalMsg,
+ const std::optional<ui32>& expectedLength = {})
{
TValuePacker packer(false, type, UseCodegen);
return TestPackUnpack(packer, uValue, additionalMsg, expectedLength);
@@ -328,8 +328,8 @@ protected:
template <typename T>
void TestNumericValue(T value, TValuePacker& packer, const TString& typeDesc) {
TString additionalMsg = TStringBuilder() << typeDesc << ", Value:" << value;
- auto uValue = TestPackUnpack(packer, NUdf::TUnboxedValuePod(value), additionalMsg);
- UNIT_ASSERT_VALUES_EQUAL_C(uValue.template Get<T>(), value, additionalMsg);
+ auto uValue = TestPackUnpack(packer, NUdf::TUnboxedValuePod(value), additionalMsg);
+ UNIT_ASSERT_VALUES_EQUAL_C(uValue.template Get<T>(), value, additionalMsg);
}
template <typename T>
@@ -344,16 +344,16 @@ protected:
}
template <typename T>
- void TestOptionalNumericValue(std::optional<T> value, TValuePacker& packer, const TString& typeDesc,
- const std::optional<ui32>& expectedLength = {})
+ void TestOptionalNumericValue(std::optional<T> value, TValuePacker& packer, const TString& typeDesc,
+ const std::optional<ui32>& expectedLength = {})
{
TString additionalMsg = TStringBuilder() << typeDesc << "), Value:" << (value ? ToString(*value) : TString("null"));
- const auto v = value ? NUdf::TUnboxedValuePod(*value) : NUdf::TUnboxedValuePod();
- const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
+ const auto v = value ? NUdf::TUnboxedValuePod(*value) : NUdf::TUnboxedValuePod();
+ const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
if (value) {
- UNIT_ASSERT_VALUES_EQUAL_C(uValue.template Get<T>(), *value, additionalMsg);
+ UNIT_ASSERT_VALUES_EQUAL_C(uValue.template Get<T>(), *value, additionalMsg);
} else {
- UNIT_ASSERT_C(!uValue, additionalMsg);
+ UNIT_ASSERT_C(!uValue, additionalMsg);
}
}
@@ -361,136 +361,136 @@ protected:
void TestOptionalNumericType(NUdf::TDataTypeId schemeType) {
TString typeDesc = TStringBuilder() << ", Type:Optional(" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Name;
TValuePacker packer(false, PgmBuilder.NewOptionalType(PgmBuilder.NewDataType(schemeType)), UseCodegen);
- TestOptionalNumericValue<T>(std::optional<T>(Max<T>()), packer, typeDesc);
- TestOptionalNumericValue<T>(std::optional<T>(Min<T>()), packer, typeDesc);
- TestOptionalNumericValue<T>(std::optional<T>(), packer, typeDesc, 1);
- TestOptionalNumericValue<T>(std::optional<T>(0), packer, typeDesc);
- TestOptionalNumericValue<T>(std::optional<T>(1), packer, typeDesc);
+ TestOptionalNumericValue<T>(std::optional<T>(Max<T>()), packer, typeDesc);
+ TestOptionalNumericValue<T>(std::optional<T>(Min<T>()), packer, typeDesc);
+ TestOptionalNumericValue<T>(std::optional<T>(), packer, typeDesc, 1);
+ TestOptionalNumericValue<T>(std::optional<T>(0), packer, typeDesc);
+ TestOptionalNumericValue<T>(std::optional<T>(1), packer, typeDesc);
}
- void TestStringValue(const std::string_view& value, TValuePacker& packer, const TString& typeDesc, ui32 expectedLength) {
+ void TestStringValue(const std::string_view& value, TValuePacker& packer, const TString& typeDesc, ui32 expectedLength) {
TString additionalMsg = TStringBuilder() << typeDesc << ", Value:" << value;
- const auto v = NUdf::TUnboxedValue(MakeString(value));
- const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
- UNIT_ASSERT_VALUES_EQUAL_C(std::string_view(uValue.AsStringRef()), value, additionalMsg);
+ const auto v = NUdf::TUnboxedValue(MakeString(value));
+ const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
+ UNIT_ASSERT_VALUES_EQUAL_C(std::string_view(uValue.AsStringRef()), value, additionalMsg);
}
void TestStringType(NUdf::TDataTypeId schemeType) {
TString typeDesc = TStringBuilder() << ", Type:" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Name;
TValuePacker packer(false, PgmBuilder.NewDataType(schemeType), UseCodegen);
- TestStringValue("0123456789012345678901234567890123456789", packer, typeDesc, 40 + 4);
- TestStringValue("[]", packer, typeDesc, 2 + 1);
- TestStringValue("1234567", packer, typeDesc, 7 + 1);
- TestStringValue("", packer, typeDesc, 1);
- TestStringValue("12345678", packer, typeDesc, 8 + 4);
+ TestStringValue("0123456789012345678901234567890123456789", packer, typeDesc, 40 + 4);
+ TestStringValue("[]", packer, typeDesc, 2 + 1);
+ TestStringValue("1234567", packer, typeDesc, 7 + 1);
+ TestStringValue("", packer, typeDesc, 1);
+ TestStringValue("12345678", packer, typeDesc, 8 + 4);
}
void TestUuidType() {
auto schemeType = NUdf::TDataType<NUdf::TUuid>::Id;
TString typeDesc = TStringBuilder() << ", Type:" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Name;
TValuePacker packer(false, PgmBuilder.NewDataType(schemeType), false);
- TestStringValue("0123456789abcdef", packer, typeDesc, 16 + 4);
+ TestStringValue("0123456789abcdef", packer, typeDesc, 16 + 4);
}
- void TestOptionalStringValue(std::optional<std::string_view> value, TValuePacker& packer, const TString& typeDesc, ui32 expectedLength) {
+ void TestOptionalStringValue(std::optional<std::string_view> value, TValuePacker& packer, const TString& typeDesc, ui32 expectedLength) {
TString additionalMsg = TStringBuilder() << typeDesc << "), Value:" << (value ? *value : TString("null"));
- const auto v = value ? NUdf::TUnboxedValue(MakeString(*value)) : NUdf::TUnboxedValue();
- const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
+ const auto v = value ? NUdf::TUnboxedValue(MakeString(*value)) : NUdf::TUnboxedValue();
+ const auto uValue = TestPackUnpack(packer, v, additionalMsg, expectedLength);
if (value) {
- UNIT_ASSERT_VALUES_EQUAL_C(std::string_view(uValue.AsStringRef()), *value, additionalMsg);
+ UNIT_ASSERT_VALUES_EQUAL_C(std::string_view(uValue.AsStringRef()), *value, additionalMsg);
} else {
- UNIT_ASSERT_C(!uValue, additionalMsg);
+ UNIT_ASSERT_C(!uValue, additionalMsg);
}
}
void TestOptionalStringType(NUdf::TDataTypeId schemeType) {
TString typeDesc = TStringBuilder() << ", Type:Optional(" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(schemeType)).Name;
TValuePacker packer(false, PgmBuilder.NewOptionalType(PgmBuilder.NewDataType(schemeType)), UseCodegen);
- TestOptionalStringValue("0123456789012345678901234567890123456789", packer, typeDesc, 40 + 4);
- TestOptionalStringValue(std::nullopt, packer, typeDesc, 1);
- TestOptionalStringValue("[]", packer, typeDesc, 2 + 1);
- TestOptionalStringValue("1234567", packer, typeDesc, 7 + 1);
- TestOptionalStringValue("", packer, typeDesc, 1);
- TestOptionalStringValue("12345678", packer, typeDesc, 8 + 4);
+ TestOptionalStringValue("0123456789012345678901234567890123456789", packer, typeDesc, 40 + 4);
+ TestOptionalStringValue(std::nullopt, packer, typeDesc, 1);
+ TestOptionalStringValue("[]", packer, typeDesc, 2 + 1);
+ TestOptionalStringValue("1234567", packer, typeDesc, 7 + 1);
+ TestOptionalStringValue("", packer, typeDesc, 1);
+ TestOptionalStringValue("12345678", packer, typeDesc, 8 + 4);
}
void TestVariantTypeImpl(TType* variantType) {
TString descr = TStringBuilder() << "Type:Variant("
<< static_cast<TVariantType*>(variantType)->GetUnderlyingType()->GetKindAsStr() << ')';
{
- const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(MakeString("01234567890123456789"), 0);
- const auto uValue = TestPackUnpack(variantType, value, descr);
+ const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(MakeString("01234567890123456789"), 0);
+ const auto uValue = TestPackUnpack(variantType, value, descr);
UNIT_ASSERT_VALUES_EQUAL(uValue.GetVariantIndex(), 0);
- auto e = uValue.GetVariantItem();
- UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
+ auto e = uValue.GetVariantItem();
+ UNIT_ASSERT_VALUES_EQUAL(std::string_view(e.AsStringRef()), "01234567890123456789");
}
{
- const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(), 1);
- const auto uValue = TestPackUnpack(variantType, value, descr);
+ const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(), 1);
+ const auto uValue = TestPackUnpack(variantType, value, descr);
UNIT_ASSERT_VALUES_EQUAL(uValue.GetVariantIndex(), 1);
- auto e = uValue.GetVariantItem();
- UNIT_ASSERT(!e);
+ auto e = uValue.GetVariantItem();
+ UNIT_ASSERT(!e);
}
{
- const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(ui64(12345)), 2);
- const auto uValue = TestPackUnpack(variantType, value, descr);
+ const NUdf::TUnboxedValue value = HolderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(ui64(12345)), 2);
+ const auto uValue = TestPackUnpack(variantType, value, descr);
UNIT_ASSERT_VALUES_EQUAL(uValue.GetVariantIndex(), 2);
- auto e = uValue.GetVariantItem();
- UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345ull);
+ auto e = uValue.GetVariantItem();
+ UNIT_ASSERT_VALUES_EQUAL(e.template Get<ui64>(), 12345ull);
}
}
- void TestTuplePackPerformance() {
- std::vector<TType*> tupleElemenTypes;
+ void TestTuplePackPerformance() {
+ std::vector<TType*> tupleElemenTypes;
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id));
- tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
- tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
+ tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
+ tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[0]));
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id));
- tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[3]));
- tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[3]));
- TType* tupleType = PgmBuilder.NewTupleType(tupleElemenTypes);
-
- TUnboxedValueVector tupleElemens;
- tupleElemens.push_back(MakeString("01234567890123456789"));
- tupleElemens.push_back(MakeString("01234567890"));
- tupleElemens.push_back(NUdf::TUnboxedValuePod());
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
- tupleElemens.push_back(NUdf::TUnboxedValuePod());
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
-
- const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
- TestPackPerformance(tupleType, value);
- }
-
- void TestPairPackPerformance() {
- std::vector<TType*> tupleElemenTypes;
+ tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[3]));
+ tupleElemenTypes.push_back(PgmBuilder.NewOptionalType(tupleElemenTypes[3]));
+ TType* tupleType = PgmBuilder.NewTupleType(tupleElemenTypes);
+
+ TUnboxedValueVector tupleElemens;
+ tupleElemens.push_back(MakeString("01234567890123456789"));
+ tupleElemens.push_back(MakeString("01234567890"));
+ tupleElemens.push_back(NUdf::TUnboxedValuePod());
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+ tupleElemens.push_back(NUdf::TUnboxedValuePod());
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui64(12345)));
+
+ const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
+ TestPackPerformance(tupleType, value);
+ }
+
+ void TestPairPackPerformance() {
+ std::vector<TType*> tupleElemenTypes;
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
tupleElemenTypes.push_back(PgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id));
- TType* tupleType = PgmBuilder.NewTupleType(tupleElemenTypes);
-
- TUnboxedValueVector tupleElemens;
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui32(12345)));
- tupleElemens.push_back(NUdf::TUnboxedValuePod(ui32(67890)));
-
- const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
- TestPackPerformance(tupleType, value);
- }
-
- void TestShortStringPackPerformance() {
- const auto v = NUdf::TUnboxedValuePod::Embedded("01234");
+ TType* tupleType = PgmBuilder.NewTupleType(tupleElemenTypes);
+
+ TUnboxedValueVector tupleElemens;
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui32(12345)));
+ tupleElemens.push_back(NUdf::TUnboxedValuePod(ui32(67890)));
+
+ const NUdf::TUnboxedValue value = HolderFactory.VectorAsArray(tupleElemens);
+ TestPackPerformance(tupleType, value);
+ }
+
+ void TestShortStringPackPerformance() {
+ const auto v = NUdf::TUnboxedValuePod::Embedded("01234");
TType* type = PgmBuilder.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
- TestPackPerformance(type, v);
- }
-
- void TestIntegerPackPerformance() {
- const auto& v = NUdf::TUnboxedValuePod(ui64("123456789ULL"));
+ TestPackPerformance(type, v);
+ }
+
+ void TestIntegerPackPerformance() {
+ const auto& v = NUdf::TUnboxedValuePod(ui64("123456789ULL"));
TType* type = PgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
- TestPackPerformance(type, v);
- }
-
+ TestPackPerformance(type, v);
+ }
+
private:
TIntrusivePtr<NMiniKQL::IFunctionRegistry> FunctionRegistry;
TIntrusivePtr<IRandomProvider> RandomProvider;
@@ -501,53 +501,53 @@ private:
THolderFactory HolderFactory;
};
-class TMiniKQLComputationNodePackCodegenTest: public TMiniKQLComputationNodePackTest<true> {
- UNIT_TEST_SUITE(TMiniKQLComputationNodePackCodegenTest);
- UNIT_TEST(TestNumericTypes);
- UNIT_TEST(TestOptionalNumericTypes);
- UNIT_TEST(TestStringTypes);
- UNIT_TEST(TestOptionalStringTypes);
- UNIT_TEST(TestListType);
- UNIT_TEST(TestListOfOptionalsType);
- UNIT_TEST(TestTupleType);
- UNIT_TEST(TestStructType);
- UNIT_TEST(TestOptionalType);
- UNIT_TEST(TestDictType);
- UNIT_TEST(TestVariantTypeOverStruct);
- UNIT_TEST(TestVariantTypeOverTuple);
- UNIT_TEST(TestIntegerPackPerformance);
- UNIT_TEST(TestShortStringPackPerformance);
- UNIT_TEST(TestPairPackPerformance);
- UNIT_TEST(TestTuplePackPerformance);
- UNIT_TEST_SUITE_END();
-};
-
-class TMiniKQLComputationNodePackBySwitchTest: public TMiniKQLComputationNodePackTest<false> {
- UNIT_TEST_SUITE(TMiniKQLComputationNodePackBySwitchTest);
- UNIT_TEST(TestNumericTypes);
- UNIT_TEST(TestOptionalNumericTypes);
- UNIT_TEST(TestStringTypes);
+class TMiniKQLComputationNodePackCodegenTest: public TMiniKQLComputationNodePackTest<true> {
+ UNIT_TEST_SUITE(TMiniKQLComputationNodePackCodegenTest);
+ UNIT_TEST(TestNumericTypes);
+ UNIT_TEST(TestOptionalNumericTypes);
+ UNIT_TEST(TestStringTypes);
+ UNIT_TEST(TestOptionalStringTypes);
+ UNIT_TEST(TestListType);
+ UNIT_TEST(TestListOfOptionalsType);
+ UNIT_TEST(TestTupleType);
+ UNIT_TEST(TestStructType);
+ UNIT_TEST(TestOptionalType);
+ UNIT_TEST(TestDictType);
+ UNIT_TEST(TestVariantTypeOverStruct);
+ UNIT_TEST(TestVariantTypeOverTuple);
+ UNIT_TEST(TestIntegerPackPerformance);
+ UNIT_TEST(TestShortStringPackPerformance);
+ UNIT_TEST(TestPairPackPerformance);
+ UNIT_TEST(TestTuplePackPerformance);
+ UNIT_TEST_SUITE_END();
+};
+
+class TMiniKQLComputationNodePackBySwitchTest: public TMiniKQLComputationNodePackTest<false> {
+ UNIT_TEST_SUITE(TMiniKQLComputationNodePackBySwitchTest);
+ UNIT_TEST(TestNumericTypes);
+ UNIT_TEST(TestOptionalNumericTypes);
+ UNIT_TEST(TestStringTypes);
UNIT_TEST(TestUuidType);
- UNIT_TEST(TestOptionalStringTypes);
- UNIT_TEST(TestListType);
- UNIT_TEST(TestListOfOptionalsType);
- UNIT_TEST(TestTupleType);
- UNIT_TEST(TestStructType);
- UNIT_TEST(TestOptionalType);
- UNIT_TEST(TestDictType);
- UNIT_TEST(TestVariantTypeOverStruct);
- UNIT_TEST(TestVariantTypeOverTuple);
- UNIT_TEST(TestIntegerPackPerformance);
- UNIT_TEST(TestShortStringPackPerformance);
- UNIT_TEST(TestPairPackPerformance);
- UNIT_TEST(TestTuplePackPerformance);
- UNIT_TEST_SUITE_END();
-};
-
-#if defined(__llvm__) && !defined(_msan_enabled_)
-UNIT_TEST_SUITE_REGISTRATION(TMiniKQLComputationNodePackCodegenTest);
-#endif
-UNIT_TEST_SUITE_REGISTRATION(TMiniKQLComputationNodePackBySwitchTest);
-
+ UNIT_TEST(TestOptionalStringTypes);
+ UNIT_TEST(TestListType);
+ UNIT_TEST(TestListOfOptionalsType);
+ UNIT_TEST(TestTupleType);
+ UNIT_TEST(TestStructType);
+ UNIT_TEST(TestOptionalType);
+ UNIT_TEST(TestDictType);
+ UNIT_TEST(TestVariantTypeOverStruct);
+ UNIT_TEST(TestVariantTypeOverTuple);
+ UNIT_TEST(TestIntegerPackPerformance);
+ UNIT_TEST(TestShortStringPackPerformance);
+ UNIT_TEST(TestPairPackPerformance);
+ UNIT_TEST(TestTuplePackPerformance);
+ UNIT_TEST_SUITE_END();
+};
+
+#if defined(__llvm__) && !defined(_msan_enabled_)
+UNIT_TEST_SUITE_REGISTRATION(TMiniKQLComputationNodePackCodegenTest);
+#endif
+UNIT_TEST_SUITE_REGISTRATION(TMiniKQLComputationNodePackBySwitchTest);
+
}
}
diff --git a/ydb/library/yql/minikql/computation/mkql_custom_list.cpp b/ydb/library/yql/minikql/computation/mkql_custom_list.cpp
index fcdd6a5853..6f8d68013b 100644
--- a/ydb/library/yql/minikql/computation/mkql_custom_list.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_custom_list.cpp
@@ -1,135 +1,135 @@
#include "mkql_custom_list.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-TForwardListValue::TForwardListValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
- : TCustomListValue(memInfo)
- , Stream(std::move(stream))
-{
- MKQL_ENSURE(Stream, "Empty stream.");
-}
-
-TForwardListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
- : TComputationValue(memInfo), Stream(std::move(stream))
-{}
-
-bool TForwardListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
- const auto status = Stream.Fetch(value);
- MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status.");
- return status == NUdf::EFetchStatus::Ok;
-}
-
-NUdf::TUnboxedValue TForwardListValue::GetListIterator() const {
- MKQL_ENSURE(Stream, "Second pass for ForwardList");
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(Stream)));
-}
-
-TExtendListValue::TExtendListValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
- : TCustomListValue(memInfo)
- , Lists(std::move(lists))
-{
- MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
- Y_ASSERT(!Lists.empty());
-}
-
-TExtendListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters)
- : TComputationValue(memInfo)
- , Iters(std::move(iters))
- , Index(0)
-{
- MKQL_MEM_TAKE(memInfo, Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
-}
-
-TExtendListValue::TIterator::~TIterator()
-{
- MKQL_MEM_RETURN(GetMemInfo(), Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
-}
-
-bool TExtendListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
- for (; Index < Iters.size(); ++Index) {
- if (Iters[Index].Next(value)) {
- return true;
- }
- }
- return false;
-}
-
-bool TExtendListValue::TIterator::Skip() {
- for (; Index < Iters.size(); ++Index) {
- if (Iters[Index].Skip()) {
- return true;
- }
- }
- return false;
-}
-
-NUdf::TUnboxedValue TExtendListValue::GetListIterator() const {
- TUnboxedValueVector iters;
- iters.reserve(Lists.size());
- for (const auto& list : Lists) {
- iters.emplace_back(list.GetListIterator());
- }
-
- return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(iters)));
-}
-
-TExtendListValue::~TExtendListValue() {
- MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
-}
-
-ui64 TExtendListValue::GetListLength() const {
- if (!Length) {
- ui64 length = 0ULL;
- for (const auto& list : Lists) {
- ui64 partialLength = list.GetListLength();
- length += partialLength;
- }
-
- Length = length;
- }
-
- return *Length;
-}
-
-bool TExtendListValue::HasListItems() const {
- if (!HasItems) {
- for (const auto& list : Lists) {
- if (list.HasListItems()) {
- HasItems = true;
- break;
- }
- }
-
- if (!HasItems) {
- HasItems = false;
- }
- }
-
- return *HasItems;
-}
-
-TExtendStreamValue::TExtendStreamValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
- : TBase(memInfo)
- , Lists(std::move(lists))
-{
- MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
- Y_ASSERT(!Lists.empty());
-}
-
-TExtendStreamValue::~TExtendStreamValue() {
- MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
-}
-
-NUdf::EFetchStatus TExtendStreamValue::Fetch(NUdf::TUnboxedValue& value) {
- for (; Index < Lists.size(); ++Index) {
- const auto status = Lists[Index].Fetch(value);
- if (status != NUdf::EFetchStatus::Finish) {
- return status;
- }
- }
- return NUdf::EFetchStatus::Finish;
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+TForwardListValue::TForwardListValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
+ : TCustomListValue(memInfo)
+ , Stream(std::move(stream))
+{
+ MKQL_ENSURE(Stream, "Empty stream.");
+}
+
+TForwardListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
+ : TComputationValue(memInfo), Stream(std::move(stream))
+{}
+
+bool TForwardListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
+ const auto status = Stream.Fetch(value);
+ MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status.");
+ return status == NUdf::EFetchStatus::Ok;
+}
+
+NUdf::TUnboxedValue TForwardListValue::GetListIterator() const {
+ MKQL_ENSURE(Stream, "Second pass for ForwardList");
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(Stream)));
+}
+
+TExtendListValue::TExtendListValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
+ : TCustomListValue(memInfo)
+ , Lists(std::move(lists))
+{
+ MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
+ Y_ASSERT(!Lists.empty());
+}
+
+TExtendListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters)
+ : TComputationValue(memInfo)
+ , Iters(std::move(iters))
+ , Index(0)
+{
+ MKQL_MEM_TAKE(memInfo, Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
+}
+
+TExtendListValue::TIterator::~TIterator()
+{
+ MKQL_MEM_RETURN(GetMemInfo(), Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
+}
+
+bool TExtendListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
+ for (; Index < Iters.size(); ++Index) {
+ if (Iters[Index].Next(value)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TExtendListValue::TIterator::Skip() {
+ for (; Index < Iters.size(); ++Index) {
+ if (Iters[Index].Skip()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+NUdf::TUnboxedValue TExtendListValue::GetListIterator() const {
+ TUnboxedValueVector iters;
+ iters.reserve(Lists.size());
+ for (const auto& list : Lists) {
+ iters.emplace_back(list.GetListIterator());
+ }
+
+ return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(iters)));
+}
+
+TExtendListValue::~TExtendListValue() {
+ MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
+}
+
+ui64 TExtendListValue::GetListLength() const {
+ if (!Length) {
+ ui64 length = 0ULL;
+ for (const auto& list : Lists) {
+ ui64 partialLength = list.GetListLength();
+ length += partialLength;
+ }
+
+ Length = length;
+ }
+
+ return *Length;
+}
+
+bool TExtendListValue::HasListItems() const {
+ if (!HasItems) {
+ for (const auto& list : Lists) {
+ if (list.HasListItems()) {
+ HasItems = true;
+ break;
+ }
+ }
+
+ if (!HasItems) {
+ HasItems = false;
+ }
+ }
+
+ return *HasItems;
+}
+
+TExtendStreamValue::TExtendStreamValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
+ : TBase(memInfo)
+ , Lists(std::move(lists))
+{
+ MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
+ Y_ASSERT(!Lists.empty());
+}
+
+TExtendStreamValue::~TExtendStreamValue() {
+ MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
+}
+
+NUdf::EFetchStatus TExtendStreamValue::Fetch(NUdf::TUnboxedValue& value) {
+ for (; Index < Lists.size(); ++Index) {
+ const auto status = Lists[Index].Fetch(value);
+ if (status != NUdf::EFetchStatus::Finish) {
+ return status;
+ }
+ }
+ return NUdf::EFetchStatus::Finish;
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_custom_list.h b/ydb/library/yql/minikql/computation/mkql_custom_list.h
index 1162a87aac..d53fbc06d8 100644
--- a/ydb/library/yql/minikql/computation/mkql_custom_list.h
+++ b/ydb/library/yql/minikql/computation/mkql_custom_list.h
@@ -12,22 +12,22 @@ public:
{
}
-private:
+private:
bool HasFastListLength() const override {
- return bool(Length);
+ return bool(Length);
}
ui64 GetListLength() const override {
if (!Length) {
- ui64 length = Iterator ? 1ULL : 0ULL;
- for (const auto it = Iterator ? std::move(Iterator) : NUdf::TBoxedValueAccessor::GetListIterator(*this); it.Skip();) {
+ ui64 length = Iterator ? 1ULL : 0ULL;
+ for (const auto it = Iterator ? std::move(Iterator) : NUdf::TBoxedValueAccessor::GetListIterator(*this); it.Skip();) {
++length;
}
Length = length;
}
- return *Length;
+ return *Length;
}
ui64 GetEstimatedListLength() const override {
@@ -44,81 +44,81 @@ private:
return *HasItems;
}
- auto iter = NUdf::TBoxedValueAccessor::GetListIterator(*this);
- HasItems = iter.Skip();
- if (*HasItems) {
- Iterator = std::move(iter);
- }
+ auto iter = NUdf::TBoxedValueAccessor::GetListIterator(*this);
+ HasItems = iter.Skip();
+ if (*HasItems) {
+ Iterator = std::move(iter);
+ }
return *HasItems;
}
protected:
- mutable std::optional<ui64> Length;
- mutable std::optional<bool> HasItems;
- mutable NUdf::TUnboxedValue Iterator;
+ mutable std::optional<ui64> Length;
+ mutable std::optional<bool> HasItems;
+ mutable NUdf::TUnboxedValue Iterator;
+};
+
+class TForwardListValue : public TCustomListValue {
+public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream);
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override;
+
+ const NUdf::TUnboxedValue Stream;
+ };
+
+ TForwardListValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream);
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const override;
+
+ mutable NUdf::TUnboxedValue Stream;
+};
+
+class TExtendListValue : public TCustomListValue {
+public:
+ class TIterator : public TComputationValue<TIterator> {
+ public:
+ TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters);
+ ~TIterator();
+
+ private:
+ bool Next(NUdf::TUnboxedValue& value) override;
+ bool Skip() override;
+
+ const TUnboxedValueVector Iters;
+ ui32 Index;
+ };
+
+ TExtendListValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists);
+
+ ~TExtendListValue();
+
+private:
+ NUdf::TUnboxedValue GetListIterator() const override;
+ ui64 GetListLength() const override;
+ bool HasListItems() const override;
+
+ const TUnboxedValueVector Lists;
+};
+
+class TExtendStreamValue : public TComputationValue<TExtendStreamValue> {
+public:
+ using TBase = TComputationValue<TExtendStreamValue>;
+
+ TExtendStreamValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists);
+
+ ~TExtendStreamValue();
+
+private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value);
+
+ const TUnboxedValueVector Lists;
+ ui32 Index = 0;
};
-class TForwardListValue : public TCustomListValue {
-public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream);
-
- private:
- bool Next(NUdf::TUnboxedValue& value) override;
-
- const NUdf::TUnboxedValue Stream;
- };
-
- TForwardListValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream);
-
-private:
- NUdf::TUnboxedValue GetListIterator() const override;
-
- mutable NUdf::TUnboxedValue Stream;
-};
-
-class TExtendListValue : public TCustomListValue {
-public:
- class TIterator : public TComputationValue<TIterator> {
- public:
- TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters);
- ~TIterator();
-
- private:
- bool Next(NUdf::TUnboxedValue& value) override;
- bool Skip() override;
-
- const TUnboxedValueVector Iters;
- ui32 Index;
- };
-
- TExtendListValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists);
-
- ~TExtendListValue();
-
-private:
- NUdf::TUnboxedValue GetListIterator() const override;
- ui64 GetListLength() const override;
- bool HasListItems() const override;
-
- const TUnboxedValueVector Lists;
-};
-
-class TExtendStreamValue : public TComputationValue<TExtendStreamValue> {
-public:
- using TBase = TComputationValue<TExtendStreamValue>;
-
- TExtendStreamValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists);
-
- ~TExtendStreamValue();
-
-private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& value);
-
- const TUnboxedValueVector Lists;
- ui32 Index = 0;
-};
-
}
}
diff --git a/ydb/library/yql/minikql/computation/mkql_optional_usage_mask.h b/ydb/library/yql/minikql/computation/mkql_optional_usage_mask.h
index b096cb1533..c9381ccd50 100644
--- a/ydb/library/yql/minikql/computation/mkql_optional_usage_mask.h
+++ b/ydb/library/yql/minikql/computation/mkql_optional_usage_mask.h
@@ -1,80 +1,80 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/pack_num.h>
-#include <util/generic/bitmap.h>
-#include <util/generic/buffer.h>
-
-#include <cstring>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace NDetails {
-
-class TOptionalUsageMask {
-public:
- TOptionalUsageMask() = default;
-
- void Reset() {
- CountOfOptional = 0U;
- Mask.Clear();
- }
-
- void Reset(TStringBuf& buf) {
- Reset();
- ui64 bytes = 0ULL;
+#include <util/generic/bitmap.h>
+#include <util/generic/buffer.h>
+
+#include <cstring>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace NDetails {
+
+class TOptionalUsageMask {
+public:
+ TOptionalUsageMask() = default;
+
+ void Reset() {
+ CountOfOptional = 0U;
+ Mask.Clear();
+ }
+
+ void Reset(TStringBuf& buf) {
+ Reset();
+ ui64 bytes = 0ULL;
buf.Skip(Unpack64(buf.data(), buf.size(), bytes));
- if (bytes) {
+ if (bytes) {
Y_VERIFY_DEBUG(bytes <= buf.size());
- Mask.Reserve(bytes << 3ULL);
+ Mask.Reserve(bytes << 3ULL);
std::memcpy(const_cast<ui8*>(Mask.GetChunks()), buf.data(), bytes);
- buf.Skip(bytes);
- }
- }
-
- void SetNextEmptyOptional(bool empty) {
- if (empty) {
- Mask.Set(CountOfOptional);
- }
- ++CountOfOptional;
- }
-
- bool IsNextEmptyOptional() {
- return Mask.Test(CountOfOptional++);
- }
-
- bool IsEmptyMask() const {
- return Mask.Empty();
- }
-
- size_t CalcSerializedSize() {
- if (!CountOfOptional || Mask.Empty()) {
- return 1ULL; // One byte for size=0
- }
-
- const size_t usedBits = Mask.ValueBitCount();
- const size_t usedBytes = (usedBits + 7ULL) >> 3ULL;
- return GetPack64Length(usedBytes) + usedBytes;
- }
-
- void Serialize(TBuffer& buf) const {
- if (!CountOfOptional || Mask.Empty()) {
- return buf.Append(0);
- }
-
- const size_t usedBits = Mask.ValueBitCount();
- const size_t usedBytes = (usedBits + 7ULL) >> 3ULL;
- const auto off = buf.Size();
- buf.Advance(MAX_PACKED64_SIZE);
- buf.EraseBack(MAX_PACKED64_SIZE - Pack64(usedBytes, buf.Data() + off));
- buf.Append(reinterpret_cast<const char*>(Mask.GetChunks()), usedBytes);
- }
-
-private:
- ui32 CountOfOptional = 0U;
- TBitMapOps<TDynamicBitMapTraits<ui8>> Mask;
-};
-
-} // NDetails
-}
-}
+ buf.Skip(bytes);
+ }
+ }
+
+ void SetNextEmptyOptional(bool empty) {
+ if (empty) {
+ Mask.Set(CountOfOptional);
+ }
+ ++CountOfOptional;
+ }
+
+ bool IsNextEmptyOptional() {
+ return Mask.Test(CountOfOptional++);
+ }
+
+ bool IsEmptyMask() const {
+ return Mask.Empty();
+ }
+
+ size_t CalcSerializedSize() {
+ if (!CountOfOptional || Mask.Empty()) {
+ return 1ULL; // One byte for size=0
+ }
+
+ const size_t usedBits = Mask.ValueBitCount();
+ const size_t usedBytes = (usedBits + 7ULL) >> 3ULL;
+ return GetPack64Length(usedBytes) + usedBytes;
+ }
+
+ void Serialize(TBuffer& buf) const {
+ if (!CountOfOptional || Mask.Empty()) {
+ return buf.Append(0);
+ }
+
+ const size_t usedBits = Mask.ValueBitCount();
+ const size_t usedBytes = (usedBits + 7ULL) >> 3ULL;
+ const auto off = buf.Size();
+ buf.Advance(MAX_PACKED64_SIZE);
+ buf.EraseBack(MAX_PACKED64_SIZE - Pack64(usedBytes, buf.Data() + off));
+ buf.Append(reinterpret_cast<const char*>(Mask.GetChunks()), usedBytes);
+ }
+
+private:
+ ui32 CountOfOptional = 0U;
+ TBitMapOps<TDynamicBitMapTraits<ui8>> Mask;
+};
+
+} // NDetails
+}
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_pack_bc.cpp b/ydb/library/yql/minikql/computation/mkql_pack_bc.cpp
index 2c8df797aa..68441746c3 100644
--- a/ydb/library/yql/minikql/computation/mkql_pack_bc.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_pack_bc.cpp
@@ -1,200 +1,200 @@
-#include <util/generic/buffer.h>
-
+#include <util/generic/buffer.h>
+
#include <ydb/library/yql/public/udf/udf_value.h>
#include <ydb/library/yql/minikql/pack_num.h>
#include <library/cpp/packedtypes/zigzag.h>
-
+
#include <ydb/library/yql/minikql/defs.h>
-#include "mkql_optional_usage_mask.h"
-
-using namespace NKikimr;
-
-namespace NDetails {
-
-void PackUInt64(ui64 pos, ui64 val, TBuffer& buf) {
- const auto actual = Pack64(val, buf.Data() + pos);
- buf.Chop(pos + actual, MAX_PACKED64_SIZE - actual);
-}
-
-void PackUInt64(ui64 val, TBuffer& buf) {
- size_t off = buf.Size();
- buf.Advance(MAX_PACKED64_SIZE);
- buf.EraseBack(MAX_PACKED64_SIZE - Pack64(val, buf.Data() + off));
-}
-
-void PackInt64(i64 val, TBuffer& buf) {
- PackUInt64(ZigZagEncode(val), buf);
-}
-
-void PackUInt32(ui32 val, TBuffer& buf) {
- size_t off = buf.Size();
- buf.Advance(MAX_PACKED32_SIZE);
- buf.EraseBack(MAX_PACKED32_SIZE - Pack32(val, buf.Data() + off));
-}
-
-void PackInt32(i32 val, TBuffer& buf) {
- PackUInt32(ZigZagEncode(val), buf);
-}
-
-ui64 UnpackUInt64(TStringBuf& buf) {
- ui64 res = 0;
+#include "mkql_optional_usage_mask.h"
+
+using namespace NKikimr;
+
+namespace NDetails {
+
+void PackUInt64(ui64 pos, ui64 val, TBuffer& buf) {
+ const auto actual = Pack64(val, buf.Data() + pos);
+ buf.Chop(pos + actual, MAX_PACKED64_SIZE - actual);
+}
+
+void PackUInt64(ui64 val, TBuffer& buf) {
+ size_t off = buf.Size();
+ buf.Advance(MAX_PACKED64_SIZE);
+ buf.EraseBack(MAX_PACKED64_SIZE - Pack64(val, buf.Data() + off));
+}
+
+void PackInt64(i64 val, TBuffer& buf) {
+ PackUInt64(ZigZagEncode(val), buf);
+}
+
+void PackUInt32(ui32 val, TBuffer& buf) {
+ size_t off = buf.Size();
+ buf.Advance(MAX_PACKED32_SIZE);
+ buf.EraseBack(MAX_PACKED32_SIZE - Pack32(val, buf.Data() + off));
+}
+
+void PackInt32(i32 val, TBuffer& buf) {
+ PackUInt32(ZigZagEncode(val), buf);
+}
+
+ui64 UnpackUInt64(TStringBuf& buf) {
+ ui64 res = 0;
size_t read = Unpack64(buf.data(), buf.length(), res);
- MKQL_ENSURE(read, "Bad ui64 packed data");
- buf.Skip(read);
- return res;
-}
-
-i64 UnpackInt64(TStringBuf& buf) {
- return ZigZagDecode(UnpackUInt64(buf));
-}
-
-ui32 UnpackUInt32(TStringBuf& buf) {
- ui32 res = 0;
+ MKQL_ENSURE(read, "Bad ui64 packed data");
+ buf.Skip(read);
+ return res;
+}
+
+i64 UnpackInt64(TStringBuf& buf) {
+ return ZigZagDecode(UnpackUInt64(buf));
+}
+
+ui32 UnpackUInt32(TStringBuf& buf) {
+ ui32 res = 0;
size_t read = Unpack32(buf.data(), buf.length(), res);
- MKQL_ENSURE(read, "Bad ui32 packed data");
- buf.Skip(read);
- return res;
-}
-
-i32 UnpackInt32(TStringBuf& buf) {
- return ZigZagDecode(UnpackUInt32(buf));
-}
-
-template <typename T>
-void PutRawData(T val, TBuffer& buf) {
- buf.Append(reinterpret_cast<const char*>(&val), sizeof(T));
-}
-
-template <typename T>
-T GetRawData(TStringBuf& buf) {
+ MKQL_ENSURE(read, "Bad ui32 packed data");
+ buf.Skip(read);
+ return res;
+}
+
+i32 UnpackInt32(TStringBuf& buf) {
+ return ZigZagDecode(UnpackUInt32(buf));
+}
+
+template <typename T>
+void PutRawData(T val, TBuffer& buf) {
+ buf.Append(reinterpret_cast<const char*>(&val), sizeof(T));
+}
+
+template <typename T>
+T GetRawData(TStringBuf& buf) {
MKQL_ENSURE(sizeof(T) <= buf.size(), "Bad packed data. Buffer too small");
- T val = 0;
+ T val = 0;
std::memcpy(&val, buf.data(), sizeof(T));
- buf.Skip(sizeof(T));
- return val;
-}
-
-}
-
-extern "C" void GetElement(const TRawUV* value, ui32 index, TRawUV* item) {
- const auto result(reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->GetElement(index));
- *item = reinterpret_cast<const TRawUV&>(result);
-}
-
-extern "C" bool FetchNextItem(const TRawUV* value, TRawUV* item) {
- NUdf::TUnboxedValue fetch;
- if (NUdf::EFetchStatus::Finish == reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->Fetch(fetch))
- return false;
- *item = reinterpret_cast<TRawUV&>(fetch);
- return true;
-}
-
-extern "C" bool NextListItem(TRawUV* value, TRawUV* item) {
- NUdf::TUnboxedValue next;
- const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
- if (!v->Next(next)) {
- v->DeleteUnreferenced();
- return false;
- }
-
- *item = reinterpret_cast<TRawUV&>(next);
- return true;
-}
-
-extern "C" bool NextDictItem(TRawUV* value, TRawUV* first, TRawUV* second) {
- NUdf::TUnboxedValue key, payload;
- const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
- if (!v->NextPair(key, payload)) {
- v->DeleteUnreferenced();
- return false;
- }
-
- *first = reinterpret_cast<TRawUV&>(key);
- *second = reinterpret_cast<TRawUV&>(payload);
- return true;
-}
-
-extern "C" void PackString(const TRawUV* value, ui64* buffer) {
- const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
- NDetails::PackUInt32(stringRef.Size(), *reinterpret_cast<TBuffer*>(buffer));
- reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
-}
-
-extern "C" void PackStringData(const TRawUV* value, ui64* buffer) {
- const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
- reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
-}
-
-extern "C" void PackBool(const TRawUV* value, ui64* buffer) {
- NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<bool>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackByte(const TRawUV* value, ui64* buffer) {
- NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui8>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackInt32(const TRawUV* value, ui64* buffer) {
- NDetails::PackInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i32>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackUInt32(const TRawUV* value, ui64* buffer) {
- NDetails::PackUInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui32>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackInt64(const TRawUV* value, ui64* buffer) {
- NDetails::PackInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i64>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackUInt64(const TRawUV* value, ui64* buffer) {
- NDetails::PackUInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui64>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackFloat(const TRawUV* value, ui64* buffer) {
- NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<float>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" void PackDouble(const TRawUV* value, ui64* buffer) {
- NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<double>(), *reinterpret_cast<TBuffer*>(buffer));
-}
-
-extern "C" ui32 GetVariantItem(const TRawUV* value, TRawUV* item, ui64* buffer) {
- const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
- const ui32 index = v->GetVariantIndex();
- NDetails::PackUInt32(index, *reinterpret_cast<TBuffer*>(buffer));
- const auto result(v->GetVariantItem());
- *item = reinterpret_cast<const TRawUV&>(result);
- return index;
-}
-
-extern "C" bool GetListIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
- const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
- const auto size = v->GetListLength();
- NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
- if (!size)
- return false;
- const auto result(v->GetListIterator().Release());
- *item = reinterpret_cast<const TRawUV&>(result);
- return true;
-}
-
-extern "C" bool GetDictIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
- const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
- const auto size = v->GetDictLength();
- NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
- if (!size)
- return false;
- const auto result(v->GetDictIterator().Release());
- *item = reinterpret_cast<const TRawUV&>(result);
- return true;
-}
-
-extern "C" bool GetOptionalValue(const TRawUV* value, TRawUV* item, ui64* mask) {
- const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
- const bool has = bool(*v);
- reinterpret_cast<NMiniKQL::NDetails::TOptionalUsageMask*>(mask)->SetNextEmptyOptional(!*v);
- if (has) {
- const auto result(v->GetOptionalValue());
- *item = reinterpret_cast<const TRawUV&>(result);
- }
- return has;
-}
+ buf.Skip(sizeof(T));
+ return val;
+}
+
+}
+
+extern "C" void GetElement(const TRawUV* value, ui32 index, TRawUV* item) {
+ const auto result(reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->GetElement(index));
+ *item = reinterpret_cast<const TRawUV&>(result);
+}
+
+extern "C" bool FetchNextItem(const TRawUV* value, TRawUV* item) {
+ NUdf::TUnboxedValue fetch;
+ if (NUdf::EFetchStatus::Finish == reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->Fetch(fetch))
+ return false;
+ *item = reinterpret_cast<TRawUV&>(fetch);
+ return true;
+}
+
+extern "C" bool NextListItem(TRawUV* value, TRawUV* item) {
+ NUdf::TUnboxedValue next;
+ const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
+ if (!v->Next(next)) {
+ v->DeleteUnreferenced();
+ return false;
+ }
+
+ *item = reinterpret_cast<TRawUV&>(next);
+ return true;
+}
+
+extern "C" bool NextDictItem(TRawUV* value, TRawUV* first, TRawUV* second) {
+ NUdf::TUnboxedValue key, payload;
+ const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
+ if (!v->NextPair(key, payload)) {
+ v->DeleteUnreferenced();
+ return false;
+ }
+
+ *first = reinterpret_cast<TRawUV&>(key);
+ *second = reinterpret_cast<TRawUV&>(payload);
+ return true;
+}
+
+extern "C" void PackString(const TRawUV* value, ui64* buffer) {
+ const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
+ NDetails::PackUInt32(stringRef.Size(), *reinterpret_cast<TBuffer*>(buffer));
+ reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
+}
+
+extern "C" void PackStringData(const TRawUV* value, ui64* buffer) {
+ const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
+ reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
+}
+
+extern "C" void PackBool(const TRawUV* value, ui64* buffer) {
+ NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<bool>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackByte(const TRawUV* value, ui64* buffer) {
+ NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui8>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackInt32(const TRawUV* value, ui64* buffer) {
+ NDetails::PackInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i32>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackUInt32(const TRawUV* value, ui64* buffer) {
+ NDetails::PackUInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui32>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackInt64(const TRawUV* value, ui64* buffer) {
+ NDetails::PackInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i64>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackUInt64(const TRawUV* value, ui64* buffer) {
+ NDetails::PackUInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui64>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackFloat(const TRawUV* value, ui64* buffer) {
+ NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<float>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" void PackDouble(const TRawUV* value, ui64* buffer) {
+ NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<double>(), *reinterpret_cast<TBuffer*>(buffer));
+}
+
+extern "C" ui32 GetVariantItem(const TRawUV* value, TRawUV* item, ui64* buffer) {
+ const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
+ const ui32 index = v->GetVariantIndex();
+ NDetails::PackUInt32(index, *reinterpret_cast<TBuffer*>(buffer));
+ const auto result(v->GetVariantItem());
+ *item = reinterpret_cast<const TRawUV&>(result);
+ return index;
+}
+
+extern "C" bool GetListIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
+ const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
+ const auto size = v->GetListLength();
+ NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
+ if (!size)
+ return false;
+ const auto result(v->GetListIterator().Release());
+ *item = reinterpret_cast<const TRawUV&>(result);
+ return true;
+}
+
+extern "C" bool GetDictIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
+ const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
+ const auto size = v->GetDictLength();
+ NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
+ if (!size)
+ return false;
+ const auto result(v->GetDictIterator().Release());
+ *item = reinterpret_cast<const TRawUV&>(result);
+ return true;
+}
+
+extern "C" bool GetOptionalValue(const TRawUV* value, TRawUV* item, ui64* mask) {
+ const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
+ const bool has = bool(*v);
+ reinterpret_cast<NMiniKQL::NDetails::TOptionalUsageMask*>(mask)->SetNextEmptyOptional(!*v);
+ if (has) {
+ const auto result(v->GetOptionalValue());
+ *item = reinterpret_cast<const TRawUV&>(result);
+ }
+ return has;
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_validate.cpp b/ydb/library/yql/minikql/computation/mkql_validate.cpp
index d1a671c3fc..b238b28aee 100644
--- a/ydb/library/yql/minikql/computation/mkql_validate.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_validate.cpp
@@ -18,7 +18,7 @@ template<class TValidateErrorPolicy>
struct TLazyVerifyListValue;
template<class TValidateErrorPolicy>
-struct TLazyVerifyListIterator: public TBoxedValue {
+struct TLazyVerifyListIterator: public TBoxedValue {
TLazyVerifyListIterator(const TLazyVerifyListValue<TValidateErrorPolicy>& lazyList, ui64 index = 0)
: LazyList(lazyList)
, OrigIter(TBoxedValueAccessor::GetListIterator(*lazyList.Orig))
@@ -30,23 +30,23 @@ struct TLazyVerifyListIterator: public TBoxedValue {
}
private:
const TLazyVerifyListValue<TValidateErrorPolicy>& LazyList;
- TUnboxedValue OrigIter;
+ TUnboxedValue OrigIter;
ui64 Index;
- bool Next(NUdf::TUnboxedValue& item) final {
- ++Index;
- if (!OrigIter.Next(item))
- return false;
- TType* itemType = LazyList.ListType->GetItemType();
- item = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyList.ValueBuilder, itemType, std::move(item),
- TStringBuilder() << "LazyList[" << Index << "]" << VERIFY_DELIMITER << LazyList.Message);
- return true;
- }
-
- bool Skip() final {
- ++Index;
- return OrigIter.Skip();
- }
+ bool Next(NUdf::TUnboxedValue& item) final {
+ ++Index;
+ if (!OrigIter.Next(item))
+ return false;
+ TType* itemType = LazyList.ListType->GetItemType();
+ item = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyList.ValueBuilder, itemType, std::move(item),
+ TStringBuilder() << "LazyList[" << Index << "]" << VERIFY_DELIMITER << LazyList.Message);
+ return true;
+ }
+
+ bool Skip() final {
+ ++Index;
+ return OrigIter.Skip();
+ }
};
template<class TValidateErrorPolicy>
@@ -61,29 +61,29 @@ struct TLazyVerifyListValue: public TBoxedValue {
, Message(message)
{}
- const IValueBuilder *const ValueBuilder;
- const TListType *const ListType;
+ const IValueBuilder *const ValueBuilder;
+ const TListType *const ListType;
const IBoxedValuePtr Orig;
- const TString Message;
-
+ const TString Message;
+
private:
- bool HasFastListLength() const override {
+ bool HasFastListLength() const override {
return TBoxedValueAccessor::HasFastListLength(*Orig);
}
- ui64 GetListLength() const override {
+ ui64 GetListLength() const override {
return TBoxedValueAccessor::GetListLength(*Orig);
}
- ui64 GetEstimatedListLength() const override {
+ ui64 GetEstimatedListLength() const override {
return TBoxedValueAccessor::GetEstimatedListLength(*Orig);
}
- TUnboxedValue GetListIterator() const override {
- return TUnboxedValuePod(new TLazyVerifyListIterator<TValidateErrorPolicy>(*this));
- }
+ TUnboxedValue GetListIterator() const override {
+ return TUnboxedValuePod(new TLazyVerifyListIterator<TValidateErrorPolicy>(*this));
+ }
- const TOpaqueListRepresentation* GetListRepresentation() const override {
+ const TOpaqueListRepresentation* GetListRepresentation() const override {
return nullptr;
}
@@ -132,11 +132,11 @@ private:
}
};
-template<class TValidateErrorPolicy, bool Keys>
-struct TLazyVerifyDictIterator: public TBoxedValue {
+template<class TValidateErrorPolicy, bool Keys>
+struct TLazyVerifyDictIterator: public TBoxedValue {
TLazyVerifyDictIterator(const TLazyVerifyDictValue<TValidateErrorPolicy>& lazyDict, ui64 index = 0)
: LazyDict(lazyDict)
- , OrigIter((Keys ? &TBoxedValueAccessor::GetKeysIterator : &TBoxedValueAccessor::GetDictIterator)(*LazyDict.Orig))
+ , OrigIter((Keys ? &TBoxedValueAccessor::GetKeysIterator : &TBoxedValueAccessor::GetDictIterator)(*LazyDict.Orig))
, Index(index)
{
if (!OrigIter) {
@@ -146,33 +146,33 @@ struct TLazyVerifyDictIterator: public TBoxedValue {
private:
const TLazyVerifyDictValue<TValidateErrorPolicy>& LazyDict;
- TUnboxedValue OrigIter;
+ TUnboxedValue OrigIter;
ui64 Index;
- bool Skip() final {
- ++Index;
- return OrigIter.Skip();
- }
-
- bool Next(NUdf::TUnboxedValue& key) final {
- ++Index;
- if (!OrigIter.Next(key))
- return false;
- key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.KeyType, std::move(key),
- TStringBuilder() << "LazyDict[" << Index << "], validate key" << VERIFY_DELIMITER << LazyDict.Message);
- return true;
- }
-
- bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
- ++Index;
- if (!OrigIter.NextPair(key, payload))
- return false;
- key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.KeyType, std::move(key),
- TStringBuilder() << "LazyDict[" << Index << "], validate key" << VERIFY_DELIMITER << LazyDict.Message);
- payload = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.PayloadType, std::move(payload),
- TStringBuilder() << "LazyDict[" << Index << "], validate payload" << VERIFY_DELIMITER << LazyDict.Message);
- return true;
- }
+ bool Skip() final {
+ ++Index;
+ return OrigIter.Skip();
+ }
+
+ bool Next(NUdf::TUnboxedValue& key) final {
+ ++Index;
+ if (!OrigIter.Next(key))
+ return false;
+ key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.KeyType, std::move(key),
+ TStringBuilder() << "LazyDict[" << Index << "], validate key" << VERIFY_DELIMITER << LazyDict.Message);
+ return true;
+ }
+
+ bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
+ ++Index;
+ if (!OrigIter.NextPair(key, payload))
+ return false;
+ key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.KeyType, std::move(key),
+ TStringBuilder() << "LazyDict[" << Index << "], validate key" << VERIFY_DELIMITER << LazyDict.Message);
+ payload = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(LazyDict.ValueBuilder, LazyDict.PayloadType, std::move(payload),
+ TStringBuilder() << "LazyDict[" << Index << "], validate payload" << VERIFY_DELIMITER << LazyDict.Message);
+ return true;
+ }
};
template<class TValidateErrorPolicy>
@@ -189,36 +189,36 @@ struct TLazyVerifyDictValue: public TBoxedValue {
, Message(message)
{}
- const IValueBuilder *const ValueBuilder;
- const TType *const KeyType;
- const TType *const PayloadType;
+ const IValueBuilder *const ValueBuilder;
+ const TType *const KeyType;
+ const TType *const PayloadType;
const IBoxedValuePtr Orig;
- const TString Message;
+ const TString Message;
private:
- ui64 GetDictLength() const override {
+ ui64 GetDictLength() const override {
return TBoxedValueAccessor::GetDictLength(*Orig);
}
-
- TUnboxedValue GetKeysIterator() const override {
- return TUnboxedValuePod(new TLazyVerifyDictIterator<TValidateErrorPolicy, true>(*this));
- }
-
- TUnboxedValue GetDictIterator() const override {
- return TUnboxedValuePod(new TLazyVerifyDictIterator<TValidateErrorPolicy, false>(*this));
- }
-
- bool Contains(const TUnboxedValuePod& key) const override {
- return TBoxedValueAccessor::Contains(*Orig, key);
- }
- TUnboxedValue Lookup(const TUnboxedValuePod& key) const override {
- if (auto lookup = TBoxedValueAccessor::Lookup(*Orig, key)) {
- return TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(ValueBuilder, PayloadType, lookup.Release().GetOptionalValue(),
- TStringBuilder() << "LazyDict, validate Lookup payload" << VERIFY_DELIMITER << Message).Release().MakeOptional();
- }
- return TUnboxedValuePod();
- }
-
+
+ TUnboxedValue GetKeysIterator() const override {
+ return TUnboxedValuePod(new TLazyVerifyDictIterator<TValidateErrorPolicy, true>(*this));
+ }
+
+ TUnboxedValue GetDictIterator() const override {
+ return TUnboxedValuePod(new TLazyVerifyDictIterator<TValidateErrorPolicy, false>(*this));
+ }
+
+ bool Contains(const TUnboxedValuePod& key) const override {
+ return TBoxedValueAccessor::Contains(*Orig, key);
+ }
+ TUnboxedValue Lookup(const TUnboxedValuePod& key) const override {
+ if (auto lookup = TBoxedValueAccessor::Lookup(*Orig, key)) {
+ return TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(ValueBuilder, PayloadType, lookup.Release().GetOptionalValue(),
+ TStringBuilder() << "LazyDict, validate Lookup payload" << VERIFY_DELIMITER << Message).Release().MakeOptional();
+ }
+ return TUnboxedValuePod();
+ }
+
bool HasListItems() const override {
const bool result = TBoxedValueAccessor::HasListItems(*Orig);
if (result) {
@@ -238,11 +238,11 @@ public:
WrapCallableValue(const TCallableType* callableType, TUnboxedValue&& callable, const TString& message);
private:
- const TCallableType *const CallableType;
- const TUnboxedValue Callable;
- const TString Message;
+ const TCallableType *const CallableType;
+ const TUnboxedValue Callable;
+ const TString Message;
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final;
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final;
};
template<class TValidateErrorPolicy, class TValidateMode>
@@ -254,13 +254,13 @@ WrapCallableValue<TValidateErrorPolicy, TValidateMode>::WrapCallableValue(const
}
template<class TValidateErrorPolicy, class TValidateMode>
-TUnboxedValue WrapCallableValue<TValidateErrorPolicy, TValidateMode>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const {
+TUnboxedValue WrapCallableValue<TValidateErrorPolicy, TValidateMode>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const {
const ui32 argsCount = CallableType->GetArgumentsCount();
TSmallVec<TUnboxedValue> wrapArgs(argsCount);
bool childWrapped = false;
for (ui32 indexArg = 0; indexArg < argsCount; ++indexArg) {
const auto argType = CallableType->GetArgumentType(indexArg);
- wrapArgs[indexArg] = TValidate<TValidateErrorPolicy, TValidateMode>::Value(valueBuilder, argType, TUnboxedValuePod(args[indexArg]), TStringBuilder() << "CallableWrapper<" << CallableType->GetName() << ">.arg[" << indexArg << "]" << VERIFY_DELIMITER << Message, &childWrapped);
+ wrapArgs[indexArg] = TValidate<TValidateErrorPolicy, TValidateMode>::Value(valueBuilder, argType, TUnboxedValuePod(args[indexArg]), TStringBuilder() << "CallableWrapper<" << CallableType->GetName() << ">.arg[" << indexArg << "]" << VERIFY_DELIMITER << Message, &childWrapped);
}
return TValidate<TValidateErrorPolicy, TValidateMode>::Value(valueBuilder, CallableType->GetReturnType(), Callable.Run(valueBuilder, childWrapped ? wrapArgs.data() : args), TStringBuilder() << "CallableWrapper<" << CallableType->GetName() << ">.result" << VERIFY_DELIMITER << Message);
}
@@ -292,14 +292,14 @@ struct TValidateModeGreedy {
}
const TType* itemType = listType->GetItemType();
- std::vector<NUdf::TUnboxedValue> list;
- if (TBoxedValueAccessor::HasFastListLength(*boxed))
- list.reserve(TBoxedValueAccessor::GetListLength(*boxed));
+ std::vector<NUdf::TUnboxedValue> list;
+ if (TBoxedValueAccessor::HasFastListLength(*boxed))
+ list.reserve(TBoxedValueAccessor::GetListLength(*boxed));
bool childWrapped = false;
ui64 curIndex = 0;
- const auto iter = TBoxedValueAccessor::GetListIterator(*boxed);
- for (NUdf::TUnboxedValue current; iter.Next(current); ++curIndex) {
- list.emplace_back(TValidate<TValidateErrorPolicy, TValidateModeGreedy>::Value(valueBuilder, itemType, std::move(current),
+ const auto iter = TBoxedValueAccessor::GetListIterator(*boxed);
+ for (NUdf::TUnboxedValue current; iter.Next(current); ++curIndex) {
+ list.emplace_back(TValidate<TValidateErrorPolicy, TValidateModeGreedy>::Value(valueBuilder, itemType, std::move(current),
TStringBuilder() << "LazyList[" << curIndex << "]" << VERIFY_DELIMITER << message, &childWrapped));
}
const auto elementsCount = TBoxedValueAccessor::GetListLength(*boxed);
@@ -310,9 +310,9 @@ struct TValidateModeGreedy {
if (wrapped) {
*wrapped = true;
}
- return valueBuilder->NewList(list.data(), list.size());
+ return valueBuilder->NewList(list.data(), list.size());
}
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
static TUnboxedValue ProcessDict(const IValueBuilder* valueBuilder, const TDictType* dictType, IBoxedValuePtr&& boxed, const TString& message, bool* wrapped) {
@@ -321,13 +321,13 @@ struct TValidateModeGreedy {
auto dictBuilder = valueBuilder->NewDict(dictType, TDictFlags::Sorted);
bool childWrapped = false;
ui64 curIndex = 0;
- const auto iter = TBoxedValueAccessor::GetDictIterator(*boxed);
- for (NUdf::TUnboxedValue key, payload; iter.NextPair(key, payload); ++curIndex) {
- key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(valueBuilder, keyType, std::move(key),
- TStringBuilder() << "GreedyDict[" << curIndex << "], validate key" << VERIFY_DELIMITER << message);
- payload = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(valueBuilder, payloadType, std::move(payload),
- TStringBuilder() << "GreedyDict[" << curIndex << "], validate payload" << VERIFY_DELIMITER << message);
- dictBuilder->Add(std::move(key), std::move(payload));
+ const auto iter = TBoxedValueAccessor::GetDictIterator(*boxed);
+ for (NUdf::TUnboxedValue key, payload; iter.NextPair(key, payload); ++curIndex) {
+ key = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(valueBuilder, keyType, std::move(key),
+ TStringBuilder() << "GreedyDict[" << curIndex << "], validate key" << VERIFY_DELIMITER << message);
+ payload = TValidate<TValidateErrorPolicy, TValidateModeLazy<TValidateErrorPolicy>>::Value(valueBuilder, payloadType, std::move(payload),
+ TStringBuilder() << "GreedyDict[" << curIndex << "], validate payload" << VERIFY_DELIMITER << message);
+ dictBuilder->Add(std::move(key), std::move(payload));
}
const auto elementsCount = TBoxedValueAccessor::GetDictLength(*boxed);
if (curIndex != elementsCount) {
@@ -339,12 +339,12 @@ struct TValidateModeGreedy {
}
return dictBuilder->Build();
}
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
};
template<class TValidateErrorPolicy, class TValidateMode>
-NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped) {
+NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped) {
if (!value && !(type->IsOptional() || type->IsNull())) {
TValidateErrorPolicy::Generate(TStringBuilder() << "Expected value '" << PrintNode(type, true) << "', but got Empty" << VERIFY_DELIMITER << message);
}
@@ -363,14 +363,14 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
if (!slot) {
TValidateErrorPolicy::GenerateExc(TUdfValidateException() << "Unregistered TypeId: " << dataTypeId << VERIFY_DELIMITER << message);
}
- if (!IsValidValue(*slot, value)) {
+ if (!IsValidValue(*slot, value)) {
TValidateErrorPolicy::Generate(TStringBuilder() << "Expected value '" << PrintNode(type, true) << "' does not conform" << VERIFY_DELIMITER << message);
}
break;
}
case TType::EKind::Optional: {
- if (!value) {
+ if (!value) {
break;
}
auto optionalType = static_cast<const TOptionalType*>(type);
@@ -380,7 +380,7 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
if (wrapped) {
*wrapped = true;
}
- return upValue.Release().MakeOptional();
+ return upValue.Release().MakeOptional();
}
break;
}
@@ -390,7 +390,7 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
TValidateErrorPolicy::Generate(TStringBuilder() << "expected value '" << PrintNode(type, true) << "' not conform" << VERIFY_DELIMITER << message);
}
auto listType = static_cast<const TListType*>(type);
- return TValidateMode::ProcessList(valueBuilder, listType, std::move(value.Release().AsBoxed()), message, wrapped);
+ return TValidateMode::ProcessList(valueBuilder, listType, std::move(value.Release().AsBoxed()), message, wrapped);
}
case TType::EKind::Struct: {
@@ -405,8 +405,8 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
stackItems[index] = TValidate<TValidateErrorPolicy, TValidateMode>::Value(valueBuilder, memberType, value.GetElement(index), TStringBuilder() << "Struct[" << structType->GetMemberName(index) << "]" << VERIFY_DELIMITER << message, &childWrapped);
}
if (childWrapped) {
- TUnboxedValue* items = nullptr;
- const auto wrappedStruct = valueBuilder->NewArray(structType->GetMembersCount(), items);
+ TUnboxedValue* items = nullptr;
+ const auto wrappedStruct = valueBuilder->NewArray(structType->GetMembersCount(), items);
for (ui32 index = 0; index < structType->GetMembersCount(); ++index) {
items[index] = std::move(stackItems[index]);
}
@@ -424,14 +424,14 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
}
auto tupleType = static_cast<const TTupleType*>(type);
bool childWrapped = false;
- TSmallVec<NUdf::TUnboxedValue> stackItems(tupleType->GetElementsCount());
+ TSmallVec<NUdf::TUnboxedValue> stackItems(tupleType->GetElementsCount());
for (ui32 index = 0; index < tupleType->GetElementsCount(); ++index) {
TType* elementType = tupleType->GetElementType(index);
stackItems[index] = TValidate<TValidateErrorPolicy, TValidateMode>::Value(valueBuilder, elementType, value.GetElement(index), TStringBuilder() << "Tuple[" << index << "]" << VERIFY_DELIMITER << message, &childWrapped);
}
if (childWrapped) {
- TUnboxedValue* items = nullptr;
- const auto wrappedTuple = valueBuilder->NewArray(tupleType->GetElementsCount(), items);
+ TUnboxedValue* items = nullptr;
+ const auto wrappedTuple = valueBuilder->NewArray(tupleType->GetElementsCount(), items);
for (ui32 index = 0; index < tupleType->GetElementsCount(); ++index) {
items[index] = std::move(stackItems[index]);
}
@@ -448,7 +448,7 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
TValidateErrorPolicy::Generate(TStringBuilder() << "expected value '" << PrintNode(type, true) << "' not conform" << VERIFY_DELIMITER << message);
}
auto dictType = static_cast<const TDictType*>(type);
- return TValidateMode::ProcessDict(valueBuilder, dictType, std::move(value.Release().AsBoxed()), message, wrapped);
+ return TValidateMode::ProcessDict(valueBuilder, dictType, std::move(value.Release().AsBoxed()), message, wrapped);
}
case TType::EKind::Callable: {
@@ -459,8 +459,8 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
if (wrapped) {
*wrapped = true;
}
- TValidate<TValidateErrorPolicy>::WrapCallable(callableType, value, message);
- return value;
+ TValidate<TValidateErrorPolicy>::WrapCallable(callableType, value, message);
+ return value;
}
case TType::EKind::Type:
@@ -492,12 +492,12 @@ NUdf::TUnboxedValue TValidate<TValidateErrorPolicy, TValidateMode>::Value(const
default:
Y_FAIL("Verify value meet unexpected type kind: %s", type->GetKindAsStr().data());
}
- return std::move(value);
+ return std::move(value);
}
template<class TValidateErrorPolicy, class TValidateMode>
-void TValidate<TValidateErrorPolicy, TValidateMode>::WrapCallable(const TCallableType* callableType, NUdf::TUnboxedValue& callable, const TString& message) {
- callable = NUdf::TUnboxedValuePod(new WrapCallableValue<TValidateErrorPolicy, TValidateMode>(callableType, std::move(callable), TStringBuilder() << "CallableWrapper<" << callableType->GetName() << ">" << VERIFY_DELIMITER << message));
+void TValidate<TValidateErrorPolicy, TValidateMode>::WrapCallable(const TCallableType* callableType, NUdf::TUnboxedValue& callable, const TString& message) {
+ callable = NUdf::TUnboxedValuePod(new WrapCallableValue<TValidateErrorPolicy, TValidateMode>(callableType, std::move(callable), TStringBuilder() << "CallableWrapper<" << callableType->GetName() << ">" << VERIFY_DELIMITER << message));
}
template struct TValidate<TValidateErrorPolicyThrow, TValidateModeLazy<TValidateErrorPolicyThrow>>;
diff --git a/ydb/library/yql/minikql/computation/mkql_validate.h b/ydb/library/yql/minikql/computation/mkql_validate.h
index 831ece5a82..136b700d5a 100644
--- a/ydb/library/yql/minikql/computation/mkql_validate.h
+++ b/ydb/library/yql/minikql/computation/mkql_validate.h
@@ -17,8 +17,8 @@ struct TValidateModeGreedy;
template<class TErrorPolicy, class TValidateMode = TValidateModeLazy<TErrorPolicy>>
struct TValidate {
- static NUdf::TUnboxedValue Value(const NUdf::IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped = nullptr);
- static void WrapCallable(const TCallableType* callableType, NUdf::TUnboxedValue& callable, const TString& message);
+ static NUdf::TUnboxedValue Value(const NUdf::IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped = nullptr);
+ static void WrapCallable(const TCallableType* callableType, NUdf::TUnboxedValue& callable, const TString& message);
};
} // namespace MiniKQL
diff --git a/ydb/library/yql/minikql/computation/mkql_validate_impl.h b/ydb/library/yql/minikql/computation/mkql_validate_impl.h
index 2fb876afea..c4e10ac4b1 100644
--- a/ydb/library/yql/minikql/computation/mkql_validate_impl.h
+++ b/ydb/library/yql/minikql/computation/mkql_validate_impl.h
@@ -36,15 +36,15 @@ struct TValidateErrorPolicyFail {
template<class TValidateMode>
struct TValidate<TValidateErrorPolicyNone, TValidateMode> {
-static NUdf::TUnboxedValue Value(const NUdf::IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped) {
+static NUdf::TUnboxedValue Value(const NUdf::IValueBuilder* valueBuilder, const TType* type, NUdf::TUnboxedValue&& value, const TString& message, bool* wrapped) {
Y_UNUSED(valueBuilder);
Y_UNUSED(type);
Y_UNUSED(message);
Y_UNUSED(wrapped);
- return std::move(value);
+ return std::move(value);
}
-static void WrapCallable(const TCallableType*, NUdf::TUnboxedValue&, const TString&) {}
+static void WrapCallable(const TCallableType*, NUdf::TUnboxedValue&, const TString&) {}
};
diff --git a/ydb/library/yql/minikql/computation/mkql_validate_ut.cpp b/ydb/library/yql/minikql/computation/mkql_validate_ut.cpp
index f1db3fbb11..ed2f12303a 100644
--- a/ydb/library/yql/minikql/computation/mkql_validate_ut.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_validate_ut.cpp
@@ -3,7 +3,7 @@
#include "mkql_computation_list_adapter.h"
#include "mkql_computation_node_impl.h"
#include "mkql_computation_node.h"
-#include "mkql_value_builder.h"
+#include "mkql_value_builder.h"
#include <ydb/library/yql/minikql/mkql_function_registry.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h>
@@ -19,20 +19,20 @@
#include <ydb/library/yql/public/udf/udf_helpers.h>
-namespace NYql {
+namespace NYql {
-namespace {
-using namespace NKikimr::NMiniKQL;
+namespace {
+using namespace NKikimr::NMiniKQL;
static const ui32 RAW_INDEX_NO_HOLE = -1;
static const ui32 RAW_BROKEN_INDEX_LIST_TO_DICT = 1;
-
-template<class T>
-NUdf::TUnboxedValue ToUnboxedValue(const T& val) {
- return NUdf::TUnboxedValuePod(val);
-}
-
-NUdf::TUnboxedValue ToUnboxedValue(const TString& val) {
- return MakeString(val);
+
+template<class T>
+NUdf::TUnboxedValue ToUnboxedValue(const T& val) {
+ return NUdf::TUnboxedValuePod(val);
+}
+
+NUdf::TUnboxedValue ToUnboxedValue(const TString& val) {
+ return MakeString(val);
}
NUdf::TUnboxedValue ToUnboxedValue(const NUdf::IBoxedValuePtr& val) {
@@ -45,8 +45,8 @@ NUdf::TUnboxedValue ToUnboxedValue(const NUdf::IBoxedValuePtr& val) {
namespace NUdf {
template<class TContainer>
- struct TListRefIterator: public TBoxedValue {
- TListRefIterator(const TContainer& listRef, ui32 holePos)
+ struct TListRefIterator: public TBoxedValue {
+ TListRefIterator(const TContainer& listRef, ui32 holePos)
: ListRef(listRef)
, Index(-1)
, HolePos(holePos)
@@ -57,16 +57,16 @@ namespace NUdf {
ui32 HolePos;
bool Next(NUdf::TUnboxedValue& value) final {
- if (++Index >= ListRef.size())
- return false;
- value = Index == HolePos ? NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(42)) : ToUnboxedValue(ListRef[Index]);
- return true;
- }
+ if (++Index >= ListRef.size())
+ return false;
+ value = Index == HolePos ? NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(42)) : ToUnboxedValue(ListRef[Index]);
+ return true;
+ }
};
- template<class TContainer, ui32 TIndexDictBrokenHole = RAW_INDEX_NO_HOLE, bool TNoDictIndex = false>
+ template<class TContainer, ui32 TIndexDictBrokenHole = RAW_INDEX_NO_HOLE, bool TNoDictIndex = false>
struct TListRef: public NUdf::TBoxedValue {
- TListRef(const TContainer& listRef, ui32 holePos = RAW_INDEX_NO_HOLE)
+ TListRef(const TContainer& listRef, ui32 holePos = RAW_INDEX_NO_HOLE)
: ListRef(listRef)
, HolePos(holePos)
{}
@@ -88,13 +88,13 @@ namespace NUdf {
return ListRef.size();
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TListRefIterator<TContainer>(ListRef, HolePos));
- }
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TListRefIterator<TContainer>(ListRef, HolePos));
+ }
NUdf::IBoxedValuePtr ToIndexDictImpl(const IValueBuilder& builder) const override {
- return TNoDictIndex ? nullptr : builder.ToIndexDict(NUdf::TUnboxedValuePod(
- new TListRef<TContainer, TIndexDictBrokenHole, true>(ListRef, TIndexDictBrokenHole))).AsBoxed();
+ return TNoDictIndex ? nullptr : builder.ToIndexDict(NUdf::TUnboxedValuePod(
+ new TListRef<TContainer, TIndexDictBrokenHole, true>(ListRef, TIndexDictBrokenHole))).AsBoxed();
}
};
@@ -107,11 +107,11 @@ namespace NUdf {
TString LastName;
ui32 Age;
- NUdf::TUnboxedValue GetByIndex(ui32 index) const {
+ NUdf::TUnboxedValue GetByIndex(ui32 index) const {
switch (index) {
- case 0: return ToUnboxedValue(FirstName);
- case 1: return ToUnboxedValue(LastName);
- case 2: return NUdf::TUnboxedValuePod(Age);
+ case 0: return ToUnboxedValue(FirstName);
+ case 1: return ToUnboxedValue(LastName);
+ case 2: return NUdf::TUnboxedValuePod(Age);
default: Y_FAIL("Unexpected");
}
}
@@ -129,17 +129,17 @@ namespace NUdf {
TString FirstName;
TString LastName;
ui32 Age;
- typedef std::vector<ui32> TTagList;
+ typedef std::vector<ui32> TTagList;
TTagList Tags;
- NUdf::TUnboxedValue GetByIndex(ui32 index) const {
+ NUdf::TUnboxedValue GetByIndex(ui32 index) const {
switch (index) {
- case 0: return ToUnboxedValue(FirstName);
- case 1: return ToUnboxedValue(LastName);
- case 2: return NUdf::TUnboxedValuePod(Age);
- case 3: return Tags.empty() ?
- NUdf::TUnboxedValuePod() :
- NUdf::TUnboxedValuePod(new TListRef<TTagList>(Tags));
+ case 0: return ToUnboxedValue(FirstName);
+ case 1: return ToUnboxedValue(LastName);
+ case 2: return NUdf::TUnboxedValuePod(Age);
+ case 3: return Tags.empty() ?
+ NUdf::TUnboxedValuePod() :
+ NUdf::TUnboxedValuePod(new TListRef<TTagList>(Tags));
default: Y_FAIL("Unexpected");
}
}
@@ -204,7 +204,7 @@ namespace NImpl {
/// @}
- struct TBrokenSeqListIterator: public NUdf::TBoxedValue {
+ struct TBrokenSeqListIterator: public NUdf::TBoxedValue {
TBrokenSeqListIterator(ui32 size, ui32 holePos)
: Size(size)
, HolePos(holePos)
@@ -216,15 +216,15 @@ namespace NImpl {
ui32 Index;
bool Skip() final {
- return ++Index < Size;
- }
-
+ return ++Index < Size;
+ }
+
bool Next(NUdf::TUnboxedValue& value) final {
- if (!Skip())
- return false;
- value = Index == HolePos ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(Index);
- return true;
- }
+ if (!Skip())
+ return false;
+ value = Index == HolePos ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(Index);
+ return true;
+ }
};
struct TBrokenSeqListBoxedValue: public NUdf::TBoxedValue {
@@ -249,14 +249,14 @@ namespace NImpl {
return ListSize;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TBrokenSeqListIterator(ListSize, HolePos));
- }
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TBrokenSeqListIterator(ListSize, HolePos));
+ }
};
template<class TStructType>
struct TBrokenStructBoxedValue: public NUdf::TBoxedValue {
- TBrokenStructBoxedValue(const TStructType& data, ui32 holePos = RAW_INDEX_NO_HOLE)
+ TBrokenStructBoxedValue(const TStructType& data, ui32 holePos = RAW_INDEX_NO_HOLE)
: Struct(data)
, HolePos(holePos)
{}
@@ -265,29 +265,29 @@ namespace NImpl {
const TStructType& Struct;
ui32 HolePos;
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- if (index == HolePos) {
- return NUdf::TUnboxedValuePod();
- }
- return Struct.GetByIndex(TStructType::MetaBackIndexes[index]);
- }
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ if (index == HolePos) {
+ return NUdf::TUnboxedValuePod();
+ }
+ return Struct.GetByIndex(TStructType::MetaBackIndexes[index]);
+ }
};
-
-namespace {
- template<>
- NUdf::TUnboxedValue ToUnboxedValue<NUdf::PersonStruct>(const NUdf::PersonStruct& val) {
- return NUdf::TUnboxedValuePod(new TBrokenStructBoxedValue<NUdf::PersonStruct>(val));
- }
-
- template<>
- NUdf::TUnboxedValue ToUnboxedValue<NUdf::PersonStructWithOptList>(const NUdf::PersonStructWithOptList& val) {
- return NUdf::TUnboxedValuePod(new TBrokenStructBoxedValue<NUdf::PersonStructWithOptList>(val));
+
+namespace {
+ template<>
+ NUdf::TUnboxedValue ToUnboxedValue<NUdf::PersonStruct>(const NUdf::PersonStruct& val) {
+ return NUdf::TUnboxedValuePod(new TBrokenStructBoxedValue<NUdf::PersonStruct>(val));
+ }
+
+ template<>
+ NUdf::TUnboxedValue ToUnboxedValue<NUdf::PersonStructWithOptList>(const NUdf::PersonStructWithOptList& val) {
+ return NUdf::TUnboxedValuePod(new TBrokenStructBoxedValue<NUdf::PersonStructWithOptList>(val));
}
template<class TTupleType>
struct TBrokenTupleBoxedValue: public NUdf::TBoxedValue {
- TBrokenTupleBoxedValue(const TTupleType& tuple, ui32 holePos)
+ TBrokenTupleBoxedValue(const TTupleType& tuple, ui32 holePos)
: Tuple(tuple)
, HolePos(holePos)
{}
@@ -296,154 +296,154 @@ namespace {
const TTupleType& Tuple;
ui32 HolePos;
- NUdf::TUnboxedValue GetElement(ui32 index) const override {
- if (index == HolePos) {
- return NUdf::TUnboxedValuePod();
- }
- switch (index) {
- case 0: return ToUnboxedValue(std::get<0>(Tuple));
- case 1: return ToUnboxedValue(std::get<1>(Tuple));
- case 2: return ToUnboxedValue(std::get<2>(Tuple));
- case 3: return ToUnboxedValue(std::get<3>(Tuple));
- default: Y_FAIL("Unexpected");
- }
+ NUdf::TUnboxedValue GetElement(ui32 index) const override {
+ if (index == HolePos) {
+ return NUdf::TUnboxedValuePod();
+ }
+ switch (index) {
+ case 0: return ToUnboxedValue(std::get<0>(Tuple));
+ case 1: return ToUnboxedValue(std::get<1>(Tuple));
+ case 2: return ToUnboxedValue(std::get<2>(Tuple));
+ case 3: return ToUnboxedValue(std::get<3>(Tuple));
+ default: Y_FAIL("Unexpected");
+ }
}
};
typedef std::pair<ui32, ui32> PosPair;
template<class TKey, class TValue>
- struct TBrokenDictIterator: public NUdf::TBoxedValue {
- TBrokenDictIterator(const std::vector<std::pair<TKey, TValue>>& dictData, PosPair holePos)
+ struct TBrokenDictIterator: public NUdf::TBoxedValue {
+ TBrokenDictIterator(const std::vector<std::pair<TKey, TValue>>& dictData, PosPair holePos)
: DictData(dictData)
, HolePos(holePos)
, Index(-1)
{}
private:
- const std::vector<std::pair<TKey, TValue>>& DictData;
+ const std::vector<std::pair<TKey, TValue>>& DictData;
PosPair HolePos;
ui32 Index;
bool Skip() final {
- return ++Index < DictData.size();
- }
-
+ return ++Index < DictData.size();
+ }
+
bool Next(NUdf::TUnboxedValue& key) final {
- if (!Skip())
- return false;
- key = Index == HolePos.first ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(DictData[Index].first);
- return true;
- }
-
+ if (!Skip())
+ return false;
+ key = Index == HolePos.first ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(DictData[Index].first);
+ return true;
+ }
+
bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
- if (!Next(key))
- return false;
- payload = Index == HolePos.second ? NUdf::TUnboxedValue() : ToUnboxedValue(DictData[Index].second);
- return true;
- }
+ if (!Next(key))
+ return false;
+ payload = Index == HolePos.second ? NUdf::TUnboxedValue() : ToUnboxedValue(DictData[Index].second);
+ return true;
+ }
};
template<class TKey, class TValue>
struct TBrokenDictBoxedValue: public NUdf::TBoxedValue {
- TBrokenDictBoxedValue(const std::vector<std::pair<TKey, TValue>>& dictData,
- PosPair holePos, NUdf::TUnboxedValue&& hole = NUdf::TUnboxedValuePod())
+ TBrokenDictBoxedValue(const std::vector<std::pair<TKey, TValue>>& dictData,
+ PosPair holePos, NUdf::TUnboxedValue&& hole = NUdf::TUnboxedValuePod())
: DictData(dictData)
, HolePos(holePos)
- , Hole(std::move(hole))
+ , Hole(std::move(hole))
{}
private:
- const std::vector<std::pair<TKey, TValue>> DictData;
+ const std::vector<std::pair<TKey, TValue>> DictData;
PosPair HolePos;
NUdf::TUnboxedValue Hole;
-
- NUdf::TUnboxedValue GetKeysIterator() const override {
- return NUdf::TUnboxedValuePod(new TBrokenDictIterator<TKey, TValue>(DictData, HolePos));
- }
-
- NUdf::TUnboxedValue GetDictIterator() const override {
- return NUdf::TUnboxedValuePod(new TBrokenDictIterator<TKey, TValue>(DictData, HolePos));
- }
+
+ NUdf::TUnboxedValue GetKeysIterator() const override {
+ return NUdf::TUnboxedValuePod(new TBrokenDictIterator<TKey, TValue>(DictData, HolePos));
+ }
+
+ NUdf::TUnboxedValue GetDictIterator() const override {
+ return NUdf::TUnboxedValuePod(new TBrokenDictIterator<TKey, TValue>(DictData, HolePos));
+ }
};
- struct TThrowerValue: public NUdf::TBoxedValue {
- static long Count;
+ struct TThrowerValue: public NUdf::TBoxedValue {
+ static long Count;
TThrowerValue(NUdf::IBoxedValuePtr&& owner = NUdf::IBoxedValuePtr())
- : Owner(std::move(owner))
- { ++Count; }
- ~TThrowerValue() { --Count; }
- private:
+ : Owner(std::move(owner))
+ { ++Count; }
+ ~TThrowerValue() { --Count; }
+ private:
const NUdf::IBoxedValuePtr Owner;
- bool Skip() override {
- ythrow yexception() << "Throw";
- }
-
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TThrowerValue(const_cast<TThrowerValue*>(this)));
- }
- };
-
+ bool Skip() override {
+ ythrow yexception() << "Throw";
+ }
+
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TThrowerValue(const_cast<TThrowerValue*>(this)));
+ }
+ };
+
SIMPLE_UDF(TException, NUdf::TListType<ui32>()) {
- Y_UNUSED(valueBuilder);
- Y_UNUSED(args);
- return NUdf::TUnboxedValuePod(new TThrowerValue);
- }
-
- long TThrowerValue::Count = 0L;
-
+ Y_UNUSED(valueBuilder);
+ Y_UNUSED(args);
+ return NUdf::TUnboxedValuePod(new TThrowerValue);
+ }
+
+ long TThrowerValue::Count = 0L;
+
SIMPLE_UDF(TVoid, void()) {
Y_UNUSED(valueBuilder);
Y_UNUSED(args);
- return NUdf::TUnboxedValuePod::Void();
+ return NUdf::TUnboxedValuePod::Void();
}
SIMPLE_UDF_RUN(TNonEmpty, ui32(), NUdf::TOptional<void>) {
Y_UNUSED(valueBuilder);
Y_UNUSED(args);
- return NUdf::TUnboxedValuePod(42);
+ return NUdf::TUnboxedValuePod(42);
}
SIMPLE_UDF(TOptionalNonEmpty, NUdf::TOptional<ui32>()) {
Y_UNUSED(valueBuilder);
Y_UNUSED(args);
- return NUdf::TUnboxedValuePod(42);
+ return NUdf::TUnboxedValuePod(42);
}
SIMPLE_UDF_RUN(TOptionalEmpty, NUdf::TOptional<ui32>(), NUdf::TOptional<void>) {
Y_UNUSED(valueBuilder);
Y_UNUSED(args);
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
SIMPLE_UDF(TSub2Mul2BrokenOnLess2, ui32(ui32)) {
Y_UNUSED(valueBuilder);
const ui32 arg = args[0].Get<ui32>();
if (arg >= 2) {
- return NUdf::TUnboxedValuePod((arg - 2) * 2);
+ return NUdf::TUnboxedValuePod((arg - 2) * 2);
}
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
SIMPLE_UDF_RUN(TBackSub2Mul2, ui32(NUdf::TCallableOneUi32Arg, ui32), NUdf::TOptional<void>) {
const auto func = args[0];
const auto& arg = args[1];
- auto usedArg = NUdf::TUnboxedValuePod();
+ auto usedArg = NUdf::TUnboxedValuePod();
if (arg.Get<ui32>() < 100) {
usedArg = arg;
}
auto funcResult = func.Run(valueBuilder, &usedArg);
const auto& backResult = funcResult.Get<ui32>() / 2 + 2;
- return NUdf::TUnboxedValuePod(backResult);
+ return NUdf::TUnboxedValuePod(backResult);
}
SIMPLE_UDF(TSeqList, NUdf::TListType<ui32>(ui32)) {
const ui32 size = args[0].Get<ui32>();
- std::vector<NUdf::TUnboxedValue> res;
+ std::vector<NUdf::TUnboxedValue> res;
res.resize(size);
for (ui32 i = 0; i < size; ++i) {
- res[i] = NUdf::TUnboxedValuePod(i);
+ res[i] = NUdf::TUnboxedValuePod(i);
}
return valueBuilder->NewList(res.data(), res.size());
}
@@ -453,7 +453,7 @@ namespace {
const ui32 size = args[0].Get<ui32>();
const ui32 hole = args[1].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenSeqListBoxedValue(size, hole));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
static const auto TUPLE = std::make_tuple(ui8(33), TString("world"), ui64(0xFEEDB00B2A115E), TString("funny bunny"));
@@ -461,13 +461,13 @@ namespace {
typedef NUdf::TTuple<ui8, char*, ui64, char*> NUdfTuple;
SIMPLE_UDF(TTuple, NUdfTuple(ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holePos = args[0].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenTupleBoxedValue<decltype(TUPLE)>(TUPLE, holePos));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
- static const std::vector<std::pair<ui32, ui64>> DICT_DIGIT2DIGIT = {
+ static const std::vector<std::pair<ui32, ui64>> DICT_DIGIT2DIGIT = {
{1, 100500},
{42, 0xDEADBEAF},
{911, 1234567890},
@@ -477,22 +477,22 @@ namespace {
typedef NUdf::TDict<ui32, ui64> NUdfDictDigDig;
SIMPLE_UDF_RUN(TDictDigDig, NUdfDictDigDig(ui32, ui32), NUdf::TOptional<void>) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holeKey = args[0].Get<ui32>();
const ui32 holeValue = args[1].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenDictBoxedValue<ui32, ui64>(
- DICT_DIGIT2DIGIT, std::make_pair(holeKey, holeValue)));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ DICT_DIGIT2DIGIT, std::make_pair(holeKey, holeValue)));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
SIMPLE_UDF(TDictDigDigHoleAsOpt, NUdfDictDigDig(ui32, ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holeKey = args[0].Get<ui32>();
const ui32 holeValue = args[1].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenDictBoxedValue<ui32, ui64>(DICT_DIGIT2DIGIT,
std::make_pair(holeKey, holeValue),
- NUdf::TUnboxedValuePod()));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ NUdf::TUnboxedValuePod()));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
static const NUdf::PersonStruct STRUCT_PERSON_JONNIE = {"Johnnie Walker", "Blue Label", 25};
@@ -504,10 +504,10 @@ namespace {
static const NUdf::PersonStructWithOptList STRUCT_PERSON_KING_LIST = {"Stephen", "King", 25, {}};
SIMPLE_UDF_RUN(TPersonStruct, NUdf::PersonStruct(ui32), NUdf::TOptional<void>) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holePos = args[0].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_JONNIE, holePos));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
typedef NUdf::TTuple<NUdf::PersonStructWithOptList,NUdf::PersonStruct,NUdf::PersonStructWithOptList,NUdf::PersonStruct> NUdfPersonTuple;
@@ -523,20 +523,20 @@ namespace {
STRUCT_PERSON_KING);
SIMPLE_UDF(TTupleOfPersonStruct, NUdfPersonTuple(ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holePos = args[0].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenTupleBoxedValue<decltype(TUPLE_OF_PERSON)>(TUPLE_OF_PERSON, holePos));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
SIMPLE_UDF(TTupleOfPersonStructNoList, NUdfPersonTuple(ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
const ui32 holePos = args[0].Get<ui32>();
NUdf::IBoxedValuePtr boxed(new TBrokenTupleBoxedValue<decltype(TUPLE_OF_PERSON_NO_LIST)>(TUPLE_OF_PERSON_NO_LIST, holePos));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
- static const std::vector<NUdf::PersonStructWithOptList> LIST_OF_STRUCT_PERSON = {
+ static const std::vector<NUdf::PersonStructWithOptList> LIST_OF_STRUCT_PERSON = {
STRUCT_PERSON_HITHCOCK_LIST,
STRUCT_PERSON_LOVECRAFT_LIST,
STRUCT_PERSON_KING_LIST
@@ -544,38 +544,38 @@ namespace {
typedef NUdf::TDict<ui64,NUdf::PersonStructWithOptList> TIndexDictFromPersonList;
SIMPLE_UDF(TListOfPersonStructToIndexDict, TIndexDictFromPersonList(ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
Y_UNUSED(args);
NUdf::IBoxedValuePtr boxed(new NUdf::TListRef<decltype(LIST_OF_STRUCT_PERSON)>(LIST_OF_STRUCT_PERSON));
- return valueBuilder->ToIndexDict(NUdf::TUnboxedValuePod(std::move(boxed)));
+ return valueBuilder->ToIndexDict(NUdf::TUnboxedValuePod(std::move(boxed)));
}
SIMPLE_UDF(TListOfPersonStruct, NUdf::TListType<NUdf::PersonStructWithOptList>(ui32)) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
Y_UNUSED(args);
NUdf::IBoxedValuePtr boxed(new NUdf::TListRef<decltype(LIST_OF_STRUCT_PERSON)>(LIST_OF_STRUCT_PERSON));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
SIMPLE_UDF(TListOfPersonStructWithBrokenIndexToDict, NUdf::TListType<NUdf::PersonStructWithOptList>()) {
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
Y_UNUSED(args);
NUdf::IBoxedValuePtr boxed(new NUdf::TListRef<decltype(LIST_OF_STRUCT_PERSON), RAW_BROKEN_INDEX_LIST_TO_DICT>(
- LIST_OF_STRUCT_PERSON));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ LIST_OF_STRUCT_PERSON));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
-
+
static const NUdf::PersonStruct* DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[] = {
&STRUCT_PERSON_HITHCOCK, &STRUCT_PERSON_JONNIE, &STRUCT_PERSON_LOVECRAFT
};
- const ui32 DICT_DIGIT2PERSON_BROKEN_PERSON_INDEX = 1;
+ const ui32 DICT_DIGIT2PERSON_BROKEN_PERSON_INDEX = 1;
const ui32 DICT_DIGIT2PERSON_BROKEN_STRUCT_INDEX = 2;
const std::vector<std::pair<ui32, NUdf::IBoxedValuePtr>> MAKE_DICT_DIGIT2PERSON_BROKEN() {
std::vector<std::pair<ui32, NUdf::IBoxedValuePtr>> DICT_DIGIT2PERSON_BROKEN = {
- { 333, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_HITHCOCK, RAW_INDEX_NO_HOLE) },
- { 5, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_JONNIE, DICT_DIGIT2PERSON_BROKEN_STRUCT_INDEX) },
- { 77, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_LOVECRAFT, RAW_INDEX_NO_HOLE) },
+ { 333, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_HITHCOCK, RAW_INDEX_NO_HOLE) },
+ { 5, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_JONNIE, DICT_DIGIT2PERSON_BROKEN_STRUCT_INDEX) },
+ { 77, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_LOVECRAFT, RAW_INDEX_NO_HOLE) },
};
return DICT_DIGIT2PERSON_BROKEN;
@@ -585,9 +585,9 @@ namespace {
std::vector<std::pair<ui32, NUdf::IBoxedValuePtr>> MAKE_DICT_DIGIT2PERSON() {
const std::vector<std::pair<ui32, NUdf::IBoxedValuePtr>> DICT_DIGIT2PERSON = {
- { 333, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_HITHCOCK, RAW_INDEX_NO_HOLE) },
- { 5, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_JONNIE, RAW_INDEX_NO_HOLE) },
- { 77, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_LOVECRAFT, RAW_INDEX_NO_HOLE) },
+ { 333, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_HITHCOCK, RAW_INDEX_NO_HOLE) },
+ { 5, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_JONNIE, RAW_INDEX_NO_HOLE) },
+ { 77, new TBrokenStructBoxedValue<NUdf::PersonStruct>(STRUCT_PERSON_LOVECRAFT, RAW_INDEX_NO_HOLE) },
};
return DICT_DIGIT2PERSON;
@@ -595,22 +595,22 @@ namespace {
SIMPLE_UDF(TDictOfPerson, NUdfDictDigPerson()) {
Y_UNUSED(args);
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
NUdf::IBoxedValuePtr boxed(new TBrokenDictBoxedValue<ui32, NUdf::IBoxedValuePtr>(
- MAKE_DICT_DIGIT2PERSON(), std::make_pair(RAW_INDEX_NO_HOLE, RAW_INDEX_NO_HOLE)));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ MAKE_DICT_DIGIT2PERSON(), std::make_pair(RAW_INDEX_NO_HOLE, RAW_INDEX_NO_HOLE)));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
SIMPLE_UDF_RUN(TDictOfPersonBroken, NUdfDictDigPerson(), NUdf::TOptional<void>) {
Y_UNUSED(args);
- Y_UNUSED(valueBuilder);
+ Y_UNUSED(valueBuilder);
NUdf::IBoxedValuePtr boxed(new TBrokenDictBoxedValue<ui32, NUdf::IBoxedValuePtr>(
- MAKE_DICT_DIGIT2PERSON_BROKEN(), std::make_pair(RAW_INDEX_NO_HOLE, RAW_INDEX_NO_HOLE)));
- return NUdf::TUnboxedValuePod(std::move(boxed));
+ MAKE_DICT_DIGIT2PERSON_BROKEN(), std::make_pair(RAW_INDEX_NO_HOLE, RAW_INDEX_NO_HOLE)));
+ return NUdf::TUnboxedValuePod(std::move(boxed));
}
SIMPLE_MODULE(TUtUDF,
- TException,
+ TException,
TVoid,
TNonEmpty,
TOptionalNonEmpty,
@@ -634,14 +634,14 @@ namespace {
} // unnamed namespace
TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistryWithUDFs() {
- auto freg = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto freg = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
freg->AddModule("", "UtUDF", new TUtUDF());
return freg;
}
Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
- typedef std::function<std::vector<TRuntimeNode>(TProgramBuilder&)> BuildArgsFunc;
- typedef std::function<void(const NUdf::TUnboxedValuePod&, const NUdf::IValueBuilder*)> ValidateValueFunc;
+ typedef std::function<std::vector<TRuntimeNode>(TProgramBuilder&)> BuildArgsFunc;
+ typedef std::function<void(const NUdf::TUnboxedValuePod&, const NUdf::IValueBuilder*)> ValidateValueFunc;
typedef std::function<void(const NUdf::TUnboxedValuePod&, const NUdf::IValueBuilder*, const TType* type)> FullValidateValueFunc;
@@ -657,7 +657,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
TProgramBuilder pgmBuilder(env, *functionRegistry);
auto funcName = pgmBuilder.Udf(udfFuncName);
- std::vector<TRuntimeNode> execArgs;
+ std::vector<TRuntimeNode> execArgs;
if (argsFunc) {
execArgs = argsFunc(pgmBuilder);
}
@@ -667,16 +667,16 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
explorer.Walk(pgmReturn.GetNode(), env);
TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(),
functionRegistry.Get(), validateMode,
- NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
+ NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- const auto builder = static_cast<TDefaultValueBuilder*>(graph->GetTerminator());
- builder->RethrowAtTerminate();
- const TBindTerminator bind(graph->GetTerminator());
+ const auto builder = static_cast<TDefaultValueBuilder*>(graph->GetTerminator());
+ builder->RethrowAtTerminate();
+ const TBindTerminator bind(graph->GetTerminator());
auto value = graph->GetValue();
if (validateFunc) {
- validateFunc(value, builder);
+ validateFunc(value, builder);
}
if (fullValidateFunc) {
ui32 flags = 0;
@@ -686,19 +686,19 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
TStatus status = functionRegistry->FindFunctionTypeInfo(env, typeInfoHelper, nullptr, udfFuncName, userType, typeConfig, flags, {}, nullptr, &funcInfo);
MKQL_ENSURE(status.IsOk(), status.GetError());
auto type = funcInfo.FunctionType->GetReturnType();
- fullValidateFunc(value, builder, type);
+ fullValidateFunc(value, builder, type);
}
}
Y_UNIT_TEST(TestUdfException) {
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
- valueBuilder->NewStringNotFilled(0xBAD).AsStringValue().Ref(); // Leak string.
- NUdf::TBoxedValueAccessor::Skip(*value.GetListIterator().AsBoxed().Release()); // Leak value and throw exception.
- };
- UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.Exception", {}, validateFunc), yexception);
- UNIT_ASSERT_VALUES_EQUAL(TThrowerValue::Count, 0L);
- }
-
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ valueBuilder->NewStringNotFilled(0xBAD).AsStringValue().Ref(); // Leak string.
+ NUdf::TBoxedValueAccessor::Skip(*value.GetListIterator().AsBoxed().Release()); // Leak value and throw exception.
+ };
+ UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.Exception", {}, validateFunc), yexception);
+ UNIT_ASSERT_VALUES_EQUAL(TThrowerValue::Count, 0L);
+ }
+
Y_UNIT_TEST(TestUdfResultCheckVoid) {
ProcessSimpleUdfFunc("UtUDF.Void");
}
@@ -708,7 +708,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
TTypeEnvironment env(alloc);
bool wrapped = false;
UNIT_ASSERT_EXCEPTION(TValidate<TValidateErrorPolicyThrow>::Value(nullptr, env.GetTypeOfType(),
- NUdf::TUnboxedValuePod(), "ut for verify empty value exception", &wrapped), TUdfValidateException);
+ NUdf::TUnboxedValuePod(), "ut for verify empty value exception", &wrapped), TUdfValidateException);
UNIT_ASSERT(!wrapped);
}
@@ -724,7 +724,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
ProcessSimpleUdfFunc("UtUDF.OptionalEmpty");
}
- std::vector<TRuntimeNode> MakeCallableInArgs(ui32 testVal, TProgramBuilder& pgmBuilder) {
+ std::vector<TRuntimeNode> MakeCallableInArgs(ui32 testVal, TProgramBuilder& pgmBuilder) {
const auto& functionRegistry = pgmBuilder.GetFunctionRegistry();
const auto udfFuncName = "UtUDF.Sub2Mul2BrokenOnLess2";
@@ -737,15 +737,15 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
udfFuncName, userType, typeConfig, flags, {}, nullptr, &funcInfo);
MKQL_ENSURE(status.IsOk(), status.GetError());
auto callable = pgmBuilder.Udf(udfFuncName);
- return std::vector<TRuntimeNode>{callable, pgmBuilder.NewDataLiteral(testVal)};
+ return std::vector<TRuntimeNode>{callable, pgmBuilder.NewDataLiteral(testVal)};
};
-
+
Y_UNIT_TEST(TestVerifyArgsCallableCorrect) {
ui32 testVal = 44;
BuildArgsFunc argsFunc = [testVal](TProgramBuilder& pgmBuilder) {
return MakeCallableInArgs(testVal, pgmBuilder);
};
- ValidateValueFunc validateFunc = [testVal](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [testVal](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
UNIT_ASSERT_VALUES_EQUAL(testVal, value.Get<ui32>());
};
@@ -770,12 +770,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckEmptySeqList) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto listIter = value.GetListIterator();
- UNIT_ASSERT(!listIter.Skip());
+ UNIT_ASSERT(!listIter.Skip());
};
ProcessSimpleUdfFunc("UtUDF.SeqList", argsFunc, validateFunc);
}
@@ -783,14 +783,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckSeqList) {
static constexpr ui32 listSize = 31;
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize)};
};
ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
ui32 index = 0;
- auto listIter = value.GetListIterator();
- for (NUdf::TUnboxedValue item; listIter.Next(item); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
+ auto listIter = value.GetListIterator();
+ for (NUdf::TUnboxedValue item; listIter.Next(item); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
}
UNIT_ASSERT_VALUES_EQUAL(index, listSize);
};
@@ -799,17 +799,17 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckSeqListWithHoleFirst) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- const ui32 listSize = 31;
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
- pgmBuilder.NewDataLiteral<ui32>(0)};
+ const ui32 listSize = 31;
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
+ pgmBuilder.NewDataLiteral<ui32>(0)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto listIter = value.GetListIterator();
- NUdf::TUnboxedValue item;
- UNIT_ASSERT_EXCEPTION(listIter.Next(item), TUdfValidateException);
- for (ui32 index = 1; listIter.Next(item); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
+ NUdf::TUnboxedValue item;
+ UNIT_ASSERT_EXCEPTION(listIter.Next(item), TUdfValidateException);
+ for (ui32 index = 1; listIter.Next(item); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
}
};
ProcessSimpleUdfFunc("UtUDF.SeqListWithHole", argsFunc, validateFunc);
@@ -819,23 +819,23 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckSeqListWithHoleMiddle) {
static constexpr ui32 listSize = 31;
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
- pgmBuilder.NewDataLiteral(listSize / 2)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
+ pgmBuilder.NewDataLiteral(listSize / 2)};
};
ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), listSize);
ui32 index = 0;
- const auto listIter = value.GetListIterator();
- for (NUdf::TUnboxedValue item; index < listSize / 2 && listIter.Next(item); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
- }
- NUdf::TUnboxedValue bad;
- UNIT_ASSERT_EXCEPTION(listIter.Next(bad), TUdfValidateException);
- ++index;
- for (NUdf::TUnboxedValue item; listIter.Next(item); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
- }
+ const auto listIter = value.GetListIterator();
+ for (NUdf::TUnboxedValue item; index < listSize / 2 && listIter.Next(item); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
+ }
+ NUdf::TUnboxedValue bad;
+ UNIT_ASSERT_EXCEPTION(listIter.Next(bad), TUdfValidateException);
+ ++index;
+ for (NUdf::TUnboxedValue item; listIter.Next(item); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
+ }
};
ProcessSimpleUdfFunc("UtUDF.SeqListWithHole", argsFunc, validateFunc);
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.SeqListWithHole", argsFunc, validateFunc, {}, NUdf::EValidateMode::Greedy), TUdfValidateException);
@@ -844,20 +844,20 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckSeqListWithHoleLast) {
static constexpr ui32 listSize = 31;
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
- pgmBuilder.NewDataLiteral(listSize - 1)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(listSize),
+ pgmBuilder.NewDataLiteral(listSize - 1)};
};
ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
UNIT_ASSERT_VALUES_EQUAL(value.GetListLength(), listSize);
ui32 index = 0;
auto listIter = value.GetListIterator();
- for (NUdf::TUnboxedValue item; index < listSize - 1 && listIter.Next(item); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
- }
- UNIT_ASSERT_VALUES_EQUAL(index, listSize - 1);
- NUdf::TUnboxedValue bad;
- UNIT_ASSERT_EXCEPTION(listIter.Next(bad), TUdfValidateException);
+ for (NUdf::TUnboxedValue item; index < listSize - 1 && listIter.Next(item); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), index);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(index, listSize - 1);
+ NUdf::TUnboxedValue bad;
+ UNIT_ASSERT_EXCEPTION(listIter.Next(bad), TUdfValidateException);
};
ProcessSimpleUdfFunc("UtUDF.SeqListWithHole", argsFunc, validateFunc);
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.SeqListWithHole", argsFunc, validateFunc, {}, NUdf::EValidateMode::Greedy), TUdfValidateException);
@@ -865,44 +865,44 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckTuple) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
ProcessSimpleUdfFunc("UtUDF.Tuple", argsFunc);
}
Y_UNIT_TEST(TestUdfResultCheckTupleWithHoleFirst) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.Tuple", argsFunc), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckTupleWithHoleMiddle) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(std::tuple_size<decltype(TUPLE)>::value / 2)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(std::tuple_size<decltype(TUPLE)>::value / 2)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.Tuple", argsFunc), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckTupleWithHoleLast) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(std::tuple_size<decltype(TUPLE)>::value - 1)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(std::tuple_size<decltype(TUPLE)>::value - 1)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.Tuple", argsFunc), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckDictDigitDigitFull) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
- pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
+ pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto dictIter = value.GetDictIterator();
ui32 index = 0;
- for (NUdf::TUnboxedValue key, payload; dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
- UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
+ for (NUdf::TUnboxedValue key, payload; dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
+ UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
}
UNIT_ASSERT_VALUES_EQUAL(index, DICT_DIGIT2DIGIT.size());
};
@@ -911,17 +911,17 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckDictDigitDigitKeyHole) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0),
- pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0),
+ pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
- for (ui32 index = 1; dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
- UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
+ NUdf::TUnboxedValue key, payload;
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ for (ui32 index = 1; dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
+ UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
}
};
ProcessSimpleUdfFunc("UtUDF.DictDigDig", argsFunc, validateFunc);
@@ -929,34 +929,34 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckDictDigitDigitValueHole) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
- pgmBuilder.NewDataLiteral<ui32>(DICT_DIGIT2DIGIT.size() - 1)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
+ pgmBuilder.NewDataLiteral<ui32>(DICT_DIGIT2DIGIT.size() - 1)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- for (ui32 index = 0; index < DICT_DIGIT2DIGIT.size() - 1 && dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
- UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
- }
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ NUdf::TUnboxedValue key, payload;
+ for (ui32 index = 0; index < DICT_DIGIT2DIGIT.size() - 1 && dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
+ UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
+ }
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
};
ProcessSimpleUdfFunc("UtUDF.DictDigDig", argsFunc, validateFunc);
}
Y_UNIT_TEST(TestUdfResultCheckDictDigitDigitHoleAsOptKeyHole) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
- pgmBuilder.NewDataLiteral<ui32>(0)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE),
+ pgmBuilder.NewDataLiteral<ui32>(0)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
- for (ui32 index = 1; dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
- UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
+ NUdf::TUnboxedValue key, payload;
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ for (ui32 index = 1; dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
+ UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
}
};
ProcessSimpleUdfFunc("UtUDF.DictDigDig", argsFunc, validateFunc);
@@ -964,122 +964,122 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckDictDigitDigitHoleAsOptValueHole) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(DICT_DIGIT2DIGIT.size() - 1),
- pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(DICT_DIGIT2DIGIT.size() - 1),
+ pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- for (ui32 index = 0; index < DICT_DIGIT2DIGIT.size() - 1 && dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
- UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
- }
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ NUdf::TUnboxedValue key, payload;
+ for (ui32 index = 0; index < DICT_DIGIT2DIGIT.size() - 1 && dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), DICT_DIGIT2DIGIT[index].first);
+ UNIT_ASSERT_VALUES_EQUAL(payload.Get<ui64>(), DICT_DIGIT2DIGIT[index].second);
+ }
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
};
ProcessSimpleUdfFunc("UtUDF.DictDigDig", argsFunc, validateFunc);
}
Y_UNIT_TEST(TestUdfResultCheckPersonStruct) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
ProcessSimpleUdfFunc("UtUDF.PersonStruct", argsFunc);
}
Y_UNIT_TEST(TestUdfResultCheckPersonStructWithHoleFirst) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(0)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.PersonStruct", argsFunc), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckPersonStructWithHoleMiddle) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(1)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(1)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.PersonStruct", argsFunc), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckPersonStructWithHoleLast) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(2)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral<ui32>(2)};
};
UNIT_ASSERT_EXCEPTION(ProcessSimpleUdfFunc("UtUDF.PersonStruct", argsFunc), TUdfValidateException);
}
-
+
Y_UNIT_TEST(TestUdfResultCheckTupleOfPersonStruct) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder,
+ FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder,
const TType* type) {
bool wrapped = false;
- TValidate<TValidateErrorPolicyThrow, TValidateModeGreedy<TValidateErrorPolicyThrow>>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
+ TValidate<TValidateErrorPolicyThrow, TValidateModeGreedy<TValidateErrorPolicyThrow>>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
UNIT_ASSERT(!wrapped);
- TValidate<TValidateErrorPolicyThrow, TValidateModeLazy<TValidateErrorPolicyThrow>>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
+ TValidate<TValidateErrorPolicyThrow, TValidateModeLazy<TValidateErrorPolicyThrow>>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
UNIT_ASSERT(wrapped);
};
- ProcessSimpleUdfFunc("UtUDF.TupleOfPersonStruct", argsFunc, {}, fullValidateFunc);
+ ProcessSimpleUdfFunc("UtUDF.TupleOfPersonStruct", argsFunc, {}, fullValidateFunc);
ProcessSimpleUdfFunc("UtUDF.TupleOfPersonStruct", argsFunc, {}, fullValidateFunc, NUdf::EValidateMode::Greedy);
}
-
+
Y_UNIT_TEST(TestUdfResultCheckTupleOfPersonStructNoList) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value,
+ FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value,
const NUdf::IValueBuilder* valueBuilder, const TType* type) {
bool wrapped = false;
- TValidate<TValidateErrorPolicyThrow>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
+ TValidate<TValidateErrorPolicyThrow>::Value(valueBuilder, type, NUdf::TUnboxedValuePod(value), "full verify func", &wrapped);
UNIT_ASSERT(!wrapped);
};
ProcessSimpleUdfFunc("UtUDF.TupleOfPersonStructNoList", argsFunc, {}, fullValidateFunc);
ProcessSimpleUdfFunc("UtUDF.TupleOfPersonStructNoList", argsFunc, {}, fullValidateFunc, NUdf::EValidateMode::Greedy);
}
- void ValidateDictOfPersonStructFunc(const NUdf::TUnboxedValuePod& value, ui32 lookupIndex = 2, ui32 broken_index = RAW_INDEX_NO_HOLE) {
- const auto person = value.Lookup(NUdf::TUnboxedValuePod(ui64(lookupIndex)));
- UNIT_ASSERT(person);
- auto firstName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[0]);
+ void ValidateDictOfPersonStructFunc(const NUdf::TUnboxedValuePod& value, ui32 lookupIndex = 2, ui32 broken_index = RAW_INDEX_NO_HOLE) {
+ const auto person = value.Lookup(NUdf::TUnboxedValuePod(ui64(lookupIndex)));
+ UNIT_ASSERT(person);
+ auto firstName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[0]);
UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), LIST_OF_STRUCT_PERSON[lookupIndex].FirstName);
- auto lastName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[1]);
+ auto lastName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[1]);
UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), LIST_OF_STRUCT_PERSON[lookupIndex].LastName);
- UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[2]).Get<ui32>(), LIST_OF_STRUCT_PERSON[lookupIndex].Age);
- UNIT_ASSERT(!person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]));
+ UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[2]).Get<ui32>(), LIST_OF_STRUCT_PERSON[lookupIndex].Age);
+ UNIT_ASSERT(!person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]));
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- for (ui32 index = 0; index < broken_index && dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui64>(), index);
- auto person = payload;
- auto firstName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[0]);
- UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), LIST_OF_STRUCT_PERSON[index].FirstName);
- auto lastName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[1]);
- UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), LIST_OF_STRUCT_PERSON[index].LastName);
- UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[2]).Get<ui32>(), LIST_OF_STRUCT_PERSON[index].Age);
- const auto origListPtr = LIST_OF_STRUCT_PERSON[index].Tags;
- if (origListPtr.empty()) {
- UNIT_ASSERT(!person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]));
- } else {
- auto memberTags = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]);
- UNIT_ASSERT(memberTags);
- UNIT_ASSERT_VALUES_EQUAL(memberTags.GetListLength(), origListPtr.size());
- auto origIter = origListPtr.begin();
- auto iter = memberTags.GetListIterator();
- for (NUdf::TUnboxedValue item; iter.Next(item); ++origIter) {
- UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), *origIter);
- }
- }
- }
- if (broken_index < RAW_INDEX_NO_HOLE)
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ NUdf::TUnboxedValue key, payload;
+ for (ui32 index = 0; index < broken_index && dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui64>(), index);
+ auto person = payload;
+ auto firstName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[0]);
+ UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), LIST_OF_STRUCT_PERSON[index].FirstName);
+ auto lastName = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[1]);
+ UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), LIST_OF_STRUCT_PERSON[index].LastName);
+ UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[2]).Get<ui32>(), LIST_OF_STRUCT_PERSON[index].Age);
+ const auto origListPtr = LIST_OF_STRUCT_PERSON[index].Tags;
+ if (origListPtr.empty()) {
+ UNIT_ASSERT(!person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]));
+ } else {
+ auto memberTags = person.GetElement(NUdf::PersonStructWithOptList::MetaIndexes[3]);
+ UNIT_ASSERT(memberTags);
+ UNIT_ASSERT_VALUES_EQUAL(memberTags.GetListLength(), origListPtr.size());
+ auto origIter = origListPtr.begin();
+ auto iter = memberTags.GetListIterator();
+ for (NUdf::TUnboxedValue item; iter.Next(item); ++origIter) {
+ UNIT_ASSERT_VALUES_EQUAL(item.Get<ui32>(), *origIter);
+ }
+ }
+ }
+ if (broken_index < RAW_INDEX_NO_HOLE)
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
}
Y_UNIT_TEST(TestUdfResultCheckListOfPersonStructToIndexDict) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder) {
Y_UNUSED(valueBuilder);
ValidateDictOfPersonStructFunc(value);
};
@@ -1088,9 +1088,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
Y_UNIT_TEST(TestUdfResultCheckListOfPersonStruct) {
BuildArgsFunc argsFunc = [](TProgramBuilder& pgmBuilder) {
- return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
+ return std::vector<TRuntimeNode>{pgmBuilder.NewDataLiteral(RAW_INDEX_NO_HOLE)};
};
- FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value,
+ FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value,
const NUdf::IValueBuilder* valueBuilder, const TType* type) {
Y_UNUSED(type);
auto indexDict = valueBuilder->ToIndexDict(value);
@@ -1100,7 +1100,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
}
Y_UNIT_TEST(TestUdfResultCheckListOfPersonStructWithBrokenIndexToDict) {
- FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder,
+ FullValidateValueFunc fullValidateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder* valueBuilder,
const TType* type) {
Y_UNUSED(type);
auto indexDict = valueBuilder->ToIndexDict(value);
@@ -1114,40 +1114,40 @@ Y_UNIT_TEST_SUITE(TMiniKQLValidateTest) {
}
Y_UNIT_TEST(TestUdfResultCheckDictOfPerson) {
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder*) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder*) {
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- for (ui32 index = 0; dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), MAKE_DICT_DIGIT2PERSON()[index].first);
- auto person = payload;
- auto firstName = person.GetElement(NUdf::PersonStruct::MetaIndexes[0]);
+ NUdf::TUnboxedValue key, payload;
+ for (ui32 index = 0; dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), MAKE_DICT_DIGIT2PERSON()[index].first);
+ auto person = payload;
+ auto firstName = person.GetElement(NUdf::PersonStruct::MetaIndexes[0]);
UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->FirstName);
- auto lastName = person.GetElement(NUdf::PersonStruct::MetaIndexes[1]);
+ auto lastName = person.GetElement(NUdf::PersonStruct::MetaIndexes[1]);
UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->LastName);
- UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStruct::MetaIndexes[2]).Get<ui32>(), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->Age);
+ UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStruct::MetaIndexes[2]).Get<ui32>(), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->Age);
}
};
ProcessSimpleUdfFunc("UtUDF.DictOfPerson", {}, validateFunc);
}
Y_UNIT_TEST(TestUdfResultCheckDictOfPersonBroken) {
- ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder*) {
+ ValidateValueFunc validateFunc = [](const NUdf::TUnboxedValuePod& value, const NUdf::IValueBuilder*) {
auto dictIter = value.GetDictIterator();
- NUdf::TUnboxedValue key, payload;
- for (ui32 index = 0; index < DICT_DIGIT2PERSON_BROKEN_PERSON_INDEX && dictIter.NextPair(key, payload); ++index) {
- UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), MAKE_DICT_DIGIT2PERSON_BROKEN()[index].first);
- auto person = payload;
- auto firstName = person.GetElement(NUdf::PersonStruct::MetaIndexes[0]);
- UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->FirstName);
- auto lastName = person.GetElement(NUdf::PersonStruct::MetaIndexes[1]);
- UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->LastName);
- UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStruct::MetaIndexes[2]).Get<ui32>(), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->Age);
- }
- UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
+ NUdf::TUnboxedValue key, payload;
+ for (ui32 index = 0; index < DICT_DIGIT2PERSON_BROKEN_PERSON_INDEX && dictIter.NextPair(key, payload); ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(key.Get<ui32>(), MAKE_DICT_DIGIT2PERSON_BROKEN()[index].first);
+ auto person = payload;
+ auto firstName = person.GetElement(NUdf::PersonStruct::MetaIndexes[0]);
+ UNIT_ASSERT_VALUES_EQUAL(TString(firstName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->FirstName);
+ auto lastName = person.GetElement(NUdf::PersonStruct::MetaIndexes[1]);
+ UNIT_ASSERT_VALUES_EQUAL(TString(lastName.AsStringRef()), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->LastName);
+ UNIT_ASSERT_VALUES_EQUAL(person.GetElement(NUdf::PersonStruct::MetaIndexes[2]).Get<ui32>(), DICT_DIGIT2PERSON_BROKEN_CONTENT_BY_INDEX[index]->Age);
+ }
+ UNIT_ASSERT_EXCEPTION(dictIter.NextPair(key, payload), TUdfValidateException);
};
ProcessSimpleUdfFunc("UtUDF.DictOfPersonBroken", {}, validateFunc);
- }
-
+ }
+
}
-}
+}
diff --git a/ydb/library/yql/minikql/computation/mkql_value_builder.cpp b/ydb/library/yql/minikql/computation/mkql_value_builder.cpp
index 74fac8a096..ad47661715 100644
--- a/ydb/library/yql/minikql/computation/mkql_value_builder.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_value_builder.cpp
@@ -13,24 +13,24 @@ namespace NMiniKQL {
///////////////////////////////////////////////////////////////////////////////
// TDefaultValueBuilder
///////////////////////////////////////////////////////////////////////////////
-TDefaultValueBuilder::TDefaultValueBuilder(const THolderFactory& holderFactory, NUdf::EValidatePolicy policy)
- : HolderFactory_(holderFactory)
- , Policy_(policy)
-{}
-
-void TDefaultValueBuilder::SetSecureParamsProvider(const NUdf::ISecureParamsProvider* provider) {
- SecureParamsProvider_ = provider;
-}
-
-void TDefaultValueBuilder::RethrowAtTerminate() {
- Rethrow_ = true;
-}
-
-void TDefaultValueBuilder::SetCalleePositionHolder(const NUdf::TSourcePosition*& position) {
- CalleePositionPtr_ = &position;
-}
-
-void TDefaultValueBuilder::Terminate(const char* message) const {
+TDefaultValueBuilder::TDefaultValueBuilder(const THolderFactory& holderFactory, NUdf::EValidatePolicy policy)
+ : HolderFactory_(holderFactory)
+ , Policy_(policy)
+{}
+
+void TDefaultValueBuilder::SetSecureParamsProvider(const NUdf::ISecureParamsProvider* provider) {
+ SecureParamsProvider_ = provider;
+}
+
+void TDefaultValueBuilder::RethrowAtTerminate() {
+ Rethrow_ = true;
+}
+
+void TDefaultValueBuilder::SetCalleePositionHolder(const NUdf::TSourcePosition*& position) {
+ CalleePositionPtr_ = &position;
+}
+
+void TDefaultValueBuilder::Terminate(const char* message) const {
TStringBuf reason = (message ? TStringBuf(message) : TStringBuf("(unknown)"));
TString fullMessage = TStringBuilder() <<
"Terminate was called, reason(" << reason.size() << "): " << reason << Endl;
@@ -48,89 +48,89 @@ void TDefaultValueBuilder::Terminate(const char* message) const {
abort();
}
-NUdf::TUnboxedValue TDefaultValueBuilder::NewStringNotFilled(ui32 size) const
-{
- return MakeStringNotFilled(size);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::NewString(const NUdf::TStringRef& ref) const
-{
- return MakeString(ref);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::ConcatStrings(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod second) const
-{
- return ::NKikimr::NMiniKQL::ConcatStrings(first, second);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::AppendString(NUdf::TUnboxedValuePod value, const NUdf::TStringRef& ref) const
-{
- return ::NKikimr::NMiniKQL::AppendString(value, ref);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::PrependString(const NUdf::TStringRef& ref, NUdf::TUnboxedValuePod value) const
-{
- return ::NKikimr::NMiniKQL::PrependString(ref, value);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::SubString(NUdf::TUnboxedValuePod value, ui32 offset, ui32 size) const
-{
- return ::NKikimr::NMiniKQL::SubString(value, offset, size);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::NewList(NUdf::TUnboxedValue* items, ui64 count) const {
- if (!items || !count)
- return HolderFactory_.GetEmptyContainer();
-
- if (count < Max<ui32>()) {
- NUdf::TUnboxedValue* inplace = nullptr;
- auto array = HolderFactory_.CreateDirectArrayHolder(count, inplace);
- for (ui64 i = 0; i < count; ++i)
- *inplace++ = std::move(*items++);
- return std::move(array);
- }
-
- TDefaultListRepresentation list;
- for (ui64 i = 0; i < count; ++i) {
- list = list.Append(std::move(*items++));
- }
-
- return HolderFactory_.CreateDirectListHolder(std::move(list));
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::ReverseList(const NUdf::TUnboxedValuePod& list) const
-{
- return HolderFactory_.ReverseList(this, list);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::SkipList(const NUdf::TUnboxedValuePod& list, ui64 count) const
-{
- return HolderFactory_.SkipList(this, list, count);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::TakeList(const NUdf::TUnboxedValuePod& list, ui64 count) const
-{
- return HolderFactory_.TakeList(this, list, count);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::ToIndexDict(const NUdf::TUnboxedValuePod& list) const
-{
- return HolderFactory_.ToIndexDict(this, list);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::NewArray(ui32 count, NUdf::TUnboxedValue*& itemsPtr) const {
- return HolderFactory_.CreateDirectArrayHolder(count, itemsPtr);
-}
-
-NUdf::TUnboxedValue TDefaultValueBuilder::NewVariant(ui32 index, NUdf::TUnboxedValue&& value) const {
- return HolderFactory_.CreateVariantHolder(value.Release(), index);
-}
-
-NUdf::IDictValueBuilder::TPtr TDefaultValueBuilder::NewDict(const NUdf::TType* dictType, ui32 flags) const
-{
- return HolderFactory_.NewDict(dictType, flags);
-}
-
+NUdf::TUnboxedValue TDefaultValueBuilder::NewStringNotFilled(ui32 size) const
+{
+ return MakeStringNotFilled(size);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::NewString(const NUdf::TStringRef& ref) const
+{
+ return MakeString(ref);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::ConcatStrings(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod second) const
+{
+ return ::NKikimr::NMiniKQL::ConcatStrings(first, second);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::AppendString(NUdf::TUnboxedValuePod value, const NUdf::TStringRef& ref) const
+{
+ return ::NKikimr::NMiniKQL::AppendString(value, ref);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::PrependString(const NUdf::TStringRef& ref, NUdf::TUnboxedValuePod value) const
+{
+ return ::NKikimr::NMiniKQL::PrependString(ref, value);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::SubString(NUdf::TUnboxedValuePod value, ui32 offset, ui32 size) const
+{
+ return ::NKikimr::NMiniKQL::SubString(value, offset, size);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::NewList(NUdf::TUnboxedValue* items, ui64 count) const {
+ if (!items || !count)
+ return HolderFactory_.GetEmptyContainer();
+
+ if (count < Max<ui32>()) {
+ NUdf::TUnboxedValue* inplace = nullptr;
+ auto array = HolderFactory_.CreateDirectArrayHolder(count, inplace);
+ for (ui64 i = 0; i < count; ++i)
+ *inplace++ = std::move(*items++);
+ return std::move(array);
+ }
+
+ TDefaultListRepresentation list;
+ for (ui64 i = 0; i < count; ++i) {
+ list = list.Append(std::move(*items++));
+ }
+
+ return HolderFactory_.CreateDirectListHolder(std::move(list));
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::ReverseList(const NUdf::TUnboxedValuePod& list) const
+{
+ return HolderFactory_.ReverseList(this, list);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::SkipList(const NUdf::TUnboxedValuePod& list, ui64 count) const
+{
+ return HolderFactory_.SkipList(this, list, count);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::TakeList(const NUdf::TUnboxedValuePod& list, ui64 count) const
+{
+ return HolderFactory_.TakeList(this, list, count);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::ToIndexDict(const NUdf::TUnboxedValuePod& list) const
+{
+ return HolderFactory_.ToIndexDict(this, list);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::NewArray(ui32 count, NUdf::TUnboxedValue*& itemsPtr) const {
+ return HolderFactory_.CreateDirectArrayHolder(count, itemsPtr);
+}
+
+NUdf::TUnboxedValue TDefaultValueBuilder::NewVariant(ui32 index, NUdf::TUnboxedValue&& value) const {
+ return HolderFactory_.CreateVariantHolder(value.Release(), index);
+}
+
+NUdf::IDictValueBuilder::TPtr TDefaultValueBuilder::NewDict(const NUdf::TType* dictType, ui32 flags) const
+{
+ return HolderFactory_.NewDict(dictType, flags);
+}
+
bool TDefaultValueBuilder::MakeDate(ui32 year, ui32 month, ui32 day, ui16& value) const {
return ::NKikimr::NMiniKQL::MakeDate(year, month, day, value);
}
@@ -149,23 +149,23 @@ bool TDefaultValueBuilder::SplitDatetime(ui32 value, ui32& year, ui32& month, ui
return ::NKikimr::NMiniKQL::SplitTzDatetime(value, year, month, day, hour, minute, second, tzId);
}
-bool TDefaultValueBuilder::FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 tzId) const {
+bool TDefaultValueBuilder::FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 tzId) const {
ui32 unusedWeekOfYearIso8601 = 0;
return ::NKikimr::NMiniKQL::SplitTzDate(value, year, month, day, dayOfYear, weekOfYear, unusedWeekOfYearIso8601, dayOfWeek, tzId);
-}
-
+}
+
bool TDefaultValueBuilder::FullSplitDate2(ui16 value, ui32& year, ui32& month, ui32& day,
ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId) const {
return ::NKikimr::NMiniKQL::SplitTzDate(value, year, month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, tzId);
}
-bool TDefaultValueBuilder::FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 tzId) const {
+bool TDefaultValueBuilder::FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 tzId) const {
ui32 unusedWeekOfYearIso8601 = 0;
return ::NKikimr::NMiniKQL::SplitTzDatetime(value, year, month, day, hour, minute, second, dayOfYear, weekOfYear, unusedWeekOfYearIso8601, dayOfWeek, tzId);
-}
-
+}
+
bool TDefaultValueBuilder::FullSplitDatetime2(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId) const {
return ::NKikimr::NMiniKQL::SplitTzDatetime(value, year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, tzId);
@@ -186,14 +186,14 @@ bool TDefaultValueBuilder::GetTimezoneShift(ui32 year, ui32 month, ui32 day, ui3
}
const NUdf::TSourcePosition* TDefaultValueBuilder::CalleePosition() const {
- return *CalleePositionPtr_;
+ return *CalleePositionPtr_;
}
NUdf::TUnboxedValue TDefaultValueBuilder::Run(const NUdf::TSourcePosition& callee, const NUdf::IBoxedValue& value, const NUdf::TUnboxedValuePod* args) const {
- const auto prev = *CalleePositionPtr_;
- *CalleePositionPtr_ = &callee;
- const auto ret = NUdf::TBoxedValueAccessor::Run(value, this, args);
- *CalleePositionPtr_ = prev;
+ const auto prev = *CalleePositionPtr_;
+ *CalleePositionPtr_ = &callee;
+ const auto ret = NUdf::TBoxedValueAccessor::Run(value, this, args);
+ *CalleePositionPtr_ = prev;
return ret;
}
diff --git a/ydb/library/yql/minikql/computation/mkql_value_builder.h b/ydb/library/yql/minikql/computation/mkql_value_builder.h
index 2a6cdf0913..b293b263a3 100644
--- a/ydb/library/yql/minikql/computation/mkql_value_builder.h
+++ b/ydb/library/yql/minikql/computation/mkql_value_builder.h
@@ -1,7 +1,7 @@
#pragma once
-#include "mkql_computation_node_holders.h"
-
+#include "mkql_computation_node_holders.h"
+
#include <ydb/library/yql/public/udf/udf_value_builder.h>
#include <ydb/library/yql/public/udf/udf_validate.h>
@@ -21,39 +21,39 @@ class TDefaultValueBuilder final: public NUdf::IValueBuilder, private TNonCopyab
public NUdf::IDateBuilder
{
public:
- TDefaultValueBuilder(const THolderFactory& holderFactory, NUdf::EValidatePolicy policy = NUdf::EValidatePolicy::Fail);
-
- void SetSecureParamsProvider(const NUdf::ISecureParamsProvider* provider);
- void RethrowAtTerminate();
- void SetCalleePositionHolder(const NUdf::TSourcePosition*& position);
-
- void Terminate(const char* message) const final;
-
- NUdf::TUnboxedValue NewStringNotFilled(ui32 size) const final;
-
- NUdf::TUnboxedValue ConcatStrings(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod second) const final;
-
- NUdf::TUnboxedValue AppendString(NUdf::TUnboxedValuePod value, const NUdf::TStringRef& ref) const final;
- NUdf::TUnboxedValue PrependString(const NUdf::TStringRef& ref,NUdf::TUnboxedValuePod value) const final;
-
- NUdf::TUnboxedValue SubString(NUdf::TUnboxedValuePod value, ui32 offset, ui32 size) const final;
- NUdf::TUnboxedValue NewList(NUdf::TUnboxedValue* items, ui64 count) const final;
-
- NUdf::TUnboxedValue NewString(const NUdf::TStringRef& ref) const final;
-
- NUdf::IDictValueBuilder::TPtr NewDict(const NUdf::TType* dictType, ui32 flags) const final;
-
- NUdf::TUnboxedValue ReverseList(const NUdf::TUnboxedValuePod& list) const final;
- NUdf::TUnboxedValue SkipList(const NUdf::TUnboxedValuePod& list, ui64 count) const final;
- NUdf::TUnboxedValue TakeList(const NUdf::TUnboxedValuePod& list, ui64 count) const final;
- NUdf::TUnboxedValue ToIndexDict(const NUdf::TUnboxedValuePod& list) const final;
-
- NUdf::TUnboxedValue NewArray(ui32 count, NUdf::TUnboxedValue*& itemsPtr) const final;
- NUdf::TUnboxedValue NewVariant(ui32 index, NUdf::TUnboxedValue&& value) const final;
+ TDefaultValueBuilder(const THolderFactory& holderFactory, NUdf::EValidatePolicy policy = NUdf::EValidatePolicy::Fail);
+
+ void SetSecureParamsProvider(const NUdf::ISecureParamsProvider* provider);
+ void RethrowAtTerminate();
+ void SetCalleePositionHolder(const NUdf::TSourcePosition*& position);
+
+ void Terminate(const char* message) const final;
+
+ NUdf::TUnboxedValue NewStringNotFilled(ui32 size) const final;
+
+ NUdf::TUnboxedValue ConcatStrings(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod second) const final;
+
+ NUdf::TUnboxedValue AppendString(NUdf::TUnboxedValuePod value, const NUdf::TStringRef& ref) const final;
+ NUdf::TUnboxedValue PrependString(const NUdf::TStringRef& ref,NUdf::TUnboxedValuePod value) const final;
+
+ NUdf::TUnboxedValue SubString(NUdf::TUnboxedValuePod value, ui32 offset, ui32 size) const final;
+ NUdf::TUnboxedValue NewList(NUdf::TUnboxedValue* items, ui64 count) const final;
+
+ NUdf::TUnboxedValue NewString(const NUdf::TStringRef& ref) const final;
+
+ NUdf::IDictValueBuilder::TPtr NewDict(const NUdf::TType* dictType, ui32 flags) const final;
+
+ NUdf::TUnboxedValue ReverseList(const NUdf::TUnboxedValuePod& list) const final;
+ NUdf::TUnboxedValue SkipList(const NUdf::TUnboxedValuePod& list, ui64 count) const final;
+ NUdf::TUnboxedValue TakeList(const NUdf::TUnboxedValuePod& list, ui64 count) const final;
+ NUdf::TUnboxedValue ToIndexDict(const NUdf::TUnboxedValuePod& list) const final;
+
+ NUdf::TUnboxedValue NewArray(ui32 count, NUdf::TUnboxedValue*& itemsPtr) const final;
+ NUdf::TUnboxedValue NewVariant(ui32 index, NUdf::TUnboxedValue&& value) const final;
const NUdf::IDateBuilder& GetDateBuilder() const final {
return *this;
}
-
+
bool GetSecureParam(NUdf::TStringRef key, NUdf::TStringRef &value) const final;
const NUdf::TSourcePosition* CalleePosition() const final;
NUdf::TUnboxedValue Run(const NUdf::TSourcePosition& callee, const NUdf::IBoxedValue& value, const NUdf::TUnboxedValuePod* args) const;
@@ -72,10 +72,10 @@ public:
// in minutes
bool GetTimezoneShift(ui32 year, ui32 month, ui32 day, ui32 hour, ui32 minute, ui32 second, ui16 tzId, i32& value) const final;
- bool FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const final;
- bool FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const final;
+ bool FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const final;
+ bool FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const final;
bool FindTimezoneName(ui32 id, NUdf::TStringRef& name) const final;
bool FindTimezoneId(const NUdf::TStringRef& name, ui32& id) const final;
@@ -86,13 +86,13 @@ public:
bool FullSplitDatetime2(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 timezoneId = 0) const final;
-private:
- const THolderFactory& HolderFactory_;
- NUdf::EValidatePolicy Policy_;
+private:
+ const THolderFactory& HolderFactory_;
+ NUdf::EValidatePolicy Policy_;
const NUdf::ISecureParamsProvider* SecureParamsProvider_ = nullptr;
- const NUdf::TSourcePosition** CalleePositionPtr_ = nullptr;
+ const NUdf::TSourcePosition** CalleePositionPtr_ = nullptr;
mutable bool Rethrow_ = false;
-};
+};
} // namespace NMiniKQL
} // namespace Nkikimr
diff --git a/ydb/library/yql/minikql/computation/mkql_value_builder_ut.cpp b/ydb/library/yql/minikql/computation/mkql_value_builder_ut.cpp
index ec950a4264..5f54b2dd24 100644
--- a/ydb/library/yql/minikql/computation/mkql_value_builder_ut.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_value_builder_ut.cpp
@@ -1,83 +1,83 @@
-#include "mkql_value_builder.h"
-#include "mkql_computation_node_holders.h"
-
+#include "mkql_value_builder.h"
+#include "mkql_computation_node_holders.h"
+
#include <ydb/library/yql/minikql/mkql_function_registry.h>
#include <ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h>
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NKikimr {
-
-using namespace NUdf;
-
-namespace NMiniKQL {
-
-class TMiniKQLValueBuilderTest: public TTestBase {
-public:
- TMiniKQLValueBuilderTest()
- : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
+
+namespace NKikimr {
+
+using namespace NUdf;
+
+namespace NMiniKQL {
+
+class TMiniKQLValueBuilderTest: public TTestBase {
+public:
+ TMiniKQLValueBuilderTest()
+ : FunctionRegistry(CreateFunctionRegistry(CreateBuiltinRegistry()))
, Env(Alloc)
- , MemInfo("Memory")
- , HolderFactory(Alloc.Ref(), MemInfo, FunctionRegistry.Get())
- , Builder(HolderFactory)
- {
- }
-
-private:
- TIntrusivePtr<NMiniKQL::IFunctionRegistry> FunctionRegistry;
- TScopedAlloc Alloc;
- TTypeEnvironment Env;
- TMemoryUsageInfo MemInfo;
- THolderFactory HolderFactory;
- TDefaultValueBuilder Builder;
-
- UNIT_TEST_SUITE(TMiniKQLValueBuilderTest);
- UNIT_TEST(TestEmbeddedVariant);
- UNIT_TEST(TestBoxedVariant);
- UNIT_TEST(TestSubstring);
- UNIT_TEST_SUITE_END();
-
-
- void TestEmbeddedVariant() {
- const auto v = Builder.NewVariant(62, TUnboxedValuePod((ui64) 42));
- UNIT_ASSERT(v);
- UNIT_ASSERT(!v.IsBoxed());
- UNIT_ASSERT_VALUES_EQUAL(62, v.GetVariantIndex());
- UNIT_ASSERT_VALUES_EQUAL(42, v.GetVariantItem().Get<ui64>());
- }
-
- void TestBoxedVariant() {
- const auto v = Builder.NewVariant(63, TUnboxedValuePod((ui64) 42));
- UNIT_ASSERT(v);
- UNIT_ASSERT(v.IsBoxed());
- UNIT_ASSERT_VALUES_EQUAL(63, v.GetVariantIndex());
- UNIT_ASSERT_VALUES_EQUAL(42, v.GetVariantItem().Get<ui64>());
- }
-
- void TestSubstring() {
- const auto string = Builder.NewString("0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM");
- UNIT_ASSERT(string);
-
- const auto zero = Builder.SubString(string, 7, 0);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf(""), TStringBuf(zero.AsStringRef()));
-
- const auto tail = Builder.SubString(string, 60, 8);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf("NM"), TStringBuf(tail.AsStringRef()));
-
- const auto small = Builder.SubString(string, 2, 14);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf("23456789qwerty"), TStringBuf(small.AsStringRef()));
-
- const auto one = Builder.SubString(string, 3, 15);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf("3456789qwertyui"), TStringBuf(one.AsStringRef()));
- UNIT_ASSERT_VALUES_EQUAL(string.AsStringValue().Data(), one.AsStringValue().Data());
-
- const auto two = Builder.SubString(string, 10, 30);
- UNIT_ASSERT_VALUES_EQUAL(TStringBuf("qwertyuiopasdfghjklzxcvbnmQWER"), TStringBuf(two.AsStringRef()));
- UNIT_ASSERT_VALUES_EQUAL(string.AsStringValue().Data(), two.AsStringValue().Data());
- }
-
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TMiniKQLValueBuilderTest);
-
-}
-}
+ , MemInfo("Memory")
+ , HolderFactory(Alloc.Ref(), MemInfo, FunctionRegistry.Get())
+ , Builder(HolderFactory)
+ {
+ }
+
+private:
+ TIntrusivePtr<NMiniKQL::IFunctionRegistry> FunctionRegistry;
+ TScopedAlloc Alloc;
+ TTypeEnvironment Env;
+ TMemoryUsageInfo MemInfo;
+ THolderFactory HolderFactory;
+ TDefaultValueBuilder Builder;
+
+ UNIT_TEST_SUITE(TMiniKQLValueBuilderTest);
+ UNIT_TEST(TestEmbeddedVariant);
+ UNIT_TEST(TestBoxedVariant);
+ UNIT_TEST(TestSubstring);
+ UNIT_TEST_SUITE_END();
+
+
+ void TestEmbeddedVariant() {
+ const auto v = Builder.NewVariant(62, TUnboxedValuePod((ui64) 42));
+ UNIT_ASSERT(v);
+ UNIT_ASSERT(!v.IsBoxed());
+ UNIT_ASSERT_VALUES_EQUAL(62, v.GetVariantIndex());
+ UNIT_ASSERT_VALUES_EQUAL(42, v.GetVariantItem().Get<ui64>());
+ }
+
+ void TestBoxedVariant() {
+ const auto v = Builder.NewVariant(63, TUnboxedValuePod((ui64) 42));
+ UNIT_ASSERT(v);
+ UNIT_ASSERT(v.IsBoxed());
+ UNIT_ASSERT_VALUES_EQUAL(63, v.GetVariantIndex());
+ UNIT_ASSERT_VALUES_EQUAL(42, v.GetVariantItem().Get<ui64>());
+ }
+
+ void TestSubstring() {
+ const auto string = Builder.NewString("0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM");
+ UNIT_ASSERT(string);
+
+ const auto zero = Builder.SubString(string, 7, 0);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf(""), TStringBuf(zero.AsStringRef()));
+
+ const auto tail = Builder.SubString(string, 60, 8);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf("NM"), TStringBuf(tail.AsStringRef()));
+
+ const auto small = Builder.SubString(string, 2, 14);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf("23456789qwerty"), TStringBuf(small.AsStringRef()));
+
+ const auto one = Builder.SubString(string, 3, 15);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf("3456789qwertyui"), TStringBuf(one.AsStringRef()));
+ UNIT_ASSERT_VALUES_EQUAL(string.AsStringValue().Data(), one.AsStringValue().Data());
+
+ const auto two = Builder.SubString(string, 10, 30);
+ UNIT_ASSERT_VALUES_EQUAL(TStringBuf("qwertyuiopasdfghjklzxcvbnmQWER"), TStringBuf(two.AsStringRef()));
+ UNIT_ASSERT_VALUES_EQUAL(string.AsStringValue().Data(), two.AsStringValue().Data());
+ }
+
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TMiniKQLValueBuilderTest);
+
+}
+}
diff --git a/ydb/library/yql/minikql/computation/presort.cpp b/ydb/library/yql/minikql/computation/presort.cpp
index 80cf145a73..26b96a60aa 100644
--- a/ydb/library/yql/minikql/computation/presort.cpp
+++ b/ydb/library/yql/minikql/computation/presort.cpp
@@ -7,7 +7,7 @@
#include <ydb/library/yql/public/decimal/yql_decimal_serialize.h>
#include <util/system/unaligned_mem.h>
-#include <util/string/builder.h>
+#include <util/string/builder.h>
namespace NKikimr {
namespace NMiniKQL {
@@ -330,23 +330,23 @@ void DecodeTzUnsigned(TStringBuf& input, TUnsigned& value, ui16& tzId) {
}
}
-constexpr size_t DecimalSize = sizeof(NYql::NDecimal::TInt128);
+constexpr size_t DecimalSize = sizeof(NYql::NDecimal::TInt128);
template <bool Desc>
Y_FORCE_INLINE
-void EncodeDecimal(TVector<ui8>& output, NYql::NDecimal::TInt128 value) {
+void EncodeDecimal(TVector<ui8>& output, NYql::NDecimal::TInt128 value) {
output.resize(output.size() + DecimalSize);
auto ptr = reinterpret_cast<char*>(output.end() - DecimalSize);
- output.resize(output.size() + NYql::NDecimal::Serialize(Desc ? -value : value, ptr) - DecimalSize);
+ output.resize(output.size() + NYql::NDecimal::Serialize(Desc ? -value : value, ptr) - DecimalSize);
}
template <bool Desc>
Y_FORCE_INLINE
-NYql::NDecimal::TInt128 DecodeDecimal(TStringBuf& input) {
- MKQL_ENSURE(input.size() > 0U && input.size() <= DecimalSize, "premature end of input");
+NYql::NDecimal::TInt128 DecodeDecimal(TStringBuf& input) {
+ MKQL_ENSURE(input.size() > 0U && input.size() <= DecimalSize, "premature end of input");
const auto des = NYql::NDecimal::Deserialize(input.data());
- input.Skip(des.second);
- return Desc ? -des.first : des.first;
+ input.Skip(des.second);
+ return Desc ? -des.first : des.first;
}
@@ -392,7 +392,7 @@ void Encode(TVector<ui8>& output, NUdf::EDataSlot slot, const NUdf::TUnboxedValu
case NUdf::EDataSlot::Float:
EncodeFloating<float, Desc>(output, value.Get<float>());
break;
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
case NUdf::EDataSlot::String:
case NUdf::EDataSlot::Utf8: {
auto stringRef = value.AsStringRef();
@@ -422,7 +422,7 @@ void Encode(TVector<ui8>& output, NUdf::EDataSlot slot, const NUdf::TUnboxedValu
template <bool Desc>
Y_FORCE_INLINE
-NUdf::TUnboxedValue Decode(TStringBuf& input, NUdf::EDataSlot slot, TVector<ui8>& buffer)
+NUdf::TUnboxedValue Decode(TStringBuf& input, NUdf::EDataSlot slot, TVector<ui8>& buffer)
{
switch (slot) {
@@ -463,11 +463,11 @@ NUdf::TUnboxedValue Decode(TStringBuf& input, NUdf::EDataSlot slot, TVector<ui8>
case NUdf::EDataSlot::Float:
return NUdf::TUnboxedValuePod(DecodeFloating<float, Desc>(input));
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
case NUdf::EDataSlot::String:
case NUdf::EDataSlot::Utf8:
buffer.clear();
- return MakeString(NUdf::TStringRef(DecodeString<Desc>(input, buffer)));
+ return MakeString(NUdf::TStringRef(DecodeString<Desc>(input, buffer)));
case NUdf::EDataSlot::Uuid:
buffer.clear();
@@ -705,7 +705,7 @@ NUdf::TUnboxedValue DecodeImpl(TType* type, TStringBuf& input, const THolderFact
TType* altType = tupleType->GetElementType(alt);
auto value = DecodeImpl(altType, input, factory, buffer);
- return factory.CreateVariantHolder(value.Release(), alt);
+ return factory.CreateVariantHolder(value.Release(), alt);
}
// Struct and Dict may be encoded into a presort form only to canonize dict keys. No need to decode them.
@@ -776,12 +776,12 @@ NUdf::TUnboxedValue TPresortDecoder::Decode() {
if (type.IsOptional && !NDetail::DecodeBool<true>(Input)) {
return NUdf::TUnboxedValuePod();
}
- return NDetail::Decode<true>(Input, type.Slot, Buffer);
+ return NDetail::Decode<true>(Input, type.Slot, Buffer);
} else {
if (type.IsOptional && !NDetail::DecodeBool<false>(Input)) {
return NUdf::TUnboxedValuePod();
}
- return NDetail::Decode<false>(Input, type.Slot, Buffer);
+ return NDetail::Decode<false>(Input, type.Slot, Buffer);
}
}
diff --git a/ydb/library/yql/minikql/computation/presort.h b/ydb/library/yql/minikql/computation/presort.h
index dddd6770fb..b90f54343b 100644
--- a/ydb/library/yql/minikql/computation/presort.h
+++ b/ydb/library/yql/minikql/computation/presort.h
@@ -41,7 +41,7 @@ private:
class TPresortDecoder : public TPresortCodec {
public:
- TPresortDecoder() = default;
+ TPresortDecoder() = default;
void Start(TStringBuf input);
NUdf::TUnboxedValue Decode();
diff --git a/ydb/library/yql/minikql/computation/presort_ut.cpp b/ydb/library/yql/minikql/computation/presort_ut.cpp
index 3fab537849..4adf957ca1 100644
--- a/ydb/library/yql/minikql/computation/presort_ut.cpp
+++ b/ydb/library/yql/minikql/computation/presort_ut.cpp
@@ -80,7 +80,7 @@ struct TPresortTest {
TPresortEncoder encoder;
encoder.AddType(NUdf::TDataType<T>::Slot, false, isDesc);
- TPresortDecoder decoder;
+ TPresortDecoder decoder;
decoder.AddType(NUdf::TDataType<T>::Slot, false, isDesc);
encoder.Start();
@@ -101,11 +101,11 @@ struct TPresortTest {
TPresortEncoder encoder;
encoder.AddType(Slot, false, isDesc);
- TPresortDecoder decoder;
+ TPresortDecoder decoder;
decoder.AddType(Slot, false, isDesc);
encoder.Start();
- encoder.Encode(NUdf::TUnboxedValue(MakeString(NUdf::TStringRef(value))));
+ encoder.Encode(NUdf::TUnboxedValue(MakeString(NUdf::TStringRef(value))));
auto bytes = encoder.Finish();
UNIT_ASSERT_EQUAL(HexEncode(bytes.data(), bytes.size()), hex);
@@ -145,7 +145,7 @@ struct TPresortTest {
UNIT_ASSERT_EQUAL(decoded.GetTimezoneId(), value.second);
};
- void ValidateEncoding(bool isDesc, NYql::NDecimal::TInt128 value, const TString& hex) {
+ void ValidateEncoding(bool isDesc, NYql::NDecimal::TInt128 value, const TString& hex) {
TPresortEncoder encoder;
encoder.AddType(NUdf::EDataSlot::Decimal, false, isDesc);
@@ -195,7 +195,7 @@ Y_UNIT_TEST(SimpleTypes) {
TPresortEncoder encoder;
AddTypes(encoder, isOptional, isDesc);
- TPresortDecoder decoder;
+ TPresortDecoder decoder;
AddTypes(decoder, isOptional, isDesc);
auto bytes = Encode(encoder, values);
@@ -406,28 +406,28 @@ Y_UNIT_TEST(TzTimestamp) {
}
Y_UNIT_TEST(Decimal) {
- const TVector<std::tuple<NYql::NDecimal::TInt128, TString, TString>> values = {
- {-NYql::NDecimal::Nan(),
- "00",
- "FF"},
- {-NYql::NDecimal::Inf(),
- "01",
- "FE"},
- {NYql::NDecimal::TInt128(-1),
- "7F",
- "8101"},
- {NYql::NDecimal::TInt128(0),
- "80",
- "80"},
- {NYql::NDecimal::TInt128(1),
- "8101",
- "7F"},
- {NYql::NDecimal::Inf(),
- "FE",
- "01"},
- {NYql::NDecimal::Nan(),
- "FF",
- "00"},
+ const TVector<std::tuple<NYql::NDecimal::TInt128, TString, TString>> values = {
+ {-NYql::NDecimal::Nan(),
+ "00",
+ "FF"},
+ {-NYql::NDecimal::Inf(),
+ "01",
+ "FE"},
+ {NYql::NDecimal::TInt128(-1),
+ "7F",
+ "8101"},
+ {NYql::NDecimal::TInt128(0),
+ "80",
+ "80"},
+ {NYql::NDecimal::TInt128(1),
+ "8101",
+ "7F"},
+ {NYql::NDecimal::Inf(),
+ "FE",
+ "01"},
+ {NYql::NDecimal::Nan(),
+ "FF",
+ "00"},
};
TPresortTest().ValidateEncoding(values);
}
diff --git a/ydb/library/yql/minikql/computation/ut/ya.make b/ydb/library/yql/minikql/computation/ut/ya.make
index bb431d3dcc..ab27689c7b 100644
--- a/ydb/library/yql/minikql/computation/ut/ya.make
+++ b/ydb/library/yql/minikql/computation/ut/ya.make
@@ -18,11 +18,11 @@ OWNER(
SRCS(
mkql_computation_node_pack_ut.cpp
- mkql_computation_node_list_ut.cpp
+ mkql_computation_node_list_ut.cpp
mkql_computation_node_dict_ut.cpp
mkql_computation_node_graph_saveload_ut.cpp
mkql_validate_ut.cpp
- mkql_value_builder_ut.cpp
+ mkql_value_builder_ut.cpp
presort_ut.cpp
)
diff --git a/ydb/library/yql/minikql/computation/ya.make b/ydb/library/yql/minikql/computation/ya.make
index d17d289da4..ae419b3b23 100644
--- a/ydb/library/yql/minikql/computation/ya.make
+++ b/ydb/library/yql/minikql/computation/ya.make
@@ -10,19 +10,19 @@ OWNER(
SRCS(
mkql_computation_node.cpp
mkql_computation_node.h
- mkql_computation_node_codegen.h
- mkql_computation_node_codegen.cpp
+ mkql_computation_node_codegen.h
+ mkql_computation_node_codegen.cpp
mkql_computation_node_graph.cpp
mkql_computation_node_graph_saveload.cpp
mkql_computation_node_graph_saveload.h
mkql_computation_node_holders.cpp
mkql_computation_node_impl.h
- mkql_computation_node_impl.cpp
+ mkql_computation_node_impl.cpp
mkql_computation_node_list.h
mkql_computation_node_pack.cpp
mkql_computation_node_pack.h
- mkql_custom_list.cpp
- mkql_custom_list.h
+ mkql_custom_list.cpp
+ mkql_custom_list.h
mkql_validate.cpp
mkql_validate.h
mkql_value_builder.cpp
@@ -31,30 +31,30 @@ SRCS(
presort.cpp
)
-LLVM_BC(
- mkql_pack_bc.cpp
- NAME mkql_pack.bc
- SYMBOLS
- FetchNextItem
- GetElement
- GetVariantItem
- NextListItem
- NextDictItem
- PackString
- PackStringData
- PackBool
- PackByte
- PackFloat
- PackDouble
- PackInt32
- PackUInt32
- PackInt64
- PackUInt64
- GetListIterator
- GetDictIterator
- GetOptionalValue
-)
-
+LLVM_BC(
+ mkql_pack_bc.cpp
+ NAME mkql_pack.bc
+ SYMBOLS
+ FetchNextItem
+ GetElement
+ GetVariantItem
+ NextListItem
+ NextDictItem
+ PackString
+ PackStringData
+ PackBool
+ PackByte
+ PackFloat
+ PackDouble
+ PackInt32
+ PackUInt32
+ PackInt64
+ PackUInt64
+ GetListIterator
+ GetDictIterator
+ GetOptionalValue
+)
+
PEERDIR(
contrib/libs/apache/arrow
library/cpp/enumbitset
@@ -71,12 +71,12 @@ IF (NOT MKQL_DISABLE_CODEGEN)
NO_COMPILER_WARNINGS()
PEERDIR(
ydb/library/yql/minikql/codegen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Transforms/IPO
)
ELSE()
CFLAGS(
diff --git a/ydb/library/yql/minikql/defs.h b/ydb/library/yql/minikql/defs.h
index 991e8c0958..3e332363c6 100644
--- a/ydb/library/yql/minikql/defs.h
+++ b/ydb/library/yql/minikql/defs.h
@@ -47,12 +47,12 @@ struct TThrowable
}
};
-typedef
-#ifdef _win_
-struct { ui64 Data, Meta; }
-#else
-unsigned __int128
-#endif
-TRawUV;
-
+typedef
+#ifdef _win_
+struct { ui64 Data, Meta; }
+#else
+unsigned __int128
+#endif
+TRawUV;
+
}
diff --git a/ydb/library/yql/minikql/dom/convert.h b/ydb/library/yql/minikql/dom/convert.h
index e1659b7cab..c2d79c72d6 100644
--- a/ydb/library/yql/minikql/dom/convert.h
+++ b/ydb/library/yql/minikql/dom/convert.h
@@ -1,386 +1,386 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_value.h>
#include <ydb/library/yql/public/udf/udf_value_builder.h>
#include <ydb/library/yql/utils/utf8.h>
-
-#include <util/string/escape.h>
-#include <util/string/cast.h>
-#include <util/string/builder.h>
-
-namespace NYql::NDom {
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod ConvertToBool(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::Bool:
- return TUnboxedValuePod(x.Get<bool>());
- case ENodeType::String:
- if (const std::string_view str = x.AsStringRef(); str == "true")
- return TUnboxedValuePod(true);
- else if (str == "false")
- return TUnboxedValuePod(false);
- else if constexpr (AutoConvert)
- return TUnboxedValuePod(x.AsStringRef().Size() > 0U);
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Uint64:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.Get<ui64>() != 0ULL);
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Int64:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.Get<i64>() != 0LL);
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Double:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.Get<double>() != 0.);
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Entity:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(false);
- else if constexpr (Strict)
- break;
- else if constexpr (AutoConvert)
- return TUnboxedValuePod(false);
- else
- return {};
- case ENodeType::List:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.IsBoxed() && x.HasListItems());
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Dict:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.IsBoxed() && x.HasDictItems());
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Attr:
- return ConvertToBool<Strict, AutoConvert>(x.GetVariantItem().Release(), valueBuilder, pos);
- }
-
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse boolean value from " << TDebugPrinter(x)).c_str());
-}
-
-template<typename TDst, typename TSrc>
-constexpr inline bool InBounds(const TSrc v) {
- if constexpr (std::is_same<TSrc, TDst>())
- return true;
- if constexpr (sizeof(TSrc) > sizeof(TDst))
- if constexpr (std::is_signed<TSrc>())
- return v <= TSrc(std::numeric_limits<TDst>::max()) && v >= TSrc(std::numeric_limits<TDst>::min());
- else
- return v <= TSrc(std::numeric_limits<TDst>::max());
- else
- if constexpr (std::is_signed<TSrc>())
- return v >= TSrc(std::numeric_limits<TDst>::min());
- else
- return v <= TSrc(std::numeric_limits<TDst>::max());
- static_assert(sizeof(TSrc) >= sizeof(TDst), "Expects wide to short.");
-}
-
-template<bool Strict, bool AutoConvert, typename TargetType>
-TUnboxedValuePod ConvertToIntegral(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::Int64: {
- const auto s = x.Get<i64>();
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(s));
- else if (InBounds<TargetType>(s))
- return TUnboxedValuePod(TargetType(s));
- else if constexpr (Strict)
- break;
- else
- return {};
- }
- case ENodeType::Uint64: {
- const auto u = x.Get<ui64>();
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(u));
- else if (InBounds<TargetType>(u))
- return TUnboxedValuePod(TargetType(u));
- else if constexpr (Strict)
- break;
- else
- return {};
- }
- case ENodeType::Bool:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(x.Get<bool>() ? 1 : 0));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Double:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(x.Get<double>()));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::String:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(FromStringWithDefault(std::string_view(x.AsStringRef()), TargetType(0)));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Entity:
- if constexpr (AutoConvert)
- return TUnboxedValuePod::Zero();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::List:
- if constexpr (AutoConvert)
- return TUnboxedValuePod::Zero();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Dict:
- if constexpr (AutoConvert)
- return TUnboxedValuePod::Zero();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Attr:
- return ConvertToIntegral<Strict, AutoConvert, TargetType>(x.GetVariantItem().Release(), valueBuilder, pos);
- }
-
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse integer value from " << TDebugPrinter(x)).c_str());
- static_assert(std::is_integral<TargetType>(), "Expect integral.");
-}
-
-template<bool Strict, bool AutoConvert, typename TargetType>
-TUnboxedValuePod ConvertToFloat(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::Double:
+
+#include <util/string/escape.h>
+#include <util/string/cast.h>
+#include <util/string/builder.h>
+
+namespace NYql::NDom {
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod ConvertToBool(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::Bool:
+ return TUnboxedValuePod(x.Get<bool>());
+ case ENodeType::String:
+ if (const std::string_view str = x.AsStringRef(); str == "true")
+ return TUnboxedValuePod(true);
+ else if (str == "false")
+ return TUnboxedValuePod(false);
+ else if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.AsStringRef().Size() > 0U);
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Uint64:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.Get<ui64>() != 0ULL);
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Int64:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.Get<i64>() != 0LL);
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Double:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.Get<double>() != 0.);
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Entity:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(false);
+ else if constexpr (Strict)
+ break;
+ else if constexpr (AutoConvert)
+ return TUnboxedValuePod(false);
+ else
+ return {};
+ case ENodeType::List:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.IsBoxed() && x.HasListItems());
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Dict:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.IsBoxed() && x.HasDictItems());
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Attr:
+ return ConvertToBool<Strict, AutoConvert>(x.GetVariantItem().Release(), valueBuilder, pos);
+ }
+
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse boolean value from " << TDebugPrinter(x)).c_str());
+}
+
+template<typename TDst, typename TSrc>
+constexpr inline bool InBounds(const TSrc v) {
+ if constexpr (std::is_same<TSrc, TDst>())
+ return true;
+ if constexpr (sizeof(TSrc) > sizeof(TDst))
+ if constexpr (std::is_signed<TSrc>())
+ return v <= TSrc(std::numeric_limits<TDst>::max()) && v >= TSrc(std::numeric_limits<TDst>::min());
+ else
+ return v <= TSrc(std::numeric_limits<TDst>::max());
+ else
+ if constexpr (std::is_signed<TSrc>())
+ return v >= TSrc(std::numeric_limits<TDst>::min());
+ else
+ return v <= TSrc(std::numeric_limits<TDst>::max());
+ static_assert(sizeof(TSrc) >= sizeof(TDst), "Expects wide to short.");
+}
+
+template<bool Strict, bool AutoConvert, typename TargetType>
+TUnboxedValuePod ConvertToIntegral(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::Int64: {
+ const auto s = x.Get<i64>();
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(s));
+ else if (InBounds<TargetType>(s))
+ return TUnboxedValuePod(TargetType(s));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ }
+ case ENodeType::Uint64: {
+ const auto u = x.Get<ui64>();
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(u));
+ else if (InBounds<TargetType>(u))
+ return TUnboxedValuePod(TargetType(u));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ }
+ case ENodeType::Bool:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(x.Get<bool>() ? 1 : 0));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Double:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(x.Get<double>()));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::String:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(FromStringWithDefault(std::string_view(x.AsStringRef()), TargetType(0)));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Entity:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod::Zero();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::List:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod::Zero();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Dict:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod::Zero();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Attr:
+ return ConvertToIntegral<Strict, AutoConvert, TargetType>(x.GetVariantItem().Release(), valueBuilder, pos);
+ }
+
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse integer value from " << TDebugPrinter(x)).c_str());
+ static_assert(std::is_integral<TargetType>(), "Expect integral.");
+}
+
+template<bool Strict, bool AutoConvert, typename TargetType>
+TUnboxedValuePod ConvertToFloat(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::Double:
return TUnboxedValuePod(TargetType(x.Get<double>()));
- case ENodeType::Uint64:
- return TUnboxedValuePod(TargetType(x.Get<ui64>()));
- case ENodeType::Int64:
- return TUnboxedValuePod(TargetType(x.Get<i64>()));
- case ENodeType::Bool:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(x.Get<bool>() ? TargetType(1) : TargetType(0));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::String:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(FromStringWithDefault(std::string_view(x.AsStringRef()), TargetType(0)));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Entity:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(0));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::List:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(0));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Dict:
- if constexpr (AutoConvert)
- return TUnboxedValuePod(TargetType(0));
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Attr:
- return ConvertToFloat<Strict, AutoConvert, TargetType>(x.GetVariantItem().Release(), valueBuilder, pos);
- }
-
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse floating point value from " << TDebugPrinter(x)).c_str());
- static_assert(std::is_floating_point<TargetType>(), "Expect float.");
-}
-
-template<bool Strict, bool AutoConvert, bool Utf8>
-TUnboxedValuePod ConvertToString(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::String:
- if constexpr (Utf8)
- if (IsUtf8(x.AsStringRef()))
- return x;
- else
- if (AutoConvert)
- return valueBuilder->NewString(EscapeC(TStringBuf(x.AsStringRef()))).Release();
- else if constexpr (Strict)
- break;
- else
- return {};
- else
- return x;
- case ENodeType::Uint64:
- if constexpr (AutoConvert)
- return valueBuilder->NewString(ToString(x.Get<ui64>())).Release();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Int64:
- if constexpr (AutoConvert)
- return valueBuilder->NewString(ToString(x.Get<i64>())).Release();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Bool:
- if constexpr (AutoConvert)
- return x.Get<bool>() ? TUnboxedValuePod::Embedded("true") : TUnboxedValuePod::Embedded("false");
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Double:
- if constexpr (AutoConvert)
+ case ENodeType::Uint64:
+ return TUnboxedValuePod(TargetType(x.Get<ui64>()));
+ case ENodeType::Int64:
+ return TUnboxedValuePod(TargetType(x.Get<i64>()));
+ case ENodeType::Bool:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(x.Get<bool>() ? TargetType(1) : TargetType(0));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::String:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(FromStringWithDefault(std::string_view(x.AsStringRef()), TargetType(0)));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Entity:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(0));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::List:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(0));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Dict:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod(TargetType(0));
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Attr:
+ return ConvertToFloat<Strict, AutoConvert, TargetType>(x.GetVariantItem().Release(), valueBuilder, pos);
+ }
+
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse floating point value from " << TDebugPrinter(x)).c_str());
+ static_assert(std::is_floating_point<TargetType>(), "Expect float.");
+}
+
+template<bool Strict, bool AutoConvert, bool Utf8>
+TUnboxedValuePod ConvertToString(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::String:
+ if constexpr (Utf8)
+ if (IsUtf8(x.AsStringRef()))
+ return x;
+ else
+ if (AutoConvert)
+ return valueBuilder->NewString(EscapeC(TStringBuf(x.AsStringRef()))).Release();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ else
+ return x;
+ case ENodeType::Uint64:
+ if constexpr (AutoConvert)
+ return valueBuilder->NewString(ToString(x.Get<ui64>())).Release();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Int64:
+ if constexpr (AutoConvert)
+ return valueBuilder->NewString(ToString(x.Get<i64>())).Release();
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Bool:
+ if constexpr (AutoConvert)
+ return x.Get<bool>() ? TUnboxedValuePod::Embedded("true") : TUnboxedValuePod::Embedded("false");
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Double:
+ if constexpr (AutoConvert)
return valueBuilder->NewString(::FloatToString(x.Get<double>())).Release();
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Entity:
- case ENodeType::List:
- case ENodeType::Dict:
- if constexpr (AutoConvert)
- return TUnboxedValuePod::Embedded("");
- else if constexpr (Strict)
- break;
- else
- return {};
- case ENodeType::Attr:
- return ConvertToString<Strict, AutoConvert, Utf8>(x.GetVariantItem().Release(), valueBuilder, pos);
- }
-
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse string value from " << TDebugPrinter(x)).c_str());
-}
-
-class TLazyConveter : public TManagedBoxedValue {
-public:
- using TConverter = std::function<TUnboxedValuePod(TUnboxedValuePod)>;
-
- TLazyConveter(TUnboxedValue&& original, TConverter&& converter)
- : Original(std::move(original)), Converter(std::move(converter))
- {}
-private:
- template <bool NoSwap>
- class TIterator: public TManagedBoxedValue {
- public:
- TIterator(TUnboxedValue&& original, const TConverter& converter)
- : Original(std::move(original)), Converter(converter)
- {}
-
- private:
- bool Skip() final {
- return Original.Skip();
- }
-
- bool Next(TUnboxedValue& value) final {
- if (Original.Next(value)) {
- if constexpr (!NoSwap) {
- value = Converter(value.Release());
- }
- return true;
- }
- return false;
- }
-
- bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final {
- if (Original.NextPair(key, payload)) {
- if constexpr (NoSwap) {
- payload = Converter(payload.Release());
- } else {
- key = Converter(key.Release());
- }
- return true;
- }
- return false;
- }
-
- const TUnboxedValue Original;
- const TConverter Converter;
- };
-
- ui64 GetDictLength() const final {
- return Original.GetDictLength();
- }
-
- ui64 GetListLength() const final {
- return Original.GetListLength();
- }
-
- bool HasFastListLength() const final {
- return Original.HasFastListLength();
- }
-
- bool HasDictItems() const final {
- return Original.HasDictItems();
- }
-
- bool HasListItems() const final {
- return Original.HasListItems();
- }
-
- TUnboxedValue GetListIterator() const final {
- return TUnboxedValuePod(new TIterator<false>(Original.GetListIterator(), Converter));
- }
-
- TUnboxedValue GetDictIterator() const final {
- return TUnboxedValuePod(new TIterator<true>(Original.GetDictIterator(), Converter));
- }
-
- TUnboxedValue GetKeysIterator() const final {
- return TUnboxedValuePod(new TIterator<true>(Original.GetKeysIterator(), Converter));
- }
-
- TUnboxedValue GetPayloadsIterator() const {
- return TUnboxedValuePod(new TIterator<false>(Original.GetPayloadsIterator(), Converter));
- }
-
- bool Contains(const TUnboxedValuePod& key) const final {
- return Original.Contains(key);
- }
-
- TUnboxedValue Lookup(const TUnboxedValuePod& key) const final {
- if (auto lookup = Original.Lookup(key)) {
- return Converter(lookup.Release().GetOptionalValue()).MakeOptional();
- }
- return {};
- }
-
- bool IsSortedDict() const final {
- return Original.IsSortedDict();
- }
-
-private:
- const TUnboxedValue Original;
- const TConverter Converter;
-};
-
-}
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Entity:
+ case ENodeType::List:
+ case ENodeType::Dict:
+ if constexpr (AutoConvert)
+ return TUnboxedValuePod::Embedded("");
+ else if constexpr (Strict)
+ break;
+ else
+ return {};
+ case ENodeType::Attr:
+ return ConvertToString<Strict, AutoConvert, Utf8>(x.GetVariantItem().Release(), valueBuilder, pos);
+ }
+
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse string value from " << TDebugPrinter(x)).c_str());
+}
+
+class TLazyConveter : public TManagedBoxedValue {
+public:
+ using TConverter = std::function<TUnboxedValuePod(TUnboxedValuePod)>;
+
+ TLazyConveter(TUnboxedValue&& original, TConverter&& converter)
+ : Original(std::move(original)), Converter(std::move(converter))
+ {}
+private:
+ template <bool NoSwap>
+ class TIterator: public TManagedBoxedValue {
+ public:
+ TIterator(TUnboxedValue&& original, const TConverter& converter)
+ : Original(std::move(original)), Converter(converter)
+ {}
+
+ private:
+ bool Skip() final {
+ return Original.Skip();
+ }
+
+ bool Next(TUnboxedValue& value) final {
+ if (Original.Next(value)) {
+ if constexpr (!NoSwap) {
+ value = Converter(value.Release());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final {
+ if (Original.NextPair(key, payload)) {
+ if constexpr (NoSwap) {
+ payload = Converter(payload.Release());
+ } else {
+ key = Converter(key.Release());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ const TUnboxedValue Original;
+ const TConverter Converter;
+ };
+
+ ui64 GetDictLength() const final {
+ return Original.GetDictLength();
+ }
+
+ ui64 GetListLength() const final {
+ return Original.GetListLength();
+ }
+
+ bool HasFastListLength() const final {
+ return Original.HasFastListLength();
+ }
+
+ bool HasDictItems() const final {
+ return Original.HasDictItems();
+ }
+
+ bool HasListItems() const final {
+ return Original.HasListItems();
+ }
+
+ TUnboxedValue GetListIterator() const final {
+ return TUnboxedValuePod(new TIterator<false>(Original.GetListIterator(), Converter));
+ }
+
+ TUnboxedValue GetDictIterator() const final {
+ return TUnboxedValuePod(new TIterator<true>(Original.GetDictIterator(), Converter));
+ }
+
+ TUnboxedValue GetKeysIterator() const final {
+ return TUnboxedValuePod(new TIterator<true>(Original.GetKeysIterator(), Converter));
+ }
+
+ TUnboxedValue GetPayloadsIterator() const {
+ return TUnboxedValuePod(new TIterator<false>(Original.GetPayloadsIterator(), Converter));
+ }
+
+ bool Contains(const TUnboxedValuePod& key) const final {
+ return Original.Contains(key);
+ }
+
+ TUnboxedValue Lookup(const TUnboxedValuePod& key) const final {
+ if (auto lookup = Original.Lookup(key)) {
+ return Converter(lookup.Release().GetOptionalValue()).MakeOptional();
+ }
+ return {};
+ }
+
+ bool IsSortedDict() const final {
+ return Original.IsSortedDict();
+ }
+
+private:
+ const TUnboxedValue Original;
+ const TConverter Converter;
+};
+
+}
diff --git a/ydb/library/yql/minikql/dom/hash.cpp b/ydb/library/yql/minikql/dom/hash.cpp
index 2b68df797e..93008c272f 100644
--- a/ydb/library/yql/minikql/dom/hash.cpp
+++ b/ydb/library/yql/minikql/dom/hash.cpp
@@ -1,151 +1,151 @@
-#include "node.h"
-#include "hash.h"
-
+#include "node.h"
+#include "hash.h"
+
#include <ydb/library/yql/public/udf/udf_type_ops.h>
-
-namespace NYql::NDom {
-
-using namespace NUdf;
-
-namespace {
-
-THashType HashList(const NUdf::TUnboxedValuePod x) {
- THashType hash = 0ULL;
- if (x.IsBoxed()) {
- if (const auto elements = x.GetElements()) {
- const auto size = x.GetListLength();
- for (ui32 i = 0U; i < size; ++i) {
- hash = CombineHashes(hash, HashDom(elements[i]));
- }
- } else {
- const auto it = x.GetListIterator();
- for (TUnboxedValue v; it.Next(v); hash = CombineHashes(hash, HashDom(v)))
- continue;
- }
- }
- return hash;
-}
-
-THashType HashDict(const NUdf::TUnboxedValuePod x) {
- THashType hash = 0ULL;
- if (x.IsBoxed()) {
- const auto it = x.GetDictIterator();
- for (TUnboxedValue k, v; it.NextPair(k, v);) {
- hash = CombineHashes(hash, CombineHashes(GetStringHash(k), HashDom(v)));
- }
- }
- return hash;
-}
-
-bool EquateLists(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
- if (x.IsBoxed() && y.IsBoxed()) {
- const auto ex = x.GetElements();
- const auto ey = y.GetElements();
- if (ex && ey) {
- const auto size = x.GetListLength();
- if (size != y.GetListLength()) {
- return false;
- }
- for (ui32 i = 0U; i < size; ++i) {
- if (!EquateDoms(ex[i], ey[i]))
- return false;
- }
- } else {
- const auto itx = x.GetListIterator();
- const auto ity = y.GetListIterator();
- for (TUnboxedValue vx, vy; itx.Next(vx);) {
- if (!ity.Next(vy))
- return false;
- if (!EquateDoms(vx, vy))
- return false;
- }
- }
- return true;
- }
- return x.IsBoxed() == y.IsBoxed();
-}
-
-bool EquateDicts(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
- if (x.IsBoxed() && y.IsBoxed()) {
- const auto size = x.GetDictLength();
- if (size != y.GetDictLength()) {
- return false;
- }
-
- const auto xr = static_cast<const TPair*>(x.GetResource());
- const auto yr = static_cast<const TPair*>(y.GetResource());
- // clone dict as attrnode
- if (xr && yr) {
- for (ui32 i = 0U; i < size; ++i) {
- if (!EquateStrings(xr[i].first, yr[i].first))
- return false;
- if (!EquateDoms(xr[i].second, yr[i].second))
- return false;
- }
- } else {
- const auto it = x.GetDictIterator();
- for (TUnboxedValue k, v; it.NextPair(k, v);) {
- if (auto l = y.Lookup(k))
- if (EquateDoms(v, l.GetOptionalValue()))
- continue;
- return false;
- }
-
- }
- return true;
- }
- return x.IsBoxed() == y.IsBoxed();
-}
-
-}
-
-THashType HashDom(const NUdf::TUnboxedValuePod x) {
- switch (const auto type = GetNodeType(x); type) {
- case ENodeType::Double:
- return CombineHashes(THashType(type), GetFloatHash<double>(x));
- case ENodeType::Uint64:
- return CombineHashes(THashType(type), GetIntegerHash<ui64>(x));
- case ENodeType::Int64:
- return CombineHashes(THashType(type), GetIntegerHash<i64>(x));
- case ENodeType::Bool:
- return CombineHashes(THashType(type), std::hash<bool>()(x.Get<bool>()));
- case ENodeType::String:
- return CombineHashes(THashType(type), GetStringHash(x));
- case ENodeType::Entity:
- return CombineHashes(THashType(type), THashType(~0ULL));
- case ENodeType::List:
- return CombineHashes(THashType(type), HashList(x));
- case ENodeType::Dict:
- return CombineHashes(THashType(type), HashDict(x));
- case ENodeType::Attr:
- return CombineHashes(THashType(type), CombineHashes(HashDict(x), HashDom(x.GetVariantItem().Release())));
- }
-}
-
-bool EquateDoms(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
- if (const auto type = GetNodeType(x); type == GetNodeType(y)) {
- switch (type) {
- case ENodeType::Double:
- return EquateFloats<double>(x, y);
- case ENodeType::Uint64:
- return EquateIntegers<ui64>(x, y);
- case ENodeType::Int64:
- return EquateIntegers<i64>(x, y);
- case ENodeType::Bool:
- return x.Get<bool>() == y.Get<bool>();
- case ENodeType::String:
- return EquateStrings(x, y);
- case ENodeType::Entity:
- return true;
- case ENodeType::List:
- return EquateLists(x, y);
- case ENodeType::Dict:
- return EquateDicts(x, y);
- case ENodeType::Attr:
- return EquateDicts(x, y) && EquateDoms(x.GetVariantItem().Release(), y.GetVariantItem().Release());
- }
- }
- return false;
-}
-
-}
+
+namespace NYql::NDom {
+
+using namespace NUdf;
+
+namespace {
+
+THashType HashList(const NUdf::TUnboxedValuePod x) {
+ THashType hash = 0ULL;
+ if (x.IsBoxed()) {
+ if (const auto elements = x.GetElements()) {
+ const auto size = x.GetListLength();
+ for (ui32 i = 0U; i < size; ++i) {
+ hash = CombineHashes(hash, HashDom(elements[i]));
+ }
+ } else {
+ const auto it = x.GetListIterator();
+ for (TUnboxedValue v; it.Next(v); hash = CombineHashes(hash, HashDom(v)))
+ continue;
+ }
+ }
+ return hash;
+}
+
+THashType HashDict(const NUdf::TUnboxedValuePod x) {
+ THashType hash = 0ULL;
+ if (x.IsBoxed()) {
+ const auto it = x.GetDictIterator();
+ for (TUnboxedValue k, v; it.NextPair(k, v);) {
+ hash = CombineHashes(hash, CombineHashes(GetStringHash(k), HashDom(v)));
+ }
+ }
+ return hash;
+}
+
+bool EquateLists(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
+ if (x.IsBoxed() && y.IsBoxed()) {
+ const auto ex = x.GetElements();
+ const auto ey = y.GetElements();
+ if (ex && ey) {
+ const auto size = x.GetListLength();
+ if (size != y.GetListLength()) {
+ return false;
+ }
+ for (ui32 i = 0U; i < size; ++i) {
+ if (!EquateDoms(ex[i], ey[i]))
+ return false;
+ }
+ } else {
+ const auto itx = x.GetListIterator();
+ const auto ity = y.GetListIterator();
+ for (TUnboxedValue vx, vy; itx.Next(vx);) {
+ if (!ity.Next(vy))
+ return false;
+ if (!EquateDoms(vx, vy))
+ return false;
+ }
+ }
+ return true;
+ }
+ return x.IsBoxed() == y.IsBoxed();
+}
+
+bool EquateDicts(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
+ if (x.IsBoxed() && y.IsBoxed()) {
+ const auto size = x.GetDictLength();
+ if (size != y.GetDictLength()) {
+ return false;
+ }
+
+ const auto xr = static_cast<const TPair*>(x.GetResource());
+ const auto yr = static_cast<const TPair*>(y.GetResource());
+ // clone dict as attrnode
+ if (xr && yr) {
+ for (ui32 i = 0U; i < size; ++i) {
+ if (!EquateStrings(xr[i].first, yr[i].first))
+ return false;
+ if (!EquateDoms(xr[i].second, yr[i].second))
+ return false;
+ }
+ } else {
+ const auto it = x.GetDictIterator();
+ for (TUnboxedValue k, v; it.NextPair(k, v);) {
+ if (auto l = y.Lookup(k))
+ if (EquateDoms(v, l.GetOptionalValue()))
+ continue;
+ return false;
+ }
+
+ }
+ return true;
+ }
+ return x.IsBoxed() == y.IsBoxed();
+}
+
+}
+
+THashType HashDom(const NUdf::TUnboxedValuePod x) {
+ switch (const auto type = GetNodeType(x); type) {
+ case ENodeType::Double:
+ return CombineHashes(THashType(type), GetFloatHash<double>(x));
+ case ENodeType::Uint64:
+ return CombineHashes(THashType(type), GetIntegerHash<ui64>(x));
+ case ENodeType::Int64:
+ return CombineHashes(THashType(type), GetIntegerHash<i64>(x));
+ case ENodeType::Bool:
+ return CombineHashes(THashType(type), std::hash<bool>()(x.Get<bool>()));
+ case ENodeType::String:
+ return CombineHashes(THashType(type), GetStringHash(x));
+ case ENodeType::Entity:
+ return CombineHashes(THashType(type), THashType(~0ULL));
+ case ENodeType::List:
+ return CombineHashes(THashType(type), HashList(x));
+ case ENodeType::Dict:
+ return CombineHashes(THashType(type), HashDict(x));
+ case ENodeType::Attr:
+ return CombineHashes(THashType(type), CombineHashes(HashDict(x), HashDom(x.GetVariantItem().Release())));
+ }
+}
+
+bool EquateDoms(const NUdf::TUnboxedValuePod x, const NUdf::TUnboxedValuePod y) {
+ if (const auto type = GetNodeType(x); type == GetNodeType(y)) {
+ switch (type) {
+ case ENodeType::Double:
+ return EquateFloats<double>(x, y);
+ case ENodeType::Uint64:
+ return EquateIntegers<ui64>(x, y);
+ case ENodeType::Int64:
+ return EquateIntegers<i64>(x, y);
+ case ENodeType::Bool:
+ return x.Get<bool>() == y.Get<bool>();
+ case ENodeType::String:
+ return EquateStrings(x, y);
+ case ENodeType::Entity:
+ return true;
+ case ENodeType::List:
+ return EquateLists(x, y);
+ case ENodeType::Dict:
+ return EquateDicts(x, y);
+ case ENodeType::Attr:
+ return EquateDicts(x, y) && EquateDoms(x.GetVariantItem().Release(), y.GetVariantItem().Release());
+ }
+ }
+ return false;
+}
+
+}
diff --git a/ydb/library/yql/minikql/dom/hash.h b/ydb/library/yql/minikql/dom/hash.h
index db55cb6302..35fd62f797 100644
--- a/ydb/library/yql/minikql/dom/hash.h
+++ b/ydb/library/yql/minikql/dom/hash.h
@@ -1,13 +1,13 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_types.h>
#include <ydb/library/yql/public/udf/udf_type_ops.h>
-
-namespace NYql::NDom {
-
-NUdf::THashType HashDom(const NUdf::TUnboxedValuePod value);
-
-bool EquateDoms(const NUdf::TUnboxedValuePod lhs, const NUdf::TUnboxedValuePod rhs);
-
-}
-
+
+namespace NYql::NDom {
+
+NUdf::THashType HashDom(const NUdf::TUnboxedValuePod value);
+
+bool EquateDoms(const NUdf::TUnboxedValuePod lhs, const NUdf::TUnboxedValuePod rhs);
+
+}
+
diff --git a/ydb/library/yql/minikql/dom/json.cpp b/ydb/library/yql/minikql/dom/json.cpp
index 128e8fdb5b..853df56cab 100644
--- a/ydb/library/yql/minikql/dom/json.cpp
+++ b/ydb/library/yql/minikql/dom/json.cpp
@@ -2,7 +2,7 @@
#include "node.h"
#include <library/cpp/containers/stack_vector/stack_vec.h>
-
+
#include <library/cpp/json/json_reader.h>
#include <library/cpp/json/json_writer.h>
@@ -13,7 +13,7 @@
#include <util/system/compiler.h>
#include <cmath>
-#include <ctype.h>
+#include <ctype.h>
namespace NYql::NDom {
@@ -22,48 +22,48 @@ using namespace NJson;
namespace {
-size_t AsciiSize(const TStringBuf& str) {
- size_t s = 0U;
- while (s < str.size() && isascii(str[s]))
- ++s;
- return s;
-}
-
-TString EncodeUtf(const TStringBuf& str, size_t from)
-{
- TString result(str.substr(0, from));
- while (from < str.size()) {
- const auto c = str[from++];
- if (isascii(c)) {
- result.append(c);
- } else {
- result.append((c >> '\x06') & '\x03' | '\xC0');
- result.append(c & '\x3F' | '\x80');
- }
- }
-
- return result;
-}
-
-TString DecodeUtf(const TStringBuf& str, size_t from)
-{
- TString result(str);
- auto i = from;
- while (from < str.size()) {
- const auto c = str[from++];
- if (isascii(c)) {
- result[i++] = c;
- } else if ((c & '\xFC') == '\xC0') {
- result[i++] = ((c & '\x03') << '\x06') | (str[from++] & '\x3F');
- } else {
- ythrow yexception() << "Unicode symbols with codes greater than 255 are not supported.";
- }
- }
- result.resize(i);
- return result;
-}
-
-template<bool DecodeUtf8>
+size_t AsciiSize(const TStringBuf& str) {
+ size_t s = 0U;
+ while (s < str.size() && isascii(str[s]))
+ ++s;
+ return s;
+}
+
+TString EncodeUtf(const TStringBuf& str, size_t from)
+{
+ TString result(str.substr(0, from));
+ while (from < str.size()) {
+ const auto c = str[from++];
+ if (isascii(c)) {
+ result.append(c);
+ } else {
+ result.append((c >> '\x06') & '\x03' | '\xC0');
+ result.append(c & '\x3F' | '\x80');
+ }
+ }
+
+ return result;
+}
+
+TString DecodeUtf(const TStringBuf& str, size_t from)
+{
+ TString result(str);
+ auto i = from;
+ while (from < str.size()) {
+ const auto c = str[from++];
+ if (isascii(c)) {
+ result[i++] = c;
+ } else if ((c & '\xFC') == '\xC0') {
+ result[i++] = ((c & '\x03') << '\x06') | (str[from++] & '\x3F');
+ } else {
+ ythrow yexception() << "Unicode symbols with codes greater than 255 are not supported.";
+ }
+ }
+ result.resize(i);
+ return result;
+}
+
+template<bool DecodeUtf8>
class TDomCallbacks : public TJsonCallbacks {
public:
TDomCallbacks(const IValueBuilder* valueBuilder, bool throwException)
@@ -98,11 +98,11 @@ public:
}
bool OnString(const TStringBuf& value) override {
- if constexpr (DecodeUtf8) {
- if (const auto from = AsciiSize(value); from < value.size()) {
- return PushToCurrentCollection(MakeString(DecodeUtf(value, from), ValueBuilder));
- }
- }
+ if constexpr (DecodeUtf8) {
+ if (const auto from = AsciiSize(value); from < value.size()) {
+ return PushToCurrentCollection(MakeString(DecodeUtf(value, from), ValueBuilder));
+ }
+ }
return PushToCurrentCollection(MakeString(value, ValueBuilder));
}
@@ -115,9 +115,9 @@ public:
}
bool OnCloseMap() override {
- Y_VERIFY_DEBUG(!Result.empty());
+ Y_VERIFY_DEBUG(!Result.empty());
auto& items = Result.top();
- Y_VERIFY_DEBUG(items.size() % 2 == 0);
+ Y_VERIFY_DEBUG(items.size() % 2 == 0);
TSmallVec<TPair, TStdAllocatorForUdf<TPair>> pairs;
for (size_t i = 0; i < items.size(); i += 2) {
@@ -151,13 +151,13 @@ public:
private:
bool OnCollectionOpen() {
- Result.emplace();
+ Result.emplace();
return true;
}
bool PushToCurrentCollection(TUnboxedValue&& value) {
Y_VERIFY_DEBUG(!Result.empty());
- Result.top().emplace_back(std::move(value));
+ Result.top().emplace_back(std::move(value));
return true;
}
@@ -168,176 +168,176 @@ private:
const IValueBuilder* ValueBuilder;
using TUnboxedValues = TSmallVec<TUnboxedValue, TStdAllocatorForUdf<TUnboxedValue>>;
- std::stack<TUnboxedValues, TSmallVec<TUnboxedValues, TStdAllocatorForUdf<TUnboxedValues>>> Result;
+ std::stack<TUnboxedValues, TSmallVec<TUnboxedValues, TStdAllocatorForUdf<TUnboxedValues>>> Result;
+};
+
+class TTestCallbacks : public TJsonCallbacks {
+public:
+ TTestCallbacks()
+ : TJsonCallbacks(false)
+ {}
+
+ bool OnNull() final { return true; }
+
+ bool OnBoolean(bool) final { return true; }
+
+ bool OnInteger(long long) final { return true; }
+
+ bool OnUInteger(unsigned long long) final { return true; }
+
+ bool OnDouble(double value) final { return !std::isinf(value); }
+
+ bool OnString(const TStringBuf&) final { return true; }
+
+ bool OnOpenMap() final { return true; }
+
+ bool OnMapKey(const TStringBuf&) final { return true; }
+
+ bool OnCloseMap() final { return true; }
+
+ bool OnOpenArray() final { return true; }
+
+ bool OnCloseArray() final { return true; }
+
+ bool OnEnd() final {
+ if (HasResult)
+ return false;
+
+ return HasResult = true;
+ }
+
+ private:
+ bool HasResult = false;
};
-class TTestCallbacks : public TJsonCallbacks {
-public:
- TTestCallbacks()
- : TJsonCallbacks(false)
- {}
-
- bool OnNull() final { return true; }
-
- bool OnBoolean(bool) final { return true; }
-
- bool OnInteger(long long) final { return true; }
-
- bool OnUInteger(unsigned long long) final { return true; }
-
- bool OnDouble(double value) final { return !std::isinf(value); }
-
- bool OnString(const TStringBuf&) final { return true; }
-
- bool OnOpenMap() final { return true; }
-
- bool OnMapKey(const TStringBuf&) final { return true; }
-
- bool OnCloseMap() final { return true; }
-
- bool OnOpenArray() final { return true; }
-
- bool OnCloseArray() final { return true; }
-
- bool OnEnd() final {
- if (HasResult)
- return false;
-
- return HasResult = true;
- }
-
- private:
- bool HasResult = false;
-};
-
-bool IsEntity(const TUnboxedValuePod value) {
- switch (GetNodeType(value)) {
- case ENodeType::Entity: return true;
- case ENodeType::Attr: return IsEntity(value.GetVariantItem().Release());
- default: return false;
- }
-}
-
-template<bool SkipMapEntity, bool EncodeUtf8>
-void WriteValue(const TUnboxedValuePod value, TJsonWriter& writer);
-
-template<bool SkipMapEntity, bool EncodeUtf8>
-void WriteArray(const TUnboxedValuePod value, TJsonWriter& writer) {
- writer.OpenArray();
- if (value.IsBoxed()) {
- if (const auto elements = value.GetElements()) {
- const auto size = value.GetListLength();
- for (ui64 i = 0; i < size; ++i) {
- WriteValue<SkipMapEntity, EncodeUtf8>(elements[i], writer);
- }
- } else {
- const auto it = value.GetListIterator();
- for (TUnboxedValue v; it.Next(v); WriteValue<SkipMapEntity, EncodeUtf8>(v, writer))
- continue;
- }
- }
- writer.CloseArray();
-}
-
-template<bool SkipMapEntity, bool EncodeUtf8>
-void WriteMap(const TUnboxedValuePod value, TJsonWriter& writer) {
- writer.OpenMap();
- if (value.IsBoxed()) {
- TUnboxedValue key, payload;
- for (const auto it = value.GetDictIterator(); it.NextPair(key, payload);) {
- if constexpr (SkipMapEntity)
- if (IsEntity(payload))
- continue;
- const TStringBuf str = key.AsStringRef();
- if constexpr (EncodeUtf8)
- if (const auto from = AsciiSize(str); from < str.size())
- writer.WriteKey(EncodeUtf(str, from));
- else
- writer.WriteKey(str);
- else
- writer.WriteKey(str);
- WriteValue<SkipMapEntity, EncodeUtf8>(payload, writer);
- }
- }
- writer.CloseMap();
-}
-
-template<bool SkipMapEntity, bool EncodeUtf8>
-void WriteValue(const TUnboxedValuePod value, TJsonWriter& writer) {
- switch (GetNodeType(value)) {
- case ENodeType::String: {
- const TStringBuf str = value.AsStringRef();
- if constexpr (EncodeUtf8) {
- if (const auto from = AsciiSize(str); from < str.size()) {
- return writer.Write(EncodeUtf(str, from));
- }
- }
- return writer.Write(str);
- }
- case ENodeType::Bool:
- return writer.Write(value.Get<bool>());
- case ENodeType::Int64:
- return writer.Write(value.Get<i64>());
- case ENodeType::Uint64:
- return writer.Write(value.Get<ui64>());
- case ENodeType::Double:
- return writer.Write(value.Get<double>());
- case ENodeType::Entity:
- return writer.WriteNull();
- case ENodeType::List:
- return WriteArray<SkipMapEntity, EncodeUtf8>(value, writer);
- case ENodeType::Dict:
- return WriteMap<SkipMapEntity, EncodeUtf8>(value, writer);
- case ENodeType::Attr:
+bool IsEntity(const TUnboxedValuePod value) {
+ switch (GetNodeType(value)) {
+ case ENodeType::Entity: return true;
+ case ENodeType::Attr: return IsEntity(value.GetVariantItem().Release());
+ default: return false;
+ }
+}
+
+template<bool SkipMapEntity, bool EncodeUtf8>
+void WriteValue(const TUnboxedValuePod value, TJsonWriter& writer);
+
+template<bool SkipMapEntity, bool EncodeUtf8>
+void WriteArray(const TUnboxedValuePod value, TJsonWriter& writer) {
+ writer.OpenArray();
+ if (value.IsBoxed()) {
+ if (const auto elements = value.GetElements()) {
+ const auto size = value.GetListLength();
+ for (ui64 i = 0; i < size; ++i) {
+ WriteValue<SkipMapEntity, EncodeUtf8>(elements[i], writer);
+ }
+ } else {
+ const auto it = value.GetListIterator();
+ for (TUnboxedValue v; it.Next(v); WriteValue<SkipMapEntity, EncodeUtf8>(v, writer))
+ continue;
+ }
+ }
+ writer.CloseArray();
+}
+
+template<bool SkipMapEntity, bool EncodeUtf8>
+void WriteMap(const TUnboxedValuePod value, TJsonWriter& writer) {
+ writer.OpenMap();
+ if (value.IsBoxed()) {
+ TUnboxedValue key, payload;
+ for (const auto it = value.GetDictIterator(); it.NextPair(key, payload);) {
+ if constexpr (SkipMapEntity)
+ if (IsEntity(payload))
+ continue;
+ const TStringBuf str = key.AsStringRef();
+ if constexpr (EncodeUtf8)
+ if (const auto from = AsciiSize(str); from < str.size())
+ writer.WriteKey(EncodeUtf(str, from));
+ else
+ writer.WriteKey(str);
+ else
+ writer.WriteKey(str);
+ WriteValue<SkipMapEntity, EncodeUtf8>(payload, writer);
+ }
+ }
+ writer.CloseMap();
+}
+
+template<bool SkipMapEntity, bool EncodeUtf8>
+void WriteValue(const TUnboxedValuePod value, TJsonWriter& writer) {
+ switch (GetNodeType(value)) {
+ case ENodeType::String: {
+ const TStringBuf str = value.AsStringRef();
+ if constexpr (EncodeUtf8) {
+ if (const auto from = AsciiSize(str); from < str.size()) {
+ return writer.Write(EncodeUtf(str, from));
+ }
+ }
+ return writer.Write(str);
+ }
+ case ENodeType::Bool:
+ return writer.Write(value.Get<bool>());
+ case ENodeType::Int64:
+ return writer.Write(value.Get<i64>());
+ case ENodeType::Uint64:
+ return writer.Write(value.Get<ui64>());
+ case ENodeType::Double:
+ return writer.Write(value.Get<double>());
+ case ENodeType::Entity:
+ return writer.WriteNull();
+ case ENodeType::List:
+ return WriteArray<SkipMapEntity, EncodeUtf8>(value, writer);
+ case ENodeType::Dict:
+ return WriteMap<SkipMapEntity, EncodeUtf8>(value, writer);
+ case ENodeType::Attr:
writer.OpenMap();
- writer.WriteKey("$attributes");
- WriteMap<SkipMapEntity, EncodeUtf8>(value, writer);
- writer.WriteKey("$value");
- WriteValue<SkipMapEntity, EncodeUtf8>(value.GetVariantItem().Release(), writer);
+ writer.WriteKey("$attributes");
+ WriteMap<SkipMapEntity, EncodeUtf8>(value, writer);
+ writer.WriteKey("$value");
+ WriteValue<SkipMapEntity, EncodeUtf8>(value.GetVariantItem().Release(), writer);
writer.CloseMap();
}
}
}
-bool IsValidJson(const TStringBuf json) {
- TMemoryInput input(json.data(), json.size());
- TTestCallbacks callbacks;
- return ReadJson(&input, &callbacks);
-}
-
-TUnboxedValue TryParseJsonDom(const TStringBuf json, const IValueBuilder* valueBuilder, bool dencodeUtf8) {
+bool IsValidJson(const TStringBuf json) {
TMemoryInput input(json.data(), json.size());
- if (dencodeUtf8) {
- TDomCallbacks<true> callbacks(valueBuilder, /* throwException */ true);
- if (!ReadJson(&input, &callbacks)) {
- UdfTerminate("Internal error: parser error occurred but corresponding callback was not called");
- }
- return std::move(callbacks).GetResult();
- } else {
- TDomCallbacks<false> callbacks(valueBuilder, /* throwException */ true);
- if (!ReadJson(&input, &callbacks)) {
- UdfTerminate("Internal error: parser error occurred but corresponding callback was not called");
- }
- return std::move(callbacks).GetResult();
+ TTestCallbacks callbacks;
+ return ReadJson(&input, &callbacks);
+}
+
+TUnboxedValue TryParseJsonDom(const TStringBuf json, const IValueBuilder* valueBuilder, bool dencodeUtf8) {
+ TMemoryInput input(json.data(), json.size());
+ if (dencodeUtf8) {
+ TDomCallbacks<true> callbacks(valueBuilder, /* throwException */ true);
+ if (!ReadJson(&input, &callbacks)) {
+ UdfTerminate("Internal error: parser error occurred but corresponding callback was not called");
+ }
+ return std::move(callbacks).GetResult();
+ } else {
+ TDomCallbacks<false> callbacks(valueBuilder, /* throwException */ true);
+ if (!ReadJson(&input, &callbacks)) {
+ UdfTerminate("Internal error: parser error occurred but corresponding callback was not called");
+ }
+ return std::move(callbacks).GetResult();
}
}
-TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity, bool encodeUtf8) {
+TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity, bool encodeUtf8) {
TStringStream output;
TJsonWriter writer(&output, /* formatOutput */ false);
- if (skipMapEntity)
- if (encodeUtf8)
- WriteValue<true, true>(dom, writer);
- else
- WriteValue<true, false>(dom, writer);
- else
- if (encodeUtf8)
- WriteValue<false, true>(dom, writer);
- else
- WriteValue<false, false>(dom, writer);
+ if (skipMapEntity)
+ if (encodeUtf8)
+ WriteValue<true, true>(dom, writer);
+ else
+ WriteValue<true, false>(dom, writer);
+ else
+ if (encodeUtf8)
+ WriteValue<false, true>(dom, writer);
+ else
+ WriteValue<false, false>(dom, writer);
writer.Flush();
return output.Str();
}
-}
+}
diff --git a/ydb/library/yql/minikql/dom/json.h b/ydb/library/yql/minikql/dom/json.h
index 2e4b2be5a3..b234fd8561 100644
--- a/ydb/library/yql/minikql/dom/json.h
+++ b/ydb/library/yql/minikql/dom/json.h
@@ -5,10 +5,10 @@
namespace NYql::NDom {
-bool IsValidJson(const TStringBuf json);
-
-NUdf::TUnboxedValue TryParseJsonDom(const TStringBuf json, const NUdf::IValueBuilder* valueBuilder, bool decodeUtf8 = false);
+bool IsValidJson(const TStringBuf json);
-TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity = false, bool encodeUtf8 = false);
+NUdf::TUnboxedValue TryParseJsonDom(const TStringBuf json, const NUdf::IValueBuilder* valueBuilder, bool decodeUtf8 = false);
-}
+TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity = false, bool encodeUtf8 = false);
+
+}
diff --git a/ydb/library/yql/minikql/dom/make.cpp b/ydb/library/yql/minikql/dom/make.cpp
index 019ef7827c..ae3c698092 100644
--- a/ydb/library/yql/minikql/dom/make.cpp
+++ b/ydb/library/yql/minikql/dom/make.cpp
@@ -1,170 +1,170 @@
-#include "make.h"
-#include "node.h"
-#include "yson.h"
-#include "json.h"
+#include "make.h"
+#include "node.h"
+#include "yson.h"
+#include "json.h"
#include <ydb/library/yql/public/udf/udf_type_inspection.h>
-#include <util/string/builder.h>
-
-namespace NYql::NDom {
-using namespace NUdf;
-
-namespace {
-
-TUnboxedValuePod MakeData(const TDataTypeId nodeType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- switch (nodeType) {
- case TDataType<char*>::Id: return value;
- case TDataType<TUtf8>::Id: return value;
- case TDataType<bool>::Id: return SetNodeType<ENodeType::Bool>(value);
- case TDataType<i8>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i8>())));
- case TDataType<i16>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i16>())));
- case TDataType<i32>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i32>())));
- case TDataType<i64>::Id: return SetNodeType<ENodeType::Int64>(value);
- case TDataType<ui8>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui8>())));
- case TDataType<ui16>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui16>())));
- case TDataType<ui32>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui32>())));
- case TDataType<ui64>::Id: return SetNodeType<ENodeType::Uint64>(value);
- case TDataType<float>::Id: return SetNodeType<ENodeType::Double>(TUnboxedValuePod(double(value.Get<float>())));
- case TDataType<double>::Id: return SetNodeType<ENodeType::Double>(value);
- case TDataType<TYson>::Id: return TryParseYsonDom(value.AsStringRef(), valueBuilder).Release();
- case TDataType<TJson>::Id: return TryParseJsonDom(value.AsStringRef(), valueBuilder).Release();
- default: break;
+#include <util/string/builder.h>
+
+namespace NYql::NDom {
+using namespace NUdf;
+
+namespace {
+
+TUnboxedValuePod MakeData(const TDataTypeId nodeType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ switch (nodeType) {
+ case TDataType<char*>::Id: return value;
+ case TDataType<TUtf8>::Id: return value;
+ case TDataType<bool>::Id: return SetNodeType<ENodeType::Bool>(value);
+ case TDataType<i8>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i8>())));
+ case TDataType<i16>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i16>())));
+ case TDataType<i32>::Id: return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(i64(value.Get<i32>())));
+ case TDataType<i64>::Id: return SetNodeType<ENodeType::Int64>(value);
+ case TDataType<ui8>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui8>())));
+ case TDataType<ui16>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui16>())));
+ case TDataType<ui32>::Id: return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(ui64(value.Get<ui32>())));
+ case TDataType<ui64>::Id: return SetNodeType<ENodeType::Uint64>(value);
+ case TDataType<float>::Id: return SetNodeType<ENodeType::Double>(TUnboxedValuePod(double(value.Get<float>())));
+ case TDataType<double>::Id: return SetNodeType<ENodeType::Double>(value);
+ case TDataType<TYson>::Id: return TryParseYsonDom(value.AsStringRef(), valueBuilder).Release();
+ case TDataType<TJson>::Id: return TryParseJsonDom(value.AsStringRef(), valueBuilder).Release();
+ default: break;
}
- Y_FAIL("Unsupported data type.");
-}
-
-TUnboxedValuePod MakeList(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- if (const auto elements = value.GetElements()) {
- if (const auto size = value.GetListLength()) {
- TUnboxedValue* items = nullptr;
- auto res = valueBuilder->NewArray(size, items);
- for (ui64 i = 0ULL; i < size; ++i) {
- *items++ = MakeDom(typeHelper, itemType, elements[i], valueBuilder);
- }
- return SetNodeType<ENodeType::List>(res.Release());
+ Y_FAIL("Unsupported data type.");
+}
+
+TUnboxedValuePod MakeList(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ if (const auto elements = value.GetElements()) {
+ if (const auto size = value.GetListLength()) {
+ TUnboxedValue* items = nullptr;
+ auto res = valueBuilder->NewArray(size, items);
+ for (ui64 i = 0ULL; i < size; ++i) {
+ *items++ = MakeDom(typeHelper, itemType, elements[i], valueBuilder);
+ }
+ return SetNodeType<ENodeType::List>(res.Release());
+ }
+ } else {
+ TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> items;
+ if (value.HasFastListLength()) {
+ items.reserve(value.GetListLength());
}
- } else {
- TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> items;
- if (value.HasFastListLength()) {
- items.reserve(value.GetListLength());
+ const auto iterator = value.GetListIterator();
+ for (TUnboxedValue current; iterator.Next(current);) {
+ items.emplace_back(MakeDom(typeHelper, itemType, current, valueBuilder));
}
- const auto iterator = value.GetListIterator();
- for (TUnboxedValue current; iterator.Next(current);) {
- items.emplace_back(MakeDom(typeHelper, itemType, current, valueBuilder));
+ if (!items.empty()) {
+ auto res = valueBuilder->NewList(items.data(), items.size());
+ return SetNodeType<ENodeType::List>(res.Release());
}
- if (!items.empty()) {
- auto res = valueBuilder->NewList(items.data(), items.size());
- return SetNodeType<ENodeType::List>(res.Release());
- }
}
- return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
-}
-
-TUnboxedValuePod MakeDict(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
- items.reserve(value.GetDictLength());
- const auto it = value.GetDictIterator();
- for (TUnboxedValue x, y; it.NextPair(x, y);) {
- items.emplace_back(x, MakeDom(typeHelper, itemType, y, valueBuilder));
+ return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
+}
+
+TUnboxedValuePod MakeDict(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
+ items.reserve(value.GetDictLength());
+ const auto it = value.GetDictIterator();
+ for (TUnboxedValue x, y; it.NextPair(x, y);) {
+ items.emplace_back(x, MakeDom(typeHelper, itemType, y, valueBuilder));
+ }
+
+ if (items.empty()) {
+ return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
}
- if (items.empty()) {
- return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
+ return SetNodeType<ENodeType::Dict>(TUnboxedValuePod(new TMapNode(items.data(), items.size())));
+}
+
+TUnboxedValuePod MakeTuple(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); const auto size = tupleTypeInspector.GetElementsCount()) {
+ TUnboxedValue* items = nullptr;
+ auto res = valueBuilder->NewArray(size, items);
+ for (ui64 i = 0ULL; i < size; ++i) {
+ *items++ = MakeDom(typeHelper, tupleTypeInspector.GetElementType(i), static_cast<const TUnboxedValuePod&>(value.GetElement(i)), valueBuilder);
+ }
+ return SetNodeType<ENodeType::List>(res.Release());
}
- return SetNodeType<ENodeType::Dict>(TUnboxedValuePod(new TMapNode(items.data(), items.size())));
-}
-
-TUnboxedValuePod MakeTuple(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); const auto size = tupleTypeInspector.GetElementsCount()) {
- TUnboxedValue* items = nullptr;
- auto res = valueBuilder->NewArray(size, items);
- for (ui64 i = 0ULL; i < size; ++i) {
- *items++ = MakeDom(typeHelper, tupleTypeInspector.GetElementType(i), static_cast<const TUnboxedValuePod&>(value.GetElement(i)), valueBuilder);
+ return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
+}
+
+TUnboxedValuePod MakeStruct(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); const auto size = structTypeInspector.GetMembersCount()) {
+ TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
+ items.reserve(size);
+
+ for (ui64 i = 0ULL; i < size; ++i) {
+ items.emplace_back(
+ valueBuilder->NewString(structTypeInspector.GetMemberName(i)),
+ MakeDom(typeHelper, structTypeInspector.GetMemberType(i), static_cast<const TUnboxedValuePod&>(value.GetElement(i)), valueBuilder)
+ );
}
- return SetNodeType<ENodeType::List>(res.Release());
+
+ return SetNodeType<ENodeType::Dict>(TUnboxedValuePod(new TMapNode(items.data(), items.size())));
}
- return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
-}
-
-TUnboxedValuePod MakeStruct(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); const auto size = structTypeInspector.GetMembersCount()) {
- TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
- items.reserve(size);
-
- for (ui64 i = 0ULL; i < size; ++i) {
- items.emplace_back(
- valueBuilder->NewString(structTypeInspector.GetMemberName(i)),
- MakeDom(typeHelper, structTypeInspector.GetMemberType(i), static_cast<const TUnboxedValuePod&>(value.GetElement(i)), valueBuilder)
- );
- }
-
- return SetNodeType<ENodeType::Dict>(TUnboxedValuePod(new TMapNode(items.data(), items.size())));
- }
-
- return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
-}
-
-TUnboxedValuePod MakeVariant(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- const auto index = value.GetVariantIndex();
- const auto& item = value.GetVariantItem();
- const auto underlyingType = TVariantTypeInspector(*typeHelper, shape).GetUnderlyingType();
- switch (const auto kind = typeHelper->GetTypeKind(underlyingType)) {
- case ETypeKind::Tuple:
- if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, underlyingType); index < tupleTypeInspector.GetElementsCount())
- return MakeDom(typeHelper, tupleTypeInspector.GetElementType(index), item, valueBuilder);
- break;
- case ETypeKind::Struct:
- if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, underlyingType); index < structTypeInspector.GetMembersCount())
- return MakeDom(typeHelper, structTypeInspector.GetMemberType(index), item, valueBuilder);
- break;
- default:
- break;
- }
- Y_FAIL("Unsupported underlying type.");
-}
-
-}
-
-TUnboxedValuePod MakeDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
- switch (const auto kind = typeHelper->GetTypeKind(shape)) {
- case ETypeKind::Null:
- return MakeEntity();
- case ETypeKind::EmptyList:
- return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
- case ETypeKind::EmptyDict:
- return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
- case ETypeKind::Data:
- return MakeData(TDataTypeInspector(*typeHelper, shape).GetTypeId(), value, valueBuilder);
- case ETypeKind::Optional:
- return value ? MakeDom(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType(), value.GetOptionalValue(), valueBuilder) : MakeEntity();
- case ETypeKind::List:
- return MakeList(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder);
- case ETypeKind::Dict: {
- const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
- const auto keyType = dictTypeInspector.GetKeyType();
- Y_VERIFY(ETypeKind::Data == typeHelper->GetTypeKind(keyType), "Unsupported dict key type kind.");
- const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId();
- Y_VERIFY(keyId == TDataType<char*>::Id || keyId == TDataType<TUtf8>::Id, "Unsupported dict key data type.");
- return MakeDict(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder);
+ return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
+}
+
+TUnboxedValuePod MakeVariant(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ const auto index = value.GetVariantIndex();
+ const auto& item = value.GetVariantItem();
+ const auto underlyingType = TVariantTypeInspector(*typeHelper, shape).GetUnderlyingType();
+ switch (const auto kind = typeHelper->GetTypeKind(underlyingType)) {
+ case ETypeKind::Tuple:
+ if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, underlyingType); index < tupleTypeInspector.GetElementsCount())
+ return MakeDom(typeHelper, tupleTypeInspector.GetElementType(index), item, valueBuilder);
+ break;
+ case ETypeKind::Struct:
+ if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, underlyingType); index < structTypeInspector.GetMembersCount())
+ return MakeDom(typeHelper, structTypeInspector.GetMemberType(index), item, valueBuilder);
+ break;
+ default:
+ break;
+ }
+ Y_FAIL("Unsupported underlying type.");
+}
+
+}
+
+TUnboxedValuePod MakeDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder) {
+ switch (const auto kind = typeHelper->GetTypeKind(shape)) {
+ case ETypeKind::Null:
+ return MakeEntity();
+ case ETypeKind::EmptyList:
+ return SetNodeType<ENodeType::List>(TUnboxedValuePod::Void());
+ case ETypeKind::EmptyDict:
+ return SetNodeType<ENodeType::Dict>(TUnboxedValuePod::Void());
+ case ETypeKind::Data:
+ return MakeData(TDataTypeInspector(*typeHelper, shape).GetTypeId(), value, valueBuilder);
+ case ETypeKind::Optional:
+ return value ? MakeDom(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType(), value.GetOptionalValue(), valueBuilder) : MakeEntity();
+ case ETypeKind::List:
+ return MakeList(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder);
+ case ETypeKind::Dict: {
+ const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
+ const auto keyType = dictTypeInspector.GetKeyType();
+ Y_VERIFY(ETypeKind::Data == typeHelper->GetTypeKind(keyType), "Unsupported dict key type kind.");
+ const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId();
+ Y_VERIFY(keyId == TDataType<char*>::Id || keyId == TDataType<TUtf8>::Id, "Unsupported dict key data type.");
+ return MakeDict(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder);
}
- case ETypeKind::Tuple:
- return MakeTuple(typeHelper, shape, value, valueBuilder);
- case ETypeKind::Struct:
- return MakeStruct(typeHelper, shape, value, valueBuilder);
- case ETypeKind::Variant:
- return MakeVariant(typeHelper, shape, value, valueBuilder);
- case ETypeKind::Resource:
- if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
- return value;
+ case ETypeKind::Tuple:
+ return MakeTuple(typeHelper, shape, value, valueBuilder);
+ case ETypeKind::Struct:
+ return MakeStruct(typeHelper, shape, value, valueBuilder);
+ case ETypeKind::Variant:
+ return MakeVariant(typeHelper, shape, value, valueBuilder);
+ case ETypeKind::Resource:
+ if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
+ return value;
[[fallthrough]];
- default:
+ default:
Y_FAIL("Unsupported data kind: %s", ToCString(kind));
}
}
-
-}
+
+}
diff --git a/ydb/library/yql/minikql/dom/make.h b/ydb/library/yql/minikql/dom/make.h
index af60925ba7..a6bba77819 100644
--- a/ydb/library/yql/minikql/dom/make.h
+++ b/ydb/library/yql/minikql/dom/make.h
@@ -1,10 +1,10 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_types.h>
#include <ydb/library/yql/public/udf/udf_value_builder.h>
-
-namespace NYql::NDom {
-
-NUdf::TUnboxedValuePod MakeDom(const NUdf::ITypeInfoHelper::TPtr typeHelper, const NUdf::TType* shape, const NUdf::TUnboxedValuePod value, const NUdf::IValueBuilder* valueBuilder);
-
-}
+
+namespace NYql::NDom {
+
+NUdf::TUnboxedValuePod MakeDom(const NUdf::ITypeInfoHelper::TPtr typeHelper, const NUdf::TType* shape, const NUdf::TUnboxedValuePod value, const NUdf::IValueBuilder* valueBuilder);
+
+}
diff --git a/ydb/library/yql/minikql/dom/node.cpp b/ydb/library/yql/minikql/dom/node.cpp
index 4325970ab1..6eabde3e4e 100644
--- a/ydb/library/yql/minikql/dom/node.cpp
+++ b/ydb/library/yql/minikql/dom/node.cpp
@@ -1,202 +1,202 @@
#include "node.h"
-
-#include <util/generic/algorithm.h>
-
-namespace NYql::NDom {
-
-namespace {
-
-inline bool StringLess(const TPair& x, const TPair& y) {
- return x.first.AsStringRef() < y.first.AsStringRef();
-}
-
-inline bool StringRefLess(const TPair& x, const TStringRef& y) {
- return x.first.AsStringRef() < y;
-}
-
-inline bool StringEquals(const TPair& x, const TPair& y) {
- return x.first.AsStringRef() == y.first.AsStringRef();
-}
-
-}
-
-template <bool NoSwap>
-TMapNode::TIterator<NoSwap>::TIterator(const TMapNode* parent)
- : Parent(const_cast<TMapNode*>(parent))
- , Index(-1)
-{}
-
-template <bool NoSwap>
-bool TMapNode::TIterator<NoSwap>::Skip() {
- if (Index + 1 == Parent->UniqueCount_) {
- return false;
- }
-
- ++Index;
- return true;
-}
-
-template <bool NoSwap>
-bool TMapNode::TIterator<NoSwap>::Next(TUnboxedValue& key) {
- if (!Skip())
- return false;
- if constexpr (NoSwap) {
- key = Parent->Items_[Index].first;
- } else {
- key = Parent->Items_[Index].second;
- }
- return true;
-}
-
-template <bool NoSwap>
-bool TMapNode::TIterator<NoSwap>::NextPair(TUnboxedValue& key, TUnboxedValue& payload) {
- if (!Next(key))
- return false;
- if constexpr (NoSwap) {
- payload = Parent->Items_[Index].second;
- } else {
- payload = Parent->Items_[Index].first;
- }
- return true;
-}
-
-TMapNode::TMapNode(TMapNode&& src)
- : Count_(src.Count_), UniqueCount_(src.UniqueCount_), Items_(src.Items_)
-{
- src.Count_ = src.UniqueCount_ = 0U;
- src.Items_ = nullptr;
-}
-
-TMapNode::TMapNode(const TPair* items, ui32 count)
- : Count_(count)
- , Items_((TPair*)UdfAllocateWithSize(sizeof(TPair) * count))
-{
- std::memset(Items_, 0, sizeof(TPair) * count);
- for (ui32 i = 0; i < count; ++i) {
- Items_[i] = std::move(items[i]);
- }
-
- StableSort(Items_, Items_ + count, StringLess);
- UniqueCount_ = Unique(Items_, Items_ + count, StringEquals) - Items_;
- for (ui32 i = UniqueCount_; i < count; ++i) {
- Items_[i].first.Clear();
- Items_[i].second.Clear();
- }
-}
-
-TMapNode::~TMapNode() {
- for (ui32 i = 0; i < UniqueCount_; ++i) {
- Items_[i].first.Clear();
- Items_[i].second.Clear();
- }
-
- UdfFreeWithSize(Items_, sizeof(TPair) * Count_);
-}
-
-ui64 TMapNode::GetDictLength() const {
- return UniqueCount_;
-}
-
-TUnboxedValue TMapNode::GetDictIterator() const {
- return TUnboxedValuePod(new TIterator<true>(this));
-}
-
-TUnboxedValue TMapNode::GetKeysIterator() const {
- return TUnboxedValuePod(new TIterator<true>(this));
-}
-
-TUnboxedValue TMapNode::GetPayloadsIterator() const {
- return TUnboxedValuePod(new TIterator<false>(this));
-}
-
-bool TMapNode::Contains(const TUnboxedValuePod& key) const {
- return BinarySearch(Items_, Items_ + UniqueCount_, std::make_pair(key, TUnboxedValuePod()), StringLess);
-}
-
-TUnboxedValue TMapNode::Lookup(const TUnboxedValuePod& key) const {
- return Lookup(key.AsStringRef());
-}
-
-TUnboxedValue TMapNode::Lookup(const TStringRef& key) const {
- const auto it = LowerBound(Items_, Items_ + UniqueCount_, key, StringRefLess);
- if (it == Items_ + UniqueCount_ || static_cast<TStringBuf>(it->first.AsStringRef()) != static_cast<TStringBuf>(key))
- return {};
-
- return it->second;
-}
-
-bool TMapNode::HasDictItems() const {
- return UniqueCount_ > 0ULL;
-}
-
-bool TMapNode::IsSortedDict() const {
- return true;
-}
-
-void* TMapNode::GetResource() {
- return Items_;
-}
-
-TAttrNode::TAttrNode(const TUnboxedValue& map, TUnboxedValue&& value)
- : TMapNode(std::move(*static_cast<TMapNode*>(map.AsBoxed().Get()))), Value_(std::move(value))
-{}
-
-TAttrNode::TAttrNode(TUnboxedValue&& value, const TPair* items, ui32 count)
- : TMapNode(items, count), Value_(std::move(value))
-{}
-
-TUnboxedValue TAttrNode::GetVariantItem() const {
- return Value_;
-}
-
-TDebugPrinter::TDebugPrinter(const TUnboxedValuePod& node)
- : Node(node)
-{}
-
-IOutputStream& TDebugPrinter::Out(IOutputStream &o) const {
- switch (GetNodeType(Node)) {
- case ENodeType::Entity:
- o << "entity (#)";
- break;
- case ENodeType::Bool:
- o << "boolean (" << (Node.Get<bool>() ? "true" : "false") << ") value";
- break;
- case ENodeType::Int64:
- o << "integer (" << Node.Get<i64>() << ") value";
- break;
- case ENodeType::Uint64:
- o << "unsigned integer (" << Node.Get<ui64>() << ") value";
- break;
- case ENodeType::Double:
- o << "floating point (" << Node.Get<double>() << ") value";
- break;
- case ENodeType::String:
- if (const std::string_view str(Node.AsStringRef()); str.empty())
- o << "empty string";
- else if(Node.IsEmbedded() && str.cend() == std::find_if(str.cbegin(), str.cend(), [](char c){ return !std::isprint(c); }))
- o << "string '" << str << "' value";
- else
- o << "string value of size " << str.size();
- break;
- case ENodeType::List:
- if (Node.IsBoxed())
- o << "list of size " << Node.GetListLength();
- else
- o << "empty list";
- break;
- case ENodeType::Dict:
- if (Node.IsBoxed())
- o << "dict of size " << Node.GetDictLength();
- else
- o << "empty dict";
- break;
- case ENodeType::Attr:
- return TDebugPrinter(Node.GetVariantItem()).Out(o);
- default:
- o << "invalid node";
- break;
- }
- return o;
-}
-
-}
+
+#include <util/generic/algorithm.h>
+
+namespace NYql::NDom {
+
+namespace {
+
+inline bool StringLess(const TPair& x, const TPair& y) {
+ return x.first.AsStringRef() < y.first.AsStringRef();
+}
+
+inline bool StringRefLess(const TPair& x, const TStringRef& y) {
+ return x.first.AsStringRef() < y;
+}
+
+inline bool StringEquals(const TPair& x, const TPair& y) {
+ return x.first.AsStringRef() == y.first.AsStringRef();
+}
+
+}
+
+template <bool NoSwap>
+TMapNode::TIterator<NoSwap>::TIterator(const TMapNode* parent)
+ : Parent(const_cast<TMapNode*>(parent))
+ , Index(-1)
+{}
+
+template <bool NoSwap>
+bool TMapNode::TIterator<NoSwap>::Skip() {
+ if (Index + 1 == Parent->UniqueCount_) {
+ return false;
+ }
+
+ ++Index;
+ return true;
+}
+
+template <bool NoSwap>
+bool TMapNode::TIterator<NoSwap>::Next(TUnboxedValue& key) {
+ if (!Skip())
+ return false;
+ if constexpr (NoSwap) {
+ key = Parent->Items_[Index].first;
+ } else {
+ key = Parent->Items_[Index].second;
+ }
+ return true;
+}
+
+template <bool NoSwap>
+bool TMapNode::TIterator<NoSwap>::NextPair(TUnboxedValue& key, TUnboxedValue& payload) {
+ if (!Next(key))
+ return false;
+ if constexpr (NoSwap) {
+ payload = Parent->Items_[Index].second;
+ } else {
+ payload = Parent->Items_[Index].first;
+ }
+ return true;
+}
+
+TMapNode::TMapNode(TMapNode&& src)
+ : Count_(src.Count_), UniqueCount_(src.UniqueCount_), Items_(src.Items_)
+{
+ src.Count_ = src.UniqueCount_ = 0U;
+ src.Items_ = nullptr;
+}
+
+TMapNode::TMapNode(const TPair* items, ui32 count)
+ : Count_(count)
+ , Items_((TPair*)UdfAllocateWithSize(sizeof(TPair) * count))
+{
+ std::memset(Items_, 0, sizeof(TPair) * count);
+ for (ui32 i = 0; i < count; ++i) {
+ Items_[i] = std::move(items[i]);
+ }
+
+ StableSort(Items_, Items_ + count, StringLess);
+ UniqueCount_ = Unique(Items_, Items_ + count, StringEquals) - Items_;
+ for (ui32 i = UniqueCount_; i < count; ++i) {
+ Items_[i].first.Clear();
+ Items_[i].second.Clear();
+ }
+}
+
+TMapNode::~TMapNode() {
+ for (ui32 i = 0; i < UniqueCount_; ++i) {
+ Items_[i].first.Clear();
+ Items_[i].second.Clear();
+ }
+
+ UdfFreeWithSize(Items_, sizeof(TPair) * Count_);
+}
+
+ui64 TMapNode::GetDictLength() const {
+ return UniqueCount_;
+}
+
+TUnboxedValue TMapNode::GetDictIterator() const {
+ return TUnboxedValuePod(new TIterator<true>(this));
+}
+
+TUnboxedValue TMapNode::GetKeysIterator() const {
+ return TUnboxedValuePod(new TIterator<true>(this));
+}
+
+TUnboxedValue TMapNode::GetPayloadsIterator() const {
+ return TUnboxedValuePod(new TIterator<false>(this));
+}
+
+bool TMapNode::Contains(const TUnboxedValuePod& key) const {
+ return BinarySearch(Items_, Items_ + UniqueCount_, std::make_pair(key, TUnboxedValuePod()), StringLess);
+}
+
+TUnboxedValue TMapNode::Lookup(const TUnboxedValuePod& key) const {
+ return Lookup(key.AsStringRef());
+}
+
+TUnboxedValue TMapNode::Lookup(const TStringRef& key) const {
+ const auto it = LowerBound(Items_, Items_ + UniqueCount_, key, StringRefLess);
+ if (it == Items_ + UniqueCount_ || static_cast<TStringBuf>(it->first.AsStringRef()) != static_cast<TStringBuf>(key))
+ return {};
+
+ return it->second;
+}
+
+bool TMapNode::HasDictItems() const {
+ return UniqueCount_ > 0ULL;
+}
+
+bool TMapNode::IsSortedDict() const {
+ return true;
+}
+
+void* TMapNode::GetResource() {
+ return Items_;
+}
+
+TAttrNode::TAttrNode(const TUnboxedValue& map, TUnboxedValue&& value)
+ : TMapNode(std::move(*static_cast<TMapNode*>(map.AsBoxed().Get()))), Value_(std::move(value))
+{}
+
+TAttrNode::TAttrNode(TUnboxedValue&& value, const TPair* items, ui32 count)
+ : TMapNode(items, count), Value_(std::move(value))
+{}
+
+TUnboxedValue TAttrNode::GetVariantItem() const {
+ return Value_;
+}
+
+TDebugPrinter::TDebugPrinter(const TUnboxedValuePod& node)
+ : Node(node)
+{}
+
+IOutputStream& TDebugPrinter::Out(IOutputStream &o) const {
+ switch (GetNodeType(Node)) {
+ case ENodeType::Entity:
+ o << "entity (#)";
+ break;
+ case ENodeType::Bool:
+ o << "boolean (" << (Node.Get<bool>() ? "true" : "false") << ") value";
+ break;
+ case ENodeType::Int64:
+ o << "integer (" << Node.Get<i64>() << ") value";
+ break;
+ case ENodeType::Uint64:
+ o << "unsigned integer (" << Node.Get<ui64>() << ") value";
+ break;
+ case ENodeType::Double:
+ o << "floating point (" << Node.Get<double>() << ") value";
+ break;
+ case ENodeType::String:
+ if (const std::string_view str(Node.AsStringRef()); str.empty())
+ o << "empty string";
+ else if(Node.IsEmbedded() && str.cend() == std::find_if(str.cbegin(), str.cend(), [](char c){ return !std::isprint(c); }))
+ o << "string '" << str << "' value";
+ else
+ o << "string value of size " << str.size();
+ break;
+ case ENodeType::List:
+ if (Node.IsBoxed())
+ o << "list of size " << Node.GetListLength();
+ else
+ o << "empty list";
+ break;
+ case ENodeType::Dict:
+ if (Node.IsBoxed())
+ o << "dict of size " << Node.GetDictLength();
+ else
+ o << "empty dict";
+ break;
+ case ENodeType::Attr:
+ return TDebugPrinter(Node.GetVariantItem()).Out(o);
+ default:
+ o << "invalid node";
+ break;
+ }
+ return o;
+}
+
+}
diff --git a/ydb/library/yql/minikql/dom/node.h b/ydb/library/yql/minikql/dom/node.h
index b5a134debd..9e9cc65840 100644
--- a/ydb/library/yql/minikql/dom/node.h
+++ b/ydb/library/yql/minikql/dom/node.h
@@ -5,10 +5,10 @@
namespace NYql::NDom {
-using namespace NUdf;
+using namespace NUdf;
+
+constexpr char NodeResourceName[] = "Yson2.Node";
-constexpr char NodeResourceName[] = "Yson2.Node";
-
using TPair = std::pair<TUnboxedValue, TUnboxedValue>;
enum class ENodeType : ui8 {
@@ -20,27 +20,27 @@ enum class ENodeType : ui8 {
Entity = 5,
List = 6,
Dict = 7,
- Attr = 8,
+ Attr = 8,
};
constexpr ui8 NodeTypeShift = 4;
constexpr ui8 NodeTypeMask = 0xf0;
-template<ENodeType type>
-constexpr inline TUnboxedValuePod SetNodeType(TUnboxedValuePod node) {
- const auto buffer = reinterpret_cast<ui8*>(&node);
- buffer[TUnboxedValuePod::InternalBufferSize] = ui8(type) << NodeTypeShift;
- return node;
-}
-
-template<ENodeType type>
-constexpr inline bool IsNodeType(const TUnboxedValuePod node) {
- const auto buffer = reinterpret_cast<const ui8*>(&node);
- const auto currentMask = buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask;
- constexpr ui8 expectedMask = static_cast<ui8>(type) << NodeTypeShift;
- return currentMask == expectedMask;
-}
-
+template<ENodeType type>
+constexpr inline TUnboxedValuePod SetNodeType(TUnboxedValuePod node) {
+ const auto buffer = reinterpret_cast<ui8*>(&node);
+ buffer[TUnboxedValuePod::InternalBufferSize] = ui8(type) << NodeTypeShift;
+ return node;
+}
+
+template<ENodeType type>
+constexpr inline bool IsNodeType(const TUnboxedValuePod node) {
+ const auto buffer = reinterpret_cast<const ui8*>(&node);
+ const auto currentMask = buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask;
+ constexpr ui8 expectedMask = static_cast<ui8>(type) << NodeTypeShift;
+ return currentMask == expectedMask;
+}
+
inline ENodeType GetNodeType(const TUnboxedValuePod& node) {
const auto* buffer = reinterpret_cast<const char*>(&node);
const ui8 flag = (buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask) >> NodeTypeShift;
@@ -59,109 +59,109 @@ public:
template <bool NoSwap>
class TIterator: public TManagedBoxedValue {
public:
- TIterator(const TMapNode* parent);
+ TIterator(const TMapNode* parent);
private:
- bool Skip() final;
- bool Next(TUnboxedValue& key) final;
- bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final;
+ bool Skip() final;
+ bool Next(TUnboxedValue& key) final;
+ bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final;
const TRefCountedPtr<TMapNode> Parent;
ui32 Index;
};
- TMapNode(const TPair* items, ui32 count);
+ TMapNode(const TPair* items, ui32 count);
- TMapNode(TMapNode&& src);
-
- ~TMapNode();
+ TMapNode(TMapNode&& src);
- TUnboxedValue Lookup(const TStringRef& key) const;
-private:
- ui64 GetDictLength() const final;
+ ~TMapNode();
- TUnboxedValue GetDictIterator() const final;
+ TUnboxedValue Lookup(const TStringRef& key) const;
+private:
+ ui64 GetDictLength() const final;
- TUnboxedValue GetKeysIterator() const final;
+ TUnboxedValue GetDictIterator() const final;
- TUnboxedValue GetPayloadsIterator() const final;
+ TUnboxedValue GetKeysIterator() const final;
- bool Contains(const TUnboxedValuePod& key) const final;
+ TUnboxedValue GetPayloadsIterator() const final;
- TUnboxedValue Lookup(const TUnboxedValuePod& key) const final;
+ bool Contains(const TUnboxedValuePod& key) const final;
- bool HasDictItems() const final;
+ TUnboxedValue Lookup(const TUnboxedValuePod& key) const final;
- bool IsSortedDict() const final;
+ bool HasDictItems() const final;
- void* GetResource() final;
-
- ui32 Count_;
+ bool IsSortedDict() const final;
+
+ void* GetResource() final;
+
+ ui32 Count_;
ui32 UniqueCount_;
- TPair * Items_;
+ TPair * Items_;
};
-class TAttrNode : public TMapNode {
-public:
- TAttrNode(const TUnboxedValue& map, NUdf::TUnboxedValue&& value);
-
- TAttrNode(NUdf::TUnboxedValue&& value, const TPair* items, ui32 count);
-
- NUdf::TUnboxedValue GetVariantItem() const final;
-
-private:
- const NUdf::TUnboxedValue Value_;
-};
-
-inline TUnboxedValuePod MakeAttr(TUnboxedValue&& value, TPair* items, ui32 count) {
- if (count == 0) {
- return value.Release();
- }
-
- return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(value), items, count)));
-}
-
-inline TUnboxedValuePod MakeString(const TStringBuf value, const IValueBuilder* valueBuilder) {
- return valueBuilder->NewString(value).Release();
+class TAttrNode : public TMapNode {
+public:
+ TAttrNode(const TUnboxedValue& map, NUdf::TUnboxedValue&& value);
+
+ TAttrNode(NUdf::TUnboxedValue&& value, const TPair* items, ui32 count);
+
+ NUdf::TUnboxedValue GetVariantItem() const final;
+
+private:
+ const NUdf::TUnboxedValue Value_;
+};
+
+inline TUnboxedValuePod MakeAttr(TUnboxedValue&& value, TPair* items, ui32 count) {
+ if (count == 0) {
+ return value.Release();
+ }
+
+ return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(value), items, count)));
+}
+
+inline TUnboxedValuePod MakeString(const TStringBuf value, const IValueBuilder* valueBuilder) {
+ return valueBuilder->NewString(value).Release();
+}
+
+inline TUnboxedValuePod MakeBool(bool value) {
+ return SetNodeType<ENodeType::Bool>(TUnboxedValuePod(value));
}
-inline TUnboxedValuePod MakeBool(bool value) {
- return SetNodeType<ENodeType::Bool>(TUnboxedValuePod(value));
+inline TUnboxedValuePod MakeInt64(i64 value) {
+ return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(value));
}
-inline TUnboxedValuePod MakeInt64(i64 value) {
- return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(value));
+inline TUnboxedValuePod MakeUint64(ui64 value) {
+ return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(value));
}
-inline TUnboxedValuePod MakeUint64(ui64 value) {
- return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(value));
+inline TUnboxedValuePod MakeDouble(double value) {
+ return SetNodeType<ENodeType::Double>(TUnboxedValuePod(value));
}
-inline TUnboxedValuePod MakeDouble(double value) {
- return SetNodeType<ENodeType::Double>(TUnboxedValuePod(value));
+inline TUnboxedValuePod MakeEntity() {
+ return SetNodeType<ENodeType::Entity>(TUnboxedValuePod::Zero());
}
-inline TUnboxedValuePod MakeEntity() {
- return SetNodeType<ENodeType::Entity>(TUnboxedValuePod::Zero());
+inline TUnboxedValuePod MakeList(TUnboxedValue* items, ui32 count, const IValueBuilder* valueBuilder) {
+ return SetNodeType<ENodeType::List>(count > 0U ? valueBuilder->NewList(items, count).Release() : TUnboxedValuePod::Zero());
}
-inline TUnboxedValuePod MakeList(TUnboxedValue* items, ui32 count, const IValueBuilder* valueBuilder) {
- return SetNodeType<ENodeType::List>(count > 0U ? valueBuilder->NewList(items, count).Release() : TUnboxedValuePod::Zero());
+inline TUnboxedValuePod MakeDict(const TPair* items, ui32 count) {
+ return SetNodeType<ENodeType::Dict>(count > 0U ? TUnboxedValuePod(new TMapNode(items, count)) : TUnboxedValuePod::Zero());
}
-inline TUnboxedValuePod MakeDict(const TPair* items, ui32 count) {
- return SetNodeType<ENodeType::Dict>(count > 0U ? TUnboxedValuePod(new TMapNode(items, count)) : TUnboxedValuePod::Zero());
+struct TDebugPrinter {
+ TDebugPrinter(const TUnboxedValuePod& node);
+ class IOutputStream& Out(class IOutputStream &o) const;
+ const TUnboxedValuePod& Node;
+};
+
}
-struct TDebugPrinter {
- TDebugPrinter(const TUnboxedValuePod& node);
- class IOutputStream& Out(class IOutputStream &o) const;
- const TUnboxedValuePod& Node;
-};
-
+template<>
+inline void Out<NYql::NDom::TDebugPrinter>(class IOutputStream &o, const NYql::NDom::TDebugPrinter& p) {
+ p.Out(o);
}
-
-template<>
-inline void Out<NYql::NDom::TDebugPrinter>(class IOutputStream &o, const NYql::NDom::TDebugPrinter& p) {
- p.Out(o);
-}
diff --git a/ydb/library/yql/minikql/dom/peel.cpp b/ydb/library/yql/minikql/dom/peel.cpp
index 114c95797b..33f22011dd 100644
--- a/ydb/library/yql/minikql/dom/peel.cpp
+++ b/ydb/library/yql/minikql/dom/peel.cpp
@@ -1,372 +1,372 @@
-#include "peel.h"
-#include "node.h"
-#include "yson.h"
-#include "json.h"
-#include "convert.h"
-
+#include "peel.h"
+#include "node.h"
+#include "yson.h"
+#include "json.h"
+#include "convert.h"
+
#include <ydb/library/yql/public/udf/udf_type_inspection.h>
#include <ydb/library/yql/public/udf/udf_type_printer.h>
-
-namespace NYql::NDom {
-using namespace NUdf;
-
-namespace {
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelData(const TDataTypeId nodeType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (nodeType) {
- case TDataType<char*>::Id: return ConvertToString<Strict, AutoConvert, false>(value, valueBuilder, pos);
- case TDataType<TUtf8>::Id: return ConvertToString<Strict, AutoConvert, true>(value, valueBuilder, pos);
- case TDataType<bool>::Id: return ConvertToBool<Strict, AutoConvert>(value, valueBuilder, pos);
- case TDataType<i8>::Id: return ConvertToIntegral<Strict, AutoConvert, i8>(value, valueBuilder, pos);
- case TDataType<i16>::Id: return ConvertToIntegral<Strict, AutoConvert, i16>(value, valueBuilder, pos);
- case TDataType<i32>::Id: return ConvertToIntegral<Strict, AutoConvert, i32>(value, valueBuilder, pos);
- case TDataType<i64>::Id: return ConvertToIntegral<Strict, AutoConvert, i64>(value, valueBuilder, pos);
- case TDataType<ui8>::Id: return ConvertToIntegral<Strict, AutoConvert, ui8>(value, valueBuilder, pos);
- case TDataType<ui16>::Id: return ConvertToIntegral<Strict, AutoConvert, ui16>(value, valueBuilder, pos);
- case TDataType<ui32>::Id: return ConvertToIntegral<Strict, AutoConvert, ui32>(value, valueBuilder, pos);
- case TDataType<ui64>::Id: return ConvertToIntegral<Strict, AutoConvert, ui64>(value, valueBuilder, pos);
- case TDataType<float>::Id: return ConvertToFloat<Strict, AutoConvert, float>(value, valueBuilder, pos);
- case TDataType<double>::Id: return ConvertToFloat<Strict, AutoConvert, double>(value, valueBuilder, pos);
- case TDataType<TYson>::Id: return valueBuilder->NewString(SerializeYsonDomToBinary(value)).Release();
- case TDataType<TJson>::Id: return valueBuilder->NewString(SerializeJsonDom(value)).Release();
- default: break;
- }
-
- UdfTerminate((::TStringBuilder() << "Unsupported data type: " << static_cast<int>(nodeType)).c_str());
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod TryPeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelList(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::List: {
- if (!x.IsBoxed())
- break;
- if constexpr (Strict || AutoConvert) {
- return TUnboxedValuePod(new TLazyConveter(x, std::bind(&PeelDom<Strict, AutoConvert>, typeHelper, itemType, std::placeholders::_1, valueBuilder, pos)));
- }
- TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> values;
- if (const auto elements = x.GetElements()) {
- const auto size = x.GetListLength();
- values.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, elements[i], valueBuilder, pos))
- values.emplace_back(item.GetOptionalValue());
- else if constexpr (Strict)
- UdfTerminate("Error on convert list item.");
- }
- } else {
- const auto it = x.GetListIterator();
- for (TUnboxedValue v; it.Next(v);) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, v, valueBuilder, pos))
- values.emplace_back(item.GetOptionalValue());
- else if constexpr (Strict)
- UdfTerminate("Error on convert list item.");
- }
- }
- if (values.empty()) {
- break;
- }
- return valueBuilder->NewList(values.data(), values.size()).Release();
- }
- case ENodeType::Attr:
- return PeelList<Strict, AutoConvert>(typeHelper, itemType, x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (AutoConvert)
- break;
- else if constexpr (Strict)
- UdfTerminate("Cannot parse list from entity, scalar value or dict.");
- else
- return {};
- }
-
- return valueBuilder->NewEmptyList().Release();
-}
-
-template<bool Strict, bool AutoConvert, bool Utf8Keys>
-TUnboxedValuePod PeelDict(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(x)) {
- case ENodeType::Dict:
- if (!x.IsBoxed())
- break;
- if constexpr (!Utf8Keys && (Strict || AutoConvert)) {
- return TUnboxedValuePod(new TLazyConveter(x, std::bind(&PeelDom<Strict, AutoConvert>, typeHelper, itemType, std::placeholders::_1, valueBuilder, pos)));
- }
- if (const auto size = x.GetDictLength()) {
- TSmallVec<TPair, TStdAllocatorForUdf<TPair>> pairs;
- pairs.reserve(size);
- const auto it = x.GetDictIterator();
- for (TUnboxedValue key, payload; it.NextPair(key, payload);) {
- if (const auto k = ConvertToString<Strict, AutoConvert, Utf8Keys>(key.Release(), valueBuilder, pos)) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, payload, valueBuilder, pos)) {
- pairs.emplace_back(std::move(k), item.GetOptionalValue());
- continue;
- }
- }
-
- if constexpr (Strict)
- UdfTerminate("Error on convert dict payload.");
- }
- if (pairs.empty()) {
- break;
- }
- return TUnboxedValuePod(new TMapNode(pairs.data(), pairs.size()));
- }
- break;
- case ENodeType::Attr:
- return PeelDict<Strict, AutoConvert, Utf8Keys>(typeHelper, itemType, x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (AutoConvert)
- break;
- else if constexpr (Strict)
- UdfTerminate("Cannot parse dict from entity, scalar value or list.");
- else
- return {};
- }
-
- return valueBuilder->NewEmptyList().Release();
-}
-
-TUnboxedValuePod MakeStub(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (const auto kind = typeHelper->GetTypeKind(shape)) {
- case ETypeKind::Optional:
- return TUnboxedValuePod();
- case ETypeKind::Data:
- switch (const auto nodeType = TDataTypeInspector(*typeHelper, shape).GetTypeId()) {
- case TDataType<char*>::Id:
- case TDataType<TUtf8>::Id:
- case TDataType<bool>::Id:
- case TDataType<i8>::Id:
- case TDataType<i16>::Id:
- case TDataType<i32>::Id:
- case TDataType<i64>::Id:
- case TDataType<ui8>::Id:
- case TDataType<ui16>::Id:
- case TDataType<ui32>::Id:
- case TDataType<ui64>::Id:
- case TDataType<float>::Id:
- case TDataType<double>::Id:
- case TDataType<TDecimal>::Id:
- return TUnboxedValuePod::Zero();
- case TDataType<TYson>::Id:
- return TUnboxedValuePod::Embedded("#");
- case TDataType<TJson>::Id:
- return TUnboxedValuePod::Embedded("null");
- default:
- UdfTerminate((::TStringBuilder() << "Unsupported data type: " << static_cast<int>(nodeType)).c_str());
- }
- case ETypeKind::Tuple:
- if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(count, items);
- items += count;
- do *--items = MakeStub(typeHelper, tupleTypeInspector.GetElementType(--count), valueBuilder, pos);
- while (count);
- return result.Release();
- }
- return valueBuilder->NewEmptyList().Release();
- case ETypeKind::Struct:
- if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); auto count = structTypeInspector.GetMembersCount()) {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(count, items);
- items += count;
- do *--items = MakeStub(typeHelper, structTypeInspector.GetMemberType(--count), valueBuilder, pos);
- while (count);
- return result.Release();
- }
- return valueBuilder->NewEmptyList().Release();
- case ETypeKind::List:
- case ETypeKind::Dict:
- return valueBuilder->NewEmptyList().Release();
- case ETypeKind::Resource:
- if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
- return MakeEntity();
+
+namespace NYql::NDom {
+using namespace NUdf;
+
+namespace {
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelData(const TDataTypeId nodeType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (nodeType) {
+ case TDataType<char*>::Id: return ConvertToString<Strict, AutoConvert, false>(value, valueBuilder, pos);
+ case TDataType<TUtf8>::Id: return ConvertToString<Strict, AutoConvert, true>(value, valueBuilder, pos);
+ case TDataType<bool>::Id: return ConvertToBool<Strict, AutoConvert>(value, valueBuilder, pos);
+ case TDataType<i8>::Id: return ConvertToIntegral<Strict, AutoConvert, i8>(value, valueBuilder, pos);
+ case TDataType<i16>::Id: return ConvertToIntegral<Strict, AutoConvert, i16>(value, valueBuilder, pos);
+ case TDataType<i32>::Id: return ConvertToIntegral<Strict, AutoConvert, i32>(value, valueBuilder, pos);
+ case TDataType<i64>::Id: return ConvertToIntegral<Strict, AutoConvert, i64>(value, valueBuilder, pos);
+ case TDataType<ui8>::Id: return ConvertToIntegral<Strict, AutoConvert, ui8>(value, valueBuilder, pos);
+ case TDataType<ui16>::Id: return ConvertToIntegral<Strict, AutoConvert, ui16>(value, valueBuilder, pos);
+ case TDataType<ui32>::Id: return ConvertToIntegral<Strict, AutoConvert, ui32>(value, valueBuilder, pos);
+ case TDataType<ui64>::Id: return ConvertToIntegral<Strict, AutoConvert, ui64>(value, valueBuilder, pos);
+ case TDataType<float>::Id: return ConvertToFloat<Strict, AutoConvert, float>(value, valueBuilder, pos);
+ case TDataType<double>::Id: return ConvertToFloat<Strict, AutoConvert, double>(value, valueBuilder, pos);
+ case TDataType<TYson>::Id: return valueBuilder->NewString(SerializeYsonDomToBinary(value)).Release();
+ case TDataType<TJson>::Id: return valueBuilder->NewString(SerializeJsonDom(value)).Release();
+ default: break;
+ }
+
+ UdfTerminate((::TStringBuilder() << "Unsupported data type: " << static_cast<int>(nodeType)).c_str());
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod TryPeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelList(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::List: {
+ if (!x.IsBoxed())
+ break;
+ if constexpr (Strict || AutoConvert) {
+ return TUnboxedValuePod(new TLazyConveter(x, std::bind(&PeelDom<Strict, AutoConvert>, typeHelper, itemType, std::placeholders::_1, valueBuilder, pos)));
+ }
+ TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> values;
+ if (const auto elements = x.GetElements()) {
+ const auto size = x.GetListLength();
+ values.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, elements[i], valueBuilder, pos))
+ values.emplace_back(item.GetOptionalValue());
+ else if constexpr (Strict)
+ UdfTerminate("Error on convert list item.");
+ }
+ } else {
+ const auto it = x.GetListIterator();
+ for (TUnboxedValue v; it.Next(v);) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, v, valueBuilder, pos))
+ values.emplace_back(item.GetOptionalValue());
+ else if constexpr (Strict)
+ UdfTerminate("Error on convert list item.");
+ }
+ }
+ if (values.empty()) {
+ break;
+ }
+ return valueBuilder->NewList(values.data(), values.size()).Release();
+ }
+ case ENodeType::Attr:
+ return PeelList<Strict, AutoConvert>(typeHelper, itemType, x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (AutoConvert)
+ break;
+ else if constexpr (Strict)
+ UdfTerminate("Cannot parse list from entity, scalar value or dict.");
+ else
+ return {};
+ }
+
+ return valueBuilder->NewEmptyList().Release();
+}
+
+template<bool Strict, bool AutoConvert, bool Utf8Keys>
+TUnboxedValuePod PeelDict(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(x)) {
+ case ENodeType::Dict:
+ if (!x.IsBoxed())
+ break;
+ if constexpr (!Utf8Keys && (Strict || AutoConvert)) {
+ return TUnboxedValuePod(new TLazyConveter(x, std::bind(&PeelDom<Strict, AutoConvert>, typeHelper, itemType, std::placeholders::_1, valueBuilder, pos)));
+ }
+ if (const auto size = x.GetDictLength()) {
+ TSmallVec<TPair, TStdAllocatorForUdf<TPair>> pairs;
+ pairs.reserve(size);
+ const auto it = x.GetDictIterator();
+ for (TUnboxedValue key, payload; it.NextPair(key, payload);) {
+ if (const auto k = ConvertToString<Strict, AutoConvert, Utf8Keys>(key.Release(), valueBuilder, pos)) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, payload, valueBuilder, pos)) {
+ pairs.emplace_back(std::move(k), item.GetOptionalValue());
+ continue;
+ }
+ }
+
+ if constexpr (Strict)
+ UdfTerminate("Error on convert dict payload.");
+ }
+ if (pairs.empty()) {
+ break;
+ }
+ return TUnboxedValuePod(new TMapNode(pairs.data(), pairs.size()));
+ }
+ break;
+ case ENodeType::Attr:
+ return PeelDict<Strict, AutoConvert, Utf8Keys>(typeHelper, itemType, x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (AutoConvert)
+ break;
+ else if constexpr (Strict)
+ UdfTerminate("Cannot parse dict from entity, scalar value or list.");
+ else
+ return {};
+ }
+
+ return valueBuilder->NewEmptyList().Release();
+}
+
+TUnboxedValuePod MakeStub(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (const auto kind = typeHelper->GetTypeKind(shape)) {
+ case ETypeKind::Optional:
+ return TUnboxedValuePod();
+ case ETypeKind::Data:
+ switch (const auto nodeType = TDataTypeInspector(*typeHelper, shape).GetTypeId()) {
+ case TDataType<char*>::Id:
+ case TDataType<TUtf8>::Id:
+ case TDataType<bool>::Id:
+ case TDataType<i8>::Id:
+ case TDataType<i16>::Id:
+ case TDataType<i32>::Id:
+ case TDataType<i64>::Id:
+ case TDataType<ui8>::Id:
+ case TDataType<ui16>::Id:
+ case TDataType<ui32>::Id:
+ case TDataType<ui64>::Id:
+ case TDataType<float>::Id:
+ case TDataType<double>::Id:
+ case TDataType<TDecimal>::Id:
+ return TUnboxedValuePod::Zero();
+ case TDataType<TYson>::Id:
+ return TUnboxedValuePod::Embedded("#");
+ case TDataType<TJson>::Id:
+ return TUnboxedValuePod::Embedded("null");
+ default:
+ UdfTerminate((::TStringBuilder() << "Unsupported data type: " << static_cast<int>(nodeType)).c_str());
+ }
+ case ETypeKind::Tuple:
+ if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(count, items);
+ items += count;
+ do *--items = MakeStub(typeHelper, tupleTypeInspector.GetElementType(--count), valueBuilder, pos);
+ while (count);
+ return result.Release();
+ }
+ return valueBuilder->NewEmptyList().Release();
+ case ETypeKind::Struct:
+ if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); auto count = structTypeInspector.GetMembersCount()) {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(count, items);
+ items += count;
+ do *--items = MakeStub(typeHelper, structTypeInspector.GetMemberType(--count), valueBuilder, pos);
+ while (count);
+ return result.Release();
+ }
+ return valueBuilder->NewEmptyList().Release();
+ case ETypeKind::List:
+ case ETypeKind::Dict:
+ return valueBuilder->NewEmptyList().Release();
+ case ETypeKind::Resource:
+ if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
+ return MakeEntity();
[[fallthrough]];
- default:
- UdfTerminate((::TStringBuilder() << "Unsupported data kind: " << kind).c_str());
- }
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelTuple(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) {
- switch (GetNodeType(x)) {
- case ENodeType::List: {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(count, items);
- ui32 i = 0U;
- if (x.IsBoxed()) {
- if (auto elements = x.GetElements()) {
- for (auto size = x.GetListLength(); count && size--; --count) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, tupleTypeInspector.GetElementType(i++), *elements++, valueBuilder, pos))
- *items++ = item.GetOptionalValue();
- else if constexpr (Strict)
- UdfTerminate("Error on convert tuple item.");
- else
- return {};
- }
- } else if (const auto it = x.GetListIterator()) {
- for (TUnboxedValue v; count && it.Next(v); --count) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, tupleTypeInspector.GetElementType(i++), v, valueBuilder, pos))
- *items++ = item.GetOptionalValue();
- else if constexpr (Strict)
- UdfTerminate("Error on convert tuple item.");
- else
- return {};
- }
- }
- }
- if (count) do
- if constexpr (AutoConvert)
- *items++ = MakeStub(typeHelper, tupleTypeInspector.GetElementType(i++), valueBuilder, pos);
- else if (ETypeKind::Optional == typeHelper->GetTypeKind(tupleTypeInspector.GetElementType(i++)))
- ++items;
- else if constexpr (Strict)
- UdfTerminate((::TStringBuilder() << "DOM list has less items then " << tupleTypeInspector.GetElementsCount() << " tuple elements.").c_str());
- else
- return {};
- while (--count);
- return result.Release();
- }
- case ENodeType::Attr:
- return PeelTuple<Strict, AutoConvert>(typeHelper, shape, x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (AutoConvert) {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(count, items);
- for (ui32 i = 0ULL; i < count; ++i)
- if (ETypeKind::Optional != typeHelper->GetTypeKind(tupleTypeInspector.GetElementType(i)))
- *items++ = MakeStub(typeHelper, tupleTypeInspector.GetElementType(i), valueBuilder, pos);
- else
- ++items;
- return result.Release();
- } else if constexpr (Strict)
- UdfTerminate("Cannot parse tuple from entity, scalar value or dict.");
- else
- break;
- }
- }
-
- return {};
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelStruct(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); const auto size = structTypeInspector.GetMembersCount()) {
- switch (GetNodeType(x)) {
- case ENodeType::Dict: {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(size, items);
- for (ui32 i = 0ULL; i < size; ++i) {
- if (x.IsBoxed()) {
- if (const auto v = x.Lookup(valueBuilder->NewString(structTypeInspector.GetMemberName(i)))) {
- if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, structTypeInspector.GetMemberType(i), v.GetOptionalValue(), valueBuilder, pos))
- *items++ = item.GetOptionalValue();
- else if constexpr (Strict)
- UdfTerminate((::TStringBuilder() << "Error on convert struct member '" << structTypeInspector.GetMemberName(i) << "'.").c_str());
- else
- return {};
- continue;
- }
- }
- if constexpr (AutoConvert)
- *items++ = MakeStub(typeHelper, structTypeInspector.GetMemberType(i), valueBuilder, pos);
- else if (ETypeKind::Optional == typeHelper->GetTypeKind(structTypeInspector.GetMemberType(i)))
- ++items;
- else if constexpr (Strict)
- UdfTerminate((::TStringBuilder() << "Missed struct member '" << structTypeInspector.GetMemberName(i) << "'.").c_str());
- else
- return {};
- }
- return result.Release();
- }
- case ENodeType::Attr:
- return PeelStruct<Strict, AutoConvert>(typeHelper, shape, x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (AutoConvert) {
- TUnboxedValue* items = nullptr;
- auto result = valueBuilder->NewArray(size, items);
- for (ui32 i = 0ULL; i < size; ++i)
- if (ETypeKind::Optional != typeHelper->GetTypeKind(structTypeInspector.GetMemberType(i)))
- *items++ = MakeStub(typeHelper, structTypeInspector.GetMemberType(i), valueBuilder, pos);
- else
- ++items;
- return result.Release();
- } else if constexpr (Strict)
- UdfTerminate("Cannot parse struct from entity, scalar value or list.");
- else
- break;
- }
- }
-
- return {};
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelOptional(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- if (IsNodeType<ENodeType::Entity>(value))
- return TUnboxedValuePod().MakeOptional();
-
- if (const auto result = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, value, valueBuilder, pos); AutoConvert || result)
- return result;
- else if constexpr (Strict)
+ default:
+ UdfTerminate((::TStringBuilder() << "Unsupported data kind: " << kind).c_str());
+ }
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelTuple(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) {
+ switch (GetNodeType(x)) {
+ case ENodeType::List: {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(count, items);
+ ui32 i = 0U;
+ if (x.IsBoxed()) {
+ if (auto elements = x.GetElements()) {
+ for (auto size = x.GetListLength(); count && size--; --count) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, tupleTypeInspector.GetElementType(i++), *elements++, valueBuilder, pos))
+ *items++ = item.GetOptionalValue();
+ else if constexpr (Strict)
+ UdfTerminate("Error on convert tuple item.");
+ else
+ return {};
+ }
+ } else if (const auto it = x.GetListIterator()) {
+ for (TUnboxedValue v; count && it.Next(v); --count) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, tupleTypeInspector.GetElementType(i++), v, valueBuilder, pos))
+ *items++ = item.GetOptionalValue();
+ else if constexpr (Strict)
+ UdfTerminate("Error on convert tuple item.");
+ else
+ return {};
+ }
+ }
+ }
+ if (count) do
+ if constexpr (AutoConvert)
+ *items++ = MakeStub(typeHelper, tupleTypeInspector.GetElementType(i++), valueBuilder, pos);
+ else if (ETypeKind::Optional == typeHelper->GetTypeKind(tupleTypeInspector.GetElementType(i++)))
+ ++items;
+ else if constexpr (Strict)
+ UdfTerminate((::TStringBuilder() << "DOM list has less items then " << tupleTypeInspector.GetElementsCount() << " tuple elements.").c_str());
+ else
+ return {};
+ while (--count);
+ return result.Release();
+ }
+ case ENodeType::Attr:
+ return PeelTuple<Strict, AutoConvert>(typeHelper, shape, x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (AutoConvert) {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(count, items);
+ for (ui32 i = 0ULL; i < count; ++i)
+ if (ETypeKind::Optional != typeHelper->GetTypeKind(tupleTypeInspector.GetElementType(i)))
+ *items++ = MakeStub(typeHelper, tupleTypeInspector.GetElementType(i), valueBuilder, pos);
+ else
+ ++items;
+ return result.Release();
+ } else if constexpr (Strict)
+ UdfTerminate("Cannot parse tuple from entity, scalar value or dict.");
+ else
+ break;
+ }
+ }
+
+ return {};
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelStruct(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); const auto size = structTypeInspector.GetMembersCount()) {
+ switch (GetNodeType(x)) {
+ case ENodeType::Dict: {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(size, items);
+ for (ui32 i = 0ULL; i < size; ++i) {
+ if (x.IsBoxed()) {
+ if (const auto v = x.Lookup(valueBuilder->NewString(structTypeInspector.GetMemberName(i)))) {
+ if (const auto item = TryPeelDom<Strict, AutoConvert>(typeHelper, structTypeInspector.GetMemberType(i), v.GetOptionalValue(), valueBuilder, pos))
+ *items++ = item.GetOptionalValue();
+ else if constexpr (Strict)
+ UdfTerminate((::TStringBuilder() << "Error on convert struct member '" << structTypeInspector.GetMemberName(i) << "'.").c_str());
+ else
+ return {};
+ continue;
+ }
+ }
+ if constexpr (AutoConvert)
+ *items++ = MakeStub(typeHelper, structTypeInspector.GetMemberType(i), valueBuilder, pos);
+ else if (ETypeKind::Optional == typeHelper->GetTypeKind(structTypeInspector.GetMemberType(i)))
+ ++items;
+ else if constexpr (Strict)
+ UdfTerminate((::TStringBuilder() << "Missed struct member '" << structTypeInspector.GetMemberName(i) << "'.").c_str());
+ else
+ return {};
+ }
+ return result.Release();
+ }
+ case ENodeType::Attr:
+ return PeelStruct<Strict, AutoConvert>(typeHelper, shape, x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (AutoConvert) {
+ TUnboxedValue* items = nullptr;
+ auto result = valueBuilder->NewArray(size, items);
+ for (ui32 i = 0ULL; i < size; ++i)
+ if (ETypeKind::Optional != typeHelper->GetTypeKind(structTypeInspector.GetMemberType(i)))
+ *items++ = MakeStub(typeHelper, structTypeInspector.GetMemberType(i), valueBuilder, pos);
+ else
+ ++items;
+ return result.Release();
+ } else if constexpr (Strict)
+ UdfTerminate("Cannot parse struct from entity, scalar value or list.");
+ else
+ break;
+ }
+ }
+
+ return {};
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelOptional(const ITypeInfoHelper::TPtr typeHelper, const TType* itemType, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ if (IsNodeType<ENodeType::Entity>(value))
+ return TUnboxedValuePod().MakeOptional();
+
+ if (const auto result = TryPeelDom<Strict, AutoConvert>(typeHelper, itemType, value, valueBuilder, pos); AutoConvert || result)
+ return result;
+ else if constexpr (Strict)
UdfTerminate("Failed to convert Yson DOM.");
- else
- return TUnboxedValuePod().MakeOptional();
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod TryPeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (const auto kind = typeHelper->GetTypeKind(shape)) {
- case ETypeKind::Data:
- return PeelData<Strict, AutoConvert>(TDataTypeInspector(*typeHelper, shape).GetTypeId(), value, valueBuilder, pos);
- case ETypeKind::Optional:
- return PeelOptional<Strict, AutoConvert>(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder, pos);
- case ETypeKind::List:
- return PeelList<Strict, AutoConvert>(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder, pos);
- case ETypeKind::Dict: {
- const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
- const auto keyType = dictTypeInspector.GetKeyType();
- if (const auto keyKind = typeHelper->GetTypeKind(keyType); ETypeKind::Data == keyKind)
- switch (const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId()) {
- case TDataType<char*>::Id: return PeelDict<Strict, AutoConvert, false>(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder, pos);
- case TDataType<TUtf8>::Id: return PeelDict<Strict, AutoConvert, true>(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder, pos);
- default: UdfTerminate((::TStringBuilder() << "Unsupported dict key type: " << keyId).c_str());
- }
- else
- UdfTerminate((::TStringBuilder() << "Unsupported dict key kind: " << keyKind).c_str());
- }
- case ETypeKind::Tuple:
- return PeelTuple<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos);
- case ETypeKind::Struct:
- return PeelStruct<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos);
- case ETypeKind::Resource:
- if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
- return value;
+ else
+ return TUnboxedValuePod().MakeOptional();
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod TryPeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (const auto kind = typeHelper->GetTypeKind(shape)) {
+ case ETypeKind::Data:
+ return PeelData<Strict, AutoConvert>(TDataTypeInspector(*typeHelper, shape).GetTypeId(), value, valueBuilder, pos);
+ case ETypeKind::Optional:
+ return PeelOptional<Strict, AutoConvert>(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder, pos);
+ case ETypeKind::List:
+ return PeelList<Strict, AutoConvert>(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType(), value, valueBuilder, pos);
+ case ETypeKind::Dict: {
+ const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
+ const auto keyType = dictTypeInspector.GetKeyType();
+ if (const auto keyKind = typeHelper->GetTypeKind(keyType); ETypeKind::Data == keyKind)
+ switch (const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId()) {
+ case TDataType<char*>::Id: return PeelDict<Strict, AutoConvert, false>(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder, pos);
+ case TDataType<TUtf8>::Id: return PeelDict<Strict, AutoConvert, true>(typeHelper, dictTypeInspector.GetValueType(), value, valueBuilder, pos);
+ default: UdfTerminate((::TStringBuilder() << "Unsupported dict key type: " << keyId).c_str());
+ }
+ else
+ UdfTerminate((::TStringBuilder() << "Unsupported dict key kind: " << keyKind).c_str());
+ }
+ case ETypeKind::Tuple:
+ return PeelTuple<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos);
+ case ETypeKind::Struct:
+ return PeelStruct<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos);
+ case ETypeKind::Resource:
+ if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
+ return value;
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- default:
- UdfTerminate((::TStringBuilder() << "Unsupported data kind: " << kind).c_str());
- }
-}
-
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod PeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- if (const auto result = TryPeelDom<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos))
- return result.GetOptionalValue();
- ::TStringBuilder sb;
- sb << "Failed to convert Yson DOM into strict type: ";
- TTypePrinter(*typeHelper, shape).Out(sb.Out);
- UdfTerminate(sb.c_str());
-}
-
-template TUnboxedValuePod PeelDom<true, true>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
-template TUnboxedValuePod PeelDom<false, true>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
-template TUnboxedValuePod PeelDom<true, false>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
-template TUnboxedValuePod PeelDom<false, false>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
-
-}
+ default:
+ UdfTerminate((::TStringBuilder() << "Unsupported data kind: " << kind).c_str());
+ }
+}
+
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod PeelDom(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ if (const auto result = TryPeelDom<Strict, AutoConvert>(typeHelper, shape, value, valueBuilder, pos))
+ return result.GetOptionalValue();
+ ::TStringBuilder sb;
+ sb << "Failed to convert Yson DOM into strict type: ";
+ TTypePrinter(*typeHelper, shape).Out(sb.Out);
+ UdfTerminate(sb.c_str());
+}
+
+template TUnboxedValuePod PeelDom<true, true>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
+template TUnboxedValuePod PeelDom<false, true>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
+template TUnboxedValuePod PeelDom<true, false>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
+template TUnboxedValuePod PeelDom<false, false>(const ITypeInfoHelper::TPtr typeHelper, const TType* shape, const TUnboxedValuePod value, const IValueBuilder* valueBuilder, const TSourcePosition& pos);
+
+}
diff --git a/ydb/library/yql/minikql/dom/peel.h b/ydb/library/yql/minikql/dom/peel.h
index 16204dbe14..35e476250f 100644
--- a/ydb/library/yql/minikql/dom/peel.h
+++ b/ydb/library/yql/minikql/dom/peel.h
@@ -1,11 +1,11 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_types.h>
#include <ydb/library/yql/public/udf/udf_value_builder.h>
-
-namespace NYql::NDom {
-
-template<bool Strict, bool AutoConvert>
-NUdf::TUnboxedValuePod PeelDom(const NUdf::ITypeInfoHelper::TPtr typeHelper, const NUdf::TType* shape, const NUdf::TUnboxedValuePod value, const NUdf::IValueBuilder* valueBuilder, const NUdf::TSourcePosition& pos);
-
-}
+
+namespace NYql::NDom {
+
+template<bool Strict, bool AutoConvert>
+NUdf::TUnboxedValuePod PeelDom(const NUdf::ITypeInfoHelper::TPtr typeHelper, const NUdf::TType* shape, const NUdf::TUnboxedValuePod value, const NUdf::IValueBuilder* valueBuilder, const NUdf::TSourcePosition& pos);
+
+}
diff --git a/ydb/library/yql/minikql/dom/ut/json_ut.cpp b/ydb/library/yql/minikql/dom/ut/json_ut.cpp
index e6e8847d19..5b636eedcf 100644
--- a/ydb/library/yql/minikql/dom/ut/json_ut.cpp
+++ b/ydb/library/yql/minikql/dom/ut/json_ut.cpp
@@ -1,2028 +1,2028 @@
#include <ydb/library/yql/minikql/dom/json.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/library/yql/minikql/mkql_alloc.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_value_builder.h>
-
-using namespace NYql;
-using namespace NYql::NDom;
-using namespace NKikimr;
-
-constexpr char json[] =
-R"(
-{
- "Fullname": [
- {
- "freqs": {
- "sum_qf@de": 28,
- "sum_qf@en": 8,
- "sum_qf@ru": 10060,
- "sum_qf@tr": 91,
- "sum_qf@uk": 245,
- "sum_qf@uz": 6
- },
- "src": [
- {
- "c": "ltr"
- }
- ],
- "value": "Татьяна Сорокина"
- }
- ],
- "Gender": [
- {
- "src": [
- {
- "c": "yam",
- "is_guessed": "True"
- },
- {
- "c": "scm",
- "is_guessed": "True"
- },
- {
- "c": "ltr",
- "is_guessed": "True"
- },
- {
- "c": "lbr",
- "is_guessed": "True"
- }
- ],
- "value": "female"
- }
- ],
- "Image": [
- {
- "RelevLocale": [
- "universe"
- ],
- "avatar_type": "face",
- "color_wiz": {
- "back": "#DBC4B5",
- "button": "#BFAC9E",
- "button_text": "#23211E",
- "text": "#705549"
- },
- "faces_count": 1,
- "langua": [
- "uk",
- "by",
- "kk",
- "ru"
- ],
- "mds_avatar_id": "2001742/402534297",
- "original_size": {
- "height": 1478,
- "width": 1478
- },
- "show_on_serp": true,
- "src": [
- {
- "url": "http://music.yandex.ru/artist/7945920",
- "url_type": "page",
- "value": "yam"
- }
- ],
- "thumb": "Face",
- "type": "image",
- "url": "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig",
- "value": "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig"
- }
- ],
- "ImageSearchRequest": [
- {
- "RelevLocale": [
- "ru",
- "by"
- ],
- "value": "Сорокина Татьяна фото"
- }
- ],
- "Key": [
- {
- "langua": [
- "ru"
- ],
- "predict": "972",
- "rank": 0,
- "src": [
- {
- "c": "rut"
- }
- ],
- "value": "sorokina tatyana"
- },
- {
- "freqs": {
- "sum_qf@de": 3,
- "sum_qf@en": 2,
- "sum_qf@ru": 11504,
- "sum_qf@tr": 35,
- "sum_qf@uk": 145,
- "sum_qf@uz": 1
- },
- "langua": [
- "ru"
- ],
- "src": [
- {
- "c": "yam"
- },
- {
- "c": "ltr"
- },
- {
- "c": "lbr"
- }
- ],
- "value": "сорокина татьяна"
- },
- {
- "langua": [
- "ru"
- ],
- "predict": "931",
- "rank": 1,
- "src": [
- {
- "c": "rut"
- }
- ],
- "value": "tatiana sorokina"
- },
- {
- "langua": [
- "ru"
- ],
- "predict": "951",
- "rank": 0,
- "src": [
- {
- "c": "rut"
- }
- ],
- "value": "tatyana sorokina"
- },
- {
- "freqs": {
- "SenseRatio": 0.01,
- "SenseRatio@de": 0.5,
- "SenseRatio@en": 0.5,
- "SenseRatio@et": 0.5,
- "SenseRatio@fi": 0.5,
- "SenseRatio@id": 0.5,
- "SenseRatio@kk": 0.5,
- "SenseRatio@lt": 0.5,
- "SenseRatio@lv": 0.5,
- "SenseRatio@pl": 0.5,
- "SenseRatio@ru": 0,
- "SenseRatio@tr": 0.5,
- "SenseRatio@uk": 0.5,
- "SenseRatio@uz": 0.5,
- "sum_qf@de": 28,
- "sum_qf@en": 8,
- "sum_qf@ru": 10060,
- "sum_qf@tr": 91,
- "sum_qf@uk": 245,
- "sum_qf@uz": 6
- },
- "langua": [
- "ru"
- ],
- "src": [
- {
- "c": "scm",
- "name": "bookmate.com"
- },
- {
- "c": "yam"
- },
- {
- "c": "ltr"
- }
- ],
- "value": "татьяна сорокина"
- }
- ],
- "Projects": [
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845750|Наши дети]]"
- }
- ],
- "freqs": {
- "sum_qf": 256643
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845750|Наши дети]]"
- },
- {
- "Role": [
- "MAIN_ARTIST"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam08459289|Сто дорог, одна – моя]]"
- }
- ],
- "freqs": {
- "sum_qf": 54092
- },
- "hint_description": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "tr",
- "by"
- ],
- "value": "2019"
- }
- ],
- "otype": "Music/Album@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam08459289|Сто дорог, одна – моя]]"
- },
- {
- "Role": "Author@on",
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm540668de..0|История медицины]]"
- }
- ],
- "freqs": {
- "sum_qf": 49611
- },
- "report": "False",
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm540668de..0|История медицины]]"
- },
- {
- "Role": "Author@on",
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm-3f1fcad4..0|Мыколка]]"
- }
- ],
- "report": "False",
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm-3f1fcad4..0|Мыколка]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845751|100 дорог]]"
- }
- ],
- "freqs": {
- "sum_qf": 21522
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845751|100 дорог]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ],
- "hint_description": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "tr",
- "by"
- ],
- "value": "2015"
- }
- ],
- "report": "False",
- "src": [
- {
- "c": "ltr"
- },
- {
- "c": "lbr"
- }
- ],
- "value": "[[#ltr08920335]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrbs464788|Пейп-арт]]"
- }
- ],
- "freqs": {
- "sum_qf": 12676
- },
- "report": "False",
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "[[#lbrbs464788]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
- }
- ],
- "freqs": {
- "sum_qf": 21
- },
- "report": "False",
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "[[#lbrbs137089]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ],
- "report": "False",
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb464788|Пейп-арт]]"
- }
- ],
- "freqs": {
- "sum_qf": 12676
- },
- "report": "False",
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb464788|Пейп-арт]]"
- },
- {
- "Role": [
- "Artist@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb274279|Что сначала,что потом?]]"
- }
- ],
- "freqs": {
- "sum_qf": 15
- },
- "report": "False",
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb274279|Что сначала,что потом?]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- }
- ],
- "freqs": {
- "sum_qf": 21
- },
- "report": "False",
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845752|Храни его]]"
- }
- ],
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845752|Храни его]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845753|Удача]]"
- }
- ],
- "freqs": {
- "sum_qf": 1431963
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845753|Удача]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- }
- ],
- "freqs": {
- "sum_qf": 34699
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- }
- ],
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845756|Я – мама]]"
- }
- ],
- "freqs": {
- "sum_qf": 441
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845756|Я – мама]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- }
- ],
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- }
- ],
- "freqs": {
- "sum_qf": 152646
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- }
- ],
- "freqs": {
- "sum_qf": 16331217
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- }
- ],
- "freqs": {
- "sum_qf": 94
- },
- "otype": "Music/Recording@on",
- "report": "False",
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- },
- {
- "Role": "Author@on",
- "carousel": "False",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ],
- "report": "False",
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ],
- "SearchRequest": [
- {
- "RelevLocale": [
- "ru",
- "by"
- ],
- "value": "Сорокина Татьяна"
- }
- ],
- "Title": [
- {
- "freqs": {
- "sum_qf@de": 3,
- "sum_qf@en": 2,
- "sum_qf@ru": 11504,
- "sum_qf@tr": 35,
- "sum_qf@uk": 145,
- "sum_qf@uz": 1
- },
- "langua": [
- "ru"
- ],
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "Сорокина Татьяна"
- },
- {
- "RelevLocale": [
- "kz",
- "ua",
- "by",
- "ru"
- ],
- "freqs": {
- "sum_qf@de": 28,
- "sum_qf@en": 8,
- "sum_qf@ru": 10060,
- "sum_qf@tr": 91,
- "sum_qf@uk": 245,
- "sum_qf@uz": 6
- },
- "langua": [
- "ru"
- ],
- "src": [
- {
- "c": "scm",
- "name": "bookmate.com"
- },
- {
- "c": "yam"
- },
- {
- "c": "ltr"
- }
- ],
- "value": "Татьяна Сорокина"
- }
- ],
- "TopTracks": [
- {
- "Position": 9,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- },
- {
- "Position": 8,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- },
- {
- "Position": 7,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- },
- {
- "Position": 6,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845752|Храни его]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845752|Храни его]]"
- },
- {
- "Position": 5,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845753|Удача]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845753|Удача]]"
- },
- {
- "Position": 4,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- },
- {
- "Position": 3,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- },
- {
- "Position": 2,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845750|Наши дети]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845750|Наши дети]]"
- },
- {
- "Position": 1,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845751|100 дорог]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845751|100 дорог]]"
- },
- {
- "Position": 0,
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- }
- ],
- "langua": [
- "uk",
- "ru",
- "kk",
- "by"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- }
- ],
- "freqs": {
- "average_proper_ratio": [
- "1.00"
- ],
- "proper_ratio": [
- {
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "1.00"
- }
- ],
- "sum_qf@de": [
- "31"
- ],
- "sum_qf@en": [
- "10"
- ],
- "sum_qf@ru": [
- "21572"
- ],
- "sum_qf@tr": [
- "126"
- ],
- "sum_qf@uk": [
- "390"
- ],
- "sum_qf@uz": [
- "7"
- ]
- },
- "fullname": [
- {
- "freqs": {
- "sum_qf@de": 28,
- "sum_qf@en": 8,
- "sum_qf@ru": 10060,
- "sum_qf@tr": 91,
- "sum_qf@uk": 245,
- "sum_qf@uz": 6
- },
- "rfr": [
- "[[#rfr21731b2]]"
- ],
- "src": [
- {
- "c": "ltr"
- }
- ],
- "value": "Татьяна Сорокина"
- }
- ],
- "human_gender": [
- {
- "rfr": [
- "[[#rfr21f0d779]]"
- ],
- "src": [
- {
- "c": "yam",
- "is_guessed": "True"
- },
- {
- "c": "scm",
- "is_guessed": "True"
- },
- {
- "c": "ltr",
- "is_guessed": "True"
- },
- {
- "c": "lbr",
- "is_guessed": "True"
- }
- ],
- "value": "female"
- }
- ],
- "ids": [
- {
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "http://music.yandex.ru/artist/7945920"
- },
- {
- "src": [
- {
- "c": "ltr"
- }
- ],
- "value": "https://www.litres.ru/4815845"
- },
- {
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "http://www.labirint.ru/authors/43298"
- }
- ],
- "isa": {
- "Wtype": "Hum",
- "otype": [
- {
- "src": [
- {
- "c": "yam"
- },
- {
- "c": "scm"
- },
- {
- "c": "ltr"
- },
- {
- "c": "lbr"
- }
- ],
- "value": "Hum"
- }
- ]
- },
- "merged_ontoids": [
- "ltr24815845",
- "scmbookmatecomh7b363cfd07a49aed419fde3dbd010f64",
- "lbrh43298",
- "yam17945920"
- ],
- "musical_artist_groups": [
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845750|Наши дети]]"
- }
- ],
- "freqs": {
- "sum_qf": 256643
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845750|Наши дети]]"
- },
- {
- "Role": [
- "MAIN_ARTIST"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam08459289|Сто дорог, одна – моя]]"
- }
- ],
- "freqs": {
- "sum_qf": 54092
- },
- "hint_description": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "tr",
- "by"
- ],
- "value": "2019"
- }
- ],
- "otype": "Music/Album@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam08459289|Сто дорог, одна – моя]]"
- },
- {
- "Role": "Author@on",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm540668de..0|История медицины]]"
- }
- ],
- "freqs": {
- "sum_qf": 49611
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm540668de..0|История медицины]]"
- },
- {
- "Role": "Author@on",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm-3f1fcad4..0|Мыколка]]"
- }
- ],
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm-3f1fcad4..0|Мыколка]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845751|100 дорог]]"
- }
- ],
- "freqs": {
- "sum_qf": 21522
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845751|100 дорог]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ],
- "hint_description": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "tr",
- "by"
- ],
- "value": "2015"
- }
- ],
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "ltr"
- },
- {
- "c": "lbr"
- }
- ],
- "value": "[[#ltr08920335]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrbs464788|Пейп-арт]]"
- }
- ],
- "freqs": {
- "sum_qf": 12676
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "[[#lbrbs464788]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
- }
- ],
- "freqs": {
- "sum_qf": 21
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr"
- }
- ],
- "value": "[[#lbrbs137089]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ],
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb464788|Пейп-арт]]"
- }
- ],
- "freqs": {
- "sum_qf": 12676
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb464788|Пейп-арт]]"
- },
- {
- "Role": [
- "Artist@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb274279|Что сначала,что потом?]]"
- }
- ],
- "freqs": {
- "sum_qf": 15
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb274279|Что сначала,что потом?]]"
- },
- {
- "Role": [
- "Author@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- }
- ],
- "freqs": {
- "sum_qf": 21
- },
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "lbr",
- "f": "book"
- }
- ],
- "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845752|Храни его]]"
- }
- ],
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845752|Храни его]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845753|Удача]]"
- }
- ],
- "freqs": {
- "sum_qf": 1431963
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845753|Удача]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- }
- ],
- "freqs": {
- "sum_qf": 34699
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845754|Матушка Россия]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- }
- ],
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845755|Нежданное свидание]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845756|Я – мама]]"
- }
- ],
- "freqs": {
- "sum_qf": 441
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845756|Я – мама]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- }
- ],
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845757|Глупый сон]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- }
- ],
- "freqs": {
- "sum_qf": 152646
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845760|Спасибо вам]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- }
- ],
- "freqs": {
- "sum_qf": 16331217
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845758|С Днём рождения]]"
- },
- {
- "Role": [
- "Performer@on"
- ],
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- }
- ],
- "freqs": {
- "sum_qf": 94
- },
- "otype": "Music/Recording@on",
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "yam"
- }
- ],
- "value": "[[#yam356845759|Песенка о мечтах]]"
- },
- {
- "Role": "Author@on",
- "formatted": [
- {
- "RelevLocale": [
- "ru",
- "ua",
- "by",
- "kz"
- ],
- "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ],
- "rfr": [
- "[[#rfr110390d1]]"
- ],
- "src": [
- {
- "c": "scm"
- }
- ],
- "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ]
-}
-)";
-
-constexpr auto Steps = 10000U;
-
-Y_UNIT_TEST_SUITE(TJsonTests) {
- Y_UNIT_TEST(TestValidate) {
- UNIT_ASSERT(IsValidJson(json));
-
- UNIT_ASSERT(!IsValidJson("[123}"));
- UNIT_ASSERT(!IsValidJson("[123],[456]"));
- UNIT_ASSERT(!IsValidJson(R"({"c" : "scm"])"));
- UNIT_ASSERT(!IsValidJson(""));
- UNIT_ASSERT(!IsValidJson(R"({"c",})"));
- UNIT_ASSERT(!IsValidJson(R"({null : "scm"})"));
- UNIT_ASSERT(!IsValidJson(R"({'one': 1})"));
- }
-
- Y_UNIT_TEST(TestPerfValidate) {
- const auto t = TInstant::Now();
- for (auto i = 0U; i < Steps; ++i) {
- UNIT_ASSERT(IsValidJson(json));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfParse) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = TryParseJsonDom(json, &builder));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfSerialize) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- const auto dom = TryParseJsonDom(json, &builder);
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = builder.NewString(SerializeJsonDom(dom)));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-}
+
+using namespace NYql;
+using namespace NYql::NDom;
+using namespace NKikimr;
+
+constexpr char json[] =
+R"(
+{
+ "Fullname": [
+ {
+ "freqs": {
+ "sum_qf@de": 28,
+ "sum_qf@en": 8,
+ "sum_qf@ru": 10060,
+ "sum_qf@tr": 91,
+ "sum_qf@uk": 245,
+ "sum_qf@uz": 6
+ },
+ "src": [
+ {
+ "c": "ltr"
+ }
+ ],
+ "value": "Татьяна Сорокина"
+ }
+ ],
+ "Gender": [
+ {
+ "src": [
+ {
+ "c": "yam",
+ "is_guessed": "True"
+ },
+ {
+ "c": "scm",
+ "is_guessed": "True"
+ },
+ {
+ "c": "ltr",
+ "is_guessed": "True"
+ },
+ {
+ "c": "lbr",
+ "is_guessed": "True"
+ }
+ ],
+ "value": "female"
+ }
+ ],
+ "Image": [
+ {
+ "RelevLocale": [
+ "universe"
+ ],
+ "avatar_type": "face",
+ "color_wiz": {
+ "back": "#DBC4B5",
+ "button": "#BFAC9E",
+ "button_text": "#23211E",
+ "text": "#705549"
+ },
+ "faces_count": 1,
+ "langua": [
+ "uk",
+ "by",
+ "kk",
+ "ru"
+ ],
+ "mds_avatar_id": "2001742/402534297",
+ "original_size": {
+ "height": 1478,
+ "width": 1478
+ },
+ "show_on_serp": true,
+ "src": [
+ {
+ "url": "http://music.yandex.ru/artist/7945920",
+ "url_type": "page",
+ "value": "yam"
+ }
+ ],
+ "thumb": "Face",
+ "type": "image",
+ "url": "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig",
+ "value": "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig"
+ }
+ ],
+ "ImageSearchRequest": [
+ {
+ "RelevLocale": [
+ "ru",
+ "by"
+ ],
+ "value": "Сорокина Татьяна фото"
+ }
+ ],
+ "Key": [
+ {
+ "langua": [
+ "ru"
+ ],
+ "predict": "972",
+ "rank": 0,
+ "src": [
+ {
+ "c": "rut"
+ }
+ ],
+ "value": "sorokina tatyana"
+ },
+ {
+ "freqs": {
+ "sum_qf@de": 3,
+ "sum_qf@en": 2,
+ "sum_qf@ru": 11504,
+ "sum_qf@tr": 35,
+ "sum_qf@uk": 145,
+ "sum_qf@uz": 1
+ },
+ "langua": [
+ "ru"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ },
+ {
+ "c": "ltr"
+ },
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "сорокина татьяна"
+ },
+ {
+ "langua": [
+ "ru"
+ ],
+ "predict": "931",
+ "rank": 1,
+ "src": [
+ {
+ "c": "rut"
+ }
+ ],
+ "value": "tatiana sorokina"
+ },
+ {
+ "langua": [
+ "ru"
+ ],
+ "predict": "951",
+ "rank": 0,
+ "src": [
+ {
+ "c": "rut"
+ }
+ ],
+ "value": "tatyana sorokina"
+ },
+ {
+ "freqs": {
+ "SenseRatio": 0.01,
+ "SenseRatio@de": 0.5,
+ "SenseRatio@en": 0.5,
+ "SenseRatio@et": 0.5,
+ "SenseRatio@fi": 0.5,
+ "SenseRatio@id": 0.5,
+ "SenseRatio@kk": 0.5,
+ "SenseRatio@lt": 0.5,
+ "SenseRatio@lv": 0.5,
+ "SenseRatio@pl": 0.5,
+ "SenseRatio@ru": 0,
+ "SenseRatio@tr": 0.5,
+ "SenseRatio@uk": 0.5,
+ "SenseRatio@uz": 0.5,
+ "sum_qf@de": 28,
+ "sum_qf@en": 8,
+ "sum_qf@ru": 10060,
+ "sum_qf@tr": 91,
+ "sum_qf@uk": 245,
+ "sum_qf@uz": 6
+ },
+ "langua": [
+ "ru"
+ ],
+ "src": [
+ {
+ "c": "scm",
+ "name": "bookmate.com"
+ },
+ {
+ "c": "yam"
+ },
+ {
+ "c": "ltr"
+ }
+ ],
+ "value": "татьяна сорокина"
+ }
+ ],
+ "Projects": [
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 256643
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ },
+ {
+ "Role": [
+ "MAIN_ARTIST"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam08459289|Сто дорог, одна – моя]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 54092
+ },
+ "hint_description": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "tr",
+ "by"
+ ],
+ "value": "2019"
+ }
+ ],
+ "otype": "Music/Album@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam08459289|Сто дорог, одна – моя]]"
+ },
+ {
+ "Role": "Author@on",
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm540668de..0|История медицины]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 49611
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm540668de..0|История медицины]]"
+ },
+ {
+ "Role": "Author@on",
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm-3f1fcad4..0|Мыколка]]"
+ }
+ ],
+ "report": "False",
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm-3f1fcad4..0|Мыколка]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21522
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "hint_description": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "tr",
+ "by"
+ ],
+ "value": "2015"
+ }
+ ],
+ "report": "False",
+ "src": [
+ {
+ "c": "ltr"
+ },
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#ltr08920335]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrbs464788|Пейп-арт]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 12676
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#lbrbs464788]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#lbrbs137089]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb464788|Пейп-арт]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 12676
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb464788|Пейп-арт]]"
+ },
+ {
+ "Role": [
+ "Artist@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb274279|Что сначала,что потом?]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 15
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb274279|Что сначала,что потом?]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21
+ },
+ "report": "False",
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 1431963
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 34699
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845756|Я – мама]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 441
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845756|Я – мама]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 152646
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 16331217
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 94
+ },
+ "otype": "Music/Recording@on",
+ "report": "False",
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ },
+ {
+ "Role": "Author@on",
+ "carousel": "False",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "report": "False",
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "SearchRequest": [
+ {
+ "RelevLocale": [
+ "ru",
+ "by"
+ ],
+ "value": "Сорокина Татьяна"
+ }
+ ],
+ "Title": [
+ {
+ "freqs": {
+ "sum_qf@de": 3,
+ "sum_qf@en": 2,
+ "sum_qf@ru": 11504,
+ "sum_qf@tr": 35,
+ "sum_qf@uk": 145,
+ "sum_qf@uz": 1
+ },
+ "langua": [
+ "ru"
+ ],
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "Сорокина Татьяна"
+ },
+ {
+ "RelevLocale": [
+ "kz",
+ "ua",
+ "by",
+ "ru"
+ ],
+ "freqs": {
+ "sum_qf@de": 28,
+ "sum_qf@en": 8,
+ "sum_qf@ru": 10060,
+ "sum_qf@tr": 91,
+ "sum_qf@uk": 245,
+ "sum_qf@uz": 6
+ },
+ "langua": [
+ "ru"
+ ],
+ "src": [
+ {
+ "c": "scm",
+ "name": "bookmate.com"
+ },
+ {
+ "c": "yam"
+ },
+ {
+ "c": "ltr"
+ }
+ ],
+ "value": "Татьяна Сорокина"
+ }
+ ],
+ "TopTracks": [
+ {
+ "Position": 9,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ },
+ {
+ "Position": 8,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ },
+ {
+ "Position": 7,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ },
+ {
+ "Position": 6,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ },
+ {
+ "Position": 5,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ },
+ {
+ "Position": 4,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ },
+ {
+ "Position": 3,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ },
+ {
+ "Position": 2,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ },
+ {
+ "Position": 1,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ },
+ {
+ "Position": 0,
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ }
+ ],
+ "langua": [
+ "uk",
+ "ru",
+ "kk",
+ "by"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ }
+ ],
+ "freqs": {
+ "average_proper_ratio": [
+ "1.00"
+ ],
+ "proper_ratio": [
+ {
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "1.00"
+ }
+ ],
+ "sum_qf@de": [
+ "31"
+ ],
+ "sum_qf@en": [
+ "10"
+ ],
+ "sum_qf@ru": [
+ "21572"
+ ],
+ "sum_qf@tr": [
+ "126"
+ ],
+ "sum_qf@uk": [
+ "390"
+ ],
+ "sum_qf@uz": [
+ "7"
+ ]
+ },
+ "fullname": [
+ {
+ "freqs": {
+ "sum_qf@de": 28,
+ "sum_qf@en": 8,
+ "sum_qf@ru": 10060,
+ "sum_qf@tr": 91,
+ "sum_qf@uk": 245,
+ "sum_qf@uz": 6
+ },
+ "rfr": [
+ "[[#rfr21731b2]]"
+ ],
+ "src": [
+ {
+ "c": "ltr"
+ }
+ ],
+ "value": "Татьяна Сорокина"
+ }
+ ],
+ "human_gender": [
+ {
+ "rfr": [
+ "[[#rfr21f0d779]]"
+ ],
+ "src": [
+ {
+ "c": "yam",
+ "is_guessed": "True"
+ },
+ {
+ "c": "scm",
+ "is_guessed": "True"
+ },
+ {
+ "c": "ltr",
+ "is_guessed": "True"
+ },
+ {
+ "c": "lbr",
+ "is_guessed": "True"
+ }
+ ],
+ "value": "female"
+ }
+ ],
+ "ids": [
+ {
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "http://music.yandex.ru/artist/7945920"
+ },
+ {
+ "src": [
+ {
+ "c": "ltr"
+ }
+ ],
+ "value": "https://www.litres.ru/4815845"
+ },
+ {
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "http://www.labirint.ru/authors/43298"
+ }
+ ],
+ "isa": {
+ "Wtype": "Hum",
+ "otype": [
+ {
+ "src": [
+ {
+ "c": "yam"
+ },
+ {
+ "c": "scm"
+ },
+ {
+ "c": "ltr"
+ },
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "Hum"
+ }
+ ]
+ },
+ "merged_ontoids": [
+ "ltr24815845",
+ "scmbookmatecomh7b363cfd07a49aed419fde3dbd010f64",
+ "lbrh43298",
+ "yam17945920"
+ ],
+ "musical_artist_groups": [
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 256643
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845750|Наши дети]]"
+ },
+ {
+ "Role": [
+ "MAIN_ARTIST"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam08459289|Сто дорог, одна – моя]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 54092
+ },
+ "hint_description": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "tr",
+ "by"
+ ],
+ "value": "2019"
+ }
+ ],
+ "otype": "Music/Album@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam08459289|Сто дорог, одна – моя]]"
+ },
+ {
+ "Role": "Author@on",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm540668de..0|История медицины]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 49611
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm540668de..0|История медицины]]"
+ },
+ {
+ "Role": "Author@on",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm-3f1fcad4..0|Мыколка]]"
+ }
+ ],
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm-3f1fcad4..0|Мыколка]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21522
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845751|100 дорог]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "hint_description": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "tr",
+ "by"
+ ],
+ "value": "2015"
+ }
+ ],
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "ltr"
+ },
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#ltr08920335]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrbs464788|Пейп-арт]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 12676
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#lbrbs464788]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr"
+ }
+ ],
+ "value": "[[#lbrbs137089]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb464788|Пейп-арт]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 12676
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb464788|Пейп-арт]]"
+ },
+ {
+ "Role": [
+ "Artist@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb274279|Что сначала,что потом?]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 15
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb274279|Что сначала,что потом?]]"
+ },
+ {
+ "Role": [
+ "Author@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 21
+ },
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "lbr",
+ "f": "book"
+ }
+ ],
+ "value": "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845752|Храни его]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 1431963
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845753|Удача]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 34699
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845754|Матушка Россия]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845755|Нежданное свидание]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845756|Я – мама]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 441
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845756|Я – мама]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ }
+ ],
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845757|Глупый сон]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 152646
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845760|Спасибо вам]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 16331217
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845758|С Днём рождения]]"
+ },
+ {
+ "Role": [
+ "Performer@on"
+ ],
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ],
+ "freqs": {
+ "sum_qf": 94
+ },
+ "otype": "Music/Recording@on",
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "yam"
+ }
+ ],
+ "value": "[[#yam356845759|Песенка о мечтах]]"
+ },
+ {
+ "Role": "Author@on",
+ "formatted": [
+ {
+ "RelevLocale": [
+ "ru",
+ "ua",
+ "by",
+ "kz"
+ ],
+ "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ],
+ "rfr": [
+ "[[#rfr110390d1]]"
+ ],
+ "src": [
+ {
+ "c": "scm"
+ }
+ ],
+ "value": "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ]
+}
+)";
+
+constexpr auto Steps = 10000U;
+
+Y_UNIT_TEST_SUITE(TJsonTests) {
+ Y_UNIT_TEST(TestValidate) {
+ UNIT_ASSERT(IsValidJson(json));
+
+ UNIT_ASSERT(!IsValidJson("[123}"));
+ UNIT_ASSERT(!IsValidJson("[123],[456]"));
+ UNIT_ASSERT(!IsValidJson(R"({"c" : "scm"])"));
+ UNIT_ASSERT(!IsValidJson(""));
+ UNIT_ASSERT(!IsValidJson(R"({"c",})"));
+ UNIT_ASSERT(!IsValidJson(R"({null : "scm"})"));
+ UNIT_ASSERT(!IsValidJson(R"({'one': 1})"));
+ }
+
+ Y_UNIT_TEST(TestPerfValidate) {
+ const auto t = TInstant::Now();
+ for (auto i = 0U; i < Steps; ++i) {
+ UNIT_ASSERT(IsValidJson(json));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfParse) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = TryParseJsonDom(json, &builder));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfSerialize) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ const auto dom = TryParseJsonDom(json, &builder);
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = builder.NewString(SerializeJsonDom(dom)));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+}
diff --git a/ydb/library/yql/minikql/dom/ut/ya.make b/ydb/library/yql/minikql/dom/ut/ya.make
index a391b4d650..d8cad5b8d8 100644
--- a/ydb/library/yql/minikql/dom/ut/ya.make
+++ b/ydb/library/yql/minikql/dom/ut/ya.make
@@ -1,24 +1,24 @@
-IF (NOT WINDOWS)
+IF (NOT WINDOWS)
UNITTEST_FOR(yql/library/dom)
-
+
OWNER(g:yql)
-
+
SRCS(
yson_ut.cpp
json_ut.cpp
)
-
+
IF (SANITIZER_TYPE)
SIZE(MEDIUM)
TIMEOUT(600)
ENDIF()
-
+
PEERDIR(
ydb/library/yql/minikql/computation
ydb/library/yql/public/udf/service/exception_policy
)
YQL_LAST_ABI_VERSION()
-
+
END()
-ENDIF()
+ENDIF()
diff --git a/ydb/library/yql/minikql/dom/ut/yson_ut.cpp b/ydb/library/yql/minikql/dom/ut/yson_ut.cpp
index 00a4e779c0..b9c479b81b 100644
--- a/ydb/library/yql/minikql/dom/ut/yson_ut.cpp
+++ b/ydb/library/yql/minikql/dom/ut/yson_ut.cpp
@@ -1,2062 +1,2062 @@
#include <ydb/library/yql/minikql/dom/yson.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/library/yql/minikql/mkql_alloc.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/minikql/computation/mkql_value_builder.h>
-
-using namespace NYql;
-using namespace NYql::NDom;
-using namespace NKikimr;
-
-constexpr char yson[] =
-R"(
-{
- "Fullname" = [
- {
- "freqs" = {
- "sum_qf@de" = 28;
- "sum_qf@en" = 8;
- "sum_qf@ru" = 10060;
- "sum_qf@tr" = 91;
- "sum_qf@uk" = 245;
- "sum_qf@uz" = 6
- };
- "src" = [
- {
- "c" = "ltr"
- }
- ];
- "value" = "Татьяна Сорокина"
- }
- ];
- "Gender" = [
- {
- "src" = [
- {
- "c" = "yam";
- "is_guessed" = "True"
- };
- {
- "c" = "scm";
- "is_guessed" = "True"
- };
- {
- "c" = "ltr";
- "is_guessed" = "True"
- };
- {
- "c" = "lbr";
- "is_guessed" = "True"
- }
- ];
- "value" = "female"
- }
- ];
- "Image" = [
- {
- "RelevLocale" = [
- "universe"
- ];
- "avatar_type" = "face";
- "color_wiz" = {
- "back" = "#DBC4B5";
- "button" = "#BFAC9E";
- "button_text" = "#23211E";
- "text" = "#705549"
- };
- "faces_count" = 1;
- "langua" = [
- "uk";
- "by";
- "kk";
- "ru"
- ];
- "mds_avatar_id" = "2001742/402534297";
- "original_size" = {
- "height" = 1478;
- "width" = 1478
- };
- "show_on_serp" = %true;
- "src" = [
- {
- "url" = "http://music.yandex.ru/artist/7945920";
- "url_type" = "page";
- "value" = "yam"
- }
- ];
- "thumb" = "Face";
- "type" = "image";
- "url" = "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig";
- "value" = "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig"
- }
- ];
- "ImageSearchRequest" = [
- {
- "RelevLocale" = [
- "ru";
- "by"
- ];
- "value" = "Сорокина Татьяна фото"
- }
- ];
- "Key" = [
- {
- "langua" = [
- "ru"
- ];
- "predict" = "972";
- "rank" = 0;
- "src" = [
- {
- "c" = "rut"
- }
- ];
- "value" = "sorokina tatyana"
- };
- {
- "freqs" = {
- "sum_qf@de" = 3;
- "sum_qf@en" = 2;
- "sum_qf@ru" = 11504;
- "sum_qf@tr" = 35;
- "sum_qf@uk" = 145;
- "sum_qf@uz" = 1
- };
- "langua" = [
- "ru"
- ];
- "src" = [
- {
- "c" = "yam"
- };
- {
- "c" = "ltr"
- };
- {
- "c" = "lbr"
- }
- ];
- "value" = "сорокина татьяна"
- };
- {
- "langua" = [
- "ru"
- ];
- "predict" = "931";
- "rank" = 1;
- "src" = [
- {
- "c" = "rut"
- }
- ];
- "value" = "tatiana sorokina"
- };
- {
- "langua" = [
- "ru"
- ];
- "predict" = "951";
- "rank" = 0;
- "src" = [
- {
- "c" = "rut"
- }
- ];
- "value" = "tatyana sorokina"
- };
- {
- "freqs" = {
- "SenseRatio" = 0.01;
- "SenseRatio@de" = 0.5;
- "SenseRatio@en" = 0.5;
- "SenseRatio@et" = 0.5;
- "SenseRatio@fi" = 0.5;
- "SenseRatio@id" = 0.5;
- "SenseRatio@kk" = 0.5;
- "SenseRatio@lt" = 0.5;
- "SenseRatio@lv" = 0.5;
- "SenseRatio@pl" = 0.5;
- "SenseRatio@ru" = 0;
- "SenseRatio@tr" = 0.5;
- "SenseRatio@uk" = 0.5;
- "SenseRatio@uz" = 0.5;
- "sum_qf@de" = 28;
- "sum_qf@en" = 8;
- "sum_qf@ru" = 10060;
- "sum_qf@tr" = 91;
- "sum_qf@uk" = 245;
- "sum_qf@uz" = 6
- };
- "langua" = [
- "ru"
- ];
- "src" = [
- {
- "c" = "scm";
- "name" = "bookmate.com"
- };
- {
- "c" = "yam"
- };
- {
- "c" = "ltr"
- }
- ];
- "value" = "татьяна сорокина"
- }
- ];
- "Projects" = [
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 256643
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- };
- {
- "Role" = [
- "MAIN_ARTIST"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 54092
- };
- "hint_description" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "tr";
- "by"
- ];
- "value" = "2019"
- }
- ];
- "otype" = "Music/Album@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
- };
- {
- "Role" = "Author@on";
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm540668de..0|История медицины]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 49611
- };
- "report" = "False";
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm540668de..0|История медицины]]"
- };
- {
- "Role" = "Author@on";
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
- }
- ];
- "report" = "False";
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21522
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ];
- "hint_description" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "tr";
- "by"
- ];
- "value" = "2015"
- }
- ];
- "report" = "False";
- "src" = [
- {
- "c" = "ltr"
- };
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#ltr08920335]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrbs464788|Пейп-арт]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 12676
- };
- "report" = "False";
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#lbrbs464788]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21
- };
- "report" = "False";
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#lbrbs137089]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ];
- "report" = "False";
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb464788|Пейп-арт]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 12676
- };
- "report" = "False";
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb464788|Пейп-арт]]"
- };
- {
- "Role" = [
- "Artist@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb274279|Что сначала,что потом?]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 15
- };
- "report" = "False";
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb274279|Что сначала,что потом?]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21
- };
- "report" = "False";
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845752|Храни его]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845752|Храни его]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845753|Удача]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 1431963
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845753|Удача]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 34699
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845756|Я – мама]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 441
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845756|Я – мама]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 152646
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 16331217
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 94
- };
- "otype" = "Music/Recording@on";
- "report" = "False";
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- };
- {
- "Role" = "Author@on";
- "carousel" = "False";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ];
- "report" = "False";
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ];
- "SearchRequest" = [
- {
- "RelevLocale" = [
- "ru";
- "by"
- ];
- "value" = "Сорокина Татьяна"
- }
- ];
- "Title" = [
- {
- "freqs" = {
- "sum_qf@de" = 3;
- "sum_qf@en" = 2;
- "sum_qf@ru" = 11504;
- "sum_qf@tr" = 35;
- "sum_qf@uk" = 145;
- "sum_qf@uz" = 1
- };
- "langua" = [
- "ru"
- ];
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "Сорокина Татьяна"
- };
- {
- "RelevLocale" = [
- "kz";
- "ua";
- "by";
- "ru"
- ];
- "freqs" = {
- "sum_qf@de" = 28;
- "sum_qf@en" = 8;
- "sum_qf@ru" = 10060;
- "sum_qf@tr" = 91;
- "sum_qf@uk" = 245;
- "sum_qf@uz" = 6
- };
- "langua" = [
- "ru"
- ];
- "src" = [
- {
- "c" = "scm";
- "name" = "bookmate.com"
- };
- {
- "c" = "yam"
- };
- {
- "c" = "ltr"
- }
- ];
- "value" = "Татьяна Сорокина"
- }
- ];
- "TopTracks" = [
- {
- "Position" = 9;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- };
- {
- "Position" = 8;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- };
- {
- "Position" = 7;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- };
- {
- "Position" = 6;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845752|Храни его]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845752|Храни его]]"
- };
- {
- "Position" = 5;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845753|Удача]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845753|Удача]]"
- };
- {
- "Position" = 4;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- };
- {
- "Position" = 3;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- };
- {
- "Position" = 2;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- };
- {
- "Position" = 1;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- };
- {
- "Position" = 0;
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- }
- ];
- "langua" = [
- "uk";
- "ru";
- "kk";
- "by"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- }
- ];
- "freqs" = {
- "average_proper_ratio" = [
- "1.00"
- ];
- "proper_ratio" = [
- {
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "1.00"
- }
- ];
- "sum_qf@de" = [
- "31"
- ];
- "sum_qf@en" = [
- "10"
- ];
- "sum_qf@ru" = [
- "21572"
- ];
- "sum_qf@tr" = [
- "126"
- ];
- "sum_qf@uk" = [
- "390"
- ];
- "sum_qf@uz" = [
- "7"
- ]
- };
- "fullname" = [
- {
- "freqs" = {
- "sum_qf@de" = 28;
- "sum_qf@en" = 8;
- "sum_qf@ru" = 10060;
- "sum_qf@tr" = 91;
- "sum_qf@uk" = 245;
- "sum_qf@uz" = 6
- };
- "rfr" = [
- "[[#rfr21731b2]]"
- ];
- "src" = [
- {
- "c" = "ltr"
- }
- ];
- "value" = "Татьяна Сорокина"
- }
- ];
- "human_gender" = [
- {
- "rfr" = [
- "[[#rfr21f0d779]]"
- ];
- "src" = [
- {
- "c" = "yam";
- "is_guessed" = "True"
- };
- {
- "c" = "scm";
- "is_guessed" = "True"
- };
- {
- "c" = "ltr";
- "is_guessed" = "True"
- };
- {
- "c" = "lbr";
- "is_guessed" = "True"
- }
- ];
- "value" = "female"
- }
- ];
- "ids" = [
- {
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "http://music.yandex.ru/artist/7945920"
- };
- {
- "src" = [
- {
- "c" = "ltr"
- }
- ];
- "value" = "https://www.litres.ru/4815845"
- };
- {
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "http://www.labirint.ru/authors/43298"
- }
- ];
- "isa" = {
- "Wtype" = "Hum";
- "otype" = [
- {
- "src" = [
- {
- "c" = "yam"
- };
- {
- "c" = "scm"
- };
- {
- "c" = "ltr"
- };
- {
- "c" = "lbr"
- }
- ];
- "value" = "Hum"
- }
- ]
- };
- "merged_ontoids" = [
- "ltr24815845";
- "scmbookmatecomh7b363cfd07a49aed419fde3dbd010f64";
- "lbrh43298";
- "yam17945920"
- ];
- "musical_artist_groups" = [
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 256643
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845750|Наши дети]]"
- };
- {
- "Role" = [
- "MAIN_ARTIST"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 54092
- };
- "hint_description" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "tr";
- "by"
- ];
- "value" = "2019"
- }
- ];
- "otype" = "Music/Album@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
- };
- {
- "Role" = "Author@on";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm540668de..0|История медицины]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 49611
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm540668de..0|История медицины]]"
- };
- {
- "Role" = "Author@on";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
- }
- ];
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21522
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845751|100 дорог]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ];
- "hint_description" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "tr";
- "by"
- ];
- "value" = "2015"
- }
- ];
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "ltr"
- };
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#ltr08920335]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrbs464788|Пейп-арт]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 12676
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#lbrbs464788]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr"
- }
- ];
- "value" = "[[#lbrbs137089]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- }
- ];
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb464788|Пейп-арт]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 12676
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb464788|Пейп-арт]]"
- };
- {
- "Role" = [
- "Artist@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb274279|Что сначала,что потом?]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 15
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb274279|Что сначала,что потом?]]"
- };
- {
- "Role" = [
- "Author@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 21
- };
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "lbr";
- "f" = "book"
- }
- ];
- "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845752|Храни его]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845752|Храни его]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845753|Удача]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 1431963
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845753|Удача]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 34699
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845754|Матушка Россия]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845755|Нежданное свидание]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845756|Я – мама]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 441
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845756|Я – мама]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- }
- ];
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845757|Глупый сон]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 152646
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845760|Спасибо вам]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 16331217
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845758|С Днём рождения]]"
- };
- {
- "Role" = [
- "Performer@on"
- ];
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- }
- ];
- "freqs" = {
- "sum_qf" = 94
- };
- "otype" = "Music/Recording@on";
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "yam"
- }
- ];
- "value" = "[[#yam356845759|Песенка о мечтах]]"
- };
- {
- "Role" = "Author@on";
- "formatted" = [
- {
- "RelevLocale" = [
- "ru";
- "ua";
- "by";
- "kz"
- ];
- "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ];
- "rfr" = [
- "[[#rfr110390d1]]"
- ];
- "src" = [
- {
- "c" = "scm"
- }
- ];
- "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
- }
- ]
-}
-)";
-
-constexpr auto Steps = 10000U;
-
-Y_UNIT_TEST_SUITE(TYsonTests) {
- Y_UNIT_TEST(TestValidate) {
- UNIT_ASSERT(IsValidYson(yson));
-
- UNIT_ASSERT(!IsValidYson("[123}"));
- UNIT_ASSERT(!IsValidYson("[123];[456]"));
- UNIT_ASSERT(!IsValidYson(R"({"c" = "scm"])"));
- UNIT_ASSERT(!IsValidYson(""));
- UNIT_ASSERT(!IsValidYson(R"({"c";})"));
- UNIT_ASSERT(!IsValidYson(R"({# = "scm"})"));
- UNIT_ASSERT(!IsValidYson(R"({'one'= 1})"));
- }
-
- Y_UNIT_TEST(TestPerfValidate) {
- const auto t = TInstant::Now();
- for (auto i = 0U; i < Steps; ++i) {
- UNIT_ASSERT(IsValidYson(yson));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfParse) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = TryParseYsonDom(yson, &builder));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfSerialize) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- const auto dom = TryParseYsonDom(yson, &builder);
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToBinary(dom)));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfSerializeText) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- const auto dom = TryParseYsonDom(yson, &builder);
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToText(dom)));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-
- Y_UNIT_TEST(TestPerfSerializePrettyText) {
- NMiniKQL::TScopedAlloc alloc;
- NMiniKQL::TMemoryUsageInfo memInfo("Memory");
- NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
- NMiniKQL::TDefaultValueBuilder builder(holderFactory);
-
- const auto dom = TryParseYsonDom(yson, &builder);
- std::array<NUdf::TUnboxedValue, Steps> v;
-
- const auto t = TInstant::Now();
- for (auto& i : v) {
- UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToPrettyText(dom)));
- }
- const auto time = TInstant::Now() - t;
- Cerr << "Time is " << time << Endl;
- }
-}
+
+using namespace NYql;
+using namespace NYql::NDom;
+using namespace NKikimr;
+
+constexpr char yson[] =
+R"(
+{
+ "Fullname" = [
+ {
+ "freqs" = {
+ "sum_qf@de" = 28;
+ "sum_qf@en" = 8;
+ "sum_qf@ru" = 10060;
+ "sum_qf@tr" = 91;
+ "sum_qf@uk" = 245;
+ "sum_qf@uz" = 6
+ };
+ "src" = [
+ {
+ "c" = "ltr"
+ }
+ ];
+ "value" = "Татьяна Сорокина"
+ }
+ ];
+ "Gender" = [
+ {
+ "src" = [
+ {
+ "c" = "yam";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "scm";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "ltr";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "lbr";
+ "is_guessed" = "True"
+ }
+ ];
+ "value" = "female"
+ }
+ ];
+ "Image" = [
+ {
+ "RelevLocale" = [
+ "universe"
+ ];
+ "avatar_type" = "face";
+ "color_wiz" = {
+ "back" = "#DBC4B5";
+ "button" = "#BFAC9E";
+ "button_text" = "#23211E";
+ "text" = "#705549"
+ };
+ "faces_count" = 1;
+ "langua" = [
+ "uk";
+ "by";
+ "kk";
+ "ru"
+ ];
+ "mds_avatar_id" = "2001742/402534297";
+ "original_size" = {
+ "height" = 1478;
+ "width" = 1478
+ };
+ "show_on_serp" = %true;
+ "src" = [
+ {
+ "url" = "http://music.yandex.ru/artist/7945920";
+ "url_type" = "page";
+ "value" = "yam"
+ }
+ ];
+ "thumb" = "Face";
+ "type" = "image";
+ "url" = "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig";
+ "value" = "//avatars.yandex.net/get-music-content/113160/26f40ebf.a.8459289-1/orig"
+ }
+ ];
+ "ImageSearchRequest" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "by"
+ ];
+ "value" = "Сорокина Татьяна фото"
+ }
+ ];
+ "Key" = [
+ {
+ "langua" = [
+ "ru"
+ ];
+ "predict" = "972";
+ "rank" = 0;
+ "src" = [
+ {
+ "c" = "rut"
+ }
+ ];
+ "value" = "sorokina tatyana"
+ };
+ {
+ "freqs" = {
+ "sum_qf@de" = 3;
+ "sum_qf@en" = 2;
+ "sum_qf@ru" = 11504;
+ "sum_qf@tr" = 35;
+ "sum_qf@uk" = 145;
+ "sum_qf@uz" = 1
+ };
+ "langua" = [
+ "ru"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ };
+ {
+ "c" = "ltr"
+ };
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "сорокина татьяна"
+ };
+ {
+ "langua" = [
+ "ru"
+ ];
+ "predict" = "931";
+ "rank" = 1;
+ "src" = [
+ {
+ "c" = "rut"
+ }
+ ];
+ "value" = "tatiana sorokina"
+ };
+ {
+ "langua" = [
+ "ru"
+ ];
+ "predict" = "951";
+ "rank" = 0;
+ "src" = [
+ {
+ "c" = "rut"
+ }
+ ];
+ "value" = "tatyana sorokina"
+ };
+ {
+ "freqs" = {
+ "SenseRatio" = 0.01;
+ "SenseRatio@de" = 0.5;
+ "SenseRatio@en" = 0.5;
+ "SenseRatio@et" = 0.5;
+ "SenseRatio@fi" = 0.5;
+ "SenseRatio@id" = 0.5;
+ "SenseRatio@kk" = 0.5;
+ "SenseRatio@lt" = 0.5;
+ "SenseRatio@lv" = 0.5;
+ "SenseRatio@pl" = 0.5;
+ "SenseRatio@ru" = 0;
+ "SenseRatio@tr" = 0.5;
+ "SenseRatio@uk" = 0.5;
+ "SenseRatio@uz" = 0.5;
+ "sum_qf@de" = 28;
+ "sum_qf@en" = 8;
+ "sum_qf@ru" = 10060;
+ "sum_qf@tr" = 91;
+ "sum_qf@uk" = 245;
+ "sum_qf@uz" = 6
+ };
+ "langua" = [
+ "ru"
+ ];
+ "src" = [
+ {
+ "c" = "scm";
+ "name" = "bookmate.com"
+ };
+ {
+ "c" = "yam"
+ };
+ {
+ "c" = "ltr"
+ }
+ ];
+ "value" = "татьяна сорокина"
+ }
+ ];
+ "Projects" = [
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 256643
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ };
+ {
+ "Role" = [
+ "MAIN_ARTIST"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 54092
+ };
+ "hint_description" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "tr";
+ "by"
+ ];
+ "value" = "2019"
+ }
+ ];
+ "otype" = "Music/Album@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
+ };
+ {
+ "Role" = "Author@on";
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm540668de..0|История медицины]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 49611
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm540668de..0|История медицины]]"
+ };
+ {
+ "Role" = "Author@on";
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
+ }
+ ];
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21522
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "hint_description" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "tr";
+ "by"
+ ];
+ "value" = "2015"
+ }
+ ];
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "ltr"
+ };
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#ltr08920335]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrbs464788|Пейп-арт]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 12676
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#lbrbs464788]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#lbrbs137089]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb464788|Пейп-арт]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 12676
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb464788|Пейп-арт]]"
+ };
+ {
+ "Role" = [
+ "Artist@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb274279|Что сначала,что потом?]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 15
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb274279|Что сначала,что потом?]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21
+ };
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 1431963
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 34699
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845756|Я – мама]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 441
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845756|Я – мама]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 152646
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 16331217
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 94
+ };
+ "otype" = "Music/Recording@on";
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ };
+ {
+ "Role" = "Author@on";
+ "carousel" = "False";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "report" = "False";
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "SearchRequest" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "by"
+ ];
+ "value" = "Сорокина Татьяна"
+ }
+ ];
+ "Title" = [
+ {
+ "freqs" = {
+ "sum_qf@de" = 3;
+ "sum_qf@en" = 2;
+ "sum_qf@ru" = 11504;
+ "sum_qf@tr" = 35;
+ "sum_qf@uk" = 145;
+ "sum_qf@uz" = 1
+ };
+ "langua" = [
+ "ru"
+ ];
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "Сорокина Татьяна"
+ };
+ {
+ "RelevLocale" = [
+ "kz";
+ "ua";
+ "by";
+ "ru"
+ ];
+ "freqs" = {
+ "sum_qf@de" = 28;
+ "sum_qf@en" = 8;
+ "sum_qf@ru" = 10060;
+ "sum_qf@tr" = 91;
+ "sum_qf@uk" = 245;
+ "sum_qf@uz" = 6
+ };
+ "langua" = [
+ "ru"
+ ];
+ "src" = [
+ {
+ "c" = "scm";
+ "name" = "bookmate.com"
+ };
+ {
+ "c" = "yam"
+ };
+ {
+ "c" = "ltr"
+ }
+ ];
+ "value" = "Татьяна Сорокина"
+ }
+ ];
+ "TopTracks" = [
+ {
+ "Position" = 9;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ };
+ {
+ "Position" = 8;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ };
+ {
+ "Position" = 7;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ };
+ {
+ "Position" = 6;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ };
+ {
+ "Position" = 5;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ };
+ {
+ "Position" = 4;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ };
+ {
+ "Position" = 3;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ };
+ {
+ "Position" = 2;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ };
+ {
+ "Position" = 1;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ };
+ {
+ "Position" = 0;
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ }
+ ];
+ "langua" = [
+ "uk";
+ "ru";
+ "kk";
+ "by"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ }
+ ];
+ "freqs" = {
+ "average_proper_ratio" = [
+ "1.00"
+ ];
+ "proper_ratio" = [
+ {
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "1.00"
+ }
+ ];
+ "sum_qf@de" = [
+ "31"
+ ];
+ "sum_qf@en" = [
+ "10"
+ ];
+ "sum_qf@ru" = [
+ "21572"
+ ];
+ "sum_qf@tr" = [
+ "126"
+ ];
+ "sum_qf@uk" = [
+ "390"
+ ];
+ "sum_qf@uz" = [
+ "7"
+ ]
+ };
+ "fullname" = [
+ {
+ "freqs" = {
+ "sum_qf@de" = 28;
+ "sum_qf@en" = 8;
+ "sum_qf@ru" = 10060;
+ "sum_qf@tr" = 91;
+ "sum_qf@uk" = 245;
+ "sum_qf@uz" = 6
+ };
+ "rfr" = [
+ "[[#rfr21731b2]]"
+ ];
+ "src" = [
+ {
+ "c" = "ltr"
+ }
+ ];
+ "value" = "Татьяна Сорокина"
+ }
+ ];
+ "human_gender" = [
+ {
+ "rfr" = [
+ "[[#rfr21f0d779]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "scm";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "ltr";
+ "is_guessed" = "True"
+ };
+ {
+ "c" = "lbr";
+ "is_guessed" = "True"
+ }
+ ];
+ "value" = "female"
+ }
+ ];
+ "ids" = [
+ {
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "http://music.yandex.ru/artist/7945920"
+ };
+ {
+ "src" = [
+ {
+ "c" = "ltr"
+ }
+ ];
+ "value" = "https://www.litres.ru/4815845"
+ };
+ {
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "http://www.labirint.ru/authors/43298"
+ }
+ ];
+ "isa" = {
+ "Wtype" = "Hum";
+ "otype" = [
+ {
+ "src" = [
+ {
+ "c" = "yam"
+ };
+ {
+ "c" = "scm"
+ };
+ {
+ "c" = "ltr"
+ };
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "Hum"
+ }
+ ]
+ };
+ "merged_ontoids" = [
+ "ltr24815845";
+ "scmbookmatecomh7b363cfd07a49aed419fde3dbd010f64";
+ "lbrh43298";
+ "yam17945920"
+ ];
+ "musical_artist_groups" = [
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 256643
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845750|Наши дети]]"
+ };
+ {
+ "Role" = [
+ "MAIN_ARTIST"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 54092
+ };
+ "hint_description" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "tr";
+ "by"
+ ];
+ "value" = "2019"
+ }
+ ];
+ "otype" = "Music/Album@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam08459289|Сто дорог, одна – моя]]"
+ };
+ {
+ "Role" = "Author@on";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm540668de..0|История медицины]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 49611
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm540668de..0|История медицины]]"
+ };
+ {
+ "Role" = "Author@on";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
+ }
+ ];
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm-3f1fcad4..0|Мыколка]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21522
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845751|100 дорог]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#ltr08920335|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "hint_description" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "tr";
+ "by"
+ ];
+ "value" = "2015"
+ }
+ ];
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "ltr"
+ };
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#ltr08920335]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrbs464788|Пейп-арт]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 12676
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#lbrbs464788]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrbs137089|Филиальная сеть: развитие и управление]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr"
+ }
+ ];
+ "value" = "[[#lbrbs137089]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb467470|Система дистрибуции. Инструменты создания конкурентного преимущества]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb464788|Пейп-арт]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 12676
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb464788|Пейп-арт]]"
+ };
+ {
+ "Role" = [
+ "Artist@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb274279|Что сначала,что потом?]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 15
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb274279|Что сначала,что потом?]]"
+ };
+ {
+ "Role" = [
+ "Author@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 21
+ };
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "lbr";
+ "f" = "book"
+ }
+ ];
+ "value" = "[[#lbrb137089|Филиальная сеть: развитие и управление]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845752|Храни его]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 1431963
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845753|Удача]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 34699
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845754|Матушка Россия]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845755|Нежданное свидание]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845756|Я – мама]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 441
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845756|Я – мама]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ }
+ ];
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845757|Глупый сон]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 152646
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845760|Спасибо вам]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 16331217
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845758|С Днём рождения]]"
+ };
+ {
+ "Role" = [
+ "Performer@on"
+ ];
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ }
+ ];
+ "freqs" = {
+ "sum_qf" = 94
+ };
+ "otype" = "Music/Recording@on";
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "yam"
+ }
+ ];
+ "value" = "[[#yam356845759|Песенка о мечтах]]"
+ };
+ {
+ "Role" = "Author@on";
+ "formatted" = [
+ {
+ "RelevLocale" = [
+ "ru";
+ "ua";
+ "by";
+ "kz"
+ ];
+ "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ];
+ "rfr" = [
+ "[[#rfr110390d1]]"
+ ];
+ "src" = [
+ {
+ "c" = "scm"
+ }
+ ];
+ "value" = "[[#scm-1eeb2744..0|Система дистрибуции: Инструменты создания конкурентного преимущества]]"
+ }
+ ]
+}
+)";
+
+constexpr auto Steps = 10000U;
+
+Y_UNIT_TEST_SUITE(TYsonTests) {
+ Y_UNIT_TEST(TestValidate) {
+ UNIT_ASSERT(IsValidYson(yson));
+
+ UNIT_ASSERT(!IsValidYson("[123}"));
+ UNIT_ASSERT(!IsValidYson("[123];[456]"));
+ UNIT_ASSERT(!IsValidYson(R"({"c" = "scm"])"));
+ UNIT_ASSERT(!IsValidYson(""));
+ UNIT_ASSERT(!IsValidYson(R"({"c";})"));
+ UNIT_ASSERT(!IsValidYson(R"({# = "scm"})"));
+ UNIT_ASSERT(!IsValidYson(R"({'one'= 1})"));
+ }
+
+ Y_UNIT_TEST(TestPerfValidate) {
+ const auto t = TInstant::Now();
+ for (auto i = 0U; i < Steps; ++i) {
+ UNIT_ASSERT(IsValidYson(yson));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfParse) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = TryParseYsonDom(yson, &builder));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfSerialize) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ const auto dom = TryParseYsonDom(yson, &builder);
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToBinary(dom)));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfSerializeText) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ const auto dom = TryParseYsonDom(yson, &builder);
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToText(dom)));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+
+ Y_UNIT_TEST(TestPerfSerializePrettyText) {
+ NMiniKQL::TScopedAlloc alloc;
+ NMiniKQL::TMemoryUsageInfo memInfo("Memory");
+ NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
+ NMiniKQL::TDefaultValueBuilder builder(holderFactory);
+
+ const auto dom = TryParseYsonDom(yson, &builder);
+ std::array<NUdf::TUnboxedValue, Steps> v;
+
+ const auto t = TInstant::Now();
+ for (auto& i : v) {
+ UNIT_ASSERT(i = builder.NewString(SerializeYsonDomToPrettyText(dom)));
+ }
+ const auto time = TInstant::Now() - t;
+ Cerr << "Time is " << time << Endl;
+ }
+}
diff --git a/ydb/library/yql/minikql/dom/ya.make b/ydb/library/yql/minikql/dom/ya.make
index 4afa33d856..d18bbe29e6 100644
--- a/ydb/library/yql/minikql/dom/ya.make
+++ b/ydb/library/yql/minikql/dom/ya.make
@@ -6,8 +6,8 @@ OWNER(
g:yql_ydb_core
)
-YQL_ABI_VERSION(2 21 0)
-
+YQL_ABI_VERSION(2 21 0)
+
PEERDIR(
library/cpp/containers/stack_vector
library/cpp/json
@@ -20,12 +20,12 @@ SRCS(
node.cpp
json.cpp
yson.cpp
- make.cpp
- peel.cpp
- hash.cpp
+ make.cpp
+ peel.cpp
+ hash.cpp
)
-END()
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/library/yql/minikql/dom/yson.cpp b/ydb/library/yql/minikql/dom/yson.cpp
index 720db94f81..f3ab30f22c 100644
--- a/ydb/library/yql/minikql/dom/yson.cpp
+++ b/ydb/library/yql/minikql/dom/yson.cpp
@@ -1,14 +1,14 @@
-#include "node.h"
+#include "node.h"
#include "yson.h"
#include <library/cpp/containers/stack_vector/stack_vec.h>
-
+
#include <library/cpp/yson_pull/exceptions.h>
#include <library/cpp/yson_pull/reader.h>
#include <library/cpp/yson_pull/writer.h>
-#include <util/string/builder.h>
-
+#include <util/string/builder.h>
+
namespace NYql::NDom {
using namespace NUdf;
@@ -17,28 +17,28 @@ using namespace NYsonPull;
namespace {
[[noreturn]] Y_NO_INLINE void UnexpectedEvent(EEventType ev) {
- UdfTerminate((::TStringBuilder() << "Unexpected event: " << ev).c_str());
+ UdfTerminate((::TStringBuilder() << "Unexpected event: " << ev).c_str());
}
-TUnboxedValuePod ParseScalar(const TScalar& scalar, const IValueBuilder* valueBuilder) {
+TUnboxedValuePod ParseScalar(const TScalar& scalar, const IValueBuilder* valueBuilder) {
switch (scalar.Type()) {
case EScalarType::Entity:
- return MakeEntity();
+ return MakeEntity();
case EScalarType::Boolean:
- return MakeBool(scalar.AsBoolean());
+ return MakeBool(scalar.AsBoolean());
case EScalarType::Int64:
- return MakeInt64(scalar.AsInt64());
+ return MakeInt64(scalar.AsInt64());
case EScalarType::UInt64:
- return MakeUint64(scalar.AsUInt64());
+ return MakeUint64(scalar.AsUInt64());
case EScalarType::Float64:
- return MakeDouble(scalar.AsFloat64());
+ return MakeDouble(scalar.AsFloat64());
case EScalarType::String:
- return MakeString(scalar.AsString(), valueBuilder);
+ return MakeString(scalar.AsString(), valueBuilder);
}
}
@@ -64,8 +64,8 @@ TUnboxedValue ParseList(TReader& reader, const IValueBuilder* valueBuilder) {
case EEventType::Scalar:
items.emplace_back(ParseScalar(ev.AsScalar(), valueBuilder));
break;
- default:
- UnexpectedEvent(ev.Type());
+ default:
+ UnexpectedEvent(ev.Type());
}
}
}
@@ -94,8 +94,8 @@ TUnboxedValue ParseDict(TReader& reader, const IValueBuilder* valueBuilder) {
case EEventType::Scalar:
items.emplace_back(std::make_pair(std::move(key), ParseScalar(ev.AsScalar(), valueBuilder)));
break;
- default:
- UnexpectedEvent(ev.Type());
+ default:
+ UnexpectedEvent(ev.Type());
}
}
}
@@ -126,8 +126,8 @@ TUnboxedValue ParseAttributes(TReader& reader, const IValueBuilder* valueBuilder
case EEventType::Scalar:
items.emplace_back(std::make_pair(std::move(key), ParseScalar(ev.AsScalar(), valueBuilder)));
break;
- default:
- UnexpectedEvent(ev.Type());
+ default:
+ UnexpectedEvent(ev.Type());
}
}
@@ -143,165 +143,165 @@ TUnboxedValue ParseValue(TReader& reader, const IValueBuilder* valueBuilder) {
return ParseDict(reader, valueBuilder);
case EEventType::BeginAttributes:
return ParseAttributes(reader, valueBuilder);
- case EEventType::Scalar:
- return ParseScalar(ev.AsScalar(), valueBuilder);
- default:
+ case EEventType::Scalar:
+ return ParseScalar(ev.AsScalar(), valueBuilder);
+ default:
UnexpectedEvent(ev.Type());
- }
-}
-
-/////////////////////////////////////
-
-bool CheckValue(TReader& reader);
-
-bool CheckDict(TReader& reader) {
- for (;;) {
- const auto& evKey = reader.NextEvent();
- if (evKey.Type() == EEventType::EndMap)
- return true;
-
- if (evKey.Type() != EEventType::Key)
- return false;
-
- if (CheckValue(reader))
- continue;
- else
- return false;
- }
-}
-
-bool CheckAttributes(TReader& reader) {
- for (;;) {
- const auto& evKey = reader.NextEvent();
- if (evKey.Type() == EEventType::EndAttributes)
+ }
+}
+
+/////////////////////////////////////
+
+bool CheckValue(TReader& reader);
+
+bool CheckDict(TReader& reader) {
+ for (;;) {
+ const auto& evKey = reader.NextEvent();
+ if (evKey.Type() == EEventType::EndMap)
+ return true;
+
+ if (evKey.Type() != EEventType::Key)
+ return false;
+
+ if (CheckValue(reader))
+ continue;
+ else
+ return false;
+ }
+}
+
+bool CheckAttributes(TReader& reader) {
+ for (;;) {
+ const auto& evKey = reader.NextEvent();
+ if (evKey.Type() == EEventType::EndAttributes)
break;
-
- if (evKey.Type() != EEventType::Key)
- return false;
-
- if (CheckValue(reader))
- continue;
- else
- return false;
- }
-
- return CheckValue(reader);
-}
-
-bool CheckList(TReader& reader) {
- for (;;) {
- const auto& ev = reader.NextEvent();
- switch (ev.Type()) {
- case EEventType::BeginList:
- if (CheckList(reader))
- break;
- else
- return false;
- case EEventType::BeginMap:
- if (CheckDict(reader))
- break;
- else
- return false;
- case EEventType::BeginAttributes:
- if (CheckAttributes(reader))
- break;
- else
- return false;
- case EEventType::Scalar:
- break;
- case EEventType::EndList:
- return true;
- default:
- return false;
- }
- }
-}
-
-bool CheckValue(TReader& reader) {
- const auto& ev = reader.NextEvent();
- switch (ev.Type()) {
- case EEventType::BeginList:
- if (CheckList(reader))
- break;
- else
- return false;
- case EEventType::BeginMap:
- if (CheckDict(reader))
- break;
- else
- return false;
- case EEventType::BeginAttributes:
- if (CheckAttributes(reader))
- break;
- else
- return false;
- case EEventType::Scalar:
+
+ if (evKey.Type() != EEventType::Key)
+ return false;
+
+ if (CheckValue(reader))
+ continue;
+ else
+ return false;
+ }
+
+ return CheckValue(reader);
+}
+
+bool CheckList(TReader& reader) {
+ for (;;) {
+ const auto& ev = reader.NextEvent();
+ switch (ev.Type()) {
+ case EEventType::BeginList:
+ if (CheckList(reader))
+ break;
+ else
+ return false;
+ case EEventType::BeginMap:
+ if (CheckDict(reader))
+ break;
+ else
+ return false;
+ case EEventType::BeginAttributes:
+ if (CheckAttributes(reader))
+ break;
+ else
+ return false;
+ case EEventType::Scalar:
+ break;
+ case EEventType::EndList:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
+
+bool CheckValue(TReader& reader) {
+ const auto& ev = reader.NextEvent();
+ switch (ev.Type()) {
+ case EEventType::BeginList:
+ if (CheckList(reader))
+ break;
+ else
+ return false;
+ case EEventType::BeginMap:
+ if (CheckDict(reader))
+ break;
+ else
+ return false;
+ case EEventType::BeginAttributes:
+ if (CheckAttributes(reader))
+ break;
+ else
+ return false;
+ case EEventType::Scalar:
break;
- default:
- return false;
+ default:
+ return false;
}
- return true;
+ return true;
}
void WriteValue(TWriter& writer, const TUnboxedValue& x) {
- switch (GetNodeType(x)) {
- case ENodeType::String:
- writer.String(x.AsStringRef());
- break;
- case ENodeType::Bool:
- writer.Boolean(x.Get<bool>());
- break;
- case ENodeType::Int64:
- writer.Int64(x.Get<i64>());
- break;
- case ENodeType::Uint64:
- writer.UInt64(x.Get<ui64>());
- break;
- case ENodeType::Double:
- writer.Float64(x.Get<double>());
- break;
- case ENodeType::Entity:
- writer.Entity();
- break;
- case ENodeType::List:
+ switch (GetNodeType(x)) {
+ case ENodeType::String:
+ writer.String(x.AsStringRef());
+ break;
+ case ENodeType::Bool:
+ writer.Boolean(x.Get<bool>());
+ break;
+ case ENodeType::Int64:
+ writer.Int64(x.Get<i64>());
+ break;
+ case ENodeType::Uint64:
+ writer.UInt64(x.Get<ui64>());
+ break;
+ case ENodeType::Double:
+ writer.Float64(x.Get<double>());
+ break;
+ case ENodeType::Entity:
+ writer.Entity();
+ break;
+ case ENodeType::List:
writer.BeginList();
- if (x.IsBoxed()) {
- if (const auto elements = x.GetElements()) {
- const auto size = x.GetListLength();
- for (ui64 i = 0; i < size; ++i) {
- WriteValue(writer, elements[i]);
- }
- } else {
- const auto it = x.GetListIterator();
- for (TUnboxedValue v; it.Next(v); WriteValue(writer, v))
- continue;
- }
+ if (x.IsBoxed()) {
+ if (const auto elements = x.GetElements()) {
+ const auto size = x.GetListLength();
+ for (ui64 i = 0; i < size; ++i) {
+ WriteValue(writer, elements[i]);
+ }
+ } else {
+ const auto it = x.GetListIterator();
+ for (TUnboxedValue v; it.Next(v); WriteValue(writer, v))
+ continue;
+ }
}
writer.EndList();
break;
- case ENodeType::Dict:
+ case ENodeType::Dict:
writer.BeginMap();
- if (x.IsBoxed()) {
- TUnboxedValue key, payload;
- for (const auto it = x.GetDictIterator(); it.NextPair(key, payload);) {
- writer.Key(key.AsStringRef());
- WriteValue(writer, payload);
- }
+ if (x.IsBoxed()) {
+ TUnboxedValue key, payload;
+ for (const auto it = x.GetDictIterator(); it.NextPair(key, payload);) {
+ writer.Key(key.AsStringRef());
+ WriteValue(writer, payload);
+ }
}
writer.EndMap();
break;
- case ENodeType::Attr: {
+ case ENodeType::Attr: {
writer.BeginAttributes();
TUnboxedValue key, payload;
- for (const auto it = x.GetDictIterator(); it.NextPair(key, payload);) {
+ for (const auto it = x.GetDictIterator(); it.NextPair(key, payload);) {
writer.Key(key.AsStringRef());
WriteValue(writer, payload);
}
writer.EndAttributes();
WriteValue(writer, x.GetVariantItem());
- }
- break;
+ }
+ break;
}
}
@@ -323,19 +323,19 @@ NUdf::TUnboxedValue TryParseYsonDom(const TStringBuf yson, const NUdf::IValueBui
return value;
}
-bool IsValidYson(const TStringBuf yson) try {
- auto reader = TReader(NInput::FromMemory(yson), EStreamType::Node);
- const auto& begin = reader.NextEvent();
- if (begin.Type() != EEventType::BeginStream)
- return false;
- if (!CheckValue(reader))
- return false;
- const auto& end = reader.NextEvent();
- return end.Type() == EEventType::EndStream;
-} catch (const NException::TBadStream&) {
- return false;
-}
-
+bool IsValidYson(const TStringBuf yson) try {
+ auto reader = TReader(NInput::FromMemory(yson), EStreamType::Node);
+ const auto& begin = reader.NextEvent();
+ if (begin.Type() != EEventType::BeginStream)
+ return false;
+ if (!CheckValue(reader))
+ return false;
+ const auto& end = reader.NextEvent();
+ return end.Type() == EEventType::EndStream;
+} catch (const NException::TBadStream&) {
+ return false;
+}
+
TString SerializeYsonDomToBinary(const NUdf::TUnboxedValue& dom) {
TString result;
TWriter writer = MakeBinaryWriter(NOutput::FromString(&result), EStreamType::Node);
diff --git a/ydb/library/yql/minikql/dom/yson.h b/ydb/library/yql/minikql/dom/yson.h
index b91dfac6f1..aba5077699 100644
--- a/ydb/library/yql/minikql/dom/yson.h
+++ b/ydb/library/yql/minikql/dom/yson.h
@@ -5,8 +5,8 @@
namespace NYql::NDom {
-bool IsValidYson(const TStringBuf yson);
-
+bool IsValidYson(const TStringBuf yson);
+
NUdf::TUnboxedValue TryParseYsonDom(const TStringBuf yson, const NUdf::IValueBuilder* valueBuilder);
TString SerializeYsonDomToBinary(const NUdf::TUnboxedValue& dom);
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp
index ff3eee40cc..ab991842f1 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp
@@ -1,18 +1,18 @@
#include "mkql_builtins_impl.h"
-#include "mkql_builtins_compare.h"
-
+#include "mkql_builtins_compare.h"
+
#include <util/digest/murmur.h>
#include <util/generic/yexception.h>
-#include <util/generic/maybe.h>
+#include <util/generic/maybe.h>
+
+#include <algorithm>
-#include <algorithm>
-
namespace NKikimr {
namespace NMiniKQL {
namespace {
-void RegisterDefaultOperations(IBuiltinFunctionRegistry& registry) {
+void RegisterDefaultOperations(IBuiltinFunctionRegistry& registry) {
RegisterAdd(registry);
RegisterAggrAdd(registry);
RegisterSub(registry);
@@ -36,27 +36,27 @@ void RegisterDefaultOperations(IBuiltinFunctionRegistry& registry) {
RegisterConvert(registry);
RegisterConcat(registry);
RegisterSubstring(registry);
- RegisterFind(registry);
- RegisterWith(registry);
+ RegisterFind(registry);
+ RegisterWith(registry);
RegisterInversePresortString(registry);
RegisterInverseString(registry);
RegisterNanvl(registry);
RegisterByteAt(registry);
- RegisterMax(registry);
- RegisterMin(registry);
- RegisterAggrMax(registry);
- RegisterAggrMin(registry);
- RegisterEquals(registry);
- RegisterNotEquals(registry);
- RegisterLess(registry);
- RegisterLessOrEqual(registry);
- RegisterGreater(registry);
- RegisterGreaterOrEqual(registry);
+ RegisterMax(registry);
+ RegisterMin(registry);
+ RegisterAggrMax(registry);
+ RegisterAggrMin(registry);
+ RegisterEquals(registry);
+ RegisterNotEquals(registry);
+ RegisterLess(registry);
+ RegisterLessOrEqual(registry);
+ RegisterGreater(registry);
+ RegisterGreaterOrEqual(registry);
}
-void PrintType(NUdf::TDataTypeId schemeType, bool isOptional, IOutputStream& out)
+void PrintType(NUdf::TDataTypeId schemeType, bool isOptional, IOutputStream& out)
{
- const auto slot = NUdf::FindDataSlot(schemeType);
+ const auto slot = NUdf::FindDataSlot(schemeType);
out << (slot ? NUdf::GetDataTypeInfo(*slot).Name : "unknown");
if (isOptional) {
@@ -65,11 +65,11 @@ void PrintType(NUdf::TDataTypeId schemeType, bool isOptional, IOutputStream& out
}
void PrintFunctionSignature(
- const std::string_view& funcName,
+ const std::string_view& funcName,
const TFunctionDescriptor& desc,
IOutputStream& out)
{
- const auto* param = desc.ResultAndArgs;
+ const auto* param = desc.ResultAndArgs;
out << '\t';
// print results type
@@ -85,7 +85,7 @@ void PrintFunctionSignature(
out << ", ";
}
}
- out << ')';
+ out << ')';
}
bool IsArgumentsMatch(
@@ -114,94 +114,94 @@ bool IsArgumentsMatch(
return index == argTypesCount;
}
-//////////////////////////////////////////////////////////////////////////////
-// TBuiltinFunctionRegistry
-//////////////////////////////////////////////////////////////////////////////
-class TBuiltinFunctionRegistry: public IBuiltinFunctionRegistry
-{
-public:
- TBuiltinFunctionRegistry();
-
-private:
- TFunctionDescriptor GetBuiltin(const std::string_view& name,
- const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const final;
-
- bool HasBuiltin(const std::string_view& name) const final;
-
- ui64 GetMetadataEtag() const final;
-
- void PrintInfoTo(IOutputStream& out) const final;
-
- void Register(const std::string_view& name, const TFunctionDescriptor& description) final;
-
- void RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments) final;
-
- const TFunctionsMap& GetFunctions() const final;
-
- void CalculateMetadataEtag();
-
- std::optional<TFunctionDescriptor> FindBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const;
-
- const TDescriptionList& FindCandidates(const std::string_view& name) const;
-
- TFunctionsMap Functions;
- TFunctionParamMetadataList ArgumentsMetadata;
- std::optional<ui64> MetadataEtag;
-};
-
+//////////////////////////////////////////////////////////////////////////////
+// TBuiltinFunctionRegistry
+//////////////////////////////////////////////////////////////////////////////
+class TBuiltinFunctionRegistry: public IBuiltinFunctionRegistry
+{
+public:
+ TBuiltinFunctionRegistry();
+
+private:
+ TFunctionDescriptor GetBuiltin(const std::string_view& name,
+ const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const final;
+
+ bool HasBuiltin(const std::string_view& name) const final;
+
+ ui64 GetMetadataEtag() const final;
+
+ void PrintInfoTo(IOutputStream& out) const final;
+
+ void Register(const std::string_view& name, const TFunctionDescriptor& description) final;
+
+ void RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments) final;
+
+ const TFunctionsMap& GetFunctions() const final;
+
+ void CalculateMetadataEtag();
+
+ std::optional<TFunctionDescriptor> FindBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const;
+
+ const TDescriptionList& FindCandidates(const std::string_view& name) const;
+
+ TFunctionsMap Functions;
+ TFunctionParamMetadataList ArgumentsMetadata;
+ std::optional<ui64> MetadataEtag;
+};
+
TBuiltinFunctionRegistry::TBuiltinFunctionRegistry()
{
RegisterDefaultOperations(*this);
CalculateMetadataEtag();
}
-void TBuiltinFunctionRegistry::Register(const std::string_view& name, const TFunctionDescriptor& description)
+void TBuiltinFunctionRegistry::Register(const std::string_view& name, const TFunctionDescriptor& description)
{
- Functions[TString(name)].push_back(description);
+ Functions[TString(name)].push_back(description);
}
-void TBuiltinFunctionRegistry::RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments)
+void TBuiltinFunctionRegistry::RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments)
{
Functions = std::move(functions);
ArgumentsMetadata = std::move(arguments);
CalculateMetadataEtag();
}
-const TFunctionsMap& TBuiltinFunctionRegistry::GetFunctions() const
-{
- return Functions;
-}
-
-const TDescriptionList& TBuiltinFunctionRegistry::FindCandidates(const std::string_view& name) const {
- if (const auto it = Functions.find(TString(name)); it != Functions.cend())
- return it->second;
-
- ythrow yexception() << "Not found builtin function: '" << name << "' in " << Functions.size() << " total.";
+const TFunctionsMap& TBuiltinFunctionRegistry::GetFunctions() const
+{
+ return Functions;
}
-std::optional<TFunctionDescriptor> TBuiltinFunctionRegistry::FindBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const
+const TDescriptionList& TBuiltinFunctionRegistry::FindCandidates(const std::string_view& name) const {
+ if (const auto it = Functions.find(TString(name)); it != Functions.cend())
+ return it->second;
+
+ ythrow yexception() << "Not found builtin function: '" << name << "' in " << Functions.size() << " total.";
+}
+
+std::optional<TFunctionDescriptor> TBuiltinFunctionRegistry::FindBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const
{
- for (const auto& desc: FindCandidates(name)) {
- if (IsArgumentsMatch(desc.ResultAndArgs, argTypes, argTypesCount)) {
+ for (const auto& desc: FindCandidates(name)) {
+ if (IsArgumentsMatch(desc.ResultAndArgs, argTypes, argTypesCount)) {
return desc;
}
}
- return std::nullopt;
+ return std::nullopt;
}
-TFunctionDescriptor TBuiltinFunctionRegistry::GetBuiltin(const std::string_view& name,
+TFunctionDescriptor TBuiltinFunctionRegistry::GetBuiltin(const std::string_view& name,
const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const
{
- if (const auto desc = FindBuiltin(name, argTypes, argTypesCount)) {
+ if (const auto desc = FindBuiltin(name, argTypes, argTypesCount)) {
return *desc;
}
TStringStream ss;
- PrintType(argTypes[0].first, argTypes[0].second, ss);
- ss << ' ' << name << '(';
- for (size_t i = 1U; i < argTypesCount; i++) {
- if (i > 1U) {
+ PrintType(argTypes[0].first, argTypes[0].second, ss);
+ ss << ' ' << name << '(';
+ for (size_t i = 1U; i < argTypesCount; i++) {
+ if (i > 1U) {
ss << ", ";
}
PrintType(argTypes[i].first, argTypes[i].second, ss);
@@ -221,20 +221,20 @@ TFunctionDescriptor TBuiltinFunctionRegistry::GetBuiltin(const std::string_view&
ythrow yexception() << "Unsupported builtin function: " << ss.Str();
}
-bool TBuiltinFunctionRegistry::HasBuiltin(const std::string_view& name) const
+bool TBuiltinFunctionRegistry::HasBuiltin(const std::string_view& name) const
{
- return Functions.find(TString(name)) != Functions.cend();
+ return Functions.find(TString(name)) != Functions.cend();
}
void TBuiltinFunctionRegistry::CalculateMetadataEtag() {
- using TFunctionPair = std::pair<std::string_view, const TDescriptionList*>;
+ using TFunctionPair = std::pair<std::string_view, const TDescriptionList*>;
- std::vector<TFunctionPair> operations;
- for (const auto& func : Functions) {
- operations.emplace_back(func.first, &func.second);
+ std::vector<TFunctionPair> operations;
+ for (const auto& func : Functions) {
+ operations.emplace_back(func.first, &func.second);
}
- std::sort(operations.begin(), operations.end(), [](const TFunctionPair& x, const TFunctionPair& y) {
+ std::sort(operations.begin(), operations.end(), [](const TFunctionPair& x, const TFunctionPair& y) {
return x.first < y.first;
});
@@ -248,7 +248,7 @@ void TBuiltinFunctionRegistry::CalculateMetadataEtag() {
const ui64 descriptionCount = descriptions.size();
hash = MurmurHash<ui64>(&descriptionCount, sizeof(descriptionCount), hash);
for (const auto& description : descriptions) {
- for (const auto* args = description.ResultAndArgs; args->SchemeType; ++args) {
+ for (const auto* args = description.ResultAndArgs; args->SchemeType; ++args) {
hash = MurmurHash<ui64>(args, sizeof(*args), hash);
}
}
@@ -276,12 +276,12 @@ void TBuiltinFunctionRegistry::PrintInfoTo(IOutputStream& out) const
}
}
-} // namespace
-
-IBuiltinFunctionRegistry::TPtr CreateBuiltinRegistry() {
- return MakeIntrusive<TBuiltinFunctionRegistry>();
-}
-
-
+} // namespace
+
+IBuiltinFunctionRegistry::TPtr CreateBuiltinRegistry() {
+ return MakeIntrusive<TBuiltinFunctionRegistry>();
+}
+
+
} // namespace NMiniKQL
} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h
index 60601e6c22..3cec6d80c1 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.h
@@ -5,7 +5,7 @@
namespace NKikimr {
namespace NMiniKQL {
-IBuiltinFunctionRegistry::TPtr CreateBuiltinRegistry();
+IBuiltinFunctionRegistry::TPtr CreateBuiltinRegistry();
} // namspace NMiniKQL
} // namspace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp
index 8bcfa56405..ba308a35c6 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp
@@ -1,82 +1,82 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
+
+#include <cmath>
-#include <cmath>
-
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template <typename T, std::enable_if_t<std::is_unsigned<T>::value>* = nullptr>
-inline T Abs(T v) {
- return v;
-}
+template <typename T, std::enable_if_t<std::is_unsigned<T>::value>* = nullptr>
+inline T Abs(T v) {
+ return v;
+}
+
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
+inline T Abs(T v) {
+ return std::fabs(v);
+}
+
+template <typename T, std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value>* = nullptr>
+inline T Abs(T v) {
+ return std::abs(v);
+}
+
+template<typename TInput, typename TOutput>
+struct TAbs : public TSimpleArithmeticUnary<TInput, TOutput, TAbs<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return Abs<TInput>(val);
+ }
-template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
-inline T Abs(T v) {
- return std::fabs(v);
-}
-
-template <typename T, std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value>* = nullptr>
-inline T Abs(T v) {
- return std::abs(v);
-}
-
-template<typename TInput, typename TOutput>
-struct TAbs : public TSimpleArithmeticUnary<TInput, TOutput, TAbs<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return Abs<TInput>(val);
- }
-
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- if (std::is_unsigned<TInput>())
- return arg;
-
- if (std::is_floating_point<TInput>()) {
- auto& module = ctx.Codegen->GetModule();
- const auto fnType = FunctionType::get(arg->getType(), {arg->getType()}, false);
- const auto& name = GetFuncNameForType<TInput>("llvm.fabs");
+ static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ if (std::is_unsigned<TInput>())
+ return arg;
+
+ if (std::is_floating_point<TInput>()) {
+ auto& module = ctx.Codegen->GetModule();
+ const auto fnType = FunctionType::get(arg->getType(), {arg->getType()}, false);
+ const auto& name = GetFuncNameForType<TInput>("llvm.fabs");
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto res = CallInst::Create(func, {arg}, "fabs", block);
- return res;
- } else {
- const auto zero = ConstantInt::get(arg->getType(), 0);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, arg, zero, "check", block);
- const auto neg = BinaryOperator::CreateNeg(arg, "neg", block);
- const auto res = SelectInst::Create(check, neg, arg, "result", block);
- return res;
- }
- }
-#endif
-};
+ const auto res = CallInst::Create(func, {arg}, "fabs", block);
+ return res;
+ } else {
+ const auto zero = ConstantInt::get(arg->getType(), 0);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, arg, zero, "check", block);
+ const auto neg = BinaryOperator::CreateNeg(arg, "neg", block);
+ const auto res = SelectInst::Create(check, neg, arg, "result", block);
+ return res;
+ }
+ }
+#endif
+};
-struct TDecimalAbs {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- const auto a = arg.GetInt128();
- return a < 0 ? NUdf::TUnboxedValuePod(-a) : arg;
+struct TDecimalAbs {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ const auto a = arg.GetInt128();
+ return a < 0 ? NUdf::TUnboxedValuePod(-a) : arg;
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
static Value* Generate(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- const auto val = GetterForInt128(arg, block);
- const auto zero = ConstantInt::get(val->getType(), 0);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, zero, "check", block);
- const auto neg = BinaryOperator::CreateNeg(val, "neg", block);
- const auto res = SelectInst::Create(check, SetterForInt128(neg, block), arg, "result", block);
- return res;
- }
-#endif
+ {
+ const auto val = GetterForInt128(arg, block);
+ const auto zero = ConstantInt::get(val->getType(), 0);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, zero, "check", block);
+ const auto neg = BinaryOperator::CreateNeg(val, "neg", block);
+ const auto res = SelectInst::Create(check, SetterForInt128(neg, block), arg, "result", block);
+ return res;
+ }
+#endif
};
}
-void RegisterAbs(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryNumericFunctionOpt<TAbs, TUnaryArgsOpt>(registry, "Abs");
+void RegisterAbs(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryNumericFunctionOpt<TAbs, TUnaryArgsOpt>(registry, "Abs");
RegisterFunctionUnOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TAbs, TUnaryArgsOpt>(registry, "Abs");
- NDecimal::RegisterUnaryFunction<TDecimalAbs, TUnaryArgsOpt>(registry, "Abs");
+ NDecimal::RegisterUnaryFunction<TDecimalAbs, TUnaryArgsOpt>(registry, "Abs");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp
index 78c086cc23..ed2631bca4 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp
@@ -1,6 +1,6 @@
#include "mkql_builtins_impl.h"
-#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_datetime.h"
+#include "mkql_builtins_decimal.h"
#include <ydb/library/yql/minikql/mkql_type_ops.h>
@@ -9,111 +9,111 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TAdd : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TAdd<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left + right;
+template<typename TLeft, typename TRight, typename TOutput>
+struct TAdd : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TAdd<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left + right;
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_integral<TOutput>() ? BinaryOperator::CreateAdd(left, right, "add", block) : BinaryOperator::CreateFAdd(left, right, "add", block);
- }
-#endif
-};
-
-template<typename TType>
-using TAggrAdd = TAdd<TType, TType, TType>;
-
-template<ui8 Precision>
-struct TDecimalAdd {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- const auto a = l + r;
-
- using namespace NYql::NDecimal;
-
- if (IsNormal<Precision>(l) && IsNormal<Precision>(r) && IsNormal<Precision>(a))
- return NUdf::TUnboxedValuePod(a);
- if (IsNan(l) || IsNan(r) || !a)
- return NUdf::TUnboxedValuePod(Nan());
- else
- return NUdf::TUnboxedValuePod(a > 0 ? +Inf() : -Inf());
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_integral<TOutput>() ? BinaryOperator::CreateAdd(left, right, "add", block) : BinaryOperator::CreateFAdd(left, right, "add", block);
}
-
+#endif
+};
+
+template<typename TType>
+using TAggrAdd = TAdd<TType, TType, TType>;
+
+template<ui8 Precision>
+struct TDecimalAdd {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ const auto a = l + r;
+
+ using namespace NYql::NDecimal;
+
+ if (IsNormal<Precision>(l) && IsNormal<Precision>(r) && IsNormal<Precision>(a))
+ return NUdf::TUnboxedValuePod(a);
+ if (IsNan(l) || IsNan(r) || !a)
+ return NUdf::TUnboxedValuePod(Nan());
+ else
+ return NUdf::TUnboxedValuePod(a > 0 ? +Inf() : -Inf());
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto& bounds = NDecimal::GenBounds<Precision>(context);
-
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto add = BinaryOperator::CreateAdd(l, r, "add", block);
-
- const auto lok = NDecimal::GenInBounds(l, bounds.first, bounds.second, block);
- const auto rok = NDecimal::GenInBounds(r, bounds.first, bounds.second, block);
- const auto aok = NDecimal::GenInBounds(add, bounds.first, bounds.second, block);
-
- const auto bok = BinaryOperator::CreateAnd(lok, rok, "bok", block);
- const auto ok = BinaryOperator::CreateAnd(aok, bok, "ok", block);
-
- const auto bads = BasicBlock::Create(context, "bads", ctx.Func);
- const auto infs = BasicBlock::Create(context, "infs", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(add->getType(), 3, "result", done);
- result->addIncoming(add, block);
- BranchInst::Create(done, bads, ok, block);
-
- block = bads;
-
- const auto lnan = NDecimal::GenIsNonComparable(l, context, block);
- const auto rnan = NDecimal::GenIsNonComparable(r, context, block);
-
- const auto anan = BinaryOperator::CreateOr(lnan, rnan, "anan", block);
- const auto null = ConstantInt::get(add->getType(), 0);
- const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, add, null, "zero", block);
- const auto nan = BinaryOperator::CreateOr(anan, zero, "nan", block);
- result->addIncoming(GetDecimalNan(context), block);
- BranchInst::Create(done, infs, nan, block);
-
- block = infs;
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, add, null, "plus", block);
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- result->addIncoming(inf, block);
- BranchInst::Create(done, block);
-
- block = done;
- return SetterForInt128(result, block);
- }
-#endif
- static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto& bounds = NDecimal::GenBounds<Precision>(context);
+
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto add = BinaryOperator::CreateAdd(l, r, "add", block);
+
+ const auto lok = NDecimal::GenInBounds(l, bounds.first, bounds.second, block);
+ const auto rok = NDecimal::GenInBounds(r, bounds.first, bounds.second, block);
+ const auto aok = NDecimal::GenInBounds(add, bounds.first, bounds.second, block);
+
+ const auto bok = BinaryOperator::CreateAnd(lok, rok, "bok", block);
+ const auto ok = BinaryOperator::CreateAnd(aok, bok, "ok", block);
+
+ const auto bads = BasicBlock::Create(context, "bads", ctx.Func);
+ const auto infs = BasicBlock::Create(context, "infs", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(add->getType(), 3, "result", done);
+ result->addIncoming(add, block);
+ BranchInst::Create(done, bads, ok, block);
+
+ block = bads;
+
+ const auto lnan = NDecimal::GenIsNonComparable(l, context, block);
+ const auto rnan = NDecimal::GenIsNonComparable(r, context, block);
+
+ const auto anan = BinaryOperator::CreateOr(lnan, rnan, "anan", block);
+ const auto null = ConstantInt::get(add->getType(), 0);
+ const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, add, null, "zero", block);
+ const auto nan = BinaryOperator::CreateOr(anan, zero, "nan", block);
+ result->addIncoming(GetDecimalNan(context), block);
+ BranchInst::Create(done, infs, nan, block);
+
+ block = infs;
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, add, null, "plus", block);
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ result->addIncoming(inf, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return SetterForInt128(result, block);
+ }
+#endif
+ static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
};
-template<typename TLeft, typename TRight, typename TOutput, bool Tz = false>
-struct TDateTimeAddT {
- static_assert(std::is_integral<TLeft>::value, "left must be integral");
- static_assert(std::is_integral<TRight>::value, "right must be integral");
- static_assert(std::is_integral<TOutput>::value, "output must be integral");
+template<typename TLeft, typename TRight, typename TOutput, bool Tz = false>
+struct TDateTimeAddT {
+ static_assert(std::is_integral<TLeft>::value, "left must be integral");
+ static_assert(std::is_integral<TRight>::value, "right must be integral");
+ static_assert(std::is_integral<TOutput>::value, "output must be integral");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
- const auto lv = ToScaledDate<TLeft>(left.template Get<TLeft>());
- const auto rv = ToScaledDate<TRight>(right.template Get<TRight>());
- const auto ret = lv + rv;
+ const auto lv = ToScaledDate<TLeft>(left.template Get<TLeft>());
+ const auto rv = ToScaledDate<TRight>(right.template Get<TRight>());
+ const auto ret = lv + rv;
if (IsBadDateTime(ret)) {
return NUdf::TUnboxedValuePod();
}
auto data = NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));
- if (Tz) {
- data.SetTimezoneId((std::is_same<TLeft, NUdf::TDataType<NUdf::TInterval>::TLayout>() ? right : left).GetTimezoneId());
- }
+ if (Tz) {
+ data.SetTimezoneId((std::is_same<TLeft, NUdf::TDataType<NUdf::TInterval>::TLayout>() ? right : left).GetTimezoneId());
+ }
return data;
}
@@ -124,35 +124,35 @@ struct TDateTimeAddT {
const auto lhs = GenToScaledDate<TLeft>(GetterFor<TLeft>(left, context, block), context, block);
const auto rhs = GenToScaledDate<TRight>(GetterFor<TRight>(right, context, block), context, block);
const auto add = BinaryOperator::CreateAdd(lhs, rhs, "add", block);
- const auto wide = SetterFor<TOutput>(GenFromScaledDate<TOutput>(add, context, block), context, block);
+ const auto wide = SetterFor<TOutput>(GenFromScaledDate<TOutput>(add, context, block), context, block);
const auto bad = std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>() ?
GenIsBadInterval(add, context, block):
GenIsBadDateTime(add, context, block);
- const auto type = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(type, 0);
-
- if (Tz) {
- const uint64_t init[] = {0ULL, 0xFFFFULL};
- const auto mask = ConstantInt::get(type, APInt(128, 2, init));
- const auto tzid = BinaryOperator::CreateAnd(std::is_same<TLeft, NUdf::TDataType<NUdf::TInterval>::TLayout>() ? right : left, mask, "tzid", block);
- const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
- const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
- return sel;
- } else {
- const auto sel = SelectInst::Create(bad, zero, wide, "sel", block);
- return sel;
- }
-
+ const auto type = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(type, 0);
+
+ if (Tz) {
+ const uint64_t init[] = {0ULL, 0xFFFFULL};
+ const auto mask = ConstantInt::get(type, APInt(128, 2, init));
+ const auto tzid = BinaryOperator::CreateAnd(std::is_same<TLeft, NUdf::TDataType<NUdf::TInterval>::TLayout>() ? right : left, mask, "tzid", block);
+ const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
+ const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
+ return sel;
+ } else {
+ const auto sel = SelectInst::Create(bad, zero, wide, "sel", block);
+ return sel;
+ }
+
}
#endif
};
-template<typename TLeft, typename TRight, typename TOutput>
-using TDateTimeAdd = TDateTimeAddT<TLeft, TRight, TOutput, false>;
-
-template<typename TLeft, typename TRight, typename TOutput>
-using TDateTimeAddTz = TDateTimeAddT<TLeft, TRight, TOutput, true>;
-
+template<typename TLeft, typename TRight, typename TOutput>
+using TDateTimeAdd = TDateTimeAddT<TLeft, TRight, TOutput, false>;
+
+template<typename TLeft, typename TRight, typename TOutput>
+using TDateTimeAddTz = TDateTimeAddT<TLeft, TRight, TOutput, true>;
+
template <bool Tz, template<typename, typename, typename> class TAdder>
void RegisterAddDateAndInterval(IBuiltinFunctionRegistry& registry) {
using TDate1 = std::conditional_t<Tz, NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDate>>;
@@ -174,26 +174,26 @@ void RegisterAddDateAndInterval(IBuiltinFunctionRegistry& registry) {
TDate3, TAdder, TBinaryArgsOptWithNullableResult>(registry, "Add");
}
-template<typename TType>
-using TIntervalAggrAdd = TDateTimeAdd<TType, TType, TType>;
-
-}
-
-void RegisterAdd(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryNumericFunctionOpt<TAdd, TBinaryArgsOpt>(registry, "Add");
- NDecimal::RegisterBinaryFunctionForAllPrecisions<TDecimalAdd, TBinaryArgsOpt>(registry, "Add_");
+template<typename TType>
+using TIntervalAggrAdd = TDateTimeAdd<TType, TType, TType>;
+
+}
+
+void RegisterAdd(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryNumericFunctionOpt<TAdd, TBinaryArgsOpt>(registry, "Add");
+ NDecimal::RegisterBinaryFunctionForAllPrecisions<TDecimalAdd, TBinaryArgsOpt>(registry, "Add_");
RegisterAddDateAndInterval<false, TDateTimeAdd>(registry);
RegisterAddDateAndInterval<true, TDateTimeAddTz>(registry);
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TInterval>, TDateTimeAdd, TBinaryArgsOptWithNullableResult>(registry, "Add");
+ NUdf::TDataType<NUdf::TInterval>, TDateTimeAdd, TBinaryArgsOptWithNullableResult>(registry, "Add");
}
-void RegisterAggrAdd(IBuiltinFunctionRegistry& registry) {
- RegisterNumericAggregateFunction<TAggrAdd, TBinaryArgsSameOpt>(registry, "AggrAdd");
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval>, TIntervalAggrAdd, TBinaryArgsSameOptArgsWithNullableResult>(registry, "AggrAdd");
- NDecimal::RegisterAggregateFunctionForAllPrecisions<TDecimalAdd, TBinaryArgsSameOpt>(registry, "AggrAdd_");
+void RegisterAggrAdd(IBuiltinFunctionRegistry& registry) {
+ RegisterNumericAggregateFunction<TAggrAdd, TBinaryArgsSameOpt>(registry, "AggrAdd");
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval>, TIntervalAggrAdd, TBinaryArgsSameOptArgsWithNullableResult>(registry, "AggrAdd");
+ NDecimal::RegisterAggregateFunctionForAllPrecisions<TDecimalAdd, TBinaryArgsSameOpt>(registry, "AggrAdd_");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitand.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitand.cpp
index 8c81ccac84..cc5fd9dfd5 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitand.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitand.cpp
@@ -5,25 +5,25 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TBitAnd : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitAnd<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left & right;
- }
-
+template<typename TLeft, typename TRight, typename TOutput>
+struct TBitAnd : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitAnd<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left & right;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return BinaryOperator::CreateAnd(left, right, "and", block);
- }
-#endif
-};
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return BinaryOperator::CreateAnd(left, right, "and", block);
+ }
+#endif
+};
}
-void RegisterBitAnd(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryUnsignedFunctionOpt<TBitAnd, TBinaryArgsOpt>(registry, "BitAnd");
+void RegisterBitAnd(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryUnsignedFunctionOpt<TBitAnd, TBinaryArgsOpt>(registry, "BitAnd");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitnot.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitnot.cpp
index 3aec1deae2..ea4b552600 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitnot.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitnot.cpp
@@ -5,25 +5,25 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TBitNot : public TSimpleArithmeticUnary<TInput, TOutput, TBitNot<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return ~val;
- }
-
+template<typename TInput, typename TOutput>
+struct TBitNot : public TSimpleArithmeticUnary<TInput, TOutput, TBitNot<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return ~val;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- return BinaryOperator::CreateNot(arg, "not", block);
- }
-#endif
-};
+ static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
+ {
+ return BinaryOperator::CreateNot(arg, "not", block);
+ }
+#endif
+};
}
-void RegisterBitNot(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryUnsignedFunctionOpt<TBitNot, TUnaryArgsOpt>(registry, "BitNot");
+void RegisterBitNot(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryUnsignedFunctionOpt<TBitNot, TUnaryArgsOpt>(registry, "BitNot");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitor.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitor.cpp
index e1b9cf4dcb..757cf58f04 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitor.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitor.cpp
@@ -5,25 +5,25 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TBitOr : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitOr<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left | right;
- }
-
+template<typename TLeft, typename TRight, typename TOutput>
+struct TBitOr : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitOr<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left | right;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return BinaryOperator::CreateOr(left, right, "or", block);
- }
-#endif
-};
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return BinaryOperator::CreateOr(left, right, "or", block);
+ }
+#endif
+};
}
-void RegisterBitOr(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryUnsignedFunctionOpt<TBitOr, TBinaryArgsOpt>(registry, "BitOr");
+void RegisterBitOr(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryUnsignedFunctionOpt<TBitOr, TBinaryArgsOpt>(registry, "BitOr");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitxor.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitxor.cpp
index 49adabca0c..7c88f90143 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitxor.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_bitxor.cpp
@@ -5,25 +5,25 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TBitXor : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitXor<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left ^ right;
- }
-
+template<typename TLeft, typename TRight, typename TOutput>
+struct TBitXor : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TBitXor<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left ^ right;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return BinaryOperator::CreateXor(left, right, "xor", block);
- }
-#endif
-};
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return BinaryOperator::CreateXor(left, right, "xor", block);
+ }
+#endif
+};
}
-void RegisterBitXor(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryUnsignedFunctionOpt<TBitXor, TBinaryArgsOpt>(registry, "BitXor");
+void RegisterBitXor(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryUnsignedFunctionOpt<TBitXor, TBinaryArgsOpt>(registry, "BitXor");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_byteat.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_byteat.cpp
index 3fba63ebc2..613aff688c 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_byteat.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_byteat.cpp
@@ -19,103 +19,103 @@ const TFunctionParamMetadata TByteAtArgs<TInput, TOutput, IsOptional>::Value[4]
};
-template <typename TInput, typename TOutput>
-struct TByteAt {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
- {
- const auto& buffer = left.AsStringRef();
- const auto index = right.Get<ui32>();
- if (index >= buffer.Size()) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(ui8(buffer.Data()[index]));
+template <typename TInput, typename TOutput>
+struct TByteAt {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ {
+ const auto& buffer = left.AsStringRef();
+ const auto index = right.Get<ui32>();
+ if (index >= buffer.Size()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(ui8(buffer.Data()[index]));
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto type = Type::getInt8Ty(context);
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto type = Type::getInt8Ty(context);
const auto embType = FixedVectorType::get(type, 16);
- const auto cast = CastInst::Create(Instruction::BitCast, left, embType, "cast", block);
+ const auto cast = CastInst::Create(Instruction::BitCast, left, embType, "cast", block);
const auto mark = ExtractElementInst::Create(cast, ConstantInt::get(type, 15), "mark", block);
- const auto index = GetterFor<ui32>(right, context, block);
-
+ const auto index = GetterFor<ui32>(right, context, block);
+
const auto bsize = ExtractElementInst::Create(cast, ConstantInt::get(type, 14), "bsize", block);
- const auto esize = CastInst::Create(Instruction::ZExt, bsize, index->getType(), "esize", block);
-
- const auto sizeType = Type::getInt32Ty(context);
+ const auto esize = CastInst::Create(Instruction::ZExt, bsize, index->getType(), "esize", block);
+
+ const auto sizeType = Type::getInt32Ty(context);
const auto strType = FixedVectorType::get(sizeType, 4);
- const auto four = CastInst::Create(Instruction::BitCast, left, strType, "four", block);
+ const auto four = CastInst::Create(Instruction::BitCast, left, strType, "four", block);
const auto ssize = ExtractElementInst::Create(four, ConstantInt::get(type, 2), "ssize", block);
-
- const auto cemb = CastInst::Create(Instruction::Trunc, mark, Type::getInt1Ty(context), "cemb", block);
- const auto size = SelectInst::Create(cemb, esize, ssize, "size", block);
- const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "ok", block);
-
- const auto sel = BasicBlock::Create(context, "sel", ctx.Func);
- const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
- const auto str = BasicBlock::Create(context, "str", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto zero = ConstantInt::get(left->getType(), 0);
- const auto result = PHINode::Create(left->getType(), 4, "result", done);
- result->addIncoming(zero, block);
-
- BranchInst::Create(sel, done, ok, block);
- block = sel;
-
- result->addIncoming(zero, block);
- const auto choise = SwitchInst::Create(mark, done, 2, block);
- choise->addCase(ConstantInt::get(type, 1), emb);
- choise->addCase(ConstantInt::get(type, 2), str);
-
- {
- block = emb;
-
+
+ const auto cemb = CastInst::Create(Instruction::Trunc, mark, Type::getInt1Ty(context), "cemb", block);
+ const auto size = SelectInst::Create(cemb, esize, ssize, "size", block);
+ const auto ok = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, index, size, "ok", block);
+
+ const auto sel = BasicBlock::Create(context, "sel", ctx.Func);
+ const auto emb = BasicBlock::Create(context, "emb", ctx.Func);
+ const auto str = BasicBlock::Create(context, "str", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto zero = ConstantInt::get(left->getType(), 0);
+ const auto result = PHINode::Create(left->getType(), 4, "result", done);
+ result->addIncoming(zero, block);
+
+ BranchInst::Create(sel, done, ok, block);
+ block = sel;
+
+ result->addIncoming(zero, block);
+ const auto choise = SwitchInst::Create(mark, done, 2, block);
+ choise->addCase(ConstantInt::get(type, 1), emb);
+ choise->addCase(ConstantInt::get(type, 2), str);
+
+ {
+ block = emb;
+
const auto byte = ExtractElementInst::Create(cast, index, "byte", block);
- const auto full = SetterFor<ui8>(byte, context, block);
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
- }
-
- {
- block = str;
-
+ const auto full = SetterFor<ui8>(byte, context, block);
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+ }
+
+ {
+ block = str;
+
const auto foffs = ExtractElementInst::Create(four, ConstantInt::get(type, 3), "foffs", block);
- const auto offs = BinaryOperator::CreateAnd(foffs, ConstantInt::get(foffs->getType(), 0xFFFFFF), "offs", block);
- const auto skip = BinaryOperator::CreateAdd(offs, ConstantInt::get(offs->getType(), 16), "skip", block);
- const auto pos = BinaryOperator::CreateAdd(index, skip, "pos", block);
-
- const auto half = CastInst::Create(Instruction::Trunc, left, Type::getInt64Ty(context), "half", block);
- const auto ptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type) , "ptr", block);
-
- const auto bytePtr = GetElementPtrInst::CreateInBounds(ptr, {pos}, "bptr", block);
- const auto got = new LoadInst(bytePtr, "got", block);
- const auto make = SetterFor<ui8>(got, context, block);
- result->addIncoming(make, block);
- BranchInst::Create(done, block);
- }
-
- block = done;
- return result;
- }
-#endif
-};
+ const auto offs = BinaryOperator::CreateAnd(foffs, ConstantInt::get(foffs->getType(), 0xFFFFFF), "offs", block);
+ const auto skip = BinaryOperator::CreateAdd(offs, ConstantInt::get(offs->getType(), 16), "skip", block);
+ const auto pos = BinaryOperator::CreateAdd(index, skip, "pos", block);
+
+ const auto half = CastInst::Create(Instruction::Trunc, left, Type::getInt64Ty(context), "half", block);
+ const auto ptr = CastInst::Create(Instruction::IntToPtr, half, PointerType::getUnqual(type) , "ptr", block);
+
+ const auto bytePtr = GetElementPtrInst::CreateInBounds(ptr, {pos}, "bptr", block);
+ const auto got = new LoadInst(bytePtr, "got", block);
+ const auto make = SetterFor<ui8>(got, context, block);
+ result->addIncoming(make, block);
+ BranchInst::Create(done, block);
+ }
+
+ block = done;
+ return result;
+ }
+#endif
+};
}
-void RegisterByteAt(IBuiltinFunctionRegistry& registry) {
- const auto name = "ByteAt";
- RegisterFunctionImpl<TByteAt<NUdf::TDataType<char*>, NUdf::TDataType<ui8>>,
- TByteAtArgs<NUdf::TDataType<char*>, NUdf::TDataType<ui8>, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TByteAt<NUdf::TDataType<char*>, NUdf::TDataType<ui8>>,
- TByteAtArgs<NUdf::TDataType<char*>, NUdf::TDataType<ui8>, true>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TByteAt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>>,
- TByteAtArgs<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TByteAt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>>,
- TByteAtArgs<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>, true>, TBinaryWrap<true, false>>(registry, name);
+void RegisterByteAt(IBuiltinFunctionRegistry& registry) {
+ const auto name = "ByteAt";
+ RegisterFunctionImpl<TByteAt<NUdf::TDataType<char*>, NUdf::TDataType<ui8>>,
+ TByteAtArgs<NUdf::TDataType<char*>, NUdf::TDataType<ui8>, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TByteAt<NUdf::TDataType<char*>, NUdf::TDataType<ui8>>,
+ TByteAtArgs<NUdf::TDataType<char*>, NUdf::TDataType<ui8>, true>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TByteAt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>>,
+ TByteAtArgs<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TByteAt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>>,
+ TByteAtArgs<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<ui8>, true>, TBinaryWrap<true, false>>(registry, name);
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.cpp
index d475e1d16f..b086d250a6 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.cpp
@@ -1,246 +1,246 @@
-#include "mkql_builtins_codegen.h"
-
-#ifndef MKQL_DISABLE_CODEGEN
-#include <llvm/IR/Constants.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Instructions.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-using namespace llvm;
-
-Value* GenerateUnaryWithoutCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator) {
- return generator(arg, ctx, block);
-}
-
-Value* GenerateUnaryWithCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator) {
- auto& context = ctx.Codegen->GetContext();
- const auto valType = Type::getInt128Ty(context);
-
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, arg, zero, "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(zero, block);
-
- BranchInst::Create(done, good, check, block);
-
- block = good;
- const auto data = generator(arg, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
-}
-
-template<bool CheckLeft, bool CheckRight>
-Value* GenerateBinary(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valType, 0ULL);
-
- if (CheckLeft && CheckRight) {
- const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "tls", block);;
- const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "trs", block);;
- const auto check = BinaryOperator::CreateOr(tls, trs, "or", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(zero, block);
-
- BranchInst::Create(done, good, check, block);
-
- block = good;
- const auto data = generator(left, right, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else if (CheckLeft || CheckRight) {
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, CheckLeft ? left : right, zero, "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(zero, block);
-
- BranchInst::Create(done, good, check, block);
-
- block = good;
- const auto data = generator(left, right, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- return generator(left, right, ctx, block);
- }
-}
-
-Value* GenerateAggregate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valType, 0ULL);
-
- const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "tls", block);;
- const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "trs", block);;
- const auto check = BinaryOperator::CreateOr(tls, trs, "or", block);
-
- const auto null = BasicBlock::Create(context, "null", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
-
- BranchInst::Create(null, good, check, block);
-
- block = null;
- const auto both = BinaryOperator::CreateOr(left, right, "both", block);
- result->addIncoming(both, block);
- BranchInst::Create(done, block);
-
- block = good;
- const auto data = generator(left, right, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
-}
-
-Value* GenerateCompareAggregate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator, CmpInst::Predicate predicate) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(valType, 0ULL);
-
- const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, left, zero, "tls", block);
- const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, right, zero, "trs", block);
- const auto check = BinaryOperator::CreateAnd(tls, trs, "and", block);
-
- const auto null = BasicBlock::Create(context, "null", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
-
- BranchInst::Create(good, null, check, block);
-
- block = good;
- const auto data = generator(left, right, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = null;
- const auto test = CmpInst::Create(Instruction::ICmp, predicate, tls, trs, "test", block);
- const auto wide = MakeBoolean(test, context, block);
- result->addIncoming(wide, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
-}
-
-template<bool CheckFirst>
-Value* GenerateTernary(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator) {
- auto& context = ctx.Codegen->GetContext();
-
- const auto valType = Type::getInt128Ty(context);
-
- if (CheckFirst) {
- const auto zero = ConstantInt::get(valType, 0ULL);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, first, zero, "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(valType, 2, "result", done);
- result->addIncoming(zero, block);
-
- BranchInst::Create(done, good, check, block);
-
- block = good;
-
- const auto data = generator(first, second, third, ctx, block);
- result->addIncoming(data, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- } else {
- return generator(first, second, third, ctx, block);
- }
-}
-
-template Value* GenerateBinary<false, false>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-template Value* GenerateBinary<true, false>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-template Value* GenerateBinary<false, true>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-template Value* GenerateBinary<true, true>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-
-template Value* GenerateTernary<true>(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
-template Value* GenerateTernary<false>(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
-
-template<>
-std::string GetFuncNameForType<bool>(const char*) {
- return std::string(); // Stub for MSVC linker
-}
-
-template<>
-std::string GetFuncNameForType<i8>(const char* name) {
- return std::string(name) += ".i8";
-}
-
-template<>
-std::string GetFuncNameForType<ui8>(const char* name) {
- return std::string(name) += ".i8";
-}
-
-template<>
-std::string GetFuncNameForType<i16>(const char* name) {
- return std::string(name) += ".i16";
-}
-
-template<>
-std::string GetFuncNameForType<ui16>(const char* name) {
- return std::string(name) += ".i16";
-}
-
-template<>
-std::string GetFuncNameForType<i32>(const char* name) {
- return std::string(name) += ".i32";
-}
-
-template<>
-std::string GetFuncNameForType<ui32>(const char* name) {
- return std::string(name) += ".i32";
-}
-
-template<>
-std::string GetFuncNameForType<i64>(const char* name) {
- return std::string(name) += ".i64";
-}
-
-template<>
-std::string GetFuncNameForType<ui64>(const char* name) {
- return std::string(name) += ".i64";
-}
-
-template<>
-std::string GetFuncNameForType<float>(const char* name) {
- return std::string(name) += ".f32";
-}
-
-template<>
-std::string GetFuncNameForType<double>(const char* name) {
- return std::string(name) += ".f64";
-}
-
-}
-}
-#endif
+#include "mkql_builtins_codegen.h"
+
+#ifndef MKQL_DISABLE_CODEGEN
+#include <llvm/IR/Constants.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/Instructions.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+using namespace llvm;
+
+Value* GenerateUnaryWithoutCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator) {
+ return generator(arg, ctx, block);
+}
+
+Value* GenerateUnaryWithCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto valType = Type::getInt128Ty(context);
+
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, arg, zero, "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ BranchInst::Create(done, good, check, block);
+
+ block = good;
+ const auto data = generator(arg, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+}
+
+template<bool CheckLeft, bool CheckRight>
+Value* GenerateBinary(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valType, 0ULL);
+
+ if (CheckLeft && CheckRight) {
+ const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "tls", block);;
+ const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "trs", block);;
+ const auto check = BinaryOperator::CreateOr(tls, trs, "or", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ BranchInst::Create(done, good, check, block);
+
+ block = good;
+ const auto data = generator(left, right, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else if (CheckLeft || CheckRight) {
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, CheckLeft ? left : right, zero, "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ BranchInst::Create(done, good, check, block);
+
+ block = good;
+ const auto data = generator(left, right, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ return generator(left, right, ctx, block);
+ }
+}
+
+Value* GenerateAggregate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valType, 0ULL);
+
+ const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, left, zero, "tls", block);;
+ const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, right, zero, "trs", block);;
+ const auto check = BinaryOperator::CreateOr(tls, trs, "or", block);
+
+ const auto null = BasicBlock::Create(context, "null", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+
+ BranchInst::Create(null, good, check, block);
+
+ block = null;
+ const auto both = BinaryOperator::CreateOr(left, right, "both", block);
+ result->addIncoming(both, block);
+ BranchInst::Create(done, block);
+
+ block = good;
+ const auto data = generator(left, right, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+}
+
+Value* GenerateCompareAggregate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator, CmpInst::Predicate predicate) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(valType, 0ULL);
+
+ const auto tls = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, left, zero, "tls", block);
+ const auto trs = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, right, zero, "trs", block);
+ const auto check = BinaryOperator::CreateAnd(tls, trs, "and", block);
+
+ const auto null = BasicBlock::Create(context, "null", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+
+ BranchInst::Create(good, null, check, block);
+
+ block = good;
+ const auto data = generator(left, right, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = null;
+ const auto test = CmpInst::Create(Instruction::ICmp, predicate, tls, trs, "test", block);
+ const auto wide = MakeBoolean(test, context, block);
+ result->addIncoming(wide, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+}
+
+template<bool CheckFirst>
+Value* GenerateTernary(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator) {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto valType = Type::getInt128Ty(context);
+
+ if (CheckFirst) {
+ const auto zero = ConstantInt::get(valType, 0ULL);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, first, zero, "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(valType, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ BranchInst::Create(done, good, check, block);
+
+ block = good;
+
+ const auto data = generator(first, second, third, ctx, block);
+ result->addIncoming(data, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ } else {
+ return generator(first, second, third, ctx, block);
+ }
+}
+
+template Value* GenerateBinary<false, false>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+template Value* GenerateBinary<true, false>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+template Value* GenerateBinary<false, true>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+template Value* GenerateBinary<true, true>(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+
+template Value* GenerateTernary<true>(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
+template Value* GenerateTernary<false>(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
+
+template<>
+std::string GetFuncNameForType<bool>(const char*) {
+ return std::string(); // Stub for MSVC linker
+}
+
+template<>
+std::string GetFuncNameForType<i8>(const char* name) {
+ return std::string(name) += ".i8";
+}
+
+template<>
+std::string GetFuncNameForType<ui8>(const char* name) {
+ return std::string(name) += ".i8";
+}
+
+template<>
+std::string GetFuncNameForType<i16>(const char* name) {
+ return std::string(name) += ".i16";
+}
+
+template<>
+std::string GetFuncNameForType<ui16>(const char* name) {
+ return std::string(name) += ".i16";
+}
+
+template<>
+std::string GetFuncNameForType<i32>(const char* name) {
+ return std::string(name) += ".i32";
+}
+
+template<>
+std::string GetFuncNameForType<ui32>(const char* name) {
+ return std::string(name) += ".i32";
+}
+
+template<>
+std::string GetFuncNameForType<i64>(const char* name) {
+ return std::string(name) += ".i64";
+}
+
+template<>
+std::string GetFuncNameForType<ui64>(const char* name) {
+ return std::string(name) += ".i64";
+}
+
+template<>
+std::string GetFuncNameForType<float>(const char* name) {
+ return std::string(name) += ".f32";
+}
+
+template<>
+std::string GetFuncNameForType<double>(const char* name) {
+ return std::string(name) += ".f64";
+}
+
+}
+}
+#endif
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.h
index 92e6f5aca4..4e46a4d31e 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_codegen.h
@@ -1,36 +1,36 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node_codegen.h>
#include <ydb/library/yql/minikql/codegen/codegen.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-#ifndef MKQL_DISABLE_CODEGEN
-using namespace llvm;
-
-using TUnaryGenFunc = Value* (*)(Value*, const TCodegenContext&, BasicBlock*&);
-using TBinaryGenFunc = Value* (*)(Value*, Value*, const TCodegenContext&, BasicBlock*&);
-using TTernaryGenFunc = Value* (*)(Value*, Value*, Value*, const TCodegenContext&, BasicBlock*&);
-
-Value* GenerateUnaryWithoutCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator);
-Value* GenerateUnaryWithCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator);
-
-template<bool CheckLeft, bool CheckRight>
-Value* GenerateBinary(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-
-Value* GenerateAggregate(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
-
-Value* GenerateCompareAggregate(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator, CmpInst::Predicate simple);
-
-template<bool CheckFirst>
-Value* GenerateTernary(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
-
-template<typename T>
-std::string GetFuncNameForType(const char* name);
-
-#endif
-
-}
-}
-
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+#ifndef MKQL_DISABLE_CODEGEN
+using namespace llvm;
+
+using TUnaryGenFunc = Value* (*)(Value*, const TCodegenContext&, BasicBlock*&);
+using TBinaryGenFunc = Value* (*)(Value*, Value*, const TCodegenContext&, BasicBlock*&);
+using TTernaryGenFunc = Value* (*)(Value*, Value*, Value*, const TCodegenContext&, BasicBlock*&);
+
+Value* GenerateUnaryWithoutCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator);
+Value* GenerateUnaryWithCheck(Value* arg, const TCodegenContext& ctx, BasicBlock*& block, TUnaryGenFunc generator);
+
+template<bool CheckLeft, bool CheckRight>
+Value* GenerateBinary(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+
+Value* GenerateAggregate(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator);
+
+Value* GenerateCompareAggregate(Value* lhs, Value* rhs, const TCodegenContext& ctx, BasicBlock*& block, TBinaryGenFunc generator, CmpInst::Predicate simple);
+
+template<bool CheckFirst>
+Value* GenerateTernary(Value* first, Value* second, Value* third, const TCodegenContext& ctx, BasicBlock*& block, TTernaryGenFunc generator);
+
+template<typename T>
+std::string GetFuncNameForType(const char* name);
+
+#endif
+
+}
+}
+
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_compare.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_compare.h
index ee3f50e5ad..8d865b86d9 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_compare.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_compare.h
@@ -1,383 +1,383 @@
-#pragma once
-
-#include "mkql_builtins_impl.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-
-template <typename TLeft, typename TRight, class TImpl>
-struct TCompareArithmeticBinary : public TArithmeticConstraintsBinary<TLeft, TRight, bool> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto res = TImpl::Gen(lhs, rhs, ctx, block);
- const auto wide = MakeBoolean(res, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TLeft, typename TRight, class TImpl>
-struct TCompareArithmeticBinaryWithTimezone : public TArithmeticConstraintsBinary<TLeft, TRight, bool> {
- static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.template Get<TLeft>();
- const auto r = right.template Get<TRight>();
- return NUdf::TUnboxedValuePod(l == r ? TImpl::DoTz(left.GetTimezoneId(), right.GetTimezoneId()) : TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto equals = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
- const auto ltz = GetterForTimezone(context, left, block);
- const auto rtz = GetterForTimezone(context, right, block);
- const auto result = SelectInst::Create(equals, TImpl::GenTz(ltz, rtz, ctx, block), TImpl::Gen(lhs, rhs, ctx, block), "result", block);
- const auto wide = MakeBoolean(result, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TType, class TImpl>
-struct TSelectArithmeticBinaryCopyTimezone : public TArithmeticConstraintsBinary<TType, TType, bool> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return TImpl::Do(left.template Get<TType>(), right.template Get<TType>()) ? left : right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TType>(left, context, block);
- const auto rhs = GetterFor<TType>(right, context, block);
- const auto result = SelectInst::Create(TImpl::Gen(lhs, rhs, ctx, block), left, right, "result", block);
- return result;
- }
-#endif
-};
-
-template <typename TType, class TImpl>
-struct TSelectArithmeticBinaryWithTimezone : public TArithmeticConstraintsBinary<TType, TType, bool> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.template Get<TType>();
- const auto r = right.template Get<TType>();
- const bool choise = l == r ? TImpl::DoTz(left.GetTimezoneId(), right.GetTimezoneId()) : TImpl::Do(l, r);
- return choise ? left : right;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TType>(left, context, block);
- const auto rhs = GetterFor<TType>(right, context, block);
- const auto equals = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
- const auto ltz = GetterForTimezone(context, left, block);
- const auto rtz = GetterForTimezone(context, right, block);
- const auto choise = SelectInst::Create(equals, TImpl::GenTz(ltz, rtz, ctx, block), TImpl::Gen(lhs, rhs, ctx, block), "choise", block);
- const auto result = SelectInst::Create(choise, left, right, "result", block);
- return result;
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-int CompareCustoms(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) {
+#pragma once
+
+#include "mkql_builtins_impl.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+
+template <typename TLeft, typename TRight, class TImpl>
+struct TCompareArithmeticBinary : public TArithmeticConstraintsBinary<TLeft, TRight, bool> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto res = TImpl::Gen(lhs, rhs, ctx, block);
+ const auto wide = MakeBoolean(res, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, class TImpl>
+struct TCompareArithmeticBinaryWithTimezone : public TArithmeticConstraintsBinary<TLeft, TRight, bool> {
+ static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.template Get<TLeft>();
+ const auto r = right.template Get<TRight>();
+ return NUdf::TUnboxedValuePod(l == r ? TImpl::DoTz(left.GetTimezoneId(), right.GetTimezoneId()) : TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto equals = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
+ const auto ltz = GetterForTimezone(context, left, block);
+ const auto rtz = GetterForTimezone(context, right, block);
+ const auto result = SelectInst::Create(equals, TImpl::GenTz(ltz, rtz, ctx, block), TImpl::Gen(lhs, rhs, ctx, block), "result", block);
+ const auto wide = MakeBoolean(result, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TType, class TImpl>
+struct TSelectArithmeticBinaryCopyTimezone : public TArithmeticConstraintsBinary<TType, TType, bool> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return TImpl::Do(left.template Get<TType>(), right.template Get<TType>()) ? left : right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TType>(left, context, block);
+ const auto rhs = GetterFor<TType>(right, context, block);
+ const auto result = SelectInst::Create(TImpl::Gen(lhs, rhs, ctx, block), left, right, "result", block);
+ return result;
+ }
+#endif
+};
+
+template <typename TType, class TImpl>
+struct TSelectArithmeticBinaryWithTimezone : public TArithmeticConstraintsBinary<TType, TType, bool> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.template Get<TType>();
+ const auto r = right.template Get<TType>();
+ const bool choise = l == r ? TImpl::DoTz(left.GetTimezoneId(), right.GetTimezoneId()) : TImpl::Do(l, r);
+ return choise ? left : right;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TType>(left, context, block);
+ const auto rhs = GetterFor<TType>(right, context, block);
+ const auto equals = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
+ const auto ltz = GetterForTimezone(context, left, block);
+ const auto rtz = GetterForTimezone(context, right, block);
+ const auto choise = SelectInst::Create(equals, TImpl::GenTz(ltz, rtz, ctx, block), TImpl::Gen(lhs, rhs, ctx, block), "choise", block);
+ const auto result = SelectInst::Create(choise, left, right, "result", block);
+ return result;
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+int CompareCustoms(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) {
const TStringBuf lhsBuf = lhs.AsStringRef();
const TStringBuf rhsBuf = rhs.AsStringRef();
return lhsBuf.compare(rhsBuf);
-}
-
-template<NUdf::EDataSlot Slot>
-int CompareCustomsWithCleanup(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- const auto c = CompareCustoms<Slot>(left, right);
- left.DeleteUnreferenced();
- right.DeleteUnreferenced();
- return c;
-}
-
-
-template <typename TInput1, typename TInput2, bool IsLeftOptional, bool IsRightOptional, bool IsResultOptional>
-struct TCompareArgsOpt {
- static const TFunctionParamMetadata Value[4];
-};
-
-template <typename TInput1, typename TInput2, bool IsLeftOptional, bool IsRightOptional, bool IsResultOptional>
-const TFunctionParamMetadata TCompareArgsOpt<TInput1, TInput2, IsLeftOptional, IsRightOptional, IsResultOptional>::Value[4] = {
- { NUdf::TDataType<bool>::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
- { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
- { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
- { 0, 0 }
-};
-
-template <
- typename TInput1, typename TInput2,
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, false, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, false, true, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, true, false, true>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, true, true, true>, TBinaryWrap<true, true>>(registry, name);
-}
-
-template <
- typename TInput,
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrCompareOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TInput::TLayout, true>, TArgs<TInput, TInput, false, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TInput::TLayout, true>, TArgs<TInput, TInput, true, true, false>, TAggrCompareWrap>(registry, name);
-}
-
-template <
- typename TType1, typename TType2,
- class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareCustomOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, false, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, false, true, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, true, false, true>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, true, true, true>, TBinaryWrap<true, true>>(registry, name);
-}
-
-template <
- typename TType,
- class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrCompareCustomOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<TType, TType, false, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<TType, TType, true, true, false>, TAggrCompareWrap>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareUnsigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareSigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareSignedAndUnsigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareUnsignedAndSigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareReal(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareBool(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareOpt<NUdf::TDataType<bool>, NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareIntegral(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareSigned<TFunc, TArgs>(registry, name);
- RegisterCompareUnsigned<TFunc, TArgs>(registry, name);
- RegisterCompareSignedAndUnsigned<TFunc, TArgs>(registry, name);
- RegisterCompareUnsignedAndSigned<TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterComparePrimitive(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareBool<TFunc, TArgs>(registry, name);
- RegisterCompareReal<TFunc, TArgs>(registry, name);
- RegisterCompareIntegral<TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrComparePrimitive(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggrCompareOpt<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
-
- RegisterAggrCompareOpt<NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
-
- RegisterAggrCompareOpt<NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
-
- RegisterAggrCompareOpt<NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
-
- RegisterAggrCompareOpt<NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterAggrCompareOpt<NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterCompareDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+}
+
+template<NUdf::EDataSlot Slot>
+int CompareCustomsWithCleanup(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ const auto c = CompareCustoms<Slot>(left, right);
+ left.DeleteUnreferenced();
+ right.DeleteUnreferenced();
+ return c;
+}
+
+
+template <typename TInput1, typename TInput2, bool IsLeftOptional, bool IsRightOptional, bool IsResultOptional>
+struct TCompareArgsOpt {
+ static const TFunctionParamMetadata Value[4];
+};
+
+template <typename TInput1, typename TInput2, bool IsLeftOptional, bool IsRightOptional, bool IsResultOptional>
+const TFunctionParamMetadata TCompareArgsOpt<TInput1, TInput2, IsLeftOptional, IsRightOptional, IsResultOptional>::Value[4] = {
+ { NUdf::TDataType<bool>::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
+ { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
+ { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
+ { 0, 0 }
+};
+
+template <
+ typename TInput1, typename TInput2,
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, false, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, false, true, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, true, false, true>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, false>, TArgs<TInput1, TInput2, true, true, true>, TBinaryWrap<true, true>>(registry, name);
+}
+
+template <
+ typename TInput,
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrCompareOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TInput::TLayout, true>, TArgs<TInput, TInput, false, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TInput::TLayout, true>, TArgs<TInput, TInput, true, true, false>, TAggrCompareWrap>(registry, name);
+}
+
+template <
+ typename TType1, typename TType2,
+ class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareCustomOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, false, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, false, true, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, true, false, true>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<TType1, TType2, true, true, true>, TBinaryWrap<true, true>>(registry, name);
+}
+
+template <
+ typename TType,
+ class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrCompareCustomOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<TType, TType, false, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<TType, TType, true, true, false>, TAggrCompareWrap>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareUnsigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareSigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareSignedAndUnsigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareUnsignedAndSigned(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareReal(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareBool(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareOpt<NUdf::TDataType<bool>, NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareIntegral(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareSigned<TFunc, TArgs>(registry, name);
+ RegisterCompareUnsigned<TFunc, TArgs>(registry, name);
+ RegisterCompareSignedAndUnsigned<TFunc, TArgs>(registry, name);
+ RegisterCompareUnsignedAndSigned<TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterComparePrimitive(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareBool<TFunc, TArgs>(registry, name);
+ RegisterCompareReal<TFunc, TArgs>(registry, name);
+ RegisterCompareIntegral<TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrComparePrimitive(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggrCompareOpt<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
+
+ RegisterAggrCompareOpt<NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+
+ RegisterAggrCompareOpt<NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+
+ RegisterAggrCompareOpt<NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+
+ RegisterAggrCompareOpt<NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterAggrCompareOpt<NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterCompareDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
@@ -389,92 +389,92 @@ void RegisterCompareDatetime(IBuiltinFunctionRegistry& registry, const std::stri
RegisterCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
- RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
RegisterCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
-
- RegisterCompareOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
+
+ RegisterCompareOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrCompareDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename, bool> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrCompareTzDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
+ RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrCompareDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, bool> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrCompareTzDatetime(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
- RegisterAggrCompareOpt<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<NUdf::EDataSlot> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs,
- bool WithSpecial = true
->
-void RegisterCompareStrings(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCompareCustomOpt<NUdf::TDataType<char*>, NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::String>, TArgs>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<char*>, NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
- if constexpr (WithSpecial) {
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUuid>, NUdf::TDataType<NUdf::TUuid>, TFunc<NUdf::EDataSlot::Uuid>, TArgs>(registry, name);
+ template<NUdf::EDataSlot> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs,
+ bool WithSpecial = true
+>
+void RegisterCompareStrings(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCompareCustomOpt<NUdf::TDataType<char*>, NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::String>, TArgs>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<char*>, NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
+ if constexpr (WithSpecial) {
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TUuid>, NUdf::TDataType<NUdf::TUuid>, TFunc<NUdf::EDataSlot::Uuid>, TArgs>(registry, name);
RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDyNumber>, NUdf::TDataType<NUdf::TDyNumber>, TFunc<NUdf::EDataSlot::DyNumber>, TArgs>(registry, name);
- }
-}
-
-template <
- template<NUdf::EDataSlot> class TFunc,
- template<typename, typename, bool, bool, bool> class TArgs
->
-void RegisterAggrCompareStrings(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggrCompareCustomOpt<NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::String>, TArgs>(registry, name);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TUuid>, TFunc<NUdf::EDataSlot::Uuid>, TArgs>(registry, name);
+ }
+}
+
+template <
+ template<NUdf::EDataSlot> class TFunc,
+ template<typename, typename, bool, bool, bool> class TArgs
+>
+void RegisterAggrCompareStrings(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<char*>, TFunc<NUdf::EDataSlot::String>, TArgs>(registry, name);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TUtf8>, TFunc<NUdf::EDataSlot::Utf8>, TArgs>(registry, name);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TUuid>, TFunc<NUdf::EDataSlot::Uuid>, TArgs>(registry, name);
RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDyNumber>, TFunc<NUdf::EDataSlot::DyNumber>, TArgs>(registry, name);
-}
-
-void RegisterEquals(IBuiltinFunctionRegistry& registry);
-void RegisterNotEquals(IBuiltinFunctionRegistry& registry);
-void RegisterLess(IBuiltinFunctionRegistry& registry);
-void RegisterLessOrEqual(IBuiltinFunctionRegistry& registry);
-void RegisterGreater(IBuiltinFunctionRegistry& registry);
-void RegisterGreaterOrEqual(IBuiltinFunctionRegistry& registry);
-
-}
-}
+}
+
+void RegisterEquals(IBuiltinFunctionRegistry& registry);
+void RegisterNotEquals(IBuiltinFunctionRegistry& registry);
+void RegisterLess(IBuiltinFunctionRegistry& registry);
+void RegisterLessOrEqual(IBuiltinFunctionRegistry& registry);
+void RegisterGreater(IBuiltinFunctionRegistry& registry);
+void RegisterGreaterOrEqual(IBuiltinFunctionRegistry& registry);
+
+}
+}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_concat.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_concat.cpp
index b8eed6ba94..239956bfa9 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_concat.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_concat.cpp
@@ -6,36 +6,36 @@ namespace NMiniKQL {
namespace {
-template <typename TLeft, typename TRight, typename TOutput>
-struct TConcat {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right)
- {
- return ConcatStrings(std::move(left), std::move(right));
+template <typename TLeft, typename TRight, typename TOutput>
+struct TConcat {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right)
+ {
+ return ConcatStrings(std::move(left), std::move(right));
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return CallBinaryUnboxedValueFunction(&ConcatStrings, Type::getInt128Ty(ctx.Codegen->GetContext()), left, right, ctx.Codegen, block);
- }
-#endif
-};
-
-template<typename TType>
-using TAggrConcat = TConcat<TType, TType, TType>;
-
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return CallBinaryUnboxedValueFunction(&ConcatStrings, Type::getInt128Ty(ctx.Codegen->GetContext()), left, right, ctx.Codegen, block);
+ }
+#endif
+};
+
+template<typename TType>
+using TAggrConcat = TConcat<TType, TType, TType>;
+
}
-void RegisterConcat(IBuiltinFunctionRegistry& registry) {
- const auto name = "Concat";
- RegisterFunctionBinOpt<NUdf::TDataType<char*>, NUdf::TDataType<char*>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<char*>, NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, TConcat, TBinaryArgsOpt>(registry, name);
-
- const auto aggrName = "AggrConcat";
- RegisterAggregateFunction<NUdf::TDataType<char*>, TAggrConcat, TBinaryArgsSameOpt>(registry, aggrName);
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TAggrConcat, TBinaryArgsSameOpt>(registry, aggrName);
+void RegisterConcat(IBuiltinFunctionRegistry& registry) {
+ const auto name = "Concat";
+ RegisterFunctionBinOpt<NUdf::TDataType<char*>, NUdf::TDataType<char*>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<char*>, NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, NUdf::TDataType<char*>, TConcat, TBinaryArgsOpt>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<NUdf::TUtf8>, TConcat, TBinaryArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrConcat";
+ RegisterAggregateFunction<NUdf::TDataType<char*>, TAggrConcat, TBinaryArgsSameOpt>(registry, aggrName);
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TAggrConcat, TBinaryArgsSameOpt>(registry, aggrName);
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_convert.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_convert.cpp
index 30e9b2a2c8..43f7287be2 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_convert.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_convert.cpp
@@ -1,4 +1,4 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
#include <ydb/library/yql/public/udf/udf_value_builder.h>
#include <util/generic/ylimits.h>
@@ -14,81 +14,81 @@ namespace NMiniKQL {
namespace {
template <typename TIn, typename TOut>
-struct TFloatToIntegralImpl {
- static constexpr TIn MinValue = static_cast<TIn>(std::numeric_limits<TOut>::min());
- static constexpr TIn MaxValue = std::is_same<TIn, double>::value ? MaxFloor<TOut>() : static_cast<TIn>(std::numeric_limits<TOut>::max());
-
+struct TFloatToIntegralImpl {
+ static constexpr TIn MinValue = static_cast<TIn>(std::numeric_limits<TOut>::min());
+ static constexpr TIn MaxValue = std::is_same<TIn, double>::value ? MaxFloor<TOut>() : static_cast<TIn>(std::numeric_limits<TOut>::max());
+
static NUdf::TUnboxedValuePod Do(TIn val) {
switch (std::fpclassify(val)) {
case FP_NORMAL:
break;
case FP_ZERO:
case FP_SUBNORMAL:
- return NUdf::TUnboxedValuePod::Zero();
+ return NUdf::TUnboxedValuePod::Zero();
default:
return NUdf::TUnboxedValuePod();
}
- if (val < MinValue || val > MaxValue) {
+ if (val < MinValue || val > MaxValue) {
return NUdf::TUnboxedValuePod();
}
-
- return NUdf::TUnboxedValuePod(static_cast<TOut>(val));
+
+ return NUdf::TUnboxedValuePod(static_cast<TOut>(val));
}
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto val = GetterFor<TIn>(arg, context, block);
- const auto type = Type::getInt32Ty(context);
- const auto fnType = FunctionType::get(type, {val->getType()}, false);
- const auto name = std::is_same<TIn, float>() ? "MyFloatClassify" : "MyDoubleClassify";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<int(*)(TIn)>(&std::fpclassify)));
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto val = GetterFor<TIn>(arg, context, block);
+ const auto type = Type::getInt32Ty(context);
+ const auto fnType = FunctionType::get(type, {val->getType()}, false);
+ const auto name = std::is_same<TIn, float>() ? "MyFloatClassify" : "MyDoubleClassify";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<int(*)(TIn)>(&std::fpclassify)));
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto classify = CallInst::Create(func, {val}, "fpclassify", block);
-
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(arg->getType(), 3, "result", done);
- result->addIncoming(GetFalse(context), zero);
- result->addIncoming(ConstantInt::get(arg->getType(), 0), none);
-
- const auto choise = SwitchInst::Create(classify, none, 5, block);
- choise->addCase(ConstantInt::get(type, FP_NAN), none);
- choise->addCase(ConstantInt::get(type, FP_INFINITE), none);
- BranchInst::Create(done, none);
-
- choise->addCase(ConstantInt::get(type, FP_ZERO), zero);
- choise->addCase(ConstantInt::get(type, FP_SUBNORMAL), zero);
- BranchInst::Create(done, zero);
-
- choise->addCase(ConstantInt::get(type, FP_NORMAL), good);
- block = good;
-
- const auto less = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLT, val, ConstantFP::get(val->getType(), MinValue), "less", block);
- const auto greater = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGT, val, ConstantFP::get(val->getType(), MaxValue), "greater", block);
- const auto bad = BinaryOperator::CreateOr(less, greater, "or", block);
-
- const auto make = BasicBlock::Create(context, "make", ctx.Func);
- BranchInst::Create(none, make, bad, block);
-
- block = make;
- const auto cast = StaticCast<TIn, TOut>(val, context, block);
- const auto wide = SetterFor<TOut>(cast, context, block);
- result->addIncoming(wide, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
+ const auto classify = CallInst::Create(func, {val}, "fpclassify", block);
+
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(arg->getType(), 3, "result", done);
+ result->addIncoming(GetFalse(context), zero);
+ result->addIncoming(ConstantInt::get(arg->getType(), 0), none);
+
+ const auto choise = SwitchInst::Create(classify, none, 5, block);
+ choise->addCase(ConstantInt::get(type, FP_NAN), none);
+ choise->addCase(ConstantInt::get(type, FP_INFINITE), none);
+ BranchInst::Create(done, none);
+
+ choise->addCase(ConstantInt::get(type, FP_ZERO), zero);
+ choise->addCase(ConstantInt::get(type, FP_SUBNORMAL), zero);
+ BranchInst::Create(done, zero);
+
+ choise->addCase(ConstantInt::get(type, FP_NORMAL), good);
+ block = good;
+
+ const auto less = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLT, val, ConstantFP::get(val->getType(), MinValue), "less", block);
+ const auto greater = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGT, val, ConstantFP::get(val->getType(), MaxValue), "greater", block);
+ const auto bad = BinaryOperator::CreateOr(less, greater, "or", block);
+
+ const auto make = BasicBlock::Create(context, "make", ctx.Func);
+ BranchInst::Create(none, make, bad, block);
+
+ block = make;
+ const auto cast = StaticCast<TIn, TOut>(val, context, block);
+ const auto wide = SetterFor<TOut>(cast, context, block);
+ result->addIncoming(wide, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
};
template <typename TIn>
-struct TFloatToIntegralImpl<TIn, bool> {
+struct TFloatToIntegralImpl<TIn, bool> {
static NUdf::TUnboxedValuePod Do(TIn val) {
switch (std::fpclassify(val)) {
case FP_NORMAL:
@@ -102,282 +102,282 @@ struct TFloatToIntegralImpl<TIn, bool> {
return NUdf::TUnboxedValuePod();
}
}
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto val = GetterFor<TIn>(arg, context, block);
- const auto type = Type::getInt32Ty(context);
- const auto fnType = FunctionType::get(type, {val->getType()}, false);
- const auto name = std::is_same<TIn, float>() ? "MyFloatClassify" : "MyDoubleClassify";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<int(*)(TIn)>(&std::fpclassify)));
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto val = GetterFor<TIn>(arg, context, block);
+ const auto type = Type::getInt32Ty(context);
+ const auto fnType = FunctionType::get(type, {val->getType()}, false);
+ const auto name = std::is_same<TIn, float>() ? "MyFloatClassify" : "MyDoubleClassify";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<int(*)(TIn)>(&std::fpclassify)));
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto classify = CallInst::Create(func, {val}, "fpclassify", block);
-
- const auto none = BasicBlock::Create(context, "none", ctx.Func);
- const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(arg->getType(), 3, "result", done);
- result->addIncoming(GetTrue(context), good);
- result->addIncoming(GetFalse(context), zero);
- result->addIncoming(ConstantInt::get(arg->getType(), 0), none);
-
- const auto choise = SwitchInst::Create(classify, none, 5, block);
- choise->addCase(ConstantInt::get(type, FP_NAN), none);
- BranchInst::Create(done, none);
-
- choise->addCase(ConstantInt::get(type, FP_ZERO), zero);
- choise->addCase(ConstantInt::get(type, FP_SUBNORMAL), zero);
- BranchInst::Create(done, zero);
-
- choise->addCase(ConstantInt::get(type, FP_INFINITE), good);
- choise->addCase(ConstantInt::get(type, FP_NORMAL), good);
- BranchInst::Create(done, good);
-
- block = done;
- return result;
- }
-#endif
+ const auto classify = CallInst::Create(func, {val}, "fpclassify", block);
+
+ const auto none = BasicBlock::Create(context, "none", ctx.Func);
+ const auto zero = BasicBlock::Create(context, "zero", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(arg->getType(), 3, "result", done);
+ result->addIncoming(GetTrue(context), good);
+ result->addIncoming(GetFalse(context), zero);
+ result->addIncoming(ConstantInt::get(arg->getType(), 0), none);
+
+ const auto choise = SwitchInst::Create(classify, none, 5, block);
+ choise->addCase(ConstantInt::get(type, FP_NAN), none);
+ BranchInst::Create(done, none);
+
+ choise->addCase(ConstantInt::get(type, FP_ZERO), zero);
+ choise->addCase(ConstantInt::get(type, FP_SUBNORMAL), zero);
+ BranchInst::Create(done, zero);
+
+ choise->addCase(ConstantInt::get(type, FP_INFINITE), good);
+ choise->addCase(ConstantInt::get(type, FP_NORMAL), good);
+ BranchInst::Create(done, good);
+
+ block = done;
+ return result;
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput>
+struct TFloatToIntegral : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static_assert(std::is_floating_point<TInput>::value, "Input type must be floating point!");
+ static_assert(std::is_integral<TOutput>::value, "Output type must be integral!");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
+ {
+ return TFloatToIntegralImpl<TInput, TOutput>::Do(arg.template Get<TInput>());
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return TFloatToIntegralImpl<TInput, TOutput>::Gen(arg, ctx, block);
+ }
+#endif
+};
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenInBounds(Value* val, Constant* low, Constant* high, BasicBlock* block) {
+ const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, high, "lt", block);
+ const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, low, "gt", block);
+ const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
+ return good;
+}
+#endif
+
+template <typename TInput, typename TOutput,
+ TOutput MaxVal = std::numeric_limits<TOutput>::max(),
+ TOutput MinVal = std::numeric_limits<TOutput>::min()>
+struct TWideToShort : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static_assert(std::is_integral_v<TInput>, "Input type must be integral!");
+ static_assert(std::is_integral_v<TOutput>, "Output type must be integral!");
+
+ static constexpr auto LowerBound = static_cast<TInput>(MinVal);
+ static constexpr auto UpperBound = static_cast<TInput>(MaxVal);
+
+ static constexpr bool SkipLower = std::is_unsigned_v<TInput> ||
+ (sizeof(TInput) < sizeof(TOutput) && std::is_signed_v<TOutput>);
+ static constexpr bool SkipUpper = sizeof(TInput) < sizeof(TOutput) ||
+ (sizeof(TInput) == sizeof(TOutput) && std::is_signed_v<TInput> && std::is_unsigned_v<TOutput> && UpperBound < 0);
+
+ static_assert(!(SkipLower && SkipUpper), "Only for cut input digits!");
+
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
+ {
+ const auto val = arg.template Get<TInput>();
+ const bool ok = (SkipLower || val >= LowerBound) && (SkipUpper || val <= UpperBound);
+ return ok ? NUdf::TUnboxedValuePod(static_cast<TOutput>(val)) : NUdf::TUnboxedValuePod();
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto lb = ConstantInt::get(val->getType(), LowerBound);
+ const auto ub = ConstantInt::get(val->getType(), UpperBound);
+ const auto good = SkipLower ?
+ CmpInst::Create(Instruction::ICmp, std::is_signed_v<TInput> ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE, val, ub, "ok", block):
+ SkipUpper ?
+ CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, lb, "ok", block):
+ GenInBounds(val, lb, ub, block);
+ const auto full = SetterFor<TOutput>(StaticCast<TInput, TOutput>(val, context, block), context, block);
+ const auto res = SelectInst::Create(good, full, ConstantInt::get(arg->getType(), 0), "result", block);
+ return res;
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput>
+struct TConvert : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.template Get<TInput>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto res = StaticCast<TInput, TOutput>(val, context, block);
+ const auto wide = SetterFor<TOutput>(res, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput, TOutput Multiplier>
+struct TScaleUp : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static_assert(sizeof(TInput) < sizeof(TOutput), "Output should be wider than input.");
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(Multiplier * static_cast<TOutput>(arg.template Get<TInput>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto cast = StaticCast<TInput, TOutput>(val, context, block);
+ const auto mul = BinaryOperator::CreateMul(ConstantInt::get(cast->getType(), Multiplier), cast, "mul", block);
+ const auto wide = SetterFor<TOutput>(mul, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput>
+struct TScale;
+
+template <>
+struct TScale<ui16, ui32> {
+ static constexpr ui32 Modifier = 86400U;
+};
+
+template <>
+struct TScale<ui32, ui64> {
+ static constexpr ui64 Modifier = 1000000ULL;
+};
+
+template <>
+struct TScale<ui16, ui64> {
+ static constexpr ui64 Modifier = 86400000000ULL;
};
-template <typename TInput, typename TOutput>
-struct TFloatToIntegral : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static_assert(std::is_floating_point<TInput>::value, "Input type must be floating point!");
- static_assert(std::is_integral<TOutput>::value, "Output type must be integral!");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
- {
- return TFloatToIntegralImpl<TInput, TOutput>::Do(arg.template Get<TInput>());
- }
+template <typename TInput, typename TOutput, bool Tz = false>
+struct TDatetimeScaleUp : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static_assert(sizeof(TInput) < sizeof(TOutput), "Output size should be wider than input size.");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ auto result = NUdf::TUnboxedValuePod(TScale<TInput, TOutput>::Modifier * static_cast<TOutput>(arg.template Get<TInput>()));
+ if constexpr (Tz) {
+ result.SetTimezoneId(arg.GetTimezoneId());
+ }
+ return result;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return TFloatToIntegralImpl<TInput, TOutput>::Gen(arg, ctx, block);
- }
-#endif
-};
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenInBounds(Value* val, Constant* low, Constant* high, BasicBlock* block) {
- const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, high, "lt", block);
- const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, low, "gt", block);
- const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
- return good;
-}
-#endif
-
-template <typename TInput, typename TOutput,
- TOutput MaxVal = std::numeric_limits<TOutput>::max(),
- TOutput MinVal = std::numeric_limits<TOutput>::min()>
-struct TWideToShort : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static_assert(std::is_integral_v<TInput>, "Input type must be integral!");
- static_assert(std::is_integral_v<TOutput>, "Output type must be integral!");
-
- static constexpr auto LowerBound = static_cast<TInput>(MinVal);
- static constexpr auto UpperBound = static_cast<TInput>(MaxVal);
-
- static constexpr bool SkipLower = std::is_unsigned_v<TInput> ||
- (sizeof(TInput) < sizeof(TOutput) && std::is_signed_v<TOutput>);
- static constexpr bool SkipUpper = sizeof(TInput) < sizeof(TOutput) ||
- (sizeof(TInput) == sizeof(TOutput) && std::is_signed_v<TInput> && std::is_unsigned_v<TOutput> && UpperBound < 0);
-
- static_assert(!(SkipLower && SkipUpper), "Only for cut input digits!");
-
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
- {
- const auto val = arg.template Get<TInput>();
- const bool ok = (SkipLower || val >= LowerBound) && (SkipUpper || val <= UpperBound);
- return ok ? NUdf::TUnboxedValuePod(static_cast<TOutput>(val)) : NUdf::TUnboxedValuePod();
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto lb = ConstantInt::get(val->getType(), LowerBound);
- const auto ub = ConstantInt::get(val->getType(), UpperBound);
- const auto good = SkipLower ?
- CmpInst::Create(Instruction::ICmp, std::is_signed_v<TInput> ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE, val, ub, "ok", block):
- SkipUpper ?
- CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, lb, "ok", block):
- GenInBounds(val, lb, ub, block);
- const auto full = SetterFor<TOutput>(StaticCast<TInput, TOutput>(val, context, block), context, block);
- const auto res = SelectInst::Create(good, full, ConstantInt::get(arg->getType(), 0), "result", block);
- return res;
- }
-#endif
-};
-
-template <typename TInput, typename TOutput>
-struct TConvert : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.template Get<TInput>()));
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto cast = StaticCast<TInput, TOutput>(val, context, block);
+ const auto mul = BinaryOperator::CreateMul(ConstantInt::get(cast->getType(), TScale<TInput, TOutput>::Modifier), cast, "mul", block);
+ const auto wide = SetterFor<TOutput>(mul, context, block);
+ if constexpr (Tz) {
+ const uint64_t init[] = {0ULL, 0xFFFFULL};
+ const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
+ const auto tzid = BinaryOperator::CreateAnd(arg, mask, "tzid", block);
+ const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
+ return full;
+ } else {
+ return wide;
+ }
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput, bool Tz = false>
+struct TDatetimeScaleDown : public TArithmeticConstraintsUnary<TInput, TOutput> {
+ static_assert(sizeof(TInput) > sizeof(TOutput), "Output size should be narrower than input size.");
+ static_assert(std::is_unsigned_v<TInput> && std::is_unsigned_v<TOutput>, "Only for unsigned.");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ auto result = NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.template Get<TInput>() / TScale<TOutput, TInput>::Modifier));
+ if constexpr (Tz) {
+ result.SetTimezoneId(arg.GetTimezoneId());
+ }
+ return result;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto div = BinaryOperator::CreateUDiv(val, ConstantInt::get(val->getType(), TScale<TOutput, TInput>::Modifier), "div", block);
+ const auto cast = StaticCast<TInput, TOutput>(div, context, block);
+ const auto wide = SetterFor<TOutput>(cast, context, block);
+ if constexpr (Tz) {
+ const uint64_t init[] = {0ULL, 0xFFFFULL};
+ const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
+ const auto tzid = BinaryOperator::CreateAnd(arg, mask, "tzid", block);
+ const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
+ return full;
+ } else {
+ return wide;
+ }
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput, bool Tz>
+using TDatetimeRescale = std::conditional_t<sizeof(TInput) < sizeof(TOutput),
+ TDatetimeScaleUp<TInput, TOutput, Tz>,
+ TDatetimeScaleDown<TInput, TOutput, Tz>
+>;
+
+template <bool Cleanup = false>
+struct TDatetimeTzStub {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ auto result = arg;
+ if (Cleanup) {
+ result.SetTimezoneId(0);
+ }
+ return result;
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto res = StaticCast<TInput, TOutput>(val, context, block);
- const auto wide = SetterFor<TOutput>(res, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TInput, typename TOutput, TOutput Multiplier>
-struct TScaleUp : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static_assert(sizeof(TInput) < sizeof(TOutput), "Output should be wider than input.");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(Multiplier * static_cast<TOutput>(arg.template Get<TInput>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto cast = StaticCast<TInput, TOutput>(val, context, block);
- const auto mul = BinaryOperator::CreateMul(ConstantInt::get(cast->getType(), Multiplier), cast, "mul", block);
- const auto wide = SetterFor<TOutput>(mul, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TInput, typename TOutput>
-struct TScale;
-
-template <>
-struct TScale<ui16, ui32> {
- static constexpr ui32 Modifier = 86400U;
-};
-
-template <>
-struct TScale<ui32, ui64> {
- static constexpr ui64 Modifier = 1000000ULL;
-};
-
-template <>
-struct TScale<ui16, ui64> {
- static constexpr ui64 Modifier = 86400000000ULL;
-};
-
-template <typename TInput, typename TOutput, bool Tz = false>
-struct TDatetimeScaleUp : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static_assert(sizeof(TInput) < sizeof(TOutput), "Output size should be wider than input size.");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- auto result = NUdf::TUnboxedValuePod(TScale<TInput, TOutput>::Modifier * static_cast<TOutput>(arg.template Get<TInput>()));
- if constexpr (Tz) {
- result.SetTimezoneId(arg.GetTimezoneId());
- }
- return result;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto cast = StaticCast<TInput, TOutput>(val, context, block);
- const auto mul = BinaryOperator::CreateMul(ConstantInt::get(cast->getType(), TScale<TInput, TOutput>::Modifier), cast, "mul", block);
- const auto wide = SetterFor<TOutput>(mul, context, block);
- if constexpr (Tz) {
- const uint64_t init[] = {0ULL, 0xFFFFULL};
- const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
- const auto tzid = BinaryOperator::CreateAnd(arg, mask, "tzid", block);
- const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
- return full;
- } else {
- return wide;
- }
- }
-#endif
-};
-
-template <typename TInput, typename TOutput, bool Tz = false>
-struct TDatetimeScaleDown : public TArithmeticConstraintsUnary<TInput, TOutput> {
- static_assert(sizeof(TInput) > sizeof(TOutput), "Output size should be narrower than input size.");
- static_assert(std::is_unsigned_v<TInput> && std::is_unsigned_v<TOutput>, "Only for unsigned.");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- auto result = NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.template Get<TInput>() / TScale<TOutput, TInput>::Modifier));
- if constexpr (Tz) {
- result.SetTimezoneId(arg.GetTimezoneId());
- }
- return result;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto div = BinaryOperator::CreateUDiv(val, ConstantInt::get(val->getType(), TScale<TOutput, TInput>::Modifier), "div", block);
- const auto cast = StaticCast<TInput, TOutput>(div, context, block);
- const auto wide = SetterFor<TOutput>(cast, context, block);
- if constexpr (Tz) {
- const uint64_t init[] = {0ULL, 0xFFFFULL};
- const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
- const auto tzid = BinaryOperator::CreateAnd(arg, mask, "tzid", block);
- const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
- return full;
- } else {
- return wide;
- }
- }
-#endif
-};
-
-template <typename TInput, typename TOutput, bool Tz>
-using TDatetimeRescale = std::conditional_t<sizeof(TInput) < sizeof(TOutput),
- TDatetimeScaleUp<TInput, TOutput, Tz>,
- TDatetimeScaleDown<TInput, TOutput, Tz>
->;
-
-template <bool Cleanup = false>
-struct TDatetimeTzStub {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- auto result = arg;
- if (Cleanup) {
- result.SetTimezoneId(0);
- }
- return result;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- if constexpr (Cleanup) {
- const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFF0000ULL};
- const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
- return BinaryOperator::CreateAnd(arg, mask, "clean", block);
- } else {
- return arg;
- }
- }
-#endif
-};
-
-struct TStringConvert {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
- {
- Y_VERIFY_DEBUG(!arg.IsBoxed(), "Expected unboxed arg in String::Convert()");
- return arg; // handle optional args as well
+ static Value* Generate(Value* arg, const TCodegenContext&, BasicBlock*& block)
+ {
+ if constexpr (Cleanup) {
+ const uint64_t init[] = {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFF0000ULL};
+ const auto mask = ConstantInt::get(arg->getType(), APInt(128, 2, init));
+ return BinaryOperator::CreateAnd(arg, mask, "clean", block);
+ } else {
+ return arg;
+ }
+ }
+#endif
+};
+
+struct TStringConvert {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
+ {
+ Y_VERIFY_DEBUG(!arg.IsBoxed(), "Expected unboxed arg in String::Convert()");
+ return arg; // handle optional args as well
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
static Value* Generate(Value* arg, const TCodegenContext&, BasicBlock*&)
- {
- return arg;
- }
-#endif
-};
+ {
+ return arg;
+ }
+#endif
+};
NUdf::TUnboxedValuePod JsonToJsonDocument(const NUdf::TUnboxedValuePod value) {
auto binaryJson = NKikimr::NBinaryJson::SerializeToBinaryJson(value.AsStringRef());
@@ -386,8 +386,8 @@ NUdf::TUnboxedValuePod JsonToJsonDocument(const NUdf::TUnboxedValuePod value) {
return NUdf::TUnboxedValuePod();
}
return MakeString(TStringBuf(binaryJson->Data(), binaryJson->Size()));
-}
-
+}
+
struct TJsonToJsonDocumentConvert {
static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
{
@@ -431,20 +431,20 @@ struct TJsonDocumentToJsonConvert {
}
-namespace NDecimal {
+namespace NDecimal {
template <typename TInput>
struct TConvertFromIntegral {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(NYql::NDecimal::TInt128(arg.Get<TInput>()));
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::TInt128(arg.Get<TInput>()));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
{
- const auto val = GetterFor<TInput>(arg, ctx.Codegen->GetContext(), block);
- const auto ext = CastInst::Create(std::is_signed<TInput>() ? Instruction::SExt : Instruction::ZExt, val, arg->getType(), "ext", block);
- return SetterForInt128(ext, block);
+ const auto val = GetterFor<TInput>(arg, ctx.Codegen->GetContext(), block);
+ const auto ext = CastInst::Create(std::is_signed<TInput>() ? Instruction::SExt : Instruction::ZExt, val, arg->getType(), "ext", block);
+ return SetterForInt128(ext, block);
}
#endif
static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
@@ -452,519 +452,519 @@ struct TConvertFromIntegral {
template <typename TOutput>
struct TConvertToIntegral {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- const auto v = arg.GetInt128();
- return v >= std::numeric_limits<TOutput>::min() && v <= std::numeric_limits<TOutput>::max() ?
- NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.GetInt128())) : NUdf::TUnboxedValuePod();
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ const auto v = arg.GetInt128();
+ return v >= std::numeric_limits<TOutput>::min() && v <= std::numeric_limits<TOutput>::max() ?
+ NUdf::TUnboxedValuePod(static_cast<TOutput>(arg.GetInt128())) : NUdf::TUnboxedValuePod();
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterForInt128(arg, block);
- const auto cut = CastInst::Create(Instruction::Trunc, val, GetTypeFor<TOutput>(context), "cut", block);
- const auto full = SetterFor<TOutput>(cut, context, block);
- const auto good = GenInBounds<true>(val, GenConstant(std::numeric_limits<TOutput>::min(), context), GenConstant(std::numeric_limits<TOutput>::max(), context), block);
- const auto res = SelectInst::Create(good, full, ConstantInt::get(arg->getType(), 0), "result", block);
- return res;
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterForInt128(arg, block);
+ const auto cut = CastInst::Create(Instruction::Trunc, val, GetTypeFor<TOutput>(context), "cut", block);
+ const auto full = SetterFor<TOutput>(cut, context, block);
+ const auto good = GenInBounds<true>(val, GenConstant(std::numeric_limits<TOutput>::min(), context), GenConstant(std::numeric_limits<TOutput>::max(), context), block);
+ const auto res = SelectInst::Create(good, full, ConstantInt::get(arg->getType(), 0), "result", block);
+ return res;
}
#endif
static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
};
-template<typename TOutput, ui8 Scale>
-TOutput GetFP(NYql::NDecimal::TInt128 v);
-
-template<>
-float GetFP<float, 0>(NYql::NDecimal::TInt128 v) {
- return static_cast<float>(v);
-}
-
-template<>
-double GetFP<double, 0>(NYql::NDecimal::TInt128 v) {
- return static_cast<double>(v);
-}
-
-template<typename TOutput, ui8 Scale>
-TOutput GetFP(NYql::NDecimal::TInt128 v) {
- if (v % 10)
- return static_cast<TOutput>(v) / static_cast<TOutput>(NYql::NDecimal::GetDivider<Scale>());
- else
- return GetFP<TOutput, Scale - 1>(v / 10);
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-template<typename TOutput, ui8 Scale>
-void GenFP(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block);
-
-template<>
-void GenFP<float, 0>(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
- const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<float>(ctx.Codegen->GetContext()), "cast", block);
- result->addIncoming(cast, block);
- BranchInst::Create(done, block);
-}
-
-template<>
-void GenFP<double, 0>(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
- const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<double>(ctx.Codegen->GetContext()), "cast", block);
- result->addIncoming(cast, block);
- BranchInst::Create(done, block);
-}
-
-template<typename TOutput, ui8 Scale>
-void GenFP(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
- auto& context = ctx.Codegen->GetContext();
- const auto& str = ToString(Scale);
- const auto stop = BasicBlock::Create(context, (TString("stop_") += str).c_str(), ctx.Func);
- const auto step = BasicBlock::Create(context, (TString("step_") += str).c_str(), ctx.Func);
-
- const auto ten = ConstantInt::get(val->getType(), 10U);
-
- const auto rem = BinaryOperator::CreateSRem(val, ten, "rem", block);
- const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rem, ConstantInt::get(val->getType(), 0U), "nul", block);
-
- BranchInst::Create(step, stop, nul, block);
-
- block = stop;
- const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<TOutput>(ctx.Codegen->GetContext()), "cast", block);
- const auto divf = BinaryOperator::CreateFDiv(cast, ConstantFP::get(GetTypeFor<TOutput>(context), static_cast<TOutput>(NYql::NDecimal::GetDivider<Scale>())), "divf", block);
- result->addIncoming(divf, block);
- BranchInst::Create(done, block);
-
- block = step;
-
- const auto div = BinaryOperator::CreateSDiv(val, ten, "div", block);
- GenFP<TOutput, Scale - 1>(result, div, ctx, done, block);
-}
-#endif
-
-template <typename TOutput, ui8 Scale>
-struct TToFP {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- const auto v = arg.GetInt128();
- if (v == +NYql::NDecimal::Inf())
- return NUdf::TUnboxedValuePod(+std::numeric_limits<TOutput>::infinity());
- if (v == -NYql::NDecimal::Inf())
- return NUdf::TUnboxedValuePod(-std::numeric_limits<TOutput>::infinity());
- if (v == +NYql::NDecimal::Nan())
- return NUdf::TUnboxedValuePod(+std::numeric_limits<TOutput>::quiet_NaN());
- if (v == -NYql::NDecimal::Nan())
- return NUdf::TUnboxedValuePod(-std::numeric_limits<TOutput>::quiet_NaN());
-
- return NUdf::TUnboxedValuePod(GetFP<TOutput, Scale>(v));
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
-
- const auto val = GetterForInt128(arg, block);
-
- const auto pnan = BasicBlock::Create(context, "pnan", ctx.Func);
- const auto pinf = BasicBlock::Create(context, "pinf", ctx.Func);
- const auto mnan = BasicBlock::Create(context, "mnan", ctx.Func);
- const auto minf = BasicBlock::Create(context, "minf", ctx.Func);
- const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
-
- const auto result = PHINode::Create(GetTypeFor<TOutput>(context), 5U + Scale, "result", done);
-
- const auto choise = SwitchInst::Create(val, norm, 4U, block);
- choise->addCase(GenConstant(+NYql::NDecimal::Nan(), context), pnan);
- choise->addCase(GenConstant(-NYql::NDecimal::Nan(), context), mnan);
- choise->addCase(GenConstant(+NYql::NDecimal::Inf(), context), pinf);
- choise->addCase(GenConstant(-NYql::NDecimal::Inf(), context), minf);
-
- block = pnan;
- result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), +std::numeric_limits<TOutput>::quiet_NaN()), block);
- BranchInst::Create(done, block);
-
- block = mnan;
- result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), -std::numeric_limits<TOutput>::quiet_NaN()), block);
- BranchInst::Create(done, block);
-
- block = pinf;
- result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), +std::numeric_limits<TOutput>::infinity()), block);
- BranchInst::Create(done, block);
-
- block = minf;
- result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), -std::numeric_limits<TOutput>::infinity()), block);
- BranchInst::Create(done, block);
-
- block = norm;
- GenFP<TOutput, Scale>(result, val, ctx, done, block);
-
- block = done;
- return SetterFor<TOutput>(result, context, block);
- }
-#endif
- static_assert(std::is_floating_point<TOutput>::value, "Output type must be floating point!");
- static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
-};
-
-template <ui8 Scale> using TToFloat = TToFP<float, Scale>;
-template <ui8 Scale> using TToDouble = TToFP<double, Scale>;
-
-template <ui8 Scale>
-struct TScaleUp {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(NYql::NDecimal::Mul(arg.GetInt128(), NYql::NDecimal::GetDivider<Scale>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterForInt128(arg, block);
- const auto mul = BinaryOperator::CreateMul(val, GenConstant(NYql::NDecimal::GetDivider<Scale>(), context), "mul", block);
- const auto res = SelectInst::Create(GenIsNormal(val, context, block), mul, val, "result", block);
- return SetterForInt128(res, block);
- }
-#endif
- static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
-};
-
-template <ui8 Scale>
-struct TScaleDown {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(NYql::NDecimal::Div(arg.GetInt128(), NYql::NDecimal::GetDivider<Scale>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterForInt128(arg, block);
- const auto divider = GenConstant(NYql::NDecimal::GetDivider<Scale>() >> 1, context);
-
- const auto nul = ConstantInt::get(val->getType(), 0);
- const auto one = ConstantInt::get(val->getType(), 1);
-
- const auto div = BinaryOperator::CreateSDiv(val, divider, "div", block);
- const auto ashr = BinaryOperator::CreateAShr(div, one, "ashr", block);
- const auto bit = CastInst::Create(Instruction::Trunc, div, Type::getInt1Ty(context), "bit", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto round = BasicBlock::Create(context, "round", ctx.Func);
- const auto result = PHINode::Create(val->getType(), 2, "result", done);
- result->addIncoming(ashr, block);
-
- BranchInst::Create(round, done, bit, block);
-
- block = round;
-
- const auto mod = BinaryOperator::CreateSRem(val, divider, "mod", block);
- const auto zero = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_EQ, mod, nul, "zero", block);
- const auto plus = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, mod, nul, "plus", block);
-
- const auto test = CastInst::Create(Instruction::Trunc, ashr, Type::getInt1Ty(context), "test", block);
- const auto even = BinaryOperator::CreateAnd(test, zero, "even", block);
- const auto up = BinaryOperator::CreateOr(plus, even, "up", block);
-
- const auto inc = BinaryOperator::CreateAdd(ashr, one, "inc", block);
- const auto rounded = SelectInst::Create(up, inc, ashr, "result", block);
- result->addIncoming(rounded, block);
- BranchInst::Create(done, block);
-
- block = done;
-
- const auto res = SelectInst::Create(GenIsNormal(val, context, block), result, val, "res", block);
- return SetterForInt128(res, block);
- }
-#endif
- static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
-};
-
-template <ui8 Precision>
-struct TCheckBounds {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- const auto v = arg.GetInt128();
-
- using namespace NYql::NDecimal;
-
- if (IsNormal<Precision>(v))
- return arg;
-
- return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
-
- const auto val = GetterForInt128(arg, block);
-
- const auto& bounds = GenBounds<Precision>(context);
- const auto good = GenInBounds(val, bounds.first, bounds.second, block);
-
- const auto nan = GenIsNonComparable(val, context, block);
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
-
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto res = SelectInst::Create(good, arg, SetterForInt128(bad, block), "res", block);
- return res;
- }
-#endif
- static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
-};
-
+template<typename TOutput, ui8 Scale>
+TOutput GetFP(NYql::NDecimal::TInt128 v);
+
+template<>
+float GetFP<float, 0>(NYql::NDecimal::TInt128 v) {
+ return static_cast<float>(v);
}
-namespace {
-
-constexpr auto convert = "Convert";
-constexpr auto integral = "ToIntegral";
-constexpr auto decimal = "ToDecimal";
-
+template<>
+double GetFP<double, 0>(NYql::NDecimal::TInt128 v) {
+ return static_cast<double>(v);
+}
+
+template<typename TOutput, ui8 Scale>
+TOutput GetFP(NYql::NDecimal::TInt128 v) {
+ if (v % 10)
+ return static_cast<TOutput>(v) / static_cast<TOutput>(NYql::NDecimal::GetDivider<Scale>());
+ else
+ return GetFP<TOutput, Scale - 1>(v / 10);
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+template<typename TOutput, ui8 Scale>
+void GenFP(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block);
+
+template<>
+void GenFP<float, 0>(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
+ const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<float>(ctx.Codegen->GetContext()), "cast", block);
+ result->addIncoming(cast, block);
+ BranchInst::Create(done, block);
+}
+
+template<>
+void GenFP<double, 0>(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
+ const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<double>(ctx.Codegen->GetContext()), "cast", block);
+ result->addIncoming(cast, block);
+ BranchInst::Create(done, block);
+}
+
+template<typename TOutput, ui8 Scale>
+void GenFP(PHINode* result, Value* val, const TCodegenContext& ctx, BasicBlock* done, BasicBlock*& block) {
+ auto& context = ctx.Codegen->GetContext();
+ const auto& str = ToString(Scale);
+ const auto stop = BasicBlock::Create(context, (TString("stop_") += str).c_str(), ctx.Func);
+ const auto step = BasicBlock::Create(context, (TString("step_") += str).c_str(), ctx.Func);
+
+ const auto ten = ConstantInt::get(val->getType(), 10U);
+
+ const auto rem = BinaryOperator::CreateSRem(val, ten, "rem", block);
+ const auto nul = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rem, ConstantInt::get(val->getType(), 0U), "nul", block);
+
+ BranchInst::Create(step, stop, nul, block);
+
+ block = stop;
+ const auto cast = CastInst::Create(Instruction::SIToFP, val, GetTypeFor<TOutput>(ctx.Codegen->GetContext()), "cast", block);
+ const auto divf = BinaryOperator::CreateFDiv(cast, ConstantFP::get(GetTypeFor<TOutput>(context), static_cast<TOutput>(NYql::NDecimal::GetDivider<Scale>())), "divf", block);
+ result->addIncoming(divf, block);
+ BranchInst::Create(done, block);
+
+ block = step;
+
+ const auto div = BinaryOperator::CreateSDiv(val, ten, "div", block);
+ GenFP<TOutput, Scale - 1>(result, div, ctx, done, block);
+}
+#endif
+
+template <typename TOutput, ui8 Scale>
+struct TToFP {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ const auto v = arg.GetInt128();
+ if (v == +NYql::NDecimal::Inf())
+ return NUdf::TUnboxedValuePod(+std::numeric_limits<TOutput>::infinity());
+ if (v == -NYql::NDecimal::Inf())
+ return NUdf::TUnboxedValuePod(-std::numeric_limits<TOutput>::infinity());
+ if (v == +NYql::NDecimal::Nan())
+ return NUdf::TUnboxedValuePod(+std::numeric_limits<TOutput>::quiet_NaN());
+ if (v == -NYql::NDecimal::Nan())
+ return NUdf::TUnboxedValuePod(-std::numeric_limits<TOutput>::quiet_NaN());
+
+ return NUdf::TUnboxedValuePod(GetFP<TOutput, Scale>(v));
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto val = GetterForInt128(arg, block);
+
+ const auto pnan = BasicBlock::Create(context, "pnan", ctx.Func);
+ const auto pinf = BasicBlock::Create(context, "pinf", ctx.Func);
+ const auto mnan = BasicBlock::Create(context, "mnan", ctx.Func);
+ const auto minf = BasicBlock::Create(context, "minf", ctx.Func);
+ const auto norm = BasicBlock::Create(context, "norm", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+
+ const auto result = PHINode::Create(GetTypeFor<TOutput>(context), 5U + Scale, "result", done);
+
+ const auto choise = SwitchInst::Create(val, norm, 4U, block);
+ choise->addCase(GenConstant(+NYql::NDecimal::Nan(), context), pnan);
+ choise->addCase(GenConstant(-NYql::NDecimal::Nan(), context), mnan);
+ choise->addCase(GenConstant(+NYql::NDecimal::Inf(), context), pinf);
+ choise->addCase(GenConstant(-NYql::NDecimal::Inf(), context), minf);
+
+ block = pnan;
+ result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), +std::numeric_limits<TOutput>::quiet_NaN()), block);
+ BranchInst::Create(done, block);
+
+ block = mnan;
+ result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), -std::numeric_limits<TOutput>::quiet_NaN()), block);
+ BranchInst::Create(done, block);
+
+ block = pinf;
+ result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), +std::numeric_limits<TOutput>::infinity()), block);
+ BranchInst::Create(done, block);
+
+ block = minf;
+ result->addIncoming(ConstantFP::get(GetTypeFor<TOutput>(context), -std::numeric_limits<TOutput>::infinity()), block);
+ BranchInst::Create(done, block);
+
+ block = norm;
+ GenFP<TOutput, Scale>(result, val, ctx, done, block);
+
+ block = done;
+ return SetterFor<TOutput>(result, context, block);
+ }
+#endif
+ static_assert(std::is_floating_point<TOutput>::value, "Output type must be floating point!");
+ static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
+};
+
+template <ui8 Scale> using TToFloat = TToFP<float, Scale>;
+template <ui8 Scale> using TToDouble = TToFP<double, Scale>;
+
+template <ui8 Scale>
+struct TScaleUp {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::Mul(arg.GetInt128(), NYql::NDecimal::GetDivider<Scale>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterForInt128(arg, block);
+ const auto mul = BinaryOperator::CreateMul(val, GenConstant(NYql::NDecimal::GetDivider<Scale>(), context), "mul", block);
+ const auto res = SelectInst::Create(GenIsNormal(val, context, block), mul, val, "result", block);
+ return SetterForInt128(res, block);
+ }
+#endif
+ static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
+};
+
+template <ui8 Scale>
+struct TScaleDown {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::Div(arg.GetInt128(), NYql::NDecimal::GetDivider<Scale>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterForInt128(arg, block);
+ const auto divider = GenConstant(NYql::NDecimal::GetDivider<Scale>() >> 1, context);
+
+ const auto nul = ConstantInt::get(val->getType(), 0);
+ const auto one = ConstantInt::get(val->getType(), 1);
+
+ const auto div = BinaryOperator::CreateSDiv(val, divider, "div", block);
+ const auto ashr = BinaryOperator::CreateAShr(div, one, "ashr", block);
+ const auto bit = CastInst::Create(Instruction::Trunc, div, Type::getInt1Ty(context), "bit", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto round = BasicBlock::Create(context, "round", ctx.Func);
+ const auto result = PHINode::Create(val->getType(), 2, "result", done);
+ result->addIncoming(ashr, block);
+
+ BranchInst::Create(round, done, bit, block);
+
+ block = round;
+
+ const auto mod = BinaryOperator::CreateSRem(val, divider, "mod", block);
+ const auto zero = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_EQ, mod, nul, "zero", block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, mod, nul, "plus", block);
+
+ const auto test = CastInst::Create(Instruction::Trunc, ashr, Type::getInt1Ty(context), "test", block);
+ const auto even = BinaryOperator::CreateAnd(test, zero, "even", block);
+ const auto up = BinaryOperator::CreateOr(plus, even, "up", block);
+
+ const auto inc = BinaryOperator::CreateAdd(ashr, one, "inc", block);
+ const auto rounded = SelectInst::Create(up, inc, ashr, "result", block);
+ result->addIncoming(rounded, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+
+ const auto res = SelectInst::Create(GenIsNormal(val, context, block), result, val, "res", block);
+ return SetterForInt128(res, block);
+ }
+#endif
+ static_assert(Scale <= NYql::NDecimal::MaxPrecision, "Too large scale!");
+};
+
+template <ui8 Precision>
+struct TCheckBounds {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ const auto v = arg.GetInt128();
+
+ using namespace NYql::NDecimal;
+
+ if (IsNormal<Precision>(v))
+ return arg;
+
+ return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto val = GetterForInt128(arg, block);
+
+ const auto& bounds = GenBounds<Precision>(context);
+ const auto good = GenInBounds(val, bounds.first, bounds.second, block);
+
+ const auto nan = GenIsNonComparable(val, context, block);
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto res = SelectInst::Create(good, arg, SetterForInt128(bad, block), "res", block);
+ return res;
+ }
+#endif
+ static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
+};
+
+}
+
+namespace {
+
+constexpr auto convert = "Convert";
+constexpr auto integral = "ToIntegral";
+constexpr auto decimal = "ToDecimal";
+
template <typename TInput, typename TOutput>
-void RegisterConvert(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionUnOpt<TInput, TOutput, TConvert, TUnaryArgsOpt>(registry, convert);
+void RegisterConvert(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionUnOpt<TInput, TOutput, TConvert, TUnaryArgsOpt>(registry, convert);
}
template <typename TInput, typename TOutput>
-void RegisterStringConvert(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionOpt<TInput, TOutput, TStringConvert, TUnaryArgsOpt>(registry, convert);
+void RegisterStringConvert(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionOpt<TInput, TOutput, TStringConvert, TUnaryArgsOpt>(registry, convert);
}
template <typename TOutput>
-void RegisterIntegralCasts(IBuiltinFunctionRegistry& registry) {
+void RegisterIntegralCasts(IBuiltinFunctionRegistry& registry) {
RegisterConvert<NUdf::TDataType<i8>, TOutput>(registry);
RegisterConvert<NUdf::TDataType<ui8>, TOutput>(registry);
RegisterConvert<NUdf::TDataType<i16>, TOutput>(registry);
RegisterConvert<NUdf::TDataType<ui16>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<i32>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<ui32>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<i64>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<ui64>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<bool>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<i32>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<ui32>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<i64>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<ui64>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<bool>, TOutput>(registry);
}
template <typename TInput>
-void RegisterDecimalConvertFromIntegral(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionOpt<NUdf::TDataType<TInput>, NUdf::TDataType<NUdf::TDecimal>, NDecimal::TConvertFromIntegral<TInput>, TUnaryArgsOpt>(registry, decimal);
+void RegisterDecimalConvertFromIntegral(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionOpt<NUdf::TDataType<TInput>, NUdf::TDataType<NUdf::TDecimal>, NDecimal::TConvertFromIntegral<TInput>, TUnaryArgsOpt>(registry, decimal);
}
-
+
template <typename TOutput>
-void RegisterDecimalConvertToIntegral(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<NDecimal::TConvertToIntegral<TOutput>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<TOutput>, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<NDecimal::TConvertToIntegral<TOutput>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<TOutput>, true>, TUnaryWrap>(registry, integral);
+void RegisterDecimalConvertToIntegral(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<NDecimal::TConvertToIntegral<TOutput>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<TOutput>, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<NDecimal::TConvertToIntegral<TOutput>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<TOutput>, true>, TUnaryWrap>(registry, integral);
}
-
-void RegisterDecimalConvert(IBuiltinFunctionRegistry& registry) {
- RegisterDecimalConvertFromIntegral<i8>(registry);
- RegisterDecimalConvertFromIntegral<ui8>(registry);
- RegisterDecimalConvertFromIntegral<i16>(registry);
- RegisterDecimalConvertFromIntegral<ui16>(registry);
- RegisterDecimalConvertFromIntegral<i32>(registry);
- RegisterDecimalConvertFromIntegral<ui32>(registry);
- RegisterDecimalConvertFromIntegral<i64>(registry);
- RegisterDecimalConvertFromIntegral<ui64>(registry);
-
- RegisterDecimalConvertToIntegral<i8>(registry);
- RegisterDecimalConvertToIntegral<ui8>(registry);
- RegisterDecimalConvertToIntegral<i16>(registry);
- RegisterDecimalConvertToIntegral<ui16>(registry);
- RegisterDecimalConvertToIntegral<i32>(registry);
- RegisterDecimalConvertToIntegral<ui32>(registry);
- RegisterDecimalConvertToIntegral<i64>(registry);
- RegisterDecimalConvertToIntegral<ui64>(registry);
-
- NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TScaleUp, TUnaryArgsOpt>(registry, "ScaleUp_");
- NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TScaleDown, TUnaryArgsOpt>(registry, "ScaleDown_");
- NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TCheckBounds, TUnaryArgsOpt>(registry, "CheckBounds_");
-
- NDecimal::RegisterCastFunctionForAllPrecisions<NDecimal::TToFloat, TUnaryArgsOpt, NUdf::TDataType<float>>(registry, "ToFloat_");
- NDecimal::RegisterCastFunctionForAllPrecisions<NDecimal::TToDouble, TUnaryArgsOpt, NUdf::TDataType<double>>(registry, "ToDouble_");
+
+void RegisterDecimalConvert(IBuiltinFunctionRegistry& registry) {
+ RegisterDecimalConvertFromIntegral<i8>(registry);
+ RegisterDecimalConvertFromIntegral<ui8>(registry);
+ RegisterDecimalConvertFromIntegral<i16>(registry);
+ RegisterDecimalConvertFromIntegral<ui16>(registry);
+ RegisterDecimalConvertFromIntegral<i32>(registry);
+ RegisterDecimalConvertFromIntegral<ui32>(registry);
+ RegisterDecimalConvertFromIntegral<i64>(registry);
+ RegisterDecimalConvertFromIntegral<ui64>(registry);
+
+ RegisterDecimalConvertToIntegral<i8>(registry);
+ RegisterDecimalConvertToIntegral<ui8>(registry);
+ RegisterDecimalConvertToIntegral<i16>(registry);
+ RegisterDecimalConvertToIntegral<ui16>(registry);
+ RegisterDecimalConvertToIntegral<i32>(registry);
+ RegisterDecimalConvertToIntegral<ui32>(registry);
+ RegisterDecimalConvertToIntegral<i64>(registry);
+ RegisterDecimalConvertToIntegral<ui64>(registry);
+
+ NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TScaleUp, TUnaryArgsOpt>(registry, "ScaleUp_");
+ NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TScaleDown, TUnaryArgsOpt>(registry, "ScaleDown_");
+ NDecimal::RegisterUnaryFunctionForAllPrecisions<NDecimal::TCheckBounds, TUnaryArgsOpt>(registry, "CheckBounds_");
+
+ NDecimal::RegisterCastFunctionForAllPrecisions<NDecimal::TToFloat, TUnaryArgsOpt, NUdf::TDataType<float>>(registry, "ToFloat_");
+ NDecimal::RegisterCastFunctionForAllPrecisions<NDecimal::TToDouble, TUnaryArgsOpt, NUdf::TDataType<double>>(registry, "ToDouble_");
}
template <typename TOutput>
-void RegisterRealCasts(IBuiltinFunctionRegistry& registry) {
- RegisterConvert<NUdf::TDataType<float>, TOutput>(registry);
- RegisterConvert<NUdf::TDataType<double>, TOutput>(registry);
+void RegisterRealCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterConvert<NUdf::TDataType<float>, TOutput>(registry);
+ RegisterConvert<NUdf::TDataType<double>, TOutput>(registry);
}
template <typename TInput, typename TOutput>
-void RegisterRealToIntegralCastsImpl(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<TFloatToIntegral<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<TFloatToIntegral<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
+void RegisterRealToIntegralCastsImpl(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<TFloatToIntegral<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<TFloatToIntegral<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
}
template <typename TInput>
-void RegisterRealToIntegralCasts(IBuiltinFunctionRegistry& registry) {
+void RegisterRealToIntegralCasts(IBuiltinFunctionRegistry& registry) {
RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i8>>(registry);
RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui8>>(registry);
RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i16>>(registry);
RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui16>>(registry);
- RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i32>>(registry);
- RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui32>>(registry);
- RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i64>>(registry);
- RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui64>>(registry);
- RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<bool>>(registry);
+ RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i32>>(registry);
+ RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui32>>(registry);
+ RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<i64>>(registry);
+ RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<ui64>>(registry);
+ RegisterRealToIntegralCastsImpl<TInput, NUdf::TDataType<bool>>(registry);
}
-template <typename TInput, typename TOutput>
-void RegisterWideToShortCastsImpl(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
-}
-
-template <typename TInput, typename TOutput,
- typename TInput::TLayout UpperBound = std::numeric_limits<typename TInput::TLayout>::max()>
-void RegisterWideToDateCastsImpl(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout, UpperBound>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout, UpperBound>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
-}
-
-void RegisterWideToIntervalCasts(IBuiltinFunctionRegistry& registry) {
- constexpr auto TimestampLimit = static_cast<i64>(NUdf::MAX_TIMESTAMP - 1ULL);
- RegisterFunctionImpl<TWideToShort<i64, i64, TimestampLimit, -TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<TWideToShort<i64, i64, TimestampLimit, -TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>, true>, TUnaryWrap>(registry, integral);
- RegisterFunctionImpl<TWideToShort<ui64, i64, TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TInterval>, false>, TUnaryStub>(registry, integral);
- RegisterFunctionImpl<TWideToShort<ui64, i64, TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TInterval>, true>, TUnaryWrap>(registry, integral);
-}
-
-template <typename TInput>
-void RegisterWideToUnsignedCasts(IBuiltinFunctionRegistry& registry) {
- RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui32>>(registry);
- RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui64>>(registry);
-}
-
-void RegisterWideToDateCasts(IBuiltinFunctionRegistry& registry) {
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
-
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzDate>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzDate>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
-}
-
-void RegisterWideToDatetimeCasts(IBuiltinFunctionRegistry& registry) {
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
-
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
-}
-
-void RegisterWideToTimestampCasts(IBuiltinFunctionRegistry& registry) {
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
-
- RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
- RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
-}
-
-void RegisterWideToShortIntegralCasts(IBuiltinFunctionRegistry& registry) {
- RegisterWideToUnsignedCasts<NUdf::TDataType<i8>>(registry);
- RegisterWideToUnsignedCasts<NUdf::TDataType<i16>>(registry);
- RegisterWideToUnsignedCasts<NUdf::TDataType<i32>>(registry);
- RegisterWideToUnsignedCasts<NUdf::TDataType<i64>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui8>, NUdf::TDataType<i8>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<i8>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<i16>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<i16>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i32>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i64>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<i16>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<i16>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i32>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i32>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui32>>(registry);
-
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>>(registry);
- RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i32>>(registry);
- RegisterWideToUnsignedCasts<NUdf::TDataType<NUdf::TInterval>>(registry);
-
- RegisterWideToDateCasts(registry);
- RegisterWideToDatetimeCasts(registry);
- RegisterWideToTimestampCasts(registry);
- RegisterWideToIntervalCasts(registry);
-}
-
-template <typename TDate>
-void RegisterFromDateConvert(IBuiltinFunctionRegistry& registry) {
+template <typename TInput, typename TOutput>
+void RegisterWideToShortCastsImpl(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
+}
+
+template <typename TInput, typename TOutput,
+ typename TInput::TLayout UpperBound = std::numeric_limits<typename TInput::TLayout>::max()>
+void RegisterWideToDateCastsImpl(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout, UpperBound>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<TWideToShort<typename TInput::TLayout, typename TOutput::TLayout, UpperBound>, TUnaryArgsWithNullableResultOpt<TInput, TOutput, true>, TUnaryWrap>(registry, integral);
+}
+
+void RegisterWideToIntervalCasts(IBuiltinFunctionRegistry& registry) {
+ constexpr auto TimestampLimit = static_cast<i64>(NUdf::MAX_TIMESTAMP - 1ULL);
+ RegisterFunctionImpl<TWideToShort<i64, i64, TimestampLimit, -TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<TWideToShort<i64, i64, TimestampLimit, -TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>, true>, TUnaryWrap>(registry, integral);
+ RegisterFunctionImpl<TWideToShort<ui64, i64, TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TInterval>, false>, TUnaryStub>(registry, integral);
+ RegisterFunctionImpl<TWideToShort<ui64, i64, TimestampLimit>, TUnaryArgsWithNullableResultOpt<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TInterval>, true>, TUnaryWrap>(registry, integral);
+}
+
+template <typename TInput>
+void RegisterWideToUnsignedCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui32>>(registry);
+ RegisterWideToShortCastsImpl<TInput, NUdf::TDataType<ui64>>(registry);
+}
+
+void RegisterWideToDateCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TDate>, NUdf::MAX_DATE - 1U>(registry);
+
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzDate>, NUdf::MAX_DATE - 1U>(registry);
+}
+
+void RegisterWideToDatetimeCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzDatetime>, NUdf::MAX_DATETIME - 1U>(registry);
+}
+
+void RegisterWideToTimestampCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
+
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
+ RegisterWideToDateCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::MAX_TIMESTAMP - 1U>(registry);
+}
+
+void RegisterWideToShortIntegralCasts(IBuiltinFunctionRegistry& registry) {
+ RegisterWideToUnsignedCasts<NUdf::TDataType<i8>>(registry);
+ RegisterWideToUnsignedCasts<NUdf::TDataType<i16>>(registry);
+ RegisterWideToUnsignedCasts<NUdf::TDataType<i32>>(registry);
+ RegisterWideToUnsignedCasts<NUdf::TDataType<i64>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui8>, NUdf::TDataType<i8>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i16>, NUdf::TDataType<i8>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui16>, NUdf::TDataType<i16>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i32>, NUdf::TDataType<i16>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui32>, NUdf::TDataType<i32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<i64>, NUdf::TDataType<i32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i32>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<ui64>, NUdf::TDataType<i64>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<i16>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<i16>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<i32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<i32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<i32>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<ui32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<i32>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<ui32>>(registry);
+
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>>(registry);
+ RegisterWideToShortCastsImpl<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i32>>(registry);
+ RegisterWideToUnsignedCasts<NUdf::TDataType<NUdf::TInterval>>(registry);
+
+ RegisterWideToDateCasts(registry);
+ RegisterWideToDatetimeCasts(registry);
+ RegisterWideToTimestampCasts(registry);
+ RegisterWideToIntervalCasts(registry);
+}
+
+template <typename TDate>
+void RegisterFromDateConvert(IBuiltinFunctionRegistry& registry) {
RegisterConvert<TDate, NUdf::TDataType<i8>>(registry);
RegisterConvert<TDate, NUdf::TDataType<ui8>>(registry);
RegisterConvert<TDate, NUdf::TDataType<i16>>(registry);
@@ -974,94 +974,94 @@ void RegisterFromDateConvert(IBuiltinFunctionRegistry& registry) {
RegisterConvert<TDate, NUdf::TDataType<i64>>(registry);
RegisterConvert<TDate, NUdf::TDataType<ui64>>(registry);
- RegisterConvert<TDate, NUdf::TDataType<float>>(registry);
- RegisterConvert<TDate, NUdf::TDataType<double>>(registry);
+ RegisterConvert<TDate, NUdf::TDataType<float>>(registry);
+ RegisterConvert<TDate, NUdf::TDataType<double>>(registry);
+}
+
+void RegisterToDateConvert(IBuiltinFunctionRegistry& registry) {
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+
+ RegisterConvert<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterConvert<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterConvert<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TInterval>>(registry);
+
+ // Unsafe converts from layout type. Only for internal use.
+ RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterConvert<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterConvert<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>>(registry);
+}
+
+template <typename TInput, typename TOutput, bool Tz = false>
+void RegisterRescaleOpt(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<TDatetimeRescale<typename TInput::TLayout, typename TOutput::TLayout, Tz>, TUnaryArgsOpt<TInput, TOutput, false>, TUnaryStub>(registry, convert);
+ RegisterFunctionImpl<TDatetimeRescale<typename TInput::TLayout, typename TOutput::TLayout, Tz>, TUnaryArgsOpt<TInput, TOutput, true>, TUnaryWrap>(registry, convert);
}
-void RegisterToDateConvert(IBuiltinFunctionRegistry& registry) {
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzDate>>(registry);
-
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
-
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
-
- RegisterConvert<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterConvert<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterConvert<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterConvert<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TInterval>>(registry);
-
- // Unsafe converts from layout type. Only for internal use.
- RegisterConvert<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterConvert<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterConvert<NUdf::TDataType<ui64>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterConvert<NUdf::TDataType<i64>, NUdf::TDataType<NUdf::TInterval>>(registry);
+void RegisterDatetimeRescale(IBuiltinFunctionRegistry& registry) {
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzDatetime>, true>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzTimestamp>, true>(registry);
+
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzDate>, true>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>, true>(registry);
+
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDate>, true>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>, true>(registry);
+}
+
+template <typename TInput, typename TOutput, bool Clenup = false>
+void RegisterTzDateimeOpt(IBuiltinFunctionRegistry& registry) {
+ RegisterFunctionImpl<TDatetimeTzStub<Clenup>, TUnaryArgsOpt<TInput, TOutput, false>, TUnaryStub>(registry, convert);
+ RegisterFunctionImpl<TDatetimeTzStub<Clenup>, TUnaryArgsOpt<TInput, TOutput, true>, TUnaryWrap>(registry, convert);
+}
+
+void RegisterTzDateimeConvert(IBuiltinFunctionRegistry& registry) {
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDate>>(registry);
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDate>, true>(registry);
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDatetime>, true>(registry);
+ RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTimestamp>, true>(registry);
}
-template <typename TInput, typename TOutput, bool Tz = false>
-void RegisterRescaleOpt(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<TDatetimeRescale<typename TInput::TLayout, typename TOutput::TLayout, Tz>, TUnaryArgsOpt<TInput, TOutput, false>, TUnaryStub>(registry, convert);
- RegisterFunctionImpl<TDatetimeRescale<typename TInput::TLayout, typename TOutput::TLayout, Tz>, TUnaryArgsOpt<TInput, TOutput, true>, TUnaryWrap>(registry, convert);
-}
-
-void RegisterDatetimeRescale(IBuiltinFunctionRegistry& registry) {
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
-
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDate>>(registry);
-
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDate>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
-
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzDatetime>, true>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TTzTimestamp>, true>(registry);
-
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzDate>, true>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TTzTimestamp>, true>(registry);
-
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDate>, true>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterRescaleOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTzDatetime>, true>(registry);
-}
-
-template <typename TInput, typename TOutput, bool Clenup = false>
-void RegisterTzDateimeOpt(IBuiltinFunctionRegistry& registry) {
- RegisterFunctionImpl<TDatetimeTzStub<Clenup>, TUnaryArgsOpt<TInput, TOutput, false>, TUnaryStub>(registry, convert);
- RegisterFunctionImpl<TDatetimeTzStub<Clenup>, TUnaryArgsOpt<TInput, TOutput, true>, TUnaryWrap>(registry, convert);
-}
-
-void RegisterTzDateimeConvert(IBuiltinFunctionRegistry& registry) {
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TTzDate>>(registry);
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
-
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TDate>, true>(registry);
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzDatetime>, NUdf::TDataType<NUdf::TDatetime>, true>(registry);
- RegisterTzDateimeOpt<NUdf::TDataType<NUdf::TTzTimestamp>, NUdf::TDataType<NUdf::TTimestamp>, true>(registry);
-}
-
void RegisterJsonDocumentConvert(IBuiltinFunctionRegistry& registry) {
// String/Utf8 -> JsonDocument and JsonDocument -> String/Utf8 conversions. TStringConvert is used as a placeholder because
// actual conversions are handled by ValueFromString and ValueToString in mkql_type_ops.cpp
@@ -1073,11 +1073,11 @@ void RegisterJsonDocumentConvert(IBuiltinFunctionRegistry& registry) {
// Json -> JsonDocument and JsonDocument -> Json conversions
RegisterFunctionOpt<NUdf::TDataType<NUdf::TJson>, NUdf::TDataType<NUdf::TJsonDocument>, TJsonToJsonDocumentConvert, TUnaryArgsOpt>(registry, convert);
RegisterFunctionOpt<NUdf::TDataType<NUdf::TJsonDocument>, NUdf::TDataType<NUdf::TJson>, TJsonDocumentToJsonConvert, TUnaryArgsOpt>(registry, convert);
-}
-
}
-void RegisterConvert(IBuiltinFunctionRegistry& registry) {
+}
+
+void RegisterConvert(IBuiltinFunctionRegistry& registry) {
RegisterIntegralCasts<NUdf::TDataType<i32>>(registry);
RegisterIntegralCasts<NUdf::TDataType<ui32>>(registry);
RegisterIntegralCasts<NUdf::TDataType<i64>>(registry);
@@ -1091,17 +1091,17 @@ void RegisterConvert(IBuiltinFunctionRegistry& registry) {
RegisterIntegralCasts<NUdf::TDataType<float>>(registry);
RegisterIntegralCasts<NUdf::TDataType<double>>(registry);
- RegisterWideToShortIntegralCasts(registry);
-
- RegisterRealCasts<NUdf::TDataType<i8>>(registry);
- RegisterRealCasts<NUdf::TDataType<ui8>>(registry);
- RegisterRealCasts<NUdf::TDataType<i16>>(registry);
- RegisterRealCasts<NUdf::TDataType<ui16>>(registry);
- RegisterRealCasts<NUdf::TDataType<i32>>(registry);
- RegisterRealCasts<NUdf::TDataType<ui32>>(registry);
- RegisterRealCasts<NUdf::TDataType<i64>>(registry);
- RegisterRealCasts<NUdf::TDataType<ui64>>(registry);
-
+ RegisterWideToShortIntegralCasts(registry);
+
+ RegisterRealCasts<NUdf::TDataType<i8>>(registry);
+ RegisterRealCasts<NUdf::TDataType<ui8>>(registry);
+ RegisterRealCasts<NUdf::TDataType<i16>>(registry);
+ RegisterRealCasts<NUdf::TDataType<ui16>>(registry);
+ RegisterRealCasts<NUdf::TDataType<i32>>(registry);
+ RegisterRealCasts<NUdf::TDataType<ui32>>(registry);
+ RegisterRealCasts<NUdf::TDataType<i64>>(registry);
+ RegisterRealCasts<NUdf::TDataType<ui64>>(registry);
+
RegisterRealCasts<NUdf::TDataType<float>>(registry);
RegisterRealCasts<NUdf::TDataType<double>>(registry);
@@ -1114,19 +1114,19 @@ void RegisterConvert(IBuiltinFunctionRegistry& registry) {
RegisterStringConvert<NUdf::TDataType<NUdf::TJson>, NUdf::TDataType<char*>>(registry);
RegisterStringConvert<NUdf::TDataType<NUdf::TJson>, NUdf::TDataType<NUdf::TUtf8>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TDate>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TDatetime>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TTimestamp>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TInterval>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzDate>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzDatetime>>(registry);
- RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
-
- RegisterTzDateimeConvert(registry);
- RegisterDatetimeRescale(registry);
- RegisterToDateConvert(registry);
-
- RegisterDecimalConvert(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TDate>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TDatetime>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TTimestamp>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TInterval>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzDate>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzDatetime>>(registry);
+ RegisterFromDateConvert<NUdf::TDataType<NUdf::TTzTimestamp>>(registry);
+
+ RegisterTzDateimeConvert(registry);
+ RegisterDatetimeRescale(registry);
+ RegisterToDateConvert(registry);
+
+ RegisterDecimalConvert(registry);
RegisterJsonDocumentConvert(registry);
}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_countbits.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_countbits.cpp
index e736792bbc..725148683e 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_countbits.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_countbits.cpp
@@ -7,31 +7,31 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TCountBits : public TSimpleArithmeticUnary<TInput, TOutput, TCountBits<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return PopCount(val);
- }
-
+template<typename TInput, typename TOutput>
+struct TCountBits : public TSimpleArithmeticUnary<TInput, TOutput, TCountBits<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return PopCount(val);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto fnType = FunctionType::get(arg->getType(), {arg->getType()}, false);
- const auto& name = GetFuncNameForType<TInput>("llvm.ctpop");
+ static Value* Gen(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto fnType = FunctionType::get(arg->getType(), {arg->getType()}, false);
+ const auto& name = GetFuncNameForType<TInput>("llvm.ctpop");
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto result = CallInst::Create(func, {arg}, "popcount", block);
- return StaticCast<TInput, TOutput>(result, context, block);
- }
-#endif
-};
+ const auto result = CallInst::Create(func, {arg}, "popcount", block);
+ return StaticCast<TInput, TOutput>(result, context, block);
+ }
+#endif
+};
}
-void RegisterCountBits(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryIntegralFunctionOpt<TCountBits, TUnaryArgsOpt>(registry, "CountBits");
+void RegisterCountBits(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryIntegralFunctionOpt<TCountBits, TUnaryArgsOpt>(registry, "CountBits");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_datetime.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_datetime.h
index 8c093eb6e9..46f1567412 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_datetime.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_datetime.h
@@ -1,164 +1,164 @@
-#pragma once
-
-#include "mkql_builtins_impl.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-using TScaledDate = i64;
-
-constexpr TScaledDate TDateScale = 86400000000ll;
-constexpr TScaledDate TDatetimeScale = 1000000ll;
-
-inline bool IsBadDateTime(TScaledDate val) {
- return val < 0 || val >= TScaledDate(NUdf::MAX_TIMESTAMP);
-}
-
-inline bool IsBadInterval(TScaledDate val) {
- return val <= -TScaledDate(NUdf::MAX_TIMESTAMP) || val >= TScaledDate(NUdf::MAX_TIMESTAMP);
-}
-
-template<typename TSrc> inline
-TScaledDate ToScaledDate(TSrc src);
-
-template<typename TDst> inline
-TDst FromScaledDate(TScaledDate src);
-
-
-template<> inline
-TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TDate>::TLayout src) {
- return src * TDateScale;
-}
-
-template<> inline
-TScaledDate ToScaledDate(std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout> src) {
- return src * TDateScale;
-}
-
-template<> inline
-NUdf::TDataType<NUdf::TDate>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(TScaledDate src) {
- return src / TDateScale;
-}
-
-template<> inline
-TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TDatetime>::TLayout src) {
- return src * TDatetimeScale;
-}
-
-template<> inline
-TScaledDate ToScaledDate(std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout> src) {
- return src * TDatetimeScale;
-}
-
-template<> inline
-NUdf::TDataType<NUdf::TDatetime>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(TScaledDate src) {
- return src / TDatetimeScale;
-}
-
-template<> inline
-TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TTimestamp>::TLayout src) {
- return src;
-}
-
-template<> inline
-NUdf::TDataType<NUdf::TTimestamp>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(TScaledDate src) {
- return src;
-}
-
-template<> inline
-TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TInterval>::TLayout src) {
- return src;
-}
-
-template<> inline
-NUdf::TDataType<NUdf::TInterval>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(TScaledDate src) {
- return src;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-inline Value* GenIsBadDateTime(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, ConstantInt::get(Type::getInt64Ty(context), 0), "lt", block);
- const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), NUdf::MAX_TIMESTAMP), "ge", block);
- const auto bad = BinaryOperator::CreateOr(lt, ge, "or", block);
- return bad;
-}
-
-inline Value* GenIsBadInterval(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, ConstantInt::get(Type::getInt64Ty(context), -(i64)NUdf::MAX_TIMESTAMP), "le", block);
- const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), +(i64)NUdf::MAX_TIMESTAMP), "ge", block);
- const auto bad = BinaryOperator::CreateOr(le, ge, "or", block);
- return bad;
-}
-
-template<typename TSrc> inline
-Value* GenToScaledDate(Value* value, LLVMContext &context, BasicBlock* block);
-
-template<typename TDst> inline
-Value* GenFromScaledDate(Value* value, LLVMContext &context, BasicBlock* block);
-
-template<> inline
-Value* GenToScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto cast = StaticCast<NUdf::TDataType<NUdf::TDate>::TLayout, TScaledDate>(value, context, block);
- const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDateScale), "mul", block);
- return mul;
-}
-
-template<> inline
-Value* GenToScaledDate<std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout>>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto cast = StaticCast<std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout>, TScaledDate>(value, context, block);
- const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDateScale), "mul", block);
- return mul;
-}
-
-template<> inline
-Value* GenFromScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), TDateScale), "div", block);
- const auto cast = StaticCast<TScaledDate, NUdf::TDataType<NUdf::TDate>::TLayout>(div, context, block);
- return cast;
-}
-
-template<> inline
-Value* GenToScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto cast = StaticCast<NUdf::TDataType<NUdf::TDatetime>::TLayout, TScaledDate>(value, context, block);
- const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDatetimeScale), "mul", block);
- return mul;
-}
-
-template<> inline
-Value* GenToScaledDate<std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout>>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto cast = StaticCast<std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout>, TScaledDate>(value, context, block);
- const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDatetimeScale), "mul", block);
- return mul;
-}
-
-template<> inline
-Value* GenFromScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), TDatetimeScale), "div", block);
- const auto cast = StaticCast<TScaledDate, NUdf::TDataType<NUdf::TDatetime>::TLayout>(div, context, block);
- return cast;
-}
-
-template<> inline
-Value* GenToScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- return StaticCast<NUdf::TDataType<NUdf::TTimestamp>::TLayout, TScaledDate>(value, context, block);
-}
-
-template<> inline
-Value* GenFromScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- return StaticCast<TScaledDate, NUdf::TDataType<NUdf::TTimestamp>::TLayout>(value, context, block);
-}
-
-template<> inline
-Value* GenToScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- return StaticCast<NUdf::TDataType<NUdf::TInterval>::TLayout, TScaledDate>(value, context, block);
-}
-
-template<> inline
-Value* GenFromScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
- return StaticCast<TScaledDate, NUdf::TDataType<NUdf::TInterval>::TLayout>(value, context, block);
-}
-
-#endif
-
-}
-}
+#pragma once
+
+#include "mkql_builtins_impl.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+using TScaledDate = i64;
+
+constexpr TScaledDate TDateScale = 86400000000ll;
+constexpr TScaledDate TDatetimeScale = 1000000ll;
+
+inline bool IsBadDateTime(TScaledDate val) {
+ return val < 0 || val >= TScaledDate(NUdf::MAX_TIMESTAMP);
+}
+
+inline bool IsBadInterval(TScaledDate val) {
+ return val <= -TScaledDate(NUdf::MAX_TIMESTAMP) || val >= TScaledDate(NUdf::MAX_TIMESTAMP);
+}
+
+template<typename TSrc> inline
+TScaledDate ToScaledDate(TSrc src);
+
+template<typename TDst> inline
+TDst FromScaledDate(TScaledDate src);
+
+
+template<> inline
+TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TDate>::TLayout src) {
+ return src * TDateScale;
+}
+
+template<> inline
+TScaledDate ToScaledDate(std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout> src) {
+ return src * TDateScale;
+}
+
+template<> inline
+NUdf::TDataType<NUdf::TDate>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(TScaledDate src) {
+ return src / TDateScale;
+}
+
+template<> inline
+TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TDatetime>::TLayout src) {
+ return src * TDatetimeScale;
+}
+
+template<> inline
+TScaledDate ToScaledDate(std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout> src) {
+ return src * TDatetimeScale;
+}
+
+template<> inline
+NUdf::TDataType<NUdf::TDatetime>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(TScaledDate src) {
+ return src / TDatetimeScale;
+}
+
+template<> inline
+TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TTimestamp>::TLayout src) {
+ return src;
+}
+
+template<> inline
+NUdf::TDataType<NUdf::TTimestamp>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(TScaledDate src) {
+ return src;
+}
+
+template<> inline
+TScaledDate ToScaledDate(NUdf::TDataType<NUdf::TInterval>::TLayout src) {
+ return src;
+}
+
+template<> inline
+NUdf::TDataType<NUdf::TInterval>::TLayout FromScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(TScaledDate src) {
+ return src;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+inline Value* GenIsBadDateTime(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, ConstantInt::get(Type::getInt64Ty(context), 0), "lt", block);
+ const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), NUdf::MAX_TIMESTAMP), "ge", block);
+ const auto bad = BinaryOperator::CreateOr(lt, ge, "or", block);
+ return bad;
+}
+
+inline Value* GenIsBadInterval(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, ConstantInt::get(Type::getInt64Ty(context), -(i64)NUdf::MAX_TIMESTAMP), "le", block);
+ const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), +(i64)NUdf::MAX_TIMESTAMP), "ge", block);
+ const auto bad = BinaryOperator::CreateOr(le, ge, "or", block);
+ return bad;
+}
+
+template<typename TSrc> inline
+Value* GenToScaledDate(Value* value, LLVMContext &context, BasicBlock* block);
+
+template<typename TDst> inline
+Value* GenFromScaledDate(Value* value, LLVMContext &context, BasicBlock* block);
+
+template<> inline
+Value* GenToScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto cast = StaticCast<NUdf::TDataType<NUdf::TDate>::TLayout, TScaledDate>(value, context, block);
+ const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDateScale), "mul", block);
+ return mul;
+}
+
+template<> inline
+Value* GenToScaledDate<std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout>>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto cast = StaticCast<std::make_signed_t<NUdf::TDataType<NUdf::TDate>::TLayout>, TScaledDate>(value, context, block);
+ const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDateScale), "mul", block);
+ return mul;
+}
+
+template<> inline
+Value* GenFromScaledDate<NUdf::TDataType<NUdf::TDate>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), TDateScale), "div", block);
+ const auto cast = StaticCast<TScaledDate, NUdf::TDataType<NUdf::TDate>::TLayout>(div, context, block);
+ return cast;
+}
+
+template<> inline
+Value* GenToScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto cast = StaticCast<NUdf::TDataType<NUdf::TDatetime>::TLayout, TScaledDate>(value, context, block);
+ const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDatetimeScale), "mul", block);
+ return mul;
+}
+
+template<> inline
+Value* GenToScaledDate<std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout>>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto cast = StaticCast<std::make_signed_t<NUdf::TDataType<NUdf::TDatetime>::TLayout>, TScaledDate>(value, context, block);
+ const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), TDatetimeScale), "mul", block);
+ return mul;
+}
+
+template<> inline
+Value* GenFromScaledDate<NUdf::TDataType<NUdf::TDatetime>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), TDatetimeScale), "div", block);
+ const auto cast = StaticCast<TScaledDate, NUdf::TDataType<NUdf::TDatetime>::TLayout>(div, context, block);
+ return cast;
+}
+
+template<> inline
+Value* GenToScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ return StaticCast<NUdf::TDataType<NUdf::TTimestamp>::TLayout, TScaledDate>(value, context, block);
+}
+
+template<> inline
+Value* GenFromScaledDate<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ return StaticCast<TScaledDate, NUdf::TDataType<NUdf::TTimestamp>::TLayout>(value, context, block);
+}
+
+template<> inline
+Value* GenToScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ return StaticCast<NUdf::TDataType<NUdf::TInterval>::TLayout, TScaledDate>(value, context, block);
+}
+
+template<> inline
+Value* GenFromScaledDate<NUdf::TDataType<NUdf::TInterval>::TLayout>(Value* value, LLVMContext &context, BasicBlock* block) {
+ return StaticCast<TScaledDate, NUdf::TDataType<NUdf::TInterval>::TLayout>(value, context, block);
+}
+
+#endif
+
+}
+}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_dec.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_dec.cpp
index 78f38012dd..c88a568103 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_dec.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_dec.cpp
@@ -1,72 +1,72 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TDecrement : public TSimpleArithmeticUnary<TInput, TOutput, TDecrement<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return --val;
- }
-
+template<typename TInput, typename TOutput>
+struct TDecrement : public TSimpleArithmeticUnary<TInput, TOutput, TDecrement<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return --val;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_integral<TOutput>() ?
- BinaryOperator::CreateSub(arg, ConstantInt::get(arg->getType(), 1), "dec", block):
- BinaryOperator::CreateFSub(arg, ConstantFP::get(arg->getType(), 1.0), "dec", block);
- }
-#endif
-};
-
-template <ui8 Precision>
-struct TDecimalDec {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- auto v = arg.GetInt128();
-
- using namespace NYql::NDecimal;
-
- const auto& bounds = GetBounds<Precision, true, false>();
-
- if (v > bounds.first && v < bounds.second)
- return NUdf::TUnboxedValuePod(--v);
-
- return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
+ static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_integral<TOutput>() ?
+ BinaryOperator::CreateSub(arg, ConstantInt::get(arg->getType(), 1), "dec", block):
+ BinaryOperator::CreateFSub(arg, ConstantFP::get(arg->getType(), 1.0), "dec", block);
}
-
+#endif
+};
+
+template <ui8 Precision>
+struct TDecimalDec {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ auto v = arg.GetInt128();
+
+ using namespace NYql::NDecimal;
+
+ const auto& bounds = GetBounds<Precision, true, false>();
+
+ if (v > bounds.first && v < bounds.second)
+ return NUdf::TUnboxedValuePod(--v);
+
+ return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto& bounds = NDecimal::GenBounds<Precision, true, false>(context);
-
- const auto val = GetterForInt128(arg, block);
- const auto sub = BinaryOperator::CreateSub(val, ConstantInt::get(val->getType(), 1), "sub", block);
-
- const auto gt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, sub, bounds.first, "gt", block);
- const auto lt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SLT, val, bounds.second, "lt", block);
-
- const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
- const auto nan = NDecimal::GenIsNonComparable(val, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto dec = SelectInst::Create(good, sub, bad, "dec", block);
- return SetterForInt128(dec, block);
- }
-#endif
- static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto& bounds = NDecimal::GenBounds<Precision, true, false>(context);
+
+ const auto val = GetterForInt128(arg, block);
+ const auto sub = BinaryOperator::CreateSub(val, ConstantInt::get(val->getType(), 1), "sub", block);
+
+ const auto gt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, sub, bounds.first, "gt", block);
+ const auto lt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SLT, val, bounds.second, "lt", block);
+
+ const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
+ const auto nan = NDecimal::GenIsNonComparable(val, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto dec = SelectInst::Create(good, sub, bad, "dec", block);
+ return SetterForInt128(dec, block);
+ }
+#endif
+ static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
};
}
-void RegisterDecrement(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryNumericFunctionOpt<TDecrement, TUnaryArgsOpt>(registry, "Decrement");
- NDecimal::RegisterUnaryFunctionForAllPrecisions<TDecimalDec, TUnaryArgsOpt>(registry, "Dec_");
+void RegisterDecrement(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryNumericFunctionOpt<TDecrement, TUnaryArgsOpt>(registry, "Decrement");
+ NDecimal::RegisterUnaryFunctionForAllPrecisions<TDecimalDec, TUnaryArgsOpt>(registry, "Dec_");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.cpp
index b48bb8968f..f89b2e7d9a 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.cpp
@@ -1,72 +1,72 @@
-#include "mkql_builtins_decimal.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-namespace NDecimal {
-#ifndef MKQL_DISABLE_CODEGEN
-
-ConstantInt* GenConstant(NYql::NDecimal::TInt128 value, LLVMContext &context) {
- const auto& pair = NYql::NDecimal::MakePair(value);
- const uint64_t init[] = {pair.first, pair.second};
- return ConstantInt::get(context, APInt(128, 2, init));
-}
-
-template<bool IncludeBounds>
-Value* GenInBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block) {
- const auto lt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, val, high, "lt", block);
- const auto gt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, val, low, "gt", block);
- const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
- return good;
-}
-
-template<bool IncludeBounds>
-Value* GenOutOfBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block) {
- const auto lt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, val, low, "lt", block);
- const auto gt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, val, high, "gt", block);
- const auto bad = BinaryOperator::CreateOr(lt, gt, "or", block);
- return bad;
-}
-
-template Value* GenInBounds<true>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-template Value* GenInBounds<false>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-template Value* GenOutOfBounds<true>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-template Value* GenOutOfBounds<false>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-
-Value* GenIsError(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalNan(context), "gt", block);
- const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalMinusNan(context), "lt", block);
- const auto bad = BinaryOperator::CreateOr(lt, gt, "or", block);
- return bad;
-}
-
-Value* GenIsNormal(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalPlusInf(context), "lt", block);
- const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalMinusInf(context), "gt", block);
- const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
- return good;
-}
-
-Value* GenIsAbnormal(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, GetDecimalMinusInf(context), "le", block);
- const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, GetDecimalPlusInf(context), "ge", block);
- const auto bad = BinaryOperator::CreateOr(le, ge, "or", block);
- return bad;
-}
-
-Value* GenIsComparable(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, GetDecimalPlusInf(context), "le", block);
- const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, GetDecimalMinusInf(context), "ge", block);
- const auto good = BinaryOperator::CreateAnd(le, ge, "and", block);
- return good;
-}
-
-Value* GenIsNonComparable(Value* val, LLVMContext &context, BasicBlock* block) {
- const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalPlusInf(context), "gt", block);
- const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalMinusInf(context), "lt", block);
- const auto bad = BinaryOperator::CreateOr(gt, lt, "or", block);
- return bad;
-}
-#endif
-}
-}
-}
+#include "mkql_builtins_decimal.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+namespace NDecimal {
+#ifndef MKQL_DISABLE_CODEGEN
+
+ConstantInt* GenConstant(NYql::NDecimal::TInt128 value, LLVMContext &context) {
+ const auto& pair = NYql::NDecimal::MakePair(value);
+ const uint64_t init[] = {pair.first, pair.second};
+ return ConstantInt::get(context, APInt(128, 2, init));
+}
+
+template<bool IncludeBounds>
+Value* GenInBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block) {
+ const auto lt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, val, high, "lt", block);
+ const auto gt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, val, low, "gt", block);
+ const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
+ return good;
+}
+
+template<bool IncludeBounds>
+Value* GenOutOfBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block) {
+ const auto lt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, val, low, "lt", block);
+ const auto gt = CmpInst::Create(Instruction::ICmp, IncludeBounds ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, val, high, "gt", block);
+ const auto bad = BinaryOperator::CreateOr(lt, gt, "or", block);
+ return bad;
+}
+
+template Value* GenInBounds<true>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+template Value* GenInBounds<false>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+template Value* GenOutOfBounds<true>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+template Value* GenOutOfBounds<false>(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+
+Value* GenIsError(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalNan(context), "gt", block);
+ const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalMinusNan(context), "lt", block);
+ const auto bad = BinaryOperator::CreateOr(lt, gt, "or", block);
+ return bad;
+}
+
+Value* GenIsNormal(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalPlusInf(context), "lt", block);
+ const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalMinusInf(context), "gt", block);
+ const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
+ return good;
+}
+
+Value* GenIsAbnormal(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, GetDecimalMinusInf(context), "le", block);
+ const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, GetDecimalPlusInf(context), "ge", block);
+ const auto bad = BinaryOperator::CreateOr(le, ge, "or", block);
+ return bad;
+}
+
+Value* GenIsComparable(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, GetDecimalPlusInf(context), "le", block);
+ const auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, GetDecimalMinusInf(context), "ge", block);
+ const auto good = BinaryOperator::CreateAnd(le, ge, "and", block);
+ return good;
+}
+
+Value* GenIsNonComparable(Value* val, LLVMContext &context, BasicBlock* block) {
+ const auto gt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, GetDecimalPlusInf(context), "gt", block);
+ const auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, GetDecimalMinusInf(context), "lt", block);
+ const auto bad = BinaryOperator::CreateOr(gt, lt, "or", block);
+ return bad;
+}
+#endif
+}
+}
+}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h
index b1706f230c..2289a5f4f6 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_decimal.h
@@ -1,298 +1,298 @@
-#pragma once
-
-#include "mkql_builtins_impl.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-namespace NDecimal {
-#ifndef MKQL_DISABLE_CODEGEN
-
-ConstantInt* GenConstant(NYql::NDecimal::TInt128 value, LLVMContext &context);
-
-template<ui8 Precision, bool IncLow = false, bool DecHigh = false>
-inline std::pair<ConstantInt*, ConstantInt*> GenBounds(LLVMContext &context) {
- const auto& bounds = NYql::NDecimal::GetBounds<Precision, IncLow, DecHigh>();
- return std::make_pair(GenConstant(bounds.first, context), GenConstant(bounds.second, context));
-}
-
-template<bool IncludeBounds = false>
-Value* GenInBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-
-template<bool IncludeBounds = true>
-Value* GenOutOfBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
-
-Value* GenIsError(Value* val, LLVMContext &context, BasicBlock* block);
-Value* GenIsNormal(Value* val, LLVMContext &context, BasicBlock* block);
-Value* GenIsAbnormal(Value* val, LLVMContext &context, BasicBlock* block);
-Value* GenIsComparable(Value* val, LLVMContext &context, BasicBlock* block);
-Value* GenIsNonComparable(Value* val, LLVMContext &context, BasicBlock* block);
-
-template <bool And, Value* (*Checker)(Value*, LLVMContext&, BasicBlock*)>
-inline Value* CheckBoth(Value* left, Value* right, LLVMContext &context, BasicBlock* block) {
- const auto l = Checker(left, context, block);
- const auto r = Checker(right, context, block);
- return And ? BinaryOperator::CreateAnd(l, r, "and", block) : BinaryOperator::CreateOr(l, r, "or", block);
-}
-#endif
-
-template <
- class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, true>, TBinaryWrap<true, true>>(registry, name);
-}
-
-template <
- class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true>, TAggregateWrap>(registry, name);
-}
-
-template <
- ui8 Precision,
- template<ui8> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterBinaryFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
-}
-
-template <
- ui8 Precision,
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterAggregateFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
-}
-
-template <
- class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterUnaryFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false>, TUnaryStub>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true>, TUnaryWrap>(registry, name);
-}
-
-template <
- ui8 Precision,
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterUnaryFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterUnaryFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
-}
-
-template <
- class TFunc,
- template<typename, typename, bool> class TArgs,
- typename TOutput
->
-void RegisterCastFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, TOutput, false>, TUnaryStub>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, TOutput, true>, TUnaryWrap>(registry, name);
-}
-
-template <
- ui8 Precision,
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs,
- typename TOutput
->
-void RegisterCastFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCastFunction<TFunc<Precision>, TArgs, TOutput>(registry, TString(name) += ToString(Precision));
-}
-
-template <
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterUnaryFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterUnaryFunctionForPrecision<1, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<2, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<3, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<4, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<5, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<6, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<7, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<8, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<9, TFunc, TArgs>(registry, name);
-
- RegisterUnaryFunctionForPrecision<10, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<11, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<12, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<13, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<14, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<15, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<16, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<17, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<18, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<19, TFunc, TArgs>(registry, name);
-
- RegisterUnaryFunctionForPrecision<20, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<21, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<22, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<23, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<24, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<25, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<26, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<27, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<28, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<29, TFunc, TArgs>(registry, name);
-
- RegisterUnaryFunctionForPrecision<30, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<31, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<32, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<33, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<34, TFunc, TArgs>(registry, name);
- RegisterUnaryFunctionForPrecision<35, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs,
- typename TOutput
->
-void RegisterCastFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterCastFunctionForPrecision<0, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<1, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<2, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<3, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<4, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<5, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<6, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<7, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<8, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<9, TFunc, TArgs, TOutput>(registry, name);
-
- RegisterCastFunctionForPrecision<10, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<11, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<12, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<13, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<14, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<15, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<16, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<17, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<18, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<19, TFunc, TArgs, TOutput>(registry, name);
-
- RegisterCastFunctionForPrecision<20, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<21, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<22, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<23, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<24, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<25, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<26, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<27, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<28, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<29, TFunc, TArgs, TOutput>(registry, name);
-
- RegisterCastFunctionForPrecision<30, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<31, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<32, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<33, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<34, TFunc, TArgs, TOutput>(registry, name);
- RegisterCastFunctionForPrecision<35, TFunc, TArgs, TOutput>(registry, name);
-}
-
-template <
- template<ui8> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterBinaryFunctionForPrecision<1, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<2, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<3, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<4, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<5, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<6, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<7, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<8, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<9, TFunc, TArgs>(registry, name);
-
- RegisterBinaryFunctionForPrecision<10,TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<11, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<12, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<13, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<14, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<15, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<16, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<17, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<18, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<19, TFunc, TArgs>(registry, name);
-
- RegisterBinaryFunctionForPrecision<20, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<21, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<22, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<23, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<24, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<25, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<26, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<27, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<28, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<29, TFunc, TArgs>(registry, name);
-
- RegisterBinaryFunctionForPrecision<30, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<31, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<32, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<33, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<34, TFunc, TArgs>(registry, name);
- RegisterBinaryFunctionForPrecision<35, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<ui8> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterAggregateFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunctionForPrecision<1, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<2, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<3, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<4, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<5, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<6, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<7, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<8, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<9, TFunc, TArgs>(registry, name);
-
- RegisterAggregateFunctionForPrecision<10, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<11, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<12, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<13, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<14, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<15, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<16, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<17, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<18, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<19, TFunc, TArgs>(registry, name);
-
- RegisterAggregateFunctionForPrecision<20, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<21, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<22, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<23, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<24, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<25, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<26, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<27, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<28, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<29, TFunc, TArgs>(registry, name);
-
- RegisterAggregateFunctionForPrecision<30, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<31, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<32, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<33, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<34, TFunc, TArgs>(registry, name);
- RegisterAggregateFunctionForPrecision<35, TFunc, TArgs>(registry, name);
-}
-
-}
-}
-}
+#pragma once
+
+#include "mkql_builtins_impl.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+namespace NDecimal {
+#ifndef MKQL_DISABLE_CODEGEN
+
+ConstantInt* GenConstant(NYql::NDecimal::TInt128 value, LLVMContext &context);
+
+template<ui8 Precision, bool IncLow = false, bool DecHigh = false>
+inline std::pair<ConstantInt*, ConstantInt*> GenBounds(LLVMContext &context) {
+ const auto& bounds = NYql::NDecimal::GetBounds<Precision, IncLow, DecHigh>();
+ return std::make_pair(GenConstant(bounds.first, context), GenConstant(bounds.second, context));
+}
+
+template<bool IncludeBounds = false>
+Value* GenInBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+
+template<bool IncludeBounds = true>
+Value* GenOutOfBounds(Value* val, ConstantInt* low, ConstantInt* high, BasicBlock* block);
+
+Value* GenIsError(Value* val, LLVMContext &context, BasicBlock* block);
+Value* GenIsNormal(Value* val, LLVMContext &context, BasicBlock* block);
+Value* GenIsAbnormal(Value* val, LLVMContext &context, BasicBlock* block);
+Value* GenIsComparable(Value* val, LLVMContext &context, BasicBlock* block);
+Value* GenIsNonComparable(Value* val, LLVMContext &context, BasicBlock* block);
+
+template <bool And, Value* (*Checker)(Value*, LLVMContext&, BasicBlock*)>
+inline Value* CheckBoth(Value* left, Value* right, LLVMContext &context, BasicBlock* block) {
+ const auto l = Checker(left, context, block);
+ const auto r = Checker(right, context, block);
+ return And ? BinaryOperator::CreateAnd(l, r, "and", block) : BinaryOperator::CreateOr(l, r, "or", block);
+}
+#endif
+
+template <
+ class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBinaryFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, true>, TBinaryWrap<true, true>>(registry, name);
+}
+
+template <
+ class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true>, TAggregateWrap>(registry, name);
+}
+
+template <
+ ui8 Precision,
+ template<ui8> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBinaryFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterBinaryFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
+}
+
+template <
+ ui8 Precision,
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterAggregateFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
+}
+
+template <
+ class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterUnaryFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false>, TUnaryStub>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true>, TUnaryWrap>(registry, name);
+}
+
+template <
+ ui8 Precision,
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterUnaryFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterUnaryFunction<TFunc<Precision>, TArgs>(registry, TString(name) += ToString(Precision));
+}
+
+template <
+ class TFunc,
+ template<typename, typename, bool> class TArgs,
+ typename TOutput
+>
+void RegisterCastFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, TOutput, false>, TUnaryStub>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<NUdf::TDataType<NUdf::TDecimal>, TOutput, true>, TUnaryWrap>(registry, name);
+}
+
+template <
+ ui8 Precision,
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs,
+ typename TOutput
+>
+void RegisterCastFunctionForPrecision(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCastFunction<TFunc<Precision>, TArgs, TOutput>(registry, TString(name) += ToString(Precision));
+}
+
+template <
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterUnaryFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterUnaryFunctionForPrecision<1, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<2, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<3, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<4, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<5, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<6, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<7, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<8, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<9, TFunc, TArgs>(registry, name);
+
+ RegisterUnaryFunctionForPrecision<10, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<11, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<12, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<13, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<14, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<15, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<16, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<17, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<18, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<19, TFunc, TArgs>(registry, name);
+
+ RegisterUnaryFunctionForPrecision<20, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<21, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<22, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<23, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<24, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<25, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<26, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<27, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<28, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<29, TFunc, TArgs>(registry, name);
+
+ RegisterUnaryFunctionForPrecision<30, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<31, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<32, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<33, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<34, TFunc, TArgs>(registry, name);
+ RegisterUnaryFunctionForPrecision<35, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs,
+ typename TOutput
+>
+void RegisterCastFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterCastFunctionForPrecision<0, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<1, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<2, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<3, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<4, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<5, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<6, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<7, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<8, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<9, TFunc, TArgs, TOutput>(registry, name);
+
+ RegisterCastFunctionForPrecision<10, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<11, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<12, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<13, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<14, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<15, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<16, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<17, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<18, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<19, TFunc, TArgs, TOutput>(registry, name);
+
+ RegisterCastFunctionForPrecision<20, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<21, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<22, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<23, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<24, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<25, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<26, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<27, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<28, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<29, TFunc, TArgs, TOutput>(registry, name);
+
+ RegisterCastFunctionForPrecision<30, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<31, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<32, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<33, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<34, TFunc, TArgs, TOutput>(registry, name);
+ RegisterCastFunctionForPrecision<35, TFunc, TArgs, TOutput>(registry, name);
+}
+
+template <
+ template<ui8> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBinaryFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterBinaryFunctionForPrecision<1, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<2, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<3, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<4, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<5, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<6, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<7, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<8, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<9, TFunc, TArgs>(registry, name);
+
+ RegisterBinaryFunctionForPrecision<10,TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<11, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<12, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<13, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<14, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<15, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<16, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<17, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<18, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<19, TFunc, TArgs>(registry, name);
+
+ RegisterBinaryFunctionForPrecision<20, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<21, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<22, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<23, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<24, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<25, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<26, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<27, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<28, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<29, TFunc, TArgs>(registry, name);
+
+ RegisterBinaryFunctionForPrecision<30, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<31, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<32, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<33, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<34, TFunc, TArgs>(registry, name);
+ RegisterBinaryFunctionForPrecision<35, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<ui8> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterAggregateFunctionForAllPrecisions(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunctionForPrecision<1, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<2, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<3, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<4, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<5, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<6, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<7, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<8, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<9, TFunc, TArgs>(registry, name);
+
+ RegisterAggregateFunctionForPrecision<10, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<11, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<12, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<13, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<14, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<15, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<16, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<17, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<18, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<19, TFunc, TArgs>(registry, name);
+
+ RegisterAggregateFunctionForPrecision<20, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<21, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<22, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<23, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<24, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<25, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<26, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<27, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<28, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<29, TFunc, TArgs>(registry, name);
+
+ RegisterAggregateFunctionForPrecision<30, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<31, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<32, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<33, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<34, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunctionForPrecision<35, TFunc, TArgs>(registry, name);
+}
+
+}
+}
+}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp
index 552428ef45..b646376ac7 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp
@@ -1,5 +1,5 @@
#include "mkql_builtins_impl.h"
-#include "mkql_builtins_datetime.h"
+#include "mkql_builtins_datetime.h"
#include <ydb/library/yql/minikql/mkql_type_ops.h>
@@ -8,85 +8,85 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TDiv : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TDiv<TLeft, TRight, TOutput>> {
- static_assert(std::is_floating_point<TOutput>::value, "expected floating point");
+template<typename TLeft, typename TRight, typename TOutput>
+struct TDiv : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TDiv<TLeft, TRight, TOutput>> {
+ static_assert(std::is_floating_point<TOutput>::value, "expected floating point");
- static TOutput Do(TOutput left, TOutput right)
- {
- return left / right;
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left / right;
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return BinaryOperator::CreateFDiv(left, right, "div", block);
- }
-#endif
-};
-
-template <typename TLeft, typename TRight, typename TOutput>
-struct TIntegralDiv {
- static_assert(std::is_integral<TOutput>::value, "integral type expected");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
- {
- const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
- const auto rv = static_cast<TOutput>(right.template Get<TRight>());
-
- if (rv == 0 ||
- (std::is_signed<TOutput>::value && sizeof(TOutput) <= sizeof(TLeft) && rv == TOutput(-1) && lv == Min<TOutput>()))
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return BinaryOperator::CreateFDiv(left, right, "div", block);
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, typename TOutput>
+struct TIntegralDiv {
+ static_assert(std::is_integral<TOutput>::value, "integral type expected");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ {
+ const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
+ const auto rv = static_cast<TOutput>(right.template Get<TRight>());
+
+ if (rv == 0 ||
+ (std::is_signed<TOutput>::value && sizeof(TOutput) <= sizeof(TLeft) && rv == TOutput(-1) && lv == Min<TOutput>()))
{
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
-
- return NUdf::TUnboxedValuePod(lv / rv);
+
+ return NUdf::TUnboxedValuePod(lv / rv);
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
- const auto type = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(type, 0);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(type, 2, "result", done);
- result->addIncoming(zero, block);
-
- if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) {
- const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
- const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
- const auto all = BinaryOperator::CreateOr(check, two, "all", block);
- BranchInst::Create(done, good, all, block);
- } else {
- BranchInst::Create(done, good, check, block);
- }
-
- block = good;
- const auto div = std::is_signed<TOutput>() ? BinaryOperator::CreateSDiv(lv, rv, "div", block) : BinaryOperator::CreateUDiv(lv, rv, "div", block);
- const auto full = SetterFor<TOutput>(div, context, block);
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-};
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
+ const auto type = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(type, 0);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(type, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) {
+ const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
+ const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
+ const auto all = BinaryOperator::CreateOr(check, two, "all", block);
+ BranchInst::Create(done, good, all, block);
+ } else {
+ BranchInst::Create(done, good, check, block);
+ }
+
+ block = good;
+ const auto div = std::is_signed<TOutput>() ? BinaryOperator::CreateSDiv(lv, rv, "div", block) : BinaryOperator::CreateUDiv(lv, rv, "div", block);
+ const auto full = SetterFor<TOutput>(div, context, block);
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+};
template <typename TLeft, typename TRight, typename TOutput>
struct TNumDivInterval {
- static_assert(std::is_integral<TLeft>::value, "left must be integral");
- static_assert(std::is_integral<TRight>::value, "right must be integral");
+ static_assert(std::is_integral<TLeft>::value, "left must be integral");
+ static_assert(std::is_integral<TRight>::value, "right must be integral");
static_assert(std::is_same<TOutput, i64>::value, "expected i64");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
const auto rv = static_cast<TOutput>(right.template Get<TRight>());
@@ -97,63 +97,63 @@ struct TNumDivInterval {
return NUdf::TUnboxedValuePod();
}
- const auto ret = lv / rv;
- return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));;
+ const auto ret = lv / rv;
+ return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));;
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
- const auto type = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(type, 0);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(type, 2, "result", done);
- result->addIncoming(zero, block);
-
- const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
- const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
- const auto all = BinaryOperator::CreateOr(check, two, "all", block);
- BranchInst::Create(done, good, all, block);
-
-
- block = good;
- const auto div = BinaryOperator::CreateSDiv(lv, rv, "div", block);
- const auto full = SetterFor<TOutput>(div, context, block);
- const auto bad = GenIsBadInterval(div, context, block);
- const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
- result->addIncoming(sel, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
+ auto& context = ctx.Codegen->GetContext();
+ const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
+ const auto type = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(type, 0);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(type, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
+ const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
+ const auto all = BinaryOperator::CreateOr(check, two, "all", block);
+ BranchInst::Create(done, good, all, block);
+
+
+ block = good;
+ const auto div = BinaryOperator::CreateSDiv(lv, rv, "div", block);
+ const auto full = SetterFor<TOutput>(div, context, block);
+ const auto bad = GenIsBadInterval(div, context, block);
+ const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
+ result->addIncoming(sel, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
}
#endif
};
}
-void RegisterDiv(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryRealFunctionOpt<TDiv, TBinaryArgsOpt>(registry, "Div");
- RegisterBinaryIntegralFunctionOpt<TIntegralDiv, TBinaryArgsOptWithNullableResult>(registry, "Div");
+void RegisterDiv(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryRealFunctionOpt<TDiv, TBinaryArgsOpt>(registry, "Div");
+ RegisterBinaryIntegralFunctionOpt<TIntegralDiv, TBinaryArgsOptWithNullableResult>(registry, "Div");
+
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>,
+ NUdf::TDataType<i64>, TIntegralDiv, TBinaryArgsOptWithNullableResult>(registry, "Div");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<i64>, TIntegralDiv, TBinaryArgsOptWithNullableResult>(registry, "Div");
-
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui8>,
NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>,
- NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui16>,
- NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>,
- NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>,
+ NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui16>,
+ NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>,
+ NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui32>,
NUdf::TDataType<NUdf::TInterval>, TNumDivInterval, TBinaryArgsOptWithNullableResult>(registry, "Div");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i32>,
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp
index 05e8a5c502..79f24a52f4 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp
@@ -1,280 +1,280 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
- return x == y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
- return x >= T1(0) && static_cast<std::make_unsigned_t<T1>>(x) == y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
- return y >= T2(0) && x == static_cast<std::make_unsigned_t<T2>>(y);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return std::isnan(l) == std::isnan(r);
- }
- return l == r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenEqualsIntegral(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
-}
-
-template <bool Aggr>
-Value* GenEqualsFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenEqualsFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OEQ, lhs, rhs, "equals", block);
-}
-
-template <>
-Value* GenEqualsFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto ueq = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UEQ, lhs, rhs, "equals", block);
- const auto lord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "lord", block);
- const auto runo = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "runo", block);
- const auto once = BinaryOperator::CreateXor(lord, runo, "xor", block);
- return BinaryOperator::CreateAnd(ueq, once, "and", block);
-}
-
-template <typename T1, typename T2>
-Value* GenEqualsIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenEqualsIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenEqualsIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenEqualsIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenEqualsFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrEquals {
- static bool Simple(bool left, bool right)
- {
- return left == right;
- }
- static bool Join(bool one, bool two)
- {
- return one && two;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_EQ;
-
- static Value* GenJoin(Value* one, Value* two, BasicBlock* block)
- {
- return BinaryOperator::CreateAnd(one, two, "and", block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TEquals : public TCompareArithmeticBinary<TLeft, TRight, TEquals<TLeft, TRight, Aggr>>, public TAggrEquals {
- static bool Do(TLeft left, TRight right)
- {
- return Equals<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenEquals<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateEquals : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateEquals<TLeft, TRight, Aggr>>, public TAggrEquals {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- Equals<TLeft, TRight, Aggr>(left, right):
- Equals<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
+ return x == y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
+ return x >= T1(0) && static_cast<std::make_unsigned_t<T1>>(x) == y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
+ return y >= T2(0) && x == static_cast<std::make_unsigned_t<T2>>(y);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Equals(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return std::isnan(l) == std::isnan(r);
+ }
+ return l == r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenEqualsIntegral(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, rhs, "equals", block);
+}
+
+template <bool Aggr>
+Value* GenEqualsFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenEqualsFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OEQ, lhs, rhs, "equals", block);
+}
+
+template <>
+Value* GenEqualsFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto ueq = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UEQ, lhs, rhs, "equals", block);
+ const auto lord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "lord", block);
+ const auto runo = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "runo", block);
+ const auto once = BinaryOperator::CreateXor(lord, runo, "xor", block);
+ return BinaryOperator::CreateAnd(ueq, once, "and", block);
+}
+
+template <typename T1, typename T2>
+Value* GenEqualsIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenEqualsIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenEqualsIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenEqualsIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenEqualsFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrEquals {
+ static bool Simple(bool left, bool right)
+ {
+ return left == right;
+ }
+ static bool Join(bool one, bool two)
+ {
+ return one && two;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_EQ;
+
+ static Value* GenJoin(Value* one, Value* two, BasicBlock* block)
+ {
+ return BinaryOperator::CreateAnd(one, two, "and", block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TEquals : public TCompareArithmeticBinary<TLeft, TRight, TEquals<TLeft, TRight, Aggr>>, public TAggrEquals {
+ static bool Do(TLeft left, TRight right)
+ {
+ return Equals<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenEquals<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateEquals : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateEquals<TLeft, TRight, Aggr>>, public TAggrEquals {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ Equals<TLeft, TRight, Aggr>(left, right):
+ Equals<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenEquals<TLeft, TRight, Aggr>(left, right, context, block):
+ GenEquals<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateEquals : public TArithmeticConstraintsBinary<TLeft, TRight, bool>, public TAggrEquals {
+ static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return NUdf::TUnboxedValuePod(Join(Equals<TLeft, TRight, Aggr>(left.template Get<TLeft>(), right.template Get<TRight>()), Equals<ui16, ui16, Aggr>(left.GetTimezoneId(), right.GetTimezoneId())));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenEquals<TLeft, TRight, Aggr>(left, right, context, block):
- GenEquals<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto ltz = GetterForTimezone(context, left, block);
+ const auto rtz = GetterForTimezone(context, right, block);
+ const auto result = GenJoin(GenEquals<TLeft, TRight, Aggr>(lhs, rhs, context, block), GenEquals<ui16, ui16, Aggr>(ltz, rtz, context, block), block);
+ const auto wide = MakeBoolean(result, context, block);
+ return wide;
}
#endif
};
-template <typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateEquals : public TArithmeticConstraintsBinary<TLeft, TRight, bool>, public TAggrEquals {
- static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return NUdf::TUnboxedValuePod(Join(Equals<TLeft, TRight, Aggr>(left.template Get<TLeft>(), right.template Get<TRight>()), Equals<ui16, ui16, Aggr>(left.GetTimezoneId(), right.GetTimezoneId())));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto ltz = GetterForTimezone(context, left, block);
- const auto rtz = GetterForTimezone(context, right, block);
- const auto result = GenJoin(GenEquals<TLeft, TRight, Aggr>(lhs, rhs, context, block), GenEquals<ui16, ui16, Aggr>(ltz, rtz, context, block), block);
- const auto wide = MakeBoolean(result, context, block);
- return wide;
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomEquals : public TAggrEquals {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) == 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, res, ConstantInt::get(res->getType(), 0), "equals", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalEquals {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && l == r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto good = NDecimal::GenIsComparable(l, context, block);
- const auto eq = GenEqualsIntegral(l, r, block);
- const auto res = BinaryOperator::CreateAnd(good, eq, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrEquals : public TAggrEquals {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l == r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto eq = GenEqualsIntegral(l, r, block);
- return MakeBoolean(eq, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterEquals(IBuiltinFunctionRegistry& registry) {
- const auto name = "Equals";
-
- RegisterComparePrimitive<TEquals, TCompareArgsOpt>(registry, name);
+template<NUdf::EDataSlot Slot>
+struct TCustomEquals : public TAggrEquals {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) == 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, res, ConstantInt::get(res->getType(), 0), "equals", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalEquals {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && l == r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto good = NDecimal::GenIsComparable(l, context, block);
+ const auto eq = GenEqualsIntegral(l, r, block);
+ const auto res = BinaryOperator::CreateAnd(good, eq, "res", block);
+ return MakeBoolean(res, context, block);
+ }
+#endif
+};
+
+struct TDecimalAggrEquals : public TAggrEquals {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l == r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto eq = GenEqualsIntegral(l, r, block);
+ return MakeBoolean(eq, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterEquals(IBuiltinFunctionRegistry& registry) {
+ const auto name = "Equals";
+
+ RegisterComparePrimitive<TEquals, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateEquals, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomEquals, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalEquals, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrEquals";
- RegisterAggrComparePrimitive<TEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateEquals, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrEquals, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomEquals, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalEquals, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrEquals";
+ RegisterAggrComparePrimitive<TEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateEquals, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrEquals, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_find.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_find.cpp
index 8c5ea625ff..7462f939e9 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_find.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_find.cpp
@@ -1,78 +1,78 @@
-#include "mkql_builtins_impl.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template<bool Reverse>
-NUdf::TUnboxedValuePod Find(const NUdf::TUnboxedValuePod haystack, const NUdf::TUnboxedValuePod needle, std::string_view::size_type pos) {
- const std::string_view& one(haystack.AsStringRef());
- const std::string_view& two(needle.AsStringRef());
- const auto f = Reverse ? one.rfind(two, pos): one.find(two, pos);
- return std::string_view::npos == f ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(ui32(f));
-}
-
-template <bool PosOptional, bool Reverse>
-struct TFind {
- static constexpr std::string_view::size_type DefaultPos = Reverse ? std::string_view::npos : 0;
-
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod sub, NUdf::TUnboxedValuePod pos)
- {
- return Find<Reverse>(string, sub, PosOptional && !pos ? DefaultPos : std::string_view::size_type(pos.Get<ui32>()));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* string, Value* sub, Value* p, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(Find<Reverse>));
- const auto pos = PosOptional ?
- SelectInst::Create(
- IsEmpty(p, block),
- ConstantInt::get(GetTypeFor<std::string_view::size_type>(context), DefaultPos),
- StaticCast<ui32, std::string_view::size_type>(GetterFor<ui32>(p, context, block), context, block),
- "pos", block):
- StaticCast<ui32, std::string_view::size_type>(GetterFor<ui32>(p, context, block), context, block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(string->getType(), {string->getType(), sub->getType(), pos->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- const auto result = CallInst::Create(funcPtr, {string, sub, pos}, "find", block);
- return result;
- } else {
- const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
- const auto ptrSub = new AllocaInst(sub->getType(), 0U, "sub", block);
- const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
- new StoreInst(string, ptrArg, block);
- new StoreInst(sub, ptrSub, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), ptrSub->getType(), pos->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- CallInst::Create(funcPtr, {ptrResult, ptrArg, ptrSub, pos}, "", block);
- const auto result = new LoadInst(ptrResult, "find", block);
- return result;
- }
- }
-#endif
-};
-
-template <typename TInput, bool Reverse>
-void RegisterFindOpt(IBuiltinFunctionRegistry& registry, const char* name) {
- RegisterFunctionImpl<TFind<false, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, false, false, false, true>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TFind<false, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, true, false, false, true>, TTernaryWrap<true>>(registry, name);
-
- RegisterFunctionImpl<TFind<true, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, false, false, true, true>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TFind<true, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, true, false, true, true>, TTernaryWrap<true>>(registry, name);
-}
-
-}
-
-void RegisterFind(IBuiltinFunctionRegistry& registry) {
- RegisterFindOpt<NUdf::TDataType<char*>, false>(registry, "Find");
- RegisterFindOpt<NUdf::TDataType<NUdf::TUtf8>, false>(registry, "Find");
-
- RegisterFindOpt<NUdf::TDataType<char*>, true>(registry, "RFind");
- RegisterFindOpt<NUdf::TDataType<NUdf::TUtf8>, true>(registry, "RFind");
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+#include "mkql_builtins_impl.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template<bool Reverse>
+NUdf::TUnboxedValuePod Find(const NUdf::TUnboxedValuePod haystack, const NUdf::TUnboxedValuePod needle, std::string_view::size_type pos) {
+ const std::string_view& one(haystack.AsStringRef());
+ const std::string_view& two(needle.AsStringRef());
+ const auto f = Reverse ? one.rfind(two, pos): one.find(two, pos);
+ return std::string_view::npos == f ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(ui32(f));
+}
+
+template <bool PosOptional, bool Reverse>
+struct TFind {
+ static constexpr std::string_view::size_type DefaultPos = Reverse ? std::string_view::npos : 0;
+
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod sub, NUdf::TUnboxedValuePod pos)
+ {
+ return Find<Reverse>(string, sub, PosOptional && !pos ? DefaultPos : std::string_view::size_type(pos.Get<ui32>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* string, Value* sub, Value* p, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(Find<Reverse>));
+ const auto pos = PosOptional ?
+ SelectInst::Create(
+ IsEmpty(p, block),
+ ConstantInt::get(GetTypeFor<std::string_view::size_type>(context), DefaultPos),
+ StaticCast<ui32, std::string_view::size_type>(GetterFor<ui32>(p, context, block), context, block),
+ "pos", block):
+ StaticCast<ui32, std::string_view::size_type>(GetterFor<ui32>(p, context, block), context, block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(string->getType(), {string->getType(), sub->getType(), pos->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ const auto result = CallInst::Create(funcPtr, {string, sub, pos}, "find", block);
+ return result;
+ } else {
+ const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
+ const auto ptrSub = new AllocaInst(sub->getType(), 0U, "sub", block);
+ const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
+ new StoreInst(string, ptrArg, block);
+ new StoreInst(sub, ptrSub, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), ptrSub->getType(), pos->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ CallInst::Create(funcPtr, {ptrResult, ptrArg, ptrSub, pos}, "", block);
+ const auto result = new LoadInst(ptrResult, "find", block);
+ return result;
+ }
+ }
+#endif
+};
+
+template <typename TInput, bool Reverse>
+void RegisterFindOpt(IBuiltinFunctionRegistry& registry, const char* name) {
+ RegisterFunctionImpl<TFind<false, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, false, false, false, true>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TFind<false, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, true, false, false, true>, TTernaryWrap<true>>(registry, name);
+
+ RegisterFunctionImpl<TFind<true, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, false, false, true, true>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TFind<true, Reverse>, TTernaryArgs<NUdf::TDataType<ui32>, TInput, TInput, NUdf::TDataType<ui32>, true, false, true, true>, TTernaryWrap<true>>(registry, name);
+}
+
+}
+
+void RegisterFind(IBuiltinFunctionRegistry& registry) {
+ RegisterFindOpt<NUdf::TDataType<char*>, false>(registry, "Find");
+ RegisterFindOpt<NUdf::TDataType<NUdf::TUtf8>, false>(registry, "Find");
+
+ RegisterFindOpt<NUdf::TDataType<char*>, true>(registry, "RFind");
+ RegisterFindOpt<NUdf::TDataType<NUdf::TUtf8>, true>(registry, "RFind");
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp
index fba26927f6..08297c8916 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp
@@ -1,277 +1,277 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
- return x > y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
- return x > T1(0) && static_cast<std::make_unsigned_t<T1>>(x) > y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
- return T2(0) > y || x > static_cast<std::make_unsigned_t<T2>>(y);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return !std::isnan(l) && std::isnan(r);
- }
- return l > r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenGreaterUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, lhs, rhs, "greater", block);
-}
-
-Value* GenGreaterSigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, lhs, rhs, "greater", block);
-}
-
-template <bool Aggr>
-Value* GenGreaterFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenGreaterFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGT, lhs, rhs, "greater", block);
-}
-
-template <>
-Value* GenGreaterFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto ugt = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UGT, lhs, rhs, "greater", block);
- const auto ord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "ordered", block);
- return BinaryOperator::CreateAnd(ugt, ord, "and", block);
-}
-
-template <typename T1, typename T2>
-Value* GenGreaterIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenGreaterIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenGreaterSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenGreaterIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenGreaterIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenGreaterFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrGreater {
- static bool Simple(bool left, bool right)
- {
- return left && !right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_UGT;
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TGreater : public TCompareArithmeticBinary<TLeft, TRight, TGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
- static bool Do(TLeft left, TRight right)
- {
- return Greater<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreater<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateGreater : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- Greater<TLeft, TRight, Aggr>(left, right):
- Greater<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
+ return x > y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
+ return x > T1(0) && static_cast<std::make_unsigned_t<T1>>(x) > y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
+ return T2(0) > y || x > static_cast<std::make_unsigned_t<T2>>(y);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Greater(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return !std::isnan(l) && std::isnan(r);
+ }
+ return l > r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenGreaterUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, lhs, rhs, "greater", block);
+}
+
+Value* GenGreaterSigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, lhs, rhs, "greater", block);
+}
+
+template <bool Aggr>
+Value* GenGreaterFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenGreaterFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGT, lhs, rhs, "greater", block);
+}
+
+template <>
+Value* GenGreaterFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto ugt = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UGT, lhs, rhs, "greater", block);
+ const auto ord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(lhs->getType(), 0.0), lhs, "ordered", block);
+ return BinaryOperator::CreateAnd(ugt, ord, "and", block);
+}
+
+template <typename T1, typename T2>
+Value* GenGreaterIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenGreaterIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenGreaterUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenGreaterSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenGreaterIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenGreaterIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenGreater(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenGreaterFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrGreater {
+ static bool Simple(bool left, bool right)
+ {
+ return left && !right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_UGT;
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TGreater : public TCompareArithmeticBinary<TLeft, TRight, TGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
+ static bool Do(TLeft left, TRight right)
+ {
+ return Greater<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreater<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateGreater : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ Greater<TLeft, TRight, Aggr>(left, right):
+ Greater<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenGreater<TLeft, TRight, Aggr>(left, right, context, block):
+ GenGreater<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateGreater : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
+ static bool Do(TLeft left, TRight right)
+ {
+ return Greater<TLeft, TRight, Aggr>(left, right);
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return Greater<ui16, ui16, Aggr>(left, right);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreater<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreater<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomGreater : public TAggrGreater {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) > 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, res, ConstantInt::get(res->getType(), 0), "greater", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalGreater {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l > r);
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenGreater<TLeft, TRight, Aggr>(left, right, context, block):
- GenGreater<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
+ const auto gt = GenGreaterSigned(l, r, block);
+ const auto res = BinaryOperator::CreateAnd(both, gt, "res", block);
+ return MakeBoolean(res, context, block);
}
#endif
};
-template<typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateGreater : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateGreater<TLeft, TRight, Aggr>>, public TAggrGreater {
- static bool Do(TLeft left, TRight right)
- {
- return Greater<TLeft, TRight, Aggr>(left, right);
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return Greater<ui16, ui16, Aggr>(left, right);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreater<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreater<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomGreater : public TAggrGreater {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) > 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, res, ConstantInt::get(res->getType(), 0), "greater", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalGreater {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l > r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
- const auto gt = GenGreaterSigned(l, r, block);
- const auto res = BinaryOperator::CreateAnd(both, gt, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrGreater : public TAggrGreater {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l > r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto gt = GenGreaterSigned(l, r, block);
- return MakeBoolean(gt, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterGreater(IBuiltinFunctionRegistry& registry) {
- const auto name = "Greater";
-
- RegisterComparePrimitive<TGreater, TCompareArgsOpt>(registry, name);
+struct TDecimalAggrGreater : public TAggrGreater {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l > r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto gt = GenGreaterSigned(l, r, block);
+ return MakeBoolean(gt, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterGreater(IBuiltinFunctionRegistry& registry) {
+ const auto name = "Greater";
+
+ RegisterComparePrimitive<TGreater, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateGreater, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomGreater, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalGreater, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrGreater";
- RegisterAggrComparePrimitive<TGreater, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateGreater, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateGreater, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomGreater, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrGreater, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomGreater, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalGreater, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrGreater";
+ RegisterAggrComparePrimitive<TGreater, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateGreater, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateGreater, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomGreater, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrGreater, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp
index 02cdede53f..dbd899eb9f 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp
@@ -1,277 +1,277 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
- return x >= y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
- return x >= T1(0) && static_cast<std::make_unsigned_t<T1>>(x) >= y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
- return T2(0) >= y || x >= static_cast<std::make_unsigned_t<T2>>(y);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return !std::isnan(l) || std::isnan(r);
- }
- return l >= r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenGreaterOrEqualUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, lhs, rhs, "greater_or_equal", block);
-}
-
-Value* GenGreaterOrEqualSigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, lhs, rhs, "greater_or_equal", block);
-}
-
-template <bool Aggr>
-Value* GenGreaterOrEqualFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenGreaterOrEqualFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, lhs, rhs, "greater_or_equal", block);
-}
-
-template <>
-Value* GenGreaterOrEqualFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto oge = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, lhs, rhs, "greater_or_equal", block);
- const auto uno = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "unordered", block);
- return BinaryOperator::CreateOr(oge, uno, "or", block);
-}
-
-template <typename T1, typename T2>
-Value* GenGreaterOrEqualIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenGreaterOrEqualIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenGreaterOrEqualSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenGreaterOrEqualIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenGreaterOrEqualIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenGreaterOrEqualFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrGreaterOrEqual {
- static bool Simple(bool left, bool right)
- {
- return left || !right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_UGE;
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TGreaterOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return GreaterOrEqual<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateGreaterOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- GreaterOrEqual<TLeft, TRight, Aggr>(left, right):
- GreaterOrEqual<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
+ return x >= y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
+ return x >= T1(0) && static_cast<std::make_unsigned_t<T1>>(x) >= y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
+ return T2(0) >= y || x >= static_cast<std::make_unsigned_t<T2>>(y);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool GreaterOrEqual(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return !std::isnan(l) || std::isnan(r);
+ }
+ return l >= r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenGreaterOrEqualUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, lhs, rhs, "greater_or_equal", block);
+}
+
+Value* GenGreaterOrEqualSigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, lhs, rhs, "greater_or_equal", block);
+}
+
+template <bool Aggr>
+Value* GenGreaterOrEqualFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenGreaterOrEqualFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, lhs, rhs, "greater_or_equal", block);
+}
+
+template <>
+Value* GenGreaterOrEqualFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto oge = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OGE, lhs, rhs, "greater_or_equal", block);
+ const auto uno = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "unordered", block);
+ return BinaryOperator::CreateOr(oge, uno, "or", block);
+}
+
+template <typename T1, typename T2>
+Value* GenGreaterOrEqualIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenGreaterOrEqualIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenGreaterOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenGreaterOrEqualSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenGreaterOrEqualIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenGreaterOrEqualIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenGreaterOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenGreaterOrEqualFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrGreaterOrEqual {
+ static bool Simple(bool left, bool right)
+ {
+ return left || !right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_UGE;
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TGreaterOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return GreaterOrEqual<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateGreaterOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ GreaterOrEqual<TLeft, TRight, Aggr>(left, right):
+ GreaterOrEqual<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, context, block):
+ GenGreaterOrEqual<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateGreaterOrEqual : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return GreaterOrEqual<TLeft, TRight, Aggr>(left, right);
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return GreaterOrEqual<ui16, ui16, Aggr>(left, right);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenGreaterOrEqual<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomGreaterOrEqual : public TAggrGreaterOrEqual {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) >= 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, res, ConstantInt::get(res->getType(), 0), "greater_or_equal", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalGreaterOrEqual {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l >= r);
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, context, block):
- GenGreaterOrEqual<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
+ const auto ge = GenGreaterOrEqualSigned(l, r, block);
+ const auto res = BinaryOperator::CreateAnd(both, ge, "res", block);
+ return MakeBoolean(res, context, block);
}
#endif
};
-template<typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateGreaterOrEqual : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateGreaterOrEqual<TLeft, TRight, Aggr>>, public TAggrGreaterOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return GreaterOrEqual<TLeft, TRight, Aggr>(left, right);
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return GreaterOrEqual<ui16, ui16, Aggr>(left, right);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreaterOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenGreaterOrEqual<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomGreaterOrEqual : public TAggrGreaterOrEqual {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) >= 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, res, ConstantInt::get(res->getType(), 0), "greater_or_equal", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalGreaterOrEqual {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l >= r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
- const auto ge = GenGreaterOrEqualSigned(l, r, block);
- const auto res = BinaryOperator::CreateAnd(both, ge, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrGreaterOrEqual : public TAggrGreaterOrEqual {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l >= r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto ge = GenGreaterOrEqualSigned(l, r, block);
- return MakeBoolean(ge, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterGreaterOrEqual(IBuiltinFunctionRegistry& registry) {
- const auto name = "GreaterOrEqual";
-
- RegisterComparePrimitive<TGreaterOrEqual, TCompareArgsOpt>(registry, name);
+struct TDecimalAggrGreaterOrEqual : public TAggrGreaterOrEqual {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l >= r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto ge = GenGreaterOrEqualSigned(l, r, block);
+ return MakeBoolean(ge, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterGreaterOrEqual(IBuiltinFunctionRegistry& registry) {
+ const auto name = "GreaterOrEqual";
+
+ RegisterComparePrimitive<TGreaterOrEqual, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateGreaterOrEqual, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomGreaterOrEqual, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalGreaterOrEqual, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrGreaterOrEqual";
- RegisterAggrComparePrimitive<TGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomGreaterOrEqual, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalGreaterOrEqual, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrGreaterOrEqual";
+ RegisterAggrComparePrimitive<TGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrGreaterOrEqual, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h
index 2b38904aac..78b35c2a69 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h
@@ -6,184 +6,184 @@
#include <ydb/library/yql/minikql/mkql_function_metadata.h>
#include <util/string/cast.h>
-#include "mkql_builtins_codegen.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-struct TUnaryStub {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- return TFunc::Execute(*args);
- }
-
+#include "mkql_builtins_codegen.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+struct TUnaryStub {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ return TFunc::Execute(*args);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateUnaryWithoutCheck(*args, ctx, block, &TFunc::Generate);
- }
-#endif
-};
-
-struct TUnaryWrap {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- return *args ? TFunc::Execute(*args) : NUdf::TUnboxedValuePod();
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateUnaryWithCheck(*args, ctx, block, &TFunc::Generate);
- }
-#endif
-};
-
-template<bool CheckLeft, bool CheckRight>
-struct TBinaryWrap {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- if (CheckLeft && !args[0])
- return NUdf::TUnboxedValuePod();
- if (CheckRight && !args[1])
- return NUdf::TUnboxedValuePod();
- return TFunc::Execute(args[0], args[1]);
- }
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateUnaryWithoutCheck(*args, ctx, block, &TFunc::Generate);
+ }
+#endif
+};
+
+struct TUnaryWrap {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ return *args ? TFunc::Execute(*args) : NUdf::TUnboxedValuePod();
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateBinary<CheckLeft, CheckRight>(args[0], args[1], ctx, block, &TFunc::Generate);
- }
-#endif
-};
-
-struct TAggregateWrap {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- if (!args[0])
- return args[1];
- if (!args[1])
- return args[0];
- return TFunc::Execute(args[0], args[1]);
- }
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateUnaryWithCheck(*args, ctx, block, &TFunc::Generate);
+ }
+#endif
+};
+
+template<bool CheckLeft, bool CheckRight>
+struct TBinaryWrap {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ if (CheckLeft && !args[0])
+ return NUdf::TUnboxedValuePod();
+ if (CheckRight && !args[1])
+ return NUdf::TUnboxedValuePod();
+ return TFunc::Execute(args[0], args[1]);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateAggregate(args[0], args[1], ctx, block, &TFunc::Generate);
- }
-#endif
-};
-
-struct TAggrCompareWrap {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- const bool a0(args[0]), a1(args[1]);
- return (a0 && a1) ?
- TFunc::Execute(args[0], args[1]) : NUdf::TUnboxedValuePod(TFunc::Simple(a0, a1));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateCompareAggregate(args[0], args[1], ctx, block, &TFunc::Generate, TFunc::SimplePredicate);
- }
-#endif
-};
-
-template<bool CheckFirst>
-struct TTernaryWrap {
- template<typename TFunc>
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
- if (CheckFirst && !*args)
- return NUdf::TUnboxedValuePod();
- return TFunc::Execute(args[0], args[1], args[2]);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- template<typename TFunc>
- static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
- return GenerateTernary<CheckFirst>(args[0], args[1], args[2], ctx, block, &TFunc::Generate);
- }
-#endif
-};
-
-template <typename TInput, typename TOutput>
-struct TArithmeticConstraintsUnary {
- static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
- static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
-};
-
-template <typename TInput, typename TOutput>
-struct TArithmeticConstraintsSame {
- static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
- static_assert(std::is_same<TInput, TOutput>::value, "Input and output must be same types!");
-};
-
-template <typename TLeft, typename TRight, typename TOutput>
-struct TArithmeticConstraintsBinary {
- static_assert(std::is_arithmetic<TLeft>::value, "Left type must be arithmetic!");
- static_assert(std::is_arithmetic<TRight>::value, "Right type must be arithmetic!");
- static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
-};
-
-template <typename TInput, typename TOutput, class TImpl>
-struct TSimpleArithmeticUnary : public TArithmeticConstraintsSame<TInput, TOutput> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- return NUdf::TUnboxedValuePod(TImpl::Do(arg.template Get<TInput>()));
- }
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateBinary<CheckLeft, CheckRight>(args[0], args[1], ctx, block, &TFunc::Generate);
+ }
+#endif
+};
+
+struct TAggregateWrap {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ if (!args[0])
+ return args[1];
+ if (!args[1])
+ return args[0];
+ return TFunc::Execute(args[0], args[1]);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto val = GetterFor<TInput>(arg, context, block);
- const auto res = TImpl::Gen(val, ctx, block);
- const auto wide = SetterFor<TOutput>(res, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TLeft, typename TRight, typename TOutput, class TImpl>
-struct TSimpleArithmeticBinary : public TArithmeticConstraintsBinary<TLeft, TRight, TOutput> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
- }
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateAggregate(args[0], args[1], ctx, block, &TFunc::Generate);
+ }
+#endif
+};
+
+struct TAggrCompareWrap {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ const bool a0(args[0]), a1(args[1]);
+ return (a0 && a1) ?
+ TFunc::Execute(args[0], args[1]) : NUdf::TUnboxedValuePod(TFunc::Simple(a0, a1));
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rhs = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
- const auto res = TImpl::Gen(lhs, rhs, ctx, block);
- const auto wide = SetterFor<TOutput>(res, context, block);
- return wide;
- }
-#endif
-};
-
-template <typename TInput, typename TOutput, class TImpl>
-struct TShiftArithmeticBinary : public TArithmeticConstraintsSame<TInput, TOutput> {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TInput>(), right.Get<ui8>()));
- }
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateCompareAggregate(args[0], args[1], ctx, block, &TFunc::Generate, TFunc::SimplePredicate);
+ }
+#endif
+};
+
+template<bool CheckFirst>
+struct TTernaryWrap {
+ template<typename TFunc>
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
+ if (CheckFirst && !*args)
+ return NUdf::TUnboxedValuePod();
+ return TFunc::Execute(args[0], args[1], args[2]);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TInput>(left, context, block);
- const auto rhs = CastInst::Create(Instruction::Trunc, right, Type::getInt8Ty(context), "bits", block);
- const auto res = TImpl::Gen(lhs, rhs, ctx, block);
- const auto wide = SetterFor<TOutput>(res, context, block);
- return wide;
- }
-#endif
-};
-
+ template<typename TFunc>
+ static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
+ return GenerateTernary<CheckFirst>(args[0], args[1], args[2], ctx, block, &TFunc::Generate);
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput>
+struct TArithmeticConstraintsUnary {
+ static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
+ static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
+};
+
+template <typename TInput, typename TOutput>
+struct TArithmeticConstraintsSame {
+ static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
+ static_assert(std::is_same<TInput, TOutput>::value, "Input and output must be same types!");
+};
+
+template <typename TLeft, typename TRight, typename TOutput>
+struct TArithmeticConstraintsBinary {
+ static_assert(std::is_arithmetic<TLeft>::value, "Left type must be arithmetic!");
+ static_assert(std::is_arithmetic<TRight>::value, "Right type must be arithmetic!");
+ static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
+};
+
+template <typename TInput, typename TOutput, class TImpl>
+struct TSimpleArithmeticUnary : public TArithmeticConstraintsSame<TInput, TOutput> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return NUdf::TUnboxedValuePod(TImpl::Do(arg.template Get<TInput>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto val = GetterFor<TInput>(arg, context, block);
+ const auto res = TImpl::Gen(val, ctx, block);
+ const auto wide = SetterFor<TOutput>(res, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, typename TOutput, class TImpl>
+struct TSimpleArithmeticBinary : public TArithmeticConstraintsBinary<TLeft, TRight, TOutput> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rhs = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
+ const auto res = TImpl::Gen(lhs, rhs, ctx, block);
+ const auto wide = SetterFor<TOutput>(res, context, block);
+ return wide;
+ }
+#endif
+};
+
+template <typename TInput, typename TOutput, class TImpl>
+struct TShiftArithmeticBinary : public TArithmeticConstraintsSame<TInput, TOutput> {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TInput>(), right.Get<ui8>()));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TInput>(left, context, block);
+ const auto rhs = CastInst::Create(Instruction::Trunc, right, Type::getInt8Ty(context), "bits", block);
+ const auto res = TImpl::Gen(lhs, rhs, ctx, block);
+ const auto wide = SetterFor<TOutput>(res, context, block);
+ return wide;
+ }
+#endif
+};
+
template <typename TInput, typename TOutput>
struct TUnaryArgs {
static const TFunctionParamMetadata Value[3];
@@ -271,19 +271,19 @@ const TFunctionParamMetadata TBinaryArgsSameOpt<TInput, TOutput, IsOptional>::Va
{ 0, 0 }
};
-template <typename TInput, typename TOutput, bool IsOptional>
-struct TBinaryArgsSameOptArgsWithNullableResult {
- static const TFunctionParamMetadata Value[4];
-};
-
-template <typename TInput, typename TOutput, bool IsOptional>
-const TFunctionParamMetadata TBinaryArgsSameOptArgsWithNullableResult<TInput, TOutput, IsOptional>::Value[4] = {
- { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
- { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
- { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
- { 0, 0 }
-};
-
+template <typename TInput, typename TOutput, bool IsOptional>
+struct TBinaryArgsSameOptArgsWithNullableResult {
+ static const TFunctionParamMetadata Value[4];
+};
+
+template <typename TInput, typename TOutput, bool IsOptional>
+const TFunctionParamMetadata TBinaryArgsSameOptArgsWithNullableResult<TInput, TOutput, IsOptional>::Value[4] = {
+ { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
+ { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
+ { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
+ { 0, 0 }
+};
+
template <typename TInput, typename TOutput>
struct TBinaryShiftArgs {
static const TFunctionParamMetadata Value[4];
@@ -323,20 +323,20 @@ const TFunctionParamMetadata TBinaryArgsWithNullableResult<TInput, TOutput>::Val
{ 0, 0 }
};
-template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional = IsFirstOptional>
-struct TTernaryArgs {
- static const TFunctionParamMetadata Value[5];
-};
-
-template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional>
-const TFunctionParamMetadata TTernaryArgs<TOutput, TInput1, TInput2, TInput3, IsFirstOptional, IsSecondOptional, IsThirdOptional, IsResultOptional>::Value[5] = {
- { TOutput::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
- { TInput1::Id, IsFirstOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
- { TInput2::Id, IsSecondOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
- { TInput3::Id, IsThirdOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
- { 0, 0 }
-};
-
+template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional = IsFirstOptional>
+struct TTernaryArgs {
+ static const TFunctionParamMetadata Value[5];
+};
+
+template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional>
+const TFunctionParamMetadata TTernaryArgs<TOutput, TInput1, TInput2, TInput3, IsFirstOptional, IsSecondOptional, IsThirdOptional, IsResultOptional>::Value[5] = {
+ { TOutput::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
+ { TInput1::Id, IsFirstOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
+ { TInput2::Id, IsSecondOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
+ { TInput3::Id, IsThirdOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
+ { 0, 0 }
+};
+
template <typename TInput1, typename TInput2, typename TOutput, bool IsLeftOptional, bool IsRightOptional>
struct TBinaryArgsOptWithNullableResult {
static const TFunctionParamMetadata Value[4];
@@ -350,14 +350,14 @@ const TFunctionParamMetadata TBinaryArgsOptWithNullableResult<TInput1, TInput2,
{ 0, 0 }
};
-template <typename TFunc, typename TArgs, typename TWrap>
-void RegisterFunctionImpl(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+template <typename TFunc, typename TArgs, typename TWrap>
+void RegisterFunctionImpl(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
#ifndef MKQL_DISABLE_CODEGEN
- const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>, reinterpret_cast<void*>(&TWrap::template Generate<TFunc>));
-#else
- const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>);
-#endif
- registry.Register(name, description);
+ const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>, reinterpret_cast<void*>(&TWrap::template Generate<TFunc>));
+#else
+ const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>);
+#endif
+ registry.Register(name, description);
}
template <
@@ -365,201 +365,201 @@ template <
template<typename, typename> class TFunc,
template<typename, typename> class TArgs
>
-void RegisterFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<TInput, TOutput>, TArgs<TInput, TOutput>, TUnaryStub>(registry, name);
+void RegisterFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<TInput, TOutput>, TArgs<TInput, TOutput>, TUnaryStub>(registry, name);
}
template <
typename TInput, typename TOutput,
- class TFunc,
+ class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
- RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
+void RegisterFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
+ RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
}
template <
- typename TType,
- template<NUdf::EDataSlot> class TFunc,
- template<typename, typename, bool> class TArgs
+ typename TType,
+ template<NUdf::EDataSlot> class TFunc,
+ template<typename, typename, bool> class TArgs
>
-void RegisterCustomAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
+void RegisterCustomAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
+}
+
+template <
+ typename TType,
+ template<NUdf::EDataSlot> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterCustomSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
+}
+
+template <
+ typename TType,
+ template<typename> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
+}
+
+template <
+ typename TType,
+ template<typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
}
template <
- typename TType,
- template<NUdf::EDataSlot> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterCustomSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
-}
-
-template <
- typename TType,
- template<typename> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
-}
-
-template <
- typename TType,
- template<typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
-}
-
-template <
typename TInput, typename TOutput,
- template<typename, typename> class TFunc,
+ template<typename, typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterFunctionUnOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
+void RegisterFunctionUnOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
}
template <
typename TInput1, typename TInput2, typename TOutput,
- template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename> class TFunc,
template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterFunctionBinOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, true>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, true>>(registry, name);
+void RegisterFunctionBinOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, true>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, true>>(registry, name);
}
template <
- template<typename, typename, typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBinaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
}
template <
typename TInput, typename TOutput,
- template<typename, typename> class TFunc,
+ template<typename, typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TBinaryWrap<true, false>>(registry, name);
+void RegisterShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TBinaryWrap<true, false>>(registry, name);
}
template <
- template<typename, typename> class TFunc,
+ template<typename, typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterUnsignedShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterShiftFunctionOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+void RegisterUnsignedShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterShiftFunctionOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
RegisterShiftFunctionOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterShiftFunctionOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterShiftFunctionOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterShiftFunctionOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterShiftFunctionOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename> class TFunc,
+ template<typename, typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterUnaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionUnOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+void RegisterUnaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionUnOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
RegisterFunctionUnOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionUnOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionUnOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename> class TFunc,
+ template<typename, typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterUnaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterUnaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
+void RegisterUnaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterUnaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
RegisterFunctionUnOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
RegisterFunctionUnOpt<NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionUnOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionUnOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename, typename> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterUnaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterUnaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
+
+ RegisterFunctionUnOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionUnOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename> class TFunc,
- template<typename, typename, bool> class TArgs
+ template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterUnaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterUnaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
+void RegisterBinaryIntegralToUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionUnOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename> class TFunc,
template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterBinaryIntegralToUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryIntegralToSignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+void RegisterBinaryIntegralToSignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
@@ -582,216 +582,216 @@ void RegisterBinaryIntegralToSignedFunctionOpt(IBuiltinFunctionRegistry& registr
RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename, typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
+ template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterBinaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterBinaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
- RegisterBinaryIntegralToUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
- RegisterBinaryIntegralToSignedFunctionOpt<TFunc, TArgs>(registry, name);
+void RegisterBinaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterBinaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
+ RegisterBinaryIntegralToUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
+ RegisterBinaryIntegralToSignedFunctionOpt<TFunc, TArgs>(registry, name);
}
template <
- template<typename, typename, typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
+ template<typename, typename, typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterBinaryRealFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+void RegisterBinaryRealFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
-
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+
RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
}
template <
template<typename, typename, typename> class TFunc,
template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterBinaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterBinaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
- RegisterBinaryRealFunctionOpt<TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename> class TFunc,
- template<typename, typename, bool> class TArgs
+void RegisterBinaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterBinaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
+ RegisterBinaryRealFunctionOpt<TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterNumericAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunction<NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
+
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, bool> class TArgs
+>
+void RegisterTzDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
+ RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterNumericAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunction<NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+void RegisterTzDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
+ RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
}
template <
- template<typename> class TFunc,
+ template<typename> class TFunc,
template<typename, typename, bool> class TArgs
>
-void RegisterDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
-
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterTzDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
- RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
+void RegisterBooleanAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterAggregateFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
+}
+
+template <
+ template<typename> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBooleanSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterSameTypesFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
}
template <
- template<typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterTzDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
- RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename> class TFunc,
- template<typename, typename, bool> class TArgs
->
-void RegisterBooleanAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterAggregateFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBooleanSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterSameTypesFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
-}
-
-template <
- template<typename, typename, typename, bool, bool> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
+ template<typename, typename, typename, bool, bool> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
>
-void RegisterBinaryRealFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
- RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+void RegisterBinaryRealFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
+ RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
}
-void RegisterAdd(IBuiltinFunctionRegistry& registry);
-void RegisterAggrAdd(IBuiltinFunctionRegistry& registry);
-void RegisterSub(IBuiltinFunctionRegistry& registry);
-void RegisterMul(IBuiltinFunctionRegistry& registry);
-void RegisterDiv(IBuiltinFunctionRegistry& registry);
-void RegisterMod(IBuiltinFunctionRegistry& registry);
-void RegisterIncrement(IBuiltinFunctionRegistry& registry);
-void RegisterDecrement(IBuiltinFunctionRegistry& registry);
-void RegisterBitAnd(IBuiltinFunctionRegistry& registry);
-void RegisterBitOr(IBuiltinFunctionRegistry& registry);
-void RegisterBitXor(IBuiltinFunctionRegistry& registry);
-void RegisterShiftLeft(IBuiltinFunctionRegistry& registry);
-void RegisterShiftRight(IBuiltinFunctionRegistry& registry);
-void RegisterRotLeft(IBuiltinFunctionRegistry& registry);
-void RegisterRotRight(IBuiltinFunctionRegistry& registry);
-void RegisterPlus(IBuiltinFunctionRegistry& registry);
-void RegisterMinus(IBuiltinFunctionRegistry& registry);
-void RegisterBitNot(IBuiltinFunctionRegistry& registry);
-void RegisterCountBits(IBuiltinFunctionRegistry& registry);
-void RegisterAbs(IBuiltinFunctionRegistry& registry);
-void RegisterConvert(IBuiltinFunctionRegistry& registry);
-void RegisterConcat(IBuiltinFunctionRegistry& registry);
-void RegisterSubstring(IBuiltinFunctionRegistry& registry);
-void RegisterFind(IBuiltinFunctionRegistry& registry);
-void RegisterInversePresortString(IBuiltinFunctionRegistry& registry);
+void RegisterAdd(IBuiltinFunctionRegistry& registry);
+void RegisterAggrAdd(IBuiltinFunctionRegistry& registry);
+void RegisterSub(IBuiltinFunctionRegistry& registry);
+void RegisterMul(IBuiltinFunctionRegistry& registry);
+void RegisterDiv(IBuiltinFunctionRegistry& registry);
+void RegisterMod(IBuiltinFunctionRegistry& registry);
+void RegisterIncrement(IBuiltinFunctionRegistry& registry);
+void RegisterDecrement(IBuiltinFunctionRegistry& registry);
+void RegisterBitAnd(IBuiltinFunctionRegistry& registry);
+void RegisterBitOr(IBuiltinFunctionRegistry& registry);
+void RegisterBitXor(IBuiltinFunctionRegistry& registry);
+void RegisterShiftLeft(IBuiltinFunctionRegistry& registry);
+void RegisterShiftRight(IBuiltinFunctionRegistry& registry);
+void RegisterRotLeft(IBuiltinFunctionRegistry& registry);
+void RegisterRotRight(IBuiltinFunctionRegistry& registry);
+void RegisterPlus(IBuiltinFunctionRegistry& registry);
+void RegisterMinus(IBuiltinFunctionRegistry& registry);
+void RegisterBitNot(IBuiltinFunctionRegistry& registry);
+void RegisterCountBits(IBuiltinFunctionRegistry& registry);
+void RegisterAbs(IBuiltinFunctionRegistry& registry);
+void RegisterConvert(IBuiltinFunctionRegistry& registry);
+void RegisterConcat(IBuiltinFunctionRegistry& registry);
+void RegisterSubstring(IBuiltinFunctionRegistry& registry);
+void RegisterFind(IBuiltinFunctionRegistry& registry);
+void RegisterInversePresortString(IBuiltinFunctionRegistry& registry);
void RegisterInverseString(IBuiltinFunctionRegistry& registry);
-void RegisterNanvl(IBuiltinFunctionRegistry& registry);
-void RegisterByteAt(IBuiltinFunctionRegistry& registry);
-void RegisterMax(IBuiltinFunctionRegistry& registry);
-void RegisterMin(IBuiltinFunctionRegistry& registry);
-void RegisterAggrMax(IBuiltinFunctionRegistry& registry);
-void RegisterAggrMin(IBuiltinFunctionRegistry& registry);
-void RegisterWith(IBuiltinFunctionRegistry& registry);
+void RegisterNanvl(IBuiltinFunctionRegistry& registry);
+void RegisterByteAt(IBuiltinFunctionRegistry& registry);
+void RegisterMax(IBuiltinFunctionRegistry& registry);
+void RegisterMin(IBuiltinFunctionRegistry& registry);
+void RegisterAggrMax(IBuiltinFunctionRegistry& registry);
+void RegisterAggrMin(IBuiltinFunctionRegistry& registry);
+void RegisterWith(IBuiltinFunctionRegistry& registry);
}
}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_inc.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_inc.cpp
index d86795ffb2..323cfb0357 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_inc.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_inc.cpp
@@ -1,72 +1,72 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TIncrement : public TSimpleArithmeticUnary<TInput, TOutput, TIncrement<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return ++val;
- }
-
+template<typename TInput, typename TOutput>
+struct TIncrement : public TSimpleArithmeticUnary<TInput, TOutput, TIncrement<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return ++val;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_integral<TOutput>() ?
- BinaryOperator::CreateAdd(arg, ConstantInt::get(arg->getType(), 1), "inc", block):
- BinaryOperator::CreateFAdd(arg, ConstantFP::get(arg->getType(), 1.0), "inc", block);
- }
-#endif
-};
-
-template <ui8 Precision>
-struct TDecimalInc {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- auto v = arg.GetInt128();
-
- using namespace NYql::NDecimal;
-
- const auto& bounds = GetBounds<Precision, false, true>();
-
- if (v > bounds.first && v < bounds.second)
- return NUdf::TUnboxedValuePod(++v);
-
- return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
+ static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_integral<TOutput>() ?
+ BinaryOperator::CreateAdd(arg, ConstantInt::get(arg->getType(), 1), "inc", block):
+ BinaryOperator::CreateFAdd(arg, ConstantFP::get(arg->getType(), 1.0), "inc", block);
}
-
+#endif
+};
+
+template <ui8 Precision>
+struct TDecimalInc {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ auto v = arg.GetInt128();
+
+ using namespace NYql::NDecimal;
+
+ const auto& bounds = GetBounds<Precision, false, true>();
+
+ if (v > bounds.first && v < bounds.second)
+ return NUdf::TUnboxedValuePod(++v);
+
+ return NUdf::TUnboxedValuePod(IsNan(v) ? Nan() : (v > 0 ? +Inf() : -Inf()));
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto& bounds = NDecimal::GenBounds<Precision, false, true>(context);
-
- const auto val = GetterForInt128(arg, block);
- const auto add = BinaryOperator::CreateAdd(val, ConstantInt::get(val->getType(), 1), "add", block);
-
- const auto gt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, val, bounds.first, "gt", block);
- const auto lt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SLT, add, bounds.second, "lt", block);
-
- const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
- const auto nan = NDecimal::GenIsNonComparable(val, context, block);
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
-
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
- const auto inc = SelectInst::Create(good, add, bad, "inc", block);
- return SetterForInt128(inc, block);
- }
-#endif
- static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto& bounds = NDecimal::GenBounds<Precision, false, true>(context);
+
+ const auto val = GetterForInt128(arg, block);
+ const auto add = BinaryOperator::CreateAdd(val, ConstantInt::get(val->getType(), 1), "add", block);
+
+ const auto gt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SGT, val, bounds.first, "gt", block);
+ const auto lt = CmpInst::Create(Instruction::ICmp, FCmpInst::ICMP_SLT, add, bounds.second, "lt", block);
+
+ const auto good = BinaryOperator::CreateAnd(lt, gt, "and", block);
+ const auto nan = NDecimal::GenIsNonComparable(val, context, block);
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(val->getType(), 0), "plus", block);
+
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ const auto bad = SelectInst::Create(nan, GetDecimalNan(context), inf, "bad", block);
+ const auto inc = SelectInst::Create(good, add, bad, "inc", block);
+ return SetterForInt128(inc, block);
+ }
+#endif
+ static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
};
}
-void RegisterIncrement(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryNumericFunctionOpt<TIncrement, TUnaryArgsOpt>(registry, "Increment");
- NDecimal::RegisterUnaryFunctionForAllPrecisions<TDecimalInc, TUnaryArgsOpt>(registry, "Inc_");
+void RegisterIncrement(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryNumericFunctionOpt<TIncrement, TUnaryArgsOpt>(registry, "Increment");
+ NDecimal::RegisterUnaryFunctionForAllPrecisions<TDecimalInc, TUnaryArgsOpt>(registry, "Inc_");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_invprestr.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_invprestr.cpp
index f038b6bec2..902a868c21 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_invprestr.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_invprestr.cpp
@@ -14,13 +14,13 @@ struct TStringDescEncoder : public TPresortEncoder {
}
};
-NUdf::TUnboxedValuePod Presort(NUdf::TUnboxedValuePod arg) {
+NUdf::TUnboxedValuePod Presort(NUdf::TUnboxedValuePod arg) {
auto encoder = FastTlsSingleton<TStringDescEncoder>();
encoder->Start();
encoder->Encode(arg);
return MakeString(encoder->Finish());
-}
-
+}
+
NUdf::TUnboxedValuePod Inverse(NUdf::TUnboxedValuePod arg) {
auto input = arg.AsStringRef();
auto ret = MakeStringNotFilled(input.Size());
@@ -33,20 +33,20 @@ NUdf::TUnboxedValuePod Inverse(NUdf::TUnboxedValuePod arg) {
return ret;
}
-template <typename TInput, typename TOutput>
-struct TInversePresortString {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
- {
- return Presort(arg);
- }
-
+template <typename TInput, typename TOutput>
+struct TInversePresortString {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg)
+ {
+ return Presort(arg);
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return CallUnaryUnboxedValueFunction(&Presort, Type::getInt128Ty(ctx.Codegen->GetContext()), arg, ctx.Codegen, block);
- }
-#endif
-};
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return CallUnaryUnboxedValueFunction(&Presort, Type::getInt128Ty(ctx.Codegen->GetContext()), arg, ctx.Codegen, block);
+ }
+#endif
+};
template <typename TInput, typename TOutput>
struct TInverseString {
@@ -65,9 +65,9 @@ struct TInverseString {
}
-void RegisterInversePresortString(IBuiltinFunctionRegistry& registry) {
- const auto name = "InversePresortString";
- RegisterFunction<NUdf::TDataType<char*>, NUdf::TDataType<char*>, TInversePresortString, TUnaryArgs>(registry, name);
+void RegisterInversePresortString(IBuiltinFunctionRegistry& registry) {
+ const auto name = "InversePresortString";
+ RegisterFunction<NUdf::TDataType<char*>, NUdf::TDataType<char*>, TInversePresortString, TUnaryArgs>(registry, name);
RegisterFunction<NUdf::TDataType<NUdf::TUtf8>, NUdf::TDataType<char*>, TInversePresortString, TUnaryArgs>(registry, name);
}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp
index d887b38c94..af400f128a 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp
@@ -1,277 +1,277 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Less(T1 x, T2 y) {
- return x < y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Less(T1 x, T2 y) {
- return x < T1(0) || static_cast<std::make_unsigned_t<T1>>(x) < y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Less(T1 x, T2 y) {
- return T2(0) < y && x < static_cast<std::make_unsigned_t<T2>>(y);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool Less(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return std::isnan(l) && !std::isnan(r);
- }
- return l < r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenLessUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, lhs, rhs, "less", block);
-}
-
-Value* GenLessSigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, lhs, rhs, "less", block);
-}
-
-template <bool Aggr>
-Value* GenLessFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenLessFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLT, lhs, rhs, "less", block);
-}
-
-template <>
-Value* GenLessFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto ult = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ULT, lhs, rhs, "less", block);
- const auto ord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(rhs->getType(), 0.0), rhs, "ordered", block);
- return BinaryOperator::CreateAnd(ult, ord, "and", block);
-}
-
-template <typename T1, typename T2>
-Value* GenLessIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenLessIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenLessSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenLessIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenLessIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenLessFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrLess {
- static bool Simple(bool left, bool right)
- {
- return !left && right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_ULT;
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TLess : public TCompareArithmeticBinary<TLeft, TRight, TLess<TLeft, TRight, Aggr>>, public TAggrLess {
- static bool Do(TLeft left, TRight right)
- {
- return Less<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLess<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateLess : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateLess<TLeft, TRight, Aggr>>, public TAggrLess {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- Less<TLeft, TRight, Aggr>(left, right):
- Less<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Less(T1 x, T2 y) {
+ return x < y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Less(T1 x, T2 y) {
+ return x < T1(0) || static_cast<std::make_unsigned_t<T1>>(x) < y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Less(T1 x, T2 y) {
+ return T2(0) < y && x < static_cast<std::make_unsigned_t<T2>>(y);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool Less(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return std::isnan(l) && !std::isnan(r);
+ }
+ return l < r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenLessUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, lhs, rhs, "less", block);
+}
+
+Value* GenLessSigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, lhs, rhs, "less", block);
+}
+
+template <bool Aggr>
+Value* GenLessFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenLessFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLT, lhs, rhs, "less", block);
+}
+
+template <>
+Value* GenLessFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto ult = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ULT, lhs, rhs, "less", block);
+ const auto ord = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ORD, ConstantFP::get(rhs->getType(), 0.0), rhs, "ordered", block);
+ return BinaryOperator::CreateAnd(ult, ord, "and", block);
+}
+
+template <typename T1, typename T2>
+Value* GenLessIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenLessIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenLessUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenLessSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenLessIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenLessIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenLess(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenLessFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrLess {
+ static bool Simple(bool left, bool right)
+ {
+ return !left && right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_ULT;
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TLess : public TCompareArithmeticBinary<TLeft, TRight, TLess<TLeft, TRight, Aggr>>, public TAggrLess {
+ static bool Do(TLeft left, TRight right)
+ {
+ return Less<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLess<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateLess : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateLess<TLeft, TRight, Aggr>>, public TAggrLess {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ Less<TLeft, TRight, Aggr>(left, right):
+ Less<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenLess<TLeft, TRight, Aggr>(left, right, context, block):
+ GenLess<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateLess : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateLess<TLeft, TRight, Aggr>>, public TAggrLess {
+ static bool Do(TLeft left, TRight right)
+ {
+ return Less<TLeft, TRight, Aggr>(left, right);
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return Less<ui16, ui16, Aggr>(left, right);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLess<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLess<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomLess : public TAggrLess {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) < 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, res, ConstantInt::get(res->getType(), 0), "less", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalLess {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l < r);
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenLess<TLeft, TRight, Aggr>(left, right, context, block):
- GenLess<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
+ const auto ls = GenLessSigned(l, r, block);
+ const auto res = BinaryOperator::CreateAnd(both, ls, "res", block);
+ return MakeBoolean(res, context, block);
}
#endif
};
-template<typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateLess : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateLess<TLeft, TRight, Aggr>>, public TAggrLess {
- static bool Do(TLeft left, TRight right)
- {
- return Less<TLeft, TRight, Aggr>(left, right);
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return Less<ui16, ui16, Aggr>(left, right);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLess<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLess<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomLess : public TAggrLess {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) < 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, res, ConstantInt::get(res->getType(), 0), "less", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalLess {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l < r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
- const auto ls = GenLessSigned(l, r, block);
- const auto res = BinaryOperator::CreateAnd(both, ls, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrLess : public TAggrLess {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l < r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto ls = GenLessSigned(l, r, block);
- return MakeBoolean(ls, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterLess(IBuiltinFunctionRegistry& registry) {
- const auto name = "Less";
-
- RegisterComparePrimitive<TLess, TCompareArgsOpt>(registry, name);
+struct TDecimalAggrLess : public TAggrLess {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l < r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto ls = GenLessSigned(l, r, block);
+ return MakeBoolean(ls, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterLess(IBuiltinFunctionRegistry& registry) {
+ const auto name = "Less";
+
+ RegisterComparePrimitive<TLess, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateLess, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomLess, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalLess, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrLess";
- RegisterAggrComparePrimitive<TLess, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateLess, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateLess, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomLess, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrLess, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomLess, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalLess, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrLess";
+ RegisterAggrComparePrimitive<TLess, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateLess, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateLess, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomLess, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrLess, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp
index ddd3690dfa..37739a4e9e 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp
@@ -1,277 +1,277 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
- return x <= y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
- return x <= T1(0) || static_cast<std::make_unsigned_t<T1>>(x) <= y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
- return T2(0) <= y && x <= static_cast<std::make_unsigned_t<T2>>(y) ;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return std::isnan(l) || !std::isnan(r);
- }
- return l <= r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenLessOrEqualUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, lhs, rhs, "less_or_equal", block);
-}
-
-Value* GenLessOrEqualSigned(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, lhs, rhs, "less_or_equal", block);
-}
-
-template <bool Aggr>
-Value* GenLessOrEqualFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenLessOrEqualFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLE, lhs, rhs, "less_or_equal", block);
-}
-
-template <>
-Value* GenLessOrEqualFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto ole = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLE, lhs, rhs, "less_or_equal", block);
- const auto uno = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(lhs->getType(), 0.0), lhs, "unordered", block);
- return BinaryOperator::CreateOr(ole, uno, "or", block);
-}
-
-template <typename T1, typename T2>
-Value* GenLessOrEqualIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenLessOrEqualIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenLessOrEqualSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenLessOrEqualIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenLessOrEqualIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenLessOrEqualFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrLessOrEqual {
- static bool Simple(bool left, bool right)
- {
- return !left || right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_ULE;
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TLessOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return LessOrEqual<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLessOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateLessOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- LessOrEqual<TLeft, TRight, Aggr>(left, right):
- LessOrEqual<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
+ return x <= y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
+ return x <= T1(0) || static_cast<std::make_unsigned_t<T1>>(x) <= y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
+ return T2(0) <= y && x <= static_cast<std::make_unsigned_t<T2>>(y) ;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool LessOrEqual(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return std::isnan(l) || !std::isnan(r);
+ }
+ return l <= r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenLessOrEqualUnsigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, lhs, rhs, "less_or_equal", block);
+}
+
+Value* GenLessOrEqualSigned(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, lhs, rhs, "less_or_equal", block);
+}
+
+template <bool Aggr>
+Value* GenLessOrEqualFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenLessOrEqualFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLE, lhs, rhs, "less_or_equal", block);
+}
+
+template <>
+Value* GenLessOrEqualFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto ole = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_OLE, lhs, rhs, "less_or_equal", block);
+ const auto uno = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(lhs->getType(), 0.0), lhs, "unordered", block);
+ return BinaryOperator::CreateOr(ole, uno, "or", block);
+}
+
+template <typename T1, typename T2>
+Value* GenLessOrEqualIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenLessOrEqualIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getFalse(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenLessOrEqualUnsigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenLessOrEqualSigned(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenLessOrEqualIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenLessOrEqualIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenLessOrEqual(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenLessOrEqualFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrLessOrEqual {
+ static bool Simple(bool left, bool right)
+ {
+ return !left || right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_ULE;
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TLessOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return LessOrEqual<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLessOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateLessOrEqual : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ LessOrEqual<TLeft, TRight, Aggr>(left, right):
+ LessOrEqual<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenLessOrEqual<TLeft, TRight, Aggr>(left, right, context, block):
+ GenLessOrEqual<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateLessOrEqual : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
+ static bool Do(TLeft left, TRight right)
+ {
+ return LessOrEqual<TLeft, TRight, Aggr>(left, right);
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return LessOrEqual<ui16, ui16, Aggr>(left, right);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLessOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenLessOrEqual<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomLessOrEqual : public TAggrLessOrEqual {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) <= 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, res, ConstantInt::get(res->getType(), 0), "less_or_equal", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalLessOrEqual {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l <= r);
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenLessOrEqual<TLeft, TRight, Aggr>(left, right, context, block):
- GenLessOrEqual<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
+ const auto le = GenLessOrEqualSigned(l, r, block);
+ const auto res = BinaryOperator::CreateAnd(both, le, "res", block);
+ return MakeBoolean(res, context, block);
}
#endif
};
-template<typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateLessOrEqual : public TCompareArithmeticBinaryWithTimezone<TLeft, TRight, TAggrTzDateLessOrEqual<TLeft, TRight, Aggr>>, public TAggrLessOrEqual {
- static bool Do(TLeft left, TRight right)
- {
- return LessOrEqual<TLeft, TRight, Aggr>(left, right);
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return LessOrEqual<ui16, ui16, Aggr>(left, right);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLessOrEqual<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenLessOrEqual<ui16, ui16, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomLessOrEqual : public TAggrLessOrEqual {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) <= 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, res, ConstantInt::get(res->getType(), 0), "less_or_equal", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalLessOrEqual {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(NYql::NDecimal::IsComparable(l) && NYql::NDecimal::IsComparable(r) && l <= r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- const auto both = BinaryOperator::CreateAnd(lok, rok, "both", block);
- const auto le = GenLessOrEqualSigned(l, r, block);
- const auto res = BinaryOperator::CreateAnd(both, le, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrLessOrEqual : public TAggrLessOrEqual {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l <= r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto le = GenLessOrEqualSigned(l, r, block);
- return MakeBoolean(le, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterLessOrEqual(IBuiltinFunctionRegistry& registry) {
- const auto name = "LessOrEqual";
-
- RegisterComparePrimitive<TLessOrEqual, TCompareArgsOpt>(registry, name);
+struct TDecimalAggrLessOrEqual : public TAggrLessOrEqual {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l <= r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto le = GenLessOrEqualSigned(l, r, block);
+ return MakeBoolean(le, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterLessOrEqual(IBuiltinFunctionRegistry& registry) {
+ const auto name = "LessOrEqual";
+
+ RegisterComparePrimitive<TLessOrEqual, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateLessOrEqual, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomLessOrEqual, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalLessOrEqual, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrLessOrEqual";
- RegisterAggrComparePrimitive<TLessOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateLessOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateLessOrEqual, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomLessOrEqual, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrLessOrEqual, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomLessOrEqual, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalLessOrEqual, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrLessOrEqual";
+ RegisterAggrComparePrimitive<TLessOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateLessOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateLessOrEqual, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomLessOrEqual, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrLessOrEqual, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_max.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_max.cpp
index ff010e5704..dc6cfe4778 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_max.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_max.cpp
@@ -1,185 +1,185 @@
-#include "mkql_builtins_decimal.h"
-#include "mkql_builtins_compare.h"
-
-#include <cmath>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
-inline T Max(T l, T r) {
- return std::max(l, r);
-}
-
-template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
-inline T Max(T l, T r) {
- return std::fmax(l, r);
-}
-
-template<typename TLeft, typename TRight, typename TOutput>
-struct TMax : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMax<TLeft, TRight, TOutput>> {
- static TOutput Do(TLeft left, TRight right)
- {
- return Max<TOutput>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- if (std::is_floating_point<TOutput>()) {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto fnType = FunctionType::get(GetTypeFor<TOutput>(context), {left->getType(), right->getType()}, false);
- const auto& name = GetFuncNameForType<TOutput>("llvm.maxnum");
+#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_compare.h"
+
+#include <cmath>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
+inline T Max(T l, T r) {
+ return std::max(l, r);
+}
+
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
+inline T Max(T l, T r) {
+ return std::fmax(l, r);
+}
+
+template<typename TLeft, typename TRight, typename TOutput>
+struct TMax : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMax<TLeft, TRight, TOutput>> {
+ static TOutput Do(TLeft left, TRight right)
+ {
+ return Max<TOutput>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ if (std::is_floating_point<TOutput>()) {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto fnType = FunctionType::get(GetTypeFor<TOutput>(context), {left->getType(), right->getType()}, false);
+ const auto& name = GetFuncNameForType<TOutput>("llvm.maxnum");
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto res = CallInst::Create(func, {left, right}, "maxnum", block);
- return res;
- } else {
- const auto check = CmpInst::Create(Instruction::ICmp, std::is_signed<TOutput>() ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, left, right, "less", block);
- const auto res = SelectInst::Create(check, right, left, "max", block);
- return res;
- }
- }
-#endif
-};
-
-template<typename TType>
-using TAggrMax = TMax<TType, TType, TType>;
-
-template<typename TType>
-struct TTzMax : public TSelectArithmeticBinaryCopyTimezone<TType, TTzMax<TType>> {
- static bool Do(TType left, TType right)
- {
- return left >= right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_or_equal", block);
- }
-#endif
-};
-
-template<typename TType>
-struct TAggrTzMax : public TSelectArithmeticBinaryWithTimezone<TType, TAggrTzMax<TType>> {
- static bool Do(TType left, TType right)
- {
- return left >= right;
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return left >= right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_value", block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_timezone", block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TDecimalMax {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto rv = right.GetInt128();
- if (!NYql::NDecimal::IsComparable(rv))
- return left;
- const auto lv = left.GetInt128();
- if (!NYql::NDecimal::IsComparable(lv))
- return right;
- return NUdf::TUnboxedValuePod(lv < rv ? rv : lv);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(Type::getInt128Ty(context), 3, "result", done);
-
- const auto r = GetterForInt128(right, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- result->addIncoming(left, block);
- BranchInst::Create(next, done, rok, block);
-
- block = next;
-
- const auto l = GetterForInt128(left, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- result->addIncoming(right, block);
- BranchInst::Create(good, done, lok, block);
-
- block = good;
-
- const auto less = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, l, r, "less", block);
- const auto res = SelectInst::Create(less, right, left, "max", block);
- result->addIncoming(res, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomMax {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- const bool r = CompareCustoms<Slot>(left, right) < 0;
- (r ? left : right).DeleteUnreferenced();
- return r ? right : left;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, res, ConstantInt::get(res->getType(), 0), "less", block);
- const auto min = SelectInst::Create(comp, left, right, "min", block);
- ValueCleanup(EValueRepresentation::String, min, ctx, block);
- const auto max = SelectInst::Create(comp, right, left, "max", block);
- return max;
- }
-#endif
-};
-
-}
-
-void RegisterMax(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryNumericFunctionOpt<TMax, TBinaryArgsOpt>(registry, "Max");
- RegisterBooleanSameTypesFunction<TAggrMax, TBinaryArgsOpt>(registry, "Max");
- RegisterDatetimeSameTypesFunction<TAggrMax, TBinaryArgsOpt>(registry, "Max");
- RegisterTzDatetimeSameTypesFunction<TTzMax, TBinaryArgsOpt>(registry, "Max");
-
- RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMax, TBinaryArgsOpt>(registry, "Max");
-
- RegisterCustomSameTypesFunction<NUdf::TDataType<char*>, TCustomMax, TBinaryArgsOpt>(registry, "Max");
- RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMax, TBinaryArgsOpt>(registry, "Max");
-}
-
-void RegisterAggrMax(IBuiltinFunctionRegistry& registry) {
- RegisterNumericAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
- RegisterBooleanAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
- RegisterDatetimeAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
- RegisterTzDatetimeAggregateFunction<TAggrTzMax, TBinaryArgsSameOpt>(registry, "AggrMax");
-
- RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMax, TBinaryArgsSameOpt>(registry, "AggrMax");
-
- RegisterCustomAggregateFunction<NUdf::TDataType<char*>, TCustomMax, TBinaryArgsSameOpt>(registry, "AggrMax");
- RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMax, TBinaryArgsSameOpt>(registry, "AggrMax");
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+ const auto res = CallInst::Create(func, {left, right}, "maxnum", block);
+ return res;
+ } else {
+ const auto check = CmpInst::Create(Instruction::ICmp, std::is_signed<TOutput>() ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, left, right, "less", block);
+ const auto res = SelectInst::Create(check, right, left, "max", block);
+ return res;
+ }
+ }
+#endif
+};
+
+template<typename TType>
+using TAggrMax = TMax<TType, TType, TType>;
+
+template<typename TType>
+struct TTzMax : public TSelectArithmeticBinaryCopyTimezone<TType, TTzMax<TType>> {
+ static bool Do(TType left, TType right)
+ {
+ return left >= right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_or_equal", block);
+ }
+#endif
+};
+
+template<typename TType>
+struct TAggrTzMax : public TSelectArithmeticBinaryWithTimezone<TType, TAggrTzMax<TType>> {
+ static bool Do(TType left, TType right)
+ {
+ return left >= right;
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return left >= right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_value", block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGE, left, right, "greater_timezone", block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TDecimalMax {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto rv = right.GetInt128();
+ if (!NYql::NDecimal::IsComparable(rv))
+ return left;
+ const auto lv = left.GetInt128();
+ if (!NYql::NDecimal::IsComparable(lv))
+ return right;
+ return NUdf::TUnboxedValuePod(lv < rv ? rv : lv);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 3, "result", done);
+
+ const auto r = GetterForInt128(right, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(next, done, rok, block);
+
+ block = next;
+
+ const auto l = GetterForInt128(left, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(good, done, lok, block);
+
+ block = good;
+
+ const auto less = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, l, r, "less", block);
+ const auto res = SelectInst::Create(less, right, left, "max", block);
+ result->addIncoming(res, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomMax {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ const bool r = CompareCustoms<Slot>(left, right) < 0;
+ (r ? left : right).DeleteUnreferenced();
+ return r ? right : left;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, res, ConstantInt::get(res->getType(), 0), "less", block);
+ const auto min = SelectInst::Create(comp, left, right, "min", block);
+ ValueCleanup(EValueRepresentation::String, min, ctx, block);
+ const auto max = SelectInst::Create(comp, right, left, "max", block);
+ return max;
+ }
+#endif
+};
+
+}
+
+void RegisterMax(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryNumericFunctionOpt<TMax, TBinaryArgsOpt>(registry, "Max");
+ RegisterBooleanSameTypesFunction<TAggrMax, TBinaryArgsOpt>(registry, "Max");
+ RegisterDatetimeSameTypesFunction<TAggrMax, TBinaryArgsOpt>(registry, "Max");
+ RegisterTzDatetimeSameTypesFunction<TTzMax, TBinaryArgsOpt>(registry, "Max");
+
+ RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMax, TBinaryArgsOpt>(registry, "Max");
+
+ RegisterCustomSameTypesFunction<NUdf::TDataType<char*>, TCustomMax, TBinaryArgsOpt>(registry, "Max");
+ RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMax, TBinaryArgsOpt>(registry, "Max");
+}
+
+void RegisterAggrMax(IBuiltinFunctionRegistry& registry) {
+ RegisterNumericAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+ RegisterBooleanAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+ RegisterDatetimeAggregateFunction<TAggrMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+ RegisterTzDatetimeAggregateFunction<TAggrTzMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+
+ RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+
+ RegisterCustomAggregateFunction<NUdf::TDataType<char*>, TCustomMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+ RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMax, TBinaryArgsSameOpt>(registry, "AggrMax");
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_min.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_min.cpp
index 3174f33162..4fb61f6554 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_min.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_min.cpp
@@ -1,185 +1,185 @@
-#include "mkql_builtins_decimal.h"
-#include "mkql_builtins_compare.h"
-
-#include <cmath>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
-inline T Min(T l, T r) {
- return std::min(l, r);
-}
-
-template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
-inline T Min(T l, T r) {
- return std::fmin(l, r);
-}
-
-template<typename TLeft, typename TRight, typename TOutput>
-struct TMin : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMin<TLeft, TRight, TOutput>> {
- static TOutput Do(TLeft left, TRight right)
- {
- return Min<TOutput>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- if (std::is_floating_point<TOutput>()) {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto fnType = FunctionType::get(GetTypeFor<TOutput>(context), {left->getType(), right->getType()}, false);
- const auto& name = GetFuncNameForType<TOutput>("llvm.minnum");
+#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_compare.h"
+
+#include <cmath>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
+inline T Min(T l, T r) {
+ return std::min(l, r);
+}
+
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
+inline T Min(T l, T r) {
+ return std::fmin(l, r);
+}
+
+template<typename TLeft, typename TRight, typename TOutput>
+struct TMin : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMin<TLeft, TRight, TOutput>> {
+ static TOutput Do(TLeft left, TRight right)
+ {
+ return Min<TOutput>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ if (std::is_floating_point<TOutput>()) {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto fnType = FunctionType::get(GetTypeFor<TOutput>(context), {left->getType(), right->getType()}, false);
+ const auto& name = GetFuncNameForType<TOutput>("llvm.minnum");
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto res = CallInst::Create(func, {left, right}, "minnum", block);
- return res;
- } else {
- const auto check = CmpInst::Create(Instruction::ICmp, std::is_signed<TOutput>() ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, left, right, "greater", block);
- const auto res = SelectInst::Create(check, right, left, "min", block);
- return res;
- }
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TDecimalMin {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto lv = left.GetInt128();
- if (!NYql::NDecimal::IsComparable(lv))
- return right;
- const auto rv = right.GetInt128();
- if (!NYql::NDecimal::IsComparable(rv))
- return left;
- return NUdf::TUnboxedValuePod(lv > rv ? rv : lv);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
-
- const auto next = BasicBlock::Create(context, "next", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(Type::getInt128Ty(context), 3, "result", done);
-
- const auto l = GetterForInt128(left, block);
- const auto lok = NDecimal::GenIsComparable(l, context, block);
- result->addIncoming(right, block);
- BranchInst::Create(next, done, lok, block);
-
- block = next;
-
- const auto r = GetterForInt128(right, block);
- const auto rok = NDecimal::GenIsComparable(r, context, block);
- result->addIncoming(left, block);
- BranchInst::Create(good, done, rok, block);
-
- block = good;
-
- const auto greater = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, l, r, "greater", block);
- const auto res = SelectInst::Create(greater, right, left, "min", block);
- result->addIncoming(res, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-};
-
-template<typename TType>
-using TAggrMin = TMin<TType, TType, TType>;
-
-template<typename TType>
-struct TTzMin : public TSelectArithmeticBinaryCopyTimezone<TType, TTzMin<TType>> {
- static bool Do(TType left, TType right)
- {
- return left <= right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_or_equal", block);
- }
-#endif
-};
-
-template<typename TType>
-struct TAggrTzMin : public TSelectArithmeticBinaryWithTimezone<TType, TAggrTzMin<TType>> {
- static bool Do(TType left, TType right)
- {
- return left <= right;
- }
-
- static bool DoTz(ui16 left, ui16 right)
- {
- return left <= right;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_value", block);
- }
-
- static Value* GenTz(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_timezone", block);
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomMin {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const bool r = CompareCustoms<Slot>(left, right) > 0;
- (r ? left : right).DeleteUnreferenced();
- return r ? right : left;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, res, ConstantInt::get(res->getType(), 0), "greater", block);
- const auto max = SelectInst::Create(comp, left, right, "max", block);
- ValueCleanup(EValueRepresentation::String, max, ctx, block);
- const auto min = SelectInst::Create(comp, right, left, "min", block);
- return min;
- }
-#endif
-};
-
-}
-
-void RegisterMin(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryNumericFunctionOpt<TMin, TBinaryArgsOpt>(registry, "Min");
- RegisterBooleanSameTypesFunction<TAggrMin, TBinaryArgsOpt>(registry, "Min");
- RegisterDatetimeSameTypesFunction<TAggrMin, TBinaryArgsOpt>(registry, "Min");
- RegisterTzDatetimeSameTypesFunction<TTzMin, TBinaryArgsOpt>(registry, "Min");
-
- RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMin, TBinaryArgsOpt>(registry, "Min");
-
- RegisterCustomSameTypesFunction<NUdf::TDataType<char*>, TCustomMin, TBinaryArgsOpt>(registry, "Min");
- RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMin, TBinaryArgsOpt>(registry, "Min");
-}
-
-void RegisterAggrMin(IBuiltinFunctionRegistry& registry) {
- RegisterNumericAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
- RegisterBooleanAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
- RegisterDatetimeAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
- RegisterTzDatetimeAggregateFunction<TAggrTzMin, TBinaryArgsSameOpt>(registry, "AggrMin");
-
- RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMin, TBinaryArgsSameOpt>(registry, "AggrMin");
-
- RegisterCustomAggregateFunction<NUdf::TDataType<char*>, TCustomMin, TBinaryArgsSameOpt>(registry, "AggrMin");
- RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMin, TBinaryArgsSameOpt>(registry, "AggrMin");
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+ const auto res = CallInst::Create(func, {left, right}, "minnum", block);
+ return res;
+ } else {
+ const auto check = CmpInst::Create(Instruction::ICmp, std::is_signed<TOutput>() ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, left, right, "greater", block);
+ const auto res = SelectInst::Create(check, right, left, "min", block);
+ return res;
+ }
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TDecimalMin {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto lv = left.GetInt128();
+ if (!NYql::NDecimal::IsComparable(lv))
+ return right;
+ const auto rv = right.GetInt128();
+ if (!NYql::NDecimal::IsComparable(rv))
+ return left;
+ return NUdf::TUnboxedValuePod(lv > rv ? rv : lv);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+
+ const auto next = BasicBlock::Create(context, "next", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(Type::getInt128Ty(context), 3, "result", done);
+
+ const auto l = GetterForInt128(left, block);
+ const auto lok = NDecimal::GenIsComparable(l, context, block);
+ result->addIncoming(right, block);
+ BranchInst::Create(next, done, lok, block);
+
+ block = next;
+
+ const auto r = GetterForInt128(right, block);
+ const auto rok = NDecimal::GenIsComparable(r, context, block);
+ result->addIncoming(left, block);
+ BranchInst::Create(good, done, rok, block);
+
+ block = good;
+
+ const auto greater = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, l, r, "greater", block);
+ const auto res = SelectInst::Create(greater, right, left, "min", block);
+ result->addIncoming(res, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+};
+
+template<typename TType>
+using TAggrMin = TMin<TType, TType, TType>;
+
+template<typename TType>
+struct TTzMin : public TSelectArithmeticBinaryCopyTimezone<TType, TTzMin<TType>> {
+ static bool Do(TType left, TType right)
+ {
+ return left <= right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_or_equal", block);
+ }
+#endif
+};
+
+template<typename TType>
+struct TAggrTzMin : public TSelectArithmeticBinaryWithTimezone<TType, TAggrTzMin<TType>> {
+ static bool Do(TType left, TType right)
+ {
+ return left <= right;
+ }
+
+ static bool DoTz(ui16 left, ui16 right)
+ {
+ return left <= right;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_value", block);
+ }
+
+ static Value* GenTz(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULE, left, right, "less_timezone", block);
+ }
+#endif
+};
+
+template<NUdf::EDataSlot Slot>
+struct TCustomMin {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const bool r = CompareCustoms<Slot>(left, right) > 0;
+ (r ? left : right).DeleteUnreferenced();
+ return r ? right : left;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, res, ConstantInt::get(res->getType(), 0), "greater", block);
+ const auto max = SelectInst::Create(comp, left, right, "max", block);
+ ValueCleanup(EValueRepresentation::String, max, ctx, block);
+ const auto min = SelectInst::Create(comp, right, left, "min", block);
+ return min;
+ }
+#endif
+};
+
+}
+
+void RegisterMin(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryNumericFunctionOpt<TMin, TBinaryArgsOpt>(registry, "Min");
+ RegisterBooleanSameTypesFunction<TAggrMin, TBinaryArgsOpt>(registry, "Min");
+ RegisterDatetimeSameTypesFunction<TAggrMin, TBinaryArgsOpt>(registry, "Min");
+ RegisterTzDatetimeSameTypesFunction<TTzMin, TBinaryArgsOpt>(registry, "Min");
+
+ RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMin, TBinaryArgsOpt>(registry, "Min");
+
+ RegisterCustomSameTypesFunction<NUdf::TDataType<char*>, TCustomMin, TBinaryArgsOpt>(registry, "Min");
+ RegisterCustomSameTypesFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMin, TBinaryArgsOpt>(registry, "Min");
+}
+
+void RegisterAggrMin(IBuiltinFunctionRegistry& registry) {
+ RegisterNumericAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+ RegisterBooleanAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+ RegisterDatetimeAggregateFunction<TAggrMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+ RegisterTzDatetimeAggregateFunction<TAggrTzMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+
+ RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TDecimal>, TDecimalMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+
+ RegisterCustomAggregateFunction<NUdf::TDataType<char*>, TCustomMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+ RegisterCustomAggregateFunction<NUdf::TDataType<NUdf::TUtf8>, TCustomMin, TBinaryArgsSameOpt>(registry, "AggrMin");
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp
index 5b9601bb5b..340f2301b5 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp
@@ -1,47 +1,47 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TMinus : public TSimpleArithmeticUnary<TInput, TOutput, TMinus<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return -val;
- }
-
+template<typename TInput, typename TOutput>
+struct TMinus : public TSimpleArithmeticUnary<TInput, TOutput, TMinus<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return -val;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_integral<TInput>() ? BinaryOperator::CreateNeg(arg, "neg", block) : BinaryOperator::CreateFNeg(arg, "neg", block);
- }
-#endif
-};
-
-struct TDecimalMinus {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
- const auto v = arg.GetInt128();
- return NYql::NDecimal::IsComparable(v) ? NUdf::TUnboxedValuePod(-v) : arg;
+ static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_integral<TInput>() ? BinaryOperator::CreateNeg(arg, "neg", block) : BinaryOperator::CreateFNeg(arg, "neg", block);
}
-
+#endif
+};
+
+struct TDecimalMinus {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ const auto v = arg.GetInt128();
+ return NYql::NDecimal::IsComparable(v) ? NUdf::TUnboxedValuePod(-v) : arg;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
- {
- const auto val = GetterForInt128(arg, block);
- const auto ok = NDecimal::GenIsComparable(val, ctx.Codegen->GetContext(), block);
- const auto neg = BinaryOperator::CreateNeg(val, "neg", block);
- const auto res = SelectInst::Create(ok, SetterForInt128(neg, block), arg, "result", block);
- return res;
- }
-#endif
+ static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ const auto val = GetterForInt128(arg, block);
+ const auto ok = NDecimal::GenIsComparable(val, ctx.Codegen->GetContext(), block);
+ const auto neg = BinaryOperator::CreateNeg(val, "neg", block);
+ const auto res = SelectInst::Create(ok, SetterForInt128(neg, block), arg, "result", block);
+ return res;
+ }
+#endif
};
}
-void RegisterMinus(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryNumericFunctionOpt<TMinus, TUnaryArgsOpt>(registry, "Minus");
- NDecimal::RegisterUnaryFunction<TDecimalMinus, TUnaryArgsOpt>(registry, "Minus");
+void RegisterMinus(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryNumericFunctionOpt<TMinus, TUnaryArgsOpt>(registry, "Minus");
+ NDecimal::RegisterUnaryFunction<TDecimalMinus, TUnaryArgsOpt>(registry, "Minus");
RegisterFunctionUnOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TMinus, TUnaryArgsOpt>(registry, "Minus");
}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp
index 0f24882fc3..6017744b88 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp
@@ -1,91 +1,91 @@
#include "mkql_builtins_impl.h"
-#include <cmath>
-
+#include <cmath>
+
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TMod : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMod<TLeft, TRight, TOutput>> {
- static_assert(std::is_floating_point<TOutput>::value, "expected floating point");
-
- static TOutput Do(TOutput left, TOutput right)
- {
- return std::fmod(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
+template<typename TLeft, typename TRight, typename TOutput>
+struct TMod : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMod<TLeft, TRight, TOutput>> {
+ static_assert(std::is_floating_point<TOutput>::value, "expected floating point");
+
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return std::fmod(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
+ {
ctx.Codegen->AddGlobalMapping("fmod", reinterpret_cast<const void*>(static_cast<double(*)(double, double)>(&std::fmod)));
ctx.Codegen->AddGlobalMapping("fmodf", reinterpret_cast<const void*>(static_cast<float(*)(float, float)>(&std::fmod)));
- return BinaryOperator::CreateFRem(left, right, "frem", block);
- }
-#endif
-};
-
-template <typename TLeft, typename TRight, typename TOutput>
-struct TIntegralMod {
- static_assert(std::is_integral<TOutput>::value, "integral type expected");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
- {
- const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
- const auto rv = static_cast<TOutput>(right.template Get<TRight>());
-
- if (rv == 0 ||
- (std::is_signed<TOutput>::value && sizeof(TOutput) <= sizeof(TLeft) && rv == TOutput(-1) && lv == Min<TOutput>()))
- {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(lv % rv);
+ return BinaryOperator::CreateFRem(left, right, "frem", block);
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, typename TOutput>
+struct TIntegralMod {
+ static_assert(std::is_integral<TOutput>::value, "integral type expected");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ {
+ const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
+ const auto rv = static_cast<TOutput>(right.template Get<TRight>());
+
+ if (rv == 0 ||
+ (std::is_signed<TOutput>::value && sizeof(TOutput) <= sizeof(TLeft) && rv == TOutput(-1) && lv == Min<TOutput>()))
+ {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(lv % rv);
}
-
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
- const auto type = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(type, 0);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
-
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto good = BasicBlock::Create(context, "good", ctx.Func);
- const auto result = PHINode::Create(type, 2, "result", done);
- result->addIncoming(zero, block);
-
- if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) {
- const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
- const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
- const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
- const auto all = BinaryOperator::CreateOr(check, two, "all", block);
- BranchInst::Create(done, good, all, block);
- } else {
- BranchInst::Create(done, good, check, block);
- }
-
- block = good;
- const auto rem = std::is_signed<TOutput>() ? BinaryOperator::CreateSRem(lv, rv, "rem", block) : BinaryOperator::CreateURem(lv, rv, "rem", block);
- const auto full = SetterFor<TOutput>(rem, context, block);
- result->addIncoming(full, block);
- BranchInst::Create(done, block);
-
- block = done;
- return result;
- }
-#endif
-};
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto lv = StaticCast<TLeft, TOutput>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rv = StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block);
+ const auto type = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(type, 0);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), 0), "check", block);
+
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto good = BasicBlock::Create(context, "good", ctx.Func);
+ const auto result = PHINode::Create(type, 2, "result", done);
+ result->addIncoming(zero, block);
+
+ if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) {
+ const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block);
+ const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block);
+ const auto two = BinaryOperator::CreateAnd(min, one, "two", block);
+ const auto all = BinaryOperator::CreateOr(check, two, "all", block);
+ BranchInst::Create(done, good, all, block);
+ } else {
+ BranchInst::Create(done, good, check, block);
+ }
+
+ block = good;
+ const auto rem = std::is_signed<TOutput>() ? BinaryOperator::CreateSRem(lv, rv, "rem", block) : BinaryOperator::CreateURem(lv, rv, "rem", block);
+ const auto full = SetterFor<TOutput>(rem, context, block);
+ result->addIncoming(full, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return result;
+ }
+#endif
+};
}
-void RegisterMod(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryRealFunctionOpt<TMod, TBinaryArgsOpt>(registry, "Mod");
- RegisterBinaryIntegralFunctionOpt<TIntegralMod, TBinaryArgsOptWithNullableResult>(registry, "Mod");
+void RegisterMod(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryRealFunctionOpt<TMod, TBinaryArgsOpt>(registry, "Mod");
+ RegisterBinaryIntegralFunctionOpt<TIntegralMod, TBinaryArgsOptWithNullableResult>(registry, "Mod");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp
index ab73e52d28..41dd8fd0f6 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp
@@ -1,5 +1,5 @@
#include "mkql_builtins_impl.h"
-#include "mkql_builtins_datetime.h"
+#include "mkql_builtins_datetime.h"
#include <ydb/library/yql/minikql/mkql_type_ops.h>
@@ -8,66 +8,66 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TMul : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMul<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left * right;
- }
-
+template<typename TLeft, typename TRight, typename TOutput>
+struct TMul : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMul<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left * right;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_floating_point<TOutput>() ?
- BinaryOperator::CreateFMul(left, right, "mul", block):
- BinaryOperator::CreateMul(left, right, "mul", block);
- }
-#endif
-};
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_floating_point<TOutput>() ?
+ BinaryOperator::CreateFMul(left, right, "mul", block):
+ BinaryOperator::CreateMul(left, right, "mul", block);
+ }
+#endif
+};
template<typename TLeft, typename TRight, typename TOutput>
-struct TNumMulInterval {
- static_assert(std::is_same<TOutput, i64>::value, "expected i64");
- static_assert(std::is_integral<TLeft>::value, "left must be integral");
- static_assert(std::is_integral<TRight>::value, "right must be integral");
-
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+struct TNumMulInterval {
+ static_assert(std::is_same<TOutput, i64>::value, "expected i64");
+ static_assert(std::is_integral<TLeft>::value, "left must be integral");
+ static_assert(std::is_integral<TRight>::value, "right must be integral");
+
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
- const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
- const auto rv = static_cast<TOutput>(right.template Get<TRight>());
- const auto ret = lv * rv;
- return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));;
+ const auto lv = static_cast<TOutput>(left.template Get<TLeft>());
+ const auto rv = static_cast<TOutput>(right.template Get<TRight>());
+ const auto ret = lv * rv;
+ return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));;
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = StaticCast<TLeft, i64>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rhs = StaticCast<TRight, i64>(GetterFor<TRight>(right, context, block), context, block);
- const auto mul = BinaryOperator::CreateMul(lhs, rhs, "mul", block);
- const auto full = SetterFor<TOutput>(mul, context, block);
- const auto bad = GenIsBadInterval(mul, context, block);
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
- const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
- return sel;
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = StaticCast<TLeft, i64>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rhs = StaticCast<TRight, i64>(GetterFor<TRight>(right, context, block), context, block);
+ const auto mul = BinaryOperator::CreateMul(lhs, rhs, "mul", block);
+ const auto full = SetterFor<TOutput>(mul, context, block);
+ const auto bad = GenIsBadInterval(mul, context, block);
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+ const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
+ return sel;
}
#endif
};
}
-void RegisterMul(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryNumericFunctionOpt<TMul, TBinaryArgsOpt>(registry, "Mul");
+void RegisterMul(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryNumericFunctionOpt<TMul, TBinaryArgsOpt>(registry, "Mul");
RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<NUdf::TInterval>,
NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<NUdf::TInterval>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<NUdf::TInterval>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<NUdf::TInterval>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<NUdf::TInterval>,
NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<NUdf::TInterval>,
@@ -79,12 +79,12 @@ void RegisterMul(IBuiltinFunctionRegistry& registry) {
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui8>,
NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui16>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
- RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>,
- NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i8>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui16>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
+ RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i16>,
+ NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<ui32>,
NUdf::TDataType<NUdf::TInterval>, TNumMulInterval, TBinaryArgsOptWithNullableResult>(registry, "Mul");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<i32>,
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_nanvl.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_nanvl.cpp
index 4b3a59ead1..bbbed3dfff 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_nanvl.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_nanvl.cpp
@@ -1,107 +1,107 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
+
+#include <cmath>
-#include <cmath>
-
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template <typename TLeft, typename TRight, typename TOutput, bool IsRightOptional>
-struct TNanvl {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
- {
- const auto lv = left.Get<TLeft>();
- if (!std::isnan(lv)) {
- return std::is_same<TLeft, TOutput>() ? left : NUdf::TUnboxedValuePod(static_cast<TOutput>(lv));
- }
-
- if (std::is_same<TRight, TOutput>()) {
- return right;
- } else {
- if (IsRightOptional && !right) {
- return NUdf::TUnboxedValuePod();
- }
-
- const auto rv = right.Get<TRight>();
- return NUdf::TUnboxedValuePod(static_cast<TOutput>(rv));
- }
- }
-
+template <typename TLeft, typename TRight, typename TOutput, bool IsRightOptional>
+struct TNanvl {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ {
+ const auto lv = left.Get<TLeft>();
+ if (!std::isnan(lv)) {
+ return std::is_same<TLeft, TOutput>() ? left : NUdf::TUnboxedValuePod(static_cast<TOutput>(lv));
+ }
+
+ if (std::is_same<TRight, TOutput>()) {
+ return right;
+ } else {
+ if (IsRightOptional && !right) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ const auto rv = right.Get<TRight>();
+ return NUdf::TUnboxedValuePod(static_cast<TOutput>(rv));
+ }
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- auto& module = ctx.Codegen->GetModule();
- const auto val = GetterFor<TLeft>(left, context, block);
- const auto fnType = FunctionType::get(Type::getInt1Ty(context), {val->getType()}, false);
- const auto name = std::is_same<TLeft, float>() ? "MyFloatIsNan" : "MyDoubleIsNan";
- ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<bool(*)(TLeft)>(&std::isnan)));
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ auto& module = ctx.Codegen->GetModule();
+ const auto val = GetterFor<TLeft>(left, context, block);
+ const auto fnType = FunctionType::get(Type::getInt1Ty(context), {val->getType()}, false);
+ const auto name = std::is_same<TLeft, float>() ? "MyFloatIsNan" : "MyDoubleIsNan";
+ ctx.Codegen->AddGlobalMapping(name, reinterpret_cast<const void*>(static_cast<bool(*)(TLeft)>(&std::isnan)));
const auto func = module.getOrInsertFunction(name, fnType).getCallee();
- const auto isnan = CallInst::Create(func, {val}, "isnan", block);
-
- const auto lout = std::is_same<TLeft, TOutput>() ? left : SetterFor<TOutput>(StaticCast<TLeft, TOutput>(val, context, block), context, block);
- const auto rout = std::is_same<TRight, TOutput>() ? right : SetterFor<TOutput>(StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block), context, block);
-
- if (IsRightOptional && !std::is_same<TRight, TOutput>()) {
- const auto nanvl = SelectInst::Create(isnan, rout, lout, "nanvl", block);
- return nanvl;
- } else {
- const auto nanvl = SelectInst::Create(isnan, rout, lout, "nanvl", block);
- return nanvl;
- }
- }
-#endif
-};
-
-struct TDecimalNanvl {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
- {
- return NYql::NDecimal::IsComparable(left.GetInt128()) ? left : right;
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto good = NDecimal::GenIsComparable(GetterForInt128(left, block), context, block);
- const auto sel = SelectInst::Create(good, left, right, "sel", block);
- return sel;
- }
-#endif
-};
-
-template <
- typename TInput1, typename TInput2, typename TOutput,
- template<typename, typename, typename, bool> class TFunc,
- template<typename, typename, typename, bool, bool> class TArgs
->
-void RegisterBinaryNavlLeftOpt(IBuiltinFunctionRegistry& registry, const char* name) {
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, false>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, true>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, false>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, true>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, false>>(registry, name);
+ const auto isnan = CallInst::Create(func, {val}, "isnan", block);
+
+ const auto lout = std::is_same<TLeft, TOutput>() ? left : SetterFor<TOutput>(StaticCast<TLeft, TOutput>(val, context, block), context, block);
+ const auto rout = std::is_same<TRight, TOutput>() ? right : SetterFor<TOutput>(StaticCast<TRight, TOutput>(GetterFor<TRight>(right, context, block), context, block), context, block);
+
+ if (IsRightOptional && !std::is_same<TRight, TOutput>()) {
+ const auto nanvl = SelectInst::Create(isnan, rout, lout, "nanvl", block);
+ return nanvl;
+ } else {
+ const auto nanvl = SelectInst::Create(isnan, rout, lout, "nanvl", block);
+ return nanvl;
+ }
+ }
+#endif
+};
+
+struct TDecimalNanvl {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ {
+ return NYql::NDecimal::IsComparable(left.GetInt128()) ? left : right;
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto good = NDecimal::GenIsComparable(GetterForInt128(left, block), context, block);
+ const auto sel = SelectInst::Create(good, left, right, "sel", block);
+ return sel;
+ }
+#endif
+};
+
+template <
+ typename TInput1, typename TInput2, typename TOutput,
+ template<typename, typename, typename, bool> class TFunc,
+ template<typename, typename, typename, bool, bool> class TArgs
+>
+void RegisterBinaryNavlLeftOpt(IBuiltinFunctionRegistry& registry, const char* name) {
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, false>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, true>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, false>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout, true>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, false>>(registry, name);
+}
+
+void RegisterBinaryNavlFunction(IBuiltinFunctionRegistry& registry, const char* name) {
+ RegisterBinaryNavlLeftOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TNanvl, TBinaryArgsOpt>(registry, name);
+ RegisterBinaryNavlLeftOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
+ RegisterBinaryNavlLeftOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
+ RegisterBinaryNavlLeftOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
+}
+
+void RegisterBinaryNavlDecimal(IBuiltinFunctionRegistry& registry, const char* name) {
+ RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, false>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, true>, TBinaryWrap<false, false>>(registry, name);
+ RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, false>, TBinaryWrap<true, false>>(registry, name);
+ RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, true>, TBinaryWrap<true, false>>(registry, name);
+}
+
}
-void RegisterBinaryNavlFunction(IBuiltinFunctionRegistry& registry, const char* name) {
- RegisterBinaryNavlLeftOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TNanvl, TBinaryArgsOpt>(registry, name);
- RegisterBinaryNavlLeftOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
- RegisterBinaryNavlLeftOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
- RegisterBinaryNavlLeftOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TNanvl, TBinaryArgsOpt>(registry, name);
-}
-
-void RegisterBinaryNavlDecimal(IBuiltinFunctionRegistry& registry, const char* name) {
- RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, false>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, false, true>, TBinaryWrap<false, false>>(registry, name);
- RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, false>, TBinaryWrap<true, false>>(registry, name);
- RegisterFunctionImpl<TDecimalNanvl, TBinaryArgsOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, true, true>, TBinaryWrap<true, false>>(registry, name);
-}
-
-}
-
-void RegisterNanvl(IBuiltinFunctionRegistry& registry) {
- RegisterBinaryNavlFunction(registry, "Nanvl");
- RegisterBinaryNavlDecimal(registry, "Nanvl");
+void RegisterNanvl(IBuiltinFunctionRegistry& registry) {
+ RegisterBinaryNavlFunction(registry, "Nanvl");
+ RegisterBinaryNavlDecimal(registry, "Nanvl");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp
index 46b4357f32..d9d8991ca0 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp
@@ -1,280 +1,280 @@
-#include "mkql_builtins_compare.h"
+#include "mkql_builtins_compare.h"
#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
-
+#include "mkql_builtins_decimal.h"
+
#include <ydb/library/yql/minikql/mkql_type_ops.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
- return x != y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
- return x < T1(0) || static_cast<std::make_unsigned_t<T1>>(x) != y;
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
- return y < T2(0) || x != static_cast<std::make_unsigned_t<T2>>(y);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- const auto l = static_cast<FT>(x);
- const auto r = static_cast<FT>(y);
- if (Aggr && std::isunordered(l, r)) {
- return std::isnan(l) != std::isnan(r);
- }
- return l != r;
-}
-
-#ifndef MKQL_DISABLE_CODEGEN
-Value* GenNotEqualsIntegral(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lhs, rhs, "not_equals", block);
-}
-
-template <bool Aggr>
-Value* GenNotEqualsFloats(Value* lhs, Value* rhs, BasicBlock* block);
-
-template <>
-Value* GenNotEqualsFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
- return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNE, lhs, rhs, "not_equals", block);
-}
-
-template <>
-Value* GenNotEqualsFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
- const auto one = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ONE, lhs, rhs, "not_equals", block);
- const auto lnan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(lhs->getType(), 0.0), lhs, "lnan", block);
- const auto rnan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "rnan", block);
- const auto once = BinaryOperator::CreateXor(lnan, rnan, "xor", block);
- return BinaryOperator::CreateOr(one, once, "or", block);
-}
-
-template <typename T1, typename T2>
-Value* GenNotEqualsIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(x->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
- using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
- const auto comp = GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
- }
-
-template <typename T1, typename T2>
-Value* GenNotEqualsIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- const auto zero = ConstantInt::get(y->getType(), 0);
- const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
- using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
- const auto comp = GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
- return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
-}
-
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
- std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
-inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
- return GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
-inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenNotEqualsIntegralLeftSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
- && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
-inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- return GenNotEqualsIntegralRightSigned<T1, T2>(x, y, context, block);
-}
-
-template <typename T1, typename T2,
- std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
-inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
- using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
- using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
- using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
- return GenNotEqualsFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
-}
-#endif
-
-struct TAggrNotEquals {
- static bool Simple(bool left, bool right)
- {
- return left != right;
- }
- static bool Join(bool one, bool two)
- {
- return one || two;
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_NE;
-
- static Value* GenJoin(Value* one, Value* two, BasicBlock* block)
- {
- return BinaryOperator::CreateOr(one, two, "or", block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TNotEquals : public TCompareArithmeticBinary<TLeft, TRight, TNotEquals<TLeft, TRight, Aggr>>, public TAggrNotEquals {
- static bool Do(TLeft left, TRight right)
- {
- return NotEquals<TLeft, TRight, Aggr>(left, right);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- return GenNotEquals<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
- }
-#endif
-};
-
-template<typename TLeft, typename TRight, bool Aggr>
-struct TDiffDateNotEquals : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateNotEquals<TLeft, TRight, Aggr>>, public TAggrNotEquals {
- static bool Do(TLeft left, TRight right)
- {
- return std::is_same<TLeft, TRight>::value ?
- NotEquals<TLeft, TRight, Aggr>(left, right):
- NotEquals<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value == std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
+ return x != y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
+ return x < T1(0) || static_cast<std::make_unsigned_t<T1>>(x) != y;
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
+ return y < T2(0) || x != static_cast<std::make_unsigned_t<T2>>(y);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+Y_FORCE_INLINE bool NotEquals(T1 x, T2 y) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ const auto l = static_cast<FT>(x);
+ const auto r = static_cast<FT>(y);
+ if (Aggr && std::isunordered(l, r)) {
+ return std::isnan(l) != std::isnan(r);
+ }
+ return l != r;
+}
+
+#ifndef MKQL_DISABLE_CODEGEN
+Value* GenNotEqualsIntegral(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, lhs, rhs, "not_equals", block);
+}
+
+template <bool Aggr>
+Value* GenNotEqualsFloats(Value* lhs, Value* rhs, BasicBlock* block);
+
+template <>
+Value* GenNotEqualsFloats<false>(Value* lhs, Value* rhs, BasicBlock* block) {
+ return CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNE, lhs, rhs, "not_equals", block);
+}
+
+template <>
+Value* GenNotEqualsFloats<true>(Value* lhs, Value* rhs, BasicBlock* block) {
+ const auto one = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_ONE, lhs, rhs, "not_equals", block);
+ const auto lnan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(lhs->getType(), 0.0), lhs, "lnan", block);
+ const auto rnan = CmpInst::Create(Instruction::FCmp, FCmpInst::FCMP_UNO, ConstantFP::get(rhs->getType(), 0.0), rhs, "rnan", block);
+ const auto once = BinaryOperator::CreateXor(lnan, rnan, "xor", block);
+ return BinaryOperator::CreateOr(one, once, "or", block);
+}
+
+template <typename T1, typename T2>
+Value* GenNotEqualsIntegralLeftSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(x->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, x, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(std::make_unsigned_t<T1>) > sizeof(T2)), std::make_unsigned_t<T1>, T2>;
+ const auto comp = GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+ }
+
+template <typename T1, typename T2>
+Value* GenNotEqualsIntegralRightSigned(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ const auto zero = ConstantInt::get(y->getType(), 0);
+ const auto neg = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, y, zero, "negative", block);
+ using T = std::conditional_t<(sizeof(T1) > sizeof(std::make_unsigned_t<T2>)), T1, std::make_unsigned_t<T2>>;
+ const auto comp = GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+ return SelectInst::Create(neg, ConstantInt::getTrue(context), comp, "result", block);
+}
+
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_unsigned<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_signed<T1>::value && std::is_signed<T2>::value &&
+ std::is_integral<T1>::value && std::is_integral<T2>::value, bool> Aggr>
+inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using T = std::conditional_t<(sizeof(T1) > sizeof(T2)), T1, T2>;
+ return GenNotEqualsIntegral(StaticCast<T1, T>(x, context, block), StaticCast<T2, T>(y, context, block), block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_signed<T1>::value && std::is_unsigned<T2>::value, bool> Aggr>
+inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenNotEqualsIntegralLeftSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_integral<T1>::value && std::is_integral<T2>::value
+ && std::is_unsigned<T1>::value && std::is_signed<T2>::value, bool> Aggr>
+inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ return GenNotEqualsIntegralRightSigned<T1, T2>(x, y, context, block);
+}
+
+template <typename T1, typename T2,
+ std::enable_if_t<std::is_floating_point<T1>::value || std::is_floating_point<T2>::value, bool> Aggr>
+inline Value* GenNotEquals(Value* x, Value* y, LLVMContext &context, BasicBlock* block) {
+ using F1 = std::conditional_t<std::is_floating_point<T1>::value, T1, T2>;
+ using F2 = std::conditional_t<std::is_floating_point<T2>::value, T2, T1>;
+ using FT = std::conditional_t<(sizeof(F1) > sizeof(F2)), F1, F2>;
+ return GenNotEqualsFloats<Aggr>(StaticCast<T1, FT>(x, context, block), StaticCast<T2, FT>(y, context, block), block);
+}
+#endif
+
+struct TAggrNotEquals {
+ static bool Simple(bool left, bool right)
+ {
+ return left != right;
+ }
+ static bool Join(bool one, bool two)
+ {
+ return one || two;
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static constexpr CmpInst::Predicate SimplePredicate = ICmpInst::ICMP_NE;
+
+ static Value* GenJoin(Value* one, Value* two, BasicBlock* block)
+ {
+ return BinaryOperator::CreateOr(one, two, "or", block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TNotEquals : public TCompareArithmeticBinary<TLeft, TRight, TNotEquals<TLeft, TRight, Aggr>>, public TAggrNotEquals {
+ static bool Do(TLeft left, TRight right)
+ {
+ return NotEquals<TLeft, TRight, Aggr>(left, right);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ return GenNotEquals<TLeft, TRight, Aggr>(left, right, ctx.Codegen->GetContext(), block);
+ }
+#endif
+};
+
+template<typename TLeft, typename TRight, bool Aggr>
+struct TDiffDateNotEquals : public TCompareArithmeticBinary<TLeft, TRight, TDiffDateNotEquals<TLeft, TRight, Aggr>>, public TAggrNotEquals {
+ static bool Do(TLeft left, TRight right)
+ {
+ return std::is_same<TLeft, TRight>::value ?
+ NotEquals<TLeft, TRight, Aggr>(left, right):
+ NotEquals<TScaledDate, TScaledDate, Aggr>(ToScaledDate<TLeft>(left), ToScaledDate<TRight>(right));
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ return std::is_same<TLeft, TRight>::value ?
+ GenNotEquals<TLeft, TRight, Aggr>(left, right, context, block):
+ GenNotEquals<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ }
+#endif
+};
+
+template <typename TLeft, typename TRight, bool Aggr>
+struct TAggrTzDateNotEquals : public TArithmeticConstraintsBinary<TLeft, TRight, bool>, public TAggrNotEquals {
+ static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ return NUdf::TUnboxedValuePod(Join(NotEquals<TLeft, TRight, Aggr>(left.template Get<TLeft>(), right.template Get<TRight>()), NotEquals<ui16, ui16, Aggr>(left.GetTimezoneId(), right.GetTimezoneId())));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- return std::is_same<TLeft, TRight>::value ?
- GenNotEquals<TLeft, TRight, Aggr>(left, right, context, block):
- GenNotEquals<TScaledDate, TScaledDate, Aggr>(GenToScaledDate<TLeft>(left, context, block), GenToScaledDate<TRight>(right, context, block), context, block);
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto ltz = GetterForTimezone(context, left, block);
+ const auto rtz = GetterForTimezone(context, right, block);
+ const auto result = GenJoin(GenNotEquals<TLeft, TRight, Aggr>(lhs, rhs, context, block), GenNotEquals<ui16, ui16, Aggr>(ltz, rtz, context, block), block);
+ const auto wide = MakeBoolean(result, context, block);
+ return wide;
}
#endif
};
-template <typename TLeft, typename TRight, bool Aggr>
-struct TAggrTzDateNotEquals : public TArithmeticConstraintsBinary<TLeft, TRight, bool>, public TAggrNotEquals {
- static_assert(std::is_same<TLeft, TRight>::value, "Must be same type.");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- return NUdf::TUnboxedValuePod(Join(NotEquals<TLeft, TRight, Aggr>(left.template Get<TLeft>(), right.template Get<TRight>()), NotEquals<ui16, ui16, Aggr>(left.GetTimezoneId(), right.GetTimezoneId())));
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto ltz = GetterForTimezone(context, left, block);
- const auto rtz = GetterForTimezone(context, right, block);
- const auto result = GenJoin(GenNotEquals<TLeft, TRight, Aggr>(lhs, rhs, context, block), GenNotEquals<ui16, ui16, Aggr>(ltz, rtz, context, block), block);
- const auto wide = MakeBoolean(result, context, block);
- return wide;
- }
-#endif
-};
-
-template<NUdf::EDataSlot Slot>
-struct TCustomNotEquals : public TAggrNotEquals {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
- return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) != 0);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
- const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, res, ConstantInt::get(res->getType(), 0), "not_equals", block);
- ValueCleanup(EValueRepresentation::String, left, ctx, block);
- ValueCleanup(EValueRepresentation::String, right, ctx, block);
- return MakeBoolean(comp, context, block);
- }
-#endif
-};
-
-struct TDecimalNotEquals {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(!NYql::NDecimal::IsComparable(r) || l != r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto bad = NDecimal::GenIsNonComparable(r, context, block);
- const auto neq = GenNotEqualsIntegral(l, r, block);
- const auto res = BinaryOperator::CreateOr(bad, neq, "res", block);
- return MakeBoolean(res, context, block);
- }
-#endif
-};
-
-struct TDecimalAggrNotEquals : public TAggrNotEquals {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- return NUdf::TUnboxedValuePod(l != r);
- }
-
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto neq = GenNotEqualsIntegral(l, r, block);
- return MakeBoolean(neq, context, block);
- }
-#endif
-};
-
-}
-
-void RegisterNotEquals(IBuiltinFunctionRegistry& registry) {
- const auto name = "NotEquals";
-
- RegisterComparePrimitive<TNotEquals, TCompareArgsOpt>(registry, name);
+template<NUdf::EDataSlot Slot>
+struct TCustomNotEquals : public TAggrNotEquals {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod left, NUdf::TUnboxedValuePod right) {
+ return NUdf::TUnboxedValuePod(CompareCustomsWithCleanup<Slot>(left, right) != 0);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto res = CallBinaryUnboxedValueFunction(&CompareCustoms<Slot>, Type::getInt32Ty(context), left, right, ctx.Codegen, block);
+ const auto comp = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, res, ConstantInt::get(res->getType(), 0), "not_equals", block);
+ ValueCleanup(EValueRepresentation::String, left, ctx, block);
+ ValueCleanup(EValueRepresentation::String, right, ctx, block);
+ return MakeBoolean(comp, context, block);
+ }
+#endif
+};
+
+struct TDecimalNotEquals {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(!NYql::NDecimal::IsComparable(r) || l != r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto bad = NDecimal::GenIsNonComparable(r, context, block);
+ const auto neq = GenNotEqualsIntegral(l, r, block);
+ const auto res = BinaryOperator::CreateOr(bad, neq, "res", block);
+ return MakeBoolean(res, context, block);
+ }
+#endif
+};
+
+struct TDecimalAggrNotEquals : public TAggrNotEquals {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ return NUdf::TUnboxedValuePod(l != r);
+ }
+
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto neq = GenNotEqualsIntegral(l, r, block);
+ return MakeBoolean(neq, context, block);
+ }
+#endif
+};
+
+}
+
+void RegisterNotEquals(IBuiltinFunctionRegistry& registry) {
+ const auto name = "NotEquals";
+
+ RegisterComparePrimitive<TNotEquals, TCompareArgsOpt>(registry, name);
RegisterCompareDatetime<TDiffDateNotEquals, TCompareArgsOpt>(registry, name);
-
- RegisterCompareStrings<TCustomNotEquals, TCompareArgsOpt>(registry, name);
- RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalNotEquals, TCompareArgsOpt>(registry, name);
-
- const auto aggrName = "AggrNotEquals";
- RegisterAggrComparePrimitive<TNotEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareDatetime<TDiffDateNotEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareTzDatetime<TAggrTzDateNotEquals, TCompareArgsOpt>(registry, aggrName);
-
- RegisterAggrCompareStrings<TCustomNotEquals, TCompareArgsOpt>(registry, aggrName);
- RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrNotEquals, TCompareArgsOpt>(registry, aggrName);
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+
+ RegisterCompareStrings<TCustomNotEquals, TCompareArgsOpt>(registry, name);
+ RegisterCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, NUdf::TDataType<NUdf::TDecimal>, TDecimalNotEquals, TCompareArgsOpt>(registry, name);
+
+ const auto aggrName = "AggrNotEquals";
+ RegisterAggrComparePrimitive<TNotEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareDatetime<TDiffDateNotEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareTzDatetime<TAggrTzDateNotEquals, TCompareArgsOpt>(registry, aggrName);
+
+ RegisterAggrCompareStrings<TCustomNotEquals, TCompareArgsOpt>(registry, aggrName);
+ RegisterAggrCompareCustomOpt<NUdf::TDataType<NUdf::TDecimal>, TDecimalAggrNotEquals, TCompareArgsOpt>(registry, aggrName);
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_plus.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_plus.cpp
index 98a5141a20..49979a435a 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_plus.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_plus.cpp
@@ -1,42 +1,42 @@
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_decimal.h"
namespace NKikimr {
namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TPlus : public TSimpleArithmeticUnary<TInput, TOutput, TPlus<TInput, TOutput>> {
- static TOutput Do(TInput val)
- {
- return +val;
- }
-
+template<typename TInput, typename TOutput>
+struct TPlus : public TSimpleArithmeticUnary<TInput, TOutput, TPlus<TInput, TOutput>> {
+ static TOutput Do(TInput val)
+ {
+ return +val;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*&)
- {
- return arg;
- }
-#endif
-};
-
-struct TDecimalPlus {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ {
return arg;
}
-
+#endif
+};
+
+struct TDecimalPlus {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
+ return arg;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
static Value* Generate(Value* arg, const TCodegenContext&, BasicBlock*&)
- {
- return arg;
- }
-#endif
+ {
+ return arg;
+ }
+#endif
};
}
-void RegisterPlus(IBuiltinFunctionRegistry& registry) {
- RegisterUnaryNumericFunctionOpt<TPlus, TUnaryArgsOpt>(registry, "Plus");
- NDecimal::RegisterUnaryFunction<TDecimalPlus, TUnaryArgsOpt>(registry, "Plus");
+void RegisterPlus(IBuiltinFunctionRegistry& registry) {
+ RegisterUnaryNumericFunctionOpt<TPlus, TUnaryArgsOpt>(registry, "Plus");
+ NDecimal::RegisterUnaryFunction<TDecimalPlus, TUnaryArgsOpt>(registry, "Plus");
RegisterFunctionUnOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TPlus, TUnaryArgsOpt>(registry, "Plus");
}
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotleft.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotleft.cpp
index fa63b7bcf8..208428e13b 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotleft.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotleft.cpp
@@ -5,33 +5,33 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TRotLeft : public TShiftArithmeticBinary<TInput, TOutput, TRotLeft<TInput, TOutput>> {
- static TOutput Do(TInput arg, ui8 bits)
- {
- bits %= (sizeof(arg) * CHAR_BIT);
- return bits ? (arg << bits) | (arg >> (sizeof(arg) * CHAR_BIT - bits)) : arg;
- }
-
+template<typename TInput, typename TOutput>
+struct TRotLeft : public TShiftArithmeticBinary<TInput, TOutput, TRotLeft<TInput, TOutput>> {
+ static TOutput Do(TInput arg, ui8 bits)
+ {
+ bits %= (sizeof(arg) * CHAR_BIT);
+ return bits ? (arg << bits) | (arg >> (sizeof(arg) * CHAR_BIT - bits)) : arg;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
- {
- const auto maxb = ConstantInt::get(arg->getType(), sizeof(TInput) * CHAR_BIT);
- const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
- const auto rem = BinaryOperator::CreateURem(zext, maxb, "rem", block);
- const auto shl = BinaryOperator::CreateShl(arg, rem, "shl", block);
- const auto sub = BinaryOperator::CreateSub(maxb, rem, "sub", block);
- const auto lshr = BinaryOperator::CreateLShr(arg, sub, "lshr", block);
- const auto res = BinaryOperator::CreateOr(shl, lshr, "res", block);
- return res;
- }
-#endif
-};
+ static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
+ {
+ const auto maxb = ConstantInt::get(arg->getType(), sizeof(TInput) * CHAR_BIT);
+ const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
+ const auto rem = BinaryOperator::CreateURem(zext, maxb, "rem", block);
+ const auto shl = BinaryOperator::CreateShl(arg, rem, "shl", block);
+ const auto sub = BinaryOperator::CreateSub(maxb, rem, "sub", block);
+ const auto lshr = BinaryOperator::CreateLShr(arg, sub, "lshr", block);
+ const auto res = BinaryOperator::CreateOr(shl, lshr, "res", block);
+ return res;
+ }
+#endif
+};
}
-void RegisterRotLeft(IBuiltinFunctionRegistry& registry) {
- RegisterUnsignedShiftFunctionOpt<TRotLeft, TBinaryShiftArgsOpt>(registry, "RotLeft");
+void RegisterRotLeft(IBuiltinFunctionRegistry& registry) {
+ RegisterUnsignedShiftFunctionOpt<TRotLeft, TBinaryShiftArgsOpt>(registry, "RotLeft");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotright.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotright.cpp
index b2164d7cfa..4694c266df 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotright.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_rotright.cpp
@@ -5,33 +5,33 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TRotRight : public TShiftArithmeticBinary<TInput, TOutput, TRotRight<TInput, TOutput>> {
- static TOutput Do(TInput arg, ui8 bits)
- {
- bits %= (sizeof(arg) * CHAR_BIT);
- return bits ? ((arg >> bits) | (arg << (sizeof(arg) * CHAR_BIT - bits))) : arg;
- }
-
+template<typename TInput, typename TOutput>
+struct TRotRight : public TShiftArithmeticBinary<TInput, TOutput, TRotRight<TInput, TOutput>> {
+ static TOutput Do(TInput arg, ui8 bits)
+ {
+ bits %= (sizeof(arg) * CHAR_BIT);
+ return bits ? ((arg >> bits) | (arg << (sizeof(arg) * CHAR_BIT - bits))) : arg;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
- {
- const auto maxb = ConstantInt::get(arg->getType(), sizeof(TInput) * CHAR_BIT);
- const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
- const auto rem = BinaryOperator::CreateURem(zext, maxb, "rem", block);
- const auto lshr = BinaryOperator::CreateLShr(arg, rem, "lshr", block);
- const auto sub = BinaryOperator::CreateSub(maxb, rem, "sub", block);
- const auto shl = BinaryOperator::CreateShl(arg, sub, "shl", block);
- const auto res = BinaryOperator::CreateOr(shl, lshr, "res", block);
- return res;
- }
-#endif
-};
+ static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
+ {
+ const auto maxb = ConstantInt::get(arg->getType(), sizeof(TInput) * CHAR_BIT);
+ const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
+ const auto rem = BinaryOperator::CreateURem(zext, maxb, "rem", block);
+ const auto lshr = BinaryOperator::CreateLShr(arg, rem, "lshr", block);
+ const auto sub = BinaryOperator::CreateSub(maxb, rem, "sub", block);
+ const auto shl = BinaryOperator::CreateShl(arg, sub, "shl", block);
+ const auto res = BinaryOperator::CreateOr(shl, lshr, "res", block);
+ return res;
+ }
+#endif
+};
}
-void RegisterRotRight(IBuiltinFunctionRegistry& registry) {
- RegisterUnsignedShiftFunctionOpt<TRotRight, TBinaryShiftArgsOpt>(registry, "RotRight");
+void RegisterRotRight(IBuiltinFunctionRegistry& registry) {
+ RegisterUnsignedShiftFunctionOpt<TRotRight, TBinaryShiftArgsOpt>(registry, "RotRight");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftleft.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftleft.cpp
index 41b329a893..02231f46cb 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftleft.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftleft.cpp
@@ -5,31 +5,31 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TShiftLeft : public TShiftArithmeticBinary<TInput, TOutput, TShiftLeft<TInput, TOutput>> {
- static TOutput Do(TInput arg, ui8 bits)
- {
- return (bits < sizeof(arg) * CHAR_BIT) ? (arg << bits) : 0;
- }
-
+template<typename TInput, typename TOutput>
+struct TShiftLeft : public TShiftArithmeticBinary<TInput, TOutput, TShiftLeft<TInput, TOutput>> {
+ static TOutput Do(TInput arg, ui8 bits)
+ {
+ return (bits < sizeof(arg) * CHAR_BIT) ? (arg << bits) : 0;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
- {
- const auto zero = ConstantInt::get(arg->getType(), 0);
- const auto maxb = ConstantInt::get(bits->getType(), sizeof(TInput) * CHAR_BIT);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, bits, maxb, "check", block);
- const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
- const auto shl = BinaryOperator::CreateShl(arg, zext, "shl", block);
- const auto res = SelectInst::Create(check, shl, zero, "res", block);
- return res;
- }
-#endif
-};
+ static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
+ {
+ const auto zero = ConstantInt::get(arg->getType(), 0);
+ const auto maxb = ConstantInt::get(bits->getType(), sizeof(TInput) * CHAR_BIT);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, bits, maxb, "check", block);
+ const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
+ const auto shl = BinaryOperator::CreateShl(arg, zext, "shl", block);
+ const auto res = SelectInst::Create(check, shl, zero, "res", block);
+ return res;
+ }
+#endif
+};
}
-void RegisterShiftLeft(IBuiltinFunctionRegistry& registry) {
- RegisterUnsignedShiftFunctionOpt<TShiftLeft, TBinaryShiftArgsOpt>(registry, "ShiftLeft");
+void RegisterShiftLeft(IBuiltinFunctionRegistry& registry) {
+ RegisterUnsignedShiftFunctionOpt<TShiftLeft, TBinaryShiftArgsOpt>(registry, "ShiftLeft");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftright.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftright.cpp
index 952a0161c7..43bfb6ad98 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftright.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_shiftright.cpp
@@ -5,31 +5,31 @@ namespace NMiniKQL {
namespace {
-template<typename TInput, typename TOutput>
-struct TShiftRight : public TShiftArithmeticBinary<TInput, TOutput, TShiftRight<TInput, TOutput>> {
- static TOutput Do(TInput arg, ui8 bits)
- {
- return (bits < sizeof(arg) * CHAR_BIT) ? (arg >> bits) : 0;
- }
-
+template<typename TInput, typename TOutput>
+struct TShiftRight : public TShiftArithmeticBinary<TInput, TOutput, TShiftRight<TInput, TOutput>> {
+ static TOutput Do(TInput arg, ui8 bits)
+ {
+ return (bits < sizeof(arg) * CHAR_BIT) ? (arg >> bits) : 0;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
- {
- const auto zero = ConstantInt::get(arg->getType(), 0);
- const auto maxb = ConstantInt::get(bits->getType(), sizeof(TInput) * CHAR_BIT);
- const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, bits, maxb, "check", block);
- const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
- const auto lshr = BinaryOperator::CreateLShr(arg, zext, "lshr", block);
- const auto res = SelectInst::Create(check, lshr, zero, "res", block);
- return res;
- }
-#endif
-};
+ static Value* Gen(Value* arg, Value* bits, const TCodegenContext&, BasicBlock*& block)
+ {
+ const auto zero = ConstantInt::get(arg->getType(), 0);
+ const auto maxb = ConstantInt::get(bits->getType(), sizeof(TInput) * CHAR_BIT);
+ const auto check = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, bits, maxb, "check", block);
+ const auto zext = arg->getType() == bits->getType() ? bits : new ZExtInst(bits, arg->getType(), "zext", block);
+ const auto lshr = BinaryOperator::CreateLShr(arg, zext, "lshr", block);
+ const auto res = SelectInst::Create(check, lshr, zero, "res", block);
+ return res;
+ }
+#endif
+};
}
-void RegisterShiftRight(IBuiltinFunctionRegistry& registry) {
- RegisterUnsignedShiftFunctionOpt<TShiftRight, TBinaryShiftArgsOpt>(registry, "ShiftRight");
+void RegisterShiftRight(IBuiltinFunctionRegistry& registry) {
+ RegisterUnsignedShiftFunctionOpt<TShiftRight, TBinaryShiftArgsOpt>(registry, "ShiftRight");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp
index 390dc668f7..c823cddce7 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp
@@ -1,6 +1,6 @@
#include "mkql_builtins_impl.h"
-#include "mkql_builtins_datetime.h"
-#include "mkql_builtins_decimal.h"
+#include "mkql_builtins_datetime.h"
+#include "mkql_builtins_decimal.h"
#include <ydb/library/yql/minikql/mkql_type_ops.h>
@@ -9,187 +9,187 @@ namespace NMiniKQL {
namespace {
-template<typename TLeft, typename TRight, typename TOutput>
-struct TSub : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TSub<TLeft, TRight, TOutput>> {
- static TOutput Do(TOutput left, TOutput right)
- {
- return left - right;
- }
-
+template<typename TLeft, typename TRight, typename TOutput>
+struct TSub : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TSub<TLeft, TRight, TOutput>> {
+ static TOutput Do(TOutput left, TOutput right)
+ {
+ return left - right;
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
- {
- return std::is_integral<TOutput>() ? BinaryOperator::CreateSub(left, right, "sub", block) : BinaryOperator::CreateFSub(left, right, "sub", block);
- }
-#endif
-};
-
-template<ui8 Precision>
-struct TDecimalSub {
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
- const auto l = left.GetInt128();
- const auto r = right.GetInt128();
- const auto s = l - r;
-
- using namespace NYql::NDecimal;
-
- if (IsNormal<Precision>(l) && IsNormal<Precision>(r) && IsNormal<Precision>(s))
- return NUdf::TUnboxedValuePod(s);
-
- if (IsNan(l) || IsNan(r) || !s)
- return NUdf::TUnboxedValuePod(Nan());
- else
- return NUdf::TUnboxedValuePod(s > 0 ? +Inf() : -Inf());
+ static Value* Gen(Value* left, Value* right, const TCodegenContext&, BasicBlock*& block)
+ {
+ return std::is_integral<TOutput>() ? BinaryOperator::CreateSub(left, right, "sub", block) : BinaryOperator::CreateFSub(left, right, "sub", block);
}
-
+#endif
+};
+
+template<ui8 Precision>
+struct TDecimalSub {
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
+ const auto l = left.GetInt128();
+ const auto r = right.GetInt128();
+ const auto s = l - r;
+
+ using namespace NYql::NDecimal;
+
+ if (IsNormal<Precision>(l) && IsNormal<Precision>(r) && IsNormal<Precision>(s))
+ return NUdf::TUnboxedValuePod(s);
+
+ if (IsNan(l) || IsNan(r) || !s)
+ return NUdf::TUnboxedValuePod(Nan());
+ else
+ return NUdf::TUnboxedValuePod(s > 0 ? +Inf() : -Inf());
+ }
+
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto& bounds = NDecimal::GenBounds<Precision>(context);
-
- const auto l = GetterForInt128(left, block);
- const auto r = GetterForInt128(right, block);
- const auto sub = BinaryOperator::CreateSub(l, r, "sub", block);
-
- const auto lok = NDecimal::GenInBounds(l, bounds.first, bounds.second, block);
- const auto rok = NDecimal::GenInBounds(r, bounds.first, bounds.second, block);
- const auto sok = NDecimal::GenInBounds(sub, bounds.first, bounds.second, block);
-
- const auto bok = BinaryOperator::CreateAnd(lok, rok, "bok", block);
- const auto ok = BinaryOperator::CreateAnd(sok, bok, "ok", block);
-
- const auto bads = BasicBlock::Create(context, "bads", ctx.Func);
- const auto infs = BasicBlock::Create(context, "infs", ctx.Func);
- const auto done = BasicBlock::Create(context, "done", ctx.Func);
- const auto result = PHINode::Create(sub->getType(), 3, "result", done);
- result->addIncoming(sub, block);
- BranchInst::Create(done, bads, ok, block);
-
- block = bads;
-
- const auto lnan = NDecimal::GenIsNonComparable(l, context, block);
- const auto rnan = NDecimal::GenIsNonComparable(r, context, block);
-
- const auto anan = BinaryOperator::CreateOr(lnan, rnan, "anan", block);
- const auto null = ConstantInt::get(sub->getType(), 0);
- const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, sub, null, "zero", block);
- const auto nan = BinaryOperator::CreateOr(anan, zero, "nan", block);
- result->addIncoming(GetDecimalNan(context), block);
- BranchInst::Create(done, infs, nan, block);
-
- block = infs;
-
- const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, sub, null, "plus", block);
- const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
- result->addIncoming(inf, block);
- BranchInst::Create(done, block);
-
- block = done;
- return SetterForInt128(result, block);
- }
-#endif
- static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto& bounds = NDecimal::GenBounds<Precision>(context);
+
+ const auto l = GetterForInt128(left, block);
+ const auto r = GetterForInt128(right, block);
+ const auto sub = BinaryOperator::CreateSub(l, r, "sub", block);
+
+ const auto lok = NDecimal::GenInBounds(l, bounds.first, bounds.second, block);
+ const auto rok = NDecimal::GenInBounds(r, bounds.first, bounds.second, block);
+ const auto sok = NDecimal::GenInBounds(sub, bounds.first, bounds.second, block);
+
+ const auto bok = BinaryOperator::CreateAnd(lok, rok, "bok", block);
+ const auto ok = BinaryOperator::CreateAnd(sok, bok, "ok", block);
+
+ const auto bads = BasicBlock::Create(context, "bads", ctx.Func);
+ const auto infs = BasicBlock::Create(context, "infs", ctx.Func);
+ const auto done = BasicBlock::Create(context, "done", ctx.Func);
+ const auto result = PHINode::Create(sub->getType(), 3, "result", done);
+ result->addIncoming(sub, block);
+ BranchInst::Create(done, bads, ok, block);
+
+ block = bads;
+
+ const auto lnan = NDecimal::GenIsNonComparable(l, context, block);
+ const auto rnan = NDecimal::GenIsNonComparable(r, context, block);
+
+ const auto anan = BinaryOperator::CreateOr(lnan, rnan, "anan", block);
+ const auto null = ConstantInt::get(sub->getType(), 0);
+ const auto zero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, sub, null, "zero", block);
+ const auto nan = BinaryOperator::CreateOr(anan, zero, "nan", block);
+ result->addIncoming(GetDecimalNan(context), block);
+ BranchInst::Create(done, infs, nan, block);
+
+ block = infs;
+
+ const auto plus = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, sub, null, "plus", block);
+ const auto inf = SelectInst::Create(plus, GetDecimalPlusInf(context), GetDecimalMinusInf(context), "inf", block);
+ result->addIncoming(inf, block);
+ BranchInst::Create(done, block);
+
+ block = done;
+ return SetterForInt128(result, block);
+ }
+#endif
+ static_assert(Precision <= NYql::NDecimal::MaxPrecision, "Too large precision!");
};
template<typename TLeft, typename TRight, typename TOutput>
struct TDiffDateTimeSub {
- static_assert(!std::is_same<TLeft, TRight>::value, "left and right must not be same");
- static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
-
+ static_assert(!std::is_same<TLeft, TRight>::value, "left and right must not be same");
+ static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
+
static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
const auto lv = static_cast<std::make_signed_t<TLeft>>(left.template Get<TLeft>());
const auto rv = static_cast<std::make_signed_t<TRight>>(right.template Get<TRight>());
- return NUdf::TUnboxedValuePod(ToScaledDate(lv) - ToScaledDate(rv));
+ return NUdf::TUnboxedValuePod(ToScaledDate(lv) - ToScaledDate(rv));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GenToScaledDate<std::make_signed_t<TLeft>>(GetterFor<TLeft>(left, context, block), context, block);
- const auto rhs = GenToScaledDate<std::make_signed_t<TRight>>(GetterFor<TRight>(right, context, block), context, block);
- const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
- const auto full = SetterFor<TOutput>(sub, context, block);
- return full;
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GenToScaledDate<std::make_signed_t<TLeft>>(GetterFor<TLeft>(left, context, block), context, block);
+ const auto rhs = GenToScaledDate<std::make_signed_t<TRight>>(GetterFor<TRight>(right, context, block), context, block);
+ const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
+ const auto full = SetterFor<TOutput>(sub, context, block);
+ return full;
}
#endif
};
template<typename TLeft, typename TRight, typename TOutput>
struct TSameDateTimeSub {
- static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
- static_assert(std::is_same<TLeft, TRight>::value, "left and right must be same");
- using TSignedArg = std::make_signed_t<TLeft>;
+ static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
+ static_assert(std::is_same<TLeft, TRight>::value, "left and right must be same");
+ using TSignedArg = std::make_signed_t<TLeft>;
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
- const auto lv = static_cast<TSignedArg>(left.template Get<TLeft>());
- const auto rv = static_cast<TSignedArg>(right.template Get<TRight>());
- return NUdf::TUnboxedValuePod(ToScaledDate<TSignedArg>(lv - rv));
+ const auto lv = static_cast<TSignedArg>(left.template Get<TLeft>());
+ const auto rv = static_cast<TSignedArg>(right.template Get<TRight>());
+ return NUdf::TUnboxedValuePod(ToScaledDate<TSignedArg>(lv - rv));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
- const auto full = SetterFor<TOutput>(GenToScaledDate<TSignedArg>(sub, context, block), context, block);
- return full;
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
+ const auto full = SetterFor<TOutput>(GenToScaledDate<TSignedArg>(sub, context, block), context, block);
+ return full;
}
#endif
};
template<typename TLeft, typename TRight, typename TOutput>
-struct TIntervalSubInterval {
- static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
- static_assert(std::is_same<TLeft, TRight>::value, "left and right must be same");
+struct TIntervalSubInterval {
+ static_assert(std::is_same<TOutput, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected output interval");
+ static_assert(std::is_same<TLeft, TRight>::value, "left and right must be same");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
- const auto lv = left.template Get<TLeft>();
- const auto rv = right.template Get<TRight>();
- const auto ret = lv - rv;
- return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));
+ const auto lv = left.template Get<TLeft>();
+ const auto rv = right.template Get<TRight>();
+ const auto ret = lv - rv;
+ return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));
}
#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
+ static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
{
- auto& context = ctx.Codegen->GetContext();
- const auto lhs = GetterFor<TLeft>(left, context, block);
- const auto rhs = GetterFor<TRight>(right, context, block);
- const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
- const auto full = SetterFor<TOutput>(sub, context, block);
- const auto bad = GenIsBadInterval(sub, context, block);
- const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
- const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
- return sel;
+ auto& context = ctx.Codegen->GetContext();
+ const auto lhs = GetterFor<TLeft>(left, context, block);
+ const auto rhs = GetterFor<TRight>(right, context, block);
+ const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
+ const auto full = SetterFor<TOutput>(sub, context, block);
+ const auto bad = GenIsBadInterval(sub, context, block);
+ const auto zero = ConstantInt::get(Type::getInt128Ty(context), 0);
+ const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
+ return sel;
}
#endif
};
-template<typename TLeft, typename TRight, typename TOutput, bool Tz>
-struct TAnyDateTimeSubIntervalT {
- static_assert(std::is_same<TRight, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected right interval");
- static_assert(std::is_same<TLeft, TOutput>::value, "left and output must be same");
+template<typename TLeft, typename TRight, typename TOutput, bool Tz>
+struct TAnyDateTimeSubIntervalT {
+ static_assert(std::is_same<TRight, NUdf::TDataType<NUdf::TInterval>::TLayout>::value, "expected right interval");
+ static_assert(std::is_same<TLeft, TOutput>::value, "left and output must be same");
- static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
+ static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right)
{
- const auto lv = ToScaledDate<TLeft>(left.template Get<TLeft>());
- const auto rv = ToScaledDate<TRight>(right.template Get<TRight>());
- const auto ret = lv - rv;
+ const auto lv = ToScaledDate<TLeft>(left.template Get<TLeft>());
+ const auto rv = ToScaledDate<TRight>(right.template Get<TRight>());
+ const auto ret = lv - rv;
if (IsBadDateTime(ret)) {
return NUdf::TUnboxedValuePod();
}
auto data = NUdf::TUnboxedValuePod(FromScaledDate<TOutput>(ret));
- if (Tz) {
- data.SetTimezoneId(left.GetTimezoneId());
- }
+ if (Tz) {
+ data.SetTimezoneId(left.GetTimezoneId());
+ }
return data;
}
@@ -200,32 +200,32 @@ struct TAnyDateTimeSubIntervalT {
const auto lhs = GenToScaledDate<TLeft>(GetterFor<TLeft>(left, context, block), context, block);
const auto rhs = GenToScaledDate<TRight>(GetterFor<TRight>(right, context, block), context, block);
const auto sub = BinaryOperator::CreateSub(lhs, rhs, "sub", block);
- const auto wide = SetterFor<TOutput>(GenFromScaledDate<TOutput>(sub, context, block), context, block);
+ const auto wide = SetterFor<TOutput>(GenFromScaledDate<TOutput>(sub, context, block), context, block);
const auto bad = GenIsBadDateTime(sub, context, block);
- const auto type = Type::getInt128Ty(context);
- const auto zero = ConstantInt::get(type, 0);
-
- if (Tz) {
- const uint64_t init[] = {0ULL, 0xFFFFULL};
- const auto mask = ConstantInt::get(type, APInt(128, 2, init));
- const auto tzid = BinaryOperator::CreateAnd(left, mask, "tzid", block);
- const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
- const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
- return sel;
- } else {
- const auto sel = SelectInst::Create(bad, zero, wide, "sel", block);
- return sel;
- }
+ const auto type = Type::getInt128Ty(context);
+ const auto zero = ConstantInt::get(type, 0);
+
+ if (Tz) {
+ const uint64_t init[] = {0ULL, 0xFFFFULL};
+ const auto mask = ConstantInt::get(type, APInt(128, 2, init));
+ const auto tzid = BinaryOperator::CreateAnd(left, mask, "tzid", block);
+ const auto full = BinaryOperator::CreateOr(wide, tzid, "full", block);
+ const auto sel = SelectInst::Create(bad, zero, full, "sel", block);
+ return sel;
+ } else {
+ const auto sel = SelectInst::Create(bad, zero, wide, "sel", block);
+ return sel;
+ }
}
#endif
};
-template<typename TLeft, typename TRight, typename TOutput>
-using TAnyDateTimeSubInterval = TAnyDateTimeSubIntervalT<TLeft, TRight, TOutput, false>;
-
-template<typename TLeft, typename TRight, typename TOutput>
-using TAnyDateTimeSubIntervalTz = TAnyDateTimeSubIntervalT<TLeft, TRight, TOutput, true>;
-
+template<typename TLeft, typename TRight, typename TOutput>
+using TAnyDateTimeSubInterval = TAnyDateTimeSubIntervalT<TLeft, TRight, TOutput, false>;
+
+template<typename TLeft, typename TRight, typename TOutput>
+using TAnyDateTimeSubIntervalTz = TAnyDateTimeSubIntervalT<TLeft, TRight, TOutput, true>;
+
}
template <bool LeftTz, bool RightTz>
@@ -262,7 +262,7 @@ void RegisterDateSub(IBuiltinFunctionRegistry& registry) {
void RegisterSub(IBuiltinFunctionRegistry& registry) {
RegisterBinaryNumericFunctionOpt<TSub, TBinaryArgsOpt>(registry, "Sub");
- NDecimal::RegisterBinaryFunctionForAllPrecisions<TDecimalSub, TBinaryArgsOpt>(registry, "Sub_");
+ NDecimal::RegisterBinaryFunctionForAllPrecisions<TDecimalSub, TBinaryArgsOpt>(registry, "Sub_");
RegisterDateSub<false, false>(registry);
RegisterDateSub<false, true>(registry);
@@ -271,13 +271,13 @@ void RegisterSub(IBuiltinFunctionRegistry& registry) {
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>,
NUdf::TDataType<NUdf::TInterval>, TIntervalSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
-
+
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TDate>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TDate>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
+ NUdf::TDataType<NUdf::TDate>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TDatetime>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TDatetime>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
+ NUdf::TDataType<NUdf::TDatetime>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TTimestamp>, NUdf::TDataType<NUdf::TInterval>,
- NUdf::TDataType<NUdf::TTimestamp>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
+ NUdf::TDataType<NUdf::TTimestamp>, TAnyDateTimeSubInterval, TBinaryArgsOptWithNullableResult>(registry, "Sub");
RegisterFunctionBinOpt<NUdf::TDataType<NUdf::TTzDate>, NUdf::TDataType<NUdf::TInterval>,
NUdf::TDataType<NUdf::TTzDate>, TAnyDateTimeSubIntervalTz, TBinaryArgsOptWithNullableResult>(registry, "Sub");
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_substring.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_substring.cpp
index eeca366baa..1a35ce31d3 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_substring.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_substring.cpp
@@ -6,74 +6,74 @@ namespace NMiniKQL {
namespace {
-template <bool StartOptional, bool CountOptional>
-struct TSubString {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod start, NUdf::TUnboxedValuePod count)
- {
- return SubString(string,
- StartOptional && !start ? std::numeric_limits<ui32>::min() : start.Get<ui32>(),
- CountOptional && !count ? std::numeric_limits<ui32>::max() : count.Get<ui32>()
- );
- }
+template <bool StartOptional, bool CountOptional>
+struct TSubString {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod start, NUdf::TUnboxedValuePod count)
+ {
+ return SubString(string,
+ StartOptional && !start ? std::numeric_limits<ui32>::min() : start.Get<ui32>(),
+ CountOptional && !count ? std::numeric_limits<ui32>::max() : count.Get<ui32>()
+ );
+ }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* string, Value* st, Value* cn, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(SubString));
- const auto start = StartOptional ?
- SelectInst::Create(
- IsEmpty(st, block),
- ConstantInt::get(GetTypeFor<ui32>(context), std::numeric_limits<ui32>::min()),
- GetterFor<ui32>(st, context, block), "start", block
- ):
- GetterFor<ui32>(st, context, block);
- const auto count = CountOptional ?
- SelectInst::Create(
- IsEmpty(cn, block),
- ConstantInt::get(GetTypeFor<ui32>(context), std::numeric_limits<ui32>::max()),
- GetterFor<ui32>(cn, context, block), "count", block
- ):
- GetterFor<ui32>(cn, context, block);
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(string->getType(), {string->getType(), start->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- const auto result = CallInst::Create(funcPtr, {string, start, count}, "substring", block);
- return result;
- } else {
- const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
- const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
- new StoreInst(string, ptrArg, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), start->getType(), count->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- CallInst::Create(funcPtr, {ptrResult, ptrArg, start, count}, "", block);
- const auto result = new LoadInst(ptrResult, "substring", block);
- return result;
- }
- }
-#endif
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* string, Value* st, Value* cn, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(SubString));
+ const auto start = StartOptional ?
+ SelectInst::Create(
+ IsEmpty(st, block),
+ ConstantInt::get(GetTypeFor<ui32>(context), std::numeric_limits<ui32>::min()),
+ GetterFor<ui32>(st, context, block), "start", block
+ ):
+ GetterFor<ui32>(st, context, block);
+ const auto count = CountOptional ?
+ SelectInst::Create(
+ IsEmpty(cn, block),
+ ConstantInt::get(GetTypeFor<ui32>(context), std::numeric_limits<ui32>::max()),
+ GetterFor<ui32>(cn, context, block), "count", block
+ ):
+ GetterFor<ui32>(cn, context, block);
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(string->getType(), {string->getType(), start->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ const auto result = CallInst::Create(funcPtr, {string, start, count}, "substring", block);
+ return result;
+ } else {
+ const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
+ const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
+ new StoreInst(string, ptrArg, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), start->getType(), count->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ CallInst::Create(funcPtr, {ptrResult, ptrArg, start, count}, "", block);
+ const auto result = new LoadInst(ptrResult, "substring", block);
+ return result;
+ }
+ }
+#endif
};
-template <typename TInput>
-void RegisterSubstringnOpt(IBuiltinFunctionRegistry& registry, const char* name) {
- RegisterFunctionImpl<TSubString<false, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, false, false>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TSubString<false, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, false, false>, TTernaryWrap<true>>(registry, name);
-
- RegisterFunctionImpl<TSubString<true, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, true, false>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TSubString<true, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, true, false>, TTernaryWrap<true>>(registry, name);
-
- RegisterFunctionImpl<TSubString<false, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, false, true>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TSubString<false, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, false, true>, TTernaryWrap<true>>(registry, name);
-
- RegisterFunctionImpl<TSubString<true, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, true, true>, TTernaryWrap<false>>(registry, name);
- RegisterFunctionImpl<TSubString<true, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, true, true>, TTernaryWrap<true>>(registry, name);
+template <typename TInput>
+void RegisterSubstringnOpt(IBuiltinFunctionRegistry& registry, const char* name) {
+ RegisterFunctionImpl<TSubString<false, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, false, false>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TSubString<false, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, false, false>, TTernaryWrap<true>>(registry, name);
+
+ RegisterFunctionImpl<TSubString<true, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, true, false>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TSubString<true, false>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, true, false>, TTernaryWrap<true>>(registry, name);
+
+ RegisterFunctionImpl<TSubString<false, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, false, true>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TSubString<false, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, false, true>, TTernaryWrap<true>>(registry, name);
+
+ RegisterFunctionImpl<TSubString<true, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, false, true, true>, TTernaryWrap<false>>(registry, name);
+ RegisterFunctionImpl<TSubString<true, true>, TTernaryArgs<TInput, TInput, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, true, true, true>, TTernaryWrap<true>>(registry, name);
+}
+
}
-}
-
-void RegisterSubstring(IBuiltinFunctionRegistry& registry) {
- RegisterSubstringnOpt<NUdf::TDataType<char*>>(registry, "Substring");
- RegisterSubstringnOpt<NUdf::TDataType<NUdf::TUtf8>>(registry, "Substring");
+void RegisterSubstring(IBuiltinFunctionRegistry& registry) {
+ RegisterSubstringnOpt<NUdf::TDataType<char*>>(registry, "Substring");
+ RegisterSubstringnOpt<NUdf::TDataType<NUdf::TUtf8>>(registry, "Substring");
}
} // namespace NMiniKQL
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_ut.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_ut.cpp
index cdf12db901..9420223b74 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_ut.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_ut.cpp
@@ -4,8 +4,8 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <array>
-
+#include <array>
+
namespace NKikimr {
namespace NMiniKQL {
@@ -16,36 +16,36 @@ static TFunctionParamMetadata AddUi32Metadata[] = {
{ 0, 0 }
};
-static NUdf::TUnboxedValuePod AddUi32(const NUdf::TUnboxedValuePod* args)
+static NUdf::TUnboxedValuePod AddUi32(const NUdf::TUnboxedValuePod* args)
{
const ui32 first = args[0].Get<ui32>();
const ui32 second = args[1].Get<ui32>();
- return NUdf::TUnboxedValuePod(first + second);
+ return NUdf::TUnboxedValuePod(first + second);
}
Y_UNIT_TEST_SUITE(TFunctionRegistryTest) {
Y_UNIT_TEST(TestRegistration) {
- const auto functionRegistry = CreateBuiltinRegistry();
- functionRegistry->Register("MyAdd", TFunctionDescriptor(AddUi32Metadata, &AddUi32));
-
- const std::array<TArgType, 3U> argTypes ={{{ NUdf::TDataType<ui32>::Id, false }, { NUdf::TDataType<ui32>::Id, false }, { NUdf::TDataType<ui32>::Id, false }}};
- auto op = functionRegistry->GetBuiltin("MyAdd", argTypes.data(), argTypes.size());
- UNIT_ASSERT_EQUAL(op.Function, &AddUi32);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].SchemeType, NUdf::TDataType<ui32>::Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].SchemeType, NUdf::TDataType<ui32>::Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].SchemeType, NUdf::TDataType<ui32>::Id);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].Flags, 0);
- UNIT_ASSERT_EQUAL(op.ResultAndArgs[3].SchemeType, 0);
-
- const NUdf::TUnboxedValuePod args[2] = {NUdf::TUnboxedValuePod(ui32(2)), NUdf::TUnboxedValuePod(ui32(3))};
-
- auto result = op.Function(&args[0]);
+ const auto functionRegistry = CreateBuiltinRegistry();
+ functionRegistry->Register("MyAdd", TFunctionDescriptor(AddUi32Metadata, &AddUi32));
+
+ const std::array<TArgType, 3U> argTypes ={{{ NUdf::TDataType<ui32>::Id, false }, { NUdf::TDataType<ui32>::Id, false }, { NUdf::TDataType<ui32>::Id, false }}};
+ auto op = functionRegistry->GetBuiltin("MyAdd", argTypes.data(), argTypes.size());
+ UNIT_ASSERT_EQUAL(op.Function, &AddUi32);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].SchemeType, NUdf::TDataType<ui32>::Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[0].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].SchemeType, NUdf::TDataType<ui32>::Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[1].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].SchemeType, NUdf::TDataType<ui32>::Id);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[2].Flags, 0);
+ UNIT_ASSERT_EQUAL(op.ResultAndArgs[3].SchemeType, 0);
+
+ const NUdf::TUnboxedValuePod args[2] = {NUdf::TUnboxedValuePod(ui32(2)), NUdf::TUnboxedValuePod(ui32(3))};
+
+ auto result = op.Function(&args[0]);
UNIT_ASSERT_EQUAL(result.Get<ui32>(), 5);
}
}
} // namespace NMiniKQL
-
+
} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_with.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_with.cpp
index 48d6a98c7e..c8cd4a51d8 100644
--- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_with.cpp
+++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_with.cpp
@@ -1,66 +1,66 @@
-#include "mkql_builtins_compare.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-namespace {
-
-template<bool Reverse>
-NUdf::TUnboxedValuePod StringWith(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part) {
- const std::string_view one = full.AsStringRef();
- const std::string_view two = part.AsStringRef();
- return NUdf::TUnboxedValuePod(Reverse ? one.ends_with(two) : one.starts_with(two));
-}
-
-NUdf::TUnboxedValuePod StringContains(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part) {
- const std::string_view one = full.AsStringRef();
- const std::string_view two = part.AsStringRef();
- return NUdf::TUnboxedValuePod(std::string_view::npos != one.find(two));
-}
-
-template <NUdf::TUnboxedValuePod (*StringFunc)(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part)>
-struct TStringWith {
- static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod sub)
- {
- return StringFunc(string, sub);
- }
-#ifndef MKQL_DISABLE_CODEGEN
- static Value* Generate(Value* string, Value* sub, const TCodegenContext& ctx, BasicBlock*& block)
- {
- auto& context = ctx.Codegen->GetContext();
- const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(StringFunc));
- if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
- const auto funType = FunctionType::get(string->getType(), {string->getType(), sub->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- const auto result = CallInst::Create(funcPtr, {string, sub}, "has", block);
- return result;
- } else {
- const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
- const auto ptrSub = new AllocaInst(sub->getType(), 0U, "sub", block);
- const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
- new StoreInst(string, ptrArg, block);
- new StoreInst(sub, ptrSub, block);
- const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), ptrSub->getType()}, false);
- const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
- CallInst::Create(funcPtr, {ptrResult, ptrArg, ptrSub}, "", block);
- const auto result = new LoadInst(ptrResult, "has", block);
- return result;
- }
- }
-#endif
-};
-
-template<NUdf::EDataSlot> using TStartsWith = TStringWith<&StringWith<false>>;
-template<NUdf::EDataSlot> using TEndsWith = TStringWith<&StringWith<true>>;
-template<NUdf::EDataSlot> using TContains = TStringWith<&StringContains>;
-
-}
-
-void RegisterWith(IBuiltinFunctionRegistry& registry) {
- RegisterCompareStrings<TStartsWith, TCompareArgsOpt, false>(registry, "StartsWith");
- RegisterCompareStrings<TEndsWith, TCompareArgsOpt, false>(registry, "EndsWith");
- RegisterCompareStrings<TContains, TCompareArgsOpt, false>(registry, "Contains");
-}
-
-} // namespace NMiniKQL
-} // namespace NKikimr
+#include "mkql_builtins_compare.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+namespace {
+
+template<bool Reverse>
+NUdf::TUnboxedValuePod StringWith(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part) {
+ const std::string_view one = full.AsStringRef();
+ const std::string_view two = part.AsStringRef();
+ return NUdf::TUnboxedValuePod(Reverse ? one.ends_with(two) : one.starts_with(two));
+}
+
+NUdf::TUnboxedValuePod StringContains(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part) {
+ const std::string_view one = full.AsStringRef();
+ const std::string_view two = part.AsStringRef();
+ return NUdf::TUnboxedValuePod(std::string_view::npos != one.find(two));
+}
+
+template <NUdf::TUnboxedValuePod (*StringFunc)(const NUdf::TUnboxedValuePod full, const NUdf::TUnboxedValuePod part)>
+struct TStringWith {
+ static NUdf::TUnboxedValuePod Execute(NUdf::TUnboxedValuePod string, NUdf::TUnboxedValuePod sub)
+ {
+ return StringFunc(string, sub);
+ }
+#ifndef MKQL_DISABLE_CODEGEN
+ static Value* Generate(Value* string, Value* sub, const TCodegenContext& ctx, BasicBlock*& block)
+ {
+ auto& context = ctx.Codegen->GetContext();
+ const auto doFunc = ConstantInt::get(Type::getInt64Ty(context), GetMethodPtr(StringFunc));
+ if (NYql::NCodegen::ETarget::Windows != ctx.Codegen->GetEffectiveTarget()) {
+ const auto funType = FunctionType::get(string->getType(), {string->getType(), sub->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ const auto result = CallInst::Create(funcPtr, {string, sub}, "has", block);
+ return result;
+ } else {
+ const auto ptrArg = new AllocaInst(string->getType(), 0U, "arg", block);
+ const auto ptrSub = new AllocaInst(sub->getType(), 0U, "sub", block);
+ const auto ptrResult = new AllocaInst(string->getType(), 0U, "result", block);
+ new StoreInst(string, ptrArg, block);
+ new StoreInst(sub, ptrSub, block);
+ const auto funType = FunctionType::get(Type::getVoidTy(context), {ptrResult->getType(), ptrArg->getType(), ptrSub->getType()}, false);
+ const auto funcPtr = CastInst::Create(Instruction::IntToPtr, doFunc, PointerType::getUnqual(funType), "func", block);
+ CallInst::Create(funcPtr, {ptrResult, ptrArg, ptrSub}, "", block);
+ const auto result = new LoadInst(ptrResult, "has", block);
+ return result;
+ }
+ }
+#endif
+};
+
+template<NUdf::EDataSlot> using TStartsWith = TStringWith<&StringWith<false>>;
+template<NUdf::EDataSlot> using TEndsWith = TStringWith<&StringWith<true>>;
+template<NUdf::EDataSlot> using TContains = TStringWith<&StringContains>;
+
+}
+
+void RegisterWith(IBuiltinFunctionRegistry& registry) {
+ RegisterCompareStrings<TStartsWith, TCompareArgsOpt, false>(registry, "StartsWith");
+ RegisterCompareStrings<TEndsWith, TCompareArgsOpt, false>(registry, "EndsWith");
+ RegisterCompareStrings<TContains, TCompareArgsOpt, false>(registry, "Contains");
+}
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/ydb/library/yql/minikql/invoke_builtins/ut/ya.make b/ydb/library/yql/minikql/invoke_builtins/ut/ya.make
index 21c292a4d9..ca5f9974c3 100644
--- a/ydb/library/yql/minikql/invoke_builtins/ut/ya.make
+++ b/ydb/library/yql/minikql/invoke_builtins/ut/ya.make
@@ -16,12 +16,12 @@ OWNER(
g:kikimr
)
-PEERDIR(
+PEERDIR(
ydb/library/yql/minikql
ydb/library/yql/public/udf
ydb/library/yql/public/udf/service/exception_policy
-)
-
+)
+
YQL_LAST_ABI_VERSION()
SRCS(
diff --git a/ydb/library/yql/minikql/invoke_builtins/ya.make b/ydb/library/yql/minikql/invoke_builtins/ya.make
index b505ab837c..8ccc53ba2d 100644
--- a/ydb/library/yql/minikql/invoke_builtins/ya.make
+++ b/ydb/library/yql/minikql/invoke_builtins/ya.make
@@ -17,19 +17,19 @@ SRCS(
mkql_builtins_bitor.cpp
mkql_builtins_bitxor.cpp
mkql_builtins_byteat.cpp
- mkql_builtins_codegen.cpp
+ mkql_builtins_codegen.cpp
mkql_builtins_concat.cpp
mkql_builtins_convert.cpp
mkql_builtins_countbits.cpp
- mkql_builtins_decimal.cpp
+ mkql_builtins_decimal.cpp
mkql_builtins_dec.cpp
mkql_builtins_div.cpp
- mkql_builtins_find.cpp
+ mkql_builtins_find.cpp
mkql_builtins_impl.h
mkql_builtins_inc.cpp
mkql_builtins_invprestr.cpp
- mkql_builtins_max.cpp
- mkql_builtins_min.cpp
+ mkql_builtins_max.cpp
+ mkql_builtins_min.cpp
mkql_builtins_minus.cpp
mkql_builtins_mod.cpp
mkql_builtins_mul.cpp
@@ -41,13 +41,13 @@ SRCS(
mkql_builtins_shiftright.cpp
mkql_builtins_sub.cpp
mkql_builtins_substring.cpp
- mkql_builtins_with.cpp
- mkql_builtins_equals.cpp
- mkql_builtins_not_equals.cpp
- mkql_builtins_less.cpp
- mkql_builtins_less_or_equal.cpp
- mkql_builtins_greater.cpp
- mkql_builtins_greater_or_equal.cpp
+ mkql_builtins_with.cpp
+ mkql_builtins_equals.cpp
+ mkql_builtins_not_equals.cpp
+ mkql_builtins_less.cpp
+ mkql_builtins_less_or_equal.cpp
+ mkql_builtins_greater.cpp
+ mkql_builtins_greater_or_equal.cpp
)
PEERDIR(
@@ -61,19 +61,19 @@ PEERDIR(
IF (NOT MKQL_DISABLE_CODEGEN)
PEERDIR(
ydb/library/yql/minikql/codegen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Transforms/IPO
)
ELSE()
CFLAGS(
-DMKQL_DISABLE_CODEGEN
)
-ENDIF()
-
+ENDIF()
+
YQL_LAST_ABI_VERSION()
END()
diff --git a/ydb/library/yql/minikql/mkql_alloc.cpp b/ydb/library/yql/minikql/mkql_alloc.cpp
index 98ef3675c7..9b77147a26 100644
--- a/ydb/library/yql/minikql/mkql_alloc.cpp
+++ b/ydb/library/yql/minikql/mkql_alloc.cpp
@@ -10,14 +10,14 @@ namespace NMiniKQL {
Y_POD_THREAD(TAllocState*) TlsAllocState;
TAllocPageHeader TAllocState::EmptyPageHeader = { 0, 0, 0, 0, 0, nullptr };
-
-void TAllocState::TListEntry::Link(TAllocState::TListEntry* root) noexcept {
+
+void TAllocState::TListEntry::Link(TAllocState::TListEntry* root) noexcept {
Left = root;
Right = root->Right;
Right->Left = Left->Right = this;
}
-void TAllocState::TListEntry::Unlink() noexcept {
+void TAllocState::TListEntry::Unlink() noexcept {
std::tie(Right->Left, Left->Right) = std::make_pair(Left, Right);
Left = Right = nullptr;
}
@@ -25,19 +25,19 @@ void TAllocState::TListEntry::Unlink() noexcept {
TAllocState::TAllocState(const NKikimr::TAlignedPagePoolCounters &counters, bool supportsSizedAllocators)
: TAlignedPagePool(counters)
, SupportsSizedAllocators(supportsSizedAllocators)
-{
- GetRoot()->InitLinks();
+{
+ GetRoot()->InitLinks();
OffloadedBlocksRoot.InitLinks();
-}
+}
-void TAllocState::KillAllBoxed() {
+void TAllocState::KillAllBoxed() {
{
const auto root = GetRoot();
for (auto next = root->GetRight(); next != root; next = root->GetLeft()) {
next->Ref();
next->~TBoxedValueLink();
}
- }
+ }
{
const auto root = &OffloadedBlocksRoot;
@@ -51,8 +51,8 @@ void TAllocState::KillAllBoxed() {
#ifndef NDEBUG
ActiveMemInfo.clear();
#endif
-}
-
+}
+
void TAllocState::InvalidateMemInfo() {
#ifndef NDEBUG
for (auto& pair : ActiveMemInfo) {
@@ -94,7 +94,7 @@ void* MKQLAllocSlow(size_t sz, TAllocState* state) {
return ret;
}
-void MKQLFreeSlow(TAllocPageHeader* header) noexcept {
+void MKQLFreeSlow(TAllocPageHeader* header) noexcept {
TAllocState *state = TlsAllocState;
Y_VERIFY_DEBUG(state);
state->ReturnBlock(header, header->Capacity);
@@ -116,7 +116,7 @@ void* TPagedArena::AllocSlow(size_t sz) {
return ret;
}
-void TPagedArena::Clear() noexcept {
+void TPagedArena::Clear() noexcept {
auto current = CurrentPage_;
while (current != &TAllocState::EmptyPageHeader) {
auto next = current->Link;
diff --git a/ydb/library/yql/minikql/mkql_alloc.h b/ydb/library/yql/minikql/mkql_alloc.h
index 85a75851c4..5e864cdc4c 100644
--- a/ydb/library/yql/minikql/mkql_alloc.h
+++ b/ydb/library/yql/minikql/mkql_alloc.h
@@ -7,7 +7,7 @@
#include <util/system/tls.h>
#include <util/system/align.h>
#include <new>
-#include <unordered_map>
+#include <unordered_map>
namespace NKikimr {
@@ -28,19 +28,19 @@ constexpr ui32 MaxPageUserData = TAlignedPagePool::POOL_PAGE_SIZE - sizeof(TAllo
static_assert(sizeof(TAllocPageHeader) % MKQL_ALIGNMENT == 0, "Incorrect size of header");
-struct TAllocState : public TAlignedPagePool
+struct TAllocState : public TAlignedPagePool
{
struct TListEntry {
TListEntry *Left = nullptr;
TListEntry *Right = nullptr;
- void Link(TListEntry* root) noexcept;
- void Unlink() noexcept;
- void InitLinks() noexcept { Left = Right = this; }
+ void Link(TListEntry* root) noexcept;
+ void Unlink() noexcept;
+ void InitLinks() noexcept { Left = Right = this; }
};
#ifndef NDEBUG
- std::unordered_map<TMemoryUsageInfo*, TIntrusivePtr<TMemoryUsageInfo>> ActiveMemInfo;
+ std::unordered_map<TMemoryUsageInfo*, TIntrusivePtr<TMemoryUsageInfo>> ActiveMemInfo;
#endif
bool SupportsSizedAllocators = false;
@@ -48,22 +48,22 @@ struct TAllocState : public TAlignedPagePool
return Alloc(size);
}
- void LargeFree(void* ptr, size_t size) noexcept {
+ void LargeFree(void* ptr, size_t size) noexcept {
Free(ptr, size);
}
static TAllocPageHeader EmptyPageHeader;
TAllocPageHeader* CurrentPage = &EmptyPageHeader;
TListEntry OffloadedBlocksRoot;
-
+
::NKikimr::NUdf::TBoxedValueLink Root;
-
- NKikimr::NUdf::TBoxedValueLink* GetRoot() noexcept {
+
+ NKikimr::NUdf::TBoxedValueLink* GetRoot() noexcept {
return &Root;
- }
-
+ }
+
explicit TAllocState(const TAlignedPagePoolCounters& counters, bool supportsSizedAllocators);
- void KillAllBoxed();
+ void KillAllBoxed();
void InvalidateMemInfo();
size_t GetDeallocatedInPages() const;
};
@@ -80,7 +80,7 @@ public:
~TScopedAlloc()
{
- MyState_.KillAllBoxed();
+ MyState_.KillAllBoxed();
Release();
}
@@ -195,13 +195,13 @@ private:
class TPagedArena {
public:
- TPagedArena(TAlignedPagePool* pagePool) noexcept
+ TPagedArena(TAlignedPagePool* pagePool) noexcept
: PagePool_(pagePool)
, CurrentPage_(&TAllocState::EmptyPageHeader)
{}
TPagedArena(const TPagedArena&) = delete;
- TPagedArena(TPagedArena&& other) noexcept
+ TPagedArena(TPagedArena&& other) noexcept
: PagePool_(other.PagePool_)
, CurrentPage_(other.CurrentPage_)
{
@@ -209,14 +209,14 @@ public:
}
void operator=(const TPagedArena&) = delete;
- void operator=(TPagedArena&& other) noexcept {
+ void operator=(TPagedArena&& other) noexcept {
Clear();
PagePool_ = other.PagePool_;
CurrentPage_ = other.CurrentPage_;
other.CurrentPage_ = &TAllocState::EmptyPageHeader;
}
- ~TPagedArena() noexcept {
+ ~TPagedArena() noexcept {
Clear();
}
@@ -230,7 +230,7 @@ public:
return AllocSlow(sz);
}
- void Clear() noexcept;
+ void Clear() noexcept;
private:
void* AllocSlow(size_t sz);
@@ -274,8 +274,8 @@ inline void* MKQLAllocFastWithSize(size_t sz, TAllocState* state) {
return MKQLAllocSlow(sz, state);
}
-void MKQLFreeSlow(TAllocPageHeader* header) noexcept;
-
+void MKQLFreeSlow(TAllocPageHeader* header) noexcept;
+
inline void MKQLFreeDeprecated(const void* p) noexcept {
if (!p) {
return;
@@ -289,7 +289,7 @@ inline void MKQLFreeDeprecated(const void* p) noexcept {
MKQLFreeSlow(header);
}
-inline void MKQLFreeFastWithSize(const void* mem, size_t sz, TAllocState* state) noexcept {
+inline void MKQLFreeFastWithSize(const void* mem, size_t sz, TAllocState* state) noexcept {
if (!mem) {
return;
}
@@ -320,18 +320,18 @@ inline void* MKQLAllocWithSize(size_t sz) {
return MKQLAllocFastWithSize(sz, TlsAllocState);
}
-inline void MKQLFreeWithSize(const void* mem, size_t sz) noexcept {
+inline void MKQLFreeWithSize(const void* mem, size_t sz) noexcept {
return MKQLFreeFastWithSize(mem, sz, TlsAllocState);
}
-inline void MKQLRegisterObject(NUdf::TBoxedValue* value) noexcept {
- return value->Link(TlsAllocState->GetRoot());
-}
-
-inline void MKQLUnregisterObject(NUdf::TBoxedValue* value) noexcept {
- return value->Unlink();
-}
-
+inline void MKQLRegisterObject(NUdf::TBoxedValue* value) noexcept {
+ return value->Link(TlsAllocState->GetRoot());
+}
+
+inline void MKQLUnregisterObject(NUdf::TBoxedValue* value) noexcept {
+ return value->Unlink();
+}
+
struct TWithMiniKQLAlloc {
void* operator new(size_t sz) {
return MKQLAllocWithSize(sz);
@@ -348,14 +348,14 @@ struct TWithMiniKQLAlloc {
void operator delete[](void *mem, std::size_t sz) noexcept {
MKQLFreeWithSize(mem, sz);
}
-};
+};
-template <typename T, typename... Args>
-T* AllocateOn(TAllocState* state, Args&&... args)
-{
+template <typename T, typename... Args>
+T* AllocateOn(TAllocState* state, Args&&... args)
+{
return ::new(MKQLAllocFastWithSize(sizeof(T), state)) T(std::forward<Args>(args)...);
- static_assert(std::is_base_of<TWithMiniKQLAlloc, T>::value, "Class must inherit TWithMiniKQLAlloc.");
-}
+ static_assert(std::is_base_of<TWithMiniKQLAlloc, T>::value, "Class must inherit TWithMiniKQLAlloc.");
+}
template <typename Type>
struct TMKQLAllocator
@@ -371,19 +371,19 @@ struct TMKQLAllocator
TMKQLAllocator() noexcept = default;
~TMKQLAllocator() noexcept = default;
- template<typename U> TMKQLAllocator(const TMKQLAllocator<U>&) noexcept {}
+ template<typename U> TMKQLAllocator(const TMKQLAllocator<U>&) noexcept {}
template<typename U> struct rebind { typedef TMKQLAllocator<U> other; };
- template<typename U> bool operator==(const TMKQLAllocator<U>&) const { return true; }
+ template<typename U> bool operator==(const TMKQLAllocator<U>&) const { return true; }
template<typename U> bool operator!=(const TMKQLAllocator<U>&) const { return false; }
static pointer allocate(size_type n, const void* = nullptr)
{
- return static_cast<pointer>(MKQLAllocWithSize(n * sizeof(value_type)));
+ return static_cast<pointer>(MKQLAllocWithSize(n * sizeof(value_type)));
}
- static void deallocate(const_pointer p, size_type n) noexcept
+ static void deallocate(const_pointer p, size_type n) noexcept
{
- return MKQLFreeWithSize(p, n * sizeof(value_type));
+ return MKQLFreeWithSize(p, n * sizeof(value_type));
}
};
@@ -444,12 +444,12 @@ public:
IndexInLastPage = OBJECTS_PER_PAGE;
}
- const T& operator[](size_t i) const {
- const auto table = i / OBJECTS_PER_PAGE;
- const auto index = i % OBJECTS_PER_PAGE;
- return *ObjectAt(Pages[table], index);
- }
-
+ const T& operator[](size_t i) const {
+ const auto table = i / OBJECTS_PER_PAGE;
+ const auto index = i % OBJECTS_PER_PAGE;
+ return *ObjectAt(Pages[table], index);
+ }
+
size_t Size() const {
return Pages.empty() ? 0 : ((Pages.size() - 1) * OBJECTS_PER_PAGE + IndexInLastPage);
}
@@ -595,21 +595,21 @@ public:
};
private:
- static const T* ObjectAt(const void* page, size_t objectIndex) {
- return reinterpret_cast<const T*>(static_cast<const char*>(page) + objectIndex * sizeof(T));
- }
-
- static T* ObjectAt(void* page, size_t objectIndex) {
- return reinterpret_cast<T*>(static_cast<char*>(page) + objectIndex * sizeof(T));
- }
-
+ static const T* ObjectAt(const void* page, size_t objectIndex) {
+ return reinterpret_cast<const T*>(static_cast<const char*>(page) + objectIndex * sizeof(T));
+ }
+
+ static T* ObjectAt(void* page, size_t objectIndex) {
+ return reinterpret_cast<T*>(static_cast<char*>(page) + objectIndex * sizeof(T));
+ }
+
TAlignedPagePool& Pool;
- using TPages = std::vector<void*, TMKQLAllocator<void*>>;
+ using TPages = std::vector<void*, TMKQLAllocator<void*>>;
TPages Pages;
size_t IndexInLastPage;
};
-
+
} // NMiniKQL
} // NKikimr
diff --git a/ydb/library/yql/minikql/mkql_function_metadata.h b/ydb/library/yql/minikql/mkql_function_metadata.h
index 70a66e6064..f52e62d64e 100644
--- a/ydb/library/yql/minikql/mkql_function_metadata.h
+++ b/ydb/library/yql/minikql/mkql_function_metadata.h
@@ -1,71 +1,71 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_value.h>
-
-namespace NKikimr {
-
-namespace NMiniKQL {
-
-using TFunctionPtr = NUdf::TUnboxedValuePod (*)(const NUdf::TUnboxedValuePod* args);
-
-struct TFunctionParamMetadata {
- enum EFlags : ui16 {
- FlagIsNullable = 0x01,
- };
-
- TFunctionParamMetadata() = default;
-
- TFunctionParamMetadata(NUdf::TDataTypeId schemeType, ui32 flags)
- : SchemeType(schemeType)
- , Flags(flags)
- {}
-
- bool IsNullable() const {
- return Flags & FlagIsNullable;
- }
-
- NUdf::TDataTypeId SchemeType = 0;
- ui16 Flags = 0;
-};
-
-struct TFunctionDescriptor {
- TFunctionDescriptor() = default;
-
- TFunctionDescriptor(const TFunctionParamMetadata* resultAndArgs, TFunctionPtr function, void* generator = nullptr)
- : ResultAndArgs(resultAndArgs)
- , Function(function)
- , Generator(generator)
- {}
-
- const TFunctionParamMetadata* ResultAndArgs = nullptr; // ends with SchemeType zero
- TFunctionPtr Function = nullptr;
- void *Generator = nullptr;
-};
-
-using TFunctionParamMetadataList = std::vector<TFunctionParamMetadata>;
-using TArgType = std::pair<NUdf::TDataTypeId, bool>; // type with optional flag
-using TDescriptionList = std::vector<TFunctionDescriptor>;
-using TFunctionsMap = std::unordered_map<TString, TDescriptionList>;
-
-class IBuiltinFunctionRegistry: public TThrRefBase, private TNonCopyable
-{
-public:
- typedef TIntrusivePtr<IBuiltinFunctionRegistry> TPtr;
-
- virtual ui64 GetMetadataEtag() const = 0;
-
- virtual void PrintInfoTo(IOutputStream& out) const = 0;
-
- virtual void Register(const std::string_view& name, const TFunctionDescriptor& description) = 0;
-
- virtual bool HasBuiltin(const std::string_view& name) const = 0;
-
- virtual void RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments) = 0;
-
- virtual const TFunctionsMap& GetFunctions() const = 0;
-
- virtual TFunctionDescriptor GetBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const = 0;
-};
-
-}
-}
+
+namespace NKikimr {
+
+namespace NMiniKQL {
+
+using TFunctionPtr = NUdf::TUnboxedValuePod (*)(const NUdf::TUnboxedValuePod* args);
+
+struct TFunctionParamMetadata {
+ enum EFlags : ui16 {
+ FlagIsNullable = 0x01,
+ };
+
+ TFunctionParamMetadata() = default;
+
+ TFunctionParamMetadata(NUdf::TDataTypeId schemeType, ui32 flags)
+ : SchemeType(schemeType)
+ , Flags(flags)
+ {}
+
+ bool IsNullable() const {
+ return Flags & FlagIsNullable;
+ }
+
+ NUdf::TDataTypeId SchemeType = 0;
+ ui16 Flags = 0;
+};
+
+struct TFunctionDescriptor {
+ TFunctionDescriptor() = default;
+
+ TFunctionDescriptor(const TFunctionParamMetadata* resultAndArgs, TFunctionPtr function, void* generator = nullptr)
+ : ResultAndArgs(resultAndArgs)
+ , Function(function)
+ , Generator(generator)
+ {}
+
+ const TFunctionParamMetadata* ResultAndArgs = nullptr; // ends with SchemeType zero
+ TFunctionPtr Function = nullptr;
+ void *Generator = nullptr;
+};
+
+using TFunctionParamMetadataList = std::vector<TFunctionParamMetadata>;
+using TArgType = std::pair<NUdf::TDataTypeId, bool>; // type with optional flag
+using TDescriptionList = std::vector<TFunctionDescriptor>;
+using TFunctionsMap = std::unordered_map<TString, TDescriptionList>;
+
+class IBuiltinFunctionRegistry: public TThrRefBase, private TNonCopyable
+{
+public:
+ typedef TIntrusivePtr<IBuiltinFunctionRegistry> TPtr;
+
+ virtual ui64 GetMetadataEtag() const = 0;
+
+ virtual void PrintInfoTo(IOutputStream& out) const = 0;
+
+ virtual void Register(const std::string_view& name, const TFunctionDescriptor& description) = 0;
+
+ virtual bool HasBuiltin(const std::string_view& name) const = 0;
+
+ virtual void RegisterAll(TFunctionsMap&& functions, TFunctionParamMetadataList&& arguments) = 0;
+
+ virtual const TFunctionsMap& GetFunctions() const = 0;
+
+ virtual TFunctionDescriptor GetBuiltin(const std::string_view& name, const std::pair<NUdf::TDataTypeId, bool>* argTypes, size_t argTypesCount) const = 0;
+};
+
+}
+}
diff --git a/ydb/library/yql/minikql/mkql_function_registry.cpp b/ydb/library/yql/minikql/mkql_function_registry.cpp
index 2b59f08a9d..d3545ad138 100644
--- a/ydb/library/yql/minikql/mkql_function_registry.cpp
+++ b/ydb/library/yql/minikql/mkql_function_registry.cpp
@@ -100,7 +100,7 @@ class TMutableFunctionRegistry: public IMutableFunctionRegistry
public:
TMutableFunctionRegistry(IBuiltinFunctionRegistry::TPtr builtins)
- : Builtins_(std::move(builtins))
+ : Builtins_(std::move(builtins))
{
}
@@ -150,7 +150,7 @@ public:
ui32 version = abiVersionFunc();
Y_ENSURE(NUdf::IsAbiCompatible(version),
"Non compatible ABI version of UDF library " << libraryPath
- << ", expected up to " << NUdf::AbiVersionToStr(NUdf::CurrentCompatibilityAbiVersion() * 100)
+ << ", expected up to " << NUdf::AbiVersionToStr(NUdf::CurrentCompatibilityAbiVersion() * 100)
<< ", got " << NUdf::AbiVersionToStr(version)
<< "; try to re-compile library using "
<< "YQL_ABI_VERSION(" << UDF_ABI_VERSION_MAJOR
@@ -160,9 +160,9 @@ public:
SupportsSizedAllocators_ = false;
}
-#if defined(_win_) || defined(_darwin_)
- auto bindSymbolsFunc = reinterpret_cast<NUdf::TBindSymbolsFunctionPtr>(lib->Lib.Sym(BindSymbolsFuncName));
- bindSymbolsFunc(NUdf::GetStaticSymbols());
+#if defined(_win_) || defined(_darwin_)
+ auto bindSymbolsFunc = reinterpret_cast<NUdf::TBindSymbolsFunctionPtr>(lib->Lib.Sym(BindSymbolsFuncName));
+ bindSymbolsFunc(NUdf::GetStaticSymbols());
#endif
if (BackTraceCallback_) {
@@ -201,7 +201,7 @@ public:
TUdfModuleLoader loader(
UdfModules_, libraryPathStr,
remappings, NUdf::CurrentAbiVersion());
- loader.AddModule(moduleName, std::move(module));
+ loader.AddModule(moduleName, std::move(module));
Y_ENSURE(!loader.HasError(), loader.GetError());
}
@@ -210,8 +210,8 @@ public:
SystemModulePaths_ = paths;
}
- const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const override {
- return Builtins_;
+ const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const override {
+ return Builtins_;
}
TStatus FindFunctionTypeInfo(
@@ -296,42 +296,42 @@ public:
THashSet<TString> GetAllModuleNames() const override {
THashSet<TString> names;
- names.reserve(UdfModules_.size());
+ names.reserve(UdfModules_.size());
for (const auto& module: UdfModules_) {
names.insert(module.first);
}
return names;
}
- TFunctionsMap GetModuleFunctions(const TStringBuf& moduleName) const override {
+ TFunctionsMap GetModuleFunctions(const TStringBuf& moduleName) const override {
struct TFunctionNamesSink: public NUdf::IFunctionNamesSink {
- TFunctionsMap Functions;
- class TFuncDescriptor : public NUdf::IFunctionDescriptor {
- public:
- TFuncDescriptor(TFunctionProperties& properties)
- : Properties(properties)
- {}
-
- private:
- void SetTypeAwareness() final {
- Properties.IsTypeAwareness = true;
- }
-
- TFunctionProperties& Properties;
- };
-
- NUdf::IFunctionDescriptor::TPtr Add(const NUdf::TStringRef& name) final {
- const auto it = Functions.emplace(name, TFunctionProperties{});
- return new TFuncDescriptor(it.first->second);
+ TFunctionsMap Functions;
+ class TFuncDescriptor : public NUdf::IFunctionDescriptor {
+ public:
+ TFuncDescriptor(TFunctionProperties& properties)
+ : Properties(properties)
+ {}
+
+ private:
+ void SetTypeAwareness() final {
+ Properties.IsTypeAwareness = true;
+ }
+
+ TFunctionProperties& Properties;
+ };
+
+ NUdf::IFunctionDescriptor::TPtr Add(const NUdf::TStringRef& name) final {
+ const auto it = Functions.emplace(name, TFunctionProperties{});
+ return new TFuncDescriptor(it.first->second);
}
} sink;
- const auto it = UdfModules_.find(moduleName);
- if (UdfModules_.cend() == it)
- return TFunctionsMap();
- it->second.Impl->GetAllFunctions(sink);
- return sink.Functions;
+ const auto it = UdfModules_.find(moduleName);
+ if (UdfModules_.cend() == it)
+ return TFunctionsMap();
+ it->second.Impl->GetAllFunctions(sink);
+ return sink.Functions;
}
bool SupportsSizedAllocators() const override {
@@ -357,7 +357,7 @@ public:
}
private:
- const IBuiltinFunctionRegistry::TPtr Builtins_;
+ const IBuiltinFunctionRegistry::TPtr Builtins_;
THashMap<TString, TUdfLibraryPtr> LoadedLibraries_;
TUdfModulesMap UdfModules_;
@@ -373,13 +373,13 @@ private:
class TBuiltinsWrapper: public IFunctionRegistry
{
public:
- TBuiltinsWrapper(IBuiltinFunctionRegistry::TPtr&& builtins)
- : Builtins_(std::move(builtins))
+ TBuiltinsWrapper(IBuiltinFunctionRegistry::TPtr&& builtins)
+ : Builtins_(std::move(builtins))
{
}
- const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const override {
- return Builtins_;
+ const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const override {
+ return Builtins_;
}
void AllowUdfPatch() override {
@@ -424,8 +424,8 @@ public:
return {};
}
- TFunctionsMap GetModuleFunctions(const TStringBuf&) const override {
- return TFunctionsMap();
+ TFunctionsMap GetModuleFunctions(const TStringBuf&) const override {
+ return TFunctionsMap();
}
bool SupportsSizedAllocators() const override {
@@ -444,7 +444,7 @@ public:
}
private:
- const IBuiltinFunctionRegistry::TPtr Builtins_;
+ const IBuiltinFunctionRegistry::TPtr Builtins_;
};
} // namespace
@@ -508,7 +508,7 @@ TString FullName(const TStringBuf& module, const TStringBuf& func)
return fullName;
}
-TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr&& builtins)
+TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr&& builtins)
{
return new TBuiltinsWrapper(std::move(builtins));
}
@@ -520,7 +520,7 @@ TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(
const TVector<TString>& udfsPaths,
ui32 flags /* = 0 */)
{
- auto registry = MakeHolder<TMutableFunctionRegistry>(std::move(builtins));
+ auto registry = MakeHolder<TMutableFunctionRegistry>(std::move(builtins));
if (allowUdfPatch) {
registry->AllowUdfPatch();
}
diff --git a/ydb/library/yql/minikql/mkql_function_registry.h b/ydb/library/yql/minikql/mkql_function_registry.h
index 6d67f1fae0..f18152cb24 100644
--- a/ydb/library/yql/minikql/mkql_function_registry.h
+++ b/ydb/library/yql/minikql/mkql_function_registry.h
@@ -1,7 +1,7 @@
#pragma once
-#include "mkql_function_metadata.h"
-
+#include "mkql_function_metadata.h"
+
#include <ydb/library/yql/public/udf/udf_counter.h>
#include <ydb/library/yql/public/udf/udf_registrator.h>
#include <ydb/library/yql/public/udf/udf_type_builder.h>
@@ -11,7 +11,7 @@
#include <util/generic/maybe.h>
#include <util/generic/hash.h>
#include <util/generic/hash_set.h>
-#include <map>
+#include <map>
#ifdef _win_
# define MKQL_UDF_LIB_PREFIX ""
@@ -51,11 +51,11 @@ using TUdfModulePathsMap = THashMap<TString, TString>; // module name => udf pat
class IFunctionRegistry: public TThrRefBase
{
public:
- typedef TIntrusivePtr<IFunctionRegistry> TPtr;
-
+ typedef TIntrusivePtr<IFunctionRegistry> TPtr;
+
virtual ~IFunctionRegistry() = default;
- virtual const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const = 0;
+ virtual const IBuiltinFunctionRegistry::TPtr& GetBuiltins() const = 0;
virtual void AllowUdfPatch() = 0;
@@ -82,12 +82,12 @@ public:
virtual void CleanupModulesOnTerminate() const = 0;
virtual TIntrusivePtr<IMutableFunctionRegistry> Clone() const = 0;
-
- struct TFunctionProperties { bool IsTypeAwareness = false; };
-
- typedef std::map<TString, TFunctionProperties> TFunctionsMap;
-
- virtual TFunctionsMap GetModuleFunctions(const TStringBuf& moduleName) const = 0;
+
+ struct TFunctionProperties { bool IsTypeAwareness = false; };
+
+ typedef std::map<TString, TFunctionProperties> TFunctionsMap;
+
+ virtual TFunctionsMap GetModuleFunctions(const TStringBuf& moduleName) const = 0;
virtual bool SupportsSizedAllocators() const = 0;
};
@@ -116,11 +116,11 @@ public:
//////////////////////////////////////////////////////////////////////////////
// factories
//////////////////////////////////////////////////////////////////////////////
-TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr&& builtins);
+TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr&& builtins);
TIntrusivePtr<IFunctionRegistry> CreateFunctionRegistry(
NKikimr::NUdf::TBackTraceCallback backtraceCallback,
- IBuiltinFunctionRegistry::TPtr&& builtins,
+ IBuiltinFunctionRegistry::TPtr&& builtins,
bool allowUdfPatch,
const TVector<TString>& udfsPaths,
ui32 flags = 0); // see NUdf::IRegistrator::TFlags
diff --git a/ydb/library/yql/minikql/mkql_mem_info.h b/ydb/library/yql/minikql/mkql_mem_info.h
index 713b725740..8e880d1db3 100644
--- a/ydb/library/yql/minikql/mkql_mem_info.h
+++ b/ydb/library/yql/minikql/mkql_mem_info.h
@@ -2,7 +2,7 @@
#include <util/stream/output.h>
#include <util/string/builder.h>
-#include <unordered_map>
+#include <unordered_map>
#ifndef NDEBUG
# define MKQL_MEM_TAKE3(MemInfo, Mem, Size) \
@@ -64,7 +64,7 @@ public:
}
#ifndef NDEBUG
- inline void Take(const void* mem, ui64 size, TString location) {
+ inline void Take(const void* mem, ui64 size, TString location) {
Allocated_ += size;
Peak_ = Max(Peak_, Allocated_ - Freed_);
if (size == 0) {
@@ -84,7 +84,7 @@ public:
#endif
#ifndef NDEBUG
- inline void Return(const void* mem, ui64 size) {
+ inline void Return(const void* mem, ui64 size) {
Freed_ += size;
if (size == 0) {
return;
@@ -113,7 +113,7 @@ public:
#endif
#ifndef NDEBUG
- inline void Return(const void* mem) {
+ inline void Return(const void* mem) {
//Clog << Title_ << " free: " << size << " -> " << mem << " " << AllocationsMap_.size() << Endl;
auto it = AllocationsMap_.find(mem);
if (AllowMissing_ && it == AllocationsMap_.end()) {
@@ -153,24 +153,24 @@ public:
inline void VerifyDebug() const {
#ifndef NDEBUG
- size_t leakCount = 0;
- for (const auto& it: AllocationsMap_) {
- if (it.second.IsDeleted) {
- continue;
+ size_t leakCount = 0;
+ for (const auto& it: AllocationsMap_) {
+ if (it.second.IsDeleted) {
+ continue;
}
- ++leakCount;
+ ++leakCount;
Cerr << TStringBuf("Not freed ")
<< it.first << TStringBuf(" size: ") << it.second.Size
<< TStringBuf(", location: ") << it.second.Location
- << Endl;
- }
+ << Endl;
+ }
- if (!AllowMissing_) {
- Y_VERIFY_DEBUG(GetUsage() == 0,
- "Allocated: %ld, Freed: %ld, Peak: %ld",
- GetAllocated(), GetFreed(), GetPeak());
+ if (!AllowMissing_) {
+ Y_VERIFY_DEBUG(GetUsage() == 0,
+ "Allocated: %ld, Freed: %ld, Peak: %ld",
+ GetAllocated(), GetFreed(), GetPeak());
}
- Y_VERIFY_DEBUG(!leakCount, "Has no freed memory");
+ Y_VERIFY_DEBUG(!leakCount, "Has no freed memory");
#endif
}
@@ -183,37 +183,37 @@ private:
bool CheckOnExit_;
#ifndef NDEBUG
- std::unordered_map<const void*, TAllocationInfo> AllocationsMap_;
+ std::unordered_map<const void*, TAllocationInfo> AllocationsMap_;
#endif
};
#ifndef NDEBUG
-inline void Take(TMemoryUsageInfo& memInfo, const void* mem, ui64 size, TString location)
+inline void Take(TMemoryUsageInfo& memInfo, const void* mem, ui64 size, TString location)
{
memInfo.Take(mem, size, std::move(location));
}
-inline void Take(TMemoryUsageInfo* memInfo, const void* mem, ui64 size, TString location)
+inline void Take(TMemoryUsageInfo* memInfo, const void* mem, ui64 size, TString location)
{
memInfo->Take(mem, size, std::move(location));
}
-inline void Return(TMemoryUsageInfo& memInfo, const void* mem, ui64 size)
+inline void Return(TMemoryUsageInfo& memInfo, const void* mem, ui64 size)
{
memInfo.Return(mem, size);
}
-inline void Return(TMemoryUsageInfo* memInfo, const void* mem, ui64 size)
+inline void Return(TMemoryUsageInfo* memInfo, const void* mem, ui64 size)
{
memInfo->Return(mem, size);
}
-inline void Return(TMemoryUsageInfo& memInfo, const void* mem)
+inline void Return(TMemoryUsageInfo& memInfo, const void* mem)
{
memInfo.Return(mem);
}
-inline void Return(TMemoryUsageInfo* memInfo, const void* mem)
+inline void Return(TMemoryUsageInfo* memInfo, const void* mem)
{
memInfo->Return(mem);
}
diff --git a/ydb/library/yql/minikql/mkql_node.cpp b/ydb/library/yql/minikql/mkql_node.cpp
index 769f51c2f6..4c6f3e45ad 100644
--- a/ydb/library/yql/minikql/mkql_node.cpp
+++ b/ydb/library/yql/minikql/mkql_node.cpp
@@ -17,7 +17,7 @@ using namespace NDetail;
TTypeEnvironment::TTypeEnvironment(TScopedAlloc& alloc)
: Alloc(alloc)
- , Arena(&Alloc.Ref())
+ , Arena(&Alloc.Ref())
, EmptyStruct(nullptr)
, EmptyTuple(nullptr)
{
@@ -203,8 +203,8 @@ TStringBuf TType::GetKindAsStr() const {
xx(Any, TAnyType) \
xx(Tuple, TTupleType) \
xx(Resource, TResourceType) \
- xx(Variant, TVariantType) \
- xx(Flow, TFlowType) \
+ xx(Variant, TVariantType) \
+ xx(Flow, TFlowType) \
xx(Null, TNullType) \
xx(EmptyList, TEmptyListType) \
xx(EmptyDict, TEmptyDictType) \
@@ -354,17 +354,17 @@ TDataType::TDataType(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env)
}
TDataType* TDataType::Create(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env) {
- MKQL_ENSURE(schemeType, "Null type isn't allowed.");
- MKQL_ENSURE(schemeType != NUdf::TDataType<NUdf::TDecimal>::Id, "Can't' create Decimal.");
+ MKQL_ENSURE(schemeType, "Null type isn't allowed.");
+ MKQL_ENSURE(schemeType != NUdf::TDataType<NUdf::TDecimal>::Id, "Can't' create Decimal.");
return ::new(env.Allocate<TDataType>()) TDataType(schemeType, env);
}
bool TDataType::IsSameType(const TDataType& typeToCompare) const {
- if (SchemeType != typeToCompare.SchemeType)
- return false;
- if (SchemeType != NUdf::TDataType<NUdf::TDecimal>::Id)
- return true;
- return static_cast<const TDataDecimalType&>(*this).IsSameType(static_cast<const TDataDecimalType&>(typeToCompare));
+ if (SchemeType != typeToCompare.SchemeType)
+ return false;
+ if (SchemeType != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return true;
+ return static_cast<const TDataDecimalType&>(*this).IsSameType(static_cast<const TDataDecimalType&>(typeToCompare));
}
bool TDataType::IsConvertableTo(const TDataType& typeToCompare, bool ignoreTagged) const {
@@ -385,38 +385,38 @@ void TDataType::DoFreeze(const TTypeEnvironment& env) {
Y_UNUSED(env);
}
-TDataDecimalType::TDataDecimalType(ui8 precision, ui8 scale, const TTypeEnvironment& env)
- : TDataType(NUdf::TDataType<NUdf::TDecimal>::Id, env), Precision(precision), Scale(scale)
-{
- MKQL_ENSURE(Precision > 0, "Precision must be positive.");
- MKQL_ENSURE(Scale <= Precision, "Scale too large.");
-}
-
-TDataDecimalType* TDataDecimalType::Create(ui8 precision, ui8 scale, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TDataDecimalType>()) TDataDecimalType(precision, scale, env);
-}
-
-bool TDataDecimalType::IsSameType(const TDataDecimalType& typeToCompare) const {
- return Precision == typeToCompare.Precision && Scale == typeToCompare.Scale;
-}
-
+TDataDecimalType::TDataDecimalType(ui8 precision, ui8 scale, const TTypeEnvironment& env)
+ : TDataType(NUdf::TDataType<NUdf::TDecimal>::Id, env), Precision(precision), Scale(scale)
+{
+ MKQL_ENSURE(Precision > 0, "Precision must be positive.");
+ MKQL_ENSURE(Scale <= Precision, "Scale too large.");
+}
+
+TDataDecimalType* TDataDecimalType::Create(ui8 precision, ui8 scale, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TDataDecimalType>()) TDataDecimalType(precision, scale, env);
+}
+
+bool TDataDecimalType::IsSameType(const TDataDecimalType& typeToCompare) const {
+ return Precision == typeToCompare.Precision && Scale == typeToCompare.Scale;
+}
+
bool TDataDecimalType::IsConvertableTo(const TDataDecimalType& typeToCompare, bool ignoreTagged) const {
Y_UNUSED(ignoreTagged);
- return Precision == typeToCompare.Precision && Scale == typeToCompare.Scale;
-}
-
-std::pair<ui8, ui8> TDataDecimalType::GetParams() const {
- return std::make_pair(Precision, Scale);
-}
-
-TDataLiteral::TDataLiteral(const TUnboxedValuePod& value, TDataType* type)
- : TNode(type), TUnboxedValuePod(value)
-{}
-
-TDataLiteral* TDataLiteral::Create(const NUdf::TUnboxedValuePod& value, TDataType* type, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TDataLiteral>()) TDataLiteral(value, type);
-}
-
+ return Precision == typeToCompare.Precision && Scale == typeToCompare.Scale;
+}
+
+std::pair<ui8, ui8> TDataDecimalType::GetParams() const {
+ return std::make_pair(Precision, Scale);
+}
+
+TDataLiteral::TDataLiteral(const TUnboxedValuePod& value, TDataType* type)
+ : TNode(type), TUnboxedValuePod(value)
+{}
+
+TDataLiteral* TDataLiteral::Create(const NUdf::TUnboxedValuePod& value, TDataType* type, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TDataLiteral>()) TDataLiteral(value, type);
+}
+
void TDataLiteral::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
auto typeIt = links.find(Type);
if (typeIt != links.end()) {
@@ -436,30 +436,30 @@ void TDataLiteral::DoFreeze(const TTypeEnvironment& env) {
}
bool TDataLiteral::Equals(const TDataLiteral& nodeToCompare) const {
- const auto& self = AsValue();
- const auto& that = nodeToCompare.AsValue();
- switch (GetType()->GetSchemeType()) {
- case NUdf::TDataType<bool>::Id: return self.Get<bool>() == that.Get<bool>();
- case NUdf::TDataType<ui8>::Id: return self.Get<ui8>() == that.Get<ui8>();
+ const auto& self = AsValue();
+ const auto& that = nodeToCompare.AsValue();
+ switch (GetType()->GetSchemeType()) {
+ case NUdf::TDataType<bool>::Id: return self.Get<bool>() == that.Get<bool>();
+ case NUdf::TDataType<ui8>::Id: return self.Get<ui8>() == that.Get<ui8>();
case NUdf::TDataType<i8>::Id: return self.Get<i8>() == that.Get<i8>();
case NUdf::TDataType<NUdf::TDate>::Id:
case NUdf::TDataType<ui16>::Id: return self.Get<ui16>() == that.Get<ui16>();
case NUdf::TDataType<i16>::Id: return self.Get<i16>() == that.Get<i16>();
- case NUdf::TDataType<i32>::Id: return self.Get<i32>() == that.Get<i32>();
+ case NUdf::TDataType<i32>::Id: return self.Get<i32>() == that.Get<i32>();
case NUdf::TDataType<NUdf::TDatetime>::Id:
- case NUdf::TDataType<ui32>::Id: return self.Get<ui32>() == that.Get<ui32>();
+ case NUdf::TDataType<ui32>::Id: return self.Get<ui32>() == that.Get<ui32>();
case NUdf::TDataType<NUdf::TInterval>::Id:
- case NUdf::TDataType<i64>::Id: return self.Get<i64>() == that.Get<i64>();
+ case NUdf::TDataType<i64>::Id: return self.Get<i64>() == that.Get<i64>();
case NUdf::TDataType<NUdf::TTimestamp>::Id:
- case NUdf::TDataType<ui64>::Id: return self.Get<ui64>() == that.Get<ui64>();
- case NUdf::TDataType<float>::Id: return self.Get<float>() == that.Get<float>();
- case NUdf::TDataType<double>::Id: return self.Get<double>() == that.Get<double>();
+ case NUdf::TDataType<ui64>::Id: return self.Get<ui64>() == that.Get<ui64>();
+ case NUdf::TDataType<float>::Id: return self.Get<float>() == that.Get<float>();
+ case NUdf::TDataType<double>::Id: return self.Get<double>() == that.Get<double>();
case NUdf::TDataType<NUdf::TTzDate>::Id: return self.Get<ui16>() == that.Get<ui16>() && self.GetTimezoneId() == that.GetTimezoneId();
case NUdf::TDataType<NUdf::TTzDatetime>::Id: return self.Get<ui32>() == that.Get<ui32>() && self.GetTimezoneId() == that.GetTimezoneId();
case NUdf::TDataType<NUdf::TTzTimestamp>::Id: return self.Get<ui64>() == that.Get<ui64>() && self.GetTimezoneId() == that.GetTimezoneId();
- case NUdf::TDataType<NUdf::TDecimal>::Id: return self.GetInt128() == that.GetInt128();
- default: return self.AsStringRef() == that.AsStringRef();
- }
+ case NUdf::TDataType<NUdf::TDecimal>::Id: return self.GetInt128() == that.GetInt128();
+ default: return self.AsStringRef() == that.AsStringRef();
+ }
}
TStructType::TStructType(ui32 membersCount, std::pair<TInternName, TType*>* members, const TTypeEnvironment& env,
@@ -853,7 +853,7 @@ TNode* TListLiteral::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
newTypeNode ? static_cast<TListType*>(newTypeNode) : GetType(), env, false);
}
-void TListLiteral::DoFreeze(const TTypeEnvironment&) {
+void TListLiteral::DoFreeze(const TTypeEnvironment&) {
ui32 voidCount = 0;
for (ui32 i = 0; i < Count; ++i) {
auto& node = Items[i];
@@ -899,7 +899,7 @@ TStreamType::TStreamType(TType* itemType, const TTypeEnvironment& env, bool vali
}
TStreamType* TStreamType::Create(TType* itemType, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TStreamType>()) TStreamType(itemType, env);
+ return ::new(env.Allocate<TStreamType>()) TStreamType(itemType, env);
}
bool TStreamType::IsSameType(const TStreamType& typeToCompare) const {
@@ -931,46 +931,46 @@ void TStreamType::DoFreeze(const TTypeEnvironment& env) {
Y_UNUSED(env);
}
-TFlowType::TFlowType(TType* itemType, const TTypeEnvironment& env, bool validate)
- : TType(EKind::Flow, env.GetTypeOfType())
- , Data(itemType)
-{
- Y_UNUSED(validate);
-}
-
-TFlowType* TFlowType::Create(TType* itemType, const TTypeEnvironment& env) {
- return ::new(env.Allocate<TFlowType>()) TFlowType(itemType, env);
-}
-
-bool TFlowType::IsSameType(const TFlowType& typeToCompare) const {
- return GetItemType()->IsSameType(*typeToCompare.GetItemType());
-}
-
+TFlowType::TFlowType(TType* itemType, const TTypeEnvironment& env, bool validate)
+ : TType(EKind::Flow, env.GetTypeOfType())
+ , Data(itemType)
+{
+ Y_UNUSED(validate);
+}
+
+TFlowType* TFlowType::Create(TType* itemType, const TTypeEnvironment& env) {
+ return ::new(env.Allocate<TFlowType>()) TFlowType(itemType, env);
+}
+
+bool TFlowType::IsSameType(const TFlowType& typeToCompare) const {
+ return GetItemType()->IsSameType(*typeToCompare.GetItemType());
+}
+
bool TFlowType::IsConvertableTo(const TFlowType& typeToCompare, bool ignoreTagged) const {
return GetItemType()->IsConvertableTo(*typeToCompare.GetItemType(), ignoreTagged);
-}
-
-void TFlowType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
- auto itemTypeIt = links.find(GetItemType());
- if (itemTypeIt != links.end()) {
- TNode* newNode = itemTypeIt->second;
- Y_VERIFY_DEBUG(GetItemType()->Equals(*newNode));
- Data = static_cast<TType*>(newNode);
- }
-}
-
-TNode* TFlowType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
- auto newTypeNode = (TNode*)GetItemType()->GetCookie();
- if (!newTypeNode)
- return const_cast<TFlowType*>(this);
-
- return ::new(env.Allocate<TFlowType>()) TFlowType(static_cast<TType*>(newTypeNode), env, false);
-}
-
-void TFlowType::DoFreeze(const TTypeEnvironment& env) {
- Y_UNUSED(env);
-}
-
+}
+
+void TFlowType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
+ auto itemTypeIt = links.find(GetItemType());
+ if (itemTypeIt != links.end()) {
+ TNode* newNode = itemTypeIt->second;
+ Y_VERIFY_DEBUG(GetItemType()->Equals(*newNode));
+ Data = static_cast<TType*>(newNode);
+ }
+}
+
+TNode* TFlowType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
+ auto newTypeNode = (TNode*)GetItemType()->GetCookie();
+ if (!newTypeNode)
+ return const_cast<TFlowType*>(this);
+
+ return ::new(env.Allocate<TFlowType>()) TFlowType(static_cast<TType*>(newTypeNode), env, false);
+}
+
+void TFlowType::DoFreeze(const TTypeEnvironment& env) {
+ Y_UNUSED(env);
+}
+
TOptionalType::TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate)
: TType(EKind::Optional, env.GetTypeOfType())
, Data(itemType)
@@ -2205,54 +2205,54 @@ bool IsIntervalType(NUdf::TDataTypeId typeId) {
return slot && NUdf::GetDataTypeInfo(*slot).Features & NUdf::TimeIntervalType;
}
-EValueRepresentation GetValueRepresentation(NUdf::TDataTypeId type) {
- switch (type) {
-#define CASE_FOR(type, layout) \
- case NUdf::TDataType<type>::Id:
-KNOWN_FIXED_VALUE_TYPES(CASE_FOR)
-#undef CASE_FOR
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- case NUdf::TDataType<NUdf::TTzDate>::Id:
- case NUdf::TDataType<NUdf::TTzDatetime>::Id:
- case NUdf::TDataType<NUdf::TTzTimestamp>::Id:
- return EValueRepresentation::Embedded;
- default:
- return EValueRepresentation::String;
- }
-}
-
-EValueRepresentation GetValueRepresentation(const TType* type) {
- switch (type->GetKind()) {
- case TType::EKind::Data:
- return GetValueRepresentation(static_cast<const TDataType*>(type)->GetSchemeType());
- case TType::EKind::Optional:
- return GetValueRepresentation(static_cast<const TOptionalType*>(type)->GetItemType());
- case TType::EKind::Flow:
- return GetValueRepresentation(static_cast<const TFlowType*>(type)->GetItemType());
-
- case TType::EKind::Stream:
- case TType::EKind::Struct:
- case TType::EKind::Tuple:
- case TType::EKind::Dict:
- case TType::EKind::List:
- case TType::EKind::Resource:
+EValueRepresentation GetValueRepresentation(NUdf::TDataTypeId type) {
+ switch (type) {
+#define CASE_FOR(type, layout) \
+ case NUdf::TDataType<type>::Id:
+KNOWN_FIXED_VALUE_TYPES(CASE_FOR)
+#undef CASE_FOR
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ case NUdf::TDataType<NUdf::TTzDate>::Id:
+ case NUdf::TDataType<NUdf::TTzDatetime>::Id:
+ case NUdf::TDataType<NUdf::TTzTimestamp>::Id:
+ return EValueRepresentation::Embedded;
+ default:
+ return EValueRepresentation::String;
+ }
+}
+
+EValueRepresentation GetValueRepresentation(const TType* type) {
+ switch (type->GetKind()) {
+ case TType::EKind::Data:
+ return GetValueRepresentation(static_cast<const TDataType*>(type)->GetSchemeType());
+ case TType::EKind::Optional:
+ return GetValueRepresentation(static_cast<const TOptionalType*>(type)->GetItemType());
+ case TType::EKind::Flow:
+ return GetValueRepresentation(static_cast<const TFlowType*>(type)->GetItemType());
+
+ case TType::EKind::Stream:
+ case TType::EKind::Struct:
+ case TType::EKind::Tuple:
+ case TType::EKind::Dict:
+ case TType::EKind::List:
+ case TType::EKind::Resource:
case TType::EKind::Block:
- case TType::EKind::Callable:
+ case TType::EKind::Callable:
case TType::EKind::EmptyList:
case TType::EKind::EmptyDict:
- return EValueRepresentation::Boxed;
-
- case TType::EKind::Variant:
- case TType::EKind::Void:
- return EValueRepresentation::Any;
-
+ return EValueRepresentation::Boxed;
+
+ case TType::EKind::Variant:
+ case TType::EKind::Void:
+ return EValueRepresentation::Any;
+
case TType::EKind::Null:
return EValueRepresentation::Embedded;
- default:
- Y_FAIL("Unsupported type.");
- }
+ default:
+ Y_FAIL("Unsupported type.");
+ }
+}
+
+}
}
-
-}
-}
diff --git a/ydb/library/yql/minikql/mkql_node.h b/ydb/library/yql/minikql/mkql_node.h
index 6920d81849..ee74455ea6 100644
--- a/ydb/library/yql/minikql/mkql_node.h
+++ b/ydb/library/yql/minikql/mkql_node.h
@@ -10,7 +10,7 @@
#include <util/generic/maybe.h>
#include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
-#include <stack>
+#include <stack>
namespace NKikimr {
namespace NMiniKQL {
@@ -42,8 +42,8 @@ private:
};
struct TRuntimeNode {
- using TList = TSmallVec<TRuntimeNode>;
-
+ using TList = TSmallVec<TRuntimeNode>;
+
TRuntimeNode()
: Data(nullptr, true)
{}
@@ -82,8 +82,8 @@ struct TRuntimeNode {
TTaggedPointer<TNode> Data;
};
-using TRuntimeNodePair = std::array<TRuntimeNode, 2U>;
-
+using TRuntimeNodePair = std::array<TRuntimeNode, 2U>;
+
class TTypeEnvironment;
class TNode : private TNonCopyable {
@@ -142,7 +142,7 @@ class TTypeEnvironment;
XX(Any, 10) \
XX(Tuple, 11) \
XX(Resource, 12) \
- XX(Flow, 13) \
+ XX(Flow, 13) \
XX(Null, 14) \
XX(ReservedKind, 15) \
XX(EmptyList, 16 + 2) \
@@ -442,39 +442,39 @@ public:
}
- std::vector<TNode*>& GetNodeStack() const {
+ std::vector<TNode*>& GetNodeStack() const {
return Stack;
}
void ClearCookies() const;
- NUdf::TUnboxedValuePod NewStringValue(const NUdf::TStringRef& data) const {
- if (data.Size() > NUdf::TUnboxedValue::InternalBufferSize) {
- auto value = NewString(data.Size());
- std::memcpy(value.Data(), data.Data(), data.Size());
- return NUdf::TUnboxedValuePod(std::move(value));
- } else {
- return NUdf::TUnboxedValuePod::Embedded(data);
- }
- }
-
- TGuard<TScopedAlloc> BindAllocator() const {
- return Guard(Alloc);
- }
-
+ NUdf::TUnboxedValuePod NewStringValue(const NUdf::TStringRef& data) const {
+ if (data.Size() > NUdf::TUnboxedValue::InternalBufferSize) {
+ auto value = NewString(data.Size());
+ std::memcpy(value.Data(), data.Data(), data.Size());
+ return NUdf::TUnboxedValuePod(std::move(value));
+ } else {
+ return NUdf::TUnboxedValuePod::Embedded(data);
+ }
+ }
+
+ TGuard<TScopedAlloc> BindAllocator() const {
+ return Guard(Alloc);
+ }
+
TScopedAlloc& GetAllocator() const { return Alloc; }
- const NUdf::TStringValue& NewString(ui32 size) const {
- Strings.emplace(size);
- return Strings.top();
- }
-
-private:
- TScopedAlloc& Alloc;
+ const NUdf::TStringValue& NewString(ui32 size) const {
+ Strings.emplace(size);
+ return Strings.top();
+ }
+
+private:
+ TScopedAlloc& Alloc;
mutable TPagedArena Arena;
- mutable std::stack<NUdf::TStringValue> Strings;
+ mutable std::stack<NUdf::TStringValue> Strings;
mutable THashSet<TStringBuf> NamesPool;
- mutable std::vector<TNode*> Stack;
+ mutable std::vector<TNode*> Stack;
TTypeType* TypeOfType;
TVoidType* TypeOfVoid;
@@ -532,7 +532,7 @@ public:
return DataSlot;
}
-protected:
+protected:
TDataType(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env);
void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
@@ -544,38 +544,38 @@ private:
const TMaybe<NUdf::EDataSlot> DataSlot;
};
-class TDataDecimalType : public TDataType {
-friend class TType;
-public:
- static TDataDecimalType* Create(ui8 precision, ui8 scale, const TTypeEnvironment& env);
-
- bool IsSameType(const TDataDecimalType& typeToCompare) const;
-
+class TDataDecimalType : public TDataType {
+friend class TType;
+public:
+ static TDataDecimalType* Create(ui8 precision, ui8 scale, const TTypeEnvironment& env);
+
+ bool IsSameType(const TDataDecimalType& typeToCompare) const;
+
bool IsConvertableTo(const TDataDecimalType& typeToCompare, bool ignoreTagged = false) const;
-
- std::pair<ui8, ui8> GetParams() const;
-private:
- TDataDecimalType(ui8 precision, ui8 scale, const TTypeEnvironment& env);
-
- const ui8 Precision;
- const ui8 Scale;
-};
-
-class TDataLiteral : public TNode, private NUdf::TUnboxedValuePod {
+
+ std::pair<ui8, ui8> GetParams() const;
+private:
+ TDataDecimalType(ui8 precision, ui8 scale, const TTypeEnvironment& env);
+
+ const ui8 Precision;
+ const ui8 Scale;
+};
+
+class TDataLiteral : public TNode, private NUdf::TUnboxedValuePod {
friend class TNode;
public:
- static TDataLiteral* Create(const NUdf::TUnboxedValuePod& value, TDataType* type, const TTypeEnvironment& env);
+ static TDataLiteral* Create(const NUdf::TUnboxedValuePod& value, TDataType* type, const TTypeEnvironment& env);
TDataType* GetType() const {
return static_cast<TDataType*>(GetGenericType());
}
- const NUdf::TUnboxedValuePod& AsValue() const {
- return *this;
+ const NUdf::TUnboxedValuePod& AsValue() const {
+ return *this;
}
private:
- TDataLiteral(const NUdf::TUnboxedValuePod& value, TDataType* type);
+ TDataLiteral(const NUdf::TUnboxedValuePod& value, TDataType* type);
using TNode::Equals;
bool Equals(const TDataLiteral& nodeToCompare) const;
@@ -771,32 +771,32 @@ private:
TType* Data;
};
-class TFlowType : public TType {
- friend class TType;
-public:
- static TFlowType* Create(TType* itemType, const TTypeEnvironment& env);
-
- using TType::IsSameType;
- bool IsSameType(const TFlowType& typeToCompare) const;
-
- using TType::IsConvertableTo;
+class TFlowType : public TType {
+ friend class TType;
+public:
+ static TFlowType* Create(TType* itemType, const TTypeEnvironment& env);
+
+ using TType::IsSameType;
+ bool IsSameType(const TFlowType& typeToCompare) const;
+
+ using TType::IsConvertableTo;
bool IsConvertableTo(const TFlowType& typeToCompare, bool ignoreTagged = false) const;
-
- TType* GetItemType() const {
- return Data;
- }
-
-private:
- TFlowType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
-
- void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
- TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
- void DoFreeze(const TTypeEnvironment& env);
-
-private:
- TType* Data;
-};
-
+
+ TType* GetItemType() const {
+ return Data;
+ }
+
+private:
+ TFlowType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
+
+ void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
+ TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
+ void DoFreeze(const TTypeEnvironment& env);
+
+private:
+ TType* Data;
+};
+
class TOptionalType : public TType {
friend class TType;
public:
@@ -1373,16 +1373,16 @@ bool IsDateType(NUdf::TDataTypeId typeId);
bool IsTzDateType(NUdf::TDataTypeId typeId);
bool IsIntervalType(NUdf::TDataTypeId typeId);
-enum class EValueRepresentation {
- Embedded = 0,
- String = 1,
- Boxed = 2,
- Any = String | Boxed
-};
+enum class EValueRepresentation {
+ Embedded = 0,
+ String = 1,
+ Boxed = 2,
+ Any = String | Boxed
+};
+
+EValueRepresentation GetValueRepresentation(const TType* type);
+EValueRepresentation GetValueRepresentation(NUdf::TDataTypeId typeId);
-EValueRepresentation GetValueRepresentation(const TType* type);
-EValueRepresentation GetValueRepresentation(NUdf::TDataTypeId typeId);
-
template <TType::EKind SingularKind>
TSingularType<SingularKind>* TSingularType<SingularKind>::Create(TTypeType* type, const TTypeEnvironment& env) {
return ::new(env.Allocate<TSingularType<SingularKind>>()) TSingularType<SingularKind>(type);
diff --git a/ydb/library/yql/minikql/mkql_node_builder.cpp b/ydb/library/yql/minikql/mkql_node_builder.cpp
index fa1b253f7a..34466b8944 100644
--- a/ydb/library/yql/minikql/mkql_node_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_node_builder.cpp
@@ -48,13 +48,13 @@ namespace {
}
TDataLiteral* BuildDataLiteral(const NUdf::TUnboxedValuePod& value, NUdf::TDataTypeId type, const TTypeEnvironment& env) {
- return TDataLiteral::Create(value, TDataType::Create(type, env), env);
-}
-
+ return TDataLiteral::Create(value, TDataType::Create(type, env), env);
+}
+
TDataLiteral* BuildDataLiteral(const NUdf::TStringRef& data, NUdf::TDataTypeId type, const TTypeEnvironment& env) {
- return BuildDataLiteral(env.NewStringValue(data), type, env);
-}
-
+ return BuildDataLiteral(env.NewStringValue(data), type, env);
+}
+
TOptionalLiteral* BuildOptionalLiteral(TRuntimeNode value, const TTypeEnvironment& env) {
auto type = TOptionalType::Create(value.GetStaticType(), env);
return TOptionalLiteral::Create(value, type, env);
diff --git a/ydb/library/yql/minikql/mkql_node_cast.cpp b/ydb/library/yql/minikql/mkql_node_cast.cpp
index 2ab6bc23a4..0a62a7d615 100644
--- a/ydb/library/yql/minikql/mkql_node_cast.cpp
+++ b/ydb/library/yql/minikql/mkql_node_cast.cpp
@@ -50,7 +50,7 @@ MKQL_AS_TYPE(Void)
MKQL_AS_TYPE(Resource)
MKQL_AS_TYPE(Variant)
MKQL_AS_TYPE(Stream)
-MKQL_AS_TYPE(Flow)
+MKQL_AS_TYPE(Flow)
MKQL_AS_TYPE(Tagged)
MKQL_AS_TYPE(Block)
@@ -66,7 +66,7 @@ MKQL_AS_VALUE(Type, Type)
MKQL_AS_VALUE(Void, Type)
MKQL_AS_VALUE(Variant, Type)
MKQL_AS_VALUE(Stream, Type)
-MKQL_AS_VALUE(Flow, Type)
+MKQL_AS_VALUE(Flow, Type)
MKQL_AS_VALUE(Data, Literal)
MKQL_AS_VALUE(Dict, Literal)
diff --git a/ydb/library/yql/minikql/mkql_node_cast_ut.cpp b/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
index 716f5b08cc..0ae19fa5e4 100644
--- a/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_cast_ut.cpp
@@ -1,6 +1,6 @@
#include "mkql_node.h"
#include "mkql_node_cast.h"
-#include "mkql_node_builder.h"
+#include "mkql_node_builder.h"
#include <library/cpp/testing/unittest/registar.h>
diff --git a/ydb/library/yql/minikql/mkql_node_printer.cpp b/ydb/library/yql/minikql/mkql_node_printer.cpp
index 7a539ee116..f7515a3005 100644
--- a/ydb/library/yql/minikql/mkql_node_printer.cpp
+++ b/ydb/library/yql/minikql/mkql_node_printer.cpp
@@ -70,10 +70,10 @@ namespace {
Out << "Type (Data), schemeType: ";
if (slot) {
Out << GetDataTypeInfo(*slot).Name;
- if (node.GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto params = static_cast<TDataDecimalType&>(node).GetParams();
- Out << '(' << int(params.first) << ',' << int(params.second) << ')';
- }
+ if (node.GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto params = static_cast<TDataDecimalType&>(node).GetParams();
+ Out << '(' << int(params.first) << ',' << int(params.second) << ')';
+ }
} else {
Out << "<" << node.GetSchemeType() << ">";
}
@@ -163,32 +163,32 @@ namespace {
WriteNewline();
}
- void Visit(TFlowType& node) override {
- WriteIndentation();
- Out << "Type (Flow) {";
- WriteNewline();
-
- {
- TIndentScope scope(this);
- WriteIndentation();
- Out << "Flow item type: {";
- WriteNewline();
-
- {
- TIndentScope scope2(this);
- node.GetItemType()->Accept(*this);
- }
-
- WriteIndentation();
- Out << "}";
- WriteNewline();
- }
-
- WriteIndentation();
- Out << "}";
- WriteNewline();
- }
-
+ void Visit(TFlowType& node) override {
+ WriteIndentation();
+ Out << "Type (Flow) {";
+ WriteNewline();
+
+ {
+ TIndentScope scope(this);
+ WriteIndentation();
+ Out << "Flow item type: {";
+ WriteNewline();
+
+ {
+ TIndentScope scope2(this);
+ node.GetItemType()->Accept(*this);
+ }
+
+ WriteIndentation();
+ Out << "}";
+ WriteNewline();
+ }
+
+ WriteIndentation();
+ Out << "}";
+ WriteNewline();
+ }
+
void Visit(TBlockType& node) override {
WriteIndentation();
Out << "Type (Block) {";
@@ -487,7 +487,7 @@ namespace {
Out << "null";
WriteNewline();
} else {
- Out << TString(node.AsValue().AsStringRef()).Quote();
+ Out << TString(node.AsValue().AsStringRef()).Quote();
WriteNewline();
}
}
diff --git a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
index b26334bc33..ec8c5d1afe 100644
--- a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp
@@ -23,7 +23,7 @@ namespace {
structBuilder.Add("04", TRuntimeNode(TDataType::Create(NUdf::TDataType<ui32>::Id, env), true));
structBuilder.Add("12", TRuntimeNode(env.GetEmptyStruct()->GetType(), true));
TVector<std::pair<TString, TType*>> smallMembers;
- smallMembers.push_back(std::make_pair("Embedded member", env.GetVoid()->GetGenericType()));
+ smallMembers.push_back(std::make_pair("Embedded member", env.GetVoid()->GetGenericType()));
structBuilder.Add("13", TRuntimeNode(TStructType::Create(smallMembers.data(), smallMembers.size(), env), true));
structBuilder.Add("14", TRuntimeNode(TListType::Create(dtype1, env), true));
structBuilder.Add("15", TRuntimeNode(TOptionalType::Create(dtype2, env), true));
@@ -34,26 +34,26 @@ namespace {
dtype2, smallTypes.size(), smallTypes.data(), nullptr, env), true));
structBuilder.Add("18", TRuntimeNode(env.GetVoid(), true));
ui32 u = 345;
- structBuilder.Add("19", TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
+ structBuilder.Add("19", TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
auto v = TRuntimeNode(env.GetVoid(), true);
structBuilder.Add("26", TRuntimeNode(TListLiteral::Create(nullptr, 0, ltype1, env), true));
TVector<TRuntimeNode> litems;
- litems.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
+ litems.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
u = 789;
- litems.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
+ litems.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true));
structBuilder.Add("27", TRuntimeNode(TListLiteral::Create(litems.data(), litems.size(), ltype1, env), true));
structBuilder.Add("28", TRuntimeNode(TOptionalLiteral::Create(otype1, env), true));
structBuilder.Add("29", TRuntimeNode(TOptionalLiteral::Create(litems[0], otype1, env), true));
auto ditype1 = TDictType::Create(dtype1, dtype2, env);
TVector<std::pair<TRuntimeNode, TRuntimeNode>> ditems;
- ditems.push_back(std::make_pair(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true),
- TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod::Embedded("aaaa"), dtype2, env), true)));
+ ditems.push_back(std::make_pair(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true),
+ TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod::Embedded("aaaa"), dtype2, env), true)));
structBuilder.Add("30", TRuntimeNode(TDictLiteral::Create(ditems.size(), ditems.data(), ditype1, env), true));
TVector<TRuntimeNode> callableArgs;
callableArgs.push_back(TRuntimeNode(env.GetVoid(), true));
TCallable* callable = TCallable::Create(callableArgs.size(), callableArgs.data(), ctype1, env);
- callable->SetResult(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true), env);
+ callable->SetResult(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env), true), env);
structBuilder.Add("31", TRuntimeNode(callable, true));
structBuilder.Add("32", TRuntimeNode(env.GetAnyType(), true));
structBuilder.Add("33", TRuntimeNode(TAny::Create(env), true));
@@ -66,7 +66,7 @@ namespace {
TVector<TType*> tupleTypes;
tupleTypes.push_back(dtype1);
TVector<TRuntimeNode> tupleValues;
- tupleValues.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true));
+ tupleValues.push_back(TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)456), dtype1, env), true));
auto tupleType = TTupleType::Create(tupleTypes.size(), tupleTypes.data(), env);
structBuilder.Add("36", TRuntimeNode(tupleType, true));
structBuilder.Add("37", TRuntimeNode(TTupleLiteral::Create(tupleValues.size(), tupleValues.data(), tupleType, env), true));
diff --git a/ydb/library/yql/minikql/mkql_node_serialization.cpp b/ydb/library/yql/minikql/mkql_node_serialization.cpp
index d553ebc36b..e314f38cd6 100644
--- a/ydb/library/yql/minikql/mkql_node_serialization.cpp
+++ b/ydb/library/yql/minikql/mkql_node_serialization.cpp
@@ -146,11 +146,11 @@ namespace {
Owner.Write(TypeMarker | (char)TType::EKind::Data);
Owner.WriteVar32(node.GetSchemeType());
- if (NUdf::TDataType<NUdf::TDecimal>::Id == node.GetSchemeType()) {
- const auto& params = static_cast<TDataDecimalType&>(node).GetParams();
- Owner.Write(params.first);
- Owner.Write(params.second);
- }
+ if (NUdf::TDataType<NUdf::TDecimal>::Id == node.GetSchemeType()) {
+ const auto& params = static_cast<TDataDecimalType&>(node).GetParams();
+ Owner.Write(params.first);
+ Owner.Write(params.second);
+ }
IsProcessed0 = false;
}
@@ -198,18 +198,18 @@ namespace {
}
void Visit(TFlowType& node) override {
- if (node.GetCookie() != 0) {
- Owner.WriteReference(node);
- IsProcessed0 = true;
- return;
- }
-
- Owner.Write(TypeMarker | (char)TType::EKind::Flow);
- auto itemType = node.GetItemType();
- Owner.AddChildNode(*itemType);
- IsProcessed0 = false;
- }
-
+ if (node.GetCookie() != 0) {
+ Owner.WriteReference(node);
+ IsProcessed0 = true;
+ return;
+ }
+
+ Owner.Write(TypeMarker | (char)TType::EKind::Flow);
+ auto itemType = node.GetItemType();
+ Owner.AddChildNode(*itemType);
+ IsProcessed0 = false;
+ }
+
void Visit(TBlockType& node) override {
if (node.GetCookie() != 0) {
Owner.WriteReference(node);
@@ -592,10 +592,10 @@ namespace {
Owner.RegisterReference(node);
}
- void Visit(TFlowType& node) override {
- Owner.RegisterReference(node);
- }
-
+ void Visit(TFlowType& node) override {
+ Owner.RegisterReference(node);
+ }
+
void Visit(TBlockType& node) override {
Owner.Write(static_cast<ui8>(node.GetShape()));
Owner.RegisterReference(node);
@@ -655,15 +655,15 @@ namespace {
}
void Visit(TDataLiteral& node) override {
- const auto type = node.GetType();
+ const auto type = node.GetType();
if (type->GetSchemeType() != 0) {
- const auto& value = node.AsValue();
+ const auto& value = node.AsValue();
switch (type->GetSchemeType()) {
case NUdf::TDataType<bool>::Id:
- Owner.Write(value.Get<bool>());
- break;
+ Owner.Write(value.Get<bool>());
+ break;
case NUdf::TDataType<ui8>::Id:
- Owner.Write(value.Get<ui8>());
+ Owner.Write(value.Get<ui8>());
break;
case NUdf::TDataType<i8>::Id:
Owner.Write((ui8)value.Get<i8>());
@@ -675,36 +675,36 @@ namespace {
Owner.WriteVar32(value.Get<ui16>());
break;
case NUdf::TDataType<i32>::Id:
- Owner.WriteVar32(ZigZagEncode(value.Get<i32>()));
+ Owner.WriteVar32(ZigZagEncode(value.Get<i32>()));
break;
case NUdf::TDataType<ui32>::Id:
- Owner.WriteVar32(value.Get<ui32>());
+ Owner.WriteVar32(value.Get<ui32>());
break;
- case NUdf::TDataType<float>::Id: {
- const auto v = value.Get<float>();
- Owner.WriteMany(&v, sizeof(v));
- break;
- }
+ case NUdf::TDataType<float>::Id: {
+ const auto v = value.Get<float>();
+ Owner.WriteMany(&v, sizeof(v));
+ break;
+ }
case NUdf::TDataType<i64>::Id:
- Owner.WriteVar64(ZigZagEncode(value.Get<i64>()));
+ Owner.WriteVar64(ZigZagEncode(value.Get<i64>()));
break;
case NUdf::TDataType<ui64>::Id:
- Owner.WriteVar64(value.Get<ui64>());
+ Owner.WriteVar64(value.Get<ui64>());
+ break;
+ case NUdf::TDataType<double>::Id: {
+ const auto v = value.Get<double>();
+ Owner.WriteMany(&v, sizeof(v));
+ break;
+ }
+ case NUdf::TDataType<NUdf::TDate>::Id:
+ Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDate>::TLayout>());
+ break;
+ case NUdf::TDataType<NUdf::TDatetime>::Id:
+ Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDatetime>::TLayout>());
+ break;
+ case NUdf::TDataType<NUdf::TTimestamp>::Id:
+ Owner.WriteVar64(value.Get<NUdf::TDataType<NUdf::TTimestamp>::TLayout>());
break;
- case NUdf::TDataType<double>::Id: {
- const auto v = value.Get<double>();
- Owner.WriteMany(&v, sizeof(v));
- break;
- }
- case NUdf::TDataType<NUdf::TDate>::Id:
- Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDate>::TLayout>());
- break;
- case NUdf::TDataType<NUdf::TDatetime>::Id:
- Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDatetime>::TLayout>());
- break;
- case NUdf::TDataType<NUdf::TTimestamp>::Id:
- Owner.WriteVar64(value.Get<NUdf::TDataType<NUdf::TTimestamp>::TLayout>());
- break;
case NUdf::TDataType<NUdf::TTzDate>::Id: {
Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TTzDate>::TLayout>());
Owner.WriteVar32(value.GetTimezoneId());
@@ -720,22 +720,22 @@ namespace {
Owner.WriteVar32(value.GetTimezoneId());
break;
}
- case NUdf::TDataType<NUdf::TInterval>::Id:
- Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TInterval>::TLayout>()));
- break;
+ case NUdf::TDataType<NUdf::TInterval>::Id:
+ Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TInterval>::TLayout>()));
+ break;
case NUdf::TDataType<NUdf::TUuid>::Id: {
const auto v = value.AsStringRef();
Owner.WriteMany(v.Data(), v.Size());
break;
}
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- Owner.WriteMany(static_cast<const char*>(value.GetRawPtr()), sizeof(NYql::NDecimal::TInt128) - 1U);
- break;
- default: {
- const auto& buffer = value.AsStringRef();
- Owner.WriteVar32(buffer.Size());
- Owner.WriteMany(buffer.Data(), buffer.Size());
- }
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ Owner.WriteMany(static_cast<const char*>(value.GetRawPtr()), sizeof(NYql::NDecimal::TInt128) - 1U);
+ break;
+ default: {
+ const auto& buffer = value.AsStringRef();
+ Owner.WriteVar32(buffer.Size());
+ Owner.WriteMany(buffer.Data(), buffer.Size());
+ }
}
}
@@ -1158,8 +1158,8 @@ namespace {
return 0;
case TType::EKind::Variant:
return 1;
- case TType::EKind::Flow:
- return 1;
+ case TType::EKind::Flow:
+ return 1;
case TType::EKind::Null:
return 0;
default:
@@ -1195,7 +1195,7 @@ namespace {
return ReadResourceType();
case TType::EKind::Variant:
return ReadVariantType();
- case TType::EKind::Flow:
+ case TType::EKind::Flow:
return ReadFlowOrBlockType(code);
case TType::EKind::Null:
return ReadNullType();
@@ -1226,14 +1226,14 @@ namespace {
TNode* ReadDataType() {
const auto schemeType = ReadVar32();
- if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- const ui8 precision = Read();
- const ui8 scale = Read();
- Nodes.emplace_back(TDataDecimalType::Create(precision, scale, Env));
- } else {
- Nodes.emplace_back(TDataType::Create(static_cast<NUdf::TDataTypeId>(schemeType), Env));
- }
- return Nodes.back();
+ if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
+ const ui8 precision = Read();
+ const ui8 scale = Read();
+ Nodes.emplace_back(TDataDecimalType::Create(precision, scale, Env));
+ } else {
+ Nodes.emplace_back(TDataType::Create(static_cast<NUdf::TDataTypeId>(schemeType), Env));
+ }
+ return Nodes.back();
}
ui32 TryReadKeyType(char code) {
@@ -1322,17 +1322,17 @@ namespace {
}
}
- TNode* ReadFlowType() {
- auto itemTypeNode = PopNode();
- if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
- ThrowCorrupted();
-
- auto itemType = static_cast<TType*>(itemTypeNode);
- auto node = TFlowType::Create(itemType, Env);
- Nodes.push_back(node);
- return node;
- }
-
+ TNode* ReadFlowType() {
+ auto itemTypeNode = PopNode();
+ if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
+ ThrowCorrupted();
+
+ auto itemType = static_cast<TType*>(itemTypeNode);
+ auto node = TFlowType::Create(itemType, Env);
+ Nodes.push_back(node);
+ return node;
+ }
+
TNode* ReadBlockType() {
auto itemTypeNode = PopNode();
if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type) {
@@ -1554,12 +1554,12 @@ namespace {
ThrowCorrupted();
auto dataType = static_cast<TDataType*>(type);
- NUdf::TUnboxedValuePod value;
+ NUdf::TUnboxedValuePod value;
switch (dataType->GetSchemeType()) {
case 0:
break;
case NUdf::TDataType<bool>::Id:
- value = NUdf::TUnboxedValuePod((bool)Read());
+ value = NUdf::TUnboxedValuePod((bool)Read());
break;
case NUdf::TDataType<i8>::Id:
{
@@ -1568,7 +1568,7 @@ namespace {
}
case NUdf::TDataType<ui8>::Id:
{
- value = NUdf::TUnboxedValuePod((ui8)Read());
+ value = NUdf::TUnboxedValuePod((ui8)Read());
break;
}
case NUdf::TDataType<i16>::Id:
@@ -1583,12 +1583,12 @@ namespace {
}
case NUdf::TDataType<i32>::Id:
{
- value = NUdf::TUnboxedValuePod((i32)ZigZagDecode(ReadVar32()));
+ value = NUdf::TUnboxedValuePod((i32)ZigZagDecode(ReadVar32()));
break;
}
case NUdf::TDataType<ui32>::Id:
{
- value = NUdf::TUnboxedValuePod((ui32)ReadVar32());
+ value = NUdf::TUnboxedValuePod((ui32)ReadVar32());
break;
}
case NUdf::TDataType<float>::Id:
@@ -1598,12 +1598,12 @@ namespace {
}
case NUdf::TDataType<i64>::Id:
{
- value = NUdf::TUnboxedValuePod((i64)ZigZagDecode(ReadVar64()));
+ value = NUdf::TUnboxedValuePod((i64)ZigZagDecode(ReadVar64()));
break;
}
case NUdf::TDataType<ui64>::Id:
{
- value = NUdf::TUnboxedValuePod((ui64)ReadVar64());
+ value = NUdf::TUnboxedValuePod((ui64)ReadVar64());
break;
}
case NUdf::TDataType<double>::Id:
@@ -1611,26 +1611,26 @@ namespace {
value = NUdf::TUnboxedValuePod(ReadUnaligned<double>(reinterpret_cast<const double*>(ReadMany(sizeof(double)))));
break;
}
- case NUdf::TDataType<NUdf::TDate>::Id:
- {
- value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDate>::TLayout>(ReadVar32()));
- break;
- }
- case NUdf::TDataType<NUdf::TDatetime>::Id:
- {
- value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDatetime>::TLayout>(ReadVar32()));
- break;
- }
- case NUdf::TDataType<NUdf::TTimestamp>::Id:
- {
- value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(ReadVar64()));
- break;
- }
- case NUdf::TDataType<NUdf::TInterval>::Id:
- {
- value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TInterval>::TLayout>(ZigZagDecode(ReadVar64())));
- break;
- }
+ case NUdf::TDataType<NUdf::TDate>::Id:
+ {
+ value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDate>::TLayout>(ReadVar32()));
+ break;
+ }
+ case NUdf::TDataType<NUdf::TDatetime>::Id:
+ {
+ value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDatetime>::TLayout>(ReadVar32()));
+ break;
+ }
+ case NUdf::TDataType<NUdf::TTimestamp>::Id:
+ {
+ value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(ReadVar64()));
+ break;
+ }
+ case NUdf::TDataType<NUdf::TInterval>::Id:
+ {
+ value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TInterval>::TLayout>(ZigZagDecode(ReadVar64())));
+ break;
+ }
case NUdf::TDataType<NUdf::TTzDate>::Id:
{
value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzDate>::TLayout>(ReadVar32()));
@@ -1661,22 +1661,22 @@ namespace {
value = Env.NewStringValue(NUdf::TStringRef(buffer, 16));
break;
}
- case NUdf::TDataType<NUdf::TDecimal>::Id:
- {
- value = NUdf::TUnboxedValuePod::Zero();
- const char* buffer = ReadMany(sizeof(NYql::NDecimal::TInt128) - 1U);
- std::memcpy(static_cast<char*>(value.GetRawPtr()), buffer, sizeof(NYql::NDecimal::TInt128) - 1U);
- break;
- }
+ case NUdf::TDataType<NUdf::TDecimal>::Id:
+ {
+ value = NUdf::TUnboxedValuePod::Zero();
+ const char* buffer = ReadMany(sizeof(NYql::NDecimal::TInt128) - 1U);
+ std::memcpy(static_cast<char*>(value.GetRawPtr()), buffer, sizeof(NYql::NDecimal::TInt128) - 1U);
+ break;
+ }
default:
- const ui32 size = ReadVar32();
- const char* buffer = ReadMany(size);
- value = Env.NewStringValue(NUdf::TStringRef(buffer, size));
- break;
+ const ui32 size = ReadVar32();
+ const char* buffer = ReadMany(size);
+ value = Env.NewStringValue(NUdf::TStringRef(buffer, size));
+ break;
}
- const auto node = TDataLiteral::Create(value, dataType, Env);
- Nodes.emplace_back(node);
+ const auto node = TDataLiteral::Create(value, dataType, Env);
+ Nodes.emplace_back(node);
return node;
}
diff --git a/ydb/library/yql/minikql/mkql_node_ut.cpp b/ydb/library/yql/minikql/mkql_node_ut.cpp
index d28642adb6..1612627246 100644
--- a/ydb/library/yql/minikql/mkql_node_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_node_ut.cpp
@@ -48,7 +48,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EQUAL(dtype1->GetSchemeType(), NUdf::TDataType<ui32>::Id);
UNIT_ASSERT(dtype1->IsSameType(*dtype1));
- UNIT_ASSERT_EXCEPTION(TDataType::Create(0, env), yexception);
+ UNIT_ASSERT_EXCEPTION(TDataType::Create(0, env), yexception);
TDataType* dtype1Cloned = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
UNIT_ASSERT(dtype1Cloned->IsSameType(*dtype1));
@@ -60,8 +60,8 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TDataType* dtype1 = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
ui32 u = 34567;
- auto d1 = TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env);
- UNIT_ASSERT(memcmp(d1->AsValue().AsStringRef().Data(), &u, sizeof(u)) == 0);
+ auto d1 = TDataLiteral::Create(NUdf::TUnboxedValuePod(u), dtype1, env);
+ UNIT_ASSERT(memcmp(d1->AsValue().AsStringRef().Data(), &u, sizeof(u)) == 0);
UNIT_ASSERT(d1->GetType() == dtype1);
}
@@ -127,7 +127,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EXCEPTION(TStructLiteral::Create(s1values.size(), s1values.data(), semptyType, env), yexception);
TVector<std::pair<TString, TType*>> s2members;
- s2members.push_back(std::make_pair("aaa", env.GetEmptyTuple()->GetGenericType()));
+ s2members.push_back(std::make_pair("aaa", env.GetEmptyTuple()->GetGenericType()));
TStructType* s2type = TStructType::Create(s2members.data(), s2members.size(), env);
UNIT_ASSERT_EXCEPTION(TStructLiteral::Create(s1values.size(), s1values.data(), s2type, env), yexception);
@@ -145,7 +145,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TTypeEnvironment env(alloc);
TListType* list1type = TListType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(list1type->GetKind(), TType::EKind::List);
- TListType* list2type = TListType::Create(env.GetEmptyTuple()->GetGenericType(), env);
+ TListType* list2type = TListType::Create(env.GetEmptyTuple()->GetGenericType(), env);
TListType* list1typeCloned = TListType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(list1type->IsSameType(*list1typeCloned));
UNIT_ASSERT(!list1type->IsSameType(*list2type));
@@ -156,7 +156,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TTypeEnvironment env(alloc);
TStreamType* stream1type = TStreamType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(stream1type->GetKind(), TType::EKind::Stream);
- TStreamType* stream2type = TStreamType::Create(env.GetEmptyTuple()->GetGenericType(), env);
+ TStreamType* stream2type = TStreamType::Create(env.GetEmptyTuple()->GetGenericType(), env);
TStreamType* stream1typeCloned = TStreamType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(stream1type->IsSameType(*stream1typeCloned));
UNIT_ASSERT(!stream1type->IsSameType(*stream2type));
@@ -174,16 +174,16 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TString u = "34567";
TVector<TRuntimeNode> someItems;
someItems.push_back(TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValue::Embedded(u), dtype1, env), true));
+ NUdf::TUnboxedValue::Embedded(u), dtype1, env), true));
u = "878";
someItems.push_back(TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValue::Embedded(u), dtype1, env), true));
+ NUdf::TUnboxedValue::Embedded(u), dtype1, env), true));
TListLiteral* list2 = TListLiteral::Create(someItems.data(), someItems.size(), list2type, env);
UNIT_ASSERT_EQUAL(list2->GetItemsCount(), 2);
UNIT_ASSERT_EQUAL(list2->GetItems()[0].GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*list2->GetItems()[0].GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*list2->GetItems()[0].GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
UNIT_ASSERT_EQUAL(list2->GetItems()[1].GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*list2->GetItems()[1].GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("878"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*list2->GetItems()[1].GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("878"));
UNIT_ASSERT_EXCEPTION(TListLiteral::Create(someItems.data(), someItems.size(), list1type, env), yexception);
@@ -202,7 +202,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TTypeEnvironment env(alloc);
TOptionalType* opt1type = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT_EQUAL(opt1type->GetKind(), TType::EKind::Optional);
- TOptionalType* opt2type = TOptionalType::Create(env.GetEmptyTuple()->GetGenericType(), env);
+ TOptionalType* opt2type = TOptionalType::Create(env.GetEmptyTuple()->GetGenericType(), env);
TOptionalType* opt1typeCloned = TOptionalType::Create(env.GetVoid()->GetGenericType(), env);
UNIT_ASSERT(opt1type->IsSameType(*opt1typeCloned));
UNIT_ASSERT(!opt1type->IsSameType(*opt2type));
@@ -220,12 +220,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TString u = "34567";
auto item1 = TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true);
+ NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true);
TOptionalLiteral* opt1 = TOptionalLiteral::Create(item1, opt2type, env);
UNIT_ASSERT(opt1->HasItem());
UNIT_ASSERT_EQUAL(opt1->GetItem().GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*opt1->GetItem().GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*opt1->GetItem().GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
UNIT_ASSERT_EXCEPTION(TOptionalLiteral::Create(item1, opt1type, env), yexception);
@@ -261,13 +261,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
UNIT_ASSERT_EQUAL(ctype1->GetReturnType()->GetKind(), TType::EKind::Void);
TVector<TType*> types;
- types.push_back(env.GetVoid()->GetGenericType());
+ types.push_back(env.GetVoid()->GetGenericType());
types.push_back(env.GetEmptyStruct()->GetGenericType());
TCallableType* ctype2 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
UNIT_ASSERT_EQUAL(ctype2->GetName(), "c2");
UNIT_ASSERT_EQUAL(ctype2->GetReturnType()->GetKind(), TType::EKind::Void);
UNIT_ASSERT_EQUAL(ctype2->GetArgumentsCount(), 2);
- UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(0)->GetKind(), TType::EKind::Void);
+ UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(0)->GetKind(), TType::EKind::Void);
UNIT_ASSERT_EQUAL(ctype2->GetArgumentType(1)->GetKind(), TType::EKind::Struct);
TCallableType* ctype2Cloned = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), nullptr, env);
@@ -277,12 +277,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TType*> types2;
types2.push_back(env.GetEmptyStruct()->GetGenericType());
- types2.push_back(env.GetVoid()->GetGenericType());
+ types2.push_back(env.GetVoid()->GetGenericType());
TCallableType* ctype2rev = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types2.size(), types2.data(), nullptr, env);
UNIT_ASSERT(!ctype2->IsSameType(*ctype2rev));
TVector<TType*> types3;
- types3.push_back(env.GetVoid()->GetGenericType());
+ types3.push_back(env.GetVoid()->GetGenericType());
types3.push_back(env.GetEmptyStruct()->GetGenericType());
TCallableType* ctype2withPayload1 = TCallableType::Create("c2", env.GetVoid()->GetGenericType(), types.size(), types.data(), env.GetEmptyStruct(), env);
UNIT_ASSERT(!ctype2withPayload1->IsSameType(*ctype2));
@@ -317,23 +317,23 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TString u = "34567";
TVector<std::pair<TRuntimeNode, TRuntimeNode>> someItems;
someItems.push_back(std::make_pair(TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true),
+ NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true),
TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValuePod((ui32)13), dtype2, env), true)));
+ NUdf::TUnboxedValuePod((ui32)13), dtype2, env), true)));
u = "878";
someItems.push_back(std::make_pair(TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true),
- TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)14), dtype2, env), true)));
+ NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true),
+ TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)14), dtype2, env), true)));
TDictLiteral* dict2 = TDictLiteral::Create(someItems.size(), someItems.data(), dict2Type, env);
UNIT_ASSERT_EQUAL(dict2->GetItemsCount(), 2);
UNIT_ASSERT_EQUAL(dict2->GetItem(0).first.GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(0).first.GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(0).first.GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
UNIT_ASSERT_EQUAL(dict2->GetItem(0).second.GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(0).second.GetNode()).AsValue().Get<ui32>(), 13);
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(0).second.GetNode()).AsValue().Get<ui32>(), 13);
UNIT_ASSERT_EQUAL(dict2->GetItem(1).first.GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(1).first.GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("878"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(1).first.GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("878"));
UNIT_ASSERT_EQUAL(dict2->GetItem(1).second.GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(1).second.GetNode()).AsValue().Get<ui32>(), 14);
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*dict2->GetItem(1).second.GetNode()).AsValue().Get<ui32>(), 14);
UNIT_ASSERT_EXCEPTION(TDictLiteral::Create(someItems.size(), someItems.data(), dict1Type, env), yexception);
@@ -344,7 +344,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TCallableType* ctype = TCallableType::Create("c1", dtype1, 0, nullptr, nullptr, env);
someDynItems.push_back(std::make_pair(
TRuntimeNode(TCallable::Create(0, nullptr, ctype, env), false),
- TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)123), dtype2, env), true)));
+ TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((ui32)123), dtype2, env), true)));
UNIT_ASSERT_NO_EXCEPTION(TDictLiteral::Create(someDynItems.size(), someDynItems.data(), dict2TypeDyn, env));
}
@@ -375,7 +375,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
TVector<TRuntimeNode> c2args;
c2args.push_back(TRuntimeNode(TDataLiteral::Create(
- NUdf::TUnboxedValuePod::Embedded("abc"), dtype1, env), true));
+ NUdf::TUnboxedValuePod::Embedded("abc"), dtype1, env), true));
c2args.push_back(TRuntimeNode(TCallable::Create(0, nullptr, ctype3, env), false));
TCallable* c2 = TCallable::Create(c2args.size(), c2args.data(), ctype2, env);
UNIT_ASSERT_EQUAL(c2->GetInputsCount(), 2);
@@ -428,7 +428,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
any1->SetItem(item1);
UNIT_ASSERT(any1->HasItem());
UNIT_ASSERT_EQUAL(any1->GetItem().GetNode()->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*any1->GetItem().GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
+ UNIT_ASSERT_EQUAL(static_cast<const TDataLiteral&>(*any1->GetItem().GetNode()).AsValue().AsStringRef(), NUdf::TStringRef::Of("34567"));
auto item2 = TRuntimeNode(TDataLiteral::Create(
NUdf::TUnboxedValuePod::Embedded(u), dtype1, env), true);
@@ -555,7 +555,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLNodeTest) {
auto tuple1type = TTupleType::Create(1, elements, env);
auto var1tuple = TVariantType::Create(tuple1type, env);
UNIT_ASSERT_EXCEPTION(TVariantLiteral::Create(TRuntimeNode(env.GetEmptyTuple(), true), 0, var1tuple, env), yexception);
- auto i32value = TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((i32)42), dt, env), true);
+ auto i32value = TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod((i32)42), dt, env), true);
UNIT_ASSERT_EXCEPTION(TVariantLiteral::Create(i32value, 23, var1tuple, env), yexception);
auto varValue = TVariantLiteral::Create(i32value, 0, var1tuple, env);
UNIT_ASSERT_VALUES_EQUAL(varValue->GetIndex(), 0);
diff --git a/ydb/library/yql/minikql/mkql_node_visitor.cpp b/ydb/library/yql/minikql/mkql_node_visitor.cpp
index 7c12252cf4..5a4ac8e479 100644
--- a/ydb/library/yql/minikql/mkql_node_visitor.cpp
+++ b/ydb/library/yql/minikql/mkql_node_visitor.cpp
@@ -156,11 +156,11 @@ void TThrowingNodeVisitor::Visit(TStreamType& node) {
ThrowUnexpectedNodeType();
}
-void TThrowingNodeVisitor::Visit(TFlowType& node) {
- Y_UNUSED(node);
- ThrowUnexpectedNodeType();
-}
-
+void TThrowingNodeVisitor::Visit(TFlowType& node) {
+ Y_UNUSED(node);
+ ThrowUnexpectedNodeType();
+}
+
void TThrowingNodeVisitor::Visit(TTaggedType& node) {
Y_UNUSED(node);
ThrowUnexpectedNodeType();
@@ -291,10 +291,10 @@ void TEmptyNodeVisitor::Visit(TStreamType& node) {
Y_UNUSED(node);
}
-void TEmptyNodeVisitor::Visit(TFlowType& node) {
- Y_UNUSED(node);
-}
-
+void TEmptyNodeVisitor::Visit(TFlowType& node) {
+ Y_UNUSED(node);
+}
+
void TEmptyNodeVisitor::Visit(TTaggedType& node) {
Y_UNUSED(node);
}
@@ -466,11 +466,11 @@ void TExploringNodeVisitor::Visit(TStreamType& node) {
AddChildNode(&node, *node.GetItemType());
}
-void TExploringNodeVisitor::Visit(TFlowType& node) {
- AddChildNode(&node, *node.GetType());
- AddChildNode(&node, *node.GetItemType());
-}
-
+void TExploringNodeVisitor::Visit(TFlowType& node) {
+ AddChildNode(&node, *node.GetType());
+ AddChildNode(&node, *node.GetItemType());
+}
+
void TExploringNodeVisitor::Visit(TTaggedType& node) {
AddChildNode(&node, *node.GetType());
AddChildNode(&node, *node.GetBaseType());
@@ -499,7 +499,7 @@ void TExploringNodeVisitor::Clear() {
ConsumersMap.clear();
}
-void TExploringNodeVisitor::Walk(TNode* root, const TTypeEnvironment& env, const std::vector<TNode*>& terminalNodes,
+void TExploringNodeVisitor::Walk(TNode* root, const TTypeEnvironment& env, const std::vector<TNode*>& terminalNodes,
bool buildConsumersMap, size_t nodesCountHint)
{
BuildConsumersMap = buildConsumersMap;
@@ -542,15 +542,15 @@ void TExploringNodeVisitor::Walk(TNode* root, const TTypeEnvironment& env, const
Stack = nullptr;
}
-const std::vector<TNode*>& TExploringNodeVisitor::GetNodes() {
+const std::vector<TNode*>& TExploringNodeVisitor::GetNodes() {
return NodeList;
}
const TExploringNodeVisitor::TNodesVec& TExploringNodeVisitor::GetConsumerNodes(TNode& node) {
Y_VERIFY(BuildConsumersMap);
- const auto consumers = ConsumersMap.find(&node);
- Y_VERIFY(consumers != ConsumersMap.cend());
- return consumers->second;
+ const auto consumers = ConsumersMap.find(&node);
+ Y_VERIFY(consumers != ConsumersMap.cend());
+ return consumers->second;
}
template <bool InPlace>
diff --git a/ydb/library/yql/minikql/mkql_node_visitor.h b/ydb/library/yql/minikql/mkql_node_visitor.h
index cb084255e3..f5bf76d520 100644
--- a/ydb/library/yql/minikql/mkql_node_visitor.h
+++ b/ydb/library/yql/minikql/mkql_node_visitor.h
@@ -6,7 +6,7 @@
#include <util/generic/hash_set.h>
#include <util/generic/vector.h>
#include <library/cpp/containers/stack_vector/stack_vec.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
namespace NMiniKQL {
@@ -43,7 +43,7 @@ public:
virtual void Visit(TTupleLiteral& node) = 0;
virtual void Visit(TVariantLiteral& node) = 0;
virtual void Visit(TStreamType& node) = 0;
- virtual void Visit(TFlowType& node) = 0;
+ virtual void Visit(TFlowType& node) = 0;
virtual void Visit(TTaggedType& node) = 0;
virtual void Visit(TBlockType& node) = 0;
};
@@ -79,7 +79,7 @@ public:
void Visit(TTupleLiteral& node) override;
void Visit(TVariantLiteral& node) override;
void Visit(TStreamType& node) override;
- void Visit(TFlowType& node) override;
+ void Visit(TFlowType& node) override;
void Visit(TTaggedType& node) override;
void Visit(TBlockType& node) override;
@@ -118,7 +118,7 @@ public:
void Visit(TTupleLiteral& node) override;
void Visit(TVariantLiteral& node) override;
void Visit(TStreamType& node) override;
- void Visit(TFlowType& node) override;
+ void Visit(TFlowType& node) override;
void Visit(TTaggedType& node) override;
void Visit(TBlockType& node) override;
};
@@ -156,13 +156,13 @@ public:
void Visit(TTupleLiteral& node) override;
void Visit(TVariantLiteral& node) override;
void Visit(TStreamType& node) override;
- void Visit(TFlowType& node) override;
+ void Visit(TFlowType& node) override;
void Visit(TTaggedType& node) override;
void Visit(TBlockType& node) override;
- void Walk(TNode* root, const TTypeEnvironment& env, const std::vector<TNode*>& terminalNodes = std::vector<TNode*>(),
+ void Walk(TNode* root, const TTypeEnvironment& env, const std::vector<TNode*>& terminalNodes = std::vector<TNode*>(),
bool buildConsumersMap = false, size_t nodesCountHint = 0);
- const std::vector<TNode*>& GetNodes();
+ const std::vector<TNode*>& GetNodes();
const TNodesVec& GetConsumerNodes(TNode& node);
void Clear();
@@ -170,14 +170,14 @@ private:
void AddChildNode(TNode* parent, TNode& child);
private:
- std::vector<TNode*> NodeList;
- std::vector<TNode*>* Stack = nullptr;
+ std::vector<TNode*> NodeList;
+ std::vector<TNode*>* Stack = nullptr;
bool BuildConsumersMap = false;
- std::unordered_map<TNode*, TNodesVec> ConsumersMap;
+ std::unordered_map<TNode*, TNodesVec> ConsumersMap;
};
class TTypeEnvironment;
-typedef std::function<TRuntimeNode (TCallable& callable, const TTypeEnvironment& env)> TCallableVisitFunc;
+typedef std::function<TRuntimeNode (TCallable& callable, const TTypeEnvironment& env)> TCallableVisitFunc;
typedef std::function<TCallableVisitFunc (const TInternName& name)> TCallableVisitFuncProvider;
TRuntimeNode SinglePassVisitCallables(TRuntimeNode root, TExploringNodeVisitor& explorer,
diff --git a/ydb/library/yql/minikql/mkql_opt_literal.cpp b/ydb/library/yql/minikql/mkql_opt_literal.cpp
index 686d778e17..832a87ea80 100644
--- a/ydb/library/yql/minikql/mkql_opt_literal.cpp
+++ b/ydb/library/yql/minikql/mkql_opt_literal.cpp
@@ -27,7 +27,7 @@ TNode* LiteralAddMember(
TStructLiteralBuilder resultBuilder(env);
TDataLiteral* positionData = AS_VALUE(TDataLiteral, position);
- const ui32 positionValue = positionData->AsValue().Get<ui32>();
+ const ui32 positionValue = positionData->AsValue().Get<ui32>();
MKQL_ENSURE(positionValue <= oldStruct.GetType()->GetMembersCount(), "Bad member index");
for (ui32 i = 0; i < positionValue; ++i) {
@@ -50,7 +50,7 @@ TNode* LiteralRemoveMember(
TStructLiteralBuilder resultBuilder(env);
TDataLiteral* positionData = AS_VALUE(TDataLiteral, position);
- const ui32 positionValue = positionData->AsValue().Get<ui32>();
+ const ui32 positionValue = positionData->AsValue().Get<ui32>();
MKQL_ENSURE(positionValue < oldStruct.GetType()->GetMembersCount(), "Bad member index");
for (ui32 i = 0; i < positionValue; ++i) {
@@ -73,7 +73,7 @@ TRuntimeNode OptimizeIf(TCallable& callable, const TTypeEnvironment& env) {
auto elseInput = callable.GetInput(2);
if (predicateInput.HasValue()) {
TDataLiteral* data = AS_VALUE(TDataLiteral, predicateInput);
- const bool predicateValue = data->AsValue().Get<bool>();
+ const bool predicateValue = data->AsValue().Get<bool>();
return predicateValue ? thenInput : elseInput;
}
@@ -90,7 +90,7 @@ TRuntimeNode OptimizeSize(TCallable& callable, const TTypeEnvironment& env) {
auto dataInput = callable.GetInput(0);
if (dataInput.HasValue()) {
TDataLiteral* value = AS_VALUE(TDataLiteral, dataInput);
- return TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod((ui32)value->AsValue().AsStringRef().Size()), NUdf::EDataSlot::Uint32, env), true);
+ return TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod((ui32)value->AsValue().AsStringRef().Size()), NUdf::EDataSlot::Uint32, env), true);
}
return TRuntimeNode(&callable, false);
@@ -150,7 +150,7 @@ TRuntimeNode OptimizeMember(TCallable& callable, const TTypeEnvironment& env) {
auto position = callable.GetInput(1);
TDataLiteral* positionData = AS_VALUE(TDataLiteral, position);
- const ui32 positionValue = positionData->AsValue().Get<ui32>();
+ const ui32 positionValue = positionData->AsValue().Get<ui32>();
MKQL_ENSURE(positionValue < value->GetValuesCount(), "Bad member index");
return value->GetValue(positionValue);
@@ -160,25 +160,25 @@ TRuntimeNode OptimizeMember(TCallable& callable, const TTypeEnvironment& env) {
}
TRuntimeNode OptimizeFilter(TCallable& callable, const TTypeEnvironment& env) {
- if (callable.GetInputsCount() == 3U) {
- auto listInput = callable.GetInput(0);
- if (!listInput.GetStaticType()->IsList()) {
- return TRuntimeNode(&callable, false);
- }
-
- auto listType = static_cast<TListType*>(listInput.GetStaticType());
- auto predicateInput = callable.GetInput(2);
- if (predicateInput.HasValue()) {
- auto predicate = predicateInput.GetValue();
- MKQL_ENSURE(predicate->GetType()->IsData(), "Expected data");
-
- const auto& data = static_cast<const TDataLiteral&>(*predicate);
- const bool predicateValue = data.AsValue().Get<bool>();
- if (predicateValue) {
- return listInput;
- } else {
- return TRuntimeNode(TListLiteral::Create(nullptr, 0, listType, env), true);
- }
+ if (callable.GetInputsCount() == 3U) {
+ auto listInput = callable.GetInput(0);
+ if (!listInput.GetStaticType()->IsList()) {
+ return TRuntimeNode(&callable, false);
+ }
+
+ auto listType = static_cast<TListType*>(listInput.GetStaticType());
+ auto predicateInput = callable.GetInput(2);
+ if (predicateInput.HasValue()) {
+ auto predicate = predicateInput.GetValue();
+ MKQL_ENSURE(predicate->GetType()->IsData(), "Expected data");
+
+ const auto& data = static_cast<const TDataLiteral&>(*predicate);
+ const bool predicateValue = data.AsValue().Get<bool>();
+ if (predicateValue) {
+ return listInput;
+ } else {
+ return TRuntimeNode(TListLiteral::Create(nullptr, 0, listType, env), true);
+ }
}
}
@@ -203,15 +203,15 @@ TRuntimeNode OptimizeMap(TCallable& callable, const TTypeEnvironment& env) {
}
TRuntimeNode OptimizeFlatMap(TCallable& callable, const TTypeEnvironment& env) {
- MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected 3 or more arguments");
+ MKQL_ENSURE(callable.GetInputsCount() > 2U, "Expected 3 or more arguments");
- const auto returnType = callable.GetType()->GetReturnType();
- if (!returnType->IsList() || callable.GetInputsCount() > 3U) {
+ const auto returnType = callable.GetType()->GetReturnType();
+ if (!returnType->IsList() || callable.GetInputsCount() > 3U) {
return TRuntimeNode(&callable, false);
}
- const auto listType = static_cast<TListType*>(returnType);
- const auto newItemInput = callable.GetInput(2);
+ const auto listType = static_cast<TListType*>(returnType);
+ const auto newItemInput = callable.GetInput(2);
if (listType->GetItemType()->IsVoid() && newItemInput.HasValue()) {
if (newItemInput.GetStaticType()->IsList()) {
TListLiteral* list = AS_VALUE(TListLiteral, newItemInput);
@@ -254,7 +254,7 @@ TRuntimeNode OptimizeExists(TCallable& callable, const TTypeEnvironment& env) {
auto optionalInput = callable.GetInput(0);
if (optionalInput.HasValue()) {
- const bool has = AS_VALUE(TOptionalLiteral, optionalInput)->HasItem();
+ const bool has = AS_VALUE(TOptionalLiteral, optionalInput)->HasItem();
return TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod(has), NUdf::EDataSlot::Bool, env), true);
}
@@ -269,7 +269,7 @@ TRuntimeNode OptimizeNth(TCallable& callable, const TTypeEnvironment& env) {
if (tupleInput.HasValue() && tupleInput.GetStaticType()->IsTuple()) {
auto tuple = tupleInput.GetValue();
auto indexData = AS_VALUE(TDataLiteral, callable.GetInput(1));
- const ui32 index = indexData->AsValue().Get<ui32>();
+ const ui32 index = indexData->AsValue().Get<ui32>();
const auto& value = static_cast<const TTupleLiteral&>(*tuple);
MKQL_ENSURE(index < value.GetValuesCount(), "Index out of range");
diff --git a/ydb/library/yql/minikql/mkql_opt_literal_ut.cpp b/ydb/library/yql/minikql/mkql_opt_literal_ut.cpp
index 1d7d81b631..c1c0a5b79d 100644
--- a/ydb/library/yql/minikql/mkql_opt_literal_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_opt_literal_ut.cpp
@@ -15,12 +15,12 @@ TRuntimeNode MakeVoidCallable(TProgramBuilder& pgmBuilder) {
Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
Y_UNIT_TEST(TestIfPredicateTrue) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
- auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(true), MakeVoidCallable(pgmBuilder), pgmBuilder.NewVoid()));
+ auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(true), MakeVoidCallable(pgmBuilder), pgmBuilder.NewVoid()));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::List);
@@ -33,12 +33,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestIfPredicateSame) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
- auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(true), MakeVoidCallable(pgmBuilder), MakeVoidCallable(pgmBuilder)));
+ auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(true), MakeVoidCallable(pgmBuilder), MakeVoidCallable(pgmBuilder)));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::List);
@@ -51,12 +51,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestIfPredicateFalse) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
- auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(false), pgmBuilder.NewVoid(), MakeVoidCallable(pgmBuilder)));
+ auto pgmReturn = pgmBuilder.AsList(pgmBuilder.If(pgmBuilder.NewDataLiteral(false), pgmBuilder.NewVoid(), MakeVoidCallable(pgmBuilder)));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::List);
@@ -69,7 +69,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestSize) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
@@ -82,7 +82,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestLength) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
@@ -96,7 +96,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestAddMember) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
@@ -109,22 +109,22 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
auto struct2 = pgmBuilder.NewEmptyStruct();
struct2 = pgmBuilder.AddMember(struct2, "x", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
- struct2 = pgmBuilder.AddMember(struct2, "z", pgmBuilder.NewDataLiteral<ui32>(11));
+ struct2 = pgmBuilder.AddMember(struct2, "z", pgmBuilder.NewDataLiteral<ui32>(11));
pgm = LiteralPropagationOptimization(struct2, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::Struct);
UNIT_ASSERT_EQUAL(static_cast<TStructLiteral&>(*pgm).GetValuesCount(), 2);
auto struct3 = pgmBuilder.NewEmptyStruct();
struct3 = pgmBuilder.AddMember(struct3, "x", pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
- struct3 = pgmBuilder.AddMember(struct3, "z", pgmBuilder.NewDataLiteral<ui32>(11));
- struct3 = pgmBuilder.AddMember(struct3, "y", pgmBuilder.NewDataLiteral<ui64>(777));
+ struct3 = pgmBuilder.AddMember(struct3, "z", pgmBuilder.NewDataLiteral<ui32>(11));
+ struct3 = pgmBuilder.AddMember(struct3, "y", pgmBuilder.NewDataLiteral<ui64>(777));
pgm = LiteralPropagationOptimization(struct3, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::Struct);
UNIT_ASSERT_EQUAL(static_cast<TStructLiteral&>(*pgm).GetValuesCount(), 3);
}
Y_UNIT_TEST(TestMember) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
@@ -138,20 +138,20 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestFilterPredicateTrue) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> items;
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
auto list = pgmBuilder.AsList(items);
auto pgmReturn = pgmBuilder.Filter(list,
[&](TRuntimeNode item) {
Y_UNUSED(item);
- return pgmBuilder.NewDataLiteral(true);
+ return pgmBuilder.NewDataLiteral(true);
});
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
@@ -160,20 +160,20 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestFilterPredicateFalse) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> items;
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
auto list = pgmBuilder.AsList(items);
auto pgmReturn = pgmBuilder.Filter(list,
[&](TRuntimeNode item) {
Y_UNUSED(item);
- return pgmBuilder.NewDataLiteral(false);
+ return pgmBuilder.NewDataLiteral(false);
});
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
@@ -182,14 +182,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestMapToVoid) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> items;
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
auto list = pgmBuilder.AsList(items);
auto pgmReturn = pgmBuilder.Map(list,
@@ -204,14 +204,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestFlatMapToLiteralListOfVoid) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> items;
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
auto list = pgmBuilder.AsList(items);
auto pgmReturn = pgmBuilder.FlatMap(list,
@@ -226,14 +226,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestFlatMapToLiteralListOfVoid_Optional) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> items;
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
- items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(1));
+ items.push_back(pgmBuilder.NewDataLiteral<ui32>(2));
auto list = pgmBuilder.AsList(items);
auto pgmReturn = pgmBuilder.FlatMap(list,
@@ -248,52 +248,52 @@ Y_UNIT_TEST_SUITE(TMiniKQLLPOTest) {
}
Y_UNIT_TEST(TestLiteralCoalesceExist) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
- auto pgmReturn = pgmBuilder.Coalesce(pgmBuilder.NewOptional(pgmBuilder.NewDataLiteral<ui32>(1)),
- pgmBuilder.NewDataLiteral<ui32>(2));
+ auto pgmReturn = pgmBuilder.Coalesce(pgmBuilder.NewOptional(pgmBuilder.NewDataLiteral<ui32>(1)),
+ pgmBuilder.NewDataLiteral<ui32>(2));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<ui32>(), 1);
+ UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<ui32>(), 1);
}
Y_UNIT_TEST(TestLiteralCoalesceNotExist) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
auto pgmReturn = pgmBuilder.Coalesce(pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id),
- pgmBuilder.NewDataLiteral<ui32>(2));
+ pgmBuilder.NewDataLiteral<ui32>(2));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<ui32>(), 2);
+ UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<ui32>(), 2);
}
Y_UNIT_TEST(TestLiteralExists) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
- auto pgmReturn = pgmBuilder.Exists(pgmBuilder.NewOptional(pgmBuilder.NewDataLiteral<ui32>(1)));
+ auto pgmReturn = pgmBuilder.Exists(pgmBuilder.NewOptional(pgmBuilder.NewDataLiteral<ui32>(1)));
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
UNIT_ASSERT_EQUAL(pgm->GetType()->GetKind(), TType::EKind::Data);
- UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<bool>(), true);
+ UNIT_ASSERT_EQUAL(static_cast<TDataLiteral&>(*pgm).AsValue().Get<bool>(), true);
}
Y_UNIT_TEST(TestNth) {
- auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
+ auto functionRegistry = CreateFunctionRegistry(IBuiltinFunctionRegistry::TPtr());
TScopedAlloc alloc;
TTypeEnvironment env(alloc);
TProgramBuilder pgmBuilder(env, *functionRegistry);
TVector<TRuntimeNode> elements(2);
elements[0] = pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("34");
- elements[1] = pgmBuilder.NewDataLiteral<ui32>(56);
+ elements[1] = pgmBuilder.NewDataLiteral<ui32>(56);
auto tuple = pgmBuilder.NewTuple(elements);
auto pgmReturn = pgmBuilder.Nth(tuple, 1);
auto pgm = LiteralPropagationOptimization(pgmReturn, env, true).GetNode();
diff --git a/ydb/library/yql/minikql/mkql_program_builder.cpp b/ydb/library/yql/minikql/mkql_program_builder.cpp
index b13e648e6c..47ae6e4c8f 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_program_builder.cpp
@@ -69,178 +69,178 @@ void EnsureScriptSpecificTypes(
TCallableType* funcType,
const TTypeEnvironment& env)
{
- switch (scriptType) {
- case EScriptType::Python:
+ switch (scriptType) {
+ case EScriptType::Python:
case EScriptType::Python2:
case EScriptType::Python3:
- case EScriptType::Lua:
- case EScriptType::ArcPython:
+ case EScriptType::Lua:
+ case EScriptType::ArcPython:
case EScriptType::ArcPython2:
case EScriptType::ArcPython3:
case EScriptType::CustomPython:
case EScriptType::CustomPython2:
case EScriptType::CustomPython3:
- return TPythonTypeChecker().Walk(funcType, env);
+ return TPythonTypeChecker().Walk(funcType, env);
case EScriptType::Javascript:
return TJavascriptTypeChecker().Walk(funcType, env);
- default:
+ default:
MKQL_ENSURE(false, "Unknown script type " << static_cast<ui32>(scriptType));
}
}
-ui32 GetNumericSchemeTypeLevel(NUdf::TDataTypeId typeId) {
- switch (typeId) {
- case NUdf::TDataType<ui8>::Id:
- return 0;
- case NUdf::TDataType<i8>::Id:
- return 1;
- case NUdf::TDataType<ui16>::Id:
- return 2;
- case NUdf::TDataType<i16>::Id:
- return 3;
- case NUdf::TDataType<ui32>::Id:
- return 4;
- case NUdf::TDataType<i32>::Id:
- return 5;
- case NUdf::TDataType<ui64>::Id:
- return 6;
- case NUdf::TDataType<i64>::Id:
- return 7;
- case NUdf::TDataType<float>::Id:
- return 8;
- case NUdf::TDataType<double>::Id:
- return 9;
- default:
- ythrow yexception() << "Unknown numeric type: " << typeId;
- }
-}
-
-NUdf::TDataTypeId GetNumericSchemeTypeByLevel(ui32 level) {
- switch (level) {
- case 0:
- return NUdf::TDataType<ui8>::Id;
- case 1:
- return NUdf::TDataType<i8>::Id;
- case 2:
- return NUdf::TDataType<ui16>::Id;
- case 3:
- return NUdf::TDataType<i16>::Id;
- case 4:
- return NUdf::TDataType<ui32>::Id;
- case 5:
- return NUdf::TDataType<i32>::Id;
- case 6:
- return NUdf::TDataType<ui64>::Id;
- case 7:
- return NUdf::TDataType<i64>::Id;
- case 8:
- return NUdf::TDataType<float>::Id;
- case 9:
- return NUdf::TDataType<double>::Id;
- default:
- ythrow yexception() << "Unknown numeric level: " << level;
- }
-}
-
-NUdf::TDataTypeId MakeNumericDataSuperType(NUdf::TDataTypeId typeId1, NUdf::TDataTypeId typeId2) {
- return typeId1 == typeId2 ? typeId1 :
- GetNumericSchemeTypeByLevel(std::max(GetNumericSchemeTypeLevel(typeId1), GetNumericSchemeTypeLevel(typeId2)));
-}
-
-template<bool IsFilter>
-bool CollectOptionalElements(const TType* type, std::vector<std::string_view>& test, std::vector<std::pair<std::string_view, TType*>>& output) {
- const auto structType = AS_TYPE(TStructType, type);
- test.reserve(structType->GetMembersCount());
- output.reserve(structType->GetMembersCount());
- bool multiOptional = false;
- for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
- output.emplace_back(structType->GetMemberName(i), structType->GetMemberType(i));
- auto& memberType = output.back().second;
- if (memberType->IsOptional()) {
- test.emplace_back(output.back().first);
- if constexpr (IsFilter) {
- memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
- multiOptional = multiOptional || memberType->IsOptional();
- }
- }
- }
-
- return multiOptional;
-}
-
-template<bool IsFilter>
-bool CollectOptionalElements(const TType* type, std::vector<ui32>& test, std::vector<TType*>& output) {
- const auto typleType = AS_TYPE(TTupleType, type);
- test.reserve(typleType->GetElementsCount());
- output.reserve(typleType->GetElementsCount());
- bool multiOptional = false;
- for (ui32 i = 0; i < typleType->GetElementsCount(); ++i) {
- output.emplace_back(typleType->GetElementType(i));
- auto& elementType = output.back();
- if (elementType->IsOptional()) {
- test.emplace_back(i);
- if constexpr (IsFilter) {
- elementType = AS_TYPE(TOptionalType, elementType)->GetItemType();
- multiOptional = multiOptional || elementType->IsOptional();
- }
- }
- }
-
- return multiOptional;
-}
-
-bool ReduceOptionalElements(const TType* type, const TArrayRef<const std::string_view>& test, std::vector<std::pair<std::string_view, TType*>>& output) {
- const auto structType = AS_TYPE(TStructType, type);
- output.reserve(structType->GetMembersCount());
- for (ui32 i = 0U; i < structType->GetMembersCount(); ++i) {
- output.emplace_back(structType->GetMemberName(i), structType->GetMemberType(i));
- }
-
- bool multiOptional = false;
- for (const auto& member : test) {
- auto& memberType = output[structType->GetMemberIndex(member)].second;
- MKQL_ENSURE(memberType->IsOptional(), "Required optional column type");
- memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
- multiOptional = multiOptional || memberType->IsOptional();
- }
-
- return multiOptional;
-}
-
-bool ReduceOptionalElements(const TType* type, const TArrayRef<const ui32>& test, std::vector<TType*>& output) {
- const auto typleType = AS_TYPE(TTupleType, type);
- output.reserve(typleType->GetElementsCount());
- for (ui32 i = 0U; i < typleType->GetElementsCount(); ++i) {
- output.emplace_back(typleType->GetElementType(i));
- }
-
- bool multiOptional = false;
- for (const auto& member : test) {
- auto& memberType = output[member];
- MKQL_ENSURE(memberType->IsOptional(), "Required optional column type");
- memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
- multiOptional = multiOptional || memberType->IsOptional();
- }
-
- return multiOptional;
-}
-
+ui32 GetNumericSchemeTypeLevel(NUdf::TDataTypeId typeId) {
+ switch (typeId) {
+ case NUdf::TDataType<ui8>::Id:
+ return 0;
+ case NUdf::TDataType<i8>::Id:
+ return 1;
+ case NUdf::TDataType<ui16>::Id:
+ return 2;
+ case NUdf::TDataType<i16>::Id:
+ return 3;
+ case NUdf::TDataType<ui32>::Id:
+ return 4;
+ case NUdf::TDataType<i32>::Id:
+ return 5;
+ case NUdf::TDataType<ui64>::Id:
+ return 6;
+ case NUdf::TDataType<i64>::Id:
+ return 7;
+ case NUdf::TDataType<float>::Id:
+ return 8;
+ case NUdf::TDataType<double>::Id:
+ return 9;
+ default:
+ ythrow yexception() << "Unknown numeric type: " << typeId;
+ }
+}
+
+NUdf::TDataTypeId GetNumericSchemeTypeByLevel(ui32 level) {
+ switch (level) {
+ case 0:
+ return NUdf::TDataType<ui8>::Id;
+ case 1:
+ return NUdf::TDataType<i8>::Id;
+ case 2:
+ return NUdf::TDataType<ui16>::Id;
+ case 3:
+ return NUdf::TDataType<i16>::Id;
+ case 4:
+ return NUdf::TDataType<ui32>::Id;
+ case 5:
+ return NUdf::TDataType<i32>::Id;
+ case 6:
+ return NUdf::TDataType<ui64>::Id;
+ case 7:
+ return NUdf::TDataType<i64>::Id;
+ case 8:
+ return NUdf::TDataType<float>::Id;
+ case 9:
+ return NUdf::TDataType<double>::Id;
+ default:
+ ythrow yexception() << "Unknown numeric level: " << level;
+ }
+}
+
+NUdf::TDataTypeId MakeNumericDataSuperType(NUdf::TDataTypeId typeId1, NUdf::TDataTypeId typeId2) {
+ return typeId1 == typeId2 ? typeId1 :
+ GetNumericSchemeTypeByLevel(std::max(GetNumericSchemeTypeLevel(typeId1), GetNumericSchemeTypeLevel(typeId2)));
+}
+
+template<bool IsFilter>
+bool CollectOptionalElements(const TType* type, std::vector<std::string_view>& test, std::vector<std::pair<std::string_view, TType*>>& output) {
+ const auto structType = AS_TYPE(TStructType, type);
+ test.reserve(structType->GetMembersCount());
+ output.reserve(structType->GetMembersCount());
+ bool multiOptional = false;
+ for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
+ output.emplace_back(structType->GetMemberName(i), structType->GetMemberType(i));
+ auto& memberType = output.back().second;
+ if (memberType->IsOptional()) {
+ test.emplace_back(output.back().first);
+ if constexpr (IsFilter) {
+ memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
+ multiOptional = multiOptional || memberType->IsOptional();
+ }
+ }
+ }
+
+ return multiOptional;
+}
+
+template<bool IsFilter>
+bool CollectOptionalElements(const TType* type, std::vector<ui32>& test, std::vector<TType*>& output) {
+ const auto typleType = AS_TYPE(TTupleType, type);
+ test.reserve(typleType->GetElementsCount());
+ output.reserve(typleType->GetElementsCount());
+ bool multiOptional = false;
+ for (ui32 i = 0; i < typleType->GetElementsCount(); ++i) {
+ output.emplace_back(typleType->GetElementType(i));
+ auto& elementType = output.back();
+ if (elementType->IsOptional()) {
+ test.emplace_back(i);
+ if constexpr (IsFilter) {
+ elementType = AS_TYPE(TOptionalType, elementType)->GetItemType();
+ multiOptional = multiOptional || elementType->IsOptional();
+ }
+ }
+ }
+
+ return multiOptional;
+}
+
+bool ReduceOptionalElements(const TType* type, const TArrayRef<const std::string_view>& test, std::vector<std::pair<std::string_view, TType*>>& output) {
+ const auto structType = AS_TYPE(TStructType, type);
+ output.reserve(structType->GetMembersCount());
+ for (ui32 i = 0U; i < structType->GetMembersCount(); ++i) {
+ output.emplace_back(structType->GetMemberName(i), structType->GetMemberType(i));
+ }
+
+ bool multiOptional = false;
+ for (const auto& member : test) {
+ auto& memberType = output[structType->GetMemberIndex(member)].second;
+ MKQL_ENSURE(memberType->IsOptional(), "Required optional column type");
+ memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
+ multiOptional = multiOptional || memberType->IsOptional();
+ }
+
+ return multiOptional;
+}
+
+bool ReduceOptionalElements(const TType* type, const TArrayRef<const ui32>& test, std::vector<TType*>& output) {
+ const auto typleType = AS_TYPE(TTupleType, type);
+ output.reserve(typleType->GetElementsCount());
+ for (ui32 i = 0U; i < typleType->GetElementsCount(); ++i) {
+ output.emplace_back(typleType->GetElementType(i));
+ }
+
+ bool multiOptional = false;
+ for (const auto& member : test) {
+ auto& memberType = output[member];
+ MKQL_ENSURE(memberType->IsOptional(), "Required optional column type");
+ memberType = AS_TYPE(TOptionalType, memberType)->GetItemType();
+ multiOptional = multiOptional || memberType->IsOptional();
+ }
+
+ return multiOptional;
+}
+
} // namespace
-std::string_view ScriptTypeAsStr(EScriptType type) {
+std::string_view ScriptTypeAsStr(EScriptType type) {
switch (type) {
#define MKQL_SCRIPT_TYPE_CASE(name, value, ...) \
- case EScriptType::name: return std::string_view(#name);
+ case EScriptType::name: return std::string_view(#name);
MKQL_SCRIPT_TYPES(MKQL_SCRIPT_TYPE_CASE)
#undef MKQL_SCRIPT_TYPE_CASE
} // switch
- return std::string_view("Unknown");
+ return std::string_view("Unknown");
}
-EScriptType ScriptTypeFromStr(std::string_view str) {
+EScriptType ScriptTypeFromStr(std::string_view str) {
TString lowerStr = TString(str);
lowerStr.to_lower();
#define MKQL_SCRIPT_TYPE_FROM_STR(name, value, lowerName) \
@@ -276,9 +276,9 @@ void EnsureDataOrOptionalOfData(TRuntimeNode node) {
->GetItemType()->IsData(), "Expected data or optional of data");
}
-TProgramBuilder::TProgramBuilder(const TTypeEnvironment& env, const IFunctionRegistry& functionRegistry, bool voidWithEffects)
- : Env(env), FunctionRegistry(functionRegistry), VoidWithEffects(voidWithEffects)
-{}
+TProgramBuilder::TProgramBuilder(const TTypeEnvironment& env, const IFunctionRegistry& functionRegistry, bool voidWithEffects)
+ : Env(env), FunctionRegistry(functionRegistry), VoidWithEffects(voidWithEffects)
+{}
const TTypeEnvironment& TProgramBuilder::GetTypeEnvironment() const {
return Env;
@@ -288,81 +288,81 @@ const IFunctionRegistry& TProgramBuilder::GetFunctionRegistry() const {
return FunctionRegistry;
}
-TType* TProgramBuilder::ChooseCommonType(TType* type1, TType* type2) {
- bool isOptional1, isOptional2;
- const auto data1 = UnpackOptionalData(type1, isOptional1);
- const auto data2 = UnpackOptionalData(type2, isOptional2);
- if (data1->IsSameType(*data2)) {
- return isOptional1 ? type1 : type2;
- }
-
- MKQL_ENSURE(!
- ((NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features | NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features) & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)),
- "Not same date types: " << *type1 << " and " << *type2
- );
-
- const auto data = NewDataType(MakeNumericDataSuperType(data1->GetSchemeType(), data2->GetSchemeType()));
- return isOptional1 || isOptional2 ? NewOptionalType(data) : data;
-}
-
-TType* TProgramBuilder::BuildArithmeticCommonType(TType* type1, TType* type2) {
- bool isOptional1, isOptional2;
- const auto data1 = UnpackOptionalData(type1, isOptional1);
- const auto data2 = UnpackOptionalData(type2, isOptional2);
- const bool isOptional = isOptional1 || isOptional2;
- if (data1->GetSchemeType() == NUdf::TDataType<NUdf::TInterval>::Id) {
- return NewOptionalType(NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features & NUdf::EDataTypeFeatures::IntegralType ? data1 : data2);
- } else if (data2->GetSchemeType() == NUdf::TDataType<NUdf::TInterval>::Id) {
- return NewOptionalType(NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features & NUdf::EDataTypeFeatures::IntegralType ? data2 : data1);
- } else if (
- NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType) &&
- NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)
- ) {
- const auto used = NewDataType(NUdf::EDataSlot::Interval);
- return isOptional ? NewOptionalType(used) : used;
- } else if (data1->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- MKQL_ENSURE(data1->IsSameType(*data2), "Must be same type.");
- return isOptional ? NewOptionalType(data1) : data2;
- }
-
- const auto data = NewDataType(MakeNumericDataSuperType(data1->GetSchemeType(), data2->GetSchemeType()));
- return isOptional ? NewOptionalType(data) : data;
-}
-
+TType* TProgramBuilder::ChooseCommonType(TType* type1, TType* type2) {
+ bool isOptional1, isOptional2;
+ const auto data1 = UnpackOptionalData(type1, isOptional1);
+ const auto data2 = UnpackOptionalData(type2, isOptional2);
+ if (data1->IsSameType(*data2)) {
+ return isOptional1 ? type1 : type2;
+ }
+
+ MKQL_ENSURE(!
+ ((NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features | NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features) & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)),
+ "Not same date types: " << *type1 << " and " << *type2
+ );
+
+ const auto data = NewDataType(MakeNumericDataSuperType(data1->GetSchemeType(), data2->GetSchemeType()));
+ return isOptional1 || isOptional2 ? NewOptionalType(data) : data;
+}
+
+TType* TProgramBuilder::BuildArithmeticCommonType(TType* type1, TType* type2) {
+ bool isOptional1, isOptional2;
+ const auto data1 = UnpackOptionalData(type1, isOptional1);
+ const auto data2 = UnpackOptionalData(type2, isOptional2);
+ const bool isOptional = isOptional1 || isOptional2;
+ if (data1->GetSchemeType() == NUdf::TDataType<NUdf::TInterval>::Id) {
+ return NewOptionalType(NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features & NUdf::EDataTypeFeatures::IntegralType ? data1 : data2);
+ } else if (data2->GetSchemeType() == NUdf::TDataType<NUdf::TInterval>::Id) {
+ return NewOptionalType(NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features & NUdf::EDataTypeFeatures::IntegralType ? data2 : data1);
+ } else if (
+ NUdf::GetDataTypeInfo(*data1->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType) &&
+ NUdf::GetDataTypeInfo(*data2->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::DateType | NUdf::EDataTypeFeatures::TzDateType)
+ ) {
+ const auto used = NewDataType(NUdf::EDataSlot::Interval);
+ return isOptional ? NewOptionalType(used) : used;
+ } else if (data1->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ MKQL_ENSURE(data1->IsSameType(*data2), "Must be same type.");
+ return isOptional ? NewOptionalType(data1) : data2;
+ }
+
+ const auto data = NewDataType(MakeNumericDataSuperType(data1->GetSchemeType(), data2->GetSchemeType()));
+ return isOptional ? NewOptionalType(data) : data;
+}
+
TRuntimeNode TProgramBuilder::Arg(TType* type) const {
- TCallableBuilder builder(Env, __func__, type, true);
+ TCallableBuilder builder(Env, __func__, type, true);
+ return TRuntimeNode(builder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideFlowArg(TType* type) const {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ TCallableBuilder builder(Env, __func__, type, true);
return TRuntimeNode(builder.Build(), false);
}
-TRuntimeNode TProgramBuilder::WideFlowArg(TType* type) const {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- TCallableBuilder builder(Env, __func__, type, true);
- return TRuntimeNode(builder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Member(TRuntimeNode structObj, const std::string_view& memberName) {
- bool isOptional;
- const auto type = AS_TYPE(TStructType, UnpackOptional(structObj.GetStaticType(), isOptional));
- const auto memberIndex = type->GetMemberIndex(memberName);
- auto memberType = type->GetMemberType(memberIndex);
+TRuntimeNode TProgramBuilder::Member(TRuntimeNode structObj, const std::string_view& memberName) {
+ bool isOptional;
+ const auto type = AS_TYPE(TStructType, UnpackOptional(structObj.GetStaticType(), isOptional));
+ const auto memberIndex = type->GetMemberIndex(memberName);
+ auto memberType = type->GetMemberType(memberIndex);
if (isOptional && !memberType->IsOptional() && !memberType->IsNull()) {
- memberType = NewOptionalType(memberType);
+ memberType = NewOptionalType(memberType);
}
- TCallableBuilder callableBuilder(Env, __func__, memberType);
+ TCallableBuilder callableBuilder(Env, __func__, memberType);
callableBuilder.Add(structObj);
- callableBuilder.Add(NewDataLiteral<ui32>(memberIndex));
+ callableBuilder.Add(NewDataLiteral<ui32>(memberIndex));
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Element(TRuntimeNode structObj, const std::string_view& memberName) {
- return Member(structObj, memberName);
-}
-
-TRuntimeNode TProgramBuilder::AddMember(TRuntimeNode structObj, const std::string_view& memberName, TRuntimeNode memberValue) {
+TRuntimeNode TProgramBuilder::Element(TRuntimeNode structObj, const std::string_view& memberName) {
+ return Member(structObj, memberName);
+}
+
+TRuntimeNode TProgramBuilder::AddMember(TRuntimeNode structObj, const std::string_view& memberName, TRuntimeNode memberValue) {
auto oldType = structObj.GetStaticType();
MKQL_ENSURE(oldType->IsStruct(), "Expected struct");
@@ -378,10 +378,10 @@ TRuntimeNode TProgramBuilder::AddMember(TRuntimeNode structObj, const std::strin
for (ui32 i = 0, e = newType->GetMembersCount(); i < e; ++i) {
if (newType->GetMemberName(i) == memberName) {
// insert at position i in the struct
- TCallableBuilder callableBuilder(Env, __func__, newType);
+ TCallableBuilder callableBuilder(Env, __func__, newType);
callableBuilder.Add(structObj);
callableBuilder.Add(memberValue);
- callableBuilder.Add(NewDataLiteral<ui32>(i));
+ callableBuilder.Add(NewDataLiteral<ui32>(i));
return TRuntimeNode(callableBuilder.Build(), false);
}
}
@@ -389,7 +389,7 @@ TRuntimeNode TProgramBuilder::AddMember(TRuntimeNode structObj, const std::strin
Y_FAIL();
}
-TRuntimeNode TProgramBuilder::RemoveMember(TRuntimeNode structObj, const std::string_view& memberName, bool forced) {
+TRuntimeNode TProgramBuilder::RemoveMember(TRuntimeNode structObj, const std::string_view& memberName, bool forced) {
auto oldType = structObj.GetStaticType();
MKQL_ENSURE(oldType->IsStruct(), "Expected struct");
@@ -398,7 +398,7 @@ TRuntimeNode TProgramBuilder::RemoveMember(TRuntimeNode structObj, const std::st
TStructTypeBuilder newTypeBuilder(Env);
newTypeBuilder.Reserve(oldTypeDetailed.GetMembersCount() - 1);
- std::optional<ui32> memberIndex;
+ std::optional<ui32> memberIndex;
for (ui32 i = 0, e = oldTypeDetailed.GetMembersCount(); i < e; ++i) {
if (oldTypeDetailed.GetMemberName(i) != memberName) {
newTypeBuilder.Add(oldTypeDetailed.GetMemberName(i), oldTypeDetailed.GetMemberType(i));
@@ -407,17 +407,17 @@ TRuntimeNode TProgramBuilder::RemoveMember(TRuntimeNode structObj, const std::st
memberIndex = i;
}
}
- if (!memberIndex && forced) {
+ if (!memberIndex && forced) {
return structObj;
}
- MKQL_ENSURE(memberIndex, "Unknown member name: " << memberName);
+ MKQL_ENSURE(memberIndex, "Unknown member name: " << memberName);
// remove at position i in the struct
auto newType = newTypeBuilder.Build();
- TCallableBuilder callableBuilder(Env, __func__, newType);
+ TCallableBuilder callableBuilder(Env, __func__, newType);
callableBuilder.Add(structObj);
- callableBuilder.Add(NewDataLiteral<ui32>(*memberIndex));
+ callableBuilder.Add(NewDataLiteral<ui32>(*memberIndex));
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -426,7 +426,7 @@ TRuntimeNode TProgramBuilder::Zip(const TArrayRef<const TRuntimeNode>& lists) {
return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
}
- std::vector<TType*> tupleTypes;
+ std::vector<TType*> tupleTypes;
tupleTypes.reserve(lists.size());
for (auto& list : lists) {
if (list.GetStaticType()->IsEmptyList()) {
@@ -440,7 +440,7 @@ TRuntimeNode TProgramBuilder::Zip(const TArrayRef<const TRuntimeNode>& lists) {
}
auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
for (auto& list : lists) {
callableBuilder.Add(list);
}
@@ -453,7 +453,7 @@ TRuntimeNode TProgramBuilder::ZipAll(const TArrayRef<const TRuntimeNode>& lists)
return NewEmptyList(Env.GetEmptyTuple()->GetGenericType());
}
- std::vector<TType*> tupleTypes;
+ std::vector<TType*> tupleTypes;
tupleTypes.reserve(lists.size());
for (auto& list : lists) {
if (list.GetStaticType()->IsEmptyList()) {
@@ -467,7 +467,7 @@ TRuntimeNode TProgramBuilder::ZipAll(const TArrayRef<const TRuntimeNode>& lists)
}
auto returnType = TListType::Create(TTupleType::Create(tupleTypes.size(), tupleTypes.data(), Env), Env);
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
for (auto& list : lists) {
callableBuilder.Add(list);
}
@@ -476,16 +476,16 @@ TRuntimeNode TProgramBuilder::ZipAll(const TArrayRef<const TRuntimeNode>& lists)
}
TRuntimeNode TProgramBuilder::Enumerate(TRuntimeNode list, TRuntimeNode start, TRuntimeNode step) {
- const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
+ const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
ThrowIfListOfVoid(itemType);
MKQL_ENSURE(AS_TYPE(TDataType, start)->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected Uint64 as start");
MKQL_ENSURE(AS_TYPE(TDataType, step)->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected Uint64 as step");
- const std::array<TType*, 2U> tupleTypes = {{ NewDataType(NUdf::EDataSlot::Uint64), itemType }};
- const auto returnType = NewListType(NewTupleType(tupleTypes));
+ const std::array<TType*, 2U> tupleTypes = {{ NewDataType(NUdf::EDataSlot::Uint64), itemType }};
+ const auto returnType = NewListType(NewTupleType(tupleTypes));
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
callableBuilder.Add(list);
callableBuilder.Add(start);
callableBuilder.Add(step);
@@ -493,19 +493,19 @@ TRuntimeNode TProgramBuilder::Enumerate(TRuntimeNode list, TRuntimeNode start, T
}
TRuntimeNode TProgramBuilder::Enumerate(TRuntimeNode list) {
- return TProgramBuilder::Enumerate(list, NewDataLiteral<ui64>(0), NewDataLiteral<ui64>(1));
+ return TProgramBuilder::Enumerate(list, NewDataLiteral<ui64>(0), NewDataLiteral<ui64>(1));
}
-TRuntimeNode TProgramBuilder::Fold(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler) {
- const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
+TRuntimeNode TProgramBuilder::Fold(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler) {
+ const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto stateNodeArg = Arg(state.GetStaticType());
- const auto itemArg = Arg(itemType);
- const auto newState = handler(itemArg, stateNodeArg);
+ const auto stateNodeArg = Arg(state.GetStaticType());
+ const auto itemArg = Arg(itemType);
+ const auto newState = handler(itemArg, stateNodeArg);
MKQL_ENSURE(newState.GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
- TCallableBuilder callableBuilder(Env, __func__, state.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, state.GetStaticType());
callableBuilder.Add(list);
callableBuilder.Add(state);
callableBuilder.Add(itemArg);
@@ -514,18 +514,18 @@ TRuntimeNode TProgramBuilder::Fold(TRuntimeNode list, TRuntimeNode state, const
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Fold1(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler) {
- const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
+TRuntimeNode TProgramBuilder::Fold1(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler) {
+ const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto initState = init(itemArg);
- const auto stateNodeArg = Arg(initState.GetStaticType());
- const auto newState = handler(itemArg, stateNodeArg);
+ const auto itemArg = Arg(itemType);
+ const auto initState = init(itemArg);
+ const auto stateNodeArg = Arg(initState.GetStaticType());
+ const auto newState = handler(itemArg, stateNodeArg);
MKQL_ENSURE(newState.GetStaticType()->IsSameType(*initState.GetStaticType()), "State type is changed by the handler");
- TCallableBuilder callableBuilder(Env, __func__, NewOptionalType(newState.GetStaticType()));
+ TCallableBuilder callableBuilder(Env, __func__, NewOptionalType(newState.GetStaticType()));
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
callableBuilder.Add(initState);
@@ -535,30 +535,30 @@ TRuntimeNode TProgramBuilder::Fold1(TRuntimeNode list, const TUnaryLambda& init,
}
TRuntimeNode TProgramBuilder::Reduce(TRuntimeNode list, TRuntimeNode state1,
- const TBinaryLambda& handler1,
- const TUnaryLambda& handler2,
+ const TBinaryLambda& handler1,
+ const TUnaryLambda& handler2,
TRuntimeNode state3,
- const TBinaryLambda& handler3) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList() || listType->IsStream(), "Expected list or stream");
- const auto itemType = listType->IsList()?
- static_cast<const TListType&>(*listType).GetItemType():
- static_cast<const TStreamType&>(*listType).GetItemType();
+ const TBinaryLambda& handler3) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList() || listType->IsStream(), "Expected list or stream");
+ const auto itemType = listType->IsList()?
+ static_cast<const TListType&>(*listType).GetItemType():
+ static_cast<const TStreamType&>(*listType).GetItemType();
ThrowIfListOfVoid(itemType);
- const auto state1NodeArg = Arg(state1.GetStaticType());
- const auto state3NodeArg = Arg(state3.GetStaticType());
- const auto itemArg = Arg(itemType);
- const auto newState1 = handler1(itemArg, state1NodeArg);
+ const auto state1NodeArg = Arg(state1.GetStaticType());
+ const auto state3NodeArg = Arg(state3.GetStaticType());
+ const auto itemArg = Arg(itemType);
+ const auto newState1 = handler1(itemArg, state1NodeArg);
MKQL_ENSURE(newState1.GetStaticType()->IsSameType(*state1.GetStaticType()), "State 1 type is changed by the handler");
- const auto newState2 = handler2(state1NodeArg);
+ const auto newState2 = handler2(state1NodeArg);
TRuntimeNode itemState2Arg = Arg(newState2.GetStaticType());
- const auto newState3 = handler3(itemState2Arg, state3NodeArg);
+ const auto newState3 = handler3(itemState2Arg, state3NodeArg);
MKQL_ENSURE(newState3.GetStaticType()->IsSameType(*state3.GetStaticType()), "State 3 type is changed by the handler");
- TCallableBuilder callableBuilder(Env, __func__, newState3.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, newState3.GetStaticType());
callableBuilder.Add(list);
callableBuilder.Add(state1);
callableBuilder.Add(state3);
@@ -572,99 +572,99 @@ TRuntimeNode TProgramBuilder::Reduce(TRuntimeNode list, TRuntimeNode state1,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Condense(TRuntimeNode flow, TRuntimeNode state,
- const TBinaryLambda& switcher,
- const TBinaryLambda& handler) {
- const auto flowType = flow.GetStaticType();
-
- if (flowType->IsList()) {
- // TODO: Native implementation for list.
- return Collect(Condense(ToFlow(flow), state, switcher, handler));
- }
-
- MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
-
- const auto itemType = flowType->IsFlow() ?
- static_cast<const TFlowType&>(*flowType).GetItemType():
- static_cast<const TStreamType&>(*flowType).GetItemType();
-
- const auto itemArg = Arg(itemType);
- const auto stateArg = Arg(state.GetStaticType());
- const auto outSwitch = switcher(itemArg, stateArg);
- const auto newState = handler(itemArg, stateArg);
- MKQL_ENSURE(newState.GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
-
- TCallableBuilder callableBuilder(Env, __func__, flowType->IsFlow() ? NewFlowType(state.GetStaticType()) : NewStreamType(state.GetStaticType()));
- callableBuilder.Add(flow);
- callableBuilder.Add(state);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(stateArg);
- callableBuilder.Add(outSwitch);
- callableBuilder.Add(newState);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Condense1(TRuntimeNode flow, const TUnaryLambda& init,
- const TBinaryLambda& switcher,
- const TBinaryLambda& handler) {
- const auto flowType = flow.GetStaticType();
-
- if (flowType->IsList()) {
- // TODO: Native implementation for list.
- return Collect(Condense1(ToFlow(flow), init, switcher, handler));
- }
-
- MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
-
- const auto itemType = flowType->IsFlow() ?
- static_cast<const TFlowType&>(*flowType).GetItemType():
- static_cast<const TStreamType&>(*flowType).GetItemType();
-
- const auto itemArg = Arg(itemType);
- const auto initState = init(itemArg);
- const auto stateArg = Arg(initState.GetStaticType());
- const auto outSwitch = switcher(itemArg, stateArg);
- const auto newState = handler(itemArg, stateArg);
-
- MKQL_ENSURE(newState.GetStaticType()->IsSameType(*initState.GetStaticType()), "State type is changed by the handler");
-
- TCallableBuilder callableBuilder(Env, __func__, flowType->IsFlow() ? NewFlowType(newState.GetStaticType()) : NewStreamType(newState.GetStaticType()));
- callableBuilder.Add(flow);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(initState);
- callableBuilder.Add(stateArg);
- callableBuilder.Add(outSwitch);
- callableBuilder.Add(newState);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::Condense(TRuntimeNode flow, TRuntimeNode state,
+ const TBinaryLambda& switcher,
+ const TBinaryLambda& handler) {
+ const auto flowType = flow.GetStaticType();
+
+ if (flowType->IsList()) {
+ // TODO: Native implementation for list.
+ return Collect(Condense(ToFlow(flow), state, switcher, handler));
+ }
+
+ MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
+
+ const auto itemType = flowType->IsFlow() ?
+ static_cast<const TFlowType&>(*flowType).GetItemType():
+ static_cast<const TStreamType&>(*flowType).GetItemType();
+
+ const auto itemArg = Arg(itemType);
+ const auto stateArg = Arg(state.GetStaticType());
+ const auto outSwitch = switcher(itemArg, stateArg);
+ const auto newState = handler(itemArg, stateArg);
+ MKQL_ENSURE(newState.GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
+
+ TCallableBuilder callableBuilder(Env, __func__, flowType->IsFlow() ? NewFlowType(state.GetStaticType()) : NewStreamType(state.GetStaticType()));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(state);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(stateArg);
+ callableBuilder.Add(outSwitch);
+ callableBuilder.Add(newState);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Condense1(TRuntimeNode flow, const TUnaryLambda& init,
+ const TBinaryLambda& switcher,
+ const TBinaryLambda& handler) {
+ const auto flowType = flow.GetStaticType();
+
+ if (flowType->IsList()) {
+ // TODO: Native implementation for list.
+ return Collect(Condense1(ToFlow(flow), init, switcher, handler));
+ }
+
+ MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
+
+ const auto itemType = flowType->IsFlow() ?
+ static_cast<const TFlowType&>(*flowType).GetItemType():
+ static_cast<const TStreamType&>(*flowType).GetItemType();
+
+ const auto itemArg = Arg(itemType);
+ const auto initState = init(itemArg);
+ const auto stateArg = Arg(initState.GetStaticType());
+ const auto outSwitch = switcher(itemArg, stateArg);
+ const auto newState = handler(itemArg, stateArg);
+
+ MKQL_ENSURE(newState.GetStaticType()->IsSameType(*initState.GetStaticType()), "State type is changed by the handler");
+
+ TCallableBuilder callableBuilder(Env, __func__, flowType->IsFlow() ? NewFlowType(newState.GetStaticType()) : NewStreamType(newState.GetStaticType()));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(initState);
+ callableBuilder.Add(stateArg);
+ callableBuilder.Add(outSwitch);
+ callableBuilder.Add(newState);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::Squeeze(TRuntimeNode stream, TRuntimeNode state,
- const TBinaryLambda& handler,
- const TUnaryLambda& save,
- const TUnaryLambda& load) {
- const auto streamType = stream.GetStaticType();
+ const TBinaryLambda& handler,
+ const TUnaryLambda& save,
+ const TUnaryLambda& load) {
+ const auto streamType = stream.GetStaticType();
MKQL_ENSURE(streamType->IsStream(), "Expected stream");
const auto& streamDetailedType = static_cast<const TStreamType&>(*streamType);
- const auto itemType = streamDetailedType.GetItemType();
+ const auto itemType = streamDetailedType.GetItemType();
ThrowIfListOfVoid(itemType);
- const auto stateNodeArg = Arg(state.GetStaticType());
- const auto itemArg = Arg(itemType);
- const auto newState = handler(itemArg, stateNodeArg);
+ const auto stateNodeArg = Arg(state.GetStaticType());
+ const auto itemArg = Arg(itemType);
+ const auto newState = handler(itemArg, stateNodeArg);
MKQL_ENSURE(newState.GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
TRuntimeNode saveArg, outSave, loadArg, outLoad;
- if (save && load) {
- outSave = save(saveArg = Arg(state.GetStaticType()));
- outLoad = load(loadArg = Arg(outSave.GetStaticType()));
+ if (save && load) {
+ outSave = save(saveArg = Arg(state.GetStaticType()));
+ outLoad = load(loadArg = Arg(outSave.GetStaticType()));
MKQL_ENSURE(outLoad.GetStaticType()->IsSameType(*state.GetStaticType()), "Loaded type is changed by the load handler");
} else {
saveArg = outSave = loadArg = outLoad = NewVoid();
}
- TCallableBuilder callableBuilder(Env, __func__, TStreamType::Create(state.GetStaticType(), Env));
+ TCallableBuilder callableBuilder(Env, __func__, TStreamType::Create(state.GetStaticType(), Env));
callableBuilder.Add(stream);
callableBuilder.Add(state);
callableBuilder.Add(itemArg);
@@ -677,34 +677,34 @@ TRuntimeNode TProgramBuilder::Squeeze(TRuntimeNode stream, TRuntimeNode state,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Squeeze1(TRuntimeNode stream, const TUnaryLambda& init,
- const TBinaryLambda& handler,
- const TUnaryLambda& save,
- const TUnaryLambda& load) {
- const auto streamType = stream.GetStaticType();
+TRuntimeNode TProgramBuilder::Squeeze1(TRuntimeNode stream, const TUnaryLambda& init,
+ const TBinaryLambda& handler,
+ const TUnaryLambda& save,
+ const TUnaryLambda& load) {
+ const auto streamType = stream.GetStaticType();
MKQL_ENSURE(streamType->IsStream(), "Expected stream");
const auto& streamDetailedType = static_cast<const TStreamType&>(*streamType);
- const auto itemType = streamDetailedType.GetItemType();
+ const auto itemType = streamDetailedType.GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto initState = init(itemArg);
- const auto stateNodeArg = Arg(initState.GetStaticType());
- const auto newState = handler(itemArg, stateNodeArg);
+ const auto itemArg = Arg(itemType);
+ const auto initState = init(itemArg);
+ const auto stateNodeArg = Arg(initState.GetStaticType());
+ const auto newState = handler(itemArg, stateNodeArg);
MKQL_ENSURE(newState.GetStaticType()->IsSameType(*initState.GetStaticType()), "State type is changed by the handler");
TRuntimeNode saveArg, outSave, loadArg, outLoad;
- if (save && load) {
- outSave = save(saveArg = Arg(initState.GetStaticType()));
- outLoad = load(loadArg = Arg(outSave.GetStaticType()));
+ if (save && load) {
+ outSave = save(saveArg = Arg(initState.GetStaticType()));
+ outLoad = load(loadArg = Arg(outSave.GetStaticType()));
MKQL_ENSURE(outLoad.GetStaticType()->IsSameType(*initState.GetStaticType()), "Loaded type is changed by the load handler");
} else {
saveArg = outSave = loadArg = outLoad = NewVoid();
}
- TCallableBuilder callableBuilder(Env, __func__, NewStreamType(newState.GetStaticType()));
+ TCallableBuilder callableBuilder(Env, __func__, NewStreamType(newState.GetStaticType()));
callableBuilder.Add(stream);
callableBuilder.Add(itemArg);
callableBuilder.Add(initState);
@@ -718,151 +718,151 @@ TRuntimeNode TProgramBuilder::Squeeze1(TRuntimeNode stream, const TUnaryLambda&
}
TRuntimeNode TProgramBuilder::Discard(TRuntimeNode stream) {
- const auto streamType = stream.GetStaticType();
- MKQL_ENSURE(streamType->IsStream() || streamType->IsFlow(), "Expected stream or flow.");
+ const auto streamType = stream.GetStaticType();
+ MKQL_ENSURE(streamType->IsStream() || streamType->IsFlow(), "Expected stream or flow.");
- TCallableBuilder callableBuilder(Env, __func__, streamType);
+ TCallableBuilder callableBuilder(Env, __func__, streamType);
callableBuilder.Add(stream);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Map(TRuntimeNode list, const TUnaryLambda& handler) {
- return BuildMap(__func__, list, handler);
-}
-
-TRuntimeNode TProgramBuilder::OrderedMap(TRuntimeNode list, const TUnaryLambda& handler) {
- return BuildMap(__func__, list, handler);
-}
-
-template <bool Ordered>
-TRuntimeNode TProgramBuilder::BuildExtract(TRuntimeNode list, const std::string_view& name) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList() || listType->IsOptional(), "Expected list or optional.");
-
- const auto itemType = listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TOptionalType, listType)->GetItemType();
-
- const auto lambda = [&](TRuntimeNode item) {
- return itemType->IsStruct() ? Member(item, name) : Nth(item, ::FromString<ui32>(name));
- };
-
- return Ordered ? OrderedMap(list, lambda) : Map(list, lambda);
-}
-
-TRuntimeNode TProgramBuilder::Extract(TRuntimeNode list, const std::string_view& name) {
- return BuildExtract<false>(list, name);
-}
-
-TRuntimeNode TProgramBuilder::OrderedExtract(TRuntimeNode list, const std::string_view& name) {
- return BuildExtract<true>(list, name);
-}
-
-TRuntimeNode TProgramBuilder::ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler) {
- return ChainMap(list, state, [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- const auto result = handler(item, state);
- return {result, result};
- });
-}
-
-TRuntimeNode TProgramBuilder::ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinarySplitLambda& handler) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream");
-
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
+TRuntimeNode TProgramBuilder::Map(TRuntimeNode list, const TUnaryLambda& handler) {
+ return BuildMap(__func__, list, handler);
+}
- ThrowIfListOfVoid(itemType);
+TRuntimeNode TProgramBuilder::OrderedMap(TRuntimeNode list, const TUnaryLambda& handler) {
+ return BuildMap(__func__, list, handler);
+}
+
+template <bool Ordered>
+TRuntimeNode TProgramBuilder::BuildExtract(TRuntimeNode list, const std::string_view& name) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList() || listType->IsOptional(), "Expected list or optional.");
- const auto stateNodeArg = Arg(state.GetStaticType());
- const auto itemArg = Arg(itemType);
- const auto newItemAndState = handler(itemArg, stateNodeArg);
+ const auto itemType = listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TOptionalType, listType)->GetItemType();
- MKQL_ENSURE(std::get<1U>(newItemAndState).GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
- const auto resultItemType = std::get<0U>(newItemAndState).GetStaticType();
- TType* resultListType = nullptr;
- if (listType->IsFlow()) {
- resultListType = TFlowType::Create(resultItemType, Env);
- } else if (listType->IsList()) {
+ const auto lambda = [&](TRuntimeNode item) {
+ return itemType->IsStruct() ? Member(item, name) : Nth(item, ::FromString<ui32>(name));
+ };
+
+ return Ordered ? OrderedMap(list, lambda) : Map(list, lambda);
+}
+
+TRuntimeNode TProgramBuilder::Extract(TRuntimeNode list, const std::string_view& name) {
+ return BuildExtract<false>(list, name);
+}
+
+TRuntimeNode TProgramBuilder::OrderedExtract(TRuntimeNode list, const std::string_view& name) {
+ return BuildExtract<true>(list, name);
+}
+
+TRuntimeNode TProgramBuilder::ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler) {
+ return ChainMap(list, state, [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ const auto result = handler(item, state);
+ return {result, result};
+ });
+}
+
+TRuntimeNode TProgramBuilder::ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinarySplitLambda& handler) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream");
+
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
+
+ ThrowIfListOfVoid(itemType);
+
+ const auto stateNodeArg = Arg(state.GetStaticType());
+ const auto itemArg = Arg(itemType);
+ const auto newItemAndState = handler(itemArg, stateNodeArg);
+
+ MKQL_ENSURE(std::get<1U>(newItemAndState).GetStaticType()->IsSameType(*state.GetStaticType()), "State type is changed by the handler");
+ const auto resultItemType = std::get<0U>(newItemAndState).GetStaticType();
+ TType* resultListType = nullptr;
+ if (listType->IsFlow()) {
+ resultListType = TFlowType::Create(resultItemType, Env);
+ } else if (listType->IsList()) {
resultListType = TListType::Create(resultItemType, Env);
- } else if (listType->IsStream()) {
+ } else if (listType->IsStream()) {
resultListType = TStreamType::Create(resultItemType, Env);
}
- TCallableBuilder callableBuilder(Env, __func__, resultListType);
+ TCallableBuilder callableBuilder(Env, __func__, resultListType);
callableBuilder.Add(list);
callableBuilder.Add(state);
callableBuilder.Add(itemArg);
callableBuilder.Add(stateNodeArg);
- callableBuilder.Add(std::get<0U>(newItemAndState));
- callableBuilder.Add(std::get<1U>(newItemAndState));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Chain1Map(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler) {
- return Chain1Map(list,
- [&](TRuntimeNode item) -> TRuntimeNodePair {
- const auto result = init(item);
- return {result, result};
- },
- [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
- const auto result = handler(item, state);
- return {result, result};
- }
- );
-}
-
-TRuntimeNode TProgramBuilder::Chain1Map(TRuntimeNode list, const TUnarySplitLambda& init, const TBinarySplitLambda& handler) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream");
-
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
+ callableBuilder.Add(std::get<0U>(newItemAndState));
+ callableBuilder.Add(std::get<1U>(newItemAndState));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Chain1Map(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler) {
+ return Chain1Map(list,
+ [&](TRuntimeNode item) -> TRuntimeNodePair {
+ const auto result = init(item);
+ return {result, result};
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) -> TRuntimeNodePair {
+ const auto result = handler(item, state);
+ return {result, result};
+ }
+ );
+}
+
+TRuntimeNode TProgramBuilder::Chain1Map(TRuntimeNode list, const TUnarySplitLambda& init, const TBinarySplitLambda& handler) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream");
+
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto initItemAndState = init(itemArg);
- const auto resultItemType = std::get<0U>(initItemAndState).GetStaticType();
- const auto stateType = std::get<1U>(initItemAndState).GetStaticType();;
- TType* resultListType = nullptr;
- if (listType->IsFlow()) {
- resultListType = TFlowType::Create(resultItemType, Env);
- } else if (listType->IsList()) {
+ const auto itemArg = Arg(itemType);
+ const auto initItemAndState = init(itemArg);
+ const auto resultItemType = std::get<0U>(initItemAndState).GetStaticType();
+ const auto stateType = std::get<1U>(initItemAndState).GetStaticType();;
+ TType* resultListType = nullptr;
+ if (listType->IsFlow()) {
+ resultListType = TFlowType::Create(resultItemType, Env);
+ } else if (listType->IsList()) {
resultListType = TListType::Create(resultItemType, Env);
- } else if (listType->IsStream()) {
+ } else if (listType->IsStream()) {
resultListType = TStreamType::Create(resultItemType, Env);
}
- const auto stateArg = Arg(stateType);
- const auto updateItemAndState = handler(itemArg, stateArg);
- MKQL_ENSURE(std::get<0U>(updateItemAndState).GetStaticType()->IsSameType(*resultItemType), "Item type is changed by the handler");
- MKQL_ENSURE(std::get<1U>(updateItemAndState).GetStaticType()->IsSameType(*stateType), "State type is changed by the handler");
+ const auto stateArg = Arg(stateType);
+ const auto updateItemAndState = handler(itemArg, stateArg);
+ MKQL_ENSURE(std::get<0U>(updateItemAndState).GetStaticType()->IsSameType(*resultItemType), "Item type is changed by the handler");
+ MKQL_ENSURE(std::get<1U>(updateItemAndState).GetStaticType()->IsSameType(*stateType), "State type is changed by the handler");
- TCallableBuilder callableBuilder(Env, __func__, resultListType);
+ TCallableBuilder callableBuilder(Env, __func__, resultListType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
- callableBuilder.Add(std::get<0U>(initItemAndState));
- callableBuilder.Add(std::get<1U>(initItemAndState));
+ callableBuilder.Add(std::get<0U>(initItemAndState));
+ callableBuilder.Add(std::get<1U>(initItemAndState));
callableBuilder.Add(stateArg);
- callableBuilder.Add(std::get<0U>(updateItemAndState));
- callableBuilder.Add(std::get<1U>(updateItemAndState));
+ callableBuilder.Add(std::get<0U>(updateItemAndState));
+ callableBuilder.Add(std::get<1U>(updateItemAndState));
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::ToList(TRuntimeNode optional) {
- const auto optionalType = optional.GetStaticType();
+ const auto optionalType = optional.GetStaticType();
MKQL_ENSURE(optionalType->IsOptional(), "Expected optional");
const auto& optionalDetailedType = static_cast<const TOptionalType&>(*optionalType);
- const auto itemType = optionalDetailedType.GetItemType();
- return IfPresent(optional, [&](TRuntimeNode item) { return AsList(item); }, NewEmptyList(itemType));
+ const auto itemType = optionalDetailedType.GetItemType();
+ return IfPresent(optional, [&](TRuntimeNode item) { return AsList(item); }, NewEmptyList(itemType));
}
TRuntimeNode TProgramBuilder::Iterable(TZeroLambda lambda) {
@@ -880,106 +880,106 @@ TRuntimeNode TProgramBuilder::Iterable(TZeroLambda lambda) {
}
TRuntimeNode TProgramBuilder::ToOptional(TRuntimeNode list) {
- return Head(list);
-}
-
-TRuntimeNode TProgramBuilder::Head(TRuntimeNode list) {
- const auto resultType = NewOptionalType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
- TCallableBuilder callableBuilder(Env, __func__, resultType);
- callableBuilder.Add(list);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Last(TRuntimeNode list) {
- const auto resultType = NewOptionalType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ return Head(list);
+}
+
+TRuntimeNode TProgramBuilder::Head(TRuntimeNode list) {
+ const auto resultType = NewOptionalType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
+ callableBuilder.Add(list);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Last(TRuntimeNode list) {
+ const auto resultType = NewOptionalType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(list);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Nanvl(TRuntimeNode data, TRuntimeNode dataIfNaN) {
- const std::array<TRuntimeNode, 2> args = {{ data, dataIfNaN }};
- return Invoke(__func__, BuildArithmeticCommonType(data.GetStaticType(), dataIfNaN.GetStaticType()), args);
+ const std::array<TRuntimeNode, 2> args = {{ data, dataIfNaN }};
+ return Invoke(__func__, BuildArithmeticCommonType(data.GetStaticType(), dataIfNaN.GetStaticType()), args);
+}
+
+TRuntimeNode TProgramBuilder::FlatMap(TRuntimeNode list, const TUnaryLambda& handler)
+{
+ return BuildFlatMap(__func__, list, handler);
+}
+
+TRuntimeNode TProgramBuilder::OrderedFlatMap(TRuntimeNode list, const TUnaryLambda& handler)
+{
+ return BuildFlatMap(__func__, list, handler);
+}
+
+TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, const TUnaryLambda& handler)
+{
+ return BuildFilter(__func__, list, handler);
+}
+
+TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler)
+{
+ return BuildFilter(__func__, list, limit, handler);
}
-TRuntimeNode TProgramBuilder::FlatMap(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::OrderedFilter(TRuntimeNode list, const TUnaryLambda& handler)
{
- return BuildFlatMap(__func__, list, handler);
+ return BuildFilter(__func__, list, handler);
}
-TRuntimeNode TProgramBuilder::OrderedFlatMap(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::OrderedFilter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler)
{
- return BuildFlatMap(__func__, list, handler);
+ return BuildFilter(__func__, list, limit, handler);
}
-TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::TakeWhile(TRuntimeNode list, const TUnaryLambda& handler)
{
- return BuildFilter(__func__, list, handler);
+ return BuildFilter(__func__, list, handler);
}
-TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler)
-{
- return BuildFilter(__func__, list, limit, handler);
-}
-
-TRuntimeNode TProgramBuilder::OrderedFilter(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::SkipWhile(TRuntimeNode list, const TUnaryLambda& handler)
{
- return BuildFilter(__func__, list, handler);
+ return BuildFilter(__func__, list, handler);
}
-TRuntimeNode TProgramBuilder::OrderedFilter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler)
-{
- return BuildFilter(__func__, list, limit, handler);
-}
-
-TRuntimeNode TProgramBuilder::TakeWhile(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::TakeWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler)
{
- return BuildFilter(__func__, list, handler);
+ return BuildFilter(__func__, list, handler);
}
-TRuntimeNode TProgramBuilder::SkipWhile(TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::SkipWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler)
{
- return BuildFilter(__func__, list, handler);
-}
-
-TRuntimeNode TProgramBuilder::TakeWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler)
-{
- return BuildFilter(__func__, list, handler);
-}
-
-TRuntimeNode TProgramBuilder::SkipWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler)
-{
- return BuildFilter(__func__, list, handler);
-}
-
-TRuntimeNode TProgramBuilder::BuildListSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending,
- const TUnaryLambda& keyExtractor)
+ return BuildFilter(__func__, list, handler);
+}
+
+TRuntimeNode TProgramBuilder::BuildListSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending,
+ const TUnaryLambda& keyExtractor)
{
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList(), "Expected list.");
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList(), "Expected list.");
- const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
+ const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
ThrowIfListOfVoid(itemType);
- const auto ascendingType = ascending.GetStaticType();
- const auto itemArg = Arg(itemType);
+ const auto ascendingType = ascending.GetStaticType();
+ const auto itemArg = Arg(itemType);
- auto key = keyExtractor(itemArg);
+ auto key = keyExtractor(itemArg);
if (ascendingType->IsTuple()) {
- const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
+ const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
if (ascendingTuple->GetElementsCount() == 0) {
return list;
}
if (ascendingTuple->GetElementsCount() == 1) {
ascending = Nth(ascending, 0);
- key = Nth(key, 0);
+ key = Nth(key, 0);
}
}
- TCallableBuilder callableBuilder(Env, callableName, listType);
+ TCallableBuilder callableBuilder(Env, callableName, listType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
callableBuilder.Add(key);
@@ -987,56 +987,56 @@ TRuntimeNode TProgramBuilder::BuildListSort(const std::string_view& callableName
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::BuildListNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending,
- const TUnaryLambda& keyExtractor)
-{
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList(), "Expected list.");
-
- const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
-
- ThrowIfListOfVoid(itemType);
- MKQL_ENSURE(n.GetStaticType()->IsData(), "Expected data");
- MKQL_ENSURE(static_cast<const TDataType&>(*n.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
-
- const auto ascendingType = ascending.GetStaticType();
- const auto itemArg = Arg(itemType);
-
- auto key = keyExtractor(itemArg);
-
- if (ascendingType->IsTuple()) {
- const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
- if (ascendingTuple->GetElementsCount() == 0) {
- return Take(list, n);
- }
-
- if (ascendingTuple->GetElementsCount() == 1) {
- ascending = Nth(ascending, 0);
- key = Nth(key, 0);
- }
- }
-
- TCallableBuilder callableBuilder(Env, callableName, listType);
- callableBuilder.Add(list);
- callableBuilder.Add(n);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(key);
- callableBuilder.Add(ascending);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::BuildSort(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode ascending,
- const TUnaryLambda& keyExtractor)
-{
- if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
+TRuntimeNode TProgramBuilder::BuildListNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending,
+ const TUnaryLambda& keyExtractor)
+{
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList(), "Expected list.");
+
+ const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
+
+ ThrowIfListOfVoid(itemType);
+ MKQL_ENSURE(n.GetStaticType()->IsData(), "Expected data");
+ MKQL_ENSURE(static_cast<const TDataType&>(*n.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
+
+ const auto ascendingType = ascending.GetStaticType();
+ const auto itemArg = Arg(itemType);
+
+ auto key = keyExtractor(itemArg);
+
+ if (ascendingType->IsTuple()) {
+ const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
+ if (ascendingTuple->GetElementsCount() == 0) {
+ return Take(list, n);
+ }
+
+ if (ascendingTuple->GetElementsCount() == 1) {
+ ascending = Nth(ascending, 0);
+ key = Nth(key, 0);
+ }
+ }
+
+ TCallableBuilder callableBuilder(Env, callableName, listType);
+ callableBuilder.Add(list);
+ callableBuilder.Add(n);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(key);
+ callableBuilder.Add(ascending);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::BuildSort(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode ascending,
+ const TUnaryLambda& keyExtractor)
+{
+ if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
const bool newVersion = RuntimeVersion >= 25U && flowType->IsFlow();
const auto condense = newVersion ?
SqueezeToList(Map(flow, [&](TRuntimeNode item) { return Pickle(item); }), NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id)) :
- Condense1(flow,
- [this](TRuntimeNode item) { return AsList(item); },
- [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
- [this](TRuntimeNode item, TRuntimeNode state) { return Append(state, item); }
- );
+ Condense1(flow,
+ [this](TRuntimeNode item) { return AsList(item); },
+ [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
+ [this](TRuntimeNode item, TRuntimeNode state) { return Append(state, item); }
+ );
const auto finalKeyExtractor = newVersion ? [&](TRuntimeNode item) {
auto itemType = AS_TYPE(TFlowType, flowType)->GetItemType();
@@ -1051,236 +1051,236 @@ TRuntimeNode TProgramBuilder::BuildSort(const std::string_view& callableName, TR
return Unpickle(itemType, item);
}) : sorted;
});
- }
-
- return BuildListSort(callableName, flow, ascending, keyExtractor);
-}
-
-TRuntimeNode TProgramBuilder::BuildNth(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode n, TRuntimeNode ascending,
- const TUnaryLambda& keyExtractor)
-{
- if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
- return FlatMap(Condense1(flow,
- [this](TRuntimeNode item) { return AsList(item); },
- [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
- [this](TRuntimeNode item, TRuntimeNode state) { return Append(state, item); }
- ),
- [&](TRuntimeNode list) { return BuildNth(callableName, list, n, ascending, keyExtractor); }
- );
- }
-
- return BuildListNth(callableName, flow, n, ascending, keyExtractor);
-}
-
-TRuntimeNode TProgramBuilder::BuildTake(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode count) {
- const auto listType = flow.GetStaticType();
-
- TType* itemType = nullptr;
- if (listType->IsFlow()) {
- itemType = AS_TYPE(TFlowType, listType)->GetItemType();
- } else if (listType->IsList()) {
- itemType = AS_TYPE(TListType, listType)->GetItemType();
- } else if (listType->IsStream()) {
- itemType = AS_TYPE(TStreamType, listType)->GetItemType();
- }
-
- MKQL_ENSURE(itemType, "Expected flow, list or stream.");
- ThrowIfListOfVoid(itemType);
-
+ }
+
+ return BuildListSort(callableName, flow, ascending, keyExtractor);
+}
+
+TRuntimeNode TProgramBuilder::BuildNth(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode n, TRuntimeNode ascending,
+ const TUnaryLambda& keyExtractor)
+{
+ if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
+ return FlatMap(Condense1(flow,
+ [this](TRuntimeNode item) { return AsList(item); },
+ [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
+ [this](TRuntimeNode item, TRuntimeNode state) { return Append(state, item); }
+ ),
+ [&](TRuntimeNode list) { return BuildNth(callableName, list, n, ascending, keyExtractor); }
+ );
+ }
+
+ return BuildListNth(callableName, flow, n, ascending, keyExtractor);
+}
+
+TRuntimeNode TProgramBuilder::BuildTake(const std::string_view& callableName, TRuntimeNode flow, TRuntimeNode count) {
+ const auto listType = flow.GetStaticType();
+
+ TType* itemType = nullptr;
+ if (listType->IsFlow()) {
+ itemType = AS_TYPE(TFlowType, listType)->GetItemType();
+ } else if (listType->IsList()) {
+ itemType = AS_TYPE(TListType, listType)->GetItemType();
+ } else if (listType->IsStream()) {
+ itemType = AS_TYPE(TStreamType, listType)->GetItemType();
+ }
+
+ MKQL_ENSURE(itemType, "Expected flow, list or stream.");
+ ThrowIfListOfVoid(itemType);
+
MKQL_ENSURE(count.GetStaticType()->IsData(), "Expected data");
MKQL_ENSURE(static_cast<const TDataType&>(*count.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
TCallableBuilder callableBuilder(Env, callableName, listType);
- callableBuilder.Add(flow);
+ callableBuilder.Add(flow);
callableBuilder.Add(count);
return TRuntimeNode(callableBuilder.Build(), false);
}
-template<bool IsFilter, bool OnStruct>
-TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list) {
- const auto listType = list.GetStaticType();
-
- TType* itemType;
- if (listType->IsFlow()) {
- itemType = AS_TYPE(TFlowType, listType)->GetItemType();
- } else if (listType->IsList()) {
- itemType = AS_TYPE(TListType, listType)->GetItemType();
- } else if (listType->IsStream()) {
- itemType = AS_TYPE(TStreamType, listType)->GetItemType();
- } else if (listType->IsOptional()) {
- itemType = AS_TYPE(TOptionalType, listType)->GetItemType();
- } else {
- THROW yexception() << "Expected flow or list or stream or optional of " << (OnStruct ? "struct." : "tuple.");
- }
-
- std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>> filteredItems;
- std::vector<std::conditional_t<OnStruct, std::string_view, ui32>> members;
- const bool multiOptional = CollectOptionalElements<IsFilter>(itemType, members, filteredItems);
-
- const auto predicate = [=](TRuntimeNode item) {
- std::vector<TRuntimeNode> checkMembers;
- checkMembers.reserve(members.size());
- std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
- [=](const auto& i){ return Exists(Element(item, i)); });
- return And(checkMembers);
- };
-
- auto resultType = listType;
-
- if constexpr (IsFilter) {
- if (const auto filteredItemType = NewArrayType(filteredItems); multiOptional) {
- return BuildFilterNulls<OnStruct>(list, members, filteredItems);
- } else {
- resultType = listType->IsFlow() ?
- NewFlowType(filteredItemType):
- listType->IsList() ?
- NewListType(filteredItemType):
- listType->IsStream() ? NewStreamType(filteredItemType) : NewOptionalType(filteredItemType);
- }
- }
-
- return Filter(list, predicate, resultType);
-}
-
-template<bool IsFilter, bool OnStruct>
-TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members) {
- if (members.empty()) {
- return list;
- }
-
- const auto listType = list.GetStaticType();
-
+template<bool IsFilter, bool OnStruct>
+TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list) {
+ const auto listType = list.GetStaticType();
+
+ TType* itemType;
+ if (listType->IsFlow()) {
+ itemType = AS_TYPE(TFlowType, listType)->GetItemType();
+ } else if (listType->IsList()) {
+ itemType = AS_TYPE(TListType, listType)->GetItemType();
+ } else if (listType->IsStream()) {
+ itemType = AS_TYPE(TStreamType, listType)->GetItemType();
+ } else if (listType->IsOptional()) {
+ itemType = AS_TYPE(TOptionalType, listType)->GetItemType();
+ } else {
+ THROW yexception() << "Expected flow or list or stream or optional of " << (OnStruct ? "struct." : "tuple.");
+ }
+
+ std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>> filteredItems;
+ std::vector<std::conditional_t<OnStruct, std::string_view, ui32>> members;
+ const bool multiOptional = CollectOptionalElements<IsFilter>(itemType, members, filteredItems);
+
+ const auto predicate = [=](TRuntimeNode item) {
+ std::vector<TRuntimeNode> checkMembers;
+ checkMembers.reserve(members.size());
+ std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
+ [=](const auto& i){ return Exists(Element(item, i)); });
+ return And(checkMembers);
+ };
+
+ auto resultType = listType;
+
+ if constexpr (IsFilter) {
+ if (const auto filteredItemType = NewArrayType(filteredItems); multiOptional) {
+ return BuildFilterNulls<OnStruct>(list, members, filteredItems);
+ } else {
+ resultType = listType->IsFlow() ?
+ NewFlowType(filteredItemType):
+ listType->IsList() ?
+ NewListType(filteredItemType):
+ listType->IsStream() ? NewStreamType(filteredItemType) : NewOptionalType(filteredItemType);
+ }
+ }
+
+ return Filter(list, predicate, resultType);
+}
+
+template<bool IsFilter, bool OnStruct>
+TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members) {
+ if (members.empty()) {
+ return list;
+ }
+
+ const auto listType = list.GetStaticType();
+
TType* itemType;
- if (listType->IsFlow()) {
- itemType = AS_TYPE(TFlowType, listType)->GetItemType();
- } else if (listType->IsList()) {
- itemType = AS_TYPE(TListType, listType)->GetItemType();
- } else if (listType->IsStream()) {
- itemType = AS_TYPE(TStreamType, listType)->GetItemType();
- } else if (listType->IsOptional()) {
- itemType = AS_TYPE(TOptionalType, listType)->GetItemType();
+ if (listType->IsFlow()) {
+ itemType = AS_TYPE(TFlowType, listType)->GetItemType();
+ } else if (listType->IsList()) {
+ itemType = AS_TYPE(TListType, listType)->GetItemType();
+ } else if (listType->IsStream()) {
+ itemType = AS_TYPE(TStreamType, listType)->GetItemType();
+ } else if (listType->IsOptional()) {
+ itemType = AS_TYPE(TOptionalType, listType)->GetItemType();
} else {
- THROW yexception() << "Expected flow or list or stream or optional of struct.";
- }
-
- const auto predicate = [=](TRuntimeNode item) {
- TRuntimeNode::TList checkMembers;
- checkMembers.reserve(members.size());
- std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
- [=](const auto& i){ return Exists(Element(item, i)); });
- return And(checkMembers);
- };
-
- auto resultType = listType;
-
- if constexpr (IsFilter) {
- if (std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>> filteredItems;
- ReduceOptionalElements(itemType, members, filteredItems)) {
- return BuildFilterNulls<OnStruct>(list, members, filteredItems);
- } else {
- const auto filteredItemType = NewArrayType(filteredItems);
- resultType = listType->IsFlow() ?
- NewFlowType(filteredItemType):
- listType->IsList() ?
- NewListType(filteredItemType):
- listType->IsStream() ? NewStreamType(filteredItemType) : NewOptionalType(filteredItemType);
- }
- }
-
- return Filter(list, predicate, resultType);
-}
-
-template<bool OnStruct>
-TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members,
- const std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>>& filteredItems) {
- return FlatMap(list, [&](TRuntimeNode item) {
- TRuntimeNode::TList checkMembers;
- checkMembers.reserve(members.size());
- std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
- [=](const auto& i){ return Element(item, i); });
-
- return IfPresent(checkMembers, [&](TRuntimeNode::TList items) {
- std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TRuntimeNode>>, TRuntimeNode::TList> row;
- row.reserve(filteredItems.size());
- auto j = 0U;
- if constexpr (OnStruct) {
- std::transform(filteredItems.cbegin(), filteredItems.cend(), std::back_inserter(row),
- [&](const std::pair<std::string_view, TType*>& i) {
- const auto& member = i.first;
- const bool passtrought = members.cend() == std::find(members.cbegin(), members.cend(), member);
- return std::make_pair(member, passtrought ? Element(item, member) : items[j++]);
- }
- );
- return NewOptional(NewStruct(row));
- } else {
- auto i = 0U;
- std::generate_n(std::back_inserter(row), filteredItems.size(),
- [&]() {
- const auto index = i++;
- const bool passtrought = members.cend() == std::find(members.cbegin(), members.cend(), index);
- return passtrought ? Element(item, index) : items[j++];
- }
- );
- return NewOptional(NewTuple(row));
- }
- }, NewEmptyOptional(NewOptionalType(NewArrayType(filteredItems))));
- });
-}
-
-TRuntimeNode TProgramBuilder::SkipNullMembers(TRuntimeNode list) {
- return BuildFilterNulls<false, true>(list);
-}
-
-TRuntimeNode TProgramBuilder::FilterNullMembers(TRuntimeNode list) {
- return BuildFilterNulls<true, true>(list);
-}
-
-TRuntimeNode TProgramBuilder::SkipNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members) {
- return BuildFilterNulls<false, true>(list, members);
-}
-
-TRuntimeNode TProgramBuilder::FilterNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members) {
- return BuildFilterNulls<true, true>(list, members);
-}
-
-TRuntimeNode TProgramBuilder::FilterNullElements(TRuntimeNode list) {
- return BuildFilterNulls<true, false>(list);
-}
-
-TRuntimeNode TProgramBuilder::SkipNullElements(TRuntimeNode list) {
- return BuildFilterNulls<false, false>(list);
-}
-
-TRuntimeNode TProgramBuilder::FilterNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements) {
- return BuildFilterNulls<true, false>(list, elements);
-}
-
-TRuntimeNode TProgramBuilder::SkipNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements) {
- return BuildFilterNulls<false, false>(list, elements);
-}
-
-template <typename ResultType>
-TRuntimeNode TProgramBuilder::BuildContainerProperty(const std::string_view& callableName, TRuntimeNode listOrDict) {
- const auto type = listOrDict.GetStaticType();
+ THROW yexception() << "Expected flow or list or stream or optional of struct.";
+ }
+
+ const auto predicate = [=](TRuntimeNode item) {
+ TRuntimeNode::TList checkMembers;
+ checkMembers.reserve(members.size());
+ std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
+ [=](const auto& i){ return Exists(Element(item, i)); });
+ return And(checkMembers);
+ };
+
+ auto resultType = listType;
+
+ if constexpr (IsFilter) {
+ if (std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>> filteredItems;
+ ReduceOptionalElements(itemType, members, filteredItems)) {
+ return BuildFilterNulls<OnStruct>(list, members, filteredItems);
+ } else {
+ const auto filteredItemType = NewArrayType(filteredItems);
+ resultType = listType->IsFlow() ?
+ NewFlowType(filteredItemType):
+ listType->IsList() ?
+ NewListType(filteredItemType):
+ listType->IsStream() ? NewStreamType(filteredItemType) : NewOptionalType(filteredItemType);
+ }
+ }
+
+ return Filter(list, predicate, resultType);
+}
+
+template<bool OnStruct>
+TRuntimeNode TProgramBuilder::BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members,
+ const std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>>& filteredItems) {
+ return FlatMap(list, [&](TRuntimeNode item) {
+ TRuntimeNode::TList checkMembers;
+ checkMembers.reserve(members.size());
+ std::transform(members.cbegin(), members.cend(), std::back_inserter(checkMembers),
+ [=](const auto& i){ return Element(item, i); });
+
+ return IfPresent(checkMembers, [&](TRuntimeNode::TList items) {
+ std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TRuntimeNode>>, TRuntimeNode::TList> row;
+ row.reserve(filteredItems.size());
+ auto j = 0U;
+ if constexpr (OnStruct) {
+ std::transform(filteredItems.cbegin(), filteredItems.cend(), std::back_inserter(row),
+ [&](const std::pair<std::string_view, TType*>& i) {
+ const auto& member = i.first;
+ const bool passtrought = members.cend() == std::find(members.cbegin(), members.cend(), member);
+ return std::make_pair(member, passtrought ? Element(item, member) : items[j++]);
+ }
+ );
+ return NewOptional(NewStruct(row));
+ } else {
+ auto i = 0U;
+ std::generate_n(std::back_inserter(row), filteredItems.size(),
+ [&]() {
+ const auto index = i++;
+ const bool passtrought = members.cend() == std::find(members.cbegin(), members.cend(), index);
+ return passtrought ? Element(item, index) : items[j++];
+ }
+ );
+ return NewOptional(NewTuple(row));
+ }
+ }, NewEmptyOptional(NewOptionalType(NewArrayType(filteredItems))));
+ });
+}
+
+TRuntimeNode TProgramBuilder::SkipNullMembers(TRuntimeNode list) {
+ return BuildFilterNulls<false, true>(list);
+}
+
+TRuntimeNode TProgramBuilder::FilterNullMembers(TRuntimeNode list) {
+ return BuildFilterNulls<true, true>(list);
+}
+
+TRuntimeNode TProgramBuilder::SkipNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members) {
+ return BuildFilterNulls<false, true>(list, members);
+}
+
+TRuntimeNode TProgramBuilder::FilterNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members) {
+ return BuildFilterNulls<true, true>(list, members);
+}
+
+TRuntimeNode TProgramBuilder::FilterNullElements(TRuntimeNode list) {
+ return BuildFilterNulls<true, false>(list);
+}
+
+TRuntimeNode TProgramBuilder::SkipNullElements(TRuntimeNode list) {
+ return BuildFilterNulls<false, false>(list);
+}
+
+TRuntimeNode TProgramBuilder::FilterNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements) {
+ return BuildFilterNulls<true, false>(list, elements);
+}
+
+TRuntimeNode TProgramBuilder::SkipNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements) {
+ return BuildFilterNulls<false, false>(list, elements);
+}
+
+template <typename ResultType>
+TRuntimeNode TProgramBuilder::BuildContainerProperty(const std::string_view& callableName, TRuntimeNode listOrDict) {
+ const auto type = listOrDict.GetStaticType();
MKQL_ENSURE(type->IsList() || type->IsDict() || type->IsEmptyList() || type->IsEmptyDict(), "Expected list or dict.");
- if (type->IsList()) {
- const auto itemType = AS_TYPE(TListType, type)->GetItemType();
+ if (type->IsList()) {
+ const auto itemType = AS_TYPE(TListType, type)->GetItemType();
ThrowIfListOfVoid(itemType);
}
- TCallableBuilder callableBuilder(Env, callableName, NewDataType(NUdf::TDataType<ResultType>::Id));
+ TCallableBuilder callableBuilder(Env, callableName, NewDataType(NUdf::TDataType<ResultType>::Id));
callableBuilder.Add(listOrDict);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Length(TRuntimeNode listOrDict) {
- return BuildContainerProperty<ui64>(__func__, listOrDict);
-}
-
+TRuntimeNode TProgramBuilder::Length(TRuntimeNode listOrDict) {
+ return BuildContainerProperty<ui64>(__func__, listOrDict);
+}
+
TRuntimeNode TProgramBuilder::Iterator(TRuntimeNode list, const TArrayRef<const TRuntimeNode>& dependentNodes) {
- const auto streamType = NewStreamType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
- TCallableBuilder callableBuilder(Env, __func__, streamType);
+ const auto streamType = NewStreamType(AS_TYPE(TListType, list.GetStaticType())->GetItemType());
+ TCallableBuilder callableBuilder(Env, __func__, streamType);
callableBuilder.Add(list);
for (auto node : dependentNodes) {
callableBuilder.Add(node);
@@ -1289,72 +1289,72 @@ TRuntimeNode TProgramBuilder::Iterator(TRuntimeNode list, const TArrayRef<const
}
TRuntimeNode TProgramBuilder::EmptyIterator(TType* streamType) {
- MKQL_ENSURE(streamType->IsStream() || streamType->IsFlow(), "Expected stream or flow.");
- if (RuntimeVersion < 7U && streamType->IsFlow()) {
- return ToFlow(EmptyIterator(NewStreamType(AS_TYPE(TFlowType, streamType)->GetItemType())));
- }
- TCallableBuilder callableBuilder(Env, __func__, streamType);
+ MKQL_ENSURE(streamType->IsStream() || streamType->IsFlow(), "Expected stream or flow.");
+ if (RuntimeVersion < 7U && streamType->IsFlow()) {
+ return ToFlow(EmptyIterator(NewStreamType(AS_TYPE(TFlowType, streamType)->GetItemType())));
+ }
+ TCallableBuilder callableBuilder(Env, __func__, streamType);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Collect(TRuntimeNode flow) {
- const auto seqType = flow.GetStaticType();
+TRuntimeNode TProgramBuilder::Collect(TRuntimeNode flow) {
+ const auto seqType = flow.GetStaticType();
TType* itemType = nullptr;
- if (seqType->IsFlow()) {
- itemType = AS_TYPE(TFlowType, seqType)->GetItemType();
- } else if (seqType->IsList()) {
+ if (seqType->IsFlow()) {
+ itemType = AS_TYPE(TFlowType, seqType)->GetItemType();
+ } else if (seqType->IsList()) {
itemType = AS_TYPE(TListType, seqType)->GetItemType();
- } else if (seqType->IsStream()) {
- itemType = AS_TYPE(TStreamType, seqType)->GetItemType();
+ } else if (seqType->IsStream()) {
+ itemType = AS_TYPE(TStreamType, seqType)->GetItemType();
} else {
- THROW yexception() << "Expected flow, list or stream.";
+ THROW yexception() << "Expected flow, list or stream.";
}
- TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
- callableBuilder.Add(flow);
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
+ callableBuilder.Add(flow);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::LazyList(TRuntimeNode list) {
+ const auto type = list.GetStaticType();
+ bool isOptional;
+ const auto listType = UnpackOptional(type, isOptional);
+ MKQL_ENSURE(listType->IsList(), "Expected list");
+ TCallableBuilder callableBuilder(Env, __func__, type);
+ callableBuilder.Add(list);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::LazyList(TRuntimeNode list) {
- const auto type = list.GetStaticType();
- bool isOptional;
- const auto listType = UnpackOptional(type, isOptional);
- MKQL_ENSURE(listType->IsList(), "Expected list");
- TCallableBuilder callableBuilder(Env, __func__, type);
- callableBuilder.Add(list);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
TRuntimeNode TProgramBuilder::ForwardList(TRuntimeNode stream) {
- const auto type = stream.GetStaticType();
- MKQL_ENSURE(type->IsStream() || type->IsFlow(), "Expected flow or stream.");
- if constexpr (RuntimeVersion < 10U) {
- if (type->IsFlow()) {
- return ForwardList(FromFlow(stream));
- }
- }
- TCallableBuilder callableBuilder(Env, __func__, NewListType(type->IsFlow() ? AS_TYPE(TFlowType, stream)->GetItemType() : AS_TYPE(TStreamType, stream)->GetItemType()));
+ const auto type = stream.GetStaticType();
+ MKQL_ENSURE(type->IsStream() || type->IsFlow(), "Expected flow or stream.");
+ if constexpr (RuntimeVersion < 10U) {
+ if (type->IsFlow()) {
+ return ForwardList(FromFlow(stream));
+ }
+ }
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(type->IsFlow() ? AS_TYPE(TFlowType, stream)->GetItemType() : AS_TYPE(TStreamType, stream)->GetItemType()));
callableBuilder.Add(stream);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::ToFlow(TRuntimeNode stream) {
- const auto type = stream.GetStaticType();
- MKQL_ENSURE(type->IsStream() || type->IsList() || type->IsOptional(), "Expected stream, list or optional.");
- const auto itemType = type->IsStream() ? AS_TYPE(TStreamType, stream)->GetItemType() :
- type->IsList() ? AS_TYPE(TListType, stream)->GetItemType() : AS_TYPE(TOptionalType, stream)->GetItemType();
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(itemType));
- callableBuilder.Add(stream);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::FromFlow(TRuntimeNode flow) {
- MKQL_ENSURE(flow.GetStaticType()->IsFlow(), "Expected flow.");
- TCallableBuilder callableBuilder(Env, __func__, NewStreamType(AS_TYPE(TFlowType, flow)->GetItemType()));
- callableBuilder.Add(flow);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::ToFlow(TRuntimeNode stream) {
+ const auto type = stream.GetStaticType();
+ MKQL_ENSURE(type->IsStream() || type->IsList() || type->IsOptional(), "Expected stream, list or optional.");
+ const auto itemType = type->IsStream() ? AS_TYPE(TStreamType, stream)->GetItemType() :
+ type->IsList() ? AS_TYPE(TListType, stream)->GetItemType() : AS_TYPE(TOptionalType, stream)->GetItemType();
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(itemType));
+ callableBuilder.Add(stream);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::FromFlow(TRuntimeNode flow) {
+ MKQL_ENSURE(flow.GetStaticType()->IsFlow(), "Expected flow.");
+ TCallableBuilder callableBuilder(Env, __func__, NewStreamType(AS_TYPE(TFlowType, flow)->GetItemType()));
+ callableBuilder.Add(flow);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::Steal(TRuntimeNode input) {
if constexpr (RuntimeVersion < 27U) {
THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
@@ -1437,20 +1437,20 @@ TRuntimeNode TProgramBuilder::ListFromRange(TRuntimeNode start, TRuntimeNode end
if constexpr (RuntimeVersion < 24U) {
MKQL_ENSURE(IsNumericType(AS_TYPE(TDataType, start)->GetSchemeType()), "Expected numeric");
} else {
- MKQL_ENSURE(IsNumericType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
- IsDateType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
- IsTzDateType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
- IsIntervalType(AS_TYPE(TDataType, start)->GetSchemeType()),
+ MKQL_ENSURE(IsNumericType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
+ IsDateType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
+ IsTzDateType(AS_TYPE(TDataType, start)->GetSchemeType()) ||
+ IsIntervalType(AS_TYPE(TDataType, start)->GetSchemeType()),
"Expected numeric, date or tzdate");
-
- if (IsNumericType(AS_TYPE(TDataType, start)->GetSchemeType())) {
- MKQL_ENSURE(IsNumericType(AS_TYPE(TDataType, step)->GetSchemeType()), "Expected numeric");
- } else {
+
+ if (IsNumericType(AS_TYPE(TDataType, start)->GetSchemeType())) {
+ MKQL_ENSURE(IsNumericType(AS_TYPE(TDataType, step)->GetSchemeType()), "Expected numeric");
+ } else {
MKQL_ENSURE(IsIntervalType(AS_TYPE(TDataType, step)->GetSchemeType()), "Expected interval");
}
}
-
- TCallableBuilder callableBuilder(Env, __func__, TListType::Create(start.GetStaticType(), Env));
+
+ TCallableBuilder callableBuilder(Env, __func__, TListType::Create(start.GetStaticType(), Env));
callableBuilder.Add(start);
callableBuilder.Add(end);
callableBuilder.Add(step);
@@ -1461,22 +1461,22 @@ TRuntimeNode TProgramBuilder::Switch(TRuntimeNode stream,
const TArrayRef<const TSwitchInput>& handlerInputs,
std::function<TRuntimeNode(ui32 index, TRuntimeNode item)> handler,
ui64 memoryLimitBytes, TType* returnType) {
- MKQL_ENSURE(stream.GetStaticType()->IsStream() || stream.GetStaticType()->IsFlow(), "Expected stream or flow.");
- std::vector<TRuntimeNode> argNodes(handlerInputs.size());
- std::vector<TRuntimeNode> outputNodes(handlerInputs.size());
+ MKQL_ENSURE(stream.GetStaticType()->IsStream() || stream.GetStaticType()->IsFlow(), "Expected stream or flow.");
+ std::vector<TRuntimeNode> argNodes(handlerInputs.size());
+ std::vector<TRuntimeNode> outputNodes(handlerInputs.size());
for (ui32 i = 0; i < handlerInputs.size(); ++i) {
TRuntimeNode arg = Arg(handlerInputs[i].InputType);
argNodes[i] = arg;
outputNodes[i] = handler(i, arg);
}
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
callableBuilder.Add(stream);
- callableBuilder.Add(NewDataLiteral<ui64>(memoryLimitBytes));
+ callableBuilder.Add(NewDataLiteral<ui64>(memoryLimitBytes));
for (ui32 i = 0; i < handlerInputs.size(); ++i) {
- std::vector<TRuntimeNode> tupleElems;
+ std::vector<TRuntimeNode> tupleElems;
for (auto index : handlerInputs[i].Indicies) {
- tupleElems.push_back(NewDataLiteral<ui32>(index));
+ tupleElems.push_back(NewDataLiteral<ui32>(index));
}
auto indiciesTuple = NewTuple(tupleElems);
@@ -1486,7 +1486,7 @@ TRuntimeNode TProgramBuilder::Switch(TRuntimeNode stream,
if (!handlerInputs[i].ResultVariantOffset) {
callableBuilder.Add(NewVoid());
} else {
- callableBuilder.Add(NewDataLiteral<ui32>(*handlerInputs[i].ResultVariantOffset));
+ callableBuilder.Add(NewDataLiteral<ui32>(*handlerInputs[i].ResultVariantOffset));
}
}
@@ -1494,41 +1494,41 @@ TRuntimeNode TProgramBuilder::Switch(TRuntimeNode stream,
}
TRuntimeNode TProgramBuilder::HasItems(TRuntimeNode listOrDict) {
- return BuildContainerProperty<bool>(__func__, listOrDict);
+ return BuildContainerProperty<bool>(__func__, listOrDict);
}
TRuntimeNode TProgramBuilder::Reverse(TRuntimeNode list) {
- bool isOptional = false;
- const auto listType = UnpackOptional(list, isOptional);
-
- if (isOptional) {
- return Map(list, [&](TRuntimeNode unpacked) { return Reverse(unpacked); } );
- }
-
- const auto listDetailedType = AS_TYPE(TListType, listType);
- const auto itemType = listDetailedType->GetItemType();
+ bool isOptional = false;
+ const auto listType = UnpackOptional(list, isOptional);
+
+ if (isOptional) {
+ return Map(list, [&](TRuntimeNode unpacked) { return Reverse(unpacked); } );
+ }
+
+ const auto listDetailedType = AS_TYPE(TListType, listType);
+ const auto itemType = listDetailedType->GetItemType();
ThrowIfListOfVoid(itemType);
- TCallableBuilder callableBuilder(Env, __func__, listType);
+ TCallableBuilder callableBuilder(Env, __func__, listType);
callableBuilder.Add(list);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Skip(TRuntimeNode list, TRuntimeNode count) {
- return BuildTake(__func__, list, count);
+ return BuildTake(__func__, list, count);
}
TRuntimeNode TProgramBuilder::Take(TRuntimeNode list, TRuntimeNode count) {
- return BuildTake(__func__, list, count);
+ return BuildTake(__func__, list, count);
}
-TRuntimeNode TProgramBuilder::Sort(TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor)
+TRuntimeNode TProgramBuilder::Sort(TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor)
{
- return BuildSort(__func__, list, ascending, keyExtractor);
+ return BuildSort(__func__, list, ascending, keyExtractor);
}
-TRuntimeNode TProgramBuilder::Top(TRuntimeNode flow, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
- if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
+TRuntimeNode TProgramBuilder::Top(TRuntimeNode flow, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
+ if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
auto itemType = flowType->IsFlow() ? AS_TYPE(TFlowType, flowType)->GetItemType() : AS_TYPE(TStreamType, flowType)->GetItemType();
const auto finalKeyExtractor = [&](TRuntimeNode item) {
return keyExtractor(Unpickle(itemType, item));
@@ -1536,20 +1536,20 @@ TRuntimeNode TProgramBuilder::Top(TRuntimeNode flow, TRuntimeNode count, TRuntim
return Map(FlatMap(Condense1(flow,
[this](TRuntimeNode item) { return AsList(Pickle(item)); },
- [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
+ [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
[&](TRuntimeNode item, TRuntimeNode state) { return KeepTop(count, state, Pickle(item), ascending, finalKeyExtractor); }
- ),
+ ),
[&](TRuntimeNode list) { return Top(list, count, ascending, finalKeyExtractor); }
), [&](TRuntimeNode item) {
return Unpickle(itemType, item);
});
- }
-
- return BuildListNth(__func__, flow, count, ascending, keyExtractor);
-}
-
-TRuntimeNode TProgramBuilder::TopSort(TRuntimeNode flow, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
- if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
+ }
+
+ return BuildListNth(__func__, flow, count, ascending, keyExtractor);
+}
+
+TRuntimeNode TProgramBuilder::TopSort(TRuntimeNode flow, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
+ if (const auto flowType = flow.GetStaticType(); flowType->IsFlow() || flowType->IsStream()) {
auto itemType = flowType->IsFlow() ? AS_TYPE(TFlowType, flowType)->GetItemType() : AS_TYPE(TStreamType, flowType)->GetItemType();
const auto finalKeyExtractor = [&](TRuntimeNode item) {
return keyExtractor(Unpickle(itemType, item));
@@ -1557,201 +1557,201 @@ TRuntimeNode TProgramBuilder::TopSort(TRuntimeNode flow, TRuntimeNode count, TRu
return Map(FlatMap(Condense1(flow,
[this](TRuntimeNode item) { return AsList(Pickle(item)); },
- [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
+ [this](TRuntimeNode, TRuntimeNode) { return NewDataLiteral<bool>(false); },
[&](TRuntimeNode item, TRuntimeNode state) { return KeepTop(count, state, Pickle(item), ascending, finalKeyExtractor); }
- ),
+ ),
[&](TRuntimeNode list) { return TopSort(list, count, ascending, finalKeyExtractor); }
), [&](TRuntimeNode item) {
return Unpickle(itemType, item);
});
- }
-
- if constexpr (RuntimeVersion >= 25U)
- return BuildListNth(__func__, flow, count, ascending, keyExtractor);
- else
- return BuildListSort("Sort", BuildListNth("Top", flow, count, ascending, keyExtractor), ascending, keyExtractor);
-}
-
-TRuntimeNode TProgramBuilder::KeepTop(TRuntimeNode count, TRuntimeNode list, TRuntimeNode item, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList(), "Expected list.");
-
- const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
-
- ThrowIfListOfVoid(itemType);
- MKQL_ENSURE(count.GetStaticType()->IsData(), "Expected data");
- MKQL_ENSURE(static_cast<const TDataType&>(*count.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
-
- MKQL_ENSURE(itemType->IsSameType(*item.GetStaticType()), "Types of list and item are different.");
-
- const auto ascendingType = ascending.GetStaticType();
- const auto itemArg = Arg(itemType);
-
- auto key = keyExtractor(itemArg);
- const auto hotkey = Arg(key.GetStaticType());
-
- if (ascendingType->IsTuple()) {
- const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
- if (ascendingTuple->GetElementsCount() == 0) {
- return If(AggrLess(Length(list), count), Append(list, item), list);
- }
-
- if (ascendingTuple->GetElementsCount() == 1) {
- ascending = Nth(ascending, 0);
- key = Nth(key, 0);
- }
- }
-
- TCallableBuilder callableBuilder(Env, __func__, listType);
- callableBuilder.Add(count);
- callableBuilder.Add(list);
- callableBuilder.Add(item);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(key);
- callableBuilder.Add(ascending);
- callableBuilder.Add(hotkey);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+ }
+
+ if constexpr (RuntimeVersion >= 25U)
+ return BuildListNth(__func__, flow, count, ascending, keyExtractor);
+ else
+ return BuildListSort("Sort", BuildListNth("Top", flow, count, ascending, keyExtractor), ascending, keyExtractor);
+}
+
+TRuntimeNode TProgramBuilder::KeepTop(TRuntimeNode count, TRuntimeNode list, TRuntimeNode item, TRuntimeNode ascending, const TUnaryLambda& keyExtractor) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList(), "Expected list.");
+
+ const auto itemType = static_cast<const TListType&>(*listType).GetItemType();
+
+ ThrowIfListOfVoid(itemType);
+ MKQL_ENSURE(count.GetStaticType()->IsData(), "Expected data");
+ MKQL_ENSURE(static_cast<const TDataType&>(*count.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
+
+ MKQL_ENSURE(itemType->IsSameType(*item.GetStaticType()), "Types of list and item are different.");
+
+ const auto ascendingType = ascending.GetStaticType();
+ const auto itemArg = Arg(itemType);
+
+ auto key = keyExtractor(itemArg);
+ const auto hotkey = Arg(key.GetStaticType());
+
+ if (ascendingType->IsTuple()) {
+ const auto ascendingTuple = AS_TYPE(TTupleType, ascendingType);
+ if (ascendingTuple->GetElementsCount() == 0) {
+ return If(AggrLess(Length(list), count), Append(list, item), list);
+ }
+
+ if (ascendingTuple->GetElementsCount() == 1) {
+ ascending = Nth(ascending, 0);
+ key = Nth(key, 0);
+ }
+ }
+
+ TCallableBuilder callableBuilder(Env, __func__, listType);
+ callableBuilder.Add(count);
+ callableBuilder.Add(list);
+ callableBuilder.Add(item);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(key);
+ callableBuilder.Add(ascending);
+ callableBuilder.Add(hotkey);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::Contains(TRuntimeNode dict, TRuntimeNode key) {
- if constexpr (RuntimeVersion >= 25U)
- if (!dict.GetStaticType()->IsDict())
- return DataCompare(__func__, dict, key);
-
- const auto keyType = AS_TYPE(TDictType, dict.GetStaticType())->GetKeyType();
- MKQL_ENSURE(keyType->IsSameType(*key.GetStaticType()), "Key type mismatch. Requred: " << *keyType << ", but got: " << *key.GetStaticType());
-
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<bool>::Id));
- callableBuilder.Add(dict);
- callableBuilder.Add(key);
- return TRuntimeNode(callableBuilder.Build(), false);
+ if constexpr (RuntimeVersion >= 25U)
+ if (!dict.GetStaticType()->IsDict())
+ return DataCompare(__func__, dict, key);
+
+ const auto keyType = AS_TYPE(TDictType, dict.GetStaticType())->GetKeyType();
+ MKQL_ENSURE(keyType->IsSameType(*key.GetStaticType()), "Key type mismatch. Requred: " << *keyType << ", but got: " << *key.GetStaticType());
+
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<bool>::Id));
+ callableBuilder.Add(dict);
+ callableBuilder.Add(key);
+ return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Lookup(TRuntimeNode dict, TRuntimeNode key) {
- const auto dictType = AS_TYPE(TDictType, dict.GetStaticType());
- const auto keyType = dictType->GetKeyType();
- MKQL_ENSURE(keyType->IsSameType(*key.GetStaticType()), "Key type mismatch. Requred: " << *keyType << ", but got: " << *key.GetStaticType());
+ const auto dictType = AS_TYPE(TDictType, dict.GetStaticType());
+ const auto keyType = dictType->GetKeyType();
+ MKQL_ENSURE(keyType->IsSameType(*key.GetStaticType()), "Key type mismatch. Requred: " << *keyType << ", but got: " << *key.GetStaticType());
- TCallableBuilder callableBuilder(Env, __func__, NewOptionalType(dictType->GetPayloadType()));
- callableBuilder.Add(dict);
- callableBuilder.Add(key);
- return TRuntimeNode(callableBuilder.Build(), false);
+ TCallableBuilder callableBuilder(Env, __func__, NewOptionalType(dictType->GetPayloadType()));
+ callableBuilder.Add(dict);
+ callableBuilder.Add(key);
+ return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict, EDictItems mode) {
- const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
- TType* itemType;
- switch (mode) {
- case EDictItems::Both: {
- const std::array<TType*, 2U> tupleTypes = {{ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() }};
- itemType = NewTupleType(tupleTypes);
- break;
- }
- case EDictItems::Keys: itemType = dictTypeChecked->GetKeyType(); break;
- case EDictItems::Payloads: itemType = dictTypeChecked->GetPayloadType(); break;
- }
-
- TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
- callableBuilder.Add(dict);
- callableBuilder.Add(NewDataLiteral((ui32)mode));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Both);
- }
- const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
- const auto itemType = NewTupleType({ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() });
- TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
- callableBuilder.Add(dict);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::DictKeys(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Keys);
- }
- const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
- TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetKeyType()));
- callableBuilder.Add(dict);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::DictPayloads(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Payloads);
- }
- const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
- TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetPayloadType()));
- callableBuilder.Add(dict);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+ const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
+ TType* itemType;
+ switch (mode) {
+ case EDictItems::Both: {
+ const std::array<TType*, 2U> tupleTypes = {{ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() }};
+ itemType = NewTupleType(tupleTypes);
+ break;
+ }
+ case EDictItems::Keys: itemType = dictTypeChecked->GetKeyType(); break;
+ case EDictItems::Payloads: itemType = dictTypeChecked->GetPayloadType(); break;
+ }
+
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
+ callableBuilder.Add(dict);
+ callableBuilder.Add(NewDataLiteral((ui32)mode));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict) {
+ if constexpr (RuntimeVersion < 6U) {
+ return DictItems(dict, EDictItems::Both);
+ }
+ const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
+ const auto itemType = NewTupleType({ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() });
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
+ callableBuilder.Add(dict);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::DictKeys(TRuntimeNode dict) {
+ if constexpr (RuntimeVersion < 6U) {
+ return DictItems(dict, EDictItems::Keys);
+ }
+ const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetKeyType()));
+ callableBuilder.Add(dict);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::DictPayloads(TRuntimeNode dict) {
+ if constexpr (RuntimeVersion < 6U) {
+ return DictItems(dict, EDictItems::Payloads);
+ }
+ const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetPayloadType()));
+ callableBuilder.Add(dict);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::ToIndexDict(TRuntimeNode list) {
- const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
+ const auto itemType = AS_TYPE(TListType, list.GetStaticType())->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto keyType = NewDataType(NUdf::TDataType<ui64>::Id);
- const auto dictType = NewDictType(keyType, itemType, false);
- TCallableBuilder callableBuilder(Env, __func__, dictType);
- callableBuilder.Add(list);
- return TRuntimeNode(callableBuilder.Build(), false);
+ const auto keyType = NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto dictType = NewDictType(keyType, itemType, false);
+ TCallableBuilder callableBuilder(Env, __func__, dictType);
+ callableBuilder.Add(list);
+ return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::JoinDict(TRuntimeNode dict1, bool isMulti1, TRuntimeNode dict2, bool isMulti2, EJoinKind joinKind) {
- const auto dict1type = AS_TYPE(TDictType, dict1);
- const auto dict2type = AS_TYPE(TDictType, dict2);
+ const auto dict1type = AS_TYPE(TDictType, dict1);
+ const auto dict2type = AS_TYPE(TDictType, dict2);
MKQL_ENSURE(dict1type->GetKeyType()->IsSameType(*dict2type->GetKeyType()), "Dict key types must be the same");
- if (joinKind == EJoinKind::RightOnly || joinKind == EJoinKind::RightSemi)
- MKQL_ENSURE(dict1type->GetPayloadType()->IsVoid(), "Void required for first dict payload.");
- else if (isMulti1)
- MKQL_ENSURE(dict1type->GetPayloadType()->IsList(), "List required for first dict payload.");
+ if (joinKind == EJoinKind::RightOnly || joinKind == EJoinKind::RightSemi)
+ MKQL_ENSURE(dict1type->GetPayloadType()->IsVoid(), "Void required for first dict payload.");
+ else if (isMulti1)
+ MKQL_ENSURE(dict1type->GetPayloadType()->IsList(), "List required for first dict payload.");
- if (joinKind == EJoinKind::LeftOnly || joinKind == EJoinKind::LeftSemi)
- MKQL_ENSURE(dict2type->GetPayloadType()->IsVoid(), "Void required for second dict payload.");
- else if (isMulti2)
- MKQL_ENSURE(dict2type->GetPayloadType()->IsList(), "List required for second dict payload.");
+ if (joinKind == EJoinKind::LeftOnly || joinKind == EJoinKind::LeftSemi)
+ MKQL_ENSURE(dict2type->GetPayloadType()->IsVoid(), "Void required for second dict payload.");
+ else if (isMulti2)
+ MKQL_ENSURE(dict2type->GetPayloadType()->IsList(), "List required for second dict payload.");
- std::array<TType*, 2> tupleItems = {{ dict1type->GetPayloadType(), dict2type->GetPayloadType() }};
- if (isMulti1 && tupleItems.front()->IsList())
- tupleItems.front() = AS_TYPE(TListType, tupleItems.front())->GetItemType();
+ std::array<TType*, 2> tupleItems = {{ dict1type->GetPayloadType(), dict2type->GetPayloadType() }};
+ if (isMulti1 && tupleItems.front()->IsList())
+ tupleItems.front() = AS_TYPE(TListType, tupleItems.front())->GetItemType();
- if (isMulti2 && tupleItems.back()->IsList())
- tupleItems.back() = AS_TYPE(TListType, tupleItems.back())->GetItemType();
+ if (isMulti2 && tupleItems.back()->IsList())
+ tupleItems.back() = AS_TYPE(TListType, tupleItems.back())->GetItemType();
- if (IsLeftOptional(joinKind))
- tupleItems.front() = NewOptionalType(tupleItems.front());
+ if (IsLeftOptional(joinKind))
+ tupleItems.front() = NewOptionalType(tupleItems.front());
- if (IsRightOptional(joinKind))
- tupleItems.back() = NewOptionalType(tupleItems.back());
+ if (IsRightOptional(joinKind))
+ tupleItems.back() = NewOptionalType(tupleItems.back());
TType* itemType;
- if (joinKind == EJoinKind::LeftOnly || joinKind == EJoinKind::LeftSemi)
- itemType = tupleItems.front();
- else if (joinKind == EJoinKind::RightOnly || joinKind == EJoinKind::RightSemi)
- itemType = tupleItems.back();
- else
+ if (joinKind == EJoinKind::LeftOnly || joinKind == EJoinKind::LeftSemi)
+ itemType = tupleItems.front();
+ else if (joinKind == EJoinKind::RightOnly || joinKind == EJoinKind::RightSemi)
+ itemType = tupleItems.back();
+ else
itemType = NewTupleType(tupleItems);
- const auto returnType = NewListType(itemType);
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ const auto returnType = NewListType(itemType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
callableBuilder.Add(dict1);
callableBuilder.Add(dict2);
- callableBuilder.Add(NewDataLiteral(isMulti1));
- callableBuilder.Add(NewDataLiteral(isMulti2));
- callableBuilder.Add(NewDataLiteral(ui32(joinKind)));
+ callableBuilder.Add(NewDataLiteral(isMulti1));
+ callableBuilder.Add(NewDataLiteral(isMulti2));
+ callableBuilder.Add(NewDataLiteral(ui32(joinKind)));
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::ToSortedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
- return ToDict(list, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
+TRuntimeNode TProgramBuilder::ToSortedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
+ const TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
+ return ToDict(list, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
}
-TRuntimeNode TProgramBuilder::ToHashedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
- return ToDict(list, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
+TRuntimeNode TProgramBuilder::ToHashedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
+ const TUnaryLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
+ return ToDict(list, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
}
TRuntimeNode TProgramBuilder::SqueezeToSortedDict(TRuntimeNode stream, bool all, const TUnaryLambda& keySelector,
@@ -1764,28 +1764,28 @@ TRuntimeNode TProgramBuilder::SqueezeToHashedDict(TRuntimeNode stream, bool all,
return SqueezeToDict(stream, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
}
-TRuntimeNode TProgramBuilder::NarrowSqueezeToSortedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
- return NarrowSqueezeToDict(stream, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
-}
-
-TRuntimeNode TProgramBuilder::NarrowSqueezeToHashedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
- return NarrowSqueezeToDict(stream, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
-}
-
-TRuntimeNode TProgramBuilder::SqueezeToList(TRuntimeNode flow, TRuntimeNode limit) {
- if constexpr (RuntimeVersion < 25U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto itemType = AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType();
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewListType(itemType)));
- callableBuilder.Add(flow);
- callableBuilder.Add(limit);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::NarrowSqueezeToSortedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
+ return NarrowSqueezeToDict(stream, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
+}
+
+TRuntimeNode TProgramBuilder::NarrowSqueezeToHashedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, bool isCompact, ui64 itemsCountHint) {
+ return NarrowSqueezeToDict(stream, all, keySelector, payloadSelector, __func__, isCompact, itemsCountHint);
+}
+
+TRuntimeNode TProgramBuilder::SqueezeToList(TRuntimeNode flow, TRuntimeNode limit) {
+ if constexpr (RuntimeVersion < 25U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto itemType = AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType();
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewListType(itemType)));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(limit);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::Append(TRuntimeNode list, TRuntimeNode item) {
auto listType = list.GetStaticType();
AS_TYPE(TListType, listType);
@@ -1794,7 +1794,7 @@ TRuntimeNode TProgramBuilder::Append(TRuntimeNode list, TRuntimeNode item) {
auto itemType = item.GetStaticType();
MKQL_ENSURE(itemType->IsSameType(*listDetailedType.GetItemType()), "Types of list and item are different");
- TCallableBuilder callableBuilder(Env, __func__, listType);
+ TCallableBuilder callableBuilder(Env, __func__, listType);
callableBuilder.Add(list);
callableBuilder.Add(item);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -1808,7 +1808,7 @@ TRuntimeNode TProgramBuilder::Prepend(TRuntimeNode item, TRuntimeNode list) {
auto itemType = item.GetStaticType();
MKQL_ENSURE(itemType->IsSameType(*listDetailedType.GetItemType()), "Types of list and item are different");
- TCallableBuilder callableBuilder(Env, __func__, listType);
+ TCallableBuilder callableBuilder(Env, __func__, listType);
callableBuilder.Add(item);
callableBuilder.Add(list);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -1822,19 +1822,19 @@ TRuntimeNode TProgramBuilder::Extend(TRuntimeNode list1, TRuntimeNode list2) {
TRuntimeNode TProgramBuilder::Extend(const TArrayRef<const TRuntimeNode>& lists) {
MKQL_ENSURE(lists.size() > 0, "Expected at least 1 list/stream");
if (lists.size() == 1) {
- return lists.front();
+ return lists.front();
}
- auto listType = lists.front().GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected either flow, list or stream");
+ auto listType = lists.front().GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected either flow, list or stream");
for (ui32 i = 1; i < lists.size(); ++i) {
auto listType2 = lists[i].GetStaticType();
- MKQL_ENSURE(listType->IsSameType(*listType2), "Types of flows are different, left: " <<
+ MKQL_ENSURE(listType->IsSameType(*listType2), "Types of flows are different, left: " <<
PrintNode(listType, true) << ", right: " <<
PrintNode(listType2, true));
}
- TCallableBuilder callableBuilder(Env, __func__, listType);
+ TCallableBuilder callableBuilder(Env, __func__, listType);
for (auto list : lists) {
callableBuilder.Add(list);
}
@@ -1842,21 +1842,21 @@ TRuntimeNode TProgramBuilder::Extend(const TArrayRef<const TRuntimeNode>& lists)
return TRuntimeNode(callableBuilder.Build(), false);
}
-template<>
+template<>
TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::String>(const NUdf::TStringRef& data) const {
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<const char*>::Id, Env), true);
-}
+}
-template<>
+template<>
TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Utf8>(const NUdf::TStringRef& data) const {
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<NUdf::TUtf8>::Id, Env), true);
}
-template<>
+template<>
TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Yson>(const NUdf::TStringRef& data) const {
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<NUdf::TYson>::Id, Env), true);
-}
-
+}
+
template<>
TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Json>(const NUdf::TStringRef& data) const {
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<NUdf::TJson>::Id, Env), true);
@@ -1892,13 +1892,13 @@ TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::Interval>(const NU
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<NUdf::TInterval>::Id, Env), true);
}
-template<>
-TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::DyNumber>(const NUdf::TStringRef& data) const {
+template<>
+TRuntimeNode TProgramBuilder::NewDataLiteral<NUdf::EDataSlot::DyNumber>(const NUdf::TStringRef& data) const {
return TRuntimeNode(BuildDataLiteral(data, NUdf::TDataType<NUdf::TDyNumber>::Id, Env), true);
-}
-
-TRuntimeNode TProgramBuilder::NewDecimalLiteral(NYql::NDecimal::TInt128 data, ui8 precision, ui8 scale) const {
- return TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(data), TDataDecimalType::Create(precision, scale, Env), Env), true);
+}
+
+TRuntimeNode TProgramBuilder::NewDecimalLiteral(NYql::NDecimal::TInt128 data, ui8 precision, ui8 scale) const {
+ return TRuntimeNode(TDataLiteral::Create(NUdf::TUnboxedValuePod(data), TDataDecimalType::Create(precision, scale, Env), Env), true);
}
TRuntimeNode TProgramBuilder::NewOptional(TRuntimeNode data) {
@@ -1937,7 +1937,7 @@ TType* TProgramBuilder::NewEmptyStructType() {
return Env.GetEmptyStruct()->GetGenericType();
}
-TType* TProgramBuilder::NewStructType(TType* baseStructType, const std::string_view& memberName, TType* memberType) {
+TType* TProgramBuilder::NewStructType(TType* baseStructType, const std::string_view& memberName, TType* memberType) {
MKQL_ENSURE(baseStructType->IsStruct(), "Expected struct type");
const auto& detailedBaseStructType = static_cast<const TStructType&>(*baseStructType);
@@ -1951,7 +1951,7 @@ TType* TProgramBuilder::NewStructType(TType* baseStructType, const std::string_v
return builder.Build();
}
-TType* TProgramBuilder::NewStructType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes) {
+TType* TProgramBuilder::NewStructType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes) {
TStructTypeBuilder builder(Env);
builder.Reserve(memberTypes.size());
for (auto& x : memberTypes) {
@@ -1961,15 +1961,15 @@ TType* TProgramBuilder::NewStructType(const TArrayRef<const std::pair<std::strin
return builder.Build();
}
-TType* TProgramBuilder::NewArrayType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes) {
- return NewStructType(memberTypes);
-}
-
-TRuntimeNode TProgramBuilder::NewStruct(const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members) {
- if (members.empty()) {
- return NewEmptyStruct();
- }
-
+TType* TProgramBuilder::NewArrayType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes) {
+ return NewStructType(memberTypes);
+}
+
+TRuntimeNode TProgramBuilder::NewStruct(const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members) {
+ if (members.empty()) {
+ return NewEmptyStruct();
+ }
+
TStructLiteralBuilder builder(Env);
for (auto x : members) {
builder.Add(x.first, x.second);
@@ -1978,14 +1978,14 @@ TRuntimeNode TProgramBuilder::NewStruct(const TArrayRef<const std::pair<std::str
return TRuntimeNode(builder.Build(), true);
}
-TRuntimeNode TProgramBuilder::NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members) {
- const auto detailedStructType = AS_TYPE(TStructType, structType);
+TRuntimeNode TProgramBuilder::NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members) {
+ const auto detailedStructType = AS_TYPE(TStructType, structType);
MKQL_ENSURE(members.size() == detailedStructType->GetMembersCount(), "Mismatch count of members");
- if (members.empty()) {
- return NewEmptyStruct();
- }
-
- std::vector<TRuntimeNode> values(detailedStructType->GetMembersCount());
+ if (members.empty()) {
+ return NewEmptyStruct();
+ }
+
+ std::vector<TRuntimeNode> values(detailedStructType->GetMembersCount());
for (ui32 i = 0; i < detailedStructType->GetMembersCount(); ++i) {
const auto& name = members[i].first;
ui32 index = detailedStructType->GetMemberIndex(name);
@@ -2010,14 +2010,14 @@ TRuntimeNode TProgramBuilder::NewList(TType* itemType, const TArrayRef<const TRu
return TRuntimeNode(builder.Build(), true);
}
-TType* TProgramBuilder::NewDataType(NUdf::TDataTypeId schemeType, bool optional) {
- return optional ? NewOptionalType(TDataType::Create(schemeType, Env)) : TDataType::Create(schemeType, Env);
+TType* TProgramBuilder::NewDataType(NUdf::TDataTypeId schemeType, bool optional) {
+ return optional ? NewOptionalType(TDataType::Create(schemeType, Env)) : TDataType::Create(schemeType, Env);
+}
+
+TType* TProgramBuilder::NewDecimalType(ui8 precision, ui8 scale) {
+ return TDataDecimalType::Create(precision, scale, Env);
}
-TType* TProgramBuilder::NewDecimalType(ui8 precision, ui8 scale) {
- return TDataDecimalType::Create(precision, scale, Env);
-}
-
TType* TProgramBuilder::NewOptionalType(TType* itemType) {
return TOptionalType::Create(itemType, Env);
}
@@ -2030,10 +2030,10 @@ TType* TProgramBuilder::NewStreamType(TType* itemType) {
return TStreamType::Create(itemType, Env);
}
-TType* TProgramBuilder::NewFlowType(TType* itemType) {
- return TFlowType::Create(itemType, Env);
-}
-
+TType* TProgramBuilder::NewFlowType(TType* itemType) {
+ return TFlowType::Create(itemType, Env);
+}
+
TType* TProgramBuilder::NewBlockType(TType* itemType, TBlockType::EShape shape) {
bool isOptional;
auto* dataType = UnpackOptionalData(itemType, isOptional);
@@ -2042,7 +2042,7 @@ TType* TProgramBuilder::NewBlockType(TType* itemType, TBlockType::EShape shape)
return TBlockType::Create(itemType, shape, Env);
}
-TType* TProgramBuilder::NewTaggedType(TType* baseType, const std::string_view& tag) {
+TType* TProgramBuilder::NewTaggedType(TType* baseType, const std::string_view& tag) {
return TTaggedType::Create(baseType, tag, Env);
}
@@ -2068,10 +2068,10 @@ TType* TProgramBuilder::NewTupleType(const TArrayRef<TType* const>& elements) {
return TTupleType::Create(elements.size(), elements.data(), Env);
}
-TType* TProgramBuilder::NewArrayType(const TArrayRef<TType* const>& elements) {
- return NewTupleType(elements);
-}
-
+TType* TProgramBuilder::NewArrayType(const TArrayRef<TType* const>& elements) {
+ return NewTupleType(elements);
+}
+
TRuntimeNode TProgramBuilder::NewTuple(TType* tupleType, const TArrayRef<const TRuntimeNode>& elements) {
MKQL_ENSURE(tupleType->IsTuple(), "Expected tuple type");
@@ -2079,7 +2079,7 @@ TRuntimeNode TProgramBuilder::NewTuple(TType* tupleType, const TArrayRef<const T
}
TRuntimeNode TProgramBuilder::NewTuple(const TArrayRef<const TRuntimeNode>& elements) {
- std::vector<TType*> types;
+ std::vector<TType*> types;
types.reserve(elements.size());
for (auto elem : elements) {
types.push_back(elem.GetStaticType());
@@ -2088,7 +2088,7 @@ TRuntimeNode TProgramBuilder::NewTuple(const TArrayRef<const TRuntimeNode>& elem
return NewTuple(NewTupleType(types), elements);
}
-TType* TProgramBuilder::NewResourceType(const std::string_view& tag) {
+TType* TProgramBuilder::NewResourceType(const std::string_view& tag) {
return TResourceType::Create(tag, Env);
}
@@ -2097,13 +2097,13 @@ TType* TProgramBuilder::NewVariantType(TType* underlyingType) {
}
TRuntimeNode TProgramBuilder::NewVariant(TRuntimeNode item, ui32 index, TType* variantType) {
- const auto type = AS_TYPE(TVariantType, variantType);
+ const auto type = AS_TYPE(TVariantType, variantType);
MKQL_ENSURE(type->GetUnderlyingType()->IsTuple(), "Expected tuple as underlying type");
return TRuntimeNode(TVariantLiteral::Create(item, index, type, Env), true);
}
-TRuntimeNode TProgramBuilder::NewVariant(TRuntimeNode item, const std::string_view& member, TType* variantType) {
- const auto type = AS_TYPE(TVariantType, variantType);
+TRuntimeNode TProgramBuilder::NewVariant(TRuntimeNode item, const std::string_view& member, TType* variantType) {
+ const auto type = AS_TYPE(TVariantType, variantType);
MKQL_ENSURE(type->GetUnderlyingType()->IsStruct(), "Expected struct as underlying type");
ui32 index = AS_TYPE(TStructType, type->GetUnderlyingType())->GetMemberIndex(member);
return TRuntimeNode(TVariantLiteral::Create(item, index, type, Env), true);
@@ -2111,7 +2111,7 @@ TRuntimeNode TProgramBuilder::NewVariant(TRuntimeNode item, const std::string_vi
TRuntimeNode TProgramBuilder::Coalesce(TRuntimeNode data, TRuntimeNode defaultData) {
bool isOptional = false;
- const auto dataType = UnpackOptional(data, isOptional);
+ const auto dataType = UnpackOptional(data, isOptional);
if (!isOptional) {
MKQL_ENSURE(data.GetStaticType()->IsSameType(*defaultData.GetStaticType()), "Mismatch operand types");
return data;
@@ -2119,17 +2119,17 @@ TRuntimeNode TProgramBuilder::Coalesce(TRuntimeNode data, TRuntimeNode defaultDa
if (!dataType->IsSameType(*defaultData.GetStaticType())) {
bool isOptionalDefault;
- const auto defaultDataType = UnpackOptional(defaultData, isOptionalDefault);
+ const auto defaultDataType = UnpackOptional(defaultData, isOptionalDefault);
MKQL_ENSURE(dataType->IsSameType(*defaultDataType), "Mismatch operand types");
}
- TCallableBuilder callableBuilder(Env, __func__, defaultData.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, defaultData.GetStaticType());
callableBuilder.Add(data);
callableBuilder.Add(defaultData);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Unwrap(TRuntimeNode optional, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column) {
+TRuntimeNode TProgramBuilder::Unwrap(TRuntimeNode optional, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column) {
bool isOptional;
auto underlyingType = UnpackOptional(optional, isOptional);
MKQL_ENSURE(isOptional, "Expected optional");
@@ -2138,9 +2138,9 @@ TRuntimeNode TProgramBuilder::Unwrap(TRuntimeNode optional, TRuntimeNode message
MKQL_ENSURE(messageType->IsData(), "Expected data");
const auto& messageTypeData = static_cast<const TDataType&>(*messageType);
- MKQL_ENSURE(messageTypeData.GetSchemeType() == NUdf::TDataType<char*>::Id || messageTypeData.GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected string or utf8.");
+ MKQL_ENSURE(messageTypeData.GetSchemeType() == NUdf::TDataType<char*>::Id || messageTypeData.GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected string or utf8.");
- TCallableBuilder callableBuilder(Env, __func__, underlyingType);
+ TCallableBuilder callableBuilder(Env, __func__, underlyingType);
callableBuilder.Add(optional);
callableBuilder.Add(message);
callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
@@ -2150,299 +2150,299 @@ TRuntimeNode TProgramBuilder::Unwrap(TRuntimeNode optional, TRuntimeNode message
}
TRuntimeNode TProgramBuilder::Increment(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- bool isOptional;
- const auto type = UnpackOptionalData(data, isOptional);
-
- if (type->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
- return Invoke(__func__, data.GetStaticType(), args);
-
- return Invoke(TString("Inc_") += ::ToString(static_cast<TDataDecimalType*>(type)->GetParams().first), data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ bool isOptional;
+ const auto type = UnpackOptionalData(data, isOptional);
+
+ if (type->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return Invoke(__func__, data.GetStaticType(), args);
+
+ return Invoke(TString("Inc_") += ::ToString(static_cast<TDataDecimalType*>(type)->GetParams().first), data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Decrement(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- bool isOptional;
- const auto type = UnpackOptionalData(data, isOptional);
-
- if (type->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
- return Invoke(__func__, data.GetStaticType(), args);
-
- return Invoke(TString("Dec_") += ::ToString(static_cast<TDataDecimalType*>(type)->GetParams().first), data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ bool isOptional;
+ const auto type = UnpackOptionalData(data, isOptional);
+
+ if (type->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return Invoke(__func__, data.GetStaticType(), args);
+
+ return Invoke(TString("Dec_") += ::ToString(static_cast<TDataDecimalType*>(type)->GetParams().first), data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Abs(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Plus(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Minus(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Add(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
-
- bool isOptionalLeft;
- const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
-
- if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
-
- const auto decimalType = static_cast<TDataDecimalType*>(leftType);
- bool isOptionalRight;
- const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
- MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
- const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(decimalType) : decimalType;
- return Invoke(TString("Add_") += ::ToString(decimalType->GetParams().first), resultType, args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+
+ bool isOptionalLeft;
+ const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
+
+ if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+
+ const auto decimalType = static_cast<TDataDecimalType*>(leftType);
+ bool isOptionalRight;
+ const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
+ MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
+ const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(decimalType) : decimalType;
+ return Invoke(TString("Add_") += ::ToString(decimalType->GetParams().first), resultType, args);
}
TRuntimeNode TProgramBuilder::Sub(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
-
- bool isOptionalLeft;
- const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
-
- if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
-
- const auto decimalType = static_cast<TDataDecimalType*>(leftType);
- bool isOptionalRight;
- const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
- MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
- const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(decimalType) : decimalType;
- return Invoke(TString("Sub_") += ::ToString(decimalType->GetParams().first), resultType, args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+
+ bool isOptionalLeft;
+ const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
+
+ if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+
+ const auto decimalType = static_cast<TDataDecimalType*>(leftType);
+ bool isOptionalRight;
+ const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
+ MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
+ const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(decimalType) : decimalType;
+ return Invoke(TString("Sub_") += ::ToString(decimalType->GetParams().first), resultType, args);
}
TRuntimeNode TProgramBuilder::Mul(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
}
TRuntimeNode TProgramBuilder::Div(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- auto resultType = BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType());
- if (resultType->IsData() && !(NUdf::GetDataTypeInfo(*static_cast<TDataType*>(resultType)->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::FloatType | NUdf::EDataTypeFeatures::DecimalType))) {
- resultType = NewOptionalType(resultType);
- }
- return Invoke(__func__, resultType, args);
-}
-
-TRuntimeNode TProgramBuilder::DecimalDiv(TRuntimeNode data1, TRuntimeNode data2) {
- bool isOptionalLeft, isOptionalRight;
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
- const auto rightType = UnpackOptionalData(data2, isOptionalRight);
-
- if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
- else
- MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
-
- const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
-
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- callableBuilder.Add(data1);
- callableBuilder.Add(data2);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::DecimalMod(TRuntimeNode data1, TRuntimeNode data2) {
- bool isOptionalLeft, isOptionalRight;
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
- const auto rightType = UnpackOptionalData(data2, isOptionalRight);
-
- if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
- else
- MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
-
- const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
-
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- callableBuilder.Add(data1);
- callableBuilder.Add(data2);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::DecimalMul(TRuntimeNode data1, TRuntimeNode data2) {
- bool isOptionalLeft, isOptionalRight;
- const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
- const auto rightType = UnpackOptionalData(data2, isOptionalRight);
-
- if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
- MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
- else
- MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
-
- const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
-
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- callableBuilder.Add(data1);
- callableBuilder.Add(data2);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::AllOf(TRuntimeNode list, const TUnaryLambda& predicate) {
- return Not(NotAllOf(list, predicate));
-}
-
-TRuntimeNode TProgramBuilder::NotAllOf(TRuntimeNode list, const TUnaryLambda& predicate) {
- return Exists(ToOptional(SkipWhile(list, predicate)));
-}
-
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ auto resultType = BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType());
+ if (resultType->IsData() && !(NUdf::GetDataTypeInfo(*static_cast<TDataType*>(resultType)->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::FloatType | NUdf::EDataTypeFeatures::DecimalType))) {
+ resultType = NewOptionalType(resultType);
+ }
+ return Invoke(__func__, resultType, args);
+}
+
+TRuntimeNode TProgramBuilder::DecimalDiv(TRuntimeNode data1, TRuntimeNode data2) {
+ bool isOptionalLeft, isOptionalRight;
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
+ const auto rightType = UnpackOptionalData(data2, isOptionalRight);
+
+ if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+ else
+ MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
+
+ const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
+
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ callableBuilder.Add(data1);
+ callableBuilder.Add(data2);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::DecimalMod(TRuntimeNode data1, TRuntimeNode data2) {
+ bool isOptionalLeft, isOptionalRight;
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
+ const auto rightType = UnpackOptionalData(data2, isOptionalRight);
+
+ if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+ else
+ MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
+
+ const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
+
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ callableBuilder.Add(data1);
+ callableBuilder.Add(data2);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::DecimalMul(TRuntimeNode data1, TRuntimeNode data2) {
+ bool isOptionalLeft, isOptionalRight;
+ const auto leftType = static_cast<TDataDecimalType*>(UnpackOptionalData(data1, isOptionalLeft));
+ const auto rightType = UnpackOptionalData(data2, isOptionalRight);
+
+ if (rightType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id)
+ MKQL_ENSURE(static_cast<TDataDecimalType*>(rightType)->IsSameType(*leftType), "Operands type mismatch");
+ else
+ MKQL_ENSURE(NUdf::GetDataTypeInfo(*rightType->GetDataSlot()).Features & NUdf::IntegralType, "Operands type mismatch");
+
+ const auto returnType = isOptionalLeft || isOptionalRight ? NewOptionalType(leftType) : leftType;
+
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ callableBuilder.Add(data1);
+ callableBuilder.Add(data2);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::AllOf(TRuntimeNode list, const TUnaryLambda& predicate) {
+ return Not(NotAllOf(list, predicate));
+}
+
+TRuntimeNode TProgramBuilder::NotAllOf(TRuntimeNode list, const TUnaryLambda& predicate) {
+ return Exists(ToOptional(SkipWhile(list, predicate)));
+}
+
TRuntimeNode TProgramBuilder::BitNot(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::CountBits(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, data.GetStaticType(), args);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, data.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::BitAnd(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
}
TRuntimeNode TProgramBuilder::BitOr(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
}
TRuntimeNode TProgramBuilder::BitXor(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(__func__, BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType()), args);
}
TRuntimeNode TProgramBuilder::ShiftLeft(TRuntimeNode arg, TRuntimeNode bits) {
- const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
- return Invoke(__func__, arg.GetStaticType(), args);
+ const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
+ return Invoke(__func__, arg.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::RotLeft(TRuntimeNode arg, TRuntimeNode bits) {
- const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
- return Invoke(__func__, arg.GetStaticType(), args);
+ const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
+ return Invoke(__func__, arg.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::ShiftRight(TRuntimeNode arg, TRuntimeNode bits) {
- const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
- return Invoke(__func__, arg.GetStaticType(), args);
+ const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
+ return Invoke(__func__, arg.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::RotRight(TRuntimeNode arg, TRuntimeNode bits) {
- const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
- return Invoke(__func__, arg.GetStaticType(), args);
+ const std::array<TRuntimeNode, 2> args = {{ arg, bits }};
+ return Invoke(__func__, arg.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::Mod(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- auto resultType = BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType());
- if (resultType->IsData() && !(NUdf::GetDataTypeInfo(*static_cast<TDataType*>(resultType)->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::FloatType | NUdf::EDataTypeFeatures::DecimalType))) {
- resultType = NewOptionalType(resultType);
- }
- return Invoke(__func__, resultType, args);
-}
-
-TRuntimeNode TProgramBuilder::BuildMinMax(const std::string_view& callableName, const TRuntimeNode* data, size_t size) {
- switch (size) {
- case 0U: return NewNull();
- case 1U: return *data;
- case 2U: return InvokeBinary(callableName, ChooseCommonType(data[0U].GetStaticType(), data[1U].GetStaticType()), data[0U], data[1U]);
- default: break;
- }
-
- const auto half = size >> 1U;
- const std::array<TRuntimeNode, 2U> args = {{ BuildMinMax(callableName, data, half), BuildMinMax(callableName, data + half, size - half) }};
- return BuildMinMax(callableName, args.data(), args.size());
-}
-
-TRuntimeNode TProgramBuilder::Min(const TArrayRef<const TRuntimeNode>& args) {
- return BuildMinMax(__func__, args.data(), args.size());
-}
-
-TRuntimeNode TProgramBuilder::Max(const TArrayRef<const TRuntimeNode>& args) {
- return BuildMinMax(__func__, args.data(), args.size());
-}
-
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ auto resultType = BuildArithmeticCommonType(data1.GetStaticType(), data2.GetStaticType());
+ if (resultType->IsData() && !(NUdf::GetDataTypeInfo(*static_cast<TDataType*>(resultType)->GetDataSlot()).Features & (NUdf::EDataTypeFeatures::FloatType | NUdf::EDataTypeFeatures::DecimalType))) {
+ resultType = NewOptionalType(resultType);
+ }
+ return Invoke(__func__, resultType, args);
+}
+
+TRuntimeNode TProgramBuilder::BuildMinMax(const std::string_view& callableName, const TRuntimeNode* data, size_t size) {
+ switch (size) {
+ case 0U: return NewNull();
+ case 1U: return *data;
+ case 2U: return InvokeBinary(callableName, ChooseCommonType(data[0U].GetStaticType(), data[1U].GetStaticType()), data[0U], data[1U]);
+ default: break;
+ }
+
+ const auto half = size >> 1U;
+ const std::array<TRuntimeNode, 2U> args = {{ BuildMinMax(callableName, data, half), BuildMinMax(callableName, data + half, size - half) }};
+ return BuildMinMax(callableName, args.data(), args.size());
+}
+
+TRuntimeNode TProgramBuilder::Min(const TArrayRef<const TRuntimeNode>& args) {
+ return BuildMinMax(__func__, args.data(), args.size());
+}
+
+TRuntimeNode TProgramBuilder::Max(const TArrayRef<const TRuntimeNode>& args) {
+ return BuildMinMax(__func__, args.data(), args.size());
+}
+
TRuntimeNode TProgramBuilder::Min(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2U> args = {{ data1, data2 }};
- return Min(args);
+ const std::array<TRuntimeNode, 2U> args = {{ data1, data2 }};
+ return Min(args);
}
TRuntimeNode TProgramBuilder::Max(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2U> args = {{ data1, data2 }};
- return Max(args);
-}
-
-TRuntimeNode TProgramBuilder::Equals(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::NotEquals(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::Less(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::LessOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::Greater(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::GreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
- return DataCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::InvokeBinary(const std::string_view& callableName, TType* type, TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(callableName, type, args);
-}
-
-TRuntimeNode TProgramBuilder::AggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2) {
- return InvokeBinary(callableName, NewDataType(NUdf::TDataType<bool>::Id), data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::DataCompare(const std::string_view& callableName, TRuntimeNode left, TRuntimeNode right) {
- bool isOptionalLeft, isOptionalRight;
- const auto leftType = UnpackOptionalData(left, isOptionalLeft);
- const auto rightType = UnpackOptionalData(right, isOptionalRight);
-
- const auto lId = leftType->GetSchemeType();
- const auto rId = rightType->GetSchemeType();
-
- if (lId == NUdf::TDataType<NUdf::TDecimal>::Id && rId == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& lDec = static_cast<TDataDecimalType*>(leftType)->GetParams();
- const auto& rDec = static_cast<TDataDecimalType*>(rightType)->GetParams();
- if (lDec.second < rDec.second) {
- left = ToDecimal(left, std::min<ui8>(lDec.first + rDec.second - lDec.second, NYql::NDecimal::MaxPrecision), rDec.second);
- } else if (lDec.second > rDec.second) {
- right = ToDecimal(right, std::min<ui8>(rDec.first + lDec.second - rDec.second, NYql::NDecimal::MaxPrecision), lDec.second);
- }
- } else if (lId == NUdf::TDataType<NUdf::TDecimal>::Id && NUdf::GetDataTypeInfo(NUdf::GetDataSlot(rId)).Features & NUdf::EDataTypeFeatures::IntegralType) {
- const auto scale = static_cast<TDataDecimalType*>(leftType)->GetParams().second;
- right = ToDecimal(right, std::min<ui8>(NYql::NDecimal::MaxPrecision, NUdf::GetDataTypeInfo(NUdf::GetDataSlot(rId)).DecimalDigits + scale), scale);
- } else if (rId == NUdf::TDataType<NUdf::TDecimal>::Id && NUdf::GetDataTypeInfo(NUdf::GetDataSlot(lId)).Features & NUdf::EDataTypeFeatures::IntegralType) {
- const auto scale = static_cast<TDataDecimalType*>(rightType)->GetParams().second;
- left = ToDecimal(left, std::min<ui8>(NYql::NDecimal::MaxPrecision, NUdf::GetDataTypeInfo(NUdf::GetDataSlot(lId)).DecimalDigits + scale), scale);
- }
-
- const std::array<TRuntimeNode, 2> args = {{ left, right }};
- const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(NewDataType(NUdf::TDataType<bool>::Id)) : NewDataType(NUdf::TDataType<bool>::Id);
- return Invoke(callableName, resultType, args);
-}
-
+ const std::array<TRuntimeNode, 2U> args = {{ data1, data2 }};
+ return Max(args);
+}
+
+TRuntimeNode TProgramBuilder::Equals(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::NotEquals(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::Less(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::LessOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::Greater(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::GreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
+ return DataCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::InvokeBinary(const std::string_view& callableName, TType* type, TRuntimeNode data1, TRuntimeNode data2) {
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(callableName, type, args);
+}
+
+TRuntimeNode TProgramBuilder::AggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2) {
+ return InvokeBinary(callableName, NewDataType(NUdf::TDataType<bool>::Id), data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::DataCompare(const std::string_view& callableName, TRuntimeNode left, TRuntimeNode right) {
+ bool isOptionalLeft, isOptionalRight;
+ const auto leftType = UnpackOptionalData(left, isOptionalLeft);
+ const auto rightType = UnpackOptionalData(right, isOptionalRight);
+
+ const auto lId = leftType->GetSchemeType();
+ const auto rId = rightType->GetSchemeType();
+
+ if (lId == NUdf::TDataType<NUdf::TDecimal>::Id && rId == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& lDec = static_cast<TDataDecimalType*>(leftType)->GetParams();
+ const auto& rDec = static_cast<TDataDecimalType*>(rightType)->GetParams();
+ if (lDec.second < rDec.second) {
+ left = ToDecimal(left, std::min<ui8>(lDec.first + rDec.second - lDec.second, NYql::NDecimal::MaxPrecision), rDec.second);
+ } else if (lDec.second > rDec.second) {
+ right = ToDecimal(right, std::min<ui8>(rDec.first + lDec.second - rDec.second, NYql::NDecimal::MaxPrecision), lDec.second);
+ }
+ } else if (lId == NUdf::TDataType<NUdf::TDecimal>::Id && NUdf::GetDataTypeInfo(NUdf::GetDataSlot(rId)).Features & NUdf::EDataTypeFeatures::IntegralType) {
+ const auto scale = static_cast<TDataDecimalType*>(leftType)->GetParams().second;
+ right = ToDecimal(right, std::min<ui8>(NYql::NDecimal::MaxPrecision, NUdf::GetDataTypeInfo(NUdf::GetDataSlot(rId)).DecimalDigits + scale), scale);
+ } else if (rId == NUdf::TDataType<NUdf::TDecimal>::Id && NUdf::GetDataTypeInfo(NUdf::GetDataSlot(lId)).Features & NUdf::EDataTypeFeatures::IntegralType) {
+ const auto scale = static_cast<TDataDecimalType*>(rightType)->GetParams().second;
+ left = ToDecimal(left, std::min<ui8>(NYql::NDecimal::MaxPrecision, NUdf::GetDataTypeInfo(NUdf::GetDataSlot(lId)).DecimalDigits + scale), scale);
+ }
+
+ const std::array<TRuntimeNode, 2> args = {{ left, right }};
+ const auto resultType = isOptionalLeft || isOptionalRight ? NewOptionalType(NewDataType(NUdf::TDataType<bool>::Id)) : NewDataType(NUdf::TDataType<bool>::Id);
+ return Invoke(callableName, resultType, args);
+}
+
TRuntimeNode TProgramBuilder::BuildRangeLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& lists) {
MKQL_ENSURE(!lists.empty(), "Expecting at least one argument");
@@ -2459,78 +2459,78 @@ TRuntimeNode TProgramBuilder::BuildRangeLogical(const std::string_view& callable
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::AggrEquals(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrNotEquals(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrLess(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrLessOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrGreater(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrGreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
- return AggrCompare(__func__, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch) {
- bool condOpt, thenOpt, elseOpt;
- const auto conditionType = UnpackOptionalData(condition, condOpt);
- MKQL_ENSURE(conditionType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
-
- const auto thenUnpacked = UnpackOptional(thenBranch, thenOpt);
- const auto elseUnpacked = UnpackOptional(elseBranch, elseOpt);
- MKQL_ENSURE(thenUnpacked->IsSameType(*elseUnpacked), "Different return types in branches.");
-
- const bool isOptional = condOpt || thenOpt || elseOpt;
-
- TCallableBuilder callableBuilder(Env, __func__, isOptional ? NewOptionalType(thenUnpacked) : thenUnpacked);
+TRuntimeNode TProgramBuilder::AggrEquals(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrNotEquals(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrLess(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrLessOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrGreater(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrGreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2) {
+ return AggrCompare(__func__, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch) {
+ bool condOpt, thenOpt, elseOpt;
+ const auto conditionType = UnpackOptionalData(condition, condOpt);
+ MKQL_ENSURE(conditionType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
+
+ const auto thenUnpacked = UnpackOptional(thenBranch, thenOpt);
+ const auto elseUnpacked = UnpackOptional(elseBranch, elseOpt);
+ MKQL_ENSURE(thenUnpacked->IsSameType(*elseUnpacked), "Different return types in branches.");
+
+ const bool isOptional = condOpt || thenOpt || elseOpt;
+
+ TCallableBuilder callableBuilder(Env, __func__, isOptional ? NewOptionalType(thenUnpacked) : thenUnpacked);
callableBuilder.Add(condition);
- callableBuilder.Add(thenBranch);
- callableBuilder.Add(elseBranch);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::If(const TArrayRef<const TRuntimeNode>& args) {
- MKQL_ENSURE(args.size() % 2U, "Expected odd arguments.");
- MKQL_ENSURE(args.size() >= 3U, "Expected at least three arguments.");
- return If(args.front(), args[1U], 3U == args.size() ? args.back() : If(args.last(args.size() - 2U)));
-}
-
-TRuntimeNode TProgramBuilder::If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch, TType* resultType) {
- bool condOpt;
- const auto conditionType = UnpackOptionalData(condition, condOpt);
- MKQL_ENSURE(conditionType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
-
- TCallableBuilder callableBuilder(Env, __func__, resultType);
- callableBuilder.Add(condition);
- callableBuilder.Add(thenBranch);
- callableBuilder.Add(elseBranch);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Ensure(TRuntimeNode value, TRuntimeNode predicate, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column) {
+ callableBuilder.Add(thenBranch);
+ callableBuilder.Add(elseBranch);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::If(const TArrayRef<const TRuntimeNode>& args) {
+ MKQL_ENSURE(args.size() % 2U, "Expected odd arguments.");
+ MKQL_ENSURE(args.size() >= 3U, "Expected at least three arguments.");
+ return If(args.front(), args[1U], 3U == args.size() ? args.back() : If(args.last(args.size() - 2U)));
+}
+
+TRuntimeNode TProgramBuilder::If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch, TType* resultType) {
+ bool condOpt;
+ const auto conditionType = UnpackOptionalData(condition, condOpt);
+ MKQL_ENSURE(conditionType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
+
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
+ callableBuilder.Add(condition);
+ callableBuilder.Add(thenBranch);
+ callableBuilder.Add(elseBranch);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Ensure(TRuntimeNode value, TRuntimeNode predicate, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column) {
bool isOptional;
- const auto unpackedType = UnpackOptionalData(predicate, isOptional);
+ const auto unpackedType = UnpackOptionalData(predicate, isOptional);
MKQL_ENSURE(unpackedType->GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected bool");
const auto& messageType = message.GetStaticType();
MKQL_ENSURE(messageType->IsData(), "Expected data");
const auto& messageTypeData = static_cast<const TDataType&>(*messageType);
- MKQL_ENSURE(messageTypeData.GetSchemeType() == NUdf::TDataType<char*>::Id || messageTypeData.GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected string or utf8.");
+ MKQL_ENSURE(messageTypeData.GetSchemeType() == NUdf::TDataType<char*>::Id || messageTypeData.GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected string or utf8.");
- TCallableBuilder callableBuilder(Env, __func__, value.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, value.GetStaticType());
callableBuilder.Add(value);
callableBuilder.Add(predicate);
callableBuilder.Add(message);
@@ -2540,111 +2540,111 @@ TRuntimeNode TProgramBuilder::Ensure(TRuntimeNode value, TRuntimeNode predicate,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::SourceOf(TType* returnType) {
- MKQL_ENSURE(returnType->IsFlow() || returnType->IsStream(), "Expected flow or stream.");
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Source() {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType({})));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::IfPresent(TRuntimeNode optional, const TUnaryLambda& thenBranch, TRuntimeNode elseBranch) {
+TRuntimeNode TProgramBuilder::SourceOf(TType* returnType) {
+ MKQL_ENSURE(returnType->IsFlow() || returnType->IsStream(), "Expected flow or stream.");
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Source() {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType({})));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::IfPresent(TRuntimeNode optional, const TUnaryLambda& thenBranch, TRuntimeNode elseBranch) {
bool isOptional;
- const auto unpackedType = UnpackOptional(optional, isOptional);
- if (!isOptional) {
- return thenBranch(optional);
- }
-
- const auto itemArg = Arg(unpackedType);
- const auto then = thenBranch(itemArg);
- bool thenOpt, elseOpt;
- const auto thenUnpacked = UnpackOptional(then, thenOpt);
- const auto elseUnpacked = UnpackOptional(elseBranch, elseOpt);
-
- MKQL_ENSURE(thenUnpacked->IsSameType(*elseUnpacked), "Different return types in branches.");
-
- TCallableBuilder callableBuilder(Env, __func__, thenOpt || elseOpt ? NewOptionalType(thenUnpacked) : thenUnpacked);
+ const auto unpackedType = UnpackOptional(optional, isOptional);
+ if (!isOptional) {
+ return thenBranch(optional);
+ }
+
+ const auto itemArg = Arg(unpackedType);
+ const auto then = thenBranch(itemArg);
+ bool thenOpt, elseOpt;
+ const auto thenUnpacked = UnpackOptional(then, thenOpt);
+ const auto elseUnpacked = UnpackOptional(elseBranch, elseOpt);
+
+ MKQL_ENSURE(thenUnpacked->IsSameType(*elseUnpacked), "Different return types in branches.");
+
+ TCallableBuilder callableBuilder(Env, __func__, thenOpt || elseOpt ? NewOptionalType(thenUnpacked) : thenUnpacked);
callableBuilder.Add(optional);
callableBuilder.Add(itemArg);
- callableBuilder.Add(then);
- callableBuilder.Add(elseBranch);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::IfPresent(TRuntimeNode::TList optionals, const TNarrowLambda& thenBranch, TRuntimeNode elseBranch) {
- switch (optionals.size()) {
- case 0U:
- return thenBranch({});
- case 1U:
- return IfPresent(optionals.front(), [&](TRuntimeNode unwrap){ return thenBranch({unwrap}); }, elseBranch);
- default:
- break;
-
- }
-
- const auto first = optionals.front();
- optionals.erase(optionals.cbegin());
- return IfPresent(first,
- [&](TRuntimeNode head) {
- return IfPresent(optionals,
- [&](TRuntimeNode::TList tail) {
- tail.insert(tail.cbegin(), head);
- return thenBranch(tail);
- },
- elseBranch
- );
- },
- elseBranch
- );
-}
-
+ callableBuilder.Add(then);
+ callableBuilder.Add(elseBranch);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::IfPresent(TRuntimeNode::TList optionals, const TNarrowLambda& thenBranch, TRuntimeNode elseBranch) {
+ switch (optionals.size()) {
+ case 0U:
+ return thenBranch({});
+ case 1U:
+ return IfPresent(optionals.front(), [&](TRuntimeNode unwrap){ return thenBranch({unwrap}); }, elseBranch);
+ default:
+ break;
+
+ }
+
+ const auto first = optionals.front();
+ optionals.erase(optionals.cbegin());
+ return IfPresent(first,
+ [&](TRuntimeNode head) {
+ return IfPresent(optionals,
+ [&](TRuntimeNode::TList tail) {
+ tail.insert(tail.cbegin(), head);
+ return thenBranch(tail);
+ },
+ elseBranch
+ );
+ },
+ elseBranch
+ );
+}
+
TRuntimeNode TProgramBuilder::Not(TRuntimeNode data) {
- return UnaryDataFunction(data, __func__, TDataFunctionFlags::CommonOptionalResult | TDataFunctionFlags::RequiresBooleanArgs | TDataFunctionFlags::AllowOptionalArgs);
-}
-
-TRuntimeNode TProgramBuilder::BuildBinaryLogical(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2) {
- bool isOpt1, isOpt2;
- MKQL_ENSURE(UnpackOptionalData(data1, isOpt1)->GetSchemeType() == NUdf::TDataType<bool>::Id, "Requires boolean args.");
- MKQL_ENSURE(UnpackOptionalData(data2, isOpt2)->GetSchemeType() == NUdf::TDataType<bool>::Id, "Requires boolean args.");
- const auto resultType = NewDataType(NUdf::TDataType<bool>::Id, isOpt1 || isOpt2);
- TCallableBuilder callableBuilder(Env, callableName, resultType);
- callableBuilder.Add(data1);
- callableBuilder.Add(data2);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::BuildLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& args) {
- MKQL_ENSURE(!args.empty(), "Empty logical args.");
-
- switch (args.size()) {
- case 1U: return args.front();
- case 2U: return BuildBinaryLogical(callableName, args.front(), args.back());
- }
-
- const auto half = (args.size() + 1U) >> 1U;
- const TArrayRef<const TRuntimeNode> one(args.data(), half), two(args.data() + half, args.size() - half);
- return BuildBinaryLogical(callableName, BuildLogical(callableName, one), BuildLogical(callableName, two));
-}
-
-TRuntimeNode TProgramBuilder::And(const TArrayRef<const TRuntimeNode>& args) {
- return BuildLogical(__func__, args);
-}
-
-TRuntimeNode TProgramBuilder::Or(const TArrayRef<const TRuntimeNode>& args) {
- return BuildLogical(__func__, args);
-}
-
-TRuntimeNode TProgramBuilder::Xor(const TArrayRef<const TRuntimeNode>& args) {
- return BuildLogical(__func__, args);
-}
-
+ return UnaryDataFunction(data, __func__, TDataFunctionFlags::CommonOptionalResult | TDataFunctionFlags::RequiresBooleanArgs | TDataFunctionFlags::AllowOptionalArgs);
+}
+
+TRuntimeNode TProgramBuilder::BuildBinaryLogical(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2) {
+ bool isOpt1, isOpt2;
+ MKQL_ENSURE(UnpackOptionalData(data1, isOpt1)->GetSchemeType() == NUdf::TDataType<bool>::Id, "Requires boolean args.");
+ MKQL_ENSURE(UnpackOptionalData(data2, isOpt2)->GetSchemeType() == NUdf::TDataType<bool>::Id, "Requires boolean args.");
+ const auto resultType = NewDataType(NUdf::TDataType<bool>::Id, isOpt1 || isOpt2);
+ TCallableBuilder callableBuilder(Env, callableName, resultType);
+ callableBuilder.Add(data1);
+ callableBuilder.Add(data2);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::BuildLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& args) {
+ MKQL_ENSURE(!args.empty(), "Empty logical args.");
+
+ switch (args.size()) {
+ case 1U: return args.front();
+ case 2U: return BuildBinaryLogical(callableName, args.front(), args.back());
+ }
+
+ const auto half = (args.size() + 1U) >> 1U;
+ const TArrayRef<const TRuntimeNode> one(args.data(), half), two(args.data() + half, args.size() - half);
+ return BuildBinaryLogical(callableName, BuildLogical(callableName, one), BuildLogical(callableName, two));
+}
+
+TRuntimeNode TProgramBuilder::And(const TArrayRef<const TRuntimeNode>& args) {
+ return BuildLogical(__func__, args);
+}
+
+TRuntimeNode TProgramBuilder::Or(const TArrayRef<const TRuntimeNode>& args) {
+ return BuildLogical(__func__, args);
+}
+
+TRuntimeNode TProgramBuilder::Xor(const TArrayRef<const TRuntimeNode>& args) {
+ return BuildLogical(__func__, args);
+}
+
TRuntimeNode TProgramBuilder::Exists(TRuntimeNode data) {
const auto& nodeType = data.GetStaticType();
if (nodeType->IsVoid()) {
@@ -2652,10 +2652,10 @@ TRuntimeNode TProgramBuilder::Exists(TRuntimeNode data) {
}
if (!nodeType->IsOptional()) {
- return NewDataLiteral(true);
+ return NewDataLiteral(true);
}
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<bool>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<bool>::Id));
callableBuilder.Add(data);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2663,7 +2663,7 @@ TRuntimeNode TProgramBuilder::Exists(TRuntimeNode data) {
TRuntimeNode TProgramBuilder::NewMTRand(TRuntimeNode seed) {
auto seedData = AS_TYPE(TDataType, seed);
MKQL_ENSURE(seedData->GetSchemeType() == NUdf::TDataType<ui64>::Id, "seed must be ui64");
- TCallableBuilder callableBuilder(Env, __func__, NewResourceType(RandomMTResource), true);
+ TCallableBuilder callableBuilder(Env, __func__, NewResourceType(RandomMTResource), true);
callableBuilder.Add(seed);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2672,53 +2672,53 @@ TRuntimeNode TProgramBuilder::NextMTRand(TRuntimeNode rand) {
auto resType = AS_TYPE(TResourceType, rand);
MKQL_ENSURE(resType->GetTag() == RandomMTResource, "Expected MTRand resource");
- const std::array<TType*, 2U> tupleTypes = {{ NewDataType(NUdf::TDataType<ui64>::Id), rand.GetStaticType() }};
+ const std::array<TType*, 2U> tupleTypes = {{ NewDataType(NUdf::TDataType<ui64>::Id), rand.GetStaticType() }};
auto returnType = NewTupleType(tupleTypes);
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
callableBuilder.Add(rand);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::AggrCountInit(TRuntimeNode value) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
callableBuilder.Add(value);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::AggrCountUpdate(TRuntimeNode value, TRuntimeNode state) {
MKQL_ENSURE(AS_TYPE(TDataType, state)->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64 type");
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
callableBuilder.Add(value);
callableBuilder.Add(state);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::AggrMin(TRuntimeNode data1, TRuntimeNode data2) {
- const auto type = data1.GetStaticType();
- MKQL_ENSURE(type->IsSameType(*data2.GetStaticType()), "Must be same type.");
- return InvokeBinary(__func__, type, data1, data2);
+ const auto type = data1.GetStaticType();
+ MKQL_ENSURE(type->IsSameType(*data2.GetStaticType()), "Must be same type.");
+ return InvokeBinary(__func__, type, data1, data2);
}
TRuntimeNode TProgramBuilder::AggrMax(TRuntimeNode data1, TRuntimeNode data2) {
- const auto type = data1.GetStaticType();
- MKQL_ENSURE(type->IsSameType(*data2.GetStaticType()), "Must be same type.");
- return InvokeBinary(__func__, type, data1, data2);
+ const auto type = data1.GetStaticType();
+ MKQL_ENSURE(type->IsSameType(*data2.GetStaticType()), "Must be same type.");
+ return InvokeBinary(__func__, type, data1, data2);
}
TRuntimeNode TProgramBuilder::AggrAdd(TRuntimeNode data1, TRuntimeNode data2) {
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- bool isOptionalLeft;
- const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
-
- if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
- return Invoke(__func__, data1.GetStaticType(), args);
-
- const auto decimalType = static_cast<TDataDecimalType*>(leftType);
- bool isOptionalRight;
- const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
- MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
- return Invoke(TString("AggrAdd_") += ::ToString(decimalType->GetParams().first), data1.GetStaticType(), args);
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ bool isOptionalLeft;
+ const auto leftType = UnpackOptionalData(data1, isOptionalLeft);
+
+ if (leftType->GetSchemeType() != NUdf::TDataType<NUdf::TDecimal>::Id)
+ return Invoke(__func__, data1.GetStaticType(), args);
+
+ const auto decimalType = static_cast<TDataDecimalType*>(leftType);
+ bool isOptionalRight;
+ const auto rightType = static_cast<TDataDecimalType*>(UnpackOptionalData(data2, isOptionalRight));
+ MKQL_ENSURE(rightType->IsSameType(*decimalType), "Operands type mismatch");
+ return Invoke(TString("AggrAdd_") += ::ToString(decimalType->GetParams().first), data1.GetStaticType(), args);
}
TRuntimeNode TProgramBuilder::QueueCreate(TRuntimeNode initCapacity, TRuntimeNode initSize, const TArrayRef<const TRuntimeNode>& dependentNodes, TType* returnType) {
@@ -2726,7 +2726,7 @@ TRuntimeNode TProgramBuilder::QueueCreate(TRuntimeNode initCapacity, TRuntimeNod
const auto tag = resType->GetTag();
if (initCapacity.GetStaticType()->IsVoid()) {
- MKQL_ENSURE(RuntimeVersion >= 13, "Unbounded queue is not supported in runtime version " << RuntimeVersion);
+ MKQL_ENSURE(RuntimeVersion >= 13, "Unbounded queue is not supported in runtime version " << RuntimeVersion);
} else {
auto initCapacityType = AS_TYPE(TDataType, initCapacity);
MKQL_ENSURE(initCapacityType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "init capcity must be ui64");
@@ -2735,7 +2735,7 @@ TRuntimeNode TProgramBuilder::QueueCreate(TRuntimeNode initCapacity, TRuntimeNod
auto initSizeType = AS_TYPE(TDataType, initSize);
MKQL_ENSURE(initSizeType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "init size must be ui64");
- TCallableBuilder callableBuilder(Env, __func__, returnType, true);
+ TCallableBuilder callableBuilder(Env, __func__, returnType, true);
callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(tag));
callableBuilder.Add(initCapacity);
callableBuilder.Add(initSize);
@@ -2749,7 +2749,7 @@ TRuntimeNode TProgramBuilder::QueuePush(TRuntimeNode resource, TRuntimeNode valu
auto resType = AS_TYPE(TResourceType, resource);
const auto tag = resType->GetTag();
MKQL_ENSURE(tag.StartsWith(ResourceQueuePrefix), "Expected Queue resource");
- TCallableBuilder callableBuilder(Env, __func__, resource.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, resource.GetStaticType());
callableBuilder.Add(resource);
callableBuilder.Add(value);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -2759,7 +2759,7 @@ TRuntimeNode TProgramBuilder::QueuePop(TRuntimeNode resource) {
auto resType = AS_TYPE(TResourceType, resource);
const auto tag = resType->GetTag();
MKQL_ENSURE(tag.StartsWith(ResourceQueuePrefix), "Expected Queue resource");
- TCallableBuilder callableBuilder(Env, __func__, resource.GetStaticType());
+ TCallableBuilder callableBuilder(Env, __func__, resource.GetStaticType());
callableBuilder.Add(resource);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2771,7 +2771,7 @@ TRuntimeNode TProgramBuilder::QueuePeek(TRuntimeNode resource, TRuntimeNode inde
MKQL_ENSURE(indexType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "index size must be ui64");
const auto tag = resType->GetTag();
MKQL_ENSURE(tag.StartsWith(ResourceQueuePrefix), "Expected Queue resource");
- TCallableBuilder callableBuilder(Env, __func__, returnType);
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
callableBuilder.Add(resource);
callableBuilder.Add(index);
for (auto node : dependentNodes) {
@@ -2781,7 +2781,7 @@ TRuntimeNode TProgramBuilder::QueuePeek(TRuntimeNode resource, TRuntimeNode inde
}
TRuntimeNode TProgramBuilder::QueueRange(TRuntimeNode resource, TRuntimeNode begin, TRuntimeNode end, const TArrayRef<const TRuntimeNode>& dependentNodes, TType* returnType) {
- MKQL_ENSURE(RuntimeVersion >= 14, "QueueRange is not supported in runtime version " << RuntimeVersion);
+ MKQL_ENSURE(RuntimeVersion >= 14, "QueueRange is not supported in runtime version " << RuntimeVersion);
MKQL_ENSURE(returnType->IsList(), "Expected list type as result of QueueRange");
auto resType = AS_TYPE(TResourceType, resource);
@@ -2811,7 +2811,7 @@ TRuntimeNode TProgramBuilder::PreserveStream(TRuntimeNode stream, TRuntimeNode q
MKQL_ENSURE(outpaceType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "PreserveStream: outpace size must be ui64");
const auto tag = resType->GetTag();
MKQL_ENSURE(tag.StartsWith(ResourceQueuePrefix), "PreserveStream: Expected Queue resource");
- TCallableBuilder callableBuilder(Env, __func__, streamType);
+ TCallableBuilder callableBuilder(Env, __func__, streamType);
callableBuilder.Add(stream);
callableBuilder.Add(queue);
callableBuilder.Add(outpace);
@@ -2836,17 +2836,17 @@ TRuntimeNode TProgramBuilder::FromYsonSimpleType(TRuntimeNode input, NUdf::TData
MKQL_ENSURE(type->IsData(), "Expected data type");
auto resDataType = NewDataType(schemeType);
auto resultType = NewOptionalType(resDataType);
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(input);
callableBuilder.Add(NewDataLiteral(static_cast<ui32>(schemeType)));
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::TryWeakMemberFromDict(TRuntimeNode other, TRuntimeNode rest, NUdf::TDataTypeId schemeType, const std::string_view& memberName) {
+TRuntimeNode TProgramBuilder::TryWeakMemberFromDict(TRuntimeNode other, TRuntimeNode rest, NUdf::TDataTypeId schemeType, const std::string_view& memberName) {
auto resDataType = NewDataType(schemeType);
auto resultType = NewOptionalType(resDataType);
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(other);
callableBuilder.Add(rest);
callableBuilder.Add(NewDataLiteral(static_cast<ui32>(schemeType)));
@@ -2859,7 +2859,7 @@ TRuntimeNode TProgramBuilder::TimezoneId(TRuntimeNode name) {
auto dataType = UnpackOptionalData(name, isOptional);
MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected string");
auto resultType = NewOptionalType(NewDataType(NUdf::EDataSlot::Uint16));
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(name);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2869,7 +2869,7 @@ TRuntimeNode TProgramBuilder::TimezoneName(TRuntimeNode id) {
auto dataType = UnpackOptionalData(id, isOptional);
MKQL_ENSURE(dataType->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected ui32");
auto resultType = NewOptionalType(NewDataType(NUdf::EDataSlot::String));
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(id);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2877,11 +2877,11 @@ TRuntimeNode TProgramBuilder::TimezoneName(TRuntimeNode id) {
TRuntimeNode TProgramBuilder::AddTimezone(TRuntimeNode utc, TRuntimeNode id) {
bool isOptional1;
auto dataType1 = UnpackOptionalData(utc, isOptional1);
- MKQL_ENSURE(NUdf::GetDataTypeInfo(*dataType1->GetDataSlot()).Features & NUdf::DateType, "Expected date type");
+ MKQL_ENSURE(NUdf::GetDataTypeInfo(*dataType1->GetDataSlot()).Features & NUdf::DateType, "Expected date type");
bool isOptional2;
auto dataType2 = UnpackOptionalData(id, isOptional2);
- MKQL_ENSURE(dataType2->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected ui16");
+ MKQL_ENSURE(dataType2->GetSchemeType() == NUdf::TDataType<ui16>::Id, "Expected ui16");
NUdf::EDataSlot tzType;
switch (*dataType1->GetDataSlot()) {
case NUdf::EDataSlot::Date: tzType = NUdf::EDataSlot::TzDate; break;
@@ -2892,7 +2892,7 @@ TRuntimeNode TProgramBuilder::AddTimezone(TRuntimeNode utc, TRuntimeNode id) {
}
auto resultType = NewOptionalType(NewDataType(tzType));
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(utc);
callableBuilder.Add(id);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -2900,7 +2900,7 @@ TRuntimeNode TProgramBuilder::AddTimezone(TRuntimeNode utc, TRuntimeNode id) {
TRuntimeNode TProgramBuilder::RemoveTimezone(TRuntimeNode local) {
bool isOptional1;
- const auto dataType1 = UnpackOptionalData(local, isOptional1);
+ const auto dataType1 = UnpackOptionalData(local, isOptional1);
MKQL_ENSURE((NUdf::GetDataTypeInfo(*dataType1->GetDataSlot()).Features & NUdf::TzDateType), "Expected date with timezone type");
NUdf::EDataSlot type;
@@ -2912,30 +2912,30 @@ TRuntimeNode TProgramBuilder::RemoveTimezone(TRuntimeNode local) {
ythrow yexception() << "Unknown date with timezone type: " << (ui32)*dataType1->GetDataSlot();
}
- return Convert(local, NewDataType(type, isOptional1));
+ return Convert(local, NewDataType(type, isOptional1));
}
TRuntimeNode TProgramBuilder::Nth(TRuntimeNode tuple, ui32 index) {
- bool isOptional;
- const auto type = AS_TYPE(TTupleType, UnpackOptional(tuple.GetStaticType(), isOptional));
+ bool isOptional;
+ const auto type = AS_TYPE(TTupleType, UnpackOptional(tuple.GetStaticType(), isOptional));
- MKQL_ENSURE(index < type->GetElementsCount(), "Index out of range: " << index <<
- " is not less than " << type->GetElementsCount());
- auto itemType = type->GetElementType(index);
+ MKQL_ENSURE(index < type->GetElementsCount(), "Index out of range: " << index <<
+ " is not less than " << type->GetElementsCount());
+ auto itemType = type->GetElementType(index);
if (isOptional && !itemType->IsOptional()) {
itemType = TOptionalType::Create(itemType, Env);
}
- TCallableBuilder callableBuilder(Env, __func__, itemType);
+ TCallableBuilder callableBuilder(Env, __func__, itemType);
callableBuilder.Add(tuple);
- callableBuilder.Add(NewDataLiteral<ui32>(index));
+ callableBuilder.Add(NewDataLiteral<ui32>(index));
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Element(TRuntimeNode tuple, ui32 index) {
- return Nth(tuple, index);
-}
-
+TRuntimeNode TProgramBuilder::Element(TRuntimeNode tuple, ui32 index) {
+ return Nth(tuple, index);
+}
+
TRuntimeNode TProgramBuilder::Guess(TRuntimeNode variant, ui32 tupleIndex) {
bool isOptional;
auto unpacked = UnpackOptional(variant, isOptional);
@@ -2944,13 +2944,13 @@ TRuntimeNode TProgramBuilder::Guess(TRuntimeNode variant, ui32 tupleIndex) {
MKQL_ENSURE(tupleIndex < underlyingType->GetElementsCount(), "Wrong tuple index");
auto resType = TOptionalType::Create(underlyingType->GetElementType(tupleIndex), Env);
- TCallableBuilder callableBuilder(Env, __func__, resType);
+ TCallableBuilder callableBuilder(Env, __func__, resType);
callableBuilder.Add(variant);
- callableBuilder.Add(NewDataLiteral<ui32>(tupleIndex));
+ callableBuilder.Add(NewDataLiteral<ui32>(tupleIndex));
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Guess(TRuntimeNode variant, const std::string_view& memberName) {
+TRuntimeNode TProgramBuilder::Guess(TRuntimeNode variant, const std::string_view& memberName) {
bool isOptional;
auto unpacked = UnpackOptional(variant, isOptional);
auto type = AS_TYPE(TVariantType, unpacked);
@@ -2958,9 +2958,9 @@ TRuntimeNode TProgramBuilder::Guess(TRuntimeNode variant, const std::string_view
auto structIndex = underlyingType->GetMemberIndex(memberName);
auto resType = TOptionalType::Create(underlyingType->GetMemberType(structIndex), Env);
- TCallableBuilder callableBuilder(Env, __func__, resType);
+ TCallableBuilder callableBuilder(Env, __func__, resType);
callableBuilder.Add(variant);
- callableBuilder.Add(NewDataLiteral<ui32>(structIndex));
+ callableBuilder.Add(NewDataLiteral<ui32>(structIndex));
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2972,7 +2972,7 @@ TRuntimeNode TProgramBuilder::Way(TRuntimeNode variant) {
auto dataType = NewDataType(underlyingType->IsTuple() ? NUdf::EDataSlot::Uint32 : NUdf::EDataSlot::Utf8);
auto resType = isOptional ? TOptionalType::Create(dataType, Env) : dataType;
- TCallableBuilder callableBuilder(Env, __func__, resType);
+ TCallableBuilder callableBuilder(Env, __func__, resType);
callableBuilder.Add(variant);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -2984,46 +2984,46 @@ TRuntimeNode TProgramBuilder::VariantItem(TRuntimeNode variant) {
auto underlyingType = type->GetAlternativeType(0);
auto resType = isOptional ? TOptionalType::Create(underlyingType, Env) : underlyingType;
- TCallableBuilder callableBuilder(Env, __func__, resType);
+ TCallableBuilder callableBuilder(Env, __func__, resType);
callableBuilder.Add(variant);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::VisitAll(TRuntimeNode variant, std::function<TRuntimeNode(ui32, TRuntimeNode)> handler) {
- const auto type = AS_TYPE(TVariantType, variant);
- std::vector<TRuntimeNode> items;
- std::vector<TRuntimeNode> newItems;
+ const auto type = AS_TYPE(TVariantType, variant);
+ std::vector<TRuntimeNode> items;
+ std::vector<TRuntimeNode> newItems;
for (ui32 i = 0; i < type->GetAlternativesCount(); ++i) {
- const auto itemType = type->GetAlternativeType(i);
- const auto itemArg = Arg(itemType);
-
- const auto res = handler(i, itemArg);
- items.emplace_back(itemArg);
- newItems.emplace_back(res);
- }
-
- bool hasOptional;
- const auto firstUnpacked = UnpackOptional(newItems.front(), hasOptional);
- bool allOptional = hasOptional;
-
- for (size_t i = 1U; i < newItems.size(); ++i) {
- bool isOptional;
- const auto unpacked = UnpackOptional(newItems[i].GetStaticType(), isOptional);
- MKQL_ENSURE(unpacked->IsSameType(*firstUnpacked), "Different return types in branches.");
- hasOptional = hasOptional || isOptional;
- allOptional = allOptional && isOptional;
- }
-
- if (hasOptional && !allOptional) {
- for (auto& item : newItems) {
- if (!item.GetStaticType()->IsOptional()) {
- item = NewOptional(item);
- }
- }
- }
-
- TCallableBuilder callableBuilder(Env, __func__, newItems.front().GetStaticType());
+ const auto itemType = type->GetAlternativeType(i);
+ const auto itemArg = Arg(itemType);
+
+ const auto res = handler(i, itemArg);
+ items.emplace_back(itemArg);
+ newItems.emplace_back(res);
+ }
+
+ bool hasOptional;
+ const auto firstUnpacked = UnpackOptional(newItems.front(), hasOptional);
+ bool allOptional = hasOptional;
+
+ for (size_t i = 1U; i < newItems.size(); ++i) {
+ bool isOptional;
+ const auto unpacked = UnpackOptional(newItems[i].GetStaticType(), isOptional);
+ MKQL_ENSURE(unpacked->IsSameType(*firstUnpacked), "Different return types in branches.");
+ hasOptional = hasOptional || isOptional;
+ allOptional = allOptional && isOptional;
+ }
+
+ if (hasOptional && !allOptional) {
+ for (auto& item : newItems) {
+ if (!item.GetStaticType()->IsOptional()) {
+ item = NewOptional(item);
+ }
+ }
+ }
+
+ TCallableBuilder callableBuilder(Env, __func__, newItems.front().GetStaticType());
callableBuilder.Add(variant);
for (ui32 i = 0; i < type->GetAlternativesCount(); ++i) {
callableBuilder.Add(items[i]);
@@ -3033,7 +3033,7 @@ TRuntimeNode TProgramBuilder::VisitAll(TRuntimeNode variant, std::function<TRunt
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::UnaryDataFunction(TRuntimeNode data, const std::string_view& callableName, ui32 flags) {
+TRuntimeNode TProgramBuilder::UnaryDataFunction(TRuntimeNode data, const std::string_view& callableName, ui32 flags) {
bool isOptional;
auto type = UnpackOptionalData(data, isOptional);
if (!(flags & TDataFunctionFlags::AllowOptionalArgs)) {
@@ -3074,22 +3074,22 @@ TRuntimeNode TProgramBuilder::UnaryDataFunction(TRuntimeNode data, const std::st
}
TRuntimeNode TProgramBuilder::ToDict(TRuntimeNode list, bool multi, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
+ const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
{
- bool isOptional;
- const auto type = UnpackOptional(list, isOptional);
- MKQL_ENSURE(type->IsList(), "Expected list.");
-
- if (isOptional) {
- return Map(list, [&](TRuntimeNode unpacked) { return ToDict(unpacked, multi, keySelector, payloadSelector, callableName, isCompact, itemsCountHint); } );
- }
-
- const auto itemType = AS_TYPE(TListType, type)->GetItemType();
+ bool isOptional;
+ const auto type = UnpackOptional(list, isOptional);
+ MKQL_ENSURE(type->IsList(), "Expected list.");
+
+ if (isOptional) {
+ return Map(list, [&](TRuntimeNode unpacked) { return ToDict(unpacked, multi, keySelector, payloadSelector, callableName, isCompact, itemsCountHint); } );
+ }
+
+ const auto itemType = AS_TYPE(TListType, type)->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
+ const auto itemArg = Arg(itemType);
- const auto key = keySelector(itemArg);
- const auto keyType = key.GetStaticType();
+ const auto key = keySelector(itemArg);
+ const auto keyType = key.GetStaticType();
auto payload = payloadSelector(itemArg);
auto payloadType = payload.GetStaticType();
@@ -3103,14 +3103,14 @@ TRuntimeNode TProgramBuilder::ToDict(TRuntimeNode list, bool multi, const TUnary
callableBuilder.Add(itemArg);
callableBuilder.Add(key);
callableBuilder.Add(payload);
- callableBuilder.Add(NewDataLiteral(multi));
- callableBuilder.Add(NewDataLiteral(isCompact));
- callableBuilder.Add(NewDataLiteral(itemsCountHint));
+ callableBuilder.Add(NewDataLiteral(multi));
+ callableBuilder.Add(NewDataLiteral(isCompact));
+ callableBuilder.Add(NewDataLiteral(itemsCountHint));
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::SqueezeToDict(TRuntimeNode stream, bool multi, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
+ const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
{
if constexpr (RuntimeVersion < 21U) {
THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
@@ -3147,90 +3147,90 @@ TRuntimeNode TProgramBuilder::SqueezeToDict(TRuntimeNode stream, bool multi, con
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::NarrowSqueezeToDict(TRuntimeNode flow, bool multi, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
-{
- if constexpr (RuntimeVersion < 23U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto key = keySelector(itemArgs);
- const auto keyType = key.GetStaticType();
-
- auto payload = payloadSelector(itemArgs);
- auto payloadType = payload.GetStaticType();
- if (multi) {
- payloadType = TListType::Create(payloadType, Env);
- }
-
- const auto dictType = TDictType::Create(keyType, payloadType, Env);
- const auto returnType = TFlowType::Create(dictType, Env);
- TCallableBuilder callableBuilder(Env, callableName, returnType);
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(key);
- callableBuilder.Add(payload);
- callableBuilder.Add(NewDataLiteral(multi));
- callableBuilder.Add(NewDataLiteral(isCompact));
- callableBuilder.Add(NewDataLiteral(itemsCountHint));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::NarrowSqueezeToDict(TRuntimeNode flow, bool multi, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint)
+{
+ if constexpr (RuntimeVersion < 23U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto key = keySelector(itemArgs);
+ const auto keyType = key.GetStaticType();
+
+ auto payload = payloadSelector(itemArgs);
+ auto payloadType = payload.GetStaticType();
+ if (multi) {
+ payloadType = TListType::Create(payloadType, Env);
+ }
+
+ const auto dictType = TDictType::Create(keyType, payloadType, Env);
+ const auto returnType = TFlowType::Create(dictType, Env);
+ TCallableBuilder callableBuilder(Env, callableName, returnType);
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(key);
+ callableBuilder.Add(payload);
+ callableBuilder.Add(NewDataLiteral(multi));
+ callableBuilder.Add(NewDataLiteral(isCompact));
+ callableBuilder.Add(NewDataLiteral(itemsCountHint));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
void TProgramBuilder::ThrowIfListOfVoid(TType* type) {
- MKQL_ENSURE(!VoidWithEffects || !type->IsVoid(), "List of void is forbidden for current function");
+ MKQL_ENSURE(!VoidWithEffects || !type->IsVoid(), "List of void is forbidden for current function");
}
-TRuntimeNode TProgramBuilder::BuildFlatMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::BuildFlatMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler)
{
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsOptional() || listType->IsStream(), "Expected flow, list, stream or optional");
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsOptional() || listType->IsStream(), "Expected flow, list, stream or optional");
if (listType->IsOptional()) {
- const auto itemArg = Arg(AS_TYPE(TOptionalType, listType)->GetItemType());
- const auto newList = handler(itemArg);
- const auto type = newList.GetStaticType();
- MKQL_ENSURE(type->IsList() || type->IsOptional() || type->IsStream() || type->IsFlow(), "Expected flow, list, stream or optional");
+ const auto itemArg = Arg(AS_TYPE(TOptionalType, listType)->GetItemType());
+ const auto newList = handler(itemArg);
+ const auto type = newList.GetStaticType();
+ MKQL_ENSURE(type->IsList() || type->IsOptional() || type->IsStream() || type->IsFlow(), "Expected flow, list, stream or optional");
return IfPresent(list, [&](TRuntimeNode item) {
return handler(item);
- }, type->IsOptional() ? NewEmptyOptional(type) : type->IsList() ? NewEmptyList(AS_TYPE(TListType, type)->GetItemType()) : EmptyIterator(type));
+ }, type->IsOptional() ? NewEmptyOptional(type) : type->IsList() ? NewEmptyList(AS_TYPE(TListType, type)->GetItemType()) : EmptyIterator(type));
}
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto newList = handler(itemArg);
- const auto type = newList.GetStaticType();
+ const auto itemArg = Arg(itemType);
+ const auto newList = handler(itemArg);
+ const auto type = newList.GetStaticType();
TType* retItemType = nullptr;
if (type->IsOptional()) {
- retItemType = AS_TYPE(TOptionalType, type)->GetItemType();
- } else if (type->IsFlow()) {
- retItemType = AS_TYPE(TFlowType, type)->GetItemType();
+ retItemType = AS_TYPE(TOptionalType, type)->GetItemType();
+ } else if (type->IsFlow()) {
+ retItemType = AS_TYPE(TFlowType, type)->GetItemType();
} else if (type->IsList()) {
- retItemType = AS_TYPE(TListType, type)->GetItemType();
- } else if (type->IsStream()) {
- retItemType = AS_TYPE(TStreamType, type)->GetItemType();
+ retItemType = AS_TYPE(TListType, type)->GetItemType();
+ } else if (type->IsStream()) {
+ retItemType = AS_TYPE(TStreamType, type)->GetItemType();
} else {
- THROW yexception() << "Expected flow, list or stream.";
+ THROW yexception() << "Expected flow, list or stream.";
}
- const auto resultListType = listType->IsFlow() || type->IsFlow() ?
- TFlowType::Create(retItemType, Env):
- listType->IsList() ?
- (TType*)TListType::Create(retItemType, Env):
- (TType*)TStreamType::Create(retItemType, Env);
+ const auto resultListType = listType->IsFlow() || type->IsFlow() ?
+ TFlowType::Create(retItemType, Env):
+ listType->IsList() ?
+ (TType*)TListType::Create(retItemType, Env):
+ (TType*)TStreamType::Create(retItemType, Env);
TCallableBuilder callableBuilder(Env, callableName, resultListType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
@@ -3238,435 +3238,435 @@ TRuntimeNode TProgramBuilder::BuildFlatMap(const std::string_view& callableName,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::MultiMap(TRuntimeNode list, const TExpandLambda& handler)
-{
- if constexpr (RuntimeVersion < 16U) {
- const auto single = [=](TRuntimeNode item) -> TRuntimeNode {
- const auto newList = handler(item);
- const auto retItemType = newList.front().GetStaticType();
- MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
- return NewList(retItemType, newList);
- };
- return OrderedFlatMap(list, single);
- }
-
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList(), "Expected flow, list, stream or optional");
-
- const auto itemType = listType->IsFlow() ? AS_TYPE(TFlowType, listType)->GetItemType() : AS_TYPE(TListType, listType)->GetItemType();
-
- const auto itemArg = Arg(itemType);
- const auto newList = handler(itemArg);
-
- MKQL_ENSURE(newList.size() > 1U, "Expected many items.");
- const auto retItemType = newList.front().GetStaticType();
- MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
-
- const auto resultListType = listType->IsFlow() ?
- (TType*)TFlowType::Create(retItemType, Env) : (TType*)TListType::Create(retItemType, Env);
- TCallableBuilder callableBuilder(Env, __func__, resultListType);
- callableBuilder.Add(list);
- callableBuilder.Add(itemArg);
- std::for_each(newList.cbegin(), newList.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::NarrowMultiMap(TRuntimeNode flow, const TWideLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto newList = handler(itemArgs);
-
- MKQL_ENSURE(newList.size() > 1U, "Expected many items.");
- const auto retItemType = newList.front().GetStaticType();
- MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(newList.front().GetStaticType()));
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(newList.cbegin(), newList.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::ExpandMap(TRuntimeNode flow, const TExpandLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto itemType = AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType();
- const auto itemArg = Arg(itemType);
- const auto newItems = handler(itemArg);
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(newItems.size());
- std::transform(newItems.cbegin(), newItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- callableBuilder.Add(itemArg);
- std::for_each(newItems.cbegin(), newItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideMap(TRuntimeNode flow, const TWideLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto newItems = handler(itemArgs);
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(newItems.size());
- std::transform(newItems.cbegin(), newItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(newItems.cbegin(), newItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideChain1Map(TRuntimeNode flow, const TWideLambda& init, const TBinaryWideLambda& update) {
- if constexpr (RuntimeVersion < 23U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList inputArgs;
- inputArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(inputArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto initItems = init(inputArgs);
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(initItems.size());
- std::transform(initItems.cbegin(), initItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TRuntimeNode::TList outputArgs;
- outputArgs.reserve(tupleItems.size());
- std::transform(tupleItems.cbegin(), tupleItems.cend(), std::back_inserter(outputArgs), std::bind(&TProgramBuilder::Arg, this, std::placeholders::_1));
-
- const auto updateItems = update(inputArgs, outputArgs);
-
- MKQL_ENSURE(initItems.size() == updateItems.size(), "Expected same width.");
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- std::for_each(inputArgs.cbegin(), inputArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(initItems.cbegin(), initItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(outputArgs.cbegin(), outputArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(updateItems.cbegin(), updateItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::NarrowMap(TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto newItem = handler(itemArgs);
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(newItem.GetStaticType()));
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(newItem);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::NarrowFlatMap(TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto newList = handler(itemArgs);
- const auto type = newList.GetStaticType();
-
- TType* retItemType = nullptr;
- if (type->IsOptional()) {
- retItemType = AS_TYPE(TOptionalType, type)->GetItemType();
- } else if (type->IsFlow()) {
- retItemType = AS_TYPE(TFlowType, type)->GetItemType();
- } else if (type->IsList()) {
- retItemType = AS_TYPE(TListType, type)->GetItemType();
- } else if (type->IsStream()) {
- retItemType = AS_TYPE(TStreamType, type)->GetItemType();
- } else {
- THROW yexception() << "Expected flow, list or stream.";
- }
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(retItemType));
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(newList);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::BuildWideFilter(const std::string_view& callableName, TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto predicate = handler(itemArgs);
-
- TCallableBuilder callableBuilder(Env, callableName, flow.GetStaticType());
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(predicate);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideFilter(TRuntimeNode flow, const TNarrowLambda& handler) {
- return BuildWideFilter(__func__, flow, handler);
-}
-
-TRuntimeNode TProgramBuilder::WideTakeWhile(TRuntimeNode flow, const TNarrowLambda& handler) {
- return BuildWideFilter(__func__, flow, handler);
-}
-
-TRuntimeNode TProgramBuilder::WideSkipWhile(TRuntimeNode flow, const TNarrowLambda& handler) {
- return BuildWideFilter(__func__, flow, handler);
-}
-
-TRuntimeNode TProgramBuilder::WideTakeWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler) {
- return BuildWideFilter(__func__, flow, handler);
-}
-
-TRuntimeNode TProgramBuilder::WideSkipWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler) {
- return BuildWideFilter(__func__, flow, handler);
-}
-
-TRuntimeNode TProgramBuilder::WideFilter(TRuntimeNode flow, TRuntimeNode limit, const TNarrowLambda& handler) {
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto predicate = handler(itemArgs);
-
- TCallableBuilder callableBuilder(Env, __func__, flow.GetStaticType());
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(predicate);
- callableBuilder.Add(limit);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler, TType* resultType)
+TRuntimeNode TProgramBuilder::MultiMap(TRuntimeNode list, const TExpandLambda& handler)
{
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream.");
- const auto outputType = resultType ? resultType : listType;
-
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
+ if constexpr (RuntimeVersion < 16U) {
+ const auto single = [=](TRuntimeNode item) -> TRuntimeNode {
+ const auto newList = handler(item);
+ const auto retItemType = newList.front().GetStaticType();
+ MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
+ return NewList(retItemType, newList);
+ };
+ return OrderedFlatMap(list, single);
+ }
+
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList(), "Expected flow, list, stream or optional");
+
+ const auto itemType = listType->IsFlow() ? AS_TYPE(TFlowType, listType)->GetItemType() : AS_TYPE(TListType, listType)->GetItemType();
+
+ const auto itemArg = Arg(itemType);
+ const auto newList = handler(itemArg);
+
+ MKQL_ENSURE(newList.size() > 1U, "Expected many items.");
+ const auto retItemType = newList.front().GetStaticType();
+ MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
+
+ const auto resultListType = listType->IsFlow() ?
+ (TType*)TFlowType::Create(retItemType, Env) : (TType*)TListType::Create(retItemType, Env);
+ TCallableBuilder callableBuilder(Env, __func__, resultListType);
+ callableBuilder.Add(list);
+ callableBuilder.Add(itemArg);
+ std::for_each(newList.cbegin(), newList.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::NarrowMultiMap(TRuntimeNode flow, const TWideLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto newList = handler(itemArgs);
+
+ MKQL_ENSURE(newList.size() > 1U, "Expected many items.");
+ const auto retItemType = newList.front().GetStaticType();
+ MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(newList.front().GetStaticType()));
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(newList.cbegin(), newList.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::ExpandMap(TRuntimeNode flow, const TExpandLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto itemType = AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType();
+ const auto itemArg = Arg(itemType);
+ const auto newItems = handler(itemArg);
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(newItems.size());
+ std::transform(newItems.cbegin(), newItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(itemArg);
+ std::for_each(newItems.cbegin(), newItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideMap(TRuntimeNode flow, const TWideLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto newItems = handler(itemArgs);
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(newItems.size());
+ std::transform(newItems.cbegin(), newItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(newItems.cbegin(), newItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideChain1Map(TRuntimeNode flow, const TWideLambda& init, const TBinaryWideLambda& update) {
+ if constexpr (RuntimeVersion < 23U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList inputArgs;
+ inputArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(inputArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto initItems = init(inputArgs);
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(initItems.size());
+ std::transform(initItems.cbegin(), initItems.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TRuntimeNode::TList outputArgs;
+ outputArgs.reserve(tupleItems.size());
+ std::transform(tupleItems.cbegin(), tupleItems.cend(), std::back_inserter(outputArgs), std::bind(&TProgramBuilder::Arg, this, std::placeholders::_1));
+
+ const auto updateItems = update(inputArgs, outputArgs);
+
+ MKQL_ENSURE(initItems.size() == updateItems.size(), "Expected same width.");
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ std::for_each(inputArgs.cbegin(), inputArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(initItems.cbegin(), initItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(outputArgs.cbegin(), outputArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(updateItems.cbegin(), updateItems.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::NarrowMap(TRuntimeNode flow, const TNarrowLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto newItem = handler(itemArgs);
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(newItem.GetStaticType()));
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(newItem);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::NarrowFlatMap(TRuntimeNode flow, const TNarrowLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto newList = handler(itemArgs);
+ const auto type = newList.GetStaticType();
+
+ TType* retItemType = nullptr;
+ if (type->IsOptional()) {
+ retItemType = AS_TYPE(TOptionalType, type)->GetItemType();
+ } else if (type->IsFlow()) {
+ retItemType = AS_TYPE(TFlowType, type)->GetItemType();
+ } else if (type->IsList()) {
+ retItemType = AS_TYPE(TListType, type)->GetItemType();
+ } else if (type->IsStream()) {
+ retItemType = AS_TYPE(TStreamType, type)->GetItemType();
+ } else {
+ THROW yexception() << "Expected flow, list or stream.";
+ }
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(retItemType));
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(newList);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::BuildWideFilter(const std::string_view& callableName, TRuntimeNode flow, const TNarrowLambda& handler) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto predicate = handler(itemArgs);
+
+ TCallableBuilder callableBuilder(Env, callableName, flow.GetStaticType());
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(predicate);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideFilter(TRuntimeNode flow, const TNarrowLambda& handler) {
+ return BuildWideFilter(__func__, flow, handler);
+}
+
+TRuntimeNode TProgramBuilder::WideTakeWhile(TRuntimeNode flow, const TNarrowLambda& handler) {
+ return BuildWideFilter(__func__, flow, handler);
+}
+
+TRuntimeNode TProgramBuilder::WideSkipWhile(TRuntimeNode flow, const TNarrowLambda& handler) {
+ return BuildWideFilter(__func__, flow, handler);
+}
+
+TRuntimeNode TProgramBuilder::WideTakeWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler) {
+ return BuildWideFilter(__func__, flow, handler);
+}
+
+TRuntimeNode TProgramBuilder::WideSkipWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler) {
+ return BuildWideFilter(__func__, flow, handler);
+}
+
+TRuntimeNode TProgramBuilder::WideFilter(TRuntimeNode flow, TRuntimeNode limit, const TNarrowLambda& handler) {
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto predicate = handler(itemArgs);
+
+ TCallableBuilder callableBuilder(Env, __func__, flow.GetStaticType());
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(predicate);
+ callableBuilder.Add(limit);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler, TType* resultType)
+{
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream.");
+ const auto outputType = resultType ? resultType : listType;
+
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto predicate = handler(itemArg);
+ const auto itemArg = Arg(itemType);
+ const auto predicate = handler(itemArg);
MKQL_ENSURE(predicate.GetStaticType()->IsData(), "Expected boolean data");
const auto& detailedPredicateType = static_cast<const TDataType&>(*predicate.GetStaticType());
MKQL_ENSURE(detailedPredicateType.GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected boolean data");
- TCallableBuilder callableBuilder(Env, callableName, outputType);
+ TCallableBuilder callableBuilder(Env, callableName, outputType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
callableBuilder.Add(predicate);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler, TType* resultType)
-{
- if constexpr (RuntimeVersion < 4U) {
- return Take(BuildFilter(callableName, list, handler, resultType), limit);
- }
-
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream.");
- MKQL_ENSURE(limit.GetStaticType()->IsData(), "Expected data");
- const auto outputType = resultType ? resultType : listType;
-
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
- ThrowIfListOfVoid(itemType);
-
- const auto itemArg = Arg(itemType);
- const auto predicate = handler(itemArg);
-
- MKQL_ENSURE(predicate.GetStaticType()->IsData(), "Expected boolean data");
-
- const auto& detailedPredicateType = static_cast<const TDataType&>(*predicate.GetStaticType());
- MKQL_ENSURE(detailedPredicateType.GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected boolean data");
-
- TCallableBuilder callableBuilder(Env, callableName, outputType);
- callableBuilder.Add(list);
- callableBuilder.Add(limit);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(predicate);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, const TUnaryLambda& handler, TType* resultType)
-{
- const auto type = list.GetStaticType();
-
- if (type->IsOptional()) {
- return
- IfPresent(list,
- [&](TRuntimeNode item) {
- return If(handler(item), item, NewEmptyOptional(resultType), resultType);
- },
- NewEmptyOptional(resultType)
- );
- }
-
- return BuildFilter(__func__, list, handler, resultType);
-}
-
-TRuntimeNode TProgramBuilder::BuildHeap(const std::string_view& callableName, TRuntimeNode list, const TBinaryLambda& comparator) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList(), "Expected list.");
- const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
-
- const auto leftArg = Arg(itemType);
- const auto rightArg = Arg(itemType);
- const auto predicate = comparator(leftArg, rightArg);
-
- TCallableBuilder callableBuilder(Env, callableName, listType);
- callableBuilder.Add(list);
- callableBuilder.Add(leftArg);
- callableBuilder.Add(rightArg);
- callableBuilder.Add(predicate);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsList(), "Expected list.");
- const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
-
- MKQL_ENSURE(n.GetStaticType()->IsData(), "Expected data");
- MKQL_ENSURE(static_cast<const TDataType&>(*n.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
-
- const auto leftArg = Arg(itemType);
- const auto rightArg = Arg(itemType);
- const auto predicate = comparator(leftArg, rightArg);
-
- TCallableBuilder callableBuilder(Env, callableName, listType);
- callableBuilder.Add(list);
- callableBuilder.Add(n);
- callableBuilder.Add(leftArg);
- callableBuilder.Add(rightArg);
- callableBuilder.Add(predicate);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::MakeHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
- return BuildHeap(__func__, list, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::PushHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
- return BuildHeap(__func__, list, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::PopHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
- return BuildHeap(__func__, list, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::SortHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
- return BuildHeap(__func__, list, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::StableSort(TRuntimeNode list, const TBinaryLambda& comparator) {
- return BuildHeap(__func__, list, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::NthElement(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
- return BuildNth(__func__, list, n, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::PartialSort(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
- return BuildNth(__func__, list, n, std::move(comparator));
-}
-
-TRuntimeNode TProgramBuilder::BuildMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler)
+TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler, TType* resultType)
{
- const auto listType = list.GetStaticType();
- MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream() || listType->IsOptional(), "Expected flow, list, stream or optional");
+ if constexpr (RuntimeVersion < 4U) {
+ return Take(BuildFilter(callableName, list, handler, resultType), limit);
+ }
+
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream.");
+ MKQL_ENSURE(limit.GetStaticType()->IsData(), "Expected data");
+ const auto outputType = resultType ? resultType : listType;
+
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
+ ThrowIfListOfVoid(itemType);
+
+ const auto itemArg = Arg(itemType);
+ const auto predicate = handler(itemArg);
+
+ MKQL_ENSURE(predicate.GetStaticType()->IsData(), "Expected boolean data");
+
+ const auto& detailedPredicateType = static_cast<const TDataType&>(*predicate.GetStaticType());
+ MKQL_ENSURE(detailedPredicateType.GetSchemeType() == NUdf::TDataType<bool>::Id, "Expected boolean data");
+
+ TCallableBuilder callableBuilder(Env, callableName, outputType);
+ callableBuilder.Add(list);
+ callableBuilder.Add(limit);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(predicate);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::Filter(TRuntimeNode list, const TUnaryLambda& handler, TType* resultType)
+{
+ const auto type = list.GetStaticType();
+
+ if (type->IsOptional()) {
+ return
+ IfPresent(list,
+ [&](TRuntimeNode item) {
+ return If(handler(item), item, NewEmptyOptional(resultType), resultType);
+ },
+ NewEmptyOptional(resultType)
+ );
+ }
+
+ return BuildFilter(__func__, list, handler, resultType);
+}
+
+TRuntimeNode TProgramBuilder::BuildHeap(const std::string_view& callableName, TRuntimeNode list, const TBinaryLambda& comparator) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList(), "Expected list.");
+ const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
+
+ const auto leftArg = Arg(itemType);
+ const auto rightArg = Arg(itemType);
+ const auto predicate = comparator(leftArg, rightArg);
+
+ TCallableBuilder callableBuilder(Env, callableName, listType);
+ callableBuilder.Add(list);
+ callableBuilder.Add(leftArg);
+ callableBuilder.Add(rightArg);
+ callableBuilder.Add(predicate);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsList(), "Expected list.");
+ const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
+
+ MKQL_ENSURE(n.GetStaticType()->IsData(), "Expected data");
+ MKQL_ENSURE(static_cast<const TDataType&>(*n.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
+
+ const auto leftArg = Arg(itemType);
+ const auto rightArg = Arg(itemType);
+ const auto predicate = comparator(leftArg, rightArg);
+
+ TCallableBuilder callableBuilder(Env, callableName, listType);
+ callableBuilder.Add(list);
+ callableBuilder.Add(n);
+ callableBuilder.Add(leftArg);
+ callableBuilder.Add(rightArg);
+ callableBuilder.Add(predicate);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::MakeHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
+ return BuildHeap(__func__, list, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::PushHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
+ return BuildHeap(__func__, list, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::PopHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
+ return BuildHeap(__func__, list, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::SortHeap(TRuntimeNode list, const TBinaryLambda& comparator) {
+ return BuildHeap(__func__, list, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::StableSort(TRuntimeNode list, const TBinaryLambda& comparator) {
+ return BuildHeap(__func__, list, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::NthElement(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
+ return BuildNth(__func__, list, n, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::PartialSort(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator) {
+ return BuildNth(__func__, list, n, std::move(comparator));
+}
+
+TRuntimeNode TProgramBuilder::BuildMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler)
+{
+ const auto listType = list.GetStaticType();
+ MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream() || listType->IsOptional(), "Expected flow, list, stream or optional");
if (listType->IsOptional()) {
- const auto itemArg = Arg(AS_TYPE(TOptionalType, listType)->GetItemType());
- const auto newItem = handler(itemArg);
+ const auto itemArg = Arg(AS_TYPE(TOptionalType, listType)->GetItemType());
+ const auto newItem = handler(itemArg);
- return IfPresent(list,
- [&](TRuntimeNode item) { return NewOptional(handler(item)); },
- NewEmptyOptional(NewOptionalType(newItem.GetStaticType()))
- );
+ return IfPresent(list,
+ [&](TRuntimeNode item) { return NewOptional(handler(item)); },
+ NewEmptyOptional(NewOptionalType(newItem.GetStaticType()))
+ );
}
- const auto itemType = listType->IsFlow() ?
- AS_TYPE(TFlowType, listType)->GetItemType():
- listType->IsList() ?
- AS_TYPE(TListType, listType)->GetItemType():
- AS_TYPE(TStreamType, listType)->GetItemType();
+ const auto itemType = listType->IsFlow() ?
+ AS_TYPE(TFlowType, listType)->GetItemType():
+ listType->IsList() ?
+ AS_TYPE(TListType, listType)->GetItemType():
+ AS_TYPE(TStreamType, listType)->GetItemType();
ThrowIfListOfVoid(itemType);
- const auto itemArg = Arg(itemType);
- const auto newItem = handler(itemArg);
+ const auto itemArg = Arg(itemType);
+ const auto newItem = handler(itemArg);
- const auto resultListType = listType->IsFlow() ?
- (TType*)TFlowType::Create(newItem.GetStaticType(), Env):
- listType->IsList() ?
- (TType*)TListType::Create(newItem.GetStaticType(), Env):
- (TType*)TStreamType::Create(newItem.GetStaticType(), Env);
+ const auto resultListType = listType->IsFlow() ?
+ (TType*)TFlowType::Create(newItem.GetStaticType(), Env):
+ listType->IsList() ?
+ (TType*)TListType::Create(newItem.GetStaticType(), Env):
+ (TType*)TStreamType::Create(newItem.GetStaticType(), Env);
TCallableBuilder callableBuilder(Env, callableName, resultListType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
@@ -3674,32 +3674,32 @@ TRuntimeNode TProgramBuilder::BuildMap(const std::string_view& callableName, TRu
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Invoke(const std::string_view& funcName, TType* resultType, const TArrayRef<const TRuntimeNode>& args) {
- MKQL_ENSURE(args.size() >= 1U && args.size() <= 3U, "Expected from one to three arguments.");
- std::array<TArgType, 4U> argTypes;
- argTypes.front().first = UnpackOptionalData(resultType, argTypes.front().second)->GetSchemeType();
- auto i = 0U;
- for (const auto& arg : args) {
- ++i;
- argTypes[i].first = UnpackOptionalData(arg, argTypes[i].second)->GetSchemeType();
- }
-
- FunctionRegistry.GetBuiltins()->GetBuiltin(funcName, argTypes.data(), 1U + args.size());
-
- TCallableBuilder callableBuilder(Env, __func__, resultType);
- callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(funcName));
- for (const auto& arg : args) {
- callableBuilder.Add(arg);
- }
-
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::Invoke(const std::string_view& funcName, TType* resultType, const TArrayRef<const TRuntimeNode>& args) {
+ MKQL_ENSURE(args.size() >= 1U && args.size() <= 3U, "Expected from one to three arguments.");
+ std::array<TArgType, 4U> argTypes;
+ argTypes.front().first = UnpackOptionalData(resultType, argTypes.front().second)->GetSchemeType();
+ auto i = 0U;
+ for (const auto& arg : args) {
+ ++i;
+ argTypes[i].first = UnpackOptionalData(arg, argTypes[i].second)->GetSchemeType();
+ }
+
+ FunctionRegistry.GetBuiltins()->GetBuiltin(funcName, argTypes.data(), 1U + args.size());
+
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(funcName));
+ for (const auto& arg : args) {
+ callableBuilder.Add(arg);
+ }
+
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::Udf(
- const std::string_view& funcName,
+ const std::string_view& funcName,
TRuntimeNode runConfig,
TType* userType,
- const std::string_view& typeConfig
+ const std::string_view& typeConfig
)
{
TRuntimeNode userTypeNode = userType ? TRuntimeNode(userType, true) : TRuntimeNode(Env.GetVoid()->GetType(), true);
@@ -3730,7 +3730,7 @@ TRuntimeNode TProgramBuilder::Udf(
auto funNameNode = NewDataLiteral<NUdf::EDataSlot::String>(funcName);
auto typeConfigNode = NewDataLiteral<NUdf::EDataSlot::String>(typeConfig);
- TCallableBuilder callableBuilder(Env, __func__, funcInfo.FunctionType);
+ TCallableBuilder callableBuilder(Env, __func__, funcInfo.FunctionType);
callableBuilder.Add(funNameNode);
callableBuilder.Add(userTypeNode);
callableBuilder.Add(typeConfigNode);
@@ -3740,12 +3740,12 @@ TRuntimeNode TProgramBuilder::Udf(
}
TRuntimeNode TProgramBuilder::TypedUdf(
- const std::string_view& funcName,
+ const std::string_view& funcName,
TType* funcType,
TRuntimeNode runConfig,
TType* userType,
- const std::string_view& typeConfig,
- const std::string_view& file,
+ const std::string_view& typeConfig,
+ const std::string_view& file,
ui32 row,
ui32 column)
{
@@ -3767,10 +3767,10 @@ TRuntimeNode TProgramBuilder::TypedUdf(
TRuntimeNode TProgramBuilder::ScriptUdf(
EScriptType scriptType,
- const std::string_view& funcName,
+ const std::string_view& funcName,
TType* funcType,
TRuntimeNode script,
- const std::string_view& file,
+ const std::string_view& file,
ui32 row,
ui32 column)
{
@@ -3787,7 +3787,7 @@ TRuntimeNode TProgramBuilder::ScriptUdf(
TRuntimeNode userTypeNode(funcType, true);
auto typeConfigNode = NewDataLiteral<NUdf::EDataSlot::String>("");
- TCallableBuilder callableBuilder(Env, __func__, funcType);
+ TCallableBuilder callableBuilder(Env, __func__, funcType);
callableBuilder.Add(funcNameNode);
callableBuilder.Add(userTypeNode);
callableBuilder.Add(typeConfigNode);
@@ -3800,7 +3800,7 @@ TRuntimeNode TProgramBuilder::ScriptUdf(
}
TRuntimeNode TProgramBuilder::Apply(TRuntimeNode callableNode, const TArrayRef<const TRuntimeNode>& args,
- const std::string_view& file, ui32 row, ui32 column, ui32 dependentCount) {
+ const std::string_view& file, ui32 row, ui32 column, ui32 dependentCount) {
MKQL_ENSURE(dependentCount <= args.size(), "Too many dependent nodes");
ui32 usedArgs = args.size() - dependentCount;
MKQL_ENSURE(!callableNode.IsImmediate() && callableNode.GetNode()->GetType()->IsCallable(),
@@ -3822,11 +3822,11 @@ TRuntimeNode TProgramBuilder::Apply(TRuntimeNode callableNode, const TArrayRef<c
<< " with static " << arg.GetStaticType()->GetKindAsStr());
}
- TCallableBuilder callableBuilder(Env, RuntimeVersion >= 8 ? "Apply2" : "Apply", callableType->GetReturnType());
+ TCallableBuilder callableBuilder(Env, RuntimeVersion >= 8 ? "Apply2" : "Apply", callableType->GetReturnType());
callableBuilder.Add(callableNode);
- callableBuilder.Add(NewDataLiteral<ui32>(dependentCount));
+ callableBuilder.Add(NewDataLiteral<ui32>(dependentCount));
- if constexpr (RuntimeVersion >= 8) {
+ if constexpr (RuntimeVersion >= 8) {
callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
callableBuilder.Add(NewDataLiteral(row));
callableBuilder.Add(NewDataLiteral(column));
@@ -3846,16 +3846,16 @@ TRuntimeNode TProgramBuilder::Apply(
return Apply(callableNode, args, {}, 0, 0, dependentCount);
}
-TRuntimeNode TProgramBuilder::Callable(TType* callableType, const TArrayLambda& handler) {
+TRuntimeNode TProgramBuilder::Callable(TType* callableType, const TArrayLambda& handler) {
auto castedCallableType = AS_TYPE(TCallableType, callableType);
- std::vector<TRuntimeNode> args;
+ std::vector<TRuntimeNode> args;
args.reserve(castedCallableType->GetArgumentsCount());
for (ui32 i = 0; i < castedCallableType->GetArgumentsCount(); ++i) {
args.push_back(Arg(castedCallableType->GetArgumentType(i)));
}
auto res = handler(args);
- TCallableBuilder callableBuilder(Env, __func__, callableType);
+ TCallableBuilder callableBuilder(Env, __func__, callableType);
for (ui32 i = 0; i < castedCallableType->GetArgumentsCount(); ++i) {
callableBuilder.Add(args[i]);
}
@@ -3874,106 +3874,106 @@ TRuntimeNode TProgramBuilder::NewNull() {
}
TRuntimeNode TProgramBuilder::Concat(TRuntimeNode data1, TRuntimeNode data2) {
- bool isOpt1, isOpt2;
- const auto type1 = UnpackOptionalData(data1, isOpt1)->GetSchemeType();
- const auto type2 = UnpackOptionalData(data2, isOpt2)->GetSchemeType();
- const auto resultType = NewDataType(type1 == type2 ? type1 : NUdf::TDataType<char*>::Id);
- return InvokeBinary(__func__, isOpt1 || isOpt2 ? NewOptionalType(resultType) : resultType, data1, data2);
-}
-
-TRuntimeNode TProgramBuilder::AggrConcat(TRuntimeNode data1, TRuntimeNode data2) {
- MKQL_ENSURE(data1.GetStaticType()->IsSameType(*data2.GetStaticType()), "Operands type mismatch.");
- const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
- return Invoke(__func__, data1.GetStaticType(), args);
-}
-
+ bool isOpt1, isOpt2;
+ const auto type1 = UnpackOptionalData(data1, isOpt1)->GetSchemeType();
+ const auto type2 = UnpackOptionalData(data2, isOpt2)->GetSchemeType();
+ const auto resultType = NewDataType(type1 == type2 ? type1 : NUdf::TDataType<char*>::Id);
+ return InvokeBinary(__func__, isOpt1 || isOpt2 ? NewOptionalType(resultType) : resultType, data1, data2);
+}
+
+TRuntimeNode TProgramBuilder::AggrConcat(TRuntimeNode data1, TRuntimeNode data2) {
+ MKQL_ENSURE(data1.GetStaticType()->IsSameType(*data2.GetStaticType()), "Operands type mismatch.");
+ const std::array<TRuntimeNode, 2> args = {{ data1, data2 }};
+ return Invoke(__func__, data1.GetStaticType(), args);
+}
+
TRuntimeNode TProgramBuilder::Substring(TRuntimeNode data, TRuntimeNode start, TRuntimeNode count) {
- const std::array<TRuntimeNode, 3U> args = {{ data, start, count }};
- return Invoke(__func__, data.GetStaticType(), args);
-}
-
-TRuntimeNode TProgramBuilder::Find(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos) {
- const std::array<TRuntimeNode, 3U> args = {{ haystack, needle, pos }};
- return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui32>::Id)), args);
-}
-
-TRuntimeNode TProgramBuilder::RFind(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos) {
- const std::array<TRuntimeNode, 3U> args = {{ haystack, needle, pos }};
- return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui32>::Id)), args);
-}
-
-TRuntimeNode TProgramBuilder::StartsWith(TRuntimeNode string, TRuntimeNode prefix) {
- if constexpr (RuntimeVersion < 19U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- return DataCompare(__func__, string, prefix);
-}
-
-TRuntimeNode TProgramBuilder::EndsWith(TRuntimeNode string, TRuntimeNode suffix) {
- if constexpr (RuntimeVersion < 19U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- return DataCompare(__func__, string, suffix);
-}
-
+ const std::array<TRuntimeNode, 3U> args = {{ data, start, count }};
+ return Invoke(__func__, data.GetStaticType(), args);
+}
+
+TRuntimeNode TProgramBuilder::Find(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos) {
+ const std::array<TRuntimeNode, 3U> args = {{ haystack, needle, pos }};
+ return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui32>::Id)), args);
+}
+
+TRuntimeNode TProgramBuilder::RFind(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos) {
+ const std::array<TRuntimeNode, 3U> args = {{ haystack, needle, pos }};
+ return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui32>::Id)), args);
+}
+
+TRuntimeNode TProgramBuilder::StartsWith(TRuntimeNode string, TRuntimeNode prefix) {
+ if constexpr (RuntimeVersion < 19U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ return DataCompare(__func__, string, prefix);
+}
+
+TRuntimeNode TProgramBuilder::EndsWith(TRuntimeNode string, TRuntimeNode suffix) {
+ if constexpr (RuntimeVersion < 19U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ return DataCompare(__func__, string, suffix);
+}
+
TRuntimeNode TProgramBuilder::ByteAt(TRuntimeNode data, TRuntimeNode index) {
- const std::array<TRuntimeNode, 2U> args = {{ data, index }};
- return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui8>::Id)), args);
+ const std::array<TRuntimeNode, 2U> args = {{ data, index }};
+ return Invoke(__func__, NewOptionalType(NewDataType(NUdf::TDataType<ui8>::Id)), args);
}
TRuntimeNode TProgramBuilder::Size(TRuntimeNode data) {
return UnaryDataFunction(data, __func__, TDataFunctionFlags::HasUi32Result | TDataFunctionFlags::AllowNull | TDataFunctionFlags::AllowOptionalArgs | TDataFunctionFlags::CommonOptionalResult);
}
-template <bool Utf8>
-TRuntimeNode TProgramBuilder::ToString(TRuntimeNode data) {
- bool isOptional;
- UnpackOptionalData(data, isOptional);
- const auto resultType = NewDataType(Utf8 ? NUdf::EDataSlot::Utf8 : NUdf::EDataSlot::String, isOptional);
-
- TCallableBuilder callableBuilder(Env, __func__, resultType);
- callableBuilder.Add(data);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::FromString(TRuntimeNode data, TType* type) {
+template <bool Utf8>
+TRuntimeNode TProgramBuilder::ToString(TRuntimeNode data) {
+ bool isOptional;
+ UnpackOptionalData(data, isOptional);
+ const auto resultType = NewDataType(Utf8 ? NUdf::EDataSlot::Utf8 : NUdf::EDataSlot::String, isOptional);
+
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
+ callableBuilder.Add(data);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::FromString(TRuntimeNode data, TType* type) {
bool isOptional;
- const auto sourceType = UnpackOptionalData(data, isOptional);
- const auto targetType = UnpackOptionalData(type, isOptional);
- MKQL_ENSURE(sourceType->GetSchemeType() == NUdf::TDataType<char*>::Id || sourceType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
+ const auto sourceType = UnpackOptionalData(data, isOptional);
+ const auto targetType = UnpackOptionalData(type, isOptional);
+ MKQL_ENSURE(sourceType->GetSchemeType() == NUdf::TDataType<char*>::Id || sourceType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
MKQL_ENSURE(targetType->GetSchemeType() != 0, "Null is not allowed");
- TCallableBuilder callableBuilder(Env, __func__, type);
+ TCallableBuilder callableBuilder(Env, __func__, type);
callableBuilder.Add(data);
- callableBuilder.Add(NewDataLiteral(static_cast<ui32>(targetType->GetSchemeType())));
- if (targetType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
- callableBuilder.Add(NewDataLiteral(params.first));
- callableBuilder.Add(NewDataLiteral(params.second));
- }
+ callableBuilder.Add(NewDataLiteral(static_cast<ui32>(targetType->GetSchemeType())));
+ if (targetType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
+ callableBuilder.Add(NewDataLiteral(params.first));
+ callableBuilder.Add(NewDataLiteral(params.second));
+ }
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::StrictFromString(TRuntimeNode data, TType* type) {
- bool isOptional;
- const auto sourceType = UnpackOptionalData(data, isOptional);
- const auto targetType = UnpackOptionalData(type, isOptional);
- MKQL_ENSURE(sourceType->GetSchemeType() == NUdf::TDataType<char*>::Id || sourceType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
+TRuntimeNode TProgramBuilder::StrictFromString(TRuntimeNode data, TType* type) {
+ bool isOptional;
+ const auto sourceType = UnpackOptionalData(data, isOptional);
+ const auto targetType = UnpackOptionalData(type, isOptional);
+ MKQL_ENSURE(sourceType->GetSchemeType() == NUdf::TDataType<char*>::Id || sourceType->GetSchemeType() == NUdf::TDataType<NUdf::TUtf8>::Id, "Expected String");
MKQL_ENSURE(targetType->GetSchemeType() != 0, "Null is not allowed");
- TCallableBuilder callableBuilder(Env, __func__, type);
- callableBuilder.Add(data);
- callableBuilder.Add(NewDataLiteral(static_cast<ui32>(targetType->GetSchemeType())));
- if (targetType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
- callableBuilder.Add(NewDataLiteral(params.first));
- callableBuilder.Add(NewDataLiteral(params.second));
+ TCallableBuilder callableBuilder(Env, __func__, type);
+ callableBuilder.Add(data);
+ callableBuilder.Add(NewDataLiteral(static_cast<ui32>(targetType->GetSchemeType())));
+ if (targetType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
+ callableBuilder.Add(NewDataLiteral(params.first));
+ callableBuilder.Add(NewDataLiteral(params.second));
}
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::ToBytes(TRuntimeNode data) {
- return UnaryDataFunction(data, __func__, TDataFunctionFlags::HasStringResult | TDataFunctionFlags::AllowOptionalArgs | TDataFunctionFlags::CommonOptionalResult);
+ return UnaryDataFunction(data, __func__, TDataFunctionFlags::HasStringResult | TDataFunctionFlags::AllowOptionalArgs | TDataFunctionFlags::CommonOptionalResult);
}
TRuntimeNode TProgramBuilder::FromBytes(TRuntimeNode data, NUdf::TDataTypeId schemeType) {
@@ -3984,24 +3984,24 @@ TRuntimeNode TProgramBuilder::FromBytes(TRuntimeNode data, NUdf::TDataTypeId sch
auto outDataType = NewDataType(schemeType);
auto resultType = NewOptionalType(outDataType);
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(data);
callableBuilder.Add(NewDataLiteral(static_cast<ui32>(schemeType)));
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::InversePresortString(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1U> args = {{ data }};
- return Invoke(__func__, NewDataType(NUdf::TDataType<char*>::Id), args);
+ const std::array<TRuntimeNode, 1U> args = {{ data }};
+ return Invoke(__func__, NewDataType(NUdf::TDataType<char*>::Id), args);
}
TRuntimeNode TProgramBuilder::InverseString(TRuntimeNode data) {
- const std::array<TRuntimeNode, 1U> args = {{ data }};
- return Invoke(__func__, NewDataType(NUdf::TDataType<char*>::Id), args);
+ const std::array<TRuntimeNode, 1U> args = {{ data }};
+ return Invoke(__func__, NewDataType(NUdf::TDataType<char*>::Id), args);
}
TRuntimeNode TProgramBuilder::Random(const TArrayRef<const TRuntimeNode>& dependentNodes) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<double>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<double>::Id));
for (auto& x : dependentNodes) {
callableBuilder.Add(x);
}
@@ -4010,7 +4010,7 @@ TRuntimeNode TProgramBuilder::Random(const TArrayRef<const TRuntimeNode>& depend
}
TRuntimeNode TProgramBuilder::RandomNumber(const TArrayRef<const TRuntimeNode>& dependentNodes) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
for (auto& x : dependentNodes) {
callableBuilder.Add(x);
}
@@ -4019,7 +4019,7 @@ TRuntimeNode TProgramBuilder::RandomNumber(const TArrayRef<const TRuntimeNode>&
}
TRuntimeNode TProgramBuilder::RandomUuid(const TArrayRef<const TRuntimeNode>& dependentNodes) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<NUdf::TUuid>::Id));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<NUdf::TUuid>::Id));
for (auto& x : dependentNodes) {
callableBuilder.Add(x);
}
@@ -4027,43 +4027,43 @@ TRuntimeNode TProgramBuilder::RandomUuid(const TArrayRef<const TRuntimeNode>& de
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Now(const TArrayRef<const TRuntimeNode>& args) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
- for (const auto& x : args) {
+TRuntimeNode TProgramBuilder::Now(const TArrayRef<const TRuntimeNode>& args) {
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::TDataType<ui64>::Id));
+ for (const auto& x : args) {
callableBuilder.Add(x);
}
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::CurrentUtcDate(const TArrayRef<const TRuntimeNode>& args) {
- return Cast(CurrentUtcTimestamp(args), NewDataType(NUdf::TDataType<NUdf::TDate>::Id));
-}
-
-TRuntimeNode TProgramBuilder::CurrentUtcDatetime(const TArrayRef<const TRuntimeNode>& args) {
- return Cast(CurrentUtcTimestamp(args), NewDataType(NUdf::TDataType<NUdf::TDatetime>::Id));
-}
-
-TRuntimeNode TProgramBuilder::CurrentUtcTimestamp(const TArrayRef<const TRuntimeNode>& args) {
- return Coalesce(ToIntegral(Now(args), NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id, true)),
- TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod(ui64(NUdf::MAX_TIMESTAMP - 1ULL)), NUdf::TDataType<NUdf::TTimestamp>::Id, Env), true));
-}
-
+TRuntimeNode TProgramBuilder::CurrentUtcDate(const TArrayRef<const TRuntimeNode>& args) {
+ return Cast(CurrentUtcTimestamp(args), NewDataType(NUdf::TDataType<NUdf::TDate>::Id));
+}
+
+TRuntimeNode TProgramBuilder::CurrentUtcDatetime(const TArrayRef<const TRuntimeNode>& args) {
+ return Cast(CurrentUtcTimestamp(args), NewDataType(NUdf::TDataType<NUdf::TDatetime>::Id));
+}
+
+TRuntimeNode TProgramBuilder::CurrentUtcTimestamp(const TArrayRef<const TRuntimeNode>& args) {
+ return Coalesce(ToIntegral(Now(args), NewDataType(NUdf::TDataType<NUdf::TTimestamp>::Id, true)),
+ TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod(ui64(NUdf::MAX_TIMESTAMP - 1ULL)), NUdf::TDataType<NUdf::TTimestamp>::Id, Env), true));
+}
+
TRuntimeNode TProgramBuilder::Pickle(TRuntimeNode data) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::EDataSlot::String));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::EDataSlot::String));
callableBuilder.Add(data);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::StablePickle(TRuntimeNode data) {
- TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::EDataSlot::String));
+ TCallableBuilder callableBuilder(Env, __func__, NewDataType(NUdf::EDataSlot::String));
callableBuilder.Add(data);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Unpickle(TType* type, TRuntimeNode serialized) {
MKQL_ENSURE(AS_TYPE(TDataType, serialized)->GetSchemeType() == NUdf::TDataType<char*>::Id, "Expected String");
- TCallableBuilder callableBuilder(Env, __func__, type);
+ TCallableBuilder callableBuilder(Env, __func__, type);
callableBuilder.Add(TRuntimeNode(type, true));
callableBuilder.Add(serialized);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -4071,89 +4071,89 @@ TRuntimeNode TProgramBuilder::Unpickle(TType* type, TRuntimeNode serialized) {
TRuntimeNode TProgramBuilder::Ascending(TRuntimeNode data) {
auto dataType = NewDataType(NUdf::EDataSlot::String);
- TCallableBuilder callableBuilder(Env, __func__, dataType);
+ TCallableBuilder callableBuilder(Env, __func__, dataType);
callableBuilder.Add(data);
return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Descending(TRuntimeNode data) {
auto dataType = NewDataType(NUdf::EDataSlot::String);
- TCallableBuilder callableBuilder(Env, __func__, dataType);
+ TCallableBuilder callableBuilder(Env, __func__, dataType);
callableBuilder.Add(data);
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Convert(TRuntimeNode data, TType* type) {
- if (data.GetStaticType()->IsSameType(*type)) {
+TRuntimeNode TProgramBuilder::Convert(TRuntimeNode data, TType* type) {
+ if (data.GetStaticType()->IsSameType(*type)) {
return data;
}
- bool isOptional;
- const auto dataType = UnpackOptionalData(data, isOptional);
-
- const std::array<TRuntimeNode, 1> args = {{ data }};
-
- if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto targetSchemeType = UnpackOptionalData(type, isOptional)->GetSchemeType();
- TStringStream str;
- str << "To" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(targetSchemeType)).Name
- << '_' << ::ToString(static_cast<const TDataDecimalType*>(dataType)->GetParams().second);
- return Invoke(str.Str().c_str(), type, args);
- }
-
- return Invoke(__func__, type, args);
-}
-
-TRuntimeNode TProgramBuilder::ToDecimal(TRuntimeNode data, ui8 precision, ui8 scale) {
- bool isOptional;
- auto dataType = UnpackOptionalData(data, isOptional);
-
- TType* decimal = TDataDecimalType::Create(precision, scale, Env);
- if (isOptional)
- decimal = TOptionalType::Create(decimal, Env);
- const std::array<TRuntimeNode, 1> args = {{ data }};
-
- if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& params = static_cast<const TDataDecimalType*>(dataType)->GetParams();
- if (precision - scale < params.first - params.second && scale != params.second) {
- return ToDecimal(ToDecimal(data, precision - scale + params.second, params.second), precision, scale);
- } else if (params.second < scale) {
- return Invoke("ScaleUp_" + ::ToString(scale - params.second), decimal, args);
- } else if (params.second > scale) {
- return Invoke("ScaleDown_" + ::ToString(params.second - scale), decimal, args);
- } else if (precision < params.first) {
- return Invoke("CheckBounds_" + ::ToString(precision), decimal, args);
- } else if (precision > params.first) {
- return Invoke("Plus", decimal, args);
- } else {
- return data;
- }
- } else {
- const auto digits = NUdf::GetDataTypeInfo(*dataType->GetDataSlot()).DecimalDigits;
- MKQL_ENSURE(digits, "Can't cast into Decimal.");
- if (digits <= precision && !scale)
- return Invoke(__func__, decimal, args);
- else
- return ToDecimal(ToDecimal(data, digits, 0), precision, scale);
- }
-}
-
-TRuntimeNode TProgramBuilder::ToIntegral(TRuntimeNode data, TType* type) {
- bool isOptional;
- auto dataType = UnpackOptionalData(data, isOptional);
-
- if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& params = static_cast<const TDataDecimalType*>(dataType)->GetParams();
- if (params.second)
- return ToIntegral(ToDecimal(data, params.first - params.second, 0), type);
- }
-
- const std::array<TRuntimeNode, 1> args = {{ data }};
- return Invoke(__func__, type, args);
+ bool isOptional;
+ const auto dataType = UnpackOptionalData(data, isOptional);
+
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+
+ if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto targetSchemeType = UnpackOptionalData(type, isOptional)->GetSchemeType();
+ TStringStream str;
+ str << "To" << NUdf::GetDataTypeInfo(NUdf::GetDataSlot(targetSchemeType)).Name
+ << '_' << ::ToString(static_cast<const TDataDecimalType*>(dataType)->GetParams().second);
+ return Invoke(str.Str().c_str(), type, args);
+ }
+
+ return Invoke(__func__, type, args);
+}
+
+TRuntimeNode TProgramBuilder::ToDecimal(TRuntimeNode data, ui8 precision, ui8 scale) {
+ bool isOptional;
+ auto dataType = UnpackOptionalData(data, isOptional);
+
+ TType* decimal = TDataDecimalType::Create(precision, scale, Env);
+ if (isOptional)
+ decimal = TOptionalType::Create(decimal, Env);
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+
+ if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& params = static_cast<const TDataDecimalType*>(dataType)->GetParams();
+ if (precision - scale < params.first - params.second && scale != params.second) {
+ return ToDecimal(ToDecimal(data, precision - scale + params.second, params.second), precision, scale);
+ } else if (params.second < scale) {
+ return Invoke("ScaleUp_" + ::ToString(scale - params.second), decimal, args);
+ } else if (params.second > scale) {
+ return Invoke("ScaleDown_" + ::ToString(params.second - scale), decimal, args);
+ } else if (precision < params.first) {
+ return Invoke("CheckBounds_" + ::ToString(precision), decimal, args);
+ } else if (precision > params.first) {
+ return Invoke("Plus", decimal, args);
+ } else {
+ return data;
+ }
+ } else {
+ const auto digits = NUdf::GetDataTypeInfo(*dataType->GetDataSlot()).DecimalDigits;
+ MKQL_ENSURE(digits, "Can't cast into Decimal.");
+ if (digits <= precision && !scale)
+ return Invoke(__func__, decimal, args);
+ else
+ return ToDecimal(ToDecimal(data, digits, 0), precision, scale);
+ }
+}
+
+TRuntimeNode TProgramBuilder::ToIntegral(TRuntimeNode data, TType* type) {
+ bool isOptional;
+ auto dataType = UnpackOptionalData(data, isOptional);
+
+ if (dataType->GetSchemeType() == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& params = static_cast<const TDataDecimalType*>(dataType)->GetParams();
+ if (params.second)
+ return ToIntegral(ToDecimal(data, params.first - params.second, 0), type);
+ }
+
+ const std::array<TRuntimeNode, 1> args = {{ data }};
+ return Invoke(__func__, type, args);
}
TRuntimeNode TProgramBuilder::ListIf(TRuntimeNode predicate, TRuntimeNode item) {
- return If(predicate, NewList(item.GetStaticType(), {item}), NewEmptyList(item.GetStaticType()));
+ return If(predicate, NewList(item.GetStaticType(), {item}), NewEmptyList(item.GetStaticType()));
}
TRuntimeNode TProgramBuilder::AsList(TRuntimeNode item) {
@@ -4172,305 +4172,305 @@ TRuntimeNode TProgramBuilder::AsList(const TArrayRef<const TRuntimeNode>& items)
return TRuntimeNode(builder.Build(), true);
}
-TRuntimeNode TProgramBuilder::MapJoinCore(TRuntimeNode flow, TRuntimeNode dict, EJoinKind joinKind,
- const TArrayRef<const ui32>& leftKeyColumns, const TArrayRef<const ui32>& leftRenames,
- const TArrayRef<const ui32>& rightRenames, TType* returnType) {
-
- MKQL_ENSURE(joinKind == EJoinKind::Inner || joinKind == EJoinKind::Left || joinKind == EJoinKind::LeftSemi || joinKind == EJoinKind::LeftOnly, "Unsupported join kind");
- MKQL_ENSURE(!leftKeyColumns.empty(), "At least one key column must be specified");
- MKQL_ENSURE(leftRenames.size() % 2U == 0U, "Expected even count");
- MKQL_ENSURE(rightRenames.size() % 2U == 0U, "Expected even count");
-
- TRuntimeNode::TList leftKeyColumnsNodes, leftRenamesNodes, rightRenamesNodes;
-
- leftKeyColumnsNodes.reserve(leftKeyColumns.size());
- std::transform(leftKeyColumns.cbegin(), leftKeyColumns.cend(), std::back_inserter(leftKeyColumnsNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
-
- leftRenamesNodes.reserve(leftRenames.size());
- std::transform(leftRenames.cbegin(), leftRenames.cend(), std::back_inserter(leftRenamesNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
-
- rightRenamesNodes.reserve(rightRenames.size());
- std::transform(rightRenames.cbegin(), rightRenames.cend(), std::back_inserter(rightRenamesNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
-
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- callableBuilder.Add(flow);
- callableBuilder.Add(dict);
- callableBuilder.Add(NewDataLiteral((ui32)joinKind));
- callableBuilder.Add(NewTuple(leftKeyColumnsNodes));
- callableBuilder.Add(NewTuple(leftRenamesNodes));
- callableBuilder.Add(NewTuple(rightRenamesNodes));
-
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::CommonJoinCore(TRuntimeNode flow, EJoinKind joinKind,
- const TArrayRef<const ui32>& leftColumns, const TArrayRef<const ui32>& rightColumns,
- const TArrayRef<const ui32>& requiredColumns, const TArrayRef<const ui32>& keyColumns,
- ui64 memLimit, std::optional<ui32> sortedTableOrder,
- EAnyJoinSettings anyJoinSettings, const ui32 tableIndexField, TType* returnType) {
-
- if constexpr (RuntimeVersion < 17U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- MKQL_ENSURE(leftColumns.size() % 2U == 0U, "Expected even count");
- MKQL_ENSURE(rightColumns.size() % 2U == 0U, "Expected even count");
-
- TRuntimeNode::TList leftInputColumnsNodes, rightInputColumnsNodes, requiredColumnsNodes,
- leftOutputColumnsNodes, rightOutputColumnsNodes, keyColumnsNodes;
-
- bool s = false;
- for (const auto idx : leftColumns) {
- ((s = !s) ? leftInputColumnsNodes : leftOutputColumnsNodes).emplace_back(NewDataLiteral(idx));
- }
-
- for (const auto idx : rightColumns) {
- ((s = !s) ? rightInputColumnsNodes : rightOutputColumnsNodes).emplace_back(NewDataLiteral(idx));
- }
-
- const std::unordered_set<ui32> requiredIndices(requiredColumns.cbegin(), requiredColumns.cend());
- MKQL_ENSURE(requiredIndices.size() == requiredColumns.size(), "Duplication of requred columns.");
-
- requiredColumnsNodes.reserve(requiredColumns.size());
- std::transform(requiredColumns.cbegin(), requiredColumns.cend(), std::back_inserter(requiredColumnsNodes),
- std::bind(&TProgramBuilder::NewDataLiteral<ui32>, this, std::placeholders::_1));
-
- const std::unordered_set<ui32> keyIndices(keyColumns.cbegin(), keyColumns.cend());
- MKQL_ENSURE(keyIndices.size() == keyColumns.size(), "Duplication of key columns.");
-
- keyColumnsNodes.reserve(keyColumns.size());
- std::transform(keyColumns.cbegin(), keyColumns.cend(), std::back_inserter(keyColumnsNodes),
- std::bind(&TProgramBuilder::NewDataLiteral<ui32>, this, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, returnType);
- callableBuilder.Add(flow);
- callableBuilder.Add(NewDataLiteral((ui32)joinKind));
- callableBuilder.Add(NewTuple(leftInputColumnsNodes));
- callableBuilder.Add(NewTuple(rightInputColumnsNodes));
- callableBuilder.Add(NewTuple(requiredColumnsNodes));
- callableBuilder.Add(NewTuple(leftOutputColumnsNodes));
- callableBuilder.Add(NewTuple(rightOutputColumnsNodes));
- callableBuilder.Add(NewTuple(keyColumnsNodes));
- callableBuilder.Add(NewDataLiteral(memLimit));
- callableBuilder.Add(sortedTableOrder ? NewDataLiteral(*sortedTableOrder) : NewVoid());
- callableBuilder.Add(NewDataLiteral((ui32)anyJoinSettings));
- callableBuilder.Add(NewDataLiteral(tableIndexField));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideCombiner(TRuntimeNode flow, ui64 memLimit, const TWideLambda& extractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
-
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto keys = extractor(itemArgs);
-
- TRuntimeNode::TList keyArgs;
- keyArgs.reserve(keys.size());
- std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
-
- const auto first = init(keyArgs, itemArgs);
-
- TRuntimeNode::TList stateArgs;
- stateArgs.reserve(first.size());
- std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
-
- const auto next = update(keyArgs, itemArgs, stateArgs);
- MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
-
- TRuntimeNode::TList finishKeyArgs;
- finishKeyArgs.reserve(keys.size());
- std::transform(keys.cbegin(), keys.cend(), std::back_inserter(finishKeyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
-
- TRuntimeNode::TList finishStateArgs;
- finishStateArgs.reserve(next.size());
- std::transform(next.cbegin(), next.cend(), std::back_inserter(finishStateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
-
- const auto output = finish(finishKeyArgs, finishStateArgs);
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(output.size());
- std::transform(output.cbegin(), output.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- callableBuilder.Add(NewDataLiteral(memLimit));
- callableBuilder.Add(NewDataLiteral(ui32(keyArgs.size())));
- callableBuilder.Add(NewDataLiteral(ui32(stateArgs.size())));
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(finishKeyArgs.cbegin(), finishKeyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(finishStateArgs.cbegin(), finishStateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(output.cbegin(), output.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideLastCombiner(TRuntimeNode flow, const TWideLambda& extractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish) {
- if constexpr (RuntimeVersion < 29U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
-
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto keys = extractor(itemArgs);
-
- TRuntimeNode::TList keyArgs;
- keyArgs.reserve(keys.size());
- std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
-
- const auto first = init(keyArgs, itemArgs);
-
- TRuntimeNode::TList stateArgs;
- stateArgs.reserve(first.size());
- std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
-
- const auto next = update(keyArgs, itemArgs, stateArgs);
- MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
-
- TRuntimeNode::TList finishKeyArgs;
- finishKeyArgs.reserve(keys.size());
- std::transform(keys.cbegin(), keys.cend(), std::back_inserter(finishKeyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
-
- TRuntimeNode::TList finishStateArgs;
- finishStateArgs.reserve(next.size());
- std::transform(next.cbegin(), next.cend(), std::back_inserter(finishStateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
-
- const auto output = finish(finishKeyArgs, finishStateArgs);
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(output.size());
- std::transform(output.cbegin(), output.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- callableBuilder.Add(NewDataLiteral(ui32(keyArgs.size())));
- callableBuilder.Add(NewDataLiteral(ui32(stateArgs.size())));
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(finishKeyArgs.cbegin(), finishKeyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(finishStateArgs.cbegin(), finishStateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(output.cbegin(), output.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideCondense1(TRuntimeNode flow, const TWideLambda& init, const TWideSwitchLambda& switcher, const TBinaryWideLambda& update) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
-
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto first = init(itemArgs);
-
- TRuntimeNode::TList stateArgs;
- stateArgs.reserve(first.size());
- std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
-
- const auto chop = switcher(itemArgs, stateArgs);
-
- const auto next = update(itemArgs, stateArgs);
- MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
-
- std::vector<TType*> tupleItems;
- tupleItems.reserve(next.size());
- std::transform(next.cbegin(), next.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
-
- TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(chop);
- std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::MapJoinCore(TRuntimeNode flow, TRuntimeNode dict, EJoinKind joinKind,
+ const TArrayRef<const ui32>& leftKeyColumns, const TArrayRef<const ui32>& leftRenames,
+ const TArrayRef<const ui32>& rightRenames, TType* returnType) {
+
+ MKQL_ENSURE(joinKind == EJoinKind::Inner || joinKind == EJoinKind::Left || joinKind == EJoinKind::LeftSemi || joinKind == EJoinKind::LeftOnly, "Unsupported join kind");
+ MKQL_ENSURE(!leftKeyColumns.empty(), "At least one key column must be specified");
+ MKQL_ENSURE(leftRenames.size() % 2U == 0U, "Expected even count");
+ MKQL_ENSURE(rightRenames.size() % 2U == 0U, "Expected even count");
+
+ TRuntimeNode::TList leftKeyColumnsNodes, leftRenamesNodes, rightRenamesNodes;
+
+ leftKeyColumnsNodes.reserve(leftKeyColumns.size());
+ std::transform(leftKeyColumns.cbegin(), leftKeyColumns.cend(), std::back_inserter(leftKeyColumnsNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
+
+ leftRenamesNodes.reserve(leftRenames.size());
+ std::transform(leftRenames.cbegin(), leftRenames.cend(), std::back_inserter(leftRenamesNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
+
+ rightRenamesNodes.reserve(rightRenames.size());
+ std::transform(rightRenames.cbegin(), rightRenames.cend(), std::back_inserter(rightRenamesNodes), [this](const ui32 idx) { return NewDataLiteral(idx); });
+
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ callableBuilder.Add(flow);
+ callableBuilder.Add(dict);
+ callableBuilder.Add(NewDataLiteral((ui32)joinKind));
+ callableBuilder.Add(NewTuple(leftKeyColumnsNodes));
+ callableBuilder.Add(NewTuple(leftRenamesNodes));
+ callableBuilder.Add(NewTuple(rightRenamesNodes));
+
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::CommonJoinCore(TRuntimeNode flow, EJoinKind joinKind,
+ const TArrayRef<const ui32>& leftColumns, const TArrayRef<const ui32>& rightColumns,
+ const TArrayRef<const ui32>& requiredColumns, const TArrayRef<const ui32>& keyColumns,
+ ui64 memLimit, std::optional<ui32> sortedTableOrder,
+ EAnyJoinSettings anyJoinSettings, const ui32 tableIndexField, TType* returnType) {
+
+ if constexpr (RuntimeVersion < 17U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ MKQL_ENSURE(leftColumns.size() % 2U == 0U, "Expected even count");
+ MKQL_ENSURE(rightColumns.size() % 2U == 0U, "Expected even count");
+
+ TRuntimeNode::TList leftInputColumnsNodes, rightInputColumnsNodes, requiredColumnsNodes,
+ leftOutputColumnsNodes, rightOutputColumnsNodes, keyColumnsNodes;
+
+ bool s = false;
+ for (const auto idx : leftColumns) {
+ ((s = !s) ? leftInputColumnsNodes : leftOutputColumnsNodes).emplace_back(NewDataLiteral(idx));
+ }
+
+ for (const auto idx : rightColumns) {
+ ((s = !s) ? rightInputColumnsNodes : rightOutputColumnsNodes).emplace_back(NewDataLiteral(idx));
+ }
+
+ const std::unordered_set<ui32> requiredIndices(requiredColumns.cbegin(), requiredColumns.cend());
+ MKQL_ENSURE(requiredIndices.size() == requiredColumns.size(), "Duplication of requred columns.");
+
+ requiredColumnsNodes.reserve(requiredColumns.size());
+ std::transform(requiredColumns.cbegin(), requiredColumns.cend(), std::back_inserter(requiredColumnsNodes),
+ std::bind(&TProgramBuilder::NewDataLiteral<ui32>, this, std::placeholders::_1));
+
+ const std::unordered_set<ui32> keyIndices(keyColumns.cbegin(), keyColumns.cend());
+ MKQL_ENSURE(keyIndices.size() == keyColumns.size(), "Duplication of key columns.");
+
+ keyColumnsNodes.reserve(keyColumns.size());
+ std::transform(keyColumns.cbegin(), keyColumns.cend(), std::back_inserter(keyColumnsNodes),
+ std::bind(&TProgramBuilder::NewDataLiteral<ui32>, this, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, returnType);
+ callableBuilder.Add(flow);
+ callableBuilder.Add(NewDataLiteral((ui32)joinKind));
+ callableBuilder.Add(NewTuple(leftInputColumnsNodes));
+ callableBuilder.Add(NewTuple(rightInputColumnsNodes));
+ callableBuilder.Add(NewTuple(requiredColumnsNodes));
+ callableBuilder.Add(NewTuple(leftOutputColumnsNodes));
+ callableBuilder.Add(NewTuple(rightOutputColumnsNodes));
+ callableBuilder.Add(NewTuple(keyColumnsNodes));
+ callableBuilder.Add(NewDataLiteral(memLimit));
+ callableBuilder.Add(sortedTableOrder ? NewDataLiteral(*sortedTableOrder) : NewVoid());
+ callableBuilder.Add(NewDataLiteral((ui32)anyJoinSettings));
+ callableBuilder.Add(NewDataLiteral(tableIndexField));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideCombiner(TRuntimeNode flow, ui64 memLimit, const TWideLambda& extractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto keys = extractor(itemArgs);
+
+ TRuntimeNode::TList keyArgs;
+ keyArgs.reserve(keys.size());
+ std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
+
+ const auto first = init(keyArgs, itemArgs);
+
+ TRuntimeNode::TList stateArgs;
+ stateArgs.reserve(first.size());
+ std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
+
+ const auto next = update(keyArgs, itemArgs, stateArgs);
+ MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
+
+ TRuntimeNode::TList finishKeyArgs;
+ finishKeyArgs.reserve(keys.size());
+ std::transform(keys.cbegin(), keys.cend(), std::back_inserter(finishKeyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
+
+ TRuntimeNode::TList finishStateArgs;
+ finishStateArgs.reserve(next.size());
+ std::transform(next.cbegin(), next.cend(), std::back_inserter(finishStateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
+
+ const auto output = finish(finishKeyArgs, finishStateArgs);
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(output.size());
+ std::transform(output.cbegin(), output.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(NewDataLiteral(memLimit));
+ callableBuilder.Add(NewDataLiteral(ui32(keyArgs.size())));
+ callableBuilder.Add(NewDataLiteral(ui32(stateArgs.size())));
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(finishKeyArgs.cbegin(), finishKeyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(finishStateArgs.cbegin(), finishStateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(output.cbegin(), output.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideLastCombiner(TRuntimeNode flow, const TWideLambda& extractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish) {
+ if constexpr (RuntimeVersion < 29U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto keys = extractor(itemArgs);
+
+ TRuntimeNode::TList keyArgs;
+ keyArgs.reserve(keys.size());
+ std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
+
+ const auto first = init(keyArgs, itemArgs);
+
+ TRuntimeNode::TList stateArgs;
+ stateArgs.reserve(first.size());
+ std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
+
+ const auto next = update(keyArgs, itemArgs, stateArgs);
+ MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
+
+ TRuntimeNode::TList finishKeyArgs;
+ finishKeyArgs.reserve(keys.size());
+ std::transform(keys.cbegin(), keys.cend(), std::back_inserter(finishKeyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
+
+ TRuntimeNode::TList finishStateArgs;
+ finishStateArgs.reserve(next.size());
+ std::transform(next.cbegin(), next.cend(), std::back_inserter(finishStateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
+
+ const auto output = finish(finishKeyArgs, finishStateArgs);
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(output.size());
+ std::transform(output.cbegin(), output.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ callableBuilder.Add(NewDataLiteral(ui32(keyArgs.size())));
+ callableBuilder.Add(NewDataLiteral(ui32(stateArgs.size())));
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(finishKeyArgs.cbegin(), finishKeyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(finishStateArgs.cbegin(), finishStateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(output.cbegin(), output.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideCondense1(TRuntimeNode flow, const TWideLambda& init, const TWideSwitchLambda& switcher, const TBinaryWideLambda& update) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto first = init(itemArgs);
+
+ TRuntimeNode::TList stateArgs;
+ stateArgs.reserve(first.size());
+ std::transform(first.cbegin(), first.cend(), std::back_inserter(stateArgs), [&](TRuntimeNode state){ return Arg(state.GetStaticType()); } );
+
+ const auto chop = switcher(itemArgs, stateArgs);
+
+ const auto next = update(itemArgs, stateArgs);
+ MKQL_ENSURE(next.size() == first.size(), "Mismatch init and update state size.");
+
+ std::vector<TType*> tupleItems;
+ tupleItems.reserve(next.size());
+ std::transform(next.cbegin(), next.cend(), std::back_inserter(tupleItems), std::bind(&TRuntimeNode::GetStaticType, std::placeholders::_1));
+
+ TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewTupleType(tupleItems)));
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(first.cbegin(), first.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(stateArgs.cbegin(), stateArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(chop);
+ std::for_each(next.cbegin(), next.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::CombineCore(TRuntimeNode stream,
- const TUnaryLambda& keyExtractor,
- const TBinaryLambda& init,
- const TTernaryLambda& update,
- const TBinaryLambda& finish,
+ const TUnaryLambda& keyExtractor,
+ const TBinaryLambda& init,
+ const TTernaryLambda& update,
+ const TBinaryLambda& finish,
ui64 memLimit)
{
- if constexpr (RuntimeVersion < 3U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
+ if constexpr (RuntimeVersion < 3U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
- const bool isStream = stream.GetStaticType()->IsStream();
- const auto itemType = isStream ? AS_TYPE(TStreamType, stream)->GetItemType() : AS_TYPE(TFlowType, stream)->GetItemType();
+ const bool isStream = stream.GetStaticType()->IsStream();
+ const auto itemType = isStream ? AS_TYPE(TStreamType, stream)->GetItemType() : AS_TYPE(TFlowType, stream)->GetItemType();
- const auto itemArg = Arg(itemType);
+ const auto itemArg = Arg(itemType);
- const auto key = keyExtractor(itemArg);
- const auto keyType = key.GetStaticType();
+ const auto key = keyExtractor(itemArg);
+ const auto keyType = key.GetStaticType();
- const auto keyArg = Arg(keyType);
+ const auto keyArg = Arg(keyType);
- const auto stateInit = init(keyArg, itemArg);
- const auto stateType = stateInit.GetStaticType();
+ const auto stateInit = init(keyArg, itemArg);
+ const auto stateType = stateInit.GetStaticType();
- const auto stateArg = Arg(stateType);
+ const auto stateArg = Arg(stateType);
- const auto stateUpdate = update(keyArg, itemArg, stateArg);
- const auto finishItem = finish(keyArg, stateArg);
+ const auto stateUpdate = update(keyArg, itemArg, stateArg);
+ const auto finishItem = finish(keyArg, stateArg);
- const auto finishType = finishItem.GetStaticType();
- MKQL_ENSURE(finishType->IsList() || finishType->IsStream() || finishType->IsOptional(), "Expected list, stream or optional");
+ const auto finishType = finishItem.GetStaticType();
+ MKQL_ENSURE(finishType->IsList() || finishType->IsStream() || finishType->IsOptional(), "Expected list, stream or optional");
- TType* retItemType = nullptr;
- if (finishType->IsOptional()) {
- retItemType = AS_TYPE(TOptionalType, finishType)->GetItemType();
- } else if (finishType->IsList()) {
- retItemType = AS_TYPE(TListType, finishType)->GetItemType();
- } else if (finishType->IsStream()) {
- retItemType = AS_TYPE(TStreamType, finishType)->GetItemType();
- }
+ TType* retItemType = nullptr;
+ if (finishType->IsOptional()) {
+ retItemType = AS_TYPE(TOptionalType, finishType)->GetItemType();
+ } else if (finishType->IsList()) {
+ retItemType = AS_TYPE(TListType, finishType)->GetItemType();
+ } else if (finishType->IsStream()) {
+ retItemType = AS_TYPE(TStreamType, finishType)->GetItemType();
+ }
+
+ const auto resultStreamType = isStream ? NewStreamType(retItemType) : NewFlowType(retItemType);
+ TCallableBuilder callableBuilder(Env, __func__, resultStreamType);
+ callableBuilder.Add(stream);
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(key);
+ callableBuilder.Add(keyArg);
+ callableBuilder.Add(stateInit);
+ callableBuilder.Add(stateArg);
+ callableBuilder.Add(stateUpdate);
+ callableBuilder.Add(finishItem);
+ callableBuilder.Add(NewDataLiteral(memLimit));
- const auto resultStreamType = isStream ? NewStreamType(retItemType) : NewFlowType(retItemType);
- TCallableBuilder callableBuilder(Env, __func__, resultStreamType);
- callableBuilder.Add(stream);
- callableBuilder.Add(itemArg);
- callableBuilder.Add(key);
- callableBuilder.Add(keyArg);
- callableBuilder.Add(stateInit);
- callableBuilder.Add(stateArg);
- callableBuilder.Add(stateUpdate);
- callableBuilder.Add(finishItem);
- callableBuilder.Add(NewDataLiteral(memLimit));
-
- return TRuntimeNode(callableBuilder.Build(), false);
+ return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::GroupingCore(TRuntimeNode stream,
- const TBinaryLambda& groupSwitch,
+ const TBinaryLambda& groupSwitch,
const TUnaryLambda& keyExtractor,
const TUnaryLambda& handler)
{
@@ -4500,9 +4500,9 @@ TRuntimeNode TProgramBuilder::GroupingCore(TRuntimeNode stream,
}
const std::array<TType*, 2U> tupleItems = {{ keyExtractorResult.GetStaticType(), NewStreamType(itemType) }};
- const auto finishType = NewStreamType(NewTupleType(tupleItems));
+ const auto finishType = NewStreamType(NewTupleType(tupleItems));
- TCallableBuilder callableBuilder(Env, __func__, finishType);
+ TCallableBuilder callableBuilder(Env, __func__, finishType);
callableBuilder.Add(stream);
callableBuilder.Add(keyExtractorResult);
callableBuilder.Add(groupSwitchResult);
@@ -4517,86 +4517,86 @@ TRuntimeNode TProgramBuilder::GroupingCore(TRuntimeNode stream,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Chopper(TRuntimeNode flow, const TUnaryLambda& keyExtractor, const TBinaryLambda& groupSwitch, const TBinaryLambda& groupHandler) {
- const auto flowType = flow.GetStaticType();
- MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
-
-
- if constexpr (RuntimeVersion < 9U) {
- return FlatMap(GroupingCore(flow, groupSwitch, keyExtractor),
- [&](TRuntimeNode item) -> TRuntimeNode { return groupHandler(Nth(item, 0U), Nth(item, 1U)); }
- );
- }
-
- const bool isStream = flowType->IsStream();
- const auto itemType = isStream ? AS_TYPE(TStreamType, flow)->GetItemType() : AS_TYPE(TFlowType, flow)->GetItemType();
-
- const auto itemArg = Arg(itemType);
- const auto keyExtractorResult = keyExtractor(itemArg);
- const auto keyArg = Arg(keyExtractorResult.GetStaticType());
- const auto groupSwitchResult = groupSwitch(keyArg, itemArg);
-
- const auto input = Arg(flowType);
- const auto output = groupHandler(keyArg, input);
-
- TCallableBuilder callableBuilder(Env, __func__, output.GetStaticType());
- callableBuilder.Add(flow);
-
- callableBuilder.Add(itemArg);
- callableBuilder.Add(keyExtractorResult);
- callableBuilder.Add(keyArg);
- callableBuilder.Add(groupSwitchResult);
-
- callableBuilder.Add(input);
- callableBuilder.Add(output);
-
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
-TRuntimeNode TProgramBuilder::WideChopper(TRuntimeNode flow, const TWideLambda& extractor, const TWideSwitchLambda& groupSwitch,
- const std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode)>& groupHandler
-) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
- const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
-
- TRuntimeNode::TList itemArgs, keyArgs;
- itemArgs.reserve(tupleType->GetElementsCount());
-
- auto i = 0U;
- std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
-
- const auto keys = extractor(itemArgs);
-
- keyArgs.reserve(keys.size());
- std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
-
- const auto groupSwitchResult = groupSwitch(keyArgs, itemArgs);
-
- const auto input = WideFlowArg(flow.GetStaticType());
- const auto output = groupHandler(keyArgs, input);
-
- TCallableBuilder callableBuilder(Env, __func__, output.GetStaticType());
- callableBuilder.Add(flow);
- std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
- callableBuilder.Add(groupSwitchResult);
- callableBuilder.Add(input);
- callableBuilder.Add(output);
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
+TRuntimeNode TProgramBuilder::Chopper(TRuntimeNode flow, const TUnaryLambda& keyExtractor, const TBinaryLambda& groupSwitch, const TBinaryLambda& groupHandler) {
+ const auto flowType = flow.GetStaticType();
+ MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
+
+
+ if constexpr (RuntimeVersion < 9U) {
+ return FlatMap(GroupingCore(flow, groupSwitch, keyExtractor),
+ [&](TRuntimeNode item) -> TRuntimeNode { return groupHandler(Nth(item, 0U), Nth(item, 1U)); }
+ );
+ }
+
+ const bool isStream = flowType->IsStream();
+ const auto itemType = isStream ? AS_TYPE(TStreamType, flow)->GetItemType() : AS_TYPE(TFlowType, flow)->GetItemType();
+
+ const auto itemArg = Arg(itemType);
+ const auto keyExtractorResult = keyExtractor(itemArg);
+ const auto keyArg = Arg(keyExtractorResult.GetStaticType());
+ const auto groupSwitchResult = groupSwitch(keyArg, itemArg);
+
+ const auto input = Arg(flowType);
+ const auto output = groupHandler(keyArg, input);
+
+ TCallableBuilder callableBuilder(Env, __func__, output.GetStaticType());
+ callableBuilder.Add(flow);
+
+ callableBuilder.Add(itemArg);
+ callableBuilder.Add(keyExtractorResult);
+ callableBuilder.Add(keyArg);
+ callableBuilder.Add(groupSwitchResult);
+
+ callableBuilder.Add(input);
+ callableBuilder.Add(output);
+
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
+TRuntimeNode TProgramBuilder::WideChopper(TRuntimeNode flow, const TWideLambda& extractor, const TWideSwitchLambda& groupSwitch,
+ const std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode)>& groupHandler
+) {
+ if constexpr (RuntimeVersion < 18U) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+
+ const auto tupleType = AS_TYPE(TTupleType, AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType());
+
+ TRuntimeNode::TList itemArgs, keyArgs;
+ itemArgs.reserve(tupleType->GetElementsCount());
+
+ auto i = 0U;
+ std::generate_n(std::back_inserter(itemArgs), tupleType->GetElementsCount(), [&](){ return Arg(tupleType->GetElementType(i++)); });
+
+ const auto keys = extractor(itemArgs);
+
+ keyArgs.reserve(keys.size());
+ std::transform(keys.cbegin(), keys.cend(), std::back_inserter(keyArgs), [&](TRuntimeNode key){ return Arg(key.GetStaticType()); } );
+
+ const auto groupSwitchResult = groupSwitch(keyArgs, itemArgs);
+
+ const auto input = WideFlowArg(flow.GetStaticType());
+ const auto output = groupHandler(keyArgs, input);
+
+ TCallableBuilder callableBuilder(Env, __func__, output.GetStaticType());
+ callableBuilder.Add(flow);
+ std::for_each(itemArgs.cbegin(), itemArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keys.cbegin(), keys.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ std::for_each(keyArgs.cbegin(), keyArgs.cend(), std::bind(&TCallableBuilder::Add, std::ref(callableBuilder), std::placeholders::_1));
+ callableBuilder.Add(groupSwitchResult);
+ callableBuilder.Add(input);
+ callableBuilder.Add(output);
+ return TRuntimeNode(callableBuilder.Build(), false);
+}
+
TRuntimeNode TProgramBuilder::HoppingCore(TRuntimeNode list,
- const TUnaryLambda& timeExtractor,
- const TUnaryLambda& init,
- const TBinaryLambda& update,
- const TUnaryLambda& save,
- const TUnaryLambda& load,
- const TBinaryLambda& merge,
- const TBinaryLambda& finish,
+ const TUnaryLambda& timeExtractor,
+ const TUnaryLambda& init,
+ const TBinaryLambda& update,
+ const TUnaryLambda& save,
+ const TUnaryLambda& load,
+ const TBinaryLambda& merge,
+ const TBinaryLambda& finish,
TRuntimeNode hop, TRuntimeNode interval, TRuntimeNode delay)
{
auto streamType = AS_TYPE(TStreamType, list);
@@ -4638,7 +4638,7 @@ TRuntimeNode TProgramBuilder::HoppingCore(TRuntimeNode list,
auto resultType = TStreamType::Create(outItemFinish.GetStaticType(), Env);
- TCallableBuilder callableBuilder(Env, __func__, resultType);
+ TCallableBuilder callableBuilder(Env, __func__, resultType);
callableBuilder.Add(list);
callableBuilder.Add(itemArg);
callableBuilder.Add(stateArg);
@@ -4743,69 +4743,69 @@ TRuntimeNode TProgramBuilder::MultiHoppingCore(TRuntimeNode list,
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::Default(TType* type) {
- bool isOptional;
- const auto targetType = UnpackOptionalData(type, isOptional);
- if (isOptional) {
- return NewOptional(Default(targetType));
- }
-
- const auto scheme = targetType->GetSchemeType();
- const auto value = scheme == NUdf::TDataType<NUdf::TUuid>::Id ?
+TRuntimeNode TProgramBuilder::Default(TType* type) {
+ bool isOptional;
+ const auto targetType = UnpackOptionalData(type, isOptional);
+ if (isOptional) {
+ return NewOptional(Default(targetType));
+ }
+
+ const auto scheme = targetType->GetSchemeType();
+ const auto value = scheme == NUdf::TDataType<NUdf::TUuid>::Id ?
Env.NewStringValue("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"sv) :
scheme == NUdf::TDataType<NUdf::TDyNumber>::Id ? NUdf::TUnboxedValuePod::Embedded("\1") : NUdf::TUnboxedValuePod::Zero();
- return TRuntimeNode(TDataLiteral::Create(value, targetType, Env), true);
-}
-
-TRuntimeNode TProgramBuilder::Cast(TRuntimeNode arg, TType* type) {
- if (arg.GetStaticType()->IsSameType(*type)) {
- return arg;
- }
-
- bool isOptional;
- const auto targetType = UnpackOptionalData(type, isOptional);
- const auto sourceType = UnpackOptionalData(arg, isOptional);
-
- const auto sId = sourceType->GetSchemeType();
- const auto tId = targetType->GetSchemeType();
-
- if (sId == NUdf::TDataType<char*>::Id) {
- if (tId != NUdf::TDataType<char*>::Id) {
- return FromString(arg, type);
- } else {
- return arg;
- }
- }
-
- if (sId == NUdf::TDataType<NUdf::TUtf8>::Id) {
- if (tId != NUdf::TDataType<char*>::Id) {
- return FromString(arg, type);
- } else {
- return ToString(arg);
- }
- }
-
- if (tId == NUdf::TDataType<char*>::Id) {
- return ToString(arg);
- }
-
- if (tId == NUdf::TDataType<NUdf::TUtf8>::Id) {
- return ToString<true>(arg);
- }
-
- if (tId == NUdf::TDataType<NUdf::TDecimal>::Id) {
- const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
- return ToDecimal(arg, params.first, params.second);
- }
-
- const auto options = NKikimr::NUdf::GetCastResult(*sourceType->GetDataSlot(), *targetType->GetDataSlot());
- MKQL_ENSURE(!(options && (*options & NKikimr::NUdf::ECastOptions::Impossible)),
- "Impossible to cast " << *static_cast<TType*>(sourceType) << " into " << *static_cast<TType*>(targetType));
-
- const bool useToIntegral = !options || NKikimr::NUdf::ECastOptions::MayFail & *options;
- return useToIntegral ? ToIntegral(arg, type) : Convert(arg, type);
-}
-
+ return TRuntimeNode(TDataLiteral::Create(value, targetType, Env), true);
+}
+
+TRuntimeNode TProgramBuilder::Cast(TRuntimeNode arg, TType* type) {
+ if (arg.GetStaticType()->IsSameType(*type)) {
+ return arg;
+ }
+
+ bool isOptional;
+ const auto targetType = UnpackOptionalData(type, isOptional);
+ const auto sourceType = UnpackOptionalData(arg, isOptional);
+
+ const auto sId = sourceType->GetSchemeType();
+ const auto tId = targetType->GetSchemeType();
+
+ if (sId == NUdf::TDataType<char*>::Id) {
+ if (tId != NUdf::TDataType<char*>::Id) {
+ return FromString(arg, type);
+ } else {
+ return arg;
+ }
+ }
+
+ if (sId == NUdf::TDataType<NUdf::TUtf8>::Id) {
+ if (tId != NUdf::TDataType<char*>::Id) {
+ return FromString(arg, type);
+ } else {
+ return ToString(arg);
+ }
+ }
+
+ if (tId == NUdf::TDataType<char*>::Id) {
+ return ToString(arg);
+ }
+
+ if (tId == NUdf::TDataType<NUdf::TUtf8>::Id) {
+ return ToString<true>(arg);
+ }
+
+ if (tId == NUdf::TDataType<NUdf::TDecimal>::Id) {
+ const auto& params = static_cast<const TDataDecimalType*>(targetType)->GetParams();
+ return ToDecimal(arg, params.first, params.second);
+ }
+
+ const auto options = NKikimr::NUdf::GetCastResult(*sourceType->GetDataSlot(), *targetType->GetDataSlot());
+ MKQL_ENSURE(!(options && (*options & NKikimr::NUdf::ECastOptions::Impossible)),
+ "Impossible to cast " << *static_cast<TType*>(sourceType) << " into " << *static_cast<TType*>(targetType));
+
+ const bool useToIntegral = !options || NKikimr::NUdf::ECastOptions::MayFail & *options;
+ return useToIntegral ? ToIntegral(arg, type) : Convert(arg, type);
+}
+
TRuntimeNode TProgramBuilder::RangeCreate(TRuntimeNode list) {
MKQL_ENSURE(list.GetStaticType()->IsList(), "Expecting list");
auto itemType = static_cast<TListType*>(list.GetStaticType())->GetItemType();
@@ -4964,19 +4964,19 @@ TRuntimeNode TProgramBuilder::NextValue(TRuntimeNode value) {
return TRuntimeNode(callableBuilder.Build(), false);
}
-bool TProgramBuilder::IsNull(TRuntimeNode arg) {
- return arg.GetStaticType()->IsSameType(*NewNull().GetStaticType()); // TODO ->IsNull();
-}
-
-TRuntimeNode TProgramBuilder::Replicate(TRuntimeNode item, TRuntimeNode count, const std::string_view& file, ui32 row, ui32 column) {
+bool TProgramBuilder::IsNull(TRuntimeNode arg) {
+ return arg.GetStaticType()->IsSameType(*NewNull().GetStaticType()); // TODO ->IsNull();
+}
+
+TRuntimeNode TProgramBuilder::Replicate(TRuntimeNode item, TRuntimeNode count, const std::string_view& file, ui32 row, ui32 column) {
MKQL_ENSURE(count.GetStaticType()->IsData(), "Expected data");
MKQL_ENSURE(static_cast<const TDataType&>(*count.GetStaticType()).GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
- const auto listType = TListType::Create(item.GetStaticType(), Env);
+ const auto listType = TListType::Create(item.GetStaticType(), Env);
TCallableBuilder callableBuilder(Env, __func__, listType);
callableBuilder.Add(item);
callableBuilder.Add(count);
- if constexpr (RuntimeVersion >= 2) {
+ if constexpr (RuntimeVersion >= 2) {
callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
callableBuilder.Add(NewDataLiteral(row));
callableBuilder.Add(NewDataLiteral(column));
diff --git a/ydb/library/yql/minikql/mkql_program_builder.h b/ydb/library/yql/minikql/mkql_program_builder.h
index 40c2ebcffe..10f1ad7ccf 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.h
+++ b/ydb/library/yql/minikql/mkql_program_builder.h
@@ -5,7 +5,7 @@
#include "mkql_node_builder.h"
#include <ydb/library/yql/public/udf/udf_value.h>
-#include <functional>
+#include <functional>
namespace NKikimr {
namespace NMiniKQL {
@@ -13,8 +13,8 @@ namespace NMiniKQL {
class IFunctionRegistry;
class TBuiltinFunctionRegistry;
-constexpr std::string_view RandomMTResource = "MTRand";
-constexpr std::string_view ResourceQueuePrefix = "TResourceQueue:";
+constexpr std::string_view RandomMTResource = "MTRand";
+constexpr std::string_view ResourceQueuePrefix = "TResourceQueue:";
enum class EJoinKind {
Min = 1,
@@ -104,44 +104,44 @@ enum class EScriptType {
MKQL_SCRIPT_TYPES(ENUM_VALUE_GEN)
};
-std::string_view ScriptTypeAsStr(EScriptType type);
-EScriptType ScriptTypeFromStr(std::string_view str);
+std::string_view ScriptTypeAsStr(EScriptType type);
+EScriptType ScriptTypeFromStr(std::string_view str);
bool IsCustomPython(EScriptType type);
EScriptType CanonizeScriptType(EScriptType type);
struct TSwitchInput {
- std::vector<ui32> Indicies;
+ std::vector<ui32> Indicies;
TType* InputType = nullptr;
- std::optional<ui32> ResultVariantOffset;
+ std::optional<ui32> ResultVariantOffset;
};
class TProgramBuilder : private TNonCopyable {
public:
- TProgramBuilder(const TTypeEnvironment& env, const IFunctionRegistry& functionRegistry, bool voidWithEffects = false);
+ TProgramBuilder(const TTypeEnvironment& env, const IFunctionRegistry& functionRegistry, bool voidWithEffects = false);
const TTypeEnvironment& GetTypeEnvironment() const;
const IFunctionRegistry& GetFunctionRegistry() const;
TRuntimeNode Arg(TType* type) const;
- TRuntimeNode WideFlowArg(TType* type) const;
+ TRuntimeNode WideFlowArg(TType* type) const;
//-- literal functions
TRuntimeNode NewVoid();
TRuntimeNode NewNull();
- TType* NewDataType(NUdf::TDataTypeId schemeType, bool optional = false);
- TType* NewDataType(NUdf::EDataSlot slot, bool optional = false) {
- return NewDataType(NUdf::GetDataTypeInfo(slot).TypeId, optional);
+ TType* NewDataType(NUdf::TDataTypeId schemeType, bool optional = false);
+ TType* NewDataType(NUdf::EDataSlot slot, bool optional = false) {
+ return NewDataType(NUdf::GetDataTypeInfo(slot).TypeId, optional);
}
- TType* NewDecimalType(ui8 precision, ui8 scale);
-
+ TType* NewDecimalType(ui8 precision, ui8 scale);
+
template <typename T, typename = std::enable_if_t<NUdf::TKnownDataType<T>::Result>>
- TRuntimeNode NewDataLiteral(T data) const {
+ TRuntimeNode NewDataLiteral(T data) const {
return TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod(data), NUdf::TDataType<T>::Id, Env), true);
- }
-
-
+ }
+
+
template <typename T, typename = std::enable_if_t<NUdf::TTzDataType<T>::Result>>
TRuntimeNode NewTzDataLiteral(typename NUdf::TDataType<T>::TLayout value, ui16 tzId) const {
auto data = NUdf::TUnboxedValuePod(value);
@@ -150,10 +150,10 @@ public:
}
template <NUdf::EDataSlot Type>
- TRuntimeNode NewDataLiteral(const NUdf::TStringRef& data) const;
-
- TRuntimeNode NewDecimalLiteral(NYql::NDecimal::TInt128 data, ui8 precision, ui8 scale) const;
-
+ TRuntimeNode NewDataLiteral(const NUdf::TStringRef& data) const;
+
+ TRuntimeNode NewDecimalLiteral(NYql::NDecimal::TInt128 data, ui8 precision, ui8 scale) const;
+
TType* NewOptionalType(TType* itemType);
TRuntimeNode NewEmptyOptional(TType* optionalType);
TRuntimeNode NewEmptyOptionalDataLiteral(NUdf::TDataTypeId schemeType);
@@ -161,12 +161,12 @@ public:
TRuntimeNode NewOptional(TType* optionalType, TRuntimeNode data);
TType* NewEmptyStructType();
- TType* NewStructType(TType* baseStructType, const std::string_view& memberName, TType* memberType);
- TType* NewStructType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes);
- TType* NewArrayType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes);
+ TType* NewStructType(TType* baseStructType, const std::string_view& memberName, TType* memberType);
+ TType* NewStructType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes);
+ TType* NewArrayType(const TArrayRef<const std::pair<std::string_view, TType*>>& memberTypes);
TRuntimeNode NewEmptyStruct();
- TRuntimeNode NewStruct(const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
- TRuntimeNode NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
+ TRuntimeNode NewStruct(const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
+ TRuntimeNode NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
TType* NewListType(TType* itemType);
TRuntimeNode NewEmptyList(TType* itemType);
@@ -177,38 +177,38 @@ public:
TRuntimeNode NewDict(TType* dictType, const TArrayRef<const std::pair<TRuntimeNode, TRuntimeNode>>& items);
TType* NewStreamType(TType* itemType);
- TType* NewFlowType(TType* itemType);
- TType* NewTaggedType(TType* baseType, const std::string_view& tag);
+ TType* NewFlowType(TType* itemType);
+ TType* NewTaggedType(TType* baseType, const std::string_view& tag);
TType* NewBlockType(TType* itemType, TBlockType::EShape shape);
TType* NewEmptyTupleType();
TType* NewTupleType(const TArrayRef<TType* const>& elements);
- TType* NewArrayType(const TArrayRef<TType* const>& elements);
+ TType* NewArrayType(const TArrayRef<TType* const>& elements);
TRuntimeNode NewEmptyTuple();
TRuntimeNode NewTuple(TType* tupleType, const TArrayRef<const TRuntimeNode>& elements);
TRuntimeNode NewTuple(const TArrayRef<const TRuntimeNode>& elements);
- TType* NewResourceType(const std::string_view& tag);
+ TType* NewResourceType(const std::string_view& tag);
TType* NewVariantType(TType* underlyingType);
TRuntimeNode NewVariant(TRuntimeNode item, ui32 tupleIndex, TType* variantType);
- TRuntimeNode NewVariant(TRuntimeNode item, const std::string_view& member, TType* variantType);
+ TRuntimeNode NewVariant(TRuntimeNode item, const std::string_view& member, TType* variantType);
// generic data transformation, some args could be optional
- TRuntimeNode Convert(TRuntimeNode data, TType* type);
- TRuntimeNode ToIntegral(TRuntimeNode data, TType* type);
- TRuntimeNode ToDecimal(TRuntimeNode data, ui8 precision, ui8 scale);
+ TRuntimeNode Convert(TRuntimeNode data, TType* type);
+ TRuntimeNode ToIntegral(TRuntimeNode data, TType* type);
+ TRuntimeNode ToDecimal(TRuntimeNode data, ui8 precision, ui8 scale);
TRuntimeNode Concat(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrConcat(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrConcat(TRuntimeNode data1, TRuntimeNode data2);
TRuntimeNode Substring(TRuntimeNode data, TRuntimeNode start, TRuntimeNode count);
- TRuntimeNode Find(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos);
- TRuntimeNode RFind(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos);
- TRuntimeNode StartsWith(TRuntimeNode string, TRuntimeNode prefix);
- TRuntimeNode EndsWith(TRuntimeNode string, TRuntimeNode suffix);
+ TRuntimeNode Find(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos);
+ TRuntimeNode RFind(TRuntimeNode haystack, TRuntimeNode needle, TRuntimeNode pos);
+ TRuntimeNode StartsWith(TRuntimeNode string, TRuntimeNode prefix);
+ TRuntimeNode EndsWith(TRuntimeNode string, TRuntimeNode suffix);
TRuntimeNode ByteAt(TRuntimeNode data, TRuntimeNode index);
TRuntimeNode Size(TRuntimeNode data);
- template <bool Utf8 = false>
+ template <bool Utf8 = false>
TRuntimeNode ToString(TRuntimeNode data);
- TRuntimeNode FromString(TRuntimeNode data, TType* type);
- TRuntimeNode StrictFromString(TRuntimeNode data, TType* type);
+ TRuntimeNode FromString(TRuntimeNode data, TType* type);
+ TRuntimeNode StrictFromString(TRuntimeNode data, TType* type);
TRuntimeNode ToBytes(TRuntimeNode data);
TRuntimeNode FromBytes(TRuntimeNode data, NUdf::TDataTypeId schemeType);
TRuntimeNode InversePresortString(TRuntimeNode data);
@@ -216,22 +216,22 @@ public:
TRuntimeNode Random(const TArrayRef<const TRuntimeNode>& dependentNodes);
TRuntimeNode RandomNumber(const TArrayRef<const TRuntimeNode>& dependentNodes);
TRuntimeNode RandomUuid(const TArrayRef<const TRuntimeNode>& dependentNodes);
-
+
TRuntimeNode Now(const TArrayRef<const TRuntimeNode>& dependentNodes);
- TRuntimeNode CurrentUtcDate(const TArrayRef<const TRuntimeNode>& dependentNodes);
- TRuntimeNode CurrentUtcDatetime(const TArrayRef<const TRuntimeNode>& dependentNodes);
- TRuntimeNode CurrentUtcTimestamp(const TArrayRef<const TRuntimeNode>& dependentNodes);
-
+ TRuntimeNode CurrentUtcDate(const TArrayRef<const TRuntimeNode>& dependentNodes);
+ TRuntimeNode CurrentUtcDatetime(const TArrayRef<const TRuntimeNode>& dependentNodes);
+ TRuntimeNode CurrentUtcTimestamp(const TArrayRef<const TRuntimeNode>& dependentNodes);
+
TRuntimeNode Pickle(TRuntimeNode data);
TRuntimeNode StablePickle(TRuntimeNode data);
TRuntimeNode Unpickle(TType* type, TRuntimeNode serialized);
TRuntimeNode Ascending(TRuntimeNode data);
TRuntimeNode Descending(TRuntimeNode data);
- TRuntimeNode ToFlow(TRuntimeNode stream);
- TRuntimeNode FromFlow(TRuntimeNode flow);
+ TRuntimeNode ToFlow(TRuntimeNode stream);
+ TRuntimeNode FromFlow(TRuntimeNode flow);
TRuntimeNode Steal(TRuntimeNode input);
-
+
TRuntimeNode ToBlocks(TRuntimeNode flow);
TRuntimeNode WideToBlocks(TRuntimeNode flow);
TRuntimeNode FromBlocks(TRuntimeNode flow);
@@ -241,54 +241,54 @@ public:
// udfs
TRuntimeNode Udf(
- const std::string_view& funcName,
+ const std::string_view& funcName,
TRuntimeNode runConfig = TRuntimeNode(),
TType* userType = nullptr,
- const std::string_view& typeConfig = std::string_view(""));
+ const std::string_view& typeConfig = std::string_view(""));
TRuntimeNode TypedUdf(
- const std::string_view& funcName,
+ const std::string_view& funcName,
TType* funcType,
TRuntimeNode runConfig = TRuntimeNode(),
TType* userType = nullptr,
- const std::string_view& typeConfig = std::string_view(""),
- const std::string_view& file = std::string_view(""), ui32 row = 0, ui32 column = 0);
+ const std::string_view& typeConfig = std::string_view(""),
+ const std::string_view& file = std::string_view(""), ui32 row = 0, ui32 column = 0);
TRuntimeNode ScriptUdf(
EScriptType scriptType,
- const std::string_view& funcName,
+ const std::string_view& funcName,
TType* funcType,
TRuntimeNode script,
- const std::string_view& file = std::string_view(""), ui32 row = 0, ui32 column = 0);
+ const std::string_view& file = std::string_view(""), ui32 row = 0, ui32 column = 0);
typedef std::function<TRuntimeNode ()> TZeroLambda;
- typedef std::function<TRuntimeNode (TRuntimeNode)> TUnaryLambda;
- typedef std::function<TRuntimeNode (TRuntimeNode, TRuntimeNode)> TBinaryLambda;
- typedef std::function<TRuntimeNode (TRuntimeNode, TRuntimeNode, TRuntimeNode)> TTernaryLambda;
- typedef std::function<TRuntimeNode(const TArrayRef<const TRuntimeNode>& args)> TArrayLambda;
-
- typedef std::function<TRuntimeNodePair (TRuntimeNode)> TUnarySplitLambda;
- typedef std::function<TRuntimeNodePair (TRuntimeNode, TRuntimeNode)> TBinarySplitLambda;
-
- typedef std::function<TRuntimeNode::TList (TRuntimeNode)> TExpandLambda;
- typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList)> TWideLambda;
- typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList, TRuntimeNode::TList)> TBinaryWideLambda;
- typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList)> TTernaryWideLambda;
- typedef std::function<TRuntimeNode (TRuntimeNode::TList)> TNarrowLambda;
-
- typedef std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode::TList)> TWideSwitchLambda;
-
- TRuntimeNode Apply(TRuntimeNode callableNode, const TArrayRef<const TRuntimeNode>& args, ui32 dependentCount = 0);
+ typedef std::function<TRuntimeNode (TRuntimeNode)> TUnaryLambda;
+ typedef std::function<TRuntimeNode (TRuntimeNode, TRuntimeNode)> TBinaryLambda;
+ typedef std::function<TRuntimeNode (TRuntimeNode, TRuntimeNode, TRuntimeNode)> TTernaryLambda;
+ typedef std::function<TRuntimeNode(const TArrayRef<const TRuntimeNode>& args)> TArrayLambda;
+
+ typedef std::function<TRuntimeNodePair (TRuntimeNode)> TUnarySplitLambda;
+ typedef std::function<TRuntimeNodePair (TRuntimeNode, TRuntimeNode)> TBinarySplitLambda;
+
+ typedef std::function<TRuntimeNode::TList (TRuntimeNode)> TExpandLambda;
+ typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList)> TWideLambda;
+ typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList, TRuntimeNode::TList)> TBinaryWideLambda;
+ typedef std::function<TRuntimeNode::TList (TRuntimeNode::TList, TRuntimeNode::TList, TRuntimeNode::TList)> TTernaryWideLambda;
+ typedef std::function<TRuntimeNode (TRuntimeNode::TList)> TNarrowLambda;
+
+ typedef std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode::TList)> TWideSwitchLambda;
+
+ TRuntimeNode Apply(TRuntimeNode callableNode, const TArrayRef<const TRuntimeNode>& args, ui32 dependentCount = 0);
TRuntimeNode Apply(TRuntimeNode callableNode, const TArrayRef<const TRuntimeNode>& args,
- const std::string_view& file, ui32 row, ui32 column, ui32 dependentCount = 0);
- TRuntimeNode Callable(TType* callableType, const TArrayLambda& handler);
+ const std::string_view& file, ui32 row, ui32 column, ui32 dependentCount = 0);
+ TRuntimeNode Callable(TType* callableType, const TArrayLambda& handler);
//-- struct functions
- TRuntimeNode Member(TRuntimeNode structObj, const std::string_view& memberName);
- TRuntimeNode Element(TRuntimeNode tuple, const std::string_view& memberName);
- TRuntimeNode AddMember(TRuntimeNode structObj, const std::string_view& memberName, TRuntimeNode memberValue);
- TRuntimeNode RemoveMember(TRuntimeNode structObj, const std::string_view& memberName, bool forced);
- TRuntimeNode RemoveMembers(TRuntimeNode structObj, const TArrayRef<const std::string_view>& members, bool forced);
+ TRuntimeNode Member(TRuntimeNode structObj, const std::string_view& memberName);
+ TRuntimeNode Element(TRuntimeNode tuple, const std::string_view& memberName);
+ TRuntimeNode AddMember(TRuntimeNode structObj, const std::string_view& memberName, TRuntimeNode memberValue);
+ TRuntimeNode RemoveMember(TRuntimeNode structObj, const std::string_view& memberName, bool forced);
+ TRuntimeNode RemoveMembers(TRuntimeNode structObj, const TArrayRef<const std::string_view>& members, bool forced);
//-- list functions
TRuntimeNode Append(TRuntimeNode list, TRuntimeNode item);
@@ -301,82 +301,82 @@ public:
TRuntimeNode ZipAll(const TArrayRef<const TRuntimeNode>& lists);
TRuntimeNode Enumerate(TRuntimeNode list);
TRuntimeNode Enumerate(TRuntimeNode list, TRuntimeNode start, TRuntimeNode step);
- TRuntimeNode Fold(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler);
- TRuntimeNode Fold1(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler);
+ TRuntimeNode Fold(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler);
+ TRuntimeNode Fold1(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler);
TRuntimeNode Reduce(TRuntimeNode list, TRuntimeNode state1,
- const TBinaryLambda& handler1,
- const TUnaryLambda& handler2,
+ const TBinaryLambda& handler1,
+ const TUnaryLambda& handler2,
TRuntimeNode state3,
- const TBinaryLambda& handler3);
- TRuntimeNode Condense(TRuntimeNode stream, TRuntimeNode state,
- const TBinaryLambda& switcher,
- const TBinaryLambda& handler);
- TRuntimeNode Condense1(TRuntimeNode stream, const TUnaryLambda& init,
- const TBinaryLambda& switcher,
- const TBinaryLambda& handler);
+ const TBinaryLambda& handler3);
+ TRuntimeNode Condense(TRuntimeNode stream, TRuntimeNode state,
+ const TBinaryLambda& switcher,
+ const TBinaryLambda& handler);
+ TRuntimeNode Condense1(TRuntimeNode stream, const TUnaryLambda& init,
+ const TBinaryLambda& switcher,
+ const TBinaryLambda& handler);
TRuntimeNode Squeeze(TRuntimeNode stream, TRuntimeNode state,
- const TBinaryLambda& handler,
- const TUnaryLambda& save = {},
- const TUnaryLambda& load = {});
- TRuntimeNode Squeeze1(TRuntimeNode stream, const TUnaryLambda& init,
- const TBinaryLambda& handler,
- const TUnaryLambda& save = {},
- const TUnaryLambda& load = {});
+ const TBinaryLambda& handler,
+ const TUnaryLambda& save = {},
+ const TUnaryLambda& load = {});
+ TRuntimeNode Squeeze1(TRuntimeNode stream, const TUnaryLambda& init,
+ const TBinaryLambda& handler,
+ const TUnaryLambda& save = {},
+ const TUnaryLambda& load = {});
TRuntimeNode Discard(TRuntimeNode stream);
- TRuntimeNode Map(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode OrderedMap(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode Extract(TRuntimeNode list, const std::string_view& name);
- TRuntimeNode OrderedExtract(TRuntimeNode list, const std::string_view& name);
- TRuntimeNode ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler);
- TRuntimeNode ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinarySplitLambda& handler);
- TRuntimeNode Chain1Map(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler);
- TRuntimeNode Chain1Map(TRuntimeNode list, const TUnarySplitLambda& init, const TBinarySplitLambda& handler);
- TRuntimeNode FlatMap(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode OrderedFlatMap(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode MultiMap(TRuntimeNode list, const TExpandLambda& handler);
- TRuntimeNode Filter(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode Filter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler);
- TRuntimeNode OrderedFilter(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode OrderedFilter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler);
- TRuntimeNode TakeWhile(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode SkipWhile(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode TakeWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode SkipWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler);
-
- TRuntimeNode FilterNullMembers(TRuntimeNode list);
- TRuntimeNode SkipNullMembers(TRuntimeNode list);
- TRuntimeNode FilterNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members);
- TRuntimeNode SkipNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members);
-
- TRuntimeNode FilterNullElements(TRuntimeNode list);
- TRuntimeNode SkipNullElements(TRuntimeNode list);
- TRuntimeNode FilterNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements);
- TRuntimeNode SkipNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements);
-
- TRuntimeNode ExpandMap(TRuntimeNode flow, const TExpandLambda& handler);
- TRuntimeNode WideMap(TRuntimeNode flow, const TWideLambda& handler);
- TRuntimeNode NarrowMap(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode NarrowFlatMap(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode NarrowMultiMap(TRuntimeNode flow, const TWideLambda& handler);
-
- TRuntimeNode WideChain1Map(TRuntimeNode flow, const TWideLambda& init, const TBinaryWideLambda& update);
-
- TRuntimeNode WideFilter(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode WideFilter(TRuntimeNode flow, TRuntimeNode limit, const TNarrowLambda& handler);
- TRuntimeNode WideTakeWhile(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode WideSkipWhile(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode WideTakeWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler);
- TRuntimeNode WideSkipWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler);
-
- TRuntimeNode WideCombiner(TRuntimeNode flow, ui64 memLimit, const TWideLambda& keyExtractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish);
- TRuntimeNode WideLastCombiner(TRuntimeNode flow, const TWideLambda& keyExtractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish);
- TRuntimeNode WideCondense1(TRuntimeNode stream, const TWideLambda& init, const TWideSwitchLambda& switcher, const TBinaryWideLambda& handler);
-
+ TRuntimeNode Map(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode OrderedMap(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode Extract(TRuntimeNode list, const std::string_view& name);
+ TRuntimeNode OrderedExtract(TRuntimeNode list, const std::string_view& name);
+ TRuntimeNode ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinaryLambda& handler);
+ TRuntimeNode ChainMap(TRuntimeNode list, TRuntimeNode state, const TBinarySplitLambda& handler);
+ TRuntimeNode Chain1Map(TRuntimeNode list, const TUnaryLambda& init, const TBinaryLambda& handler);
+ TRuntimeNode Chain1Map(TRuntimeNode list, const TUnarySplitLambda& init, const TBinarySplitLambda& handler);
+ TRuntimeNode FlatMap(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode OrderedFlatMap(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode MultiMap(TRuntimeNode list, const TExpandLambda& handler);
+ TRuntimeNode Filter(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode Filter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler);
+ TRuntimeNode OrderedFilter(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode OrderedFilter(TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler);
+ TRuntimeNode TakeWhile(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode SkipWhile(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode TakeWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode SkipWhileInclusive(TRuntimeNode list, const TUnaryLambda& handler);
+
+ TRuntimeNode FilterNullMembers(TRuntimeNode list);
+ TRuntimeNode SkipNullMembers(TRuntimeNode list);
+ TRuntimeNode FilterNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members);
+ TRuntimeNode SkipNullMembers(TRuntimeNode list, const TArrayRef<const std::string_view>& members);
+
+ TRuntimeNode FilterNullElements(TRuntimeNode list);
+ TRuntimeNode SkipNullElements(TRuntimeNode list);
+ TRuntimeNode FilterNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements);
+ TRuntimeNode SkipNullElements(TRuntimeNode list, const TArrayRef<const ui32>& elements);
+
+ TRuntimeNode ExpandMap(TRuntimeNode flow, const TExpandLambda& handler);
+ TRuntimeNode WideMap(TRuntimeNode flow, const TWideLambda& handler);
+ TRuntimeNode NarrowMap(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode NarrowFlatMap(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode NarrowMultiMap(TRuntimeNode flow, const TWideLambda& handler);
+
+ TRuntimeNode WideChain1Map(TRuntimeNode flow, const TWideLambda& init, const TBinaryWideLambda& update);
+
+ TRuntimeNode WideFilter(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode WideFilter(TRuntimeNode flow, TRuntimeNode limit, const TNarrowLambda& handler);
+ TRuntimeNode WideTakeWhile(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode WideSkipWhile(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode WideTakeWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler);
+ TRuntimeNode WideSkipWhileInclusive(TRuntimeNode flow, const TNarrowLambda& handler);
+
+ TRuntimeNode WideCombiner(TRuntimeNode flow, ui64 memLimit, const TWideLambda& keyExtractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish);
+ TRuntimeNode WideLastCombiner(TRuntimeNode flow, const TWideLambda& keyExtractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish);
+ TRuntimeNode WideCondense1(TRuntimeNode stream, const TWideLambda& init, const TWideSwitchLambda& switcher, const TBinaryWideLambda& handler);
+
TRuntimeNode Length(TRuntimeNode listOrDict);
TRuntimeNode Iterator(TRuntimeNode list, const TArrayRef<const TRuntimeNode>& dependentNodes);
TRuntimeNode EmptyIterator(TType* streamType);
TRuntimeNode Collect(TRuntimeNode listOrStream);
- TRuntimeNode LazyList(TRuntimeNode list);
+ TRuntimeNode LazyList(TRuntimeNode list);
TRuntimeNode ListFromRange(TRuntimeNode start, TRuntimeNode end, TRuntimeNode step);
TRuntimeNode ForwardList(TRuntimeNode stream);
TRuntimeNode Switch(TRuntimeNode stream,
@@ -387,43 +387,43 @@ public:
TRuntimeNode Reverse(TRuntimeNode list);
TRuntimeNode Skip(TRuntimeNode list, TRuntimeNode count);
TRuntimeNode Take(TRuntimeNode list, TRuntimeNode count);
- TRuntimeNode Replicate(TRuntimeNode item, TRuntimeNode count, const std::string_view& file, ui32 row, ui32 column);
- TRuntimeNode Sort(TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode Top(TRuntimeNode list, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode TopSort(TRuntimeNode list, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode KeepTop(TRuntimeNode count, TRuntimeNode list, TRuntimeNode item, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
-
+ TRuntimeNode Replicate(TRuntimeNode item, TRuntimeNode count, const std::string_view& file, ui32 row, ui32 column);
+ TRuntimeNode Sort(TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode Top(TRuntimeNode list, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode TopSort(TRuntimeNode list, TRuntimeNode count, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode KeepTop(TRuntimeNode count, TRuntimeNode list, TRuntimeNode item, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+
TRuntimeNode ListIf(TRuntimeNode predicate, TRuntimeNode item);
-
+
TRuntimeNode AsList(TRuntimeNode item);
TRuntimeNode AsList(const TArrayRef<const TRuntimeNode>& items);
- TRuntimeNode MapJoinCore(TRuntimeNode flow, TRuntimeNode dict, EJoinKind joinKind,
- const TArrayRef<const ui32>& leftKeyColumns, const TArrayRef<const ui32>& leftRenames,
- const TArrayRef<const ui32>& rightRenames, TType* returnType);
+ TRuntimeNode MapJoinCore(TRuntimeNode flow, TRuntimeNode dict, EJoinKind joinKind,
+ const TArrayRef<const ui32>& leftKeyColumns, const TArrayRef<const ui32>& leftRenames,
+ const TArrayRef<const ui32>& rightRenames, TType* returnType);
TRuntimeNode CommonJoinCore(TRuntimeNode list, EJoinKind joinKind,
- const TArrayRef<const ui32>& leftColumns, const TArrayRef<const ui32>& rightColumns,
- const TArrayRef<const ui32>& requiredColumns, const TArrayRef<const ui32>& keyColumns,
- ui64 memLimit, std::optional<ui32> sortedTableOrder,
- EAnyJoinSettings anyJoinSettings, const ui32 tableIndexField,
- TType* returnType);
+ const TArrayRef<const ui32>& leftColumns, const TArrayRef<const ui32>& rightColumns,
+ const TArrayRef<const ui32>& requiredColumns, const TArrayRef<const ui32>& keyColumns,
+ ui64 memLimit, std::optional<ui32> sortedTableOrder,
+ EAnyJoinSettings anyJoinSettings, const ui32 tableIndexField,
+ TType* returnType);
TRuntimeNode CombineCore(TRuntimeNode stream,
- const TUnaryLambda& keyExtractor,
- const TBinaryLambda& init,
- const TTernaryLambda& update,
- const TBinaryLambda& finish,
+ const TUnaryLambda& keyExtractor,
+ const TBinaryLambda& init,
+ const TTernaryLambda& update,
+ const TBinaryLambda& finish,
ui64 memLimit);
TRuntimeNode GroupingCore(TRuntimeNode stream,
- const TBinaryLambda& groupSwitch,
+ const TBinaryLambda& groupSwitch,
const TUnaryLambda& keyExtractor,
const TUnaryLambda& handler = {});
TRuntimeNode HoppingCore(TRuntimeNode list,
- const TUnaryLambda& timeExtractor,
- const TUnaryLambda& init,
- const TBinaryLambda& update,
- const TUnaryLambda& save,
- const TUnaryLambda& load,
- const TBinaryLambda& merge,
- const TBinaryLambda& finish,
+ const TUnaryLambda& timeExtractor,
+ const TUnaryLambda& init,
+ const TBinaryLambda& update,
+ const TUnaryLambda& save,
+ const TUnaryLambda& load,
+ const TBinaryLambda& merge,
+ const TBinaryLambda& finish,
TRuntimeNode hop, TRuntimeNode interval, TRuntimeNode delay);
TRuntimeNode MultiHoppingCore(TRuntimeNode list,
const TUnaryLambda& keyExtractor,
@@ -436,66 +436,66 @@ public:
const TTernaryLambda& finish,
TRuntimeNode hop, TRuntimeNode interval, TRuntimeNode delay, TRuntimeNode dataWatermarks);
- TRuntimeNode Chopper(TRuntimeNode flow, const TUnaryLambda& keyExtractor, const TBinaryLambda& groupSwitch, const TBinaryLambda& groupHandler);
-
- TRuntimeNode WideChopper(TRuntimeNode flow, const TWideLambda& keyExtractor, const TWideSwitchLambda& groupSwitch,
- const std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode)>& groupHandler
- );
-
+ TRuntimeNode Chopper(TRuntimeNode flow, const TUnaryLambda& keyExtractor, const TBinaryLambda& groupSwitch, const TBinaryLambda& groupHandler);
+
+ TRuntimeNode WideChopper(TRuntimeNode flow, const TWideLambda& keyExtractor, const TWideSwitchLambda& groupSwitch,
+ const std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode)>& groupHandler
+ );
+
//-- dict functions
TRuntimeNode Contains(TRuntimeNode dict, TRuntimeNode key);
TRuntimeNode Lookup(TRuntimeNode dict, TRuntimeNode key);
// all - keep all payloads in list or keep first payload only
- TRuntimeNode ToSortedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
- TRuntimeNode ToHashedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
+ TRuntimeNode ToSortedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
+ const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
+ TRuntimeNode ToHashedDict(TRuntimeNode list, bool all, const TUnaryLambda& keySelector,
+ const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
TRuntimeNode SqueezeToSortedDict(TRuntimeNode stream, bool all, const TUnaryLambda& keySelector,
const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
TRuntimeNode SqueezeToHashedDict(TRuntimeNode stream, bool all, const TUnaryLambda& keySelector,
const TUnaryLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
- TRuntimeNode NarrowSqueezeToSortedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
- TRuntimeNode NarrowSqueezeToHashedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
- TRuntimeNode SqueezeToList(TRuntimeNode flow, TRuntimeNode sizeHint);
-
+ TRuntimeNode NarrowSqueezeToSortedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
+ TRuntimeNode NarrowSqueezeToHashedDict(TRuntimeNode stream, bool all, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, bool isCompact = false, ui64 itemsCountHint = 0);
+ TRuntimeNode SqueezeToList(TRuntimeNode flow, TRuntimeNode sizeHint);
+
// return list of 2-item tuples with key and payload
- TRuntimeNode DictItems(TRuntimeNode dict);
- TRuntimeNode DictKeys(TRuntimeNode dict);
- TRuntimeNode DictPayloads(TRuntimeNode dict);
-
+ TRuntimeNode DictItems(TRuntimeNode dict);
+ TRuntimeNode DictKeys(TRuntimeNode dict);
+ TRuntimeNode DictPayloads(TRuntimeNode dict);
+
TRuntimeNode ToIndexDict(TRuntimeNode list); // make a dict ui64->item
// build a list from tuple of payloads or just a list if semijoin kind is used
TRuntimeNode JoinDict(TRuntimeNode dict1, bool isMulti1, TRuntimeNode dict2, bool isMulti2, EJoinKind joinKind);
//-- branching functions
TRuntimeNode Coalesce(TRuntimeNode data, TRuntimeNode defaultData);
- TRuntimeNode Unwrap(TRuntimeNode optional, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column);
+ TRuntimeNode Unwrap(TRuntimeNode optional, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column);
TRuntimeNode Exists(TRuntimeNode data);
- TRuntimeNode If(const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode If(const TArrayRef<const TRuntimeNode>& args);
TRuntimeNode If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch);
- TRuntimeNode IfPresent(TRuntimeNode::TList optional, const TNarrowLambda& thenBranch, TRuntimeNode elseBranch);
+ TRuntimeNode IfPresent(TRuntimeNode::TList optional, const TNarrowLambda& thenBranch, TRuntimeNode elseBranch);
TRuntimeNode ToList(TRuntimeNode optional);
TRuntimeNode Iterable(TZeroLambda lambda);
TRuntimeNode ToOptional(TRuntimeNode list);
- TRuntimeNode Head(TRuntimeNode list);
- TRuntimeNode Last(TRuntimeNode list);
+ TRuntimeNode Head(TRuntimeNode list);
+ TRuntimeNode Last(TRuntimeNode list);
TRuntimeNode Nanvl(TRuntimeNode data, TRuntimeNode dataIfNaN);
- TRuntimeNode Ensure(TRuntimeNode value, TRuntimeNode predicate, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column);
-
- TRuntimeNode SourceOf(TType* returnType);
- TRuntimeNode Source();
-
- TRuntimeNode MakeHeap(TRuntimeNode list, const TBinaryLambda& comparator);
- TRuntimeNode PushHeap(TRuntimeNode list, const TBinaryLambda& comparator);
- TRuntimeNode PopHeap(TRuntimeNode list, const TBinaryLambda& comparator);
- TRuntimeNode SortHeap(TRuntimeNode list, const TBinaryLambda& comparator);
- TRuntimeNode StableSort(TRuntimeNode list, const TBinaryLambda& comparator);
-
- TRuntimeNode NthElement(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
- TRuntimeNode PartialSort(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
-
+ TRuntimeNode Ensure(TRuntimeNode value, TRuntimeNode predicate, TRuntimeNode message, const std::string_view& file, ui32 row, ui32 column);
+
+ TRuntimeNode SourceOf(TType* returnType);
+ TRuntimeNode Source();
+
+ TRuntimeNode MakeHeap(TRuntimeNode list, const TBinaryLambda& comparator);
+ TRuntimeNode PushHeap(TRuntimeNode list, const TBinaryLambda& comparator);
+ TRuntimeNode PopHeap(TRuntimeNode list, const TBinaryLambda& comparator);
+ TRuntimeNode SortHeap(TRuntimeNode list, const TBinaryLambda& comparator);
+ TRuntimeNode StableSort(TRuntimeNode list, const TBinaryLambda& comparator);
+
+ TRuntimeNode NthElement(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
+ TRuntimeNode PartialSort(TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
+
//-- arithmetic functions
TRuntimeNode Increment(TRuntimeNode data);
TRuntimeNode Decrement(TRuntimeNode data);
@@ -508,17 +508,17 @@ public:
TRuntimeNode Mul(TRuntimeNode data1, TRuntimeNode data2);
TRuntimeNode Div(TRuntimeNode data1, TRuntimeNode data2);
TRuntimeNode Mod(TRuntimeNode data1, TRuntimeNode data2);
-
- TRuntimeNode Min(const TArrayRef<const TRuntimeNode>& args);
- TRuntimeNode Max(const TArrayRef<const TRuntimeNode>& args);
-
+
+ TRuntimeNode Min(const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode Max(const TArrayRef<const TRuntimeNode>& args);
+
TRuntimeNode Min(TRuntimeNode data1, TRuntimeNode data2);
TRuntimeNode Max(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode DecimalDiv(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode DecimalMod(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode DecimalMul(TRuntimeNode data1, TRuntimeNode data2);
-
+ TRuntimeNode DecimalDiv(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode DecimalMod(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode DecimalMul(TRuntimeNode data1, TRuntimeNode data2);
+
//-- bit logical functions
TRuntimeNode BitNot(TRuntimeNode data);
TRuntimeNode CountBits(TRuntimeNode data);
@@ -533,35 +533,35 @@ public:
TRuntimeNode RotRight(TRuntimeNode arg, TRuntimeNode bits);
// -- sql comparison functions - empty optional looks like an unknown value
- TRuntimeNode Equals(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode NotEquals(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode Less(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode LessOrEqual(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode Greater(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode GreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2);
-
- // -- aggr comparison functions
- TRuntimeNode AggrEquals(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrNotEquals(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrLess(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrLessOrEqual(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrGreater(TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrGreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2);
-
+ TRuntimeNode Equals(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode NotEquals(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode Less(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode LessOrEqual(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode Greater(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode GreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2);
+
+ // -- aggr comparison functions
+ TRuntimeNode AggrEquals(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrNotEquals(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrLess(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrLessOrEqual(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrGreater(TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrGreaterOrEqual(TRuntimeNode data1, TRuntimeNode data2);
+
//-- logical functions
TRuntimeNode Not(TRuntimeNode data);
- TRuntimeNode And(const TArrayRef<const TRuntimeNode>& args);
- TRuntimeNode Or(const TArrayRef<const TRuntimeNode>& args);
- TRuntimeNode Xor(const TArrayRef<const TRuntimeNode>& args);
-
+ TRuntimeNode And(const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode Or(const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode Xor(const TArrayRef<const TRuntimeNode>& args);
+
//-- tuple functions
TRuntimeNode Nth(TRuntimeNode tuple, ui32 index);
- TRuntimeNode Element(TRuntimeNode tuple, ui32 index);
+ TRuntimeNode Element(TRuntimeNode tuple, ui32 index);
//-- variant functions
TRuntimeNode Guess(TRuntimeNode variant, ui32 tupleIndex);
- TRuntimeNode Guess(TRuntimeNode variant, const std::string_view& memberName);
+ TRuntimeNode Guess(TRuntimeNode variant, const std::string_view& memberName);
TRuntimeNode VisitAll(TRuntimeNode variant, std::function<TRuntimeNode(ui32, TRuntimeNode)> handler);
TRuntimeNode Way(TRuntimeNode variant);
TRuntimeNode VariantItem(TRuntimeNode variant);
@@ -585,25 +585,25 @@ public:
TRuntimeNode QueuePop(TRuntimeNode resource);
TRuntimeNode QueuePeek(TRuntimeNode resource, TRuntimeNode index, const TArrayRef<const TRuntimeNode>& dependentNodes, TType* returnType);
TRuntimeNode QueueRange(TRuntimeNode resource, TRuntimeNode begin, TRuntimeNode end, const TArrayRef<const TRuntimeNode>& dependentNodes, TType* returnType);
-
+
TRuntimeNode PreserveStream(TRuntimeNode stream, TRuntimeNode preserve, TRuntimeNode outpace);
TRuntimeNode Seq(const TArrayRef<const TRuntimeNode>& items, TType* returnType);
TRuntimeNode FromYsonSimpleType(TRuntimeNode input, NUdf::TDataTypeId schemeType);
- TRuntimeNode TryWeakMemberFromDict(TRuntimeNode other, TRuntimeNode rest, NUdf::TDataTypeId schemeType, const std::string_view& memberName);
+ TRuntimeNode TryWeakMemberFromDict(TRuntimeNode other, TRuntimeNode rest, NUdf::TDataTypeId schemeType, const std::string_view& memberName);
TRuntimeNode TimezoneId(TRuntimeNode name);
TRuntimeNode TimezoneName(TRuntimeNode id);
TRuntimeNode AddTimezone(TRuntimeNode utc, TRuntimeNode id);
TRuntimeNode RemoveTimezone(TRuntimeNode local);
-
- TRuntimeNode AllOf(TRuntimeNode list, const TUnaryLambda& predicate);
- TRuntimeNode NotAllOf(TRuntimeNode list, const TUnaryLambda& predicate);
-
- TRuntimeNode Cast(TRuntimeNode data, TType* type);
- TRuntimeNode Default(TType* type);
-
+
+ TRuntimeNode AllOf(TRuntimeNode list, const TUnaryLambda& predicate);
+ TRuntimeNode NotAllOf(TRuntimeNode list, const TUnaryLambda& predicate);
+
+ TRuntimeNode Cast(TRuntimeNode data, TType* type);
+ TRuntimeNode Default(TType* type);
+
TRuntimeNode RangeCreate(TRuntimeNode list);
TRuntimeNode RangeUnion(const TArrayRef<const TRuntimeNode>& lists);
TRuntimeNode RangeIntersect(const TArrayRef<const TRuntimeNode>& lists);
@@ -614,125 +614,125 @@ public:
TRuntimeNode NextValue(TRuntimeNode value);
- typedef TRuntimeNode (TProgramBuilder::*UnaryFunctionMethod)(TRuntimeNode);
- typedef TRuntimeNode (TProgramBuilder::*BinaryFunctionMethod)(TRuntimeNode, TRuntimeNode);
- typedef TRuntimeNode (TProgramBuilder::*TernaryFunctionMethod)(TRuntimeNode, TRuntimeNode, TRuntimeNode);
- typedef TRuntimeNode (TProgramBuilder::*ArrayFunctionMethod)(const TArrayRef<const TRuntimeNode>&);
- typedef TRuntimeNode (TProgramBuilder::*ProcessFunctionMethod)(TRuntimeNode, const TUnaryLambda&);
- typedef TRuntimeNode (TProgramBuilder::*NarrowFunctionMethod)(TRuntimeNode, const TNarrowLambda&);
-
+ typedef TRuntimeNode (TProgramBuilder::*UnaryFunctionMethod)(TRuntimeNode);
+ typedef TRuntimeNode (TProgramBuilder::*BinaryFunctionMethod)(TRuntimeNode, TRuntimeNode);
+ typedef TRuntimeNode (TProgramBuilder::*TernaryFunctionMethod)(TRuntimeNode, TRuntimeNode, TRuntimeNode);
+ typedef TRuntimeNode (TProgramBuilder::*ArrayFunctionMethod)(const TArrayRef<const TRuntimeNode>&);
+ typedef TRuntimeNode (TProgramBuilder::*ProcessFunctionMethod)(TRuntimeNode, const TUnaryLambda&);
+ typedef TRuntimeNode (TProgramBuilder::*NarrowFunctionMethod)(TRuntimeNode, const TNarrowLambda&);
+
protected:
- TRuntimeNode Invoke(const std::string_view& funcName, TType* resultType, const TArrayRef<const TRuntimeNode>& args);
- TRuntimeNode IfPresent(TRuntimeNode optional, const TUnaryLambda& thenBranch, TRuntimeNode elseBranch);
-
+ TRuntimeNode Invoke(const std::string_view& funcName, TType* resultType, const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode IfPresent(TRuntimeNode optional, const TUnaryLambda& thenBranch, TRuntimeNode elseBranch);
+
void ThrowIfListOfVoid(TType* type);
- template <typename ResultType>
- TRuntimeNode BuildContainerProperty(const std::string_view& callableName, TRuntimeNode listOrDict);
- TRuntimeNode Filter(TRuntimeNode list, const TUnaryLambda& handler, TType* resultType);
- template <bool Ordered>
- TRuntimeNode BuildExtract(TRuntimeNode list, const std::string_view& name);
-
- TRuntimeNode BuildMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode BuildFlatMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler);
- TRuntimeNode BuildFilter(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler, TType* resultType = nullptr);
- TRuntimeNode BuildFilter(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler, TType* resultType = nullptr);
- TRuntimeNode BuildSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode BuildListSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode BuildListNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
- TRuntimeNode BuildTake(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode count);
- TRuntimeNode BuildHeap(const std::string_view& callableName, TRuntimeNode list, const TBinaryLambda& comparator);
- TRuntimeNode BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
- TRuntimeNode BuildLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& args);
- TRuntimeNode BuildBinaryLogical(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode BuildMinMax(const std::string_view& callableName, const TRuntimeNode* data, size_t size);
+ template <typename ResultType>
+ TRuntimeNode BuildContainerProperty(const std::string_view& callableName, TRuntimeNode listOrDict);
+ TRuntimeNode Filter(TRuntimeNode list, const TUnaryLambda& handler, TType* resultType);
+ template <bool Ordered>
+ TRuntimeNode BuildExtract(TRuntimeNode list, const std::string_view& name);
+
+ TRuntimeNode BuildMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode BuildFlatMap(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler);
+ TRuntimeNode BuildFilter(const std::string_view& callableName, TRuntimeNode list, const TUnaryLambda& handler, TType* resultType = nullptr);
+ TRuntimeNode BuildFilter(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler, TType* resultType = nullptr);
+ TRuntimeNode BuildSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode BuildListSort(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode BuildListNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, TRuntimeNode ascending, const TUnaryLambda& keyExtractor);
+ TRuntimeNode BuildTake(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode count);
+ TRuntimeNode BuildHeap(const std::string_view& callableName, TRuntimeNode list, const TBinaryLambda& comparator);
+ TRuntimeNode BuildNth(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode n, const TBinaryLambda& comparator);
+ TRuntimeNode BuildLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& args);
+ TRuntimeNode BuildBinaryLogical(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode BuildMinMax(const std::string_view& callableName, const TRuntimeNode* data, size_t size);
private:
- TRuntimeNode BuildWideFilter(const std::string_view& callableName, TRuntimeNode flow, const TNarrowLambda& handler);
-
- TRuntimeNode DictItems(TRuntimeNode dict, EDictItems mode);
- TRuntimeNode If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch, TType* resultType);
-
- TRuntimeNode ToDict(TRuntimeNode list, bool multi, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
+ TRuntimeNode BuildWideFilter(const std::string_view& callableName, TRuntimeNode flow, const TNarrowLambda& handler);
+
+ TRuntimeNode DictItems(TRuntimeNode dict, EDictItems mode);
+ TRuntimeNode If(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch, TType* resultType);
+
+ TRuntimeNode ToDict(TRuntimeNode list, bool multi, const TUnaryLambda& keySelector,
+ const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
TRuntimeNode SqueezeToDict(TRuntimeNode stream, bool multi, const TUnaryLambda& keySelector,
- const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
- TRuntimeNode NarrowSqueezeToDict(TRuntimeNode stream, bool multi, const TNarrowLambda& keySelector,
- const TNarrowLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
-
- TRuntimeNode UnaryDataFunction(TRuntimeNode data, const std::string_view& callableName, ui32 flags);
-
- template<bool IsFilter, bool OnStruct>
- TRuntimeNode BuildFilterNulls(TRuntimeNode list);
- template<bool IsFilter, bool OnStruct>
- TRuntimeNode BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members);
- template<bool OnStruct>
- TRuntimeNode BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members,
- const std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>>& filteredItems);
-
- TRuntimeNode InvokeBinary(const std::string_view& callableName, TType* type, TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode AggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
- TRuntimeNode DataCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
-
+ const TUnaryLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
+ TRuntimeNode NarrowSqueezeToDict(TRuntimeNode stream, bool multi, const TNarrowLambda& keySelector,
+ const TNarrowLambda& payloadSelector, std::string_view callableName, bool isCompact, ui64 itemsCountHint);
+
+ TRuntimeNode UnaryDataFunction(TRuntimeNode data, const std::string_view& callableName, ui32 flags);
+
+ template<bool IsFilter, bool OnStruct>
+ TRuntimeNode BuildFilterNulls(TRuntimeNode list);
+ template<bool IsFilter, bool OnStruct>
+ TRuntimeNode BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members);
+ template<bool OnStruct>
+ TRuntimeNode BuildFilterNulls(TRuntimeNode list, const TArrayRef<std::conditional_t<OnStruct, const std::string_view, const ui32>>& members,
+ const std::conditional_t<OnStruct, std::vector<std::pair<std::string_view, TType*>>, std::vector<TType*>>& filteredItems);
+
+ TRuntimeNode InvokeBinary(const std::string_view& callableName, TType* type, TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode AggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+ TRuntimeNode DataCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+
TRuntimeNode BuildRangeLogical(const std::string_view& callableName, const TArrayRef<const TRuntimeNode>& lists);
- template<bool Default>
- TRuntimeNode DefaultResult(TRuntimeNode data);
-
- template<BinaryFunctionMethod Compare>
- TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Compare, bool OnEqual>
- TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Compare, bool OnEqual, bool Asc>
- TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare>
- TRuntimeNode BuildByNthCompare(ui32 count, TRuntimeNode data1, TRuntimeNode data2, ui32 index = 0U);
-
- template<BinaryFunctionMethod Compare, bool Fallback>
- TRuntimeNode BuildVariantCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Compare>
- TRuntimeNode BuildVariantCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare>
- TRuntimeNode BuildMembersCompare(const TStructType* type, TRuntimeNode data1, TRuntimeNode data2, ui32 index = 0U);
-
- template<TProgramBuilder::BinaryFunctionMethod Compare, TProgramBuilder::ArrayFunctionMethod Join, bool OnEqual>
- TRuntimeNode BuildStructCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare, bool OnEqual>
- TRuntimeNode BuildStructCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<TProgramBuilder::BinaryFunctionMethod Compare, TProgramBuilder::ArrayFunctionMethod Join, bool OnEqual>
- TRuntimeNode BuildTupleCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare, bool OnEqual>
- TRuntimeNode BuildTupleCompare(TRuntimeNode data1, TRuntimeNode data2);
-
- template<bool Equal>
- TRuntimeNode BuildAggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
-
- template <bool Equal>
- TRuntimeNode BuildSqlCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
-
- template <bool Asc, bool Equal>
- TRuntimeNode BuildAggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
-
- template <bool Asc, bool Equal>
- TRuntimeNode BuildSqlCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
-
- TType* ChooseCommonType(TType* type1, TType* type2);
- TType* BuildArithmeticCommonType(TType* type1, TType* type2);
-
- bool IsNull(TRuntimeNode arg);
+ template<bool Default>
+ TRuntimeNode DefaultResult(TRuntimeNode data);
+
+ template<BinaryFunctionMethod Compare>
+ TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Compare, bool OnEqual>
+ TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Compare, bool OnEqual, bool Asc>
+ TRuntimeNode BuildOptionalCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare>
+ TRuntimeNode BuildByNthCompare(ui32 count, TRuntimeNode data1, TRuntimeNode data2, ui32 index = 0U);
+
+ template<BinaryFunctionMethod Compare, bool Fallback>
+ TRuntimeNode BuildVariantCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Compare>
+ TRuntimeNode BuildVariantCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare>
+ TRuntimeNode BuildMembersCompare(const TStructType* type, TRuntimeNode data1, TRuntimeNode data2, ui32 index = 0U);
+
+ template<TProgramBuilder::BinaryFunctionMethod Compare, TProgramBuilder::ArrayFunctionMethod Join, bool OnEqual>
+ TRuntimeNode BuildStructCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare, bool OnEqual>
+ TRuntimeNode BuildStructCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<TProgramBuilder::BinaryFunctionMethod Compare, TProgramBuilder::ArrayFunctionMethod Join, bool OnEqual>
+ TRuntimeNode BuildTupleCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<BinaryFunctionMethod Equal, BinaryFunctionMethod Compare, BinaryFunctionMethod FinalCompare, bool OnEqual>
+ TRuntimeNode BuildTupleCompare(TRuntimeNode data1, TRuntimeNode data2);
+
+ template<bool Equal>
+ TRuntimeNode BuildAggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+
+ template <bool Equal>
+ TRuntimeNode BuildSqlCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+
+ template <bool Asc, bool Equal>
+ TRuntimeNode BuildAggrCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+
+ template <bool Asc, bool Equal>
+ TRuntimeNode BuildSqlCompare(const std::string_view& callableName, TRuntimeNode data1, TRuntimeNode data2);
+
+ TType* ChooseCommonType(TType* type1, TType* type2);
+ TType* BuildArithmeticCommonType(TType* type1, TType* type2);
+
+ bool IsNull(TRuntimeNode arg);
protected:
const TTypeEnvironment& Env;
const IFunctionRegistry& FunctionRegistry;
- const bool VoidWithEffects;
+ const bool VoidWithEffects;
NUdf::ITypeInfoHelper::TPtr TypeInfoHelper;
bool UseNullType = true;
};
diff --git a/ydb/library/yql/minikql/mkql_runtime_version.h b/ydb/library/yql/minikql/mkql_runtime_version.h
index b10e3ea59d..6cccfed0c6 100644
--- a/ydb/library/yql/minikql/mkql_runtime_version.h
+++ b/ydb/library/yql/minikql/mkql_runtime_version.h
@@ -23,14 +23,14 @@ namespace NMiniKQL {
// 1. Bump this version every time incompatible runtime nodes are introduced.
// 2. Make sure you provide runtime node generation for previous runtime versions.
-#ifndef MKQL_RUNTIME_VERSION
-#define MKQL_RUNTIME_VERSION 29U
+#ifndef MKQL_RUNTIME_VERSION
+#define MKQL_RUNTIME_VERSION 29U
#endif
// History:
// v4 is the version supported by kikimr-19-6
// v14 is the version supported by kikimr-20-2
-constexpr ui32 RuntimeVersion = MKQL_RUNTIME_VERSION;
-
+constexpr ui32 RuntimeVersion = MKQL_RUNTIME_VERSION;
+
}
}
diff --git a/ydb/library/yql/minikql/mkql_string_util.cpp b/ydb/library/yql/minikql/mkql_string_util.cpp
index 73f4b4f2c1..40aba1c341 100644
--- a/ydb/library/yql/minikql/mkql_string_util.cpp
+++ b/ydb/library/yql/minikql/mkql_string_util.cpp
@@ -1,158 +1,158 @@
-#include "mkql_string_util.h"
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-NUdf::TUnboxedValuePod AppendString(const NUdf::TUnboxedValuePod value, const NUdf::TStringRef ref)
-{
- if (!ref.Size())
- return value;
-
- const auto& valueRef = value.AsStringRef();
- if (!valueRef.Size())
- return MakeString(ref);
-
- const auto newSize = valueRef.Size() + ref.Size();
- if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
- auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
- const auto buf = result.AsStringRef().Data();
- std::memcpy(buf, valueRef.Data(), valueRef.Size());
- std::memcpy(buf + valueRef.Size(), ref.Data(), ref.Size());
- return result;
- } else {
- if (value.IsString()) {
- auto str = value.AsStringValue();
- const ui32 offset = ref.Data() - str.Data();
- if (str.Size() == valueRef.Size() + offset) {
- if (str.TryExpandOn(ref.Size())) {
- std::memcpy(str.Data() + offset + valueRef.Size(), ref.Data(), ref.Size());
- return NUdf::TUnboxedValuePod(std::move(str), newSize, offset);
- }
- }
- }
-
+#include "mkql_string_util.h"
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+NUdf::TUnboxedValuePod AppendString(const NUdf::TUnboxedValuePod value, const NUdf::TStringRef ref)
+{
+ if (!ref.Size())
+ return value;
+
+ const auto& valueRef = value.AsStringRef();
+ if (!valueRef.Size())
+ return MakeString(ref);
+
+ const auto newSize = valueRef.Size() + ref.Size();
+ if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
+ auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
+ const auto buf = result.AsStringRef().Data();
+ std::memcpy(buf, valueRef.Data(), valueRef.Size());
+ std::memcpy(buf + valueRef.Size(), ref.Data(), ref.Size());
+ return result;
+ } else {
+ if (value.IsString()) {
+ auto str = value.AsStringValue();
+ const ui32 offset = ref.Data() - str.Data();
+ if (str.Size() == valueRef.Size() + offset) {
+ if (str.TryExpandOn(ref.Size())) {
+ std::memcpy(str.Data() + offset + valueRef.Size(), ref.Data(), ref.Size());
+ return NUdf::TUnboxedValuePod(std::move(str), newSize, offset);
+ }
+ }
+ }
+
auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2);
NUdf::TStringValue str(data);
data->UnRef();
- std::memcpy(str.Data(), valueRef.Data(), valueRef.Size());
- std::memcpy(str.Data() + valueRef.Size(), ref.Data(), ref.Size());
- return NUdf::TUnboxedValuePod(std::move(str));
- }
-}
-
-NUdf::TUnboxedValuePod PrependString(const NUdf::TStringRef ref, const NUdf::TUnboxedValuePod value)
-{
- if (!ref.Size())
- return value;
-
- const auto& valueRef = value.AsStringRef();
- if (!valueRef.Size())
- return MakeString(ref);
-
- const auto newSize = valueRef.Size() + ref.Size();
- if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
- auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
- const auto buf = result.AsStringRef().Data();
- std::memcpy(buf, ref.Data(), ref.Size());
- std::memcpy(buf + ref.Size(), valueRef.Data(), valueRef.Size());
- return result;
- } else {
+ std::memcpy(str.Data(), valueRef.Data(), valueRef.Size());
+ std::memcpy(str.Data() + valueRef.Size(), ref.Data(), ref.Size());
+ return NUdf::TUnboxedValuePod(std::move(str));
+ }
+}
+
+NUdf::TUnboxedValuePod PrependString(const NUdf::TStringRef ref, const NUdf::TUnboxedValuePod value)
+{
+ if (!ref.Size())
+ return value;
+
+ const auto& valueRef = value.AsStringRef();
+ if (!valueRef.Size())
+ return MakeString(ref);
+
+ const auto newSize = valueRef.Size() + ref.Size();
+ if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
+ auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
+ const auto buf = result.AsStringRef().Data();
+ std::memcpy(buf, ref.Data(), ref.Size());
+ std::memcpy(buf + ref.Size(), valueRef.Data(), valueRef.Size());
+ return result;
+ } else {
auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2);
NUdf::TStringValue str(data);
data->UnRef();
- std::memcpy(str.Data(), ref.Data(), ref.Size());
- std::memcpy(str.Data() + ref.Size(), valueRef.Data(), valueRef.Size());
- value.DeleteUnreferenced();
- return NUdf::TUnboxedValuePod(std::move(str));
- }
-}
-
-NUdf::TUnboxedValuePod ConcatStrings(const NUdf::TUnboxedValuePod first, const NUdf::TUnboxedValuePod second)
-{
- const auto& leftRef = first.AsStringRef();
- if (!leftRef.Size())
- return second;
-
- const auto& rightRef = second.AsStringRef();
- if (!rightRef.Size())
- return first;
-
- const auto newSize = leftRef.Size() + rightRef.Size();
- if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
- auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
- const auto buf = result.AsStringRef().Data();
- std::memcpy(buf, leftRef.Data(), leftRef.Size());
- std::memcpy(buf + leftRef.Size(), rightRef.Data(), rightRef.Size());
- return result;
- } else {
- if (first.IsString()) {
- auto str = first.AsStringValue();
- const ui32 offset = leftRef.Data() - str.Data();
- if (str.Size() == leftRef.Size() + offset) {
- if (str.TryExpandOn(rightRef.Size())) {
- std::memcpy(str.Data() + offset + leftRef.Size(), rightRef.Data(), rightRef.Size());
- second.DeleteUnreferenced();
- return NUdf::TUnboxedValuePod(std::move(str), newSize, offset);
- }
- }
- }
-
+ std::memcpy(str.Data(), ref.Data(), ref.Size());
+ std::memcpy(str.Data() + ref.Size(), valueRef.Data(), valueRef.Size());
+ value.DeleteUnreferenced();
+ return NUdf::TUnboxedValuePod(std::move(str));
+ }
+}
+
+NUdf::TUnboxedValuePod ConcatStrings(const NUdf::TUnboxedValuePod first, const NUdf::TUnboxedValuePod second)
+{
+ const auto& leftRef = first.AsStringRef();
+ if (!leftRef.Size())
+ return second;
+
+ const auto& rightRef = second.AsStringRef();
+ if (!rightRef.Size())
+ return first;
+
+ const auto newSize = leftRef.Size() + rightRef.Size();
+ if (newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
+ auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
+ const auto buf = result.AsStringRef().Data();
+ std::memcpy(buf, leftRef.Data(), leftRef.Size());
+ std::memcpy(buf + leftRef.Size(), rightRef.Data(), rightRef.Size());
+ return result;
+ } else {
+ if (first.IsString()) {
+ auto str = first.AsStringValue();
+ const ui32 offset = leftRef.Data() - str.Data();
+ if (str.Size() == leftRef.Size() + offset) {
+ if (str.TryExpandOn(rightRef.Size())) {
+ std::memcpy(str.Data() + offset + leftRef.Size(), rightRef.Data(), rightRef.Size());
+ second.DeleteUnreferenced();
+ return NUdf::TUnboxedValuePod(std::move(str), newSize, offset);
+ }
+ }
+ }
+
auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2);
NUdf::TStringValue str(data);
data->UnRef();
- std::memcpy(str.Data(), leftRef.Data(), leftRef.Size());
- std::memcpy(str.Data() + leftRef.Size(), rightRef.Data(), rightRef.Size());
- second.DeleteUnreferenced();
- return NUdf::TUnboxedValuePod(std::move(str));
- }
-}
-
-NUdf::TUnboxedValuePod SubString(const NUdf::TUnboxedValuePod value, ui32 offset, ui32 size)
-{
- const auto& ref = value.AsStringRef();
- if (size == 0U || ref.Size() <= offset) {
- value.DeleteUnreferenced();
- return NUdf::TUnboxedValuePod::Zero();
- }
-
- if (offset == 0U && ref.Size() <= size)
- return value;
-
- if (const auto newSize = std::min(ref.Size() - offset, size); newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
- auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
- std::memcpy(result.AsStringRef().Data(), ref.Data() + offset, newSize);
- value.DeleteUnreferenced();
- return result;
- } else {
- auto old = value.AsStringValue();
- if (const auto newOffset = ui32(ref.Data() - old.Data()) + offset; NUdf::TUnboxedValuePod::OffsetLimit > newOffset)
- return NUdf::TUnboxedValuePod(std::move(old), newSize, newOffset);
-
- auto data = NUdf::TStringValue::AllocateData(newSize, newSize + (newSize >> 1U));
- NUdf::TStringValue str(data);
- data->UnRef();
- std::memcpy(str.Data(), ref.Data() + offset, newSize);
- return NUdf::TUnboxedValuePod(std::move(str));
- }
-}
-
-NUdf::TUnboxedValuePod MakeString(const NUdf::TStringRef ref)
-{
- if (ref.Size() <= NUdf::TUnboxedValuePod::InternalBufferSize)
- return NUdf::TUnboxedValuePod::Embedded(ref);
-
- NUdf::TStringValue str(ref.Size());
- std::memcpy(str.Data(), ref.Data(), ref.Size());
- return NUdf::TUnboxedValuePod(std::move(str));
-}
-
-NUdf::TUnboxedValuePod MakeStringNotFilled(ui32 size)
-{
- if (size <= NUdf::TUnboxedValuePod::InternalBufferSize)
- return NUdf::TUnboxedValuePod::Embedded(size);
-
- return NUdf::TUnboxedValuePod(NUdf::TStringValue(size));
-}
-
-}
-}
+ std::memcpy(str.Data(), leftRef.Data(), leftRef.Size());
+ std::memcpy(str.Data() + leftRef.Size(), rightRef.Data(), rightRef.Size());
+ second.DeleteUnreferenced();
+ return NUdf::TUnboxedValuePod(std::move(str));
+ }
+}
+
+NUdf::TUnboxedValuePod SubString(const NUdf::TUnboxedValuePod value, ui32 offset, ui32 size)
+{
+ const auto& ref = value.AsStringRef();
+ if (size == 0U || ref.Size() <= offset) {
+ value.DeleteUnreferenced();
+ return NUdf::TUnboxedValuePod::Zero();
+ }
+
+ if (offset == 0U && ref.Size() <= size)
+ return value;
+
+ if (const auto newSize = std::min(ref.Size() - offset, size); newSize <= NUdf::TUnboxedValuePod::InternalBufferSize) {
+ auto result = NUdf::TUnboxedValuePod::Embedded(newSize);
+ std::memcpy(result.AsStringRef().Data(), ref.Data() + offset, newSize);
+ value.DeleteUnreferenced();
+ return result;
+ } else {
+ auto old = value.AsStringValue();
+ if (const auto newOffset = ui32(ref.Data() - old.Data()) + offset; NUdf::TUnboxedValuePod::OffsetLimit > newOffset)
+ return NUdf::TUnboxedValuePod(std::move(old), newSize, newOffset);
+
+ auto data = NUdf::TStringValue::AllocateData(newSize, newSize + (newSize >> 1U));
+ NUdf::TStringValue str(data);
+ data->UnRef();
+ std::memcpy(str.Data(), ref.Data() + offset, newSize);
+ return NUdf::TUnboxedValuePod(std::move(str));
+ }
+}
+
+NUdf::TUnboxedValuePod MakeString(const NUdf::TStringRef ref)
+{
+ if (ref.Size() <= NUdf::TUnboxedValuePod::InternalBufferSize)
+ return NUdf::TUnboxedValuePod::Embedded(ref);
+
+ NUdf::TStringValue str(ref.Size());
+ std::memcpy(str.Data(), ref.Data(), ref.Size());
+ return NUdf::TUnboxedValuePod(std::move(str));
+}
+
+NUdf::TUnboxedValuePod MakeStringNotFilled(ui32 size)
+{
+ if (size <= NUdf::TUnboxedValuePod::InternalBufferSize)
+ return NUdf::TUnboxedValuePod::Embedded(size);
+
+ return NUdf::TUnboxedValuePod(NUdf::TStringValue(size));
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/mkql_string_util.h b/ydb/library/yql/minikql/mkql_string_util.h
index a1c999dbce..5a59e91ba4 100644
--- a/ydb/library/yql/minikql/mkql_string_util.h
+++ b/ydb/library/yql/minikql/mkql_string_util.h
@@ -1,16 +1,16 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/public/udf/udf_value.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-NUdf::TUnboxedValuePod AppendString(const NUdf::TUnboxedValuePod value, const NUdf::TStringRef ref);
-NUdf::TUnboxedValuePod PrependString(const NUdf::TStringRef ref, const NUdf::TUnboxedValuePod value);
-NUdf::TUnboxedValuePod ConcatStrings(const NUdf::TUnboxedValuePod first, const NUdf::TUnboxedValuePod second);
-NUdf::TUnboxedValuePod SubString(const NUdf::TUnboxedValuePod value, ui32 offset, ui32 size);
-NUdf::TUnboxedValuePod MakeString(const NUdf::TStringRef ref);
-NUdf::TUnboxedValuePod MakeStringNotFilled(ui32 size);
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+NUdf::TUnboxedValuePod AppendString(const NUdf::TUnboxedValuePod value, const NUdf::TStringRef ref);
+NUdf::TUnboxedValuePod PrependString(const NUdf::TStringRef ref, const NUdf::TUnboxedValuePod value);
+NUdf::TUnboxedValuePod ConcatStrings(const NUdf::TUnboxedValuePod first, const NUdf::TUnboxedValuePod second);
+NUdf::TUnboxedValuePod SubString(const NUdf::TUnboxedValuePod value, ui32 offset, ui32 size);
+NUdf::TUnboxedValuePod MakeString(const NUdf::TStringRef ref);
+NUdf::TUnboxedValuePod MakeStringNotFilled(ui32 size);
+
+}
+}
diff --git a/ydb/library/yql/minikql/mkql_string_util_ut.cpp b/ydb/library/yql/minikql/mkql_string_util_ut.cpp
index da13ff5caf..f3186c6608 100644
--- a/ydb/library/yql/minikql/mkql_string_util_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_string_util_ut.cpp
@@ -1,21 +1,21 @@
-#include "mkql_alloc.h"
-#include "mkql_string_util.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NYql;
-using namespace NKikimr::NMiniKQL;
-
-Y_UNIT_TEST_SUITE(TMiniKQLStringUtils) {
- Y_UNIT_TEST(SubstringWithLargeOffset) {
- TScopedAlloc alloc;
- const auto big = MakeStringNotFilled(NUdf::TUnboxedValuePod::OffsetLimit << 1U);
- const auto sub0 = SubString(big, 1U, 42U);
- const auto sub1 = SubString(big, NUdf::TUnboxedValuePod::OffsetLimit - 1U, 42U);
- const auto sub2 = SubString(big, NUdf::TUnboxedValuePod::OffsetLimit, 42U);
-
- UNIT_ASSERT(sub0.AsStringValue().Data() == sub1.AsStringValue().Data());
- UNIT_ASSERT(sub1.AsStringValue().Data() != sub2.AsStringValue().Data());
- }
-}
-
+#include "mkql_alloc.h"
+#include "mkql_string_util.h"
+
+#include <library/cpp/testing/unittest/registar.h>
+
+using namespace NYql;
+using namespace NKikimr::NMiniKQL;
+
+Y_UNIT_TEST_SUITE(TMiniKQLStringUtils) {
+ Y_UNIT_TEST(SubstringWithLargeOffset) {
+ TScopedAlloc alloc;
+ const auto big = MakeStringNotFilled(NUdf::TUnboxedValuePod::OffsetLimit << 1U);
+ const auto sub0 = SubString(big, 1U, 42U);
+ const auto sub1 = SubString(big, NUdf::TUnboxedValuePod::OffsetLimit - 1U, 42U);
+ const auto sub2 = SubString(big, NUdf::TUnboxedValuePod::OffsetLimit, 42U);
+
+ UNIT_ASSERT(sub0.AsStringValue().Data() == sub1.AsStringValue().Data());
+ UNIT_ASSERT(sub1.AsStringValue().Data() != sub2.AsStringValue().Data());
+ }
+}
+
diff --git a/ydb/library/yql/minikql/mkql_terminator.cpp b/ydb/library/yql/minikql/mkql_terminator.cpp
index 41401d046e..d86ba4edaf 100644
--- a/ydb/library/yql/minikql/mkql_terminator.cpp
+++ b/ydb/library/yql/minikql/mkql_terminator.cpp
@@ -1,32 +1,32 @@
-#include "defs.h"
-#include "mkql_terminator.h"
-
-namespace NKikimr {
-
-namespace NMiniKQL {
-
-thread_local ITerminator* TBindTerminator::Terminator = nullptr;
-
-TBindTerminator::TBindTerminator(ITerminator* terminator)
+#include "defs.h"
+#include "mkql_terminator.h"
+
+namespace NKikimr {
+
+namespace NMiniKQL {
+
+thread_local ITerminator* TBindTerminator::Terminator = nullptr;
+
+TBindTerminator::TBindTerminator(ITerminator* terminator)
: PreviousTerminator(Terminator)
-{
+{
Terminator = terminator;
-}
-
-TBindTerminator::~TBindTerminator()
-{
+}
+
+TBindTerminator::~TBindTerminator()
+{
Terminator = PreviousTerminator;
-}
-
+}
+
[[noreturn]] void MKQLTerminate(const char* message) {
- if (const auto t = TBindTerminator::Terminator)
- t->Terminate(message);
-
- if (message)
- Cerr << message << Endl;
- ::abort();
-}
-
-}
-
-}
+ if (const auto t = TBindTerminator::Terminator)
+ t->Terminate(message);
+
+ if (message)
+ Cerr << message << Endl;
+ ::abort();
+}
+
+}
+
+}
diff --git a/ydb/library/yql/minikql/mkql_terminator.h b/ydb/library/yql/minikql/mkql_terminator.h
index 07914ab9a8..2453e88938 100644
--- a/ydb/library/yql/minikql/mkql_terminator.h
+++ b/ydb/library/yql/minikql/mkql_terminator.h
@@ -1,33 +1,33 @@
-#pragma once
-
-#include <util/generic/noncopyable.h>
-#include <util/system/compiler.h>
-
-
-namespace NKikimr {
-
-namespace NMiniKQL {
-///////////////////////////////////////////////////////////////////////////////
-// ITerminator
-///////////////////////////////////////////////////////////////////////////////
-class ITerminator
-{
-public:
- virtual ~ITerminator() = default;
- virtual void Terminate(const char* message) const = 0;
-};
-
-struct TBindTerminator : private TNonCopyable {
- TBindTerminator(ITerminator* terminator);
- ~TBindTerminator();
-
- static thread_local ITerminator* Terminator;
-private:
+#pragma once
+
+#include <util/generic/noncopyable.h>
+#include <util/system/compiler.h>
+
+
+namespace NKikimr {
+
+namespace NMiniKQL {
+///////////////////////////////////////////////////////////////////////////////
+// ITerminator
+///////////////////////////////////////////////////////////////////////////////
+class ITerminator
+{
+public:
+ virtual ~ITerminator() = default;
+ virtual void Terminate(const char* message) const = 0;
+};
+
+struct TBindTerminator : private TNonCopyable {
+ TBindTerminator(ITerminator* terminator);
+ ~TBindTerminator();
+
+ static thread_local ITerminator* Terminator;
+private:
ITerminator* PreviousTerminator;
-};
-
+};
+
[[noreturn]] void MKQLTerminate(const char* message);
-
-}
-
-}
+
+}
+
+}
diff --git a/ydb/library/yql/minikql/mkql_type_builder.cpp b/ydb/library/yql/minikql/mkql_type_builder.cpp
index 4438fab388..4aecb564bf 100644
--- a/ydb/library/yql/minikql/mkql_type_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_type_builder.cpp
@@ -22,7 +22,7 @@ public:
auto structObj = AS_VALUE(NMiniKQL::TStructLiteral, NMiniKQL::TRuntimeNode(node, true));
auto argsIndex = structObj->GetType()->GetMemberIndex("Args");
auto payloadIndex = structObj->GetType()->GetMemberIndex("Payload");
- Payload_ = AS_VALUE(NMiniKQL::TDataLiteral, structObj->GetValue(payloadIndex))->AsValue().AsStringRef();
+ Payload_ = AS_VALUE(NMiniKQL::TDataLiteral, structObj->GetValue(payloadIndex))->AsValue().AsStringRef();
auto args = structObj->GetValue(argsIndex);
auto argsList = AS_VALUE(NMiniKQL::TListLiteral, args);
auto itemType = AS_TYPE(NMiniKQL::TStructType, AS_TYPE(NMiniKQL::TListType, args)->GetItemType());
@@ -32,7 +32,7 @@ public:
ArgsFlags_.reserve(argsList->GetItemsCount());
for (ui32 i = 0; i < argsList->GetItemsCount(); ++i) {
auto arg = AS_VALUE(NMiniKQL::TStructLiteral, argsList->GetItems()[i]);
- ArgsNames_.push_back(AS_VALUE(NMiniKQL::TDataLiteral, arg->GetValue(nameIndex))->AsValue().AsStringRef());
+ ArgsNames_.push_back(AS_VALUE(NMiniKQL::TDataLiteral, arg->GetValue(nameIndex))->AsValue().AsStringRef());
ArgsFlags_.push_back(AS_VALUE(NMiniKQL::TDataLiteral, arg->GetValue(flagsIndex))->AsValue().Get<ui64>());
}
}
@@ -620,16 +620,16 @@ template <NUdf::EDataSlot Slot>
class THash<NMiniKQL::TType::EKind::Data, Slot> final : public NUdf::IHash {
public:
ui64 Hash(NUdf::TUnboxedValuePod value) const override {
- return NUdf::GetValueHash<Slot>(std::move(value));
+ return NUdf::GetValueHash<Slot>(std::move(value));
}
};
template <>
class THash<NMiniKQL::TType::EKind::Optional> final : public NUdf::IHash {
public:
- explicit THash(const NMiniKQL::TType* type)
- : Hash_(MakeHashImpl(static_cast<const NMiniKQL::TOptionalType*>(type)->GetItemType()))
- {}
+ explicit THash(const NMiniKQL::TType* type)
+ : Hash_(MakeHashImpl(static_cast<const NMiniKQL::TOptionalType*>(type)->GetItemType()))
+ {}
ui64 Hash(NUdf::TUnboxedValuePod value) const override {
if (!value) {
@@ -639,30 +639,30 @@ public:
}
private:
- const NUdf::IHash::TPtr Hash_;
+ const NUdf::IHash::TPtr Hash_;
};
-template <>
-class THash<NMiniKQL::TType::EKind::List> final : public NUdf::IHash {
-public:
- explicit THash(const NMiniKQL::TType* type)
- : Hash_(MakeHashImpl(static_cast<const NMiniKQL::TListType*>(type)->GetItemType()))
- {}
-
- ui64 Hash(NUdf::TUnboxedValuePod value) const override {
- ui64 result = 0ULL;
- NKikimr::NMiniKQL::TThresher<false>::DoForEachItem(value,
- [&result, this] (NUdf::TUnboxedValue&& item) {
+template <>
+class THash<NMiniKQL::TType::EKind::List> final : public NUdf::IHash {
+public:
+ explicit THash(const NMiniKQL::TType* type)
+ : Hash_(MakeHashImpl(static_cast<const NMiniKQL::TListType*>(type)->GetItemType()))
+ {}
+
+ ui64 Hash(NUdf::TUnboxedValuePod value) const override {
+ ui64 result = 0ULL;
+ NKikimr::NMiniKQL::TThresher<false>::DoForEachItem(value,
+ [&result, this] (NUdf::TUnboxedValue&& item) {
result = CombineHashes(result, Hash_->Hash(static_cast<const NUdf::TUnboxedValuePod&>(item)));
- }
- );
- return result;
- }
-
-private:
- const NUdf::IHash::TPtr Hash_;
-};
-
+ }
+ );
+ return result;
+ }
+
+private:
+ const NUdf::IHash::TPtr Hash_;
+};
+
template <>
class THash<NMiniKQL::TType::EKind::Dict> final : public NUdf::IHash {
public:
@@ -714,12 +714,12 @@ private:
class TVectorHash : public NUdf::IHash {
public:
ui64 Hash(NUdf::TUnboxedValuePod value) const override {
- ui64 result = 0ULL;
+ ui64 result = 0ULL;
auto elements = value.GetElements();
if (elements) {
for (ui32 i = 0; i < Hash_.size(); ++i) {
result = CombineHashes(result, Hash_[i]->Hash(static_cast<const NUdf::TUnboxedValuePod&>(elements[i])));
- }
+ }
} else {
for (ui32 i = 0; i < Hash_.size(); ++i) {
auto item = value.GetElement(i);
@@ -731,7 +731,7 @@ public:
}
protected:
- std::vector<NUdf::IHash::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::IHash::TPtr>> Hash_;
+ std::vector<NUdf::IHash::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::IHash::TPtr>> Hash_;
};
template <>
@@ -813,16 +813,16 @@ template <NUdf::EDataSlot Slot>
class TEquate<NMiniKQL::TType::EKind::Data, Slot> final : public NUdf::IEquate {
public:
bool Equals(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
- return NUdf::EquateValues<Slot>(std::move(lhs), std::move(rhs));
+ return NUdf::EquateValues<Slot>(std::move(lhs), std::move(rhs));
}
};
template <>
class TEquate<NMiniKQL::TType::EKind::Optional> final : public NUdf::IEquate {
public:
- explicit TEquate(const NMiniKQL::TType* type)
- : Equate_(MakeEquateImpl(static_cast<const NMiniKQL::TOptionalType*>(type)->GetItemType()))
- {}
+ explicit TEquate(const NMiniKQL::TType* type)
+ : Equate_(MakeEquateImpl(static_cast<const NMiniKQL::TOptionalType*>(type)->GetItemType()))
+ {}
bool Equals(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
if (!lhs) {
@@ -839,75 +839,75 @@ public:
}
private:
- const NUdf::IEquate::TPtr Equate_;
+ const NUdf::IEquate::TPtr Equate_;
+};
+
+template <>
+class TEquate<NMiniKQL::TType::EKind::List> final : public NUdf::IEquate {
+public:
+ explicit TEquate(const NMiniKQL::TType* type)
+ : Equate_(MakeEquateImpl(static_cast<const NMiniKQL::TListType*>(type)->GetItemType()))
+ {}
+
+ bool Equals(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
+ auto elementsL = lhs.GetElements();
+ auto elementsR = rhs.GetElements();
+ if (elementsL && elementsR) {
+ const auto size = lhs.GetListLength();
+ if (size != rhs.GetListLength()) {
+ return false;
+ }
+
+ for (ui64 i = 0ULL; i < size; ++i) {
+ if (!Equate_->Equals(*elementsL++, *elementsR++)) {
+ return false;
+ }
+ }
+ } else if (elementsL) {
+ const auto iter = rhs.GetListIterator();
+ auto size = lhs.GetListLength();
+ for (NUdf::TUnboxedValue item; iter.Next(item); --size) {
+ if (!size || !Equate_->Equals(*elementsL++, static_cast<const NUdf::TUnboxedValuePod&>(item))) {
+ return false;
+ }
+ }
+
+ if (size) {
+ return false;
+ }
+ } else if (elementsR) {
+ const auto iter = lhs.GetListIterator();
+ auto size = rhs.GetListLength();
+ for (NUdf::TUnboxedValue item; iter.Next(item); --size) {
+ if (!size || !Equate_->Equals(static_cast<const NUdf::TUnboxedValuePod&>(item), *elementsR++)) {
+ return false;
+ }
+ }
+
+ if (size) {
+ return false;
+ }
+ } else {
+ const auto lIter = lhs.GetListIterator();
+ const auto rIter = rhs.GetListIterator();
+ for (NUdf::TUnboxedValue left, right;;) {
+ if (const bool lOk = lIter.Next(left), rOk = rIter.Next(right); lOk && rOk) {
+ if (!Equate_->Equals(
+ static_cast<const NUdf::TUnboxedValuePod&>(left),
+ static_cast<const NUdf::TUnboxedValuePod&>(right))) {
+ return false;
+ }
+ } else {
+ return !(lOk || rOk);
+ }
+ }
+ }
+ return true;
+ }
+private:
+ const NUdf::IEquate::TPtr Equate_;
};
-template <>
-class TEquate<NMiniKQL::TType::EKind::List> final : public NUdf::IEquate {
-public:
- explicit TEquate(const NMiniKQL::TType* type)
- : Equate_(MakeEquateImpl(static_cast<const NMiniKQL::TListType*>(type)->GetItemType()))
- {}
-
- bool Equals(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
- auto elementsL = lhs.GetElements();
- auto elementsR = rhs.GetElements();
- if (elementsL && elementsR) {
- const auto size = lhs.GetListLength();
- if (size != rhs.GetListLength()) {
- return false;
- }
-
- for (ui64 i = 0ULL; i < size; ++i) {
- if (!Equate_->Equals(*elementsL++, *elementsR++)) {
- return false;
- }
- }
- } else if (elementsL) {
- const auto iter = rhs.GetListIterator();
- auto size = lhs.GetListLength();
- for (NUdf::TUnboxedValue item; iter.Next(item); --size) {
- if (!size || !Equate_->Equals(*elementsL++, static_cast<const NUdf::TUnboxedValuePod&>(item))) {
- return false;
- }
- }
-
- if (size) {
- return false;
- }
- } else if (elementsR) {
- const auto iter = lhs.GetListIterator();
- auto size = rhs.GetListLength();
- for (NUdf::TUnboxedValue item; iter.Next(item); --size) {
- if (!size || !Equate_->Equals(static_cast<const NUdf::TUnboxedValuePod&>(item), *elementsR++)) {
- return false;
- }
- }
-
- if (size) {
- return false;
- }
- } else {
- const auto lIter = lhs.GetListIterator();
- const auto rIter = rhs.GetListIterator();
- for (NUdf::TUnboxedValue left, right;;) {
- if (const bool lOk = lIter.Next(left), rOk = rIter.Next(right); lOk && rOk) {
- if (!Equate_->Equals(
- static_cast<const NUdf::TUnboxedValuePod&>(left),
- static_cast<const NUdf::TUnboxedValuePod&>(right))) {
- return false;
- }
- } else {
- return !(lOk || rOk);
- }
- }
- }
- return true;
- }
-private:
- const NUdf::IEquate::TPtr Equate_;
-};
-
template <>
class TEquate<NMiniKQL::TType::EKind::Dict> final : public NUdf::IEquate {
public:
@@ -958,7 +958,7 @@ public:
}
protected:
- std::vector<NUdf::IEquate::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::IEquate::TPtr>> Equate_;
+ std::vector<NUdf::IEquate::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::IEquate::TPtr>> Equate_;
};
template <>
@@ -1052,11 +1052,11 @@ template <NUdf::EDataSlot Slot>
class TCompare<NMiniKQL::TType::EKind::Data, Slot> final : public NUdf::ICompare {
public:
bool Less(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
- return NUdf::CompareValues<Slot>(std::move(lhs), std::move(rhs)) < 0;
+ return NUdf::CompareValues<Slot>(std::move(lhs), std::move(rhs)) < 0;
}
int Compare(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
- return NUdf::CompareValues<Slot>(std::move(lhs), std::move(rhs));
+ return NUdf::CompareValues<Slot>(std::move(lhs), std::move(rhs));
}
};
@@ -1065,7 +1065,7 @@ class TCompare<NMiniKQL::TType::EKind::Optional> final : public NUdf::ICompare {
public:
explicit TCompare(const NMiniKQL::TType* type)
: Compare_(MakeCompareImpl(static_cast<const NMiniKQL::TOptionalType*>(type)->GetItemType()))
- {}
+ {}
bool Less(NUdf::TUnboxedValuePod lhs, NUdf::TUnboxedValuePod rhs) const override {
if (!lhs) {
@@ -1096,7 +1096,7 @@ public:
}
private:
- const NUdf::ICompare::TPtr Compare_;
+ const NUdf::ICompare::TPtr Compare_;
};
template <>
@@ -1128,7 +1128,7 @@ public:
}
private:
- std::vector<NUdf::ICompare::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::ICompare::TPtr>> Compare_;
+ std::vector<NUdf::ICompare::TPtr, NKikimr::NMiniKQL::TMKQLAllocator<NUdf::ICompare::TPtr>> Compare_;
};
template <>
@@ -1262,7 +1262,7 @@ TFunctionTypeInfoBuilder::TFunctionTypeInfoBuilder(
NUdf::IFunctionTypeInfoBuilder1& TFunctionTypeInfoBuilder::ImplementationImpl(
NUdf::TUniquePtr<NUdf::IBoxedValue> impl)
{
- Implementation_ = std::move(impl);
+ Implementation_ = std::move(impl);
return *this;
}
@@ -1426,7 +1426,7 @@ void TFunctionTypeInfoBuilder::Build(TFunctionTypeInfo* funcInfo)
funcInfo->RunConfigType = RunConfigType_;
funcInfo->UserType = UserType_;
- funcInfo->Implementation = std::move(Implementation_);
+ funcInfo->Implementation = std::move(Implementation_);
funcInfo->ModuleIR = std::move(ModuleIR_);
funcInfo->ModuleIRUniqID = std::move(ModuleIRUniqID_);
funcInfo->IRFunctionName = std::move(IRFunctionName_);
@@ -1438,11 +1438,11 @@ NUdf::TType* TFunctionTypeInfoBuilder::Primitive(NUdf::TDataTypeId typeId) const
return TDataType::Create(typeId, Env_);
}
-NUdf::TType* TFunctionTypeInfoBuilder::Decimal(ui8 precision, ui8 scale) const
-{
- return TDataDecimalType::Create(precision, scale, Env_);
-}
-
+NUdf::TType* TFunctionTypeInfoBuilder::Decimal(ui8 precision, ui8 scale) const
+{
+ return TDataDecimalType::Create(precision, scale, Env_);
+}
+
NUdf::IOptionalTypeBuilder::TPtr TFunctionTypeInfoBuilder::Optional() const
{
return new TOptionalTypeBuilder(*this);
@@ -1621,14 +1621,14 @@ bool TTypeInfoHelper::IsSameType(const NUdf::TType* type1, const NUdf::TType* ty
}
void TTypeInfoHelper::DoData(const NMiniKQL::TDataType* dt, NUdf::ITypeVisitor* v) {
- const auto typeId = dt->GetSchemeType();
+ const auto typeId = dt->GetSchemeType();
v->OnDataType(typeId);
- if (v->IsCompatibleTo(NUdf::MakeAbiCompatibilityVersion(2, 13))) {
- if (NUdf::TDataType<NUdf::TDecimal>::Id == typeId) {
- const auto& params = static_cast<const NMiniKQL::TDataDecimalType*>(dt)->GetParams();
- v->OnDecimal(params.first, params.second);
- }
- }
+ if (v->IsCompatibleTo(NUdf::MakeAbiCompatibilityVersion(2, 13))) {
+ if (NUdf::TDataType<NUdf::TDecimal>::Id == typeId) {
+ const auto& params = static_cast<const NMiniKQL::TDataDecimalType*>(dt)->GetParams();
+ v->OnDecimal(params.first, params.second);
+ }
+ }
}
void TTypeInfoHelper::DoStruct(const NMiniKQL::TStructType* st, NUdf::ITypeVisitor* v) {
@@ -1694,7 +1694,7 @@ void TTypeInfoHelper::DoCallable(const NMiniKQL::TCallableType* ct, NUdf::ITypeV
}
void TTypeInfoHelper::DoVariant(const NMiniKQL::TVariantType* vt, NUdf::ITypeVisitor* v) {
- v->OnVariant(vt->GetUnderlyingType());
+ v->OnVariant(vt->GetUnderlyingType());
}
void TTypeInfoHelper::DoStream(const NMiniKQL::TStreamType* st, NUdf::ITypeVisitor* v) {
diff --git a/ydb/library/yql/minikql/mkql_type_builder.h b/ydb/library/yql/minikql/mkql_type_builder.h
index 800158c606..a93fb41cee 100644
--- a/ydb/library/yql/minikql/mkql_type_builder.h
+++ b/ydb/library/yql/minikql/mkql_type_builder.h
@@ -99,7 +99,7 @@ public:
NUdf::IEquate::TPtr MakeEquate(const NUdf::TType* type) override;
NUdf::ICompare::TPtr MakeCompare(const NUdf::TType* type) override;
- NUdf::TType* Decimal(ui8 precision, ui8 scale) const override;
+ NUdf::TType* Decimal(ui8 precision, ui8 scale) const override;
NUdf::IFunctionTypeInfoBuilder7& IRImplementationImpl(
const NUdf::TStringRef& moduleIR,
diff --git a/ydb/library/yql/minikql/mkql_type_ops.cpp b/ydb/library/yql/minikql/mkql_type_ops.cpp
index 553a505037..d559bb108c 100644
--- a/ydb/library/yql/minikql/mkql_type_ops.cpp
+++ b/ydb/library/yql/minikql/mkql_type_ops.cpp
@@ -1,6 +1,6 @@
#include "mkql_type_ops.h"
-#include "mkql_string_util.h"
-#include "mkql_unboxed_value_stream.h"
+#include "mkql_string_util.h"
+#include "mkql_unboxed_value_stream.h"
#include <ydb/library/yql/minikql/dom/json.h>
#include <ydb/library/yql/minikql/dom/yson.h>
@@ -13,8 +13,8 @@
#include <ydb/library/binary_json/read.h>
#include <ydb/library/dynumber/dynumber.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-
+#include <library/cpp/containers/stack_vector/stack_vec.h>
+
#include <library/cpp/yson/parser.h>
#include <library/cpp/yson/consumer.h>
#include <library/cpp/yson/varint.h>
@@ -33,27 +33,27 @@
#include <util/generic/singleton.h>
#include <util/system/unaligned_mem.h>
#include <array>
-#include <functional>
+#include <functional>
namespace NKikimr {
namespace NMiniKQL {
-using namespace NYql;
+using namespace NYql;
struct TTimezones {
- std::unordered_map<std::string_view, ui16> Name2Id;
- std::vector<std::optional<cctz::time_zone>> Zones;
+ std::unordered_map<std::string_view, ui16> Name2Id;
+ std::vector<std::optional<cctz::time_zone>> Zones;
TTimezones() {
NResource::TResources resList;
const TStringBuf prefix = "/cctz/tzdata/";
NResource::FindMatch(prefix, &resList);
- const auto allTimezones = NUdf::GetTimezones();
- for (ui16 id = 0; id < allTimezones.size(); ++id) {
- const auto& t = allTimezones[id];
- if (!t.empty()) {
- MKQL_ENSURE(Name2Id.emplace(t, id).second, "Duplicated zone: " << t);
- }
+ const auto allTimezones = NUdf::GetTimezones();
+ for (ui16 id = 0; id < allTimezones.size(); ++id) {
+ const auto& t = allTimezones[id];
+ if (!t.empty()) {
+ MKQL_ENSURE(Name2Id.emplace(t, id).second, "Duplicated zone: " << t);
+ }
}
for (const auto& res : resList) {
@@ -61,55 +61,55 @@ struct TTimezones {
MKQL_ENSURE(res.Key.AfterPrefix(prefix, zoneBuf), "Bad resource key: " << res.Key);
}
- Zones.resize(allTimezones.size());
- for (const auto& zone : Name2Id) {
- auto& tz = Zones[zone.second];
- tz.emplace();
- MKQL_ENSURE(cctz::load_time_zone(std::string(zone.first), &*tz), "Failed to load zone: " << zone.first);
+ Zones.resize(allTimezones.size());
+ for (const auto& zone : Name2Id) {
+ auto& tz = Zones[zone.second];
+ tz.emplace();
+ MKQL_ENSURE(cctz::load_time_zone(std::string(zone.first), &*tz), "Failed to load zone: " << zone.first);
}
}
- const cctz::time_zone& GetZone(ui16 tzId) const {
+ const cctz::time_zone& GetZone(ui16 tzId) const {
MKQL_ENSURE(tzId < Zones.size(), "Bad timezone id:" << tzId);
return *Zones[tzId];
}
};
-bool IsValidDecimal(NUdf::TStringRef buf) {
- return NDecimal::IsValid(buf);
-}
+bool IsValidDecimal(NUdf::TStringRef buf) {
+ return NDecimal::IsValid(buf);
+}
-TStringBuf AdaptLegacyYqlType(const TStringBuf& type) {
- if (type == "ByteString") {
- return "String";
- }
+TStringBuf AdaptLegacyYqlType(const TStringBuf& type) {
+ if (type == "ByteString") {
+ return "String";
+ }
- if (type == "Utf8String") {
- return "Utf8";
- }
+ if (type == "Utf8String") {
+ return "Utf8";
+ }
- return type;
-}
+ return type;
+}
-bool IsValidValue(NUdf::EDataSlot type, const NUdf::TUnboxedValuePod& value) {
- switch (type) {
- case NUdf::EDataSlot::Bool:
+bool IsValidValue(NUdf::EDataSlot type, const NUdf::TUnboxedValuePod& value) {
+ switch (type) {
+ case NUdf::EDataSlot::Bool:
case NUdf::EDataSlot::Int8:
case NUdf::EDataSlot::Uint8:
case NUdf::EDataSlot::Int16:
case NUdf::EDataSlot::Uint16:
- case NUdf::EDataSlot::Int32:
- case NUdf::EDataSlot::Uint32:
- case NUdf::EDataSlot::Int64:
- case NUdf::EDataSlot::Uint64:
- case NUdf::EDataSlot::Float:
- case NUdf::EDataSlot::Double:
- case NUdf::EDataSlot::String:
- return bool(value);
-
- case NUdf::EDataSlot::Decimal:
- return bool(value) && !NYql::NDecimal::IsError(value.GetInt128());
-
+ case NUdf::EDataSlot::Int32:
+ case NUdf::EDataSlot::Uint32:
+ case NUdf::EDataSlot::Int64:
+ case NUdf::EDataSlot::Uint64:
+ case NUdf::EDataSlot::Float:
+ case NUdf::EDataSlot::Double:
+ case NUdf::EDataSlot::String:
+ return bool(value);
+
+ case NUdf::EDataSlot::Decimal:
+ return bool(value) && !NYql::NDecimal::IsError(value.GetInt128());
+
case NUdf::EDataSlot::Date:
return bool(value) && value.Get<ui16>() < NUdf::MAX_DATE;
@@ -131,15 +131,15 @@ bool IsValidValue(NUdf::EDataSlot type, const NUdf::TUnboxedValuePod& value) {
case NUdf::EDataSlot::TzTimestamp:
return bool(value) && value.Get<ui64>() < NUdf::MAX_TIMESTAMP && value.GetTimezoneId() < NUdf::GetTimezones().size();
- case NUdf::EDataSlot::Utf8:
- return bool(value) && IsUtf8(value.AsStringRef());
- case NUdf::EDataSlot::Yson:
- return bool(value) && NDom::IsValidYson(value.AsStringRef());
- case NUdf::EDataSlot::Json:
- return bool(value) && NDom::IsValidJson(value.AsStringRef());
+ case NUdf::EDataSlot::Utf8:
+ return bool(value) && IsUtf8(value.AsStringRef());
+ case NUdf::EDataSlot::Yson:
+ return bool(value) && NDom::IsValidYson(value.AsStringRef());
+ case NUdf::EDataSlot::Json:
+ return bool(value) && NDom::IsValidJson(value.AsStringRef());
case NUdf::EDataSlot::Uuid:
return bool(value) && value.AsStringRef().Size() == 16;
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
return NDyNumber::IsValidDyNumber(value.AsStringRef());
case NUdf::EDataSlot::JsonDocument:
return bool(value) && NKikimr::NBinaryJson::IsValidBinaryJson(value.AsStringRef());
@@ -192,14 +192,14 @@ void WriteDate(IOutputStream& out, ui32 year, ui32 month, ui32 day) {
out << year << '-' << LeftPad(month, 2, '0') << '-' << LeftPad(day, 2, '0');
}
-bool WriteDate(IOutputStream& out, ui16 value) {
+bool WriteDate(IOutputStream& out, ui16 value) {
ui32 year, month, day;
if (!SplitDate(value, year, month, day)) {
- return false;
+ return false;
}
WriteDate(out, year, month, day);
- return true;
+ return true;
}
void SplitTime(ui32 value, ui32& hour, ui32& min, ui32& sec) {
@@ -219,19 +219,19 @@ void WriteTime(IOutputStream& out, ui32 time) {
WriteTime(out, hour, min, sec);
}
-bool WriteDatetime(IOutputStream& out, ui32 value) {
+bool WriteDatetime(IOutputStream& out, ui32 value) {
if (value >= NUdf::MAX_DATETIME) {
- return false;
+ return false;
}
- const auto date = value / 86400u;
+ const auto date = value / 86400u;
value -= date * 86400u;
- if (!WriteDate(out, date)) {
- return false;
- }
+ if (!WriteDate(out, date)) {
+ return false;
+ }
out << 'T';
WriteTime(out, value);
- return true;
+ return true;
}
void WriteUs(IOutputStream& out, ui32 value) {
@@ -241,76 +241,76 @@ void WriteUs(IOutputStream& out, ui32 value) {
}
}
-bool WriteTimestamp(IOutputStream& out, ui64 value) {
+bool WriteTimestamp(IOutputStream& out, ui64 value) {
if (value >= NUdf::MAX_TIMESTAMP) {
- return false;
+ return false;
}
- const auto date = value / 86400000000ull;
+ const auto date = value / 86400000000ull;
value -= date * 86400000000ull;
- if (!WriteDate(out, date)) {
- return false;
- }
+ if (!WriteDate(out, date)) {
+ return false;
+ }
out << 'T';
- const auto time = value / 1000000ull;
+ const auto time = value / 1000000ull;
value -= time * 1000000ull;
WriteTime(out, time);
WriteUs(out, value);
- return true;
-}
-
-bool WriteInterval(IOutputStream& out, i64 signedValue) {
- ui64 value = signedValue < 0 ? -signedValue : signedValue;
-
- if (value >= NUdf::MAX_TIMESTAMP) {
- return false;
- }
-
- if (signedValue < 0) {
- out << '-';
- }
-
- const auto days = value / 86400000000ull;
- value -= 86400000000ull * days;
- const auto hours = value / 3600000000ull;
- value -= 3600000000ull * hours;
- const auto minutes = value / 60000000ull;
- value -= 60000000ull * minutes;
- const auto seconds = value / 1000000ull;
- value -= 1000000ull * seconds;
-
- out << 'P';
- if (days) {
- out << days << 'D';
- }
-
- if (!days || hours || minutes || seconds || value) {
- out << 'T';
- if (hours) {
- out << hours << 'H';
- }
-
- if (minutes) {
- out << minutes << 'M';
- }
-
- if (seconds || value || !(days || hours || minutes)) {
- out << seconds;
- if (value) {
- out << '.';
- auto d = 6U;
- while (!(value % 10ull)) {
- value /= 10ull;
- --d;
- }
- out << LeftPad(value, d, '0');
- }
- out << 'S';
- }
- }
- return true;
-}
-
+ return true;
+}
+
+bool WriteInterval(IOutputStream& out, i64 signedValue) {
+ ui64 value = signedValue < 0 ? -signedValue : signedValue;
+
+ if (value >= NUdf::MAX_TIMESTAMP) {
+ return false;
+ }
+
+ if (signedValue < 0) {
+ out << '-';
+ }
+
+ const auto days = value / 86400000000ull;
+ value -= 86400000000ull * days;
+ const auto hours = value / 3600000000ull;
+ value -= 3600000000ull * hours;
+ const auto minutes = value / 60000000ull;
+ value -= 60000000ull * minutes;
+ const auto seconds = value / 1000000ull;
+ value -= 1000000ull * seconds;
+
+ out << 'P';
+ if (days) {
+ out << days << 'D';
+ }
+
+ if (!days || hours || minutes || seconds || value) {
+ out << 'T';
+ if (hours) {
+ out << hours << 'H';
+ }
+
+ if (minutes) {
+ out << minutes << 'M';
+ }
+
+ if (seconds || value || !(days || hours || minutes)) {
+ out << seconds;
+ if (value) {
+ out << '.';
+ auto d = 6U;
+ while (!(value % 10ull)) {
+ value /= 10ull;
+ --d;
+ }
+ out << LeftPad(value, d, '0');
+ }
+ out << 'S';
+ }
+ }
+ return true;
+}
+
static void WriteHexDigit(ui8 digit, IOutputStream& out) {
if (digit <= 9) {
out << char('0' + digit);
@@ -349,8 +349,8 @@ static void UuidToString(ui16 dw[8], IOutputStream& out) {
WriteHex(dw[7], out, true);
}
-}
-
+}
+
void UuidHalfsToByteString(ui64 low, ui64 hi, IOutputStream& out) {
union {
char bytes[16];
@@ -362,226 +362,226 @@ void UuidHalfsToByteString(ui64 low, ui64 hi, IOutputStream& out) {
}
NUdf::TUnboxedValuePod ValueToString(NUdf::EDataSlot type, NUdf::TUnboxedValuePod value) {
- TUnboxedValueStream out;
+ TUnboxedValueStream out;
switch (type) {
case NUdf::EDataSlot::Bool:
- out << (value.Get<bool>() ? "true" : "false");
- break;
+ out << (value.Get<bool>() ? "true" : "false");
+ break;
case NUdf::EDataSlot::Int8:
- out << i16(value.Get<i8>());
- break;
+ out << i16(value.Get<i8>());
+ break;
case NUdf::EDataSlot::Uint8:
- out << ui16(value.Get<ui8>());
- break;
+ out << ui16(value.Get<ui8>());
+ break;
case NUdf::EDataSlot::Int16:
- out << value.Get<i16>();
- break;
+ out << value.Get<i16>();
+ break;
case NUdf::EDataSlot::Uint16:
- out << value.Get<ui16>();
- break;
+ out << value.Get<ui16>();
+ break;
case NUdf::EDataSlot::Int32:
- out << value.Get<i32>();
- break;
+ out << value.Get<i32>();
+ break;
case NUdf::EDataSlot::Uint32:
- out << value.Get<ui32>();
- break;
+ out << value.Get<ui32>();
+ break;
case NUdf::EDataSlot::Int64:
- out << value.Get<i64>();
- break;
+ out << value.Get<i64>();
+ break;
case NUdf::EDataSlot::Uint64:
- out << value.Get<ui64>();
- break;
+ out << value.Get<ui64>();
+ break;
case NUdf::EDataSlot::Float:
out << ::FloatToString(value.Get<float>());
- break;
+ break;
case NUdf::EDataSlot::Double:
out << ::FloatToString(value.Get<double>());
- break;
+ break;
case NUdf::EDataSlot::String:
case NUdf::EDataSlot::Utf8:
case NUdf::EDataSlot::Yson:
case NUdf::EDataSlot::Json:
- return value;
+ return value;
case NUdf::EDataSlot::Uuid: {
ui16 dw[8];
- std::memcpy(dw, value.AsStringRef().Data(), sizeof(dw));
+ std::memcpy(dw, value.AsStringRef().Data(), sizeof(dw));
UuidToString(dw, out);
- break;
+ break;
}
- case NUdf::EDataSlot::Date:
- if (!WriteDate(out, value.Get<ui16>())) {
- return NUdf::TUnboxedValuePod();
+ case NUdf::EDataSlot::Date:
+ if (!WriteDate(out, value.Get<ui16>())) {
+ return NUdf::TUnboxedValuePod();
}
- break;
+ break;
- case NUdf::EDataSlot::Datetime:
- if (!WriteDatetime(out, value.Get<ui32>())) {
- return NUdf::TUnboxedValuePod();
+ case NUdf::EDataSlot::Datetime:
+ if (!WriteDatetime(out, value.Get<ui32>())) {
+ return NUdf::TUnboxedValuePod();
}
- out << 'Z';
- break;
+ out << 'Z';
+ break;
- case NUdf::EDataSlot::Timestamp:
- if (!WriteTimestamp(out, value.Get<ui64>())) {
- return NUdf::TUnboxedValuePod();
+ case NUdf::EDataSlot::Timestamp:
+ if (!WriteTimestamp(out, value.Get<ui64>())) {
+ return NUdf::TUnboxedValuePod();
}
- out << 'Z';
- break;
+ out << 'Z';
+ break;
- case NUdf::EDataSlot::Interval:
- if (!WriteInterval(out, value.Get<i64>())) {
- return NUdf::TUnboxedValuePod();
+ case NUdf::EDataSlot::Interval:
+ if (!WriteInterval(out, value.Get<i64>())) {
+ return NUdf::TUnboxedValuePod();
}
- break;
+ break;
- case NUdf::EDataSlot::TzDate: {
- const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
+ case NUdf::EDataSlot::TzDate: {
+ const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
const ui32 seconds = 86400u * value.Get<ui16>() + (86400u - 1u);
- const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
- WriteDate(out, converted.year(), converted.month(), converted.day());
- out << ',' << tz.name();
- break;
- }
-
- case NUdf::EDataSlot::TzDatetime: {
- const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
- const ui32 seconds = value.Get<ui32>();
- const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
- WriteDate(out, converted.year(), converted.month(), converted.day());
+ const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
+ WriteDate(out, converted.year(), converted.month(), converted.day());
+ out << ',' << tz.name();
+ break;
+ }
+
+ case NUdf::EDataSlot::TzDatetime: {
+ const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
+ const ui32 seconds = value.Get<ui32>();
+ const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
+ WriteDate(out, converted.year(), converted.month(), converted.day());
out << 'T';
- WriteTime(out, converted.hour(), converted.minute(), converted.second());
- out << ',' << tz.name();
- break;
- }
-
- case NUdf::EDataSlot::TzTimestamp: {
- const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
- const ui32 seconds = ui32(value.Get<ui64>() / 1000000u);
- const ui32 frac = ui32(value.Get<ui64>() % 1000000u);
- const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
- WriteDate(out, converted.year(), converted.month(), converted.day());
- out << 'T';
- WriteTime(out, converted.hour(), converted.minute(), converted.second());
- WriteUs(out, frac);
- out << ',' << tz.name();
- break;
- }
-
- case NUdf::EDataSlot::DyNumber: {
+ WriteTime(out, converted.hour(), converted.minute(), converted.second());
+ out << ',' << tz.name();
+ break;
+ }
+
+ case NUdf::EDataSlot::TzTimestamp: {
+ const auto& tz = Singleton<TTimezones>()->GetZone(value.GetTimezoneId());
+ const ui32 seconds = ui32(value.Get<ui64>() / 1000000u);
+ const ui32 frac = ui32(value.Get<ui64>() % 1000000u);
+ const auto converted = cctz::convert(std::chrono::system_clock::from_time_t(seconds), tz);
+ WriteDate(out, converted.year(), converted.month(), converted.day());
+ out << 'T';
+ WriteTime(out, converted.hour(), converted.minute(), converted.second());
+ WriteUs(out, frac);
+ out << ',' << tz.name();
+ break;
+ }
+
+ case NUdf::EDataSlot::DyNumber: {
out << NDyNumber::DyNumberToString(value.AsStringRef());
- break;
- }
-
+ break;
+ }
+
case NUdf::EDataSlot::JsonDocument: {
out << NKikimr::NBinaryJson::SerializeToJson(value.AsStringRef());
break;
}
- case NUdf::EDataSlot::Decimal:
- default:
- THROW yexception() << "Incorrect data slot: " << (ui32)type;
+ case NUdf::EDataSlot::Decimal:
+ default:
+ THROW yexception() << "Incorrect data slot: " << (ui32)type;
+ }
+
+ return out.Value();
+}
+
+template <typename T>
+bool IsValidNumberString(NUdf::TStringRef buf);
+
+template <>
+bool IsValidNumberString<float>(NUdf::TStringRef buf) {
+ float value;
+ return NYql::TryFloatFromString(buf, value);
+}
+
+template <>
+bool IsValidNumberString<double>(NUdf::TStringRef buf) {
+ double value;
+ return NYql::TryDoubleFromString(buf, value);
+}
+
+template <>
+bool IsValidNumberString<i8>(NUdf::TStringRef buf) {
+ i16 value;
+ return TryFromString(buf.Data(), buf.Size(), value) && value < 128 && value > -129;
+}
+
+template <>
+bool IsValidNumberString<ui8>(NUdf::TStringRef buf) {
+ ui16 value;
+ return TryFromString(buf, value) && value < 256;
+}
+
+template <typename T>
+bool IsValidNumberString(NUdf::TStringRef buf) {
+ T value;
+ return TryFromString(buf.Data(), buf.Size(), value);
+}
+
+template <typename T>
+NUdf::TUnboxedValuePod NumberFromString(NUdf::TStringRef buf);
+
+template <>
+NUdf::TUnboxedValuePod NumberFromString<i8>(NUdf::TStringRef buf) {
+ i16 value;
+ if (!TryFromString(buf.Data(), buf.Size(), value) || value > 127 || value < -128) {
+ return NUdf::TUnboxedValuePod();
+ }
+ return NUdf::TUnboxedValuePod(i8(value));
+}
+
+template <>
+NUdf::TUnboxedValuePod NumberFromString<ui8>(NUdf::TStringRef buf) {
+ ui16 value;
+ if (!TryFromString(buf.Data(), buf.Size(), value) || value > 255) {
+ return NUdf::TUnboxedValuePod();
+ }
+ return NUdf::TUnboxedValuePod(ui8(value));
+}
+
+template <>
+NUdf::TUnboxedValuePod NumberFromString<float>(NUdf::TStringRef buf) {
+ float value;
+ if (!NYql::TryFloatFromString((TStringBuf)buf, value)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(value);
+}
+
+template <>
+NUdf::TUnboxedValuePod NumberFromString<double>(NUdf::TStringRef buf) {
+ double value;
+ if (!NYql::TryDoubleFromString((TStringBuf)buf, value)) {
+ return NUdf::TUnboxedValuePod();
}
- return out.Value();
+ return NUdf::TUnboxedValuePod(value);
}
template <typename T>
-bool IsValidNumberString(NUdf::TStringRef buf);
-
-template <>
-bool IsValidNumberString<float>(NUdf::TStringRef buf) {
- float value;
- return NYql::TryFloatFromString(buf, value);
-}
-
-template <>
-bool IsValidNumberString<double>(NUdf::TStringRef buf) {
- double value;
- return NYql::TryDoubleFromString(buf, value);
-}
-
-template <>
-bool IsValidNumberString<i8>(NUdf::TStringRef buf) {
- i16 value;
- return TryFromString(buf.Data(), buf.Size(), value) && value < 128 && value > -129;
-}
-
-template <>
-bool IsValidNumberString<ui8>(NUdf::TStringRef buf) {
- ui16 value;
- return TryFromString(buf, value) && value < 256;
-}
-
-template <typename T>
-bool IsValidNumberString(NUdf::TStringRef buf) {
- T value;
- return TryFromString(buf.Data(), buf.Size(), value);
-}
-
-template <typename T>
-NUdf::TUnboxedValuePod NumberFromString(NUdf::TStringRef buf);
-
-template <>
-NUdf::TUnboxedValuePod NumberFromString<i8>(NUdf::TStringRef buf) {
- i16 value;
- if (!TryFromString(buf.Data(), buf.Size(), value) || value > 127 || value < -128) {
- return NUdf::TUnboxedValuePod();
- }
- return NUdf::TUnboxedValuePod(i8(value));
-}
-
-template <>
-NUdf::TUnboxedValuePod NumberFromString<ui8>(NUdf::TStringRef buf) {
- ui16 value;
- if (!TryFromString(buf.Data(), buf.Size(), value) || value > 255) {
- return NUdf::TUnboxedValuePod();
- }
- return NUdf::TUnboxedValuePod(ui8(value));
-}
-
-template <>
-NUdf::TUnboxedValuePod NumberFromString<float>(NUdf::TStringRef buf) {
- float value;
- if (!NYql::TryFloatFromString((TStringBuf)buf, value)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
-template <>
-NUdf::TUnboxedValuePod NumberFromString<double>(NUdf::TStringRef buf) {
- double value;
- if (!NYql::TryDoubleFromString((TStringBuf)buf, value)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
-template <typename T>
-NUdf::TUnboxedValuePod NumberFromString(NUdf::TStringRef buf) {
- T value;
- if (!TryFromString(buf.Data(), buf.Size(), value)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
+NUdf::TUnboxedValuePod NumberFromString(NUdf::TStringRef buf) {
+ T value;
+ if (!TryFromString(buf.Data(), buf.Size(), value)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(value);
+}
+
bool MakeDateUncached(ui32 year, ui32 month, ui32 day, ui16& value) {
if (year < NUdf::MIN_YEAR || year >= NUdf::MAX_YEAR) {
return false;
@@ -619,12 +619,12 @@ bool MakeTime(ui32 hour, ui32 minute, ui32 second, ui32& value) {
}
bool SplitDateUncached(ui16 value, ui32& year, ui32& month, ui32& day) {
- if (!value) {
- year = NUdf::MIN_YEAR - 1;
- month = 12;
- day = 31;
- return true;
- } else if (--value > NUdf::MAX_DATE) {
+ if (!value) {
+ year = NUdf::MIN_YEAR - 1;
+ month = 12;
+ day = 31;
+ return true;
+ } else if (--value > NUdf::MAX_DATE) {
return false;
}
@@ -660,20 +660,20 @@ bool SplitDateUncached(ui16 value, ui32& year, ui32& month, ui32& day) {
return true;
}
-namespace {
-
+namespace {
+
class TDateTable {
public:
TDateTable() {
- ui32 prevYear = NUdf::MIN_YEAR - 1;
+ ui32 prevYear = NUdf::MIN_YEAR - 1;
YearsOffsets_[0] = 0;
- ui32 dayOfYear = 365;
- ui32 dayOfWeek = 2;
- ui32 weekOfYear = 52;
+ ui32 dayOfYear = 365;
+ ui32 dayOfWeek = 2;
+ ui32 weekOfYear = 52;
ui32 weekOfYearIso8601 = 1;
- for (ui16 date = 0; date < Days_.size(); ++date) {
+ for (ui16 date = 0; date < Days_.size(); ++date) {
ui32 year, month, day;
Y_VERIFY(SplitDateUncached(date, year, month, day));
@@ -700,36 +700,36 @@ public:
}
bool SplitDate(ui16 value, ui32& year, ui32& month, ui32& day) const {
- if (Y_UNLIKELY(++value >= Days_.size())) {
+ if (Y_UNLIKELY(++value >= Days_.size())) {
return false;
}
- year = NUdf::MIN_YEAR + std::distance(YearsOffsets_.cbegin(), std::upper_bound(YearsOffsets_.cbegin(), YearsOffsets_.cend(), value)) - 1;
+ year = NUdf::MIN_YEAR + std::distance(YearsOffsets_.cbegin(), std::upper_bound(YearsOffsets_.cbegin(), YearsOffsets_.cend(), value)) - 1;
auto& info = Days_[value];
month = info.Month;
day = info.Day;
return true;
}
- bool GetDateOffset(ui32 year, ui32 month, ui32 day, ui16& value) const {
- if (Y_UNLIKELY(year < NUdf::MIN_YEAR - 1U || year > NUdf::MAX_YEAR
- || (year == NUdf::MAX_YEAR && (day > 1U || month > 1U))
- || (year == NUdf::MIN_YEAR - 1U && (day < 31U || month < 12U)))) {
+ bool GetDateOffset(ui32 year, ui32 month, ui32 day, ui16& value) const {
+ if (Y_UNLIKELY(year < NUdf::MIN_YEAR - 1U || year > NUdf::MAX_YEAR
+ || (year == NUdf::MAX_YEAR && (day > 1U || month > 1U))
+ || (year == NUdf::MIN_YEAR - 1U && (day < 31U || month < 12U)))) {
return false;
}
- if (Y_UNLIKELY(year == NUdf::MIN_YEAR - 1U && day == 31U && month == 12U)) {
- value = 0;
- return true;
- }
-
- const auto ptr = YearsOffsets_.data() + year - NUdf::MIN_YEAR;
- const auto begin = Days_.cbegin() + ptr[0];
- const auto end = year == NUdf::MAX_YEAR ? Days_.cend() : Days_.cbegin() + ptr[1];
+ if (Y_UNLIKELY(year == NUdf::MIN_YEAR - 1U && day == 31U && month == 12U)) {
+ value = 0;
+ return true;
+ }
+
+ const auto ptr = YearsOffsets_.data() + year - NUdf::MIN_YEAR;
+ const auto begin = Days_.cbegin() + ptr[0];
+ const auto end = year == NUdf::MAX_YEAR ? Days_.cend() : Days_.cbegin() + ptr[1];
// search valid month/day in this year
- const auto target = PackMonthDay(month, day);
- const auto it = std::lower_bound(begin, end, target, [](const TDayInfo& info, ui16 y) {
+ const auto target = PackMonthDay(month, day);
+ const auto it = std::lower_bound(begin, end, target, [](const TDayInfo& info, ui16 y) {
return PackMonthDay(info.Month, info.Day) < y;
});
@@ -737,26 +737,26 @@ public:
return false;
}
- value = std::distance(Days_.cbegin(), it);
+ value = std::distance(Days_.cbegin(), it);
+ return true;
+ }
+
+ bool MakeDate(ui32 year, ui32 month, ui32 day, ui16& value) const {
+ if (Y_UNLIKELY(year < NUdf::MIN_YEAR || year > NUdf::MAX_YEAR
+ || (year == NUdf::MAX_YEAR && (day > 1U || month > 1U)))) {
+ return false;
+ }
+
+ if (Y_LIKELY(GetDateOffset(year, month, day, value) && value))
+ --value;
+ else
+ return false;
+
return true;
}
- bool MakeDate(ui32 year, ui32 month, ui32 day, ui16& value) const {
- if (Y_UNLIKELY(year < NUdf::MIN_YEAR || year > NUdf::MAX_YEAR
- || (year == NUdf::MAX_YEAR && (day > 1U || month > 1U)))) {
- return false;
- }
-
- if (Y_LIKELY(GetDateOffset(year, month, day, value) && value))
- --value;
- else
- return false;
-
- return true;
- }
-
bool EnrichByOffset(ui16 value, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek) const {
- if (Y_UNLIKELY(value >= Days_.size())) {
+ if (Y_UNLIKELY(value >= Days_.size())) {
return false;
}
@@ -770,8 +770,8 @@ public:
bool EnrichDate(ui16 value, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek) const {
return EnrichByOffset(++value, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek);
- }
-
+ }
+
static const TDateTable& Instance() {
return *HugeSingleton<TDateTable>();
}
@@ -791,11 +791,11 @@ private:
};
std::array<ui16, NUdf::MAX_YEAR - NUdf::MIN_YEAR + 1> YearsOffsets_; // start of linear date for each year
- std::array<TDayInfo, NUdf::MAX_DATE + 2> Days_; // packed info for each date
+ std::array<TDayInfo, NUdf::MAX_DATE + 2> Days_; // packed info for each date
};
-}
-
+}
+
bool SplitDate(ui16 value, ui32& year, ui32& month, ui32& day) {
return TDateTable::Instance().SplitDate(value, year, month, day);
}
@@ -892,43 +892,43 @@ bool SplitTzDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour,
}
bool SplitTzDate(ui16 value, ui32& year, ui32& month, ui32& day, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId) {
- if (tzId) {
- if (value >= NUdf::MAX_DATE) {
- return false;
- }
-
- ui32 hour, min, sec;
- ToLocalTime(86400u * ++value - 1u, tzId, year, month, day, hour, min, sec);
- if (!TDateTable::Instance().GetDateOffset(year, month, day, value)) {
- return false;
- }
- } else if (SplitDate(value, year, month, day)) {
- ++value;
- } else {
- return false;
- }
+ if (tzId) {
+ if (value >= NUdf::MAX_DATE) {
+ return false;
+ }
+
+ ui32 hour, min, sec;
+ ToLocalTime(86400u * ++value - 1u, tzId, year, month, day, hour, min, sec);
+ if (!TDateTable::Instance().GetDateOffset(year, month, day, value)) {
+ return false;
+ }
+ } else if (SplitDate(value, year, month, day)) {
+ ++value;
+ } else {
+ return false;
+ }
return TDateTable::Instance().EnrichByOffset(value, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek);
-}
-
+}
+
bool SplitTzDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& min, ui32& sec, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId) {
- ui16 offset;
- if (tzId) {
- if (value >= NUdf::MAX_DATETIME) {
- return false;
- }
- ToLocalTime(value, tzId, year, month, day, hour, min, sec);
- if (!TDateTable::Instance().GetDateOffset(year, month, day, offset)) {
- return false;
- }
- } else if (SplitDatetime(value, year, month, day, hour, min, sec)) {
- offset = value / 86400u + 1u;
- } else {
- return false;
- }
-
+ ui16 offset;
+ if (tzId) {
+ if (value >= NUdf::MAX_DATETIME) {
+ return false;
+ }
+ ToLocalTime(value, tzId, year, month, day, hour, min, sec);
+ if (!TDateTable::Instance().GetDateOffset(year, month, day, offset)) {
+ return false;
+ }
+ } else if (SplitDatetime(value, year, month, day, hour, min, sec)) {
+ offset = value / 86400u + 1u;
+ } else {
+ return false;
+ }
+
return TDateTable::Instance().EnrichByOffset(offset, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek);
-}
-
+}
+
bool EnrichDate(ui16 date, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek) {
return TDateTable::Instance().EnrichDate(date, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek);
}
@@ -1014,718 +1014,718 @@ static bool GetDigit(char c, ui32& digit) {
return true;
}
-bool IsValidUuid(NUdf::TStringRef buf) {
- if (buf.Size() != 36) {
- return false;
- }
-
- for (size_t i = 0; i < buf.Size(); ++i) {
- const char c = buf.Data()[i];
-
- if (c == '-') {
- if (i != 8 && i != 13 && i != 18 && i != 23) {
- return false;
- }
- } else if (!std::isxdigit(c)) {
- return false;
- }
- }
-
- return true;
-}
-
+bool IsValidUuid(NUdf::TStringRef buf) {
+ if (buf.Size() != 36) {
+ return false;
+ }
+
+ for (size_t i = 0; i < buf.Size(); ++i) {
+ const char c = buf.Data()[i];
+
+ if (c == '-') {
+ if (i != 8 && i != 13 && i != 18 && i != 23) {
+ return false;
+ }
+ } else if (!std::isxdigit(c)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool ParseUuidToArray(NUdf::TStringRef buf, ui16* dw, bool shortForm) {
if (buf.Size() != (shortForm ? 32 : 36)) {
return false;
- }
-
- size_t partId = 0;
- ui64 partValue = 0;
- size_t digitCount = 0;
-
- for (size_t i = 0; i < buf.Size(); ++i) {
- const char c = buf.Data()[i];
-
+ }
+
+ size_t partId = 0;
+ ui64 partValue = 0;
+ size_t digitCount = 0;
+
+ for (size_t i = 0; i < buf.Size(); ++i) {
+ const char c = buf.Data()[i];
+
if (!shortForm && (i == 8 || i == 13 || i == 18 || i == 23)) {
if (c == '-') {
continue;
} else {
return false;
- }
- }
-
- ui32 digit = 0;
- if (!GetDigit(c, digit)) {
+ }
+ }
+
+ ui32 digit = 0;
+ if (!GetDigit(c, digit)) {
return false;
- }
-
- partValue = partValue * 16 + digit;
-
- if (++digitCount == 4) {
- dw[partId++] = partValue;
- digitCount = 0;
- }
- }
-
- std::swap(dw[0], dw[1]);
- for (ui32 i = 4; i < 8; ++i) {
- dw[i] = ((dw[i] >> 8) & 0xff) | ((dw[i] & 0xff) << 8);
- }
-
+ }
+
+ partValue = partValue * 16 + digit;
+
+ if (++digitCount == 4) {
+ dw[partId++] = partValue;
+ digitCount = 0;
+ }
+ }
+
+ std::swap(dw[0], dw[1]);
+ for (ui32 i = 4; i < 8; ++i) {
+ dw[i] = ((dw[i] >> 8) & 0xff) | ((dw[i] & 0xff) << 8);
+ }
+
return true;
-}
-
+}
+
NUdf::TUnboxedValuePod ParseUuid(NUdf::TStringRef buf, bool shortForm) {
- ui16 dw[8];
+ ui16 dw[8];
if (!ParseUuidToArray(buf, dw, shortForm)) {
return NUdf::TUnboxedValuePod();
- }
-
+ }
+
return MakeString(NUdf::TStringRef(reinterpret_cast<char*>(dw), sizeof(dw)));
}
-
+
bool ParseUuid(NUdf::TStringRef buf, void* out, bool shortForm) {
ui16 dw[8];
-
+
if (!ParseUuidToArray(buf, dw, shortForm)) {
return false;
- }
-
- if (out) {
- std::memcpy(out, dw, sizeof(dw));
- }
- return true;
-}
-
-NUdf::TUnboxedValuePod ParseDate(NUdf::TStringRef buf) {
- ui32 year, month, day;
- ui32 pos = 0;
- if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, day) || pos != buf.Size()) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui16 value;
- if (!MakeDate(year, month, day, value)) {
- return NUdf::TUnboxedValuePod();
- }
-
- if (value >= NUdf::MAX_DATE) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
+ }
+
+ if (out) {
+ std::memcpy(out, dw, sizeof(dw));
+ }
+ return true;
+}
+
+NUdf::TUnboxedValuePod ParseDate(NUdf::TStringRef buf) {
+ ui32 year, month, day;
+ ui32 pos = 0;
+ if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, day) || pos != buf.Size()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui16 value;
+ if (!MakeDate(year, month, day, value)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ if (value >= NUdf::MAX_DATE) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(value);
+}
+
NUdf::TUnboxedValuePod ParseTzDate(NUdf::TStringRef str) {
- TStringBuf full = str;
- TStringBuf buf;
- GetNext(full, ',', buf);
- const auto tzId = FindTimezoneId(full);
- if (!tzId) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 year, month, day;
- ui32 pos = 0;
+ TStringBuf full = str;
+ TStringBuf buf;
+ GetNext(full, ',', buf);
+ const auto tzId = FindTimezoneId(full);
+ if (!tzId) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 year, month, day;
+ ui32 pos = 0;
if (!ParseNumber(pos, buf, year) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, month) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, day) || pos != buf.size()) {
- return NUdf::TUnboxedValuePod();
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+
ui32 absoluteSeconds;
if (!FromLocalTimeValidated(*tzId, year, month, day, 0, 0, 0, absoluteSeconds)) {
- return NUdf::TUnboxedValuePod();
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+
ui16 value = absoluteSeconds / 86400u;
- NUdf::TUnboxedValuePod out(value);
- out.SetTimezoneId(*tzId);
- return out;
-}
-
-NUdf::TUnboxedValuePod ParseDatetime(NUdf::TStringRef buf) {
- ui32 year, month, day;
- ui32 pos = 0;
- if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, day) || pos == buf.Size() || buf.Data()[pos] != 'T') {
- return NUdf::TUnboxedValuePod();
- }
-
- ui16 dateValue;
- if (!MakeDate(year, month, day, dateValue)) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 hour, minute, second;
- // skip 'T'
- ++pos;
- if (!ParseNumber(pos, buf, hour) || pos == buf.Size() || buf.Data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
- if (!ParseNumber(pos, buf, minute) || pos == buf.Size() || buf.Data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
- if (!ParseNumber(pos, buf, second) || pos == buf.Size() || buf.Data()[pos] != 'Z') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip 'Z'
- ++pos;
- if (pos != buf.Size()) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 timeValue;
- if (!MakeTime(hour, minute, second, timeValue)) {
- return NUdf::TUnboxedValuePod();
- }
-
+ NUdf::TUnboxedValuePod out(value);
+ out.SetTimezoneId(*tzId);
+ return out;
+}
+
+NUdf::TUnboxedValuePod ParseDatetime(NUdf::TStringRef buf) {
+ ui32 year, month, day;
+ ui32 pos = 0;
+ if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, day) || pos == buf.Size() || buf.Data()[pos] != 'T') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui16 dateValue;
+ if (!MakeDate(year, month, day, dateValue)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 hour, minute, second;
+ // skip 'T'
+ ++pos;
+ if (!ParseNumber(pos, buf, hour) || pos == buf.Size() || buf.Data()[pos] != ':') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
+ if (!ParseNumber(pos, buf, minute) || pos == buf.Size() || buf.Data()[pos] != ':') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
+ if (!ParseNumber(pos, buf, second) || pos == buf.Size() || buf.Data()[pos] != 'Z') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip 'Z'
+ ++pos;
+ if (pos != buf.Size()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 timeValue;
+ if (!MakeTime(hour, minute, second, timeValue)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
ui32 value = dateValue * 86400u + timeValue;
- if (value >= NUdf::MAX_DATETIME) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
-NUdf::TUnboxedValuePod ParseTzDatetime(NUdf::TStringRef str) {
- TStringBuf full = str;
- TStringBuf buf;
- GetNext(full, ',', buf);
- const auto tzId = FindTimezoneId(full);
- if (!tzId) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 year, month, day;
- ui32 pos = 0;
+ if (value >= NUdf::MAX_DATETIME) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(value);
+}
+
+NUdf::TUnboxedValuePod ParseTzDatetime(NUdf::TStringRef str) {
+ TStringBuf full = str;
+ TStringBuf buf;
+ GetNext(full, ',', buf);
+ const auto tzId = FindTimezoneId(full);
+ if (!tzId) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 year, month, day;
+ ui32 pos = 0;
if (!ParseNumber(pos, buf, year) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, month) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, day) || pos == buf.size() || buf.data()[pos] != 'T') {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 hour, minute, second;
- // skip 'T'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 hour, minute, second;
+ // skip 'T'
+ ++pos;
if (!ParseNumber(pos, buf, hour) || pos == buf.size() || buf.data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
if (!ParseNumber(pos, buf, minute) || pos == buf.size() || buf.data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
if (!ParseNumber(pos, buf, second) || pos != buf.size()) {
- return NUdf::TUnboxedValuePod();
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+
ui32 absoluteSeconds;
if (!FromLocalTimeValidated(*tzId, year, month, day, hour, minute, second, absoluteSeconds)) {
- return NUdf::TUnboxedValuePod();
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+
ui32 value = absoluteSeconds;
- NUdf::TUnboxedValuePod out(value);
- out.SetTimezoneId(*tzId);
- return out;
-}
-
-NUdf::TUnboxedValuePod ParseTimestamp(NUdf::TStringRef buf) {
- ui32 year, month, day;
- ui32 pos = 0;
- if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
- if (!ParseNumber(pos, buf, day) || pos == buf.Size() || buf.Data()[pos] != 'T') {
- return NUdf::TUnboxedValuePod();
- }
-
- ui16 dateValue;
- if (!MakeDate(year, month, day, dateValue)) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 hour, minute, second;
- // skip 'T'
- ++pos;
- if (!ParseNumber(pos, buf, hour) || pos == buf.Size() || buf.Data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
- if (!ParseNumber(pos, buf, minute) || pos == buf.Size() || buf.Data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
- if (!ParseNumber(pos, buf, second) || pos == buf.Size()) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 microseconds = 0;
- if (buf.Data()[pos] != 'Z') {
- if (buf.Data()[pos] != '.') {
- return NUdf::TUnboxedValuePod();
- }
-
- ++pos;
- ui32 prevPos = pos;
- if (!ParseNumber(pos, buf, microseconds)) {
- return NUdf::TUnboxedValuePod();
- }
-
- prevPos = pos - prevPos;
- if (prevPos > 6) {
- return NUdf::TUnboxedValuePod();
- }
-
- while (prevPos < 6) {
- microseconds *= 10;
- ++prevPos;
- }
-
- if (pos == buf.Size() || buf.Data()[pos] != 'Z') {
- return NUdf::TUnboxedValuePod();
- }
- }
-
- // skip 'Z'
- ++pos;
- if (pos != buf.Size()) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 timeValue;
- if (!MakeTime(hour, minute, second, timeValue)) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui64 value = dateValue * 86400000000ull + timeValue * 1000000ull + microseconds;
- if (value >= NUdf::MAX_TIMESTAMP) {
- return NUdf::TUnboxedValuePod();
- }
-
- return NUdf::TUnboxedValuePod(value);
-}
-
-NUdf::TUnboxedValuePod ParseTzTimestamp(NUdf::TStringRef str) {
- TStringBuf full = str;
- TStringBuf buf;
- GetNext(full, ',', buf);
- const auto tzId = FindTimezoneId(full);
- if (!tzId) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 year, month, day;
- ui32 pos = 0;
+ NUdf::TUnboxedValuePod out(value);
+ out.SetTimezoneId(*tzId);
+ return out;
+}
+
+NUdf::TUnboxedValuePod ParseTimestamp(NUdf::TStringRef buf) {
+ ui32 year, month, day;
+ ui32 pos = 0;
+ if (!ParseNumber(pos, buf, year) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, month) || pos == buf.Size() || buf.Data()[pos] != '-') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
+ if (!ParseNumber(pos, buf, day) || pos == buf.Size() || buf.Data()[pos] != 'T') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui16 dateValue;
+ if (!MakeDate(year, month, day, dateValue)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 hour, minute, second;
+ // skip 'T'
+ ++pos;
+ if (!ParseNumber(pos, buf, hour) || pos == buf.Size() || buf.Data()[pos] != ':') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
+ if (!ParseNumber(pos, buf, minute) || pos == buf.Size() || buf.Data()[pos] != ':') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
+ if (!ParseNumber(pos, buf, second) || pos == buf.Size()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 microseconds = 0;
+ if (buf.Data()[pos] != 'Z') {
+ if (buf.Data()[pos] != '.') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ++pos;
+ ui32 prevPos = pos;
+ if (!ParseNumber(pos, buf, microseconds)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ prevPos = pos - prevPos;
+ if (prevPos > 6) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ while (prevPos < 6) {
+ microseconds *= 10;
+ ++prevPos;
+ }
+
+ if (pos == buf.Size() || buf.Data()[pos] != 'Z') {
+ return NUdf::TUnboxedValuePod();
+ }
+ }
+
+ // skip 'Z'
+ ++pos;
+ if (pos != buf.Size()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 timeValue;
+ if (!MakeTime(hour, minute, second, timeValue)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui64 value = dateValue * 86400000000ull + timeValue * 1000000ull + microseconds;
+ if (value >= NUdf::MAX_TIMESTAMP) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return NUdf::TUnboxedValuePod(value);
+}
+
+NUdf::TUnboxedValuePod ParseTzTimestamp(NUdf::TStringRef str) {
+ TStringBuf full = str;
+ TStringBuf buf;
+ GetNext(full, ',', buf);
+ const auto tzId = FindTimezoneId(full);
+ if (!tzId) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 year, month, day;
+ ui32 pos = 0;
if (!ParseNumber(pos, buf, year) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, month) || pos == buf.size() || buf.data()[pos] != '-') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip '-'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip '-'
+ ++pos;
if (!ParseNumber(pos, buf, day) || pos == buf.size() || buf.data()[pos] != 'T') {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 hour, minute, second;
- // skip 'T'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 hour, minute, second;
+ // skip 'T'
+ ++pos;
if (!ParseNumber(pos, buf, hour) || pos == buf.size() || buf.data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
if (!ParseNumber(pos, buf, minute) || pos == buf.size() || buf.data()[pos] != ':') {
- return NUdf::TUnboxedValuePod();
- }
-
- // skip ':'
- ++pos;
- if (!ParseNumber(pos, buf, second)) {
- return NUdf::TUnboxedValuePod();
- }
-
- ui32 microseconds = 0;
+ return NUdf::TUnboxedValuePod();
+ }
+
+ // skip ':'
+ ++pos;
+ if (!ParseNumber(pos, buf, second)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ui32 microseconds = 0;
if (pos != buf.size()) {
if (buf.data()[pos] != '.') {
- return NUdf::TUnboxedValuePod();
- }
-
- ++pos;
- ui32 prevPos = pos;
- if (!ParseNumber(pos, buf, microseconds)) {
- return NUdf::TUnboxedValuePod();
- }
-
- prevPos = pos - prevPos;
- if (prevPos > 6) {
- return NUdf::TUnboxedValuePod();
- }
-
- while (prevPos < 6) {
- microseconds *= 10;
- ++prevPos;
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+
+ ++pos;
+ ui32 prevPos = pos;
+ if (!ParseNumber(pos, buf, microseconds)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ prevPos = pos - prevPos;
+ if (prevPos > 6) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ while (prevPos < 6) {
+ microseconds *= 10;
+ ++prevPos;
+ }
+
if (pos != buf.size()) {
- return NUdf::TUnboxedValuePod();
- }
- }
-
+ return NUdf::TUnboxedValuePod();
+ }
+ }
+
ui32 absoluteSeconds;
if (!FromLocalTimeValidated(*tzId, year, month, day, hour, minute, second, absoluteSeconds)) {
- return NUdf::TUnboxedValuePod();
- }
-
- const ui64 value = absoluteSeconds * 1000000ull + microseconds;
- NUdf::TUnboxedValuePod out(value);
- out.SetTimezoneId(*tzId);
- return out;
-}
-
-template <bool DecimalPart = false>
-bool ParseNumber(std::string_view::const_iterator& pos, const std::string_view& buf, ui32& value) {
- value = 0U;
-
- if (buf.cend() == pos || !std::isdigit(*pos)) {
- return false;
- }
-
- auto digits = 6U;
- do {
- value *= 10U;
- value += *pos - '0';
- if (buf.cend() == ++pos || !digits--) {
- return false;
- }
- } while (std::isdigit(*pos));
- if (DecimalPart) {
- while (digits--) {
- value *= 10U;
- }
- }
- return true;
-}
-
-NUdf::TUnboxedValuePod ParseInterval(const std::string_view& buf) {
- if (buf.empty()) {
- return NUdf::TUnboxedValuePod();
- }
-
- auto pos = buf.cbegin();
- bool isSigned = *pos == '-';
- if (isSigned || *pos == '+') {
- ++pos;
- }
-
- if (buf.cend() == pos || *pos++ != 'P' || buf.cend() == pos) {
- return NUdf::TUnboxedValuePod();
- }
-
- std::optional<ui32> days, hours, minutes, seconds, microseconds;
- ui32 num;
-
- if (*pos != 'T') {
- if (!ParseNumber(pos, buf, num)) {
- return NUdf::TUnboxedValuePod();
- }
-
- switch (*pos++) {
- case 'D': days = num; break;
- case 'W': days = 7U * num; break;
- default: return NUdf::TUnboxedValuePod();
- }
- }
-
- if (buf.cend() != pos) {
- if (*pos++ != 'T') {
- return NUdf::TUnboxedValuePod();
- }
-
- if (buf.cend() != pos) // TODO: Remove this line later.
- do {
- if (!ParseNumber(pos, buf, num)) {
- return NUdf::TUnboxedValuePod();
- }
-
- switch (*pos++) {
- case 'H':
- if (hours || minutes || seconds) {
- return NUdf::TUnboxedValuePod();
- }
- hours = num;
- break;
- case 'M':
- if (minutes || seconds) {
- return NUdf::TUnboxedValuePod();
- }
- minutes = num;
- break;
- case 'S':
- if (seconds) {
- return NUdf::TUnboxedValuePod();
- }
- seconds = num;
- break;
- case '.':
- if (seconds) {
- return NUdf::TUnboxedValuePod();
- }
- seconds = num;
- if (!ParseNumber<true>(pos, buf, num) || *pos++ != 'S') {
- return NUdf::TUnboxedValuePod();
- }
- microseconds = num;
- break;
- default: return NUdf::TUnboxedValuePod();
- }
- } while (buf.cend() != pos);
- }
-
- const ui64 value
- = days.value_or(0U) * 86400000000ull
- + hours.value_or(0U) * 3600000000ull
- + minutes.value_or(0U) * 60000000ull
- + seconds.value_or(0U) * 1000000ull
- + microseconds.value_or(0U);
-
- if (value >= NUdf::MAX_TIMESTAMP) {
- return NUdf::TUnboxedValuePod();
- }
-
- i64 signedValue = value;
- if (isSigned) {
- signedValue =-signedValue;
- }
-
- return NUdf::TUnboxedValuePod(signedValue);
-}
-
-bool IsValidStringValue(NUdf::EDataSlot type, NUdf::TStringRef buf) {
- switch (type) {
- case NUdf::EDataSlot::Bool:
+ return NUdf::TUnboxedValuePod();
+ }
+
+ const ui64 value = absoluteSeconds * 1000000ull + microseconds;
+ NUdf::TUnboxedValuePod out(value);
+ out.SetTimezoneId(*tzId);
+ return out;
+}
+
+template <bool DecimalPart = false>
+bool ParseNumber(std::string_view::const_iterator& pos, const std::string_view& buf, ui32& value) {
+ value = 0U;
+
+ if (buf.cend() == pos || !std::isdigit(*pos)) {
+ return false;
+ }
+
+ auto digits = 6U;
+ do {
+ value *= 10U;
+ value += *pos - '0';
+ if (buf.cend() == ++pos || !digits--) {
+ return false;
+ }
+ } while (std::isdigit(*pos));
+ if (DecimalPart) {
+ while (digits--) {
+ value *= 10U;
+ }
+ }
+ return true;
+}
+
+NUdf::TUnboxedValuePod ParseInterval(const std::string_view& buf) {
+ if (buf.empty()) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ auto pos = buf.cbegin();
+ bool isSigned = *pos == '-';
+ if (isSigned || *pos == '+') {
+ ++pos;
+ }
+
+ if (buf.cend() == pos || *pos++ != 'P' || buf.cend() == pos) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ std::optional<ui32> days, hours, minutes, seconds, microseconds;
+ ui32 num;
+
+ if (*pos != 'T') {
+ if (!ParseNumber(pos, buf, num)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ switch (*pos++) {
+ case 'D': days = num; break;
+ case 'W': days = 7U * num; break;
+ default: return NUdf::TUnboxedValuePod();
+ }
+ }
+
+ if (buf.cend() != pos) {
+ if (*pos++ != 'T') {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ if (buf.cend() != pos) // TODO: Remove this line later.
+ do {
+ if (!ParseNumber(pos, buf, num)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ switch (*pos++) {
+ case 'H':
+ if (hours || minutes || seconds) {
+ return NUdf::TUnboxedValuePod();
+ }
+ hours = num;
+ break;
+ case 'M':
+ if (minutes || seconds) {
+ return NUdf::TUnboxedValuePod();
+ }
+ minutes = num;
+ break;
+ case 'S':
+ if (seconds) {
+ return NUdf::TUnboxedValuePod();
+ }
+ seconds = num;
+ break;
+ case '.':
+ if (seconds) {
+ return NUdf::TUnboxedValuePod();
+ }
+ seconds = num;
+ if (!ParseNumber<true>(pos, buf, num) || *pos++ != 'S') {
+ return NUdf::TUnboxedValuePod();
+ }
+ microseconds = num;
+ break;
+ default: return NUdf::TUnboxedValuePod();
+ }
+ } while (buf.cend() != pos);
+ }
+
+ const ui64 value
+ = days.value_or(0U) * 86400000000ull
+ + hours.value_or(0U) * 3600000000ull
+ + minutes.value_or(0U) * 60000000ull
+ + seconds.value_or(0U) * 1000000ull
+ + microseconds.value_or(0U);
+
+ if (value >= NUdf::MAX_TIMESTAMP) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ i64 signedValue = value;
+ if (isSigned) {
+ signedValue =-signedValue;
+ }
+
+ return NUdf::TUnboxedValuePod(signedValue);
+}
+
+bool IsValidStringValue(NUdf::EDataSlot type, NUdf::TStringRef buf) {
+ switch (type) {
+ case NUdf::EDataSlot::Bool:
return AsciiEqualsIgnoreCase(buf, TStringBuf("true")) || AsciiEqualsIgnoreCase(buf, TStringBuf("false"));
-
- case NUdf::EDataSlot::Int8:
- return IsValidNumberString<i8>(buf);
- case NUdf::EDataSlot::Uint8:
- return IsValidNumberString<ui8>(buf);
- case NUdf::EDataSlot::Int16:
- return IsValidNumberString<i16>(buf);
- case NUdf::EDataSlot::Uint16:
- return IsValidNumberString<ui16>(buf);
- case NUdf::EDataSlot::Int32:
- return IsValidNumberString<i32>(buf);
- case NUdf::EDataSlot::Uint32:
- return IsValidNumberString<ui32>(buf);
- case NUdf::EDataSlot::Int64:
- return IsValidNumberString<i64>(buf);
- case NUdf::EDataSlot::Uint64:
- return IsValidNumberString<ui64>(buf);
- case NUdf::EDataSlot::Float:
- return IsValidNumberString<float>(buf);
- case NUdf::EDataSlot::Double:
- return IsValidNumberString<double>(buf);
- case NUdf::EDataSlot::Decimal:
- return IsValidDecimal(buf);
- case NUdf::EDataSlot::String:
- return true;
- case NUdf::EDataSlot::Utf8:
- return IsUtf8(buf);
- case NUdf::EDataSlot::Yson:
- return NDom::IsValidYson(buf);
- case NUdf::EDataSlot::Json:
+
+ case NUdf::EDataSlot::Int8:
+ return IsValidNumberString<i8>(buf);
+ case NUdf::EDataSlot::Uint8:
+ return IsValidNumberString<ui8>(buf);
+ case NUdf::EDataSlot::Int16:
+ return IsValidNumberString<i16>(buf);
+ case NUdf::EDataSlot::Uint16:
+ return IsValidNumberString<ui16>(buf);
+ case NUdf::EDataSlot::Int32:
+ return IsValidNumberString<i32>(buf);
+ case NUdf::EDataSlot::Uint32:
+ return IsValidNumberString<ui32>(buf);
+ case NUdf::EDataSlot::Int64:
+ return IsValidNumberString<i64>(buf);
+ case NUdf::EDataSlot::Uint64:
+ return IsValidNumberString<ui64>(buf);
+ case NUdf::EDataSlot::Float:
+ return IsValidNumberString<float>(buf);
+ case NUdf::EDataSlot::Double:
+ return IsValidNumberString<double>(buf);
+ case NUdf::EDataSlot::Decimal:
+ return IsValidDecimal(buf);
+ case NUdf::EDataSlot::String:
+ return true;
+ case NUdf::EDataSlot::Utf8:
+ return IsUtf8(buf);
+ case NUdf::EDataSlot::Yson:
+ return NDom::IsValidYson(buf);
+ case NUdf::EDataSlot::Json:
case NUdf::EDataSlot::JsonDocument:
- return NDom::IsValidJson(buf);
- case NUdf::EDataSlot::Uuid:
- return IsValidUuid(buf);
-
- case NUdf::EDataSlot::DyNumber:
+ return NDom::IsValidJson(buf);
+ case NUdf::EDataSlot::Uuid:
+ return IsValidUuid(buf);
+
+ case NUdf::EDataSlot::DyNumber:
return NDyNumber::IsValidDyNumberString(buf);
-
- case NUdf::EDataSlot::Date:
- case NUdf::EDataSlot::Datetime:
- case NUdf::EDataSlot::Timestamp:
- case NUdf::EDataSlot::Interval:
- case NUdf::EDataSlot::TzDate:
- case NUdf::EDataSlot::TzDatetime:
- case NUdf::EDataSlot::TzTimestamp:
- return bool(ValueFromString(type, buf));
-
- default:
- break;
- }
-
- MKQL_ENSURE(false, "Incorrect data slot: " << (ui32)type);
-}
-
+
+ case NUdf::EDataSlot::Date:
+ case NUdf::EDataSlot::Datetime:
+ case NUdf::EDataSlot::Timestamp:
+ case NUdf::EDataSlot::Interval:
+ case NUdf::EDataSlot::TzDate:
+ case NUdf::EDataSlot::TzDatetime:
+ case NUdf::EDataSlot::TzTimestamp:
+ return bool(ValueFromString(type, buf));
+
+ default:
+ break;
+ }
+
+ MKQL_ENSURE(false, "Incorrect data slot: " << (ui32)type);
+}
+
NUdf::TUnboxedValuePod ValueFromString(NUdf::EDataSlot type, NUdf::TStringRef buf) {
- switch (type) {
- case NUdf::EDataSlot::Bool: {
+ switch (type) {
+ case NUdf::EDataSlot::Bool: {
if (AsciiEqualsIgnoreCase(buf, TStringBuf("true"))) {
- return NUdf::TUnboxedValuePod(true);
- }
+ return NUdf::TUnboxedValuePod(true);
+ }
if (AsciiEqualsIgnoreCase(buf, TStringBuf("false"))) {
- return NUdf::TUnboxedValuePod(false);
- }
- return NUdf::TUnboxedValuePod();
- }
-
- case NUdf::EDataSlot::Int8:
- return NumberFromString<i8>(buf);
-
- case NUdf::EDataSlot::Uint8:
- return NumberFromString<ui8>(buf);
-
- case NUdf::EDataSlot::Int16:
- return NumberFromString<i16>(buf);
-
- case NUdf::EDataSlot::Uint16:
- return NumberFromString<ui16>(buf);
-
- case NUdf::EDataSlot::Int32:
- return NumberFromString<i32>(buf);
-
- case NUdf::EDataSlot::Uint32:
- return NumberFromString<ui32>(buf);
-
- case NUdf::EDataSlot::Int64:
- return NumberFromString<i64>(buf);
-
- case NUdf::EDataSlot::Uint64:
- return NumberFromString<ui64>(buf);
-
- case NUdf::EDataSlot::Float:
- return NumberFromString<float>(buf);
-
- case NUdf::EDataSlot::Double:
- return NumberFromString<double>(buf);
-
- case NUdf::EDataSlot::String:
- return MakeString(buf);
-
- case NUdf::EDataSlot::Utf8:
- if (!IsUtf8(buf)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return MakeString(buf);
-
- case NUdf::EDataSlot::Yson:
- if (!NDom::IsValidYson(buf)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return MakeString(buf);
-
- case NUdf::EDataSlot::Json:
- if (!NDom::IsValidJson(buf)) {
- return NUdf::TUnboxedValuePod();
- }
-
- return MakeString(buf);
-
- case NUdf::EDataSlot::Uuid:
- return ParseUuid(buf);
-
- case NUdf::EDataSlot::Date:
- return ParseDate(buf);
-
- case NUdf::EDataSlot::Datetime:
- return ParseDatetime(buf);
-
- case NUdf::EDataSlot::Timestamp:
- return ParseTimestamp(buf);
-
- case NUdf::EDataSlot::Interval:
- return ParseInterval(buf);
-
- case NUdf::EDataSlot::TzDate:
+ return NUdf::TUnboxedValuePod(false);
+ }
+ return NUdf::TUnboxedValuePod();
+ }
+
+ case NUdf::EDataSlot::Int8:
+ return NumberFromString<i8>(buf);
+
+ case NUdf::EDataSlot::Uint8:
+ return NumberFromString<ui8>(buf);
+
+ case NUdf::EDataSlot::Int16:
+ return NumberFromString<i16>(buf);
+
+ case NUdf::EDataSlot::Uint16:
+ return NumberFromString<ui16>(buf);
+
+ case NUdf::EDataSlot::Int32:
+ return NumberFromString<i32>(buf);
+
+ case NUdf::EDataSlot::Uint32:
+ return NumberFromString<ui32>(buf);
+
+ case NUdf::EDataSlot::Int64:
+ return NumberFromString<i64>(buf);
+
+ case NUdf::EDataSlot::Uint64:
+ return NumberFromString<ui64>(buf);
+
+ case NUdf::EDataSlot::Float:
+ return NumberFromString<float>(buf);
+
+ case NUdf::EDataSlot::Double:
+ return NumberFromString<double>(buf);
+
+ case NUdf::EDataSlot::String:
+ return MakeString(buf);
+
+ case NUdf::EDataSlot::Utf8:
+ if (!IsUtf8(buf)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return MakeString(buf);
+
+ case NUdf::EDataSlot::Yson:
+ if (!NDom::IsValidYson(buf)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return MakeString(buf);
+
+ case NUdf::EDataSlot::Json:
+ if (!NDom::IsValidJson(buf)) {
+ return NUdf::TUnboxedValuePod();
+ }
+
+ return MakeString(buf);
+
+ case NUdf::EDataSlot::Uuid:
+ return ParseUuid(buf);
+
+ case NUdf::EDataSlot::Date:
+ return ParseDate(buf);
+
+ case NUdf::EDataSlot::Datetime:
+ return ParseDatetime(buf);
+
+ case NUdf::EDataSlot::Timestamp:
+ return ParseTimestamp(buf);
+
+ case NUdf::EDataSlot::Interval:
+ return ParseInterval(buf);
+
+ case NUdf::EDataSlot::TzDate:
return ParseTzDate(buf);
-
- case NUdf::EDataSlot::TzDatetime:
- return ParseTzDatetime(buf);
-
- case NUdf::EDataSlot::TzTimestamp:
- return ParseTzTimestamp(buf);
-
+
+ case NUdf::EDataSlot::TzDatetime:
+ return ParseTzDatetime(buf);
+
+ case NUdf::EDataSlot::TzTimestamp:
+ return ParseTzTimestamp(buf);
+
case NUdf::EDataSlot::DyNumber: {
auto dyNumber = NDyNumber::ParseDyNumberString(buf);
if (!dyNumber.Defined()) {
@@ -1734,7 +1734,7 @@ NUdf::TUnboxedValuePod ValueFromString(NUdf::EDataSlot type, NUdf::TStringRef bu
}
return MakeString(*dyNumber);
}
-
+
case NUdf::EDataSlot::JsonDocument: {
auto binaryJson = NKikimr::NBinaryJson::SerializeToBinaryJson(buf);
if (!binaryJson.Defined()) {
@@ -1744,29 +1744,29 @@ NUdf::TUnboxedValuePod ValueFromString(NUdf::EDataSlot type, NUdf::TStringRef bu
return MakeString(TStringBuf(binaryJson->Data(), binaryJson->Size()));
}
- case NUdf::EDataSlot::Decimal:
- default:
- break;
- }
-
- MKQL_ENSURE(false, "Incorrect data slot: " << (ui32)type);
-}
-
-NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRef buf) {
+ case NUdf::EDataSlot::Decimal:
+ default:
+ break;
+ }
+
+ MKQL_ENSURE(false, "Incorrect data slot: " << (ui32)type);
+}
+
+NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRef buf) {
const bool isBinYson = !buf.Empty() && *buf.Data() <= NYson::NDetail::Uint64Marker;
if (!isBinYson) {
auto textBuf = buf;
switch (type) {
case NUdf::EDataSlot::Bool:
if (buf.Empty()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
textBuf = buf.Substring(1, buf.Size() - 1);
break;
case NUdf::EDataSlot::Float:
case NUdf::EDataSlot::Double:
if (buf.Empty()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
if (buf.Data()[0] == '%') {
@@ -1782,7 +1782,7 @@ NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRe
case NUdf::EDataSlot::Datetime:
case NUdf::EDataSlot::Timestamp:
if (buf.Empty()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
/// YSON for unsigned may be with or without suffix 'u'
if (buf.Data()[buf.Size() - 1] == 'u') {
@@ -1791,32 +1791,32 @@ NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRe
break;
case NUdf::EDataSlot::String: {
if (buf.Empty()) {
- return NUdf::TUnboxedValuePod::Zero();
+ return NUdf::TUnboxedValuePod::Zero();
}
const char ysonQuote = '"';
if (*buf.Data() == NYson::NDetail::EntitySymbol) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
} else if (*buf.Data() != ysonQuote) {
- return MakeString(buf);
+ return MakeString(buf);
}
- if (const auto count = std::count(buf.Data(), buf.Data() + buf.Size(), '\\')) {
- if (const auto size = buf.Size() - count) {
- auto out = MakeStringNotFilled(size);
- std::copy_if(buf.Data(), buf.Data() + buf.Size(), out.AsStringRef().Data(), [](char c){ return c != '\\'; });
- return out;
+ if (const auto count = std::count(buf.Data(), buf.Data() + buf.Size(), '\\')) {
+ if (const auto size = buf.Size() - count) {
+ auto out = MakeStringNotFilled(size);
+ std::copy_if(buf.Data(), buf.Data() + buf.Size(), out.AsStringRef().Data(), [](char c){ return c != '\\'; });
+ return out;
} else {
- return NUdf::TUnboxedValuePod::Zero();
+ return NUdf::TUnboxedValuePod::Zero();
}
- } else {
- return MakeString(buf);
+ } else {
+ return MakeString(buf);
}
}
case NUdf::EDataSlot::TzDate:
case NUdf::EDataSlot::TzDatetime:
case NUdf::EDataSlot::TzTimestamp:
- case NUdf::EDataSlot::Decimal:
+ case NUdf::EDataSlot::Decimal:
case NUdf::EDataSlot::Uuid:
Y_FAIL("TODO");
@@ -1824,22 +1824,22 @@ NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRe
;
}
- return ValueFromString(type, textBuf);
+ return ValueFromString(type, textBuf);
}
-
+
const ui8 ytBinType = *buf.Data();
auto binPayload = buf.Substring(1, buf.Size() - 1);
switch (type) {
case NUdf::EDataSlot::Bool: {
if (ytBinType == NYson::NDetail::FalseMarker) {
- return NUdf::TUnboxedValuePod(false);
- }
+ return NUdf::TUnboxedValuePod(false);
+ }
if (ytBinType == NYson::NDetail::TrueMarker) {
- return NUdf::TUnboxedValuePod(true);
- }
-
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod(true);
+ }
+
+ return NUdf::TUnboxedValuePod();
}
case NUdf::EDataSlot::Uint8:
@@ -1850,17 +1850,17 @@ NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRe
case NUdf::EDataSlot::Datetime:
case NUdf::EDataSlot::Timestamp: {
if (ytBinType != NYson::NDetail::Uint64Marker) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
TMemoryInput stringRefStream(binPayload.Data(), binPayload.Size());
ui64 value;
const size_t read = NYson::ReadVarUInt64(&stringRefStream, &value);
if (read != binPayload.Size()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
- return NUdf::TUnboxedValuePod(value);
+ return NUdf::TUnboxedValuePod(value);
}
case NUdf::EDataSlot::Int8:
@@ -1869,65 +1869,65 @@ NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRe
case NUdf::EDataSlot::Int64:
case NUdf::EDataSlot::Interval: {
if (ytBinType != NYson::NDetail::Int64Marker) {
- return NUdf::TUnboxedValuePod();
- }
+ return NUdf::TUnboxedValuePod();
+ }
TMemoryInput stringRefStream(binPayload.Data(), binPayload.Size());
i64 value;
const size_t read = NYson::ReadVarInt64(&stringRefStream, &value);
if (read != binPayload.Size()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
- return NUdf::TUnboxedValuePod(value);
+ return NUdf::TUnboxedValuePod(value);
}
case NUdf::EDataSlot::Float: {
if (ytBinType != NYson::NDetail::DoubleMarker || binPayload.Size() != 8) {
- return NUdf::TUnboxedValuePod();
- }
+ return NUdf::TUnboxedValuePod();
+ }
- const float x = *reinterpret_cast<const double*>(binPayload.Data());
- return NUdf::TUnboxedValuePod(x);
+ const float x = *reinterpret_cast<const double*>(binPayload.Data());
+ return NUdf::TUnboxedValuePod(x);
}
case NUdf::EDataSlot::Double: {
if (ytBinType != NYson::NDetail::DoubleMarker || binPayload.Size() != 8) {
- return NUdf::TUnboxedValuePod();
- }
+ return NUdf::TUnboxedValuePod();
+ }
- const double x = *reinterpret_cast<const double*>(binPayload.Data());
- return NUdf::TUnboxedValuePod(x);
+ const double x = *reinterpret_cast<const double*>(binPayload.Data());
+ return NUdf::TUnboxedValuePod(x);
}
case NUdf::EDataSlot::String:
case NUdf::EDataSlot::Utf8:
- case NUdf::EDataSlot::Json: {
+ case NUdf::EDataSlot::Json: {
if (ytBinType != NYson::NDetail::StringMarker) {
- return NUdf::TUnboxedValuePod();
- }
+ return NUdf::TUnboxedValuePod();
+ }
TMemoryInput stringRefStream(binPayload.Data(), binPayload.Size());
i32 value;
const size_t read = NYson::ReadVarInt32(&stringRefStream, &value);
binPayload = binPayload.Substring(read, binPayload.Size() - read);
- const size_t strLen = value;
+ const size_t strLen = value;
if (strLen != binPayload.Size()) {
- return NUdf::TUnboxedValuePod();
+ return NUdf::TUnboxedValuePod();
}
- return MakeString(NUdf::TStringRef(binPayload.Data(), strLen));
+ return MakeString(NUdf::TStringRef(binPayload.Data(), strLen));
}
case NUdf::EDataSlot::Yson:
- return MakeString(buf);
+ return MakeString(buf);
case NUdf::EDataSlot::TzDate:
case NUdf::EDataSlot::TzDatetime:
case NUdf::EDataSlot::TzTimestamp:
- case NUdf::EDataSlot::Decimal:
+ case NUdf::EDataSlot::Decimal:
case NUdf::EDataSlot::Uuid:
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
case NUdf::EDataSlot::JsonDocument:
Y_FAIL("TODO");
}
@@ -1951,19 +1951,19 @@ TMaybe<ui16> FindTimezoneId(TStringBuf ianaName) {
ui16 GetTimezoneId(TStringBuf ianaName) {
const auto& zones = *Singleton<TTimezones>();
- const auto it = zones.Name2Id.find(ianaName);
- MKQL_ENSURE(it != zones.Name2Id.cend(), "Unknown time zone name: " << ianaName);
+ const auto it = zones.Name2Id.find(ianaName);
+ MKQL_ENSURE(it != zones.Name2Id.cend(), "Unknown time zone name: " << ianaName);
return it->second;
}
bool IsValidTimezoneId(ui16 id) {
- const auto zones = NUdf::GetTimezones();
- return id < zones.size() && !zones[id].empty();
+ const auto zones = NUdf::GetTimezones();
+ return id < zones.size() && !zones[id].empty();
}
TMaybe<TStringBuf> FindTimezoneIANAName(ui16 id) {
- const auto zones = NUdf::GetTimezones();
- if (id >= zones.size() || zones[id].empty()) {
+ const auto zones = NUdf::GetTimezones();
+ if (id >= zones.size() || zones[id].empty()) {
return Nothing();
}
@@ -1971,22 +1971,22 @@ TMaybe<TStringBuf> FindTimezoneIANAName(ui16 id) {
}
TStringBuf GetTimezoneIANAName(ui16 id) {
- const auto zones = NUdf::GetTimezones();
- MKQL_ENSURE(id < zones.size() && !zones[id].empty(), "Invalid time zone id: " << id);
+ const auto zones = NUdf::GetTimezones();
+ MKQL_ENSURE(id < zones.size() && !zones[id].empty(), "Invalid time zone id: " << id);
return TStringBuf(zones[id]);
}
-std::vector<ui16> GetTzBlackList() {
- std::vector<ui16> result;
- const auto& zones = NUdf::GetTimezones();
- for (ui16 id = 0; id < zones.size(); ++id) {
- if (zones[id].empty()) {
- result.emplace_back(id);
- }
- }
- return result;
-}
-
+std::vector<ui16> GetTzBlackList() {
+ std::vector<ui16> result;
+ const auto& zones = NUdf::GetTimezones();
+ for (ui16 id = 0; id < zones.size(); ++id) {
+ if (zones[id].empty()) {
+ result.emplace_back(id);
+ }
+ }
+ return result;
+}
+
void ToLocalTime(ui32 utcSeconds, ui16 tzId, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& min, ui32& sec) {
const auto& tz = Singleton<TTimezones>()->GetZone(tzId);
auto converted = cctz::convert(std::chrono::system_clock::from_time_t(utcSeconds), tz);
diff --git a/ydb/library/yql/minikql/mkql_type_ops.h b/ydb/library/yql/minikql/mkql_type_ops.h
index c67b3e9e9d..8ff9b258dd 100644
--- a/ydb/library/yql/minikql/mkql_type_ops.h
+++ b/ydb/library/yql/minikql/mkql_type_ops.h
@@ -13,26 +13,26 @@ namespace NMiniKQL {
//TODO remove
TStringBuf AdaptLegacyYqlType(const TStringBuf& type);
-bool IsValidValue(NUdf::EDataSlot type, const NUdf::TUnboxedValuePod& value);
-
+bool IsValidValue(NUdf::EDataSlot type, const NUdf::TUnboxedValuePod& value);
+
bool IsLeapYear(ui32 year);
ui32 GetMonthLength(ui32 month, bool isLeap);
void UuidHalfsToByteString(ui64 low, ui64 hi, IOutputStream& out);
-bool IsValidStringValue(NUdf::EDataSlot type, NUdf::TStringRef buf);
-
+bool IsValidStringValue(NUdf::EDataSlot type, NUdf::TStringRef buf);
+
NUdf::TUnboxedValuePod ValueFromString(NUdf::EDataSlot type, NUdf::TStringRef buf);
-NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRef buf);
-
+NUdf::TUnboxedValuePod SimpleValueFromYson(NUdf::EDataSlot type, NUdf::TStringRef buf);
+
NUdf::TUnboxedValuePod ValueToString(NUdf::EDataSlot type, NUdf::TUnboxedValuePod value);
-
+
NUdf::TUnboxedValuePod ParseUuid(NUdf::TStringRef buf, bool shortForm=false);
bool ParseUuid(NUdf::TStringRef buf, void* output, bool shortForm=false);
-
-bool IsValidDecimal(NUdf::TStringRef buf);
-
+
+bool IsValidDecimal(NUdf::TStringRef buf);
+
bool MakeDate(ui32 year, ui32 month, ui32 day, ui16& value);
bool MakeTime(ui32 hour, ui32 minute, ui32 second, ui32& value);
bool SplitDate(ui16 value, ui32& year, ui32& month, ui32& day);
@@ -42,7 +42,7 @@ bool SplitInterval(i64 value, bool& sign, ui32& day, ui32& hour, ui32& min, ui32
bool SplitTzDate(ui16 value, ui32& year, ui32& month, ui32& day, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId);
bool SplitTzDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& min, ui32& sec, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek, ui16 tzId);
-
+
bool MakeTzDatetime(ui32 year, ui32 month, ui32 day, ui32 hour, ui32 min, ui32 sec, ui32& value, ui16 tzId);
bool SplitTzDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& min, ui32& sec, ui16 tzId);
bool EnrichDate(ui16 date, ui32& dayOfYear, ui32& weekOfYear, ui32& weekOfYearIso8601, ui32& dayOfWeek);
@@ -54,7 +54,7 @@ TMaybe<ui16> FindTimezoneId(TStringBuf ianaName);
ui16 GetTimezoneId(TStringBuf ianaName);
TMaybe<TStringBuf> FindTimezoneIANAName(ui16 id);
TStringBuf GetTimezoneIANAName(ui16 id);
-std::vector<ui16> GetTzBlackList();
+std::vector<ui16> GetTzBlackList();
void ToLocalTime(ui32 utcSeconds, ui16 tzId, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& min, ui32& sec);
ui32 FromLocalTime(ui16 tzId, ui32 year, ui32 month, ui32 day, ui32 hour, ui32 min, ui32 sec);
diff --git a/ydb/library/yql/minikql/mkql_type_ops_ut.cpp b/ydb/library/yql/minikql/mkql_type_ops_ut.cpp
index 8d94d654aa..01828a9a52 100644
--- a/ydb/library/yql/minikql/mkql_type_ops_ut.cpp
+++ b/ydb/library/yql/minikql/mkql_type_ops_ut.cpp
@@ -1,12 +1,12 @@
-#include "mkql_alloc.h"
-#include "mkql_type_ops.h"
+#include "mkql_alloc.h"
+#include "mkql_type_ops.h"
#include <library/cpp/testing/unittest/registar.h>
#include <util/stream/format.h>
#include <util/stream/str.h>
-using namespace NYql;
+using namespace NYql;
using namespace NKikimr;
using namespace NKikimr::NMiniKQL;
@@ -15,15 +15,15 @@ Y_UNIT_TEST_SUITE(TMiniKQLTypeOps) {
ui32 year = 1970;
ui32 month = 1;
ui32 day = 1;
- for (ui16 packed = 0U; year < NUdf::MAX_YEAR; ++packed) {
- const NUdf::TUnboxedValue& out = ValueToString(NUdf::EDataSlot::Date, NUdf::TUnboxedValuePod(packed));
+ for (ui16 packed = 0U; year < NUdf::MAX_YEAR; ++packed) {
+ const NUdf::TUnboxedValue& out = ValueToString(NUdf::EDataSlot::Date, NUdf::TUnboxedValuePod(packed));
TStringStream expected;
expected << LeftPad(year, 4, '0') << '-' << LeftPad(month, 2, '0') << '-' << LeftPad(day, 2, '0');
UNIT_ASSERT_VALUES_EQUAL_C(TStringBuf(out.AsStringRef()), expected.Str(), "Packed value: " << packed);
- const auto out2 = ValueFromString(NUdf::EDataSlot::Date, expected.Str());
- UNIT_ASSERT_C(out2, "Date value: " << expected.Str());
- UNIT_ASSERT_VALUES_EQUAL_C(out2.Get<ui16>(), packed, "Date value: " << expected.Str());
+ const auto out2 = ValueFromString(NUdf::EDataSlot::Date, expected.Str());
+ UNIT_ASSERT_C(out2, "Date value: " << expected.Str());
+ UNIT_ASSERT_VALUES_EQUAL_C(out2.Get<ui16>(), packed, "Date value: " << expected.Str());
++day;
ui32 monthLength = 31;
@@ -52,12 +52,12 @@ Y_UNIT_TEST_SUITE(TMiniKQLTypeOps) {
Y_UNIT_TEST(AllTimezones) {
auto count = InitTimezones();
- UNIT_ASSERT_VALUES_EQUAL(count, 597);
+ UNIT_ASSERT_VALUES_EQUAL(count, 597);
for (ui32 i = 0; i < count; ++i) {
- if (const auto name = FindTimezoneIANAName(i)) {
- UNIT_ASSERT(!name->empty());
- UNIT_ASSERT_VALUES_EQUAL(FindTimezoneId(*name), i);
- }
+ if (const auto name = FindTimezoneIANAName(i)) {
+ UNIT_ASSERT(!name->empty());
+ UNIT_ASSERT_VALUES_EQUAL(FindTimezoneId(*name), i);
+ }
}
UNIT_ASSERT(!FindTimezoneIANAName(count));
diff --git a/ydb/library/yql/minikql/mkql_unboxed_value_stream.cpp b/ydb/library/yql/minikql/mkql_unboxed_value_stream.cpp
index bdd12f7e14..a90afdfa41 100644
--- a/ydb/library/yql/minikql/mkql_unboxed_value_stream.cpp
+++ b/ydb/library/yql/minikql/mkql_unboxed_value_stream.cpp
@@ -1,21 +1,21 @@
#include "mkql_unboxed_value_stream.h"
-
+
#include <ydb/library/yql/minikql/mkql_string_util.h>
-
-namespace NKikimr {
-namespace NMiniKQL {
-
-TUnboxedValueStream::TUnboxedValueStream()
- : Value_(NUdf::TUnboxedValuePod::Zero())
-{}
-
-NUdf::TUnboxedValuePod TUnboxedValueStream::Value() {
- return Value_.Release();
-}
-
-void TUnboxedValueStream::DoWrite(const void* buf, size_t len) {
- Value_ = AppendString(Value_.Release(), NUdf::TStringRef(static_cast<const char*>(buf), len));
-}
-
-}
-}
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+TUnboxedValueStream::TUnboxedValueStream()
+ : Value_(NUdf::TUnboxedValuePod::Zero())
+{}
+
+NUdf::TUnboxedValuePod TUnboxedValueStream::Value() {
+ return Value_.Release();
+}
+
+void TUnboxedValueStream::DoWrite(const void* buf, size_t len) {
+ Value_ = AppendString(Value_.Release(), NUdf::TStringRef(static_cast<const char*>(buf), len));
+}
+
+}
+}
diff --git a/ydb/library/yql/minikql/mkql_unboxed_value_stream.h b/ydb/library/yql/minikql/mkql_unboxed_value_stream.h
index 814f7fb61a..43005db571 100644
--- a/ydb/library/yql/minikql/mkql_unboxed_value_stream.h
+++ b/ydb/library/yql/minikql/mkql_unboxed_value_stream.h
@@ -5,14 +5,14 @@ namespace NKikimr {
namespace NMiniKQL {
struct TUnboxedValueStream : public IOutputStream {
- NUdf::TUnboxedValue Value_;
-
- TUnboxedValueStream();
-
- NUdf::TUnboxedValuePod Value();
-
- void DoWrite(const void* buf, size_t len) override;
-};
+ NUdf::TUnboxedValue Value_;
+
+ TUnboxedValueStream();
+
+ NUdf::TUnboxedValuePod Value();
+
+ void DoWrite(const void* buf, size_t len) override;
+};
}
}
diff --git a/ydb/library/yql/minikql/mkql_utils.h b/ydb/library/yql/minikql/mkql_utils.h
index 5146ae6a48..0c22d2857c 100644
--- a/ydb/library/yql/minikql/mkql_utils.h
+++ b/ydb/library/yql/minikql/mkql_utils.h
@@ -20,7 +20,7 @@ public:
inline static TStatus Error(TString&& error) {
Y_VERIFY_DEBUG(!error.empty());
- return TStatus(std::move(error));
+ return TStatus(std::move(error));
}
inline static TStatus Error() {
@@ -45,7 +45,7 @@ private:
inline TStatus() = default;
inline TStatus(TString&& error)
- : Error_(std::move(error))
+ : Error_(std::move(error))
{
}
diff --git a/ydb/library/yql/minikql/perf/alloc/alloc.cpp b/ydb/library/yql/minikql/perf/alloc/alloc.cpp
index 31dba3216d..90f848aec8 100644
--- a/ydb/library/yql/minikql/perf/alloc/alloc.cpp
+++ b/ydb/library/yql/minikql/perf/alloc/alloc.cpp
@@ -8,7 +8,7 @@ using namespace NKikimr::NUdf;
namespace {
inline void MyFree(const void* p, size_t) { return free(const_cast<void*>(p)); }
-
+
template <void*(*Alloc)(ui64), void (*Free)(const void*,ui64)>
void Test(const TString& name) {
TSimpleTimer timer;
@@ -31,10 +31,10 @@ namespace {
}
int main(int, char**) {
- Test<&malloc, &MyFree>("malloc");
- {
- TScopedAlloc sopedAlloc;
+ Test<&malloc, &MyFree>("malloc");
+ {
+ TScopedAlloc sopedAlloc;
Test<&UdfAllocateWithSize, &UdfFreeWithSize>("mkql");
- }
+ }
return 0;
}
diff --git a/ydb/library/yql/minikql/perf/presort/presort.cpp b/ydb/library/yql/minikql/perf/presort/presort.cpp
index aa94c2fafe..cfe4ddfb8f 100644
--- a/ydb/library/yql/minikql/perf/presort/presort.cpp
+++ b/ydb/library/yql/minikql/perf/presort/presort.cpp
@@ -9,7 +9,7 @@
#include <util/random/random.h>
#include <util/datetime/cputimer.h>
-#include <util/string/builder.h>
+#include <util/string/builder.h>
using namespace NKikimr;
using namespace NKikimr::NMiniKQL;
@@ -32,7 +32,7 @@ struct TPresortOps : public NPresort::TResultOps {
TPresortOps(
const TVector<TSettings>& settings,
NUdf::TUnboxedValue* items)
- : Settings(settings)
+ : Settings(settings)
, Items(items)
{}
@@ -150,21 +150,21 @@ struct TPresortOps : public NPresort::TResultOps {
}
void SetString(const TString& value) {
- Items[Settings[Current++].Index] = MakeString(NUdf::TStringRef(value.data(), value.size()));
+ Items[Settings[Current++].Index] = MakeString(NUdf::TStringRef(value.data(), value.size()));
}
void SetOptional(bool) {}
};
template <typename T>
-NUdf::TUnboxedValue RandomValue() {
+NUdf::TUnboxedValue RandomValue() {
return NUdf::TUnboxedValuePod(RandomNumber<T>());
}
template <>
-NUdf::TUnboxedValue RandomValue<char*>() {
+NUdf::TUnboxedValue RandomValue<char*>() {
auto length = RandomNumber<ui64>(64);
- return MakeStringNotFilled(length);
+ return MakeStringNotFilled(length);
}
template <typename T, NUdf::EDataSlot Slot, bool Desc>
@@ -179,7 +179,7 @@ std::pair<ui64, ui64> MeasureOld() {
TVector<TSettings> settings;
for (ui32 i = 0; i < count; ++i) {
- values.push_back(RandomValue<T>());
+ values.push_back(RandomValue<T>());
settings.push_back({i, false, NUdf::TDataType<T>::Slot});
}
@@ -188,7 +188,7 @@ std::pair<ui64, ui64> MeasureOld() {
TStringStream stream;
for (size_t n = 0; n < rowCount; ++n) {
stream.clear();
- TPresortOps<Desc> ops{settings, values.begin()};
+ TPresortOps<Desc> ops{settings, values.begin()};
ops.Encode(stream);
}
auto encodeTime = timer.Get().MicroSeconds();
@@ -200,7 +200,7 @@ std::pair<ui64, ui64> MeasureOld() {
timer.Reset();
for (size_t n = 0; n < rowCount; ++n) {
- TPresortOps<Desc> ops{settings, values.begin()};
+ TPresortOps<Desc> ops{settings, values.begin()};
auto str = stream.Str();
NPresort::Decode(ops, TStringBuf(str.data(), str.size()));
}
@@ -223,10 +223,10 @@ std::pair<ui64, ui64> MeasureNew() {
TVector<NUdf::TUnboxedValuePod> values;
TPresortEncoder encoder;
- TPresortDecoder decoder;
+ TPresortDecoder decoder;
for (size_t i = 0; i < count; ++i) {
- values.push_back(RandomValue<T>());
+ values.push_back(RandomValue<T>());
encoder.AddType(Slot, false, Desc);
decoder.AddType(Slot, false, Desc);
}
diff --git a/ydb/library/yql/minikql/ut/ya.make b/ydb/library/yql/minikql/ut/ya.make
index 7e8cc557b1..098a77d0c6 100644
--- a/ydb/library/yql/minikql/ut/ya.make
+++ b/ydb/library/yql/minikql/ut/ya.make
@@ -26,7 +26,7 @@ SRCS(
mkql_opt_literal_ut.cpp
mkql_stats_registry_ut.cpp
mkql_type_ops_ut.cpp
- mkql_string_util_ut.cpp
+ mkql_string_util_ut.cpp
pack_num_ut.cpp
watermark_tracker_ut.cpp
)
diff --git a/ydb/library/yql/minikql/ya.make b/ydb/library/yql/minikql/ya.make
index 84e7b7776e..c4b608128d 100644
--- a/ydb/library/yql/minikql/ya.make
+++ b/ydb/library/yql/minikql/ya.make
@@ -14,7 +14,7 @@ SRCS(
compact_hash.h
defs.h
mkql_alloc.cpp
- mkql_function_metadata.h
+ mkql_function_metadata.h
mkql_function_registry.cpp
mkql_function_registry.h
mkql_node.cpp
@@ -36,16 +36,16 @@ SRCS(
mkql_runtime_version.cpp
mkql_runtime_version.h
mkql_stats_registry.cpp
- mkql_string_util.cpp
- mkql_string_util.h
- mkql_terminator.cpp
- mkql_terminator.h
+ mkql_string_util.cpp
+ mkql_string_util.h
+ mkql_terminator.cpp
+ mkql_terminator.h
mkql_type_builder.cpp
mkql_type_builder.h
mkql_type_ops.cpp
mkql_type_ops.h
- mkql_unboxed_value_stream.cpp
- mkql_unboxed_value_stream.h
+ mkql_unboxed_value_stream.cpp
+ mkql_unboxed_value_stream.h
primes.cpp
primes.h
watermark_tracker.cpp
diff --git a/ydb/library/yql/mount/lib/yql/aggregate.yql b/ydb/library/yql/mount/lib/yql/aggregate.yql
index 85208fc92c..a1c231f339 100644
--- a/ydb/library/yql/mount/lib/yql/aggregate.yql
+++ b/ydb/library/yql/mount/lib/yql/aggregate.yql
@@ -1,20 +1,20 @@
-# library
-(
-
+# library
+(
+
(let empty_list (lambda '(list_type) (MatchType list_type 'Null (lambda '() (EmptyList)) (lambda '() (List list_type)))))
-# list_type:type function:lambda
-# doesn't support optional values
-(let simple_traits_factory (lambda '(list_type function) (block '(
- (let init (lambda '(value) value))
+# list_type:type function:lambda
+# doesn't support optional values
+(let simple_traits_factory (lambda '(list_type function) (block '(
+ (let init (lambda '(value) value))
(let update (lambda '(value state) (Apply function value state)))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
- (let merge (lambda '(state1 state2) (Apply function state1 state2)))
- (let finish (lambda '(state) state))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
+ (let merge (lambda '(state1 state2) (Apply function state1 state2)))
+ (let finish (lambda '(state) state))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
+))))
+
# list_type:type function:lambda
# doesn't support optional values
(let simple_traits_factory_map (lambda '(list_type reduce_function map_function) (block '(
@@ -27,32 +27,32 @@
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
))))
-# list_type:type
-# doesn't support optional values
+# list_type:type
+# doesn't support optional values
(let some_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (Coalesce two one)))))
-(let bit_and_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitAnd one two)))))
-(let bit_or_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitOr one two)))))
-(let bit_xor_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitXor one two)))))
-
-# list_type:type
-# support optional values
-(let bool_and_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (And one two)))))
-(let bool_or_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (Or one two)))))
-(let bool_xor_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (Xor one two)))))
-
-# list_type:type init:lambda
-# doesn't support optional values
-(let count_traits_factory (lambda '(list_type init) (block '(
- (let update (lambda '(value state) (+ state (Apply init value))))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
- (let merge (lambda '(state1 state2) (+ state1 state2)))
- (let finish (lambda '(state) state))
+(let bit_and_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitAnd one two)))))
+(let bit_or_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitOr one two)))))
+(let bit_xor_traits_factory_raw (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (BitXor one two)))))
+
+# list_type:type
+# support optional values
+(let bool_and_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (And one two)))))
+(let bool_or_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (Or one two)))))
+(let bool_xor_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (Xor one two)))))
+
+# list_type:type init:lambda
+# doesn't support optional values
+(let count_traits_factory (lambda '(list_type init) (block '(
+ (let update (lambda '(value state) (+ state (Apply init value))))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
+ (let merge (lambda '(state1 state2) (+ state1 state2)))
+ (let finish (lambda '(state) state))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Uint64 '0)))
-))))
-
-# list_type:type
-# support optional values
+))))
+
+# list_type:type
+# support optional values
(let count_traits_factory_opt (lambda '(list_type) (block '(
(let init (lambda '(value) (AggrCountInit value)))
(let update (lambda '(value state) (AggrCountUpdate value state)))
@@ -66,11 +66,11 @@
# list_type:type
# support optional values
(let count_if_traits_factory_opt (lambda '(list_type) (Apply count_traits_factory list_type (lambda '(value) (If (Coalesce value (Bool '0)) (Uint64 '1) (Uint64 '0))))))
-(let count_all_traits_factory_opt (lambda '(list_type) (Apply count_traits_factory list_type (lambda '(value) (Uint64 '1)))))
-
-# list_type:type
-# doesn't support optional values
-(let avg_traits_factory_raw (lambda '(list_type) (block '(
+(let count_all_traits_factory_opt (lambda '(list_type) (Apply count_traits_factory list_type (lambda '(value) (Uint64 '1)))))
+
+# list_type:type
+# doesn't support optional values
+(let avg_traits_factory_raw (lambda '(list_type) (block '(
(let convert_interval_to_decimal (lambda '(value) (StrictCast (StrictCast value (DataType 'Int64)) (DataType 'Decimal '35 '0))))
(let convert_decimal_to_interval (lambda '(value) (Unwrap (StrictCast (StrictCast value (DataType 'Int64)) (DataType 'Interval)))))
(let init (lambda '(value) '((MatchType (TypeOf value)
@@ -83,9 +83,9 @@
'Interval (lambda '() (Apply convert_interval_to_decimal value ))
(lambda '() (Convert value 'Double)))
) (Inc (Nth state '1)))))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
- (let merge (lambda '(state1 state2) '((+ (Nth state1 '0) (Nth state2 '0)) (+ (Nth state1 '1) (Nth state2 '1)))))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
+ (let merge (lambda '(state1 state2) '((+ (Nth state1 '0) (Nth state2 '0)) (+ (Nth state1 '1) (Nth state2 '1)))))
(let finish (lambda '(state)
(MatchType (ListItemType list_type)
'Decimal
@@ -96,36 +96,36 @@
)
))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
-# list_type:type
+))))
+
+# list_type:type
# defval
-# support optional values
+# support optional values
(let list_traits_factory_opt_gen (lambda '(limit defval) (block '(
(return (lambda '(list_type) (block '(
- (let item_type (ListItemType list_type))
- (let init (lambda '(value) (MatchType item_type
- 'Optional (lambda '() (ToList value))
- 'Null (lambda '() (EmptyList))
- (lambda '() (AsList value)))))
+ (let item_type (ListItemType list_type))
+ (let init (lambda '(value) (MatchType item_type
+ 'Optional (lambda '() (ToList value))
+ 'Null (lambda '() (EmptyList))
+ (lambda '() (AsList value)))))
(let update (lambda '(value state) (block '(
- (let x (MatchType item_type
- 'Optional (lambda '() (IfPresent value (lambda '(value) (Insert state value)) state))
- 'Null (lambda '() (EmptyList))
- (lambda '() (Insert state value))))
+ (let x (MatchType item_type
+ 'Optional (lambda '() (IfPresent value (lambda '(value) (Insert state value)) state))
+ 'Null (lambda '() (EmptyList))
+ (lambda '() (Insert state value))))
(return (If (== limit (Uint64 '0)) x (Take x limit)))))))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
(let merge (lambda '(state1 state2) (block '(
(let x (Extend state1 state2))
(return (If (== limit (Uint64 '0)) x (Take x limit)))))))
- (let finish (lambda '(state) state))
+ (let finish (lambda '(state) state))
(return (AggregationTraits item_type init update save load merge finish defval))
))))))))
-
-# list_type:type stddev:bool sample:bool
-# doesn't support optional values
-(let variance_traits_factory_raw (lambda '(list_type stddev sample) (block '(
+
+# list_type:type stddev:bool sample:bool
+# doesn't support optional values
+(let variance_traits_factory_raw (lambda '(list_type stddev sample) (block '(
(let init (lambda '(value) '(
(Convert value 'Double)
(Double '1)
@@ -138,8 +138,8 @@
next_n
(+ (Nth state '2) (/ (* (* delta delta) (Nth state '1)) next_n))
))))))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
(let merge (lambda '(one two) (block '(
(let delta (- (Nth one '0) (Nth two '0)))
(let sum_n (+ (Nth one '1) (Nth two '1)))
@@ -154,15 +154,15 @@
(let result (/ (Nth state '2) (If sample (- count (Double '1)) count)))
(return (If stddev (Apply (Udf 'Math.Sqrt) result) result))))))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
-# list_type:type
-# doesn't support optional values
-(let variance_0_0_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '0) (Bool '0))))
-(let variance_1_0_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '1) (Bool '0))))
-(let variance_0_1_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '0) (Bool '1))))
-(let variance_1_1_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '1) (Bool '1))))
-
+))))
+
+# list_type:type
+# doesn't support optional values
+(let variance_0_0_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '0) (Bool '0))))
+(let variance_1_0_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '1) (Bool '0))))
+(let variance_0_1_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '0) (Bool '1))))
+(let variance_1_1_traits_factory_raw (lambda '(list_type) (Apply variance_traits_factory_raw list_type (Bool '1) (Bool '1))))
+
# list_type:type
# doesn't support optional values
(let correlation_traits_factory_raw (lambda '(list_type) (block '(
@@ -206,17 +206,17 @@
(let covariance_sample_traits_factory_raw (lambda '(list_type) (Apply covariance_traits_factory_raw list_type (Bool '1))))
# list_type:type histogram:atom value:lambda weight:lambda intervals:integer
-# doesn't support optional values
-(let histogram_traits_factory_raw (lambda '(list_type histogram value weight intervals) (block '(
+# doesn't support optional values
+(let histogram_traits_factory_raw (lambda '(list_type histogram value weight intervals) (block '(
(let init (lambda '(row parent) (NamedApply (Udf (Combine histogram '_Create)) '((Apply value row) (Apply weight row) intervals) (AsStruct) (DependsOn parent))))
(let update (lambda '(row state parent) (NamedApply (Udf (Combine histogram '_AddValue)) '(state (Apply value row) (Apply weight row)) (AsStruct) (DependsOn parent))))
- (let save (lambda '(state) (Apply (Udf (Combine histogram '_Serialize)) state)))
- (let load (lambda '(state) (Apply (Udf (Combine histogram '_Deserialize)) state intervals)))
- (let merge (lambda '(one two) (Apply (Udf (Combine histogram '_Merge)) one two)))
- (let finish (lambda '(state) (Apply (Udf (Combine histogram '_GetResult)) state)))
+ (let save (lambda '(state) (Apply (Udf (Combine histogram '_Serialize)) state)))
+ (let load (lambda '(state) (Apply (Udf (Combine histogram '_Deserialize)) state intervals)))
+ (let merge (lambda '(one two) (Apply (Udf (Combine histogram '_Merge)) one two)))
+ (let finish (lambda '(state) (Apply (Udf (Combine histogram '_GetResult)) state)))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
+))))
+
# list_type:type count:ui32
# doesn't support optional values
(let set_traits_factory_raw (lambda '(list_type count) (block '(
@@ -240,7 +240,7 @@
(let merge (lambda '(one two) (Apply UdfSetMerge one two)))
(let finish (lambda '(state) (Apply UdfSetGetResult state)))
- (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
+ (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
))))
# list_type:type n:ui32 buffer:ui32
@@ -267,7 +267,7 @@
(let merge (lambda '(one two) (Apply UdfTopFreqMerge one two)))
(let finish (lambda '(state) (Apply UdfTopFreqGet state n)))
- (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
+ (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
))))
# list_type:type extractor:lambda count:ui32 is_top:atom
@@ -294,7 +294,7 @@
(let merge (lambda '(one two) (Apply UdfTopMerge one two)))
(let finish (lambda '(state) (Apply UdfTopGetResult state)))
- (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
+ (return (AggregationTraits value_type init update save load merge finish (EmptyList)))
))))
# list_type:type key_extractor:lambda payload_extractor:lambda count:ui32 is_top:atom
@@ -324,13 +324,13 @@
(let merge (lambda '(one two) (Apply UdfTopMerge one two)))
(let finish (lambda '(state) (Apply UdfTopGetResult state)))
- (return (AggregationTraits value_type init update save load merge finish (List (ListType payload_type))))
+ (return (AggregationTraits value_type init update save load merge finish (List (ListType payload_type))))
))))
-# list_type:type n:double
-# doesn't support optional values
-(let percentile_traits_factory_raw (lambda '(list_type n) (block '(
+# list_type:type n:double
+# doesn't support optional values
+(let percentile_traits_factory_raw (lambda '(list_type n) (block '(
(let convert_into (lambda '(value) (MatchType (ListItemType list_type)
'Interval (lambda '() (SafeCast value (DataType 'Double)) ) # TODO:YQL-14129 cast to Decimal
(lambda '() value)
@@ -346,15 +346,15 @@
(let get_convert_percentile (lambda '(state n) (Apply convert_out (Apply (Udf 'Stat.TDigest_GetPercentile) state n))))
(let init (lambda '(value parent) (NamedApply (Udf 'Stat.TDigest_Create) '((Apply convert_into value)) (AsStruct) (DependsOn parent))))
(let update (lambda '(value state parent) (NamedApply (Udf 'Stat.TDigest_AddValue) '(state (Apply convert_into value)) (AsStruct) (DependsOn parent))))
- (let save (lambda '(state) (Apply (Udf 'Stat.TDigest_Serialize) state)))
- (let load (lambda '(state) (Apply (Udf 'Stat.TDigest_Deserialize) state)))
- (let merge (lambda '(one two) (Apply (Udf 'Stat.TDigest_Merge) one two)))
+ (let save (lambda '(state) (Apply (Udf 'Stat.TDigest_Serialize) state)))
+ (let load (lambda '(state) (Apply (Udf 'Stat.TDigest_Deserialize) state)))
+ (let merge (lambda '(one two) (Apply (Udf 'Stat.TDigest_Merge) one two)))
(let finish (lambda '(state) (MatchType n
'Tuple (lambda '() (StaticMap n (lambda '(n) (Apply get_convert_percentile state n))))
(lambda '() (Apply get_convert_percentile state n)))))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
+))))
+
# list_type:type
# doesn't support optional values
(let hyperloglog_traits_factory_raw (lambda '(list_type precision) (block '(
@@ -367,14 +367,14 @@
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
))))
-# list_type:type value:lambda weight:lambda intervals:integer
-# doesn't support optional values
-(let histogram_adaptive_ward_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveWardHistogram value weight intervals)))
-(let histogram_adaptive_weight_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveWeightHistogram value weight intervals)))
-(let histogram_adaptive_distance_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveDistanceHistogram value weight intervals)))
-(let histogram_block_ward_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.BlockWardHistogram value weight intervals)))
-(let histogram_block_weight_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.BlockWeightHistogram value weight intervals)))
-
+# list_type:type value:lambda weight:lambda intervals:integer
+# doesn't support optional values
+(let histogram_adaptive_ward_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveWardHistogram value weight intervals)))
+(let histogram_adaptive_weight_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveWeightHistogram value weight intervals)))
+(let histogram_adaptive_distance_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.AdaptiveDistanceHistogram value weight intervals)))
+(let histogram_block_ward_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.BlockWardHistogram value weight intervals)))
+(let histogram_block_weight_traits_factory_raw (lambda '(list_type value weight intervals) (Apply histogram_traits_factory_raw list_type 'Histogram.BlockWeightHistogram value weight intervals)))
+
# list_type:type histogram:atom value:lamba binsize:double minimum:double maximum:double
# doesn't support optional values
(let histogram_linear_traits_factory_impl (lambda '(list_type histogram value binsize minimum maximum) (block '(
@@ -392,61 +392,61 @@
(let histogram_linear_traits_factory_raw (lambda '(list_type value binsize minimum maximum) (Apply histogram_linear_traits_factory_impl list_type 'Histogram.LinearHistogram value binsize minimum maximum)))
(let histogram_logarithmic_traits_factory_raw (lambda '(list_type value binsize minimum maximum) (Apply histogram_linear_traits_factory_impl list_type 'Histogram.LogarithmicHistogram value binsize minimum maximum)))
-# list_type:type factory:lambda
-# support optional values
-(let optional_traits_factory (lambda '(list_type factory) (block '(
- (let item_type (ListItemType list_type))
+# list_type:type factory:lambda
+# support optional values
+(let optional_traits_factory (lambda '(list_type factory) (block '(
+ (let item_type (ListItemType list_type))
(let traits (Apply factory (MatchType item_type 'Optional (lambda '() (ListType (OptionalItemType item_type))) (lambda '() (ListType item_type)))))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let save (NthArg '3 traits))
- (let load (NthArg '4 traits))
- (let merge (NthArg '5 traits))
- (let finish (NthArg '6 traits))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let save (NthArg '3 traits))
+ (let load (NthArg '4 traits))
+ (let merge (NthArg '5 traits))
+ (let finish (NthArg '6 traits))
(let defval (NthArg '7 traits))
-
- (let init_optional
- (lambda '(value)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent value
- (lambda '(value) (Just (Apply init value)))
- (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value)))))))
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply init value))
- )
- )
- )
-
- (let update_optional
- (lambda '(value state)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent state
- (lambda '(state)
- (IfPresent value
- (lambda '(value) (Just (Apply update value state)))
- (Just state)
- )
- )
- (Apply init_optional value)
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply update value state))
- )
- )
- )
-
- (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
- (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
- (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
- (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
+
+ (let init_optional
+ (lambda '(value)
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent value
+ (lambda '(value) (Just (Apply init value)))
+ (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value)))))))
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply init value))
+ )
+ )
+ )
+
+ (let update_optional
+ (lambda '(value state)
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent state
+ (lambda '(state)
+ (IfPresent value
+ (lambda '(value) (Just (Apply update value state)))
+ (Just state)
+ )
+ )
+ (Apply init_optional value)
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply update value state))
+ )
+ )
+ )
+
+ (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
+ (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
+ (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
+ (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
(return (AggregationTraits item_type init_optional update_optional save_optional load_optional merge_optional finish_optional defval))
-))))
-
+))))
+
# list_type:type factory:lambda
# support optional values, init and update with parent
(let optional_traits_factory_parent (lambda '(list_type factory) (block '(
@@ -462,14 +462,69 @@
(let init_optional
(lambda '(value parent)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent value
+ (lambda '(value) (Just (Apply init value parent)))
+ (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply init value parent))
+ )
+ )
+ )
+
+ (let update_optional
+ (lambda '(value state parent)
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent state
+ (lambda '(state)
+ (IfPresent value
+ (lambda '(value) (Just (Apply update value state parent)))
+ (Just state)
+ )
+ )
+ (Apply init_optional value parent)
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply update value state parent))
+ )
+ )
+ )
+
+ (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
+ (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
+ (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
+ (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
+ (return (AggregationTraits item_type init_optional update_optional save_optional load_optional merge_optional finish_optional defval))
+))))
+
+# list_type:type factory:lambda
+# support optional values, init and update with parent
+(let flatten_traits_factory_parent (lambda '(list_type factory) (block '(
+ (let item_type (ListItemType list_type))
+ (let traits (Apply factory (MatchType item_type 'Optional (lambda '() (ListType (OptionalItemType item_type))) (lambda '() (ListType item_type)))))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let save (NthArg '3 traits))
+ (let load (NthArg '4 traits))
+ (let merge (NthArg '5 traits))
+ (let finish (NthArg '6 traits))
+ (let defval (NthArg '7 traits))
+
+ (let init_optional
+ (lambda '(value parent)
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent value
(lambda '(value) (Just (Apply init value parent)))
(Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply init value parent))
)
)
@@ -477,8 +532,8 @@
(let update_optional
(lambda '(value state parent)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent state
(lambda '(state)
(IfPresent value
@@ -489,130 +544,75 @@
(Apply init_optional value parent)
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply update value state parent))
)
)
)
- (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
- (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
- (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
- (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
+ (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
+ (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
+ (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
+ (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (FlatMap state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
(return (AggregationTraits item_type init_optional update_optional save_optional load_optional merge_optional finish_optional defval))
))))
-# list_type:type factory:lambda
-# support optional values, init and update with parent
-(let flatten_traits_factory_parent (lambda '(list_type factory) (block '(
- (let item_type (ListItemType list_type))
- (let traits (Apply factory (MatchType item_type 'Optional (lambda '() (ListType (OptionalItemType item_type))) (lambda '() (ListType item_type)))))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let save (NthArg '3 traits))
- (let load (NthArg '4 traits))
- (let merge (NthArg '5 traits))
- (let finish (NthArg '6 traits))
- (let defval (NthArg '7 traits))
-
- (let init_optional
- (lambda '(value parent)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent value
- (lambda '(value) (Just (Apply init value parent)))
- (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply init value parent))
- )
- )
- )
-
- (let update_optional
- (lambda '(value state parent)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent state
- (lambda '(state)
- (IfPresent value
- (lambda '(value) (Just (Apply update value state parent)))
- (Just state)
- )
- )
- (Apply init_optional value parent)
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply update value state parent))
- )
- )
- )
-
- (let save_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
- (let load_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
- (let merge_optional (lambda '(one two) (MatchType item_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
- (let finish_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (FlatMap state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
- (return (AggregationTraits item_type init_optional update_optional save_optional load_optional merge_optional finish_optional defval))
-))))
-
-# list_type:type
-# support optional values
+# list_type:type
+# support optional values
(let min_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (AggrMin one two)))))
(let max_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (AggrMax one two)))))
(let sum_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory_map list_type (lambda '(one two) (AggrAdd one two)) (lambda '(x) (WidenIntegral x)) )))
-(let bit_and_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_and_traits_factory_raw)))
-(let bit_or_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_or_traits_factory_raw)))
-(let bit_xor_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_xor_traits_factory_raw)))
-(let avg_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type avg_traits_factory_raw)))
-(let variance_0_0_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_0_0_traits_factory_raw)))
-(let variance_1_0_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_1_0_traits_factory_raw)))
-(let variance_0_1_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_0_1_traits_factory_raw)))
-(let variance_1_1_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_1_1_traits_factory_raw)))
+(let bit_and_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_and_traits_factory_raw)))
+(let bit_or_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_or_traits_factory_raw)))
+(let bit_xor_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type bit_xor_traits_factory_raw)))
+(let avg_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type avg_traits_factory_raw)))
+(let variance_0_0_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_0_0_traits_factory_raw)))
+(let variance_1_0_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_1_0_traits_factory_raw)))
+(let variance_0_1_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_0_1_traits_factory_raw)))
+(let variance_1_1_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type variance_1_1_traits_factory_raw)))
(let correlation_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type correlation_traits_factory_raw)))
(let covariance_population_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type covariance_population_traits_factory_raw)))
(let covariance_sample_traits_factory_opt (lambda '(list_type) (Apply optional_traits_factory list_type covariance_sample_traits_factory_raw)))
-
-# list_type:type n:double
-# support optional values
+
+# list_type:type n:double
+# support optional values
(let percentile_traits_factory_opt (lambda '(list_type n) (Apply optional_traits_factory_parent list_type (lambda '(list_type) (Apply percentile_traits_factory_raw list_type n)))))
-
+
# list_type:type count:ui32
# support optional values
-(let set_traits_factory_opt (lambda '(list_type count) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply set_traits_factory_raw list_type count)))))
+(let set_traits_factory_opt (lambda '(list_type count) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply set_traits_factory_raw list_type count)))))
# list_type:type n:ui32 buffer:ui32
# support optional values
-(let topfreq_traits_factory_opt (lambda '(list_type n buffer) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply topfreq_traits_factory_raw list_type n buffer)))))
+(let topfreq_traits_factory_opt (lambda '(list_type n buffer) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply topfreq_traits_factory_raw list_type n buffer)))))
# list_type:type
# support optional values
(let hyperloglog_traits_factory_opt (lambda '(list_type precision) (Apply optional_traits_factory_parent list_type (lambda '(list_type) (Apply hyperloglog_traits_factory_raw list_type precision)))))
-# list_type:type init:lambda update:lambda merge:lambda finish:lambda save:lambda load:lambda
-# support optional values
+# list_type:type init:lambda update:lambda merge:lambda finish:lambda save:lambda load:lambda
+# support optional values
(let udaf_traits_factory_opt (lambda '(list_type init update merge finish save load defval) (Apply optional_traits_factory_parent list_type (lambda '(list_type)
(AggregationTraits (ListItemType list_type) init update save load merge finish defval)))))
-
-# list_type:type, factory:lambda, extractor:lambda
-(let extractor_traits_factory (lambda '(list_type extractor factory) (block '(
- (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let save (NthArg '3 traits))
- (let load (NthArg '4 traits))
- (let merge (NthArg '5 traits))
- (let finish (NthArg '6 traits))
+
+# list_type:type, factory:lambda, extractor:lambda
+(let extractor_traits_factory (lambda '(list_type extractor factory) (block '(
+ (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let save (NthArg '3 traits))
+ (let load (NthArg '4 traits))
+ (let merge (NthArg '5 traits))
+ (let finish (NthArg '6 traits))
(let defval (NthArg '7 traits))
- (let init_ext (lambda '(row) (Apply init (Apply extractor row))))
- (let update_ext (lambda '(row state) (Apply update (Apply extractor row) state)))
- (return (AggregationTraits (ListItemType list_type) init_ext update_ext save load merge finish defval))
-))))
-
+ (let init_ext (lambda '(row) (Apply init (Apply extractor row))))
+ (let update_ext (lambda '(row state) (Apply update (Apply extractor row) state)))
+ (return (AggregationTraits (ListItemType list_type) init_ext update_ext save load merge finish defval))
+))))
+
# list_type:type, factory:lambda, extractor:lambda
(let extractor_traits_factory_parent (lambda '(list_type extractor factory) (block '(
- (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
+ (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
(let init (NthArg '1 traits))
(let update (NthArg '2 traits))
(let save (NthArg '3 traits))
@@ -622,39 +622,39 @@
(let defval (NthArg '7 traits))
(let init_ext (lambda '(row parent) (Apply init (Apply extractor row) parent)))
(let update_ext (lambda '(row state parent) (Apply update (Apply extractor row) state parent)))
- (return (AggregationTraits (ListItemType list_type) init_ext update_ext save load merge finish defval))
+ (return (AggregationTraits (ListItemType list_type) init_ext update_ext save load merge finish defval))
))))
-# list_type:type, extractor:lambda
-# support optional columns
-(let min_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor min_traits_factory_opt)))
-(let max_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor max_traits_factory_opt)))
-(let sum_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor sum_traits_factory_opt)))
-(let count_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_traits_factory_opt)))
-(let count_all_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_all_traits_factory_opt)))
-(let count_if_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_if_traits_factory_opt)))
-(let some_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor some_traits_factory_raw)))
-(let bit_and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_and_traits_factory_opt)))
-(let bit_or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_or_traits_factory_opt)))
-(let bit_xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_xor_traits_factory_opt)))
-(let and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_and_traits_factory_opt)))
-(let or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_or_traits_factory_opt)))
-(let xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_xor_traits_factory_opt)))
-(let avg_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor avg_traits_factory_opt)))
+# list_type:type, extractor:lambda
+# support optional columns
+(let min_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor min_traits_factory_opt)))
+(let max_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor max_traits_factory_opt)))
+(let sum_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor sum_traits_factory_opt)))
+(let count_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_traits_factory_opt)))
+(let count_all_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_all_traits_factory_opt)))
+(let count_if_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor count_if_traits_factory_opt)))
+(let some_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor some_traits_factory_raw)))
+(let bit_and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_and_traits_factory_opt)))
+(let bit_or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_or_traits_factory_opt)))
+(let bit_xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_xor_traits_factory_opt)))
+(let and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_and_traits_factory_opt)))
+(let or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_or_traits_factory_opt)))
+(let xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_xor_traits_factory_opt)))
+(let avg_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor avg_traits_factory_opt)))
(let list_traits_factory (lambda '(list_type extractor limit) (Apply extractor_traits_factory list_type extractor (Apply list_traits_factory_opt_gen limit (Null)))))
(let list2_traits_factory (lambda '(list_type extractor limit) (Apply extractor_traits_factory list_type extractor (Apply list_traits_factory_opt_gen limit empty_list))))
-(let variance_0_0_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_0_0_traits_factory_opt)))
-(let variance_1_0_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_1_0_traits_factory_opt)))
-(let variance_0_1_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_0_1_traits_factory_opt)))
-(let variance_1_1_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_1_1_traits_factory_opt)))
+(let variance_0_0_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_0_0_traits_factory_opt)))
+(let variance_1_0_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_1_0_traits_factory_opt)))
+(let variance_0_1_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_0_1_traits_factory_opt)))
+(let variance_1_1_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor variance_1_1_traits_factory_opt)))
(let correlation_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor correlation_traits_factory_opt)))
(let covariance_population_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor covariance_population_traits_factory_opt)))
(let covariance_sample_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor covariance_sample_traits_factory_opt)))
-
-# list_type:type extractor:lambda n:double
-# support optional values
+
+# list_type:type extractor:lambda n:double
+# support optional values
(let percentile_traits_factory (lambda '(list_type extractor n) (Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type) (Apply percentile_traits_factory_opt list_type n)))))
-
+
# list_type:type extractor:lambda count:ui32
# support optional values
(let set_traits_factory (lambda '(list_type extractor count) (Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type) (Apply set_traits_factory_opt list_type count)))))
@@ -667,80 +667,80 @@
# support optional values
(let hyperloglog_traits_factory (lambda '(list_type extractor precision) (Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type) (Apply hyperloglog_traits_factory_opt list_type precision)))))
-# list_type:type extractor:lambda init:lambda update:lambda merge:lambda finish:lambda save:lambda load:lambda
-# support optional values
+# list_type:type extractor:lambda init:lambda update:lambda merge:lambda finish:lambda save:lambda load:lambda
+# support optional values
(let udaf_traits_factory (lambda '(list_type extractor init update merge finish save load defval) (Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type) (Apply udaf_traits_factory_opt list_type init update merge finish save load defval)))))
-
-# list_type:type compare:lambda first:lambda second:lambda stub
-# doesn't support optional values
-(let compare_traits_factory_raw (lambda '(list_type compare first second stub) (block '(
- (let key_type (TypeOf (Apply first (InstanceOf (ListItemType list_type)))))
- (let init (lambda '(row) '((Apply second row) (Apply first row))))
- (let update (lambda '(row state) (If (Apply compare (Apply first row) (Nth state '1)) (Apply init row) state)))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
- (let merge (lambda '(one two) (If (Apply compare (Nth one '1) (Nth two '1)) one two)))
- (let finish (lambda '(state) (Nth state '0)))
+
+# list_type:type compare:lambda first:lambda second:lambda stub
+# doesn't support optional values
+(let compare_traits_factory_raw (lambda '(list_type compare first second stub) (block '(
+ (let key_type (TypeOf (Apply first (InstanceOf (ListItemType list_type)))))
+ (let init (lambda '(row) '((Apply second row) (Apply first row))))
+ (let update (lambda '(row state) (If (Apply compare (Apply first row) (Nth state '1)) (Apply init row) state)))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
+ (let merge (lambda '(one two) (If (Apply compare (Nth one '1) (Nth two '1)) one two)))
+ (let finish (lambda '(state) (Nth state '0)))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
-# list_type:type compare:lambda first:lambda second:lambda limit:Uint64
-# doesn't support optional values
-(let compare_traits_factory_list_raw (lambda '(list_type compare first second limit) (block '(
- (let key_type (TypeOf (Apply first (InstanceOf (ListItemType list_type)))))
- (let init (lambda '(row) '((AsList (Apply second row)) (Apply first row))))
+))))
+
+# list_type:type compare:lambda first:lambda second:lambda limit:Uint64
+# doesn't support optional values
+(let compare_traits_factory_list_raw (lambda '(list_type compare first second limit) (block '(
+ (let key_type (TypeOf (Apply first (InstanceOf (ListItemType list_type)))))
+ (let init (lambda '(row) '((AsList (Apply second row)) (Apply first row))))
(let update (lambda '(row state) (If (AggrEquals (Apply first row) (Nth state '1)) '((Take (Insert (Nth state '0) (Apply second row)) limit) (Nth state '1)) (If (Apply compare (Apply first row) (Nth state '1)) (Apply init row) state))))
- (let save (lambda '(state) state))
- (let load (lambda '(state) state))
+ (let save (lambda '(state) state))
+ (let load (lambda '(state) state))
(let merge (lambda '(one two) (If (AggrEquals (Nth one '1) (Nth two '1)) '((Take (Extend (Nth one '0) (Nth two '0)) limit) (Nth one '1)) (If (Apply compare (Nth one '1) (Nth two '1)) one two))))
- (let finish (lambda '(state) (Nth state '0)))
+ (let finish (lambda '(state) (Nth state '0)))
(return (AggregationTraits (ListItemType list_type) init update save load merge finish (Null)))
-))))
-
-# factory:lambda list_type:type first:lambda second:lambda
-# support optional values
-(let double_traits_factory_opt (lambda '(factory list_type first second) (block '(
- (let item_type (ListItemType list_type))
- (let key_type (TypeOf (Apply first (InstanceOf item_type))))
+))))
+
+# factory:lambda list_type:type first:lambda second:lambda
+# support optional values
+(let double_traits_factory_opt (lambda '(factory list_type first second) (block '(
+ (let item_type (ListItemType list_type))
+ (let key_type (TypeOf (Apply first (InstanceOf item_type))))
(let test_type (MatchType item_type 'Optional (lambda '() item_type) (lambda '() key_type)))
(let traits (Apply factory (ListType (MatchType item_type 'Optional (lambda '() (OptionalItemType item_type)) (lambda '() item_type)))
- (lambda '(row) (MatchType key_type 'Optional
- (lambda '() (Unwrap (Apply first row)))
- (lambda '() (Apply first row))
- ))
- second
- ))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let save (NthArg '3 traits))
- (let load (NthArg '4 traits))
- (let merge (NthArg '5 traits))
- (let finish (NthArg '6 traits))
+ (lambda '(row) (MatchType key_type 'Optional
+ (lambda '() (Unwrap (Apply first row)))
+ (lambda '() (Apply first row))
+ ))
+ second
+ ))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let save (NthArg '3 traits))
+ (let load (NthArg '4 traits))
+ (let merge (NthArg '5 traits))
+ (let finish (NthArg '6 traits))
(let defval (NthArg '7 traits))
-
- (let init_opt (lambda '(row) (MatchType test_type 'Optional
- (lambda '() (Map (Apply first row) (lambda '(key) (Apply init row))))
- (lambda '() (Apply init row))
- )))
- (let update_opt (lambda '(row state)
- (MatchType test_type 'Optional
- (lambda '() (IfPresent state (lambda '(state) (Just (If (Exists (Apply first row)) (Apply update row state) state))) (Apply init_opt row)))
- (lambda '() (Apply update row state))
- )
- ))
- (let save_opt (lambda '(state) (MatchType test_type 'Optional (lambda '() (Map state save)) (lambda '() (Apply save state)))))
- (let load_opt (lambda '(state) (MatchType test_type 'Optional (lambda '() (Map state load)) (lambda '() (Apply load state)))))
- (let merge_opt (lambda '(one two) (MatchType test_type 'Optional (lambda '() (OptionalReduce one two merge)) (lambda '() (Apply merge one two)))))
- (let finish_opt (lambda '(state) (MatchType test_type 'Optional
- (lambda '() (MatchType (TypeOf (Apply finish (InstanceOf (OptionalItemType (TypeOf state))))) 'Optional
- (lambda '() (FlatMap state finish))
- (lambda '() (Map state finish))
- ))
- (lambda '() (Apply finish state))
- )))
+
+ (let init_opt (lambda '(row) (MatchType test_type 'Optional
+ (lambda '() (Map (Apply first row) (lambda '(key) (Apply init row))))
+ (lambda '() (Apply init row))
+ )))
+ (let update_opt (lambda '(row state)
+ (MatchType test_type 'Optional
+ (lambda '() (IfPresent state (lambda '(state) (Just (If (Exists (Apply first row)) (Apply update row state) state))) (Apply init_opt row)))
+ (lambda '() (Apply update row state))
+ )
+ ))
+ (let save_opt (lambda '(state) (MatchType test_type 'Optional (lambda '() (Map state save)) (lambda '() (Apply save state)))))
+ (let load_opt (lambda '(state) (MatchType test_type 'Optional (lambda '() (Map state load)) (lambda '() (Apply load state)))))
+ (let merge_opt (lambda '(one two) (MatchType test_type 'Optional (lambda '() (OptionalReduce one two merge)) (lambda '() (Apply merge one two)))))
+ (let finish_opt (lambda '(state) (MatchType test_type 'Optional
+ (lambda '() (MatchType (TypeOf (Apply finish (InstanceOf (OptionalItemType (TypeOf state))))) 'Optional
+ (lambda '() (FlatMap state finish))
+ (lambda '() (Map state finish))
+ ))
+ (lambda '() (Apply finish state))
+ )))
(return (AggregationTraits item_type init_opt update_opt save_opt load_opt merge_opt finish_opt defval))
-))))
-
+))))
+
# factory:lambda list_type:type first:lambda second:lambda
# support optional values, init and update has parent arg
(let double_traits_factory_opt_parent (lambda '(factory list_type first second) (block '(
@@ -779,61 +779,61 @@
(return (AggregationTraits item_type init_opt update_opt save_opt load_opt merge_opt finish_opt defval))
))))
-# factory:lambda list_type:type first:lambda second:lambda
-# support optional values, init and update has parent arg
-(let list_by_traits_factory_opt_parent (lambda '(factory list_type first second) (block '(
- (let item_type (ListItemType list_type))
- (let key_type (TypeOf (Apply first (InstanceOf item_type))))
- (let traits (Apply factory list_type first second))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let save (NthArg '3 traits))
- (let load (NthArg '4 traits))
- (let merge (NthArg '5 traits))
- (let finish (NthArg '6 traits))
- (let defval (NthArg '7 traits))
-
- (let init_opt (lambda '(row parent) (MatchType key_type
- 'Optional (lambda '()
- (IfPresent (Apply first row)
- (lambda '(key) (Just (Apply init row parent)))
- (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (TypeOf row)) parent))))
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply init row parent))
- )))
- (let update_opt (lambda '(row state parent) (MatchType key_type
- 'Optional (lambda '()
- (IfPresent state
- (lambda '(state)
- (IfPresent (Apply first row)
- (lambda '(key) (Just (Apply update row state parent)))
- (Just state)
- )
- )
- (Apply init_opt row parent)
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply update row state parent))
- )))
-
- (let save_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
- (let load_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
- (let merge_opt (lambda '(one two) (MatchType key_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
- (let finish_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (FlatMap state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
- (return (AggregationTraits item_type init_opt update_opt save_opt load_opt merge_opt finish_opt defval))
-))))
-
-# list_type:type value:lambda weight:lambda intervals:integer
-# support optional values
+# factory:lambda list_type:type first:lambda second:lambda
+# support optional values, init and update has parent arg
+(let list_by_traits_factory_opt_parent (lambda '(factory list_type first second) (block '(
+ (let item_type (ListItemType list_type))
+ (let key_type (TypeOf (Apply first (InstanceOf item_type))))
+ (let traits (Apply factory list_type first second))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let save (NthArg '3 traits))
+ (let load (NthArg '4 traits))
+ (let merge (NthArg '5 traits))
+ (let finish (NthArg '6 traits))
+ (let defval (NthArg '7 traits))
+
+ (let init_opt (lambda '(row parent) (MatchType key_type
+ 'Optional (lambda '()
+ (IfPresent (Apply first row)
+ (lambda '(key) (Just (Apply init row parent)))
+ (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (TypeOf row)) parent))))
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply init row parent))
+ )))
+ (let update_opt (lambda '(row state parent) (MatchType key_type
+ 'Optional (lambda '()
+ (IfPresent state
+ (lambda '(state)
+ (IfPresent (Apply first row)
+ (lambda '(key) (Just (Apply update row state parent)))
+ (Just state)
+ )
+ )
+ (Apply init_opt row parent)
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply update row state parent))
+ )))
+
+ (let save_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (Map state save)) 'Null (lambda '() defval) (lambda '() (Apply save state)))))
+ (let load_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (Map state load)) 'Null (lambda '() defval) (lambda '() (Apply load state)))))
+ (let merge_opt (lambda '(one two) (MatchType key_type 'Optional (lambda '() (OptionalReduce one two merge)) 'Null (lambda '() defval) (lambda '() (Apply merge one two)))))
+ (let finish_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (FlatMap state finish)) 'Null (lambda '() defval) (lambda '() (Apply finish state)))))
+ (return (AggregationTraits item_type init_opt update_opt save_opt load_opt merge_opt finish_opt defval))
+))))
+
+# list_type:type value:lambda weight:lambda intervals:integer
+# support optional values
(let histogram_adaptive_ward_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_adaptive_ward_traits_factory_raw list_type value weight intervals)) list_type value weight)))
(let histogram_adaptive_weight_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_adaptive_weight_traits_factory_raw list_type value weight intervals)) list_type value weight)))
(let histogram_adaptive_distance_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_adaptive_distance_traits_factory_raw list_type value weight intervals)) list_type value weight)))
(let histogram_block_ward_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_block_ward_traits_factory_raw list_type value weight intervals)) list_type value weight)))
(let histogram_block_weight_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_block_weight_traits_factory_raw list_type value weight intervals)) list_type value weight)))
-
+
# list_type:type value:lambda binsize:double minimum:double maximum:double
# support optional values
(let histogram_linear_traits_factory (lambda '(list_type value binsize minimum maximum) (Apply double_traits_factory_opt_parent (lambda '(list_type value binsize) (Apply histogram_linear_traits_factory_raw list_type value binsize minimum maximum)) list_type value binsize)))
@@ -841,13 +841,13 @@
(let compare_by_traits_factory_opt (lambda '(list_type compare first second limit) (Apply double_traits_factory_opt (lambda '(list_type first second) (Apply compare_traits_factory_raw list_type compare first second limit)) list_type first second)))
(let list_compare_by_traits_factory_opt (lambda '(list_type compare first second limit) (Apply double_traits_factory_opt (lambda '(list_type first second) (Apply compare_traits_factory_list_raw list_type compare first second limit)) list_type first second)))
-
+
# deprecated
-(let compare_by_traits_factory (lambda '(list_type compare first second limit) (IfType limit (VoidType)
+(let compare_by_traits_factory (lambda '(list_type compare first second limit) (IfType limit (VoidType)
(lambda '() (Apply compare_by_traits_factory_opt list_type compare first second limit))
(lambda '() (Apply list_compare_by_traits_factory_opt list_type compare first second limit))
-)))
-
+)))
+
# deprecated
(let min_by_traits_factory (lambda '(list_type first second limit) (Apply compare_by_traits_factory list_type (lambda '(one two) (AggrLess one two)) first second limit)))
(let max_by_traits_factory (lambda '(list_type first second limit) (Apply compare_by_traits_factory list_type (lambda '(one two) (AggrLess two one)) first second limit)))
@@ -866,10 +866,10 @@
(Apply sum_traits_factory list_type (lambda '(value) (FlatOptionalIf (Coalesce (Apply predicate value) (Bool '0)) (block '(
(let pl (Apply payload value))
(return (MatchType pl 'Optional (lambda '() pl) (lambda '() (Just pl)))))))))))
-
+
(let top_bottom_traits_factory (lambda '(list_type extractor count is_top)
(Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type)
- (Apply flatten_traits_factory_parent list_type (lambda '(list_type)
+ (Apply flatten_traits_factory_parent list_type (lambda '(list_type)
(Apply top_traits_factory_raw list_type extractor count is_top)))))))
(let top_traits_factory (lambda '(list_type extractor count)
@@ -879,7 +879,7 @@
(Apply top_bottom_traits_factory list_type extractor count '0)))
(let top_bottom_by_traits_factory (lambda '(list_type key_extractor payload_extractor count is_top)
- (Apply list_by_traits_factory_opt_parent (lambda '(list_type key_extractor payload_extractor)
+ (Apply list_by_traits_factory_opt_parent (lambda '(list_type key_extractor payload_extractor)
(Apply top_by_traits_factory_raw list_type key_extractor payload_extractor count is_top)) list_type key_extractor payload_extractor)))
(let top_by_traits_factory (lambda '(list_type key_extractor payload_extractor count)
@@ -888,46 +888,46 @@
(let bottom_by_traits_factory (lambda '(list_type key_extractor payload_extractor count)
(Apply top_bottom_by_traits_factory list_type key_extractor payload_extractor count '0)))
-(export min_traits_factory)
-(export max_traits_factory)
-(export sum_traits_factory)
+(export min_traits_factory)
+(export max_traits_factory)
+(export sum_traits_factory)
(export sum_if_traits_factory)
-(export count_traits_factory)
-(export count_all_traits_factory)
-(export count_if_traits_factory)
-(export some_traits_factory)
-(export bit_and_traits_factory)
-(export bit_or_traits_factory)
-(export bit_xor_traits_factory)
-(export and_traits_factory)
-(export or_traits_factory)
-(export xor_traits_factory)
-(export avg_traits_factory)
+(export count_traits_factory)
+(export count_all_traits_factory)
+(export count_if_traits_factory)
+(export some_traits_factory)
+(export bit_and_traits_factory)
+(export bit_or_traits_factory)
+(export bit_xor_traits_factory)
+(export and_traits_factory)
+(export or_traits_factory)
+(export xor_traits_factory)
+(export avg_traits_factory)
(export avg_if_traits_factory)
-(export list_traits_factory)
+(export list_traits_factory)
(export list2_traits_factory)
-(export min_by_traits_factory)
-(export max_by_traits_factory)
+(export min_by_traits_factory)
+(export max_by_traits_factory)
(export min_by_traits_factory1)
(export max_by_traits_factory1)
(export min_by_traits_factory2)
(export max_by_traits_factory2)
-(export variance_0_0_traits_factory)
-(export variance_1_0_traits_factory)
-(export variance_0_1_traits_factory)
-(export variance_1_1_traits_factory)
+(export variance_0_0_traits_factory)
+(export variance_1_0_traits_factory)
+(export variance_0_1_traits_factory)
+(export variance_1_1_traits_factory)
(export correlation_traits_factory)
(export covariance_population_traits_factory)
(export covariance_sample_traits_factory)
-(export histogram_adaptive_ward_traits_factory)
-(export histogram_adaptive_weight_traits_factory)
-(export histogram_adaptive_distance_traits_factory)
-(export histogram_block_ward_traits_factory)
-(export histogram_block_weight_traits_factory)
+(export histogram_adaptive_ward_traits_factory)
+(export histogram_adaptive_weight_traits_factory)
+(export histogram_adaptive_distance_traits_factory)
+(export histogram_block_ward_traits_factory)
+(export histogram_block_weight_traits_factory)
(export histogram_linear_traits_factory)
(export histogram_logarithmic_traits_factory)
-(export udaf_traits_factory)
-(export percentile_traits_factory)
+(export udaf_traits_factory)
+(export percentile_traits_factory)
(export set_traits_factory)
(export topfreq_traits_factory)
(export hyperloglog_traits_factory)
@@ -935,5 +935,5 @@
(export bottom_traits_factory)
(export top_by_traits_factory)
(export bottom_by_traits_factory)
-
-)
+
+)
diff --git a/ydb/library/yql/mount/lib/yql/core.yql b/ydb/library/yql/mount/lib/yql/core.yql
index 6645ad0e92..f12c459358 100644
--- a/ydb/library/yql/mount/lib/yql/core.yql
+++ b/ydb/library/yql/mount/lib/yql/core.yql
@@ -12,8 +12,8 @@
(let RemoveOptionalType (lambda '(type) (MatchType type 'Optional (lambda '() (OptionalItemType type)) (lambda '() type))))
(let MaskBit (lambda '(value index) (ShiftLeft (Data (Apply RemoveOptionalType (TypeOf value)) '1) index)))
-(let TestBitInt (lambda '(value index) (Convert (BitAnd value (Apply MaskBit value index)) 'Bool)))
-(let TestBitStr (lambda '(value index) (Apply TestBitInt (ByteAt value (Convert (ShiftRight (Convert index 'Uint64) (Uint8 '8)) 'Uint32)) (BitAnd (Convert index 'Uint8) (Uint8 '7)))))
+(let TestBitInt (lambda '(value index) (Convert (BitAnd value (Apply MaskBit value index)) 'Bool)))
+(let TestBitStr (lambda '(value index) (Apply TestBitInt (ByteAt value (Convert (ShiftRight (Convert index 'Uint64) (Uint8 '8)) 'Uint32)) (BitAnd (Convert index 'Uint8) (Uint8 '7)))))
(let TestBit (lambda '(value index) (block '(
(let x (InstanceOf (Apply RemoveOptionalType (TypeOf value))))
(return (IfType x (DataType 'String)
@@ -218,7 +218,7 @@ def signature(script, name):
(Map list (lambda '(x) (AsStruct '('Data x))))
'()
'('('Data (Apply factory (StructType '('Data (ListItemType (TypeOf list)))) (lambda '(x) (Member x 'Data)))))
- '('('compact))
+ '('('compact))
) 'Data))
)))
@@ -234,7 +234,7 @@ def signature(script, name):
(lambda '(row) (Map (Member row 'Data) (lambda '(item) (AsStruct '('Key (Member row 'Key)) '('Data item))))))
'('Key)
'('('Data (Apply factory (StructType '('Data (ListItemType (DictPayloadType (TypeOf dict))))) (lambda '(x) (Member x 'Data)))))
- '('('compact))
+ '('('compact))
)
(lambda '(x) (Member x 'Key)) (lambda '(x) (Member x 'Data)) '('Hashed 'One)
)))))
diff --git a/ydb/library/yql/mount/lib/yql/window.yql b/ydb/library/yql/mount/lib/yql/window.yql
index 37c0c38595..371f4c687c 100644
--- a/ydb/library/yql/mount/lib/yql/window.yql
+++ b/ydb/library/yql/mount/lib/yql/window.yql
@@ -38,7 +38,7 @@
# list_type:type, factory:lambda, extractor:lambda
(let extractor_traits_factory (lambda '(list_type extractor factory) (block '(
- (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
+ (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
(let init (NthArg '1 traits))
(let update (NthArg '2 traits))
(let shift (lambda '(value state) (Void)))
@@ -128,15 +128,15 @@
(let list_traits_factory_opt_gen (lambda '(limit defval) (block '(
(return (lambda '(list_type) (block '(
(let item_type (ListItemType list_type))
- (let init (lambda '(value) (MatchType item_type
- 'Optional (lambda '() (ToList value))
- 'Null (lambda '() (EmptyList))
- (lambda '() (AsList value)))))
+ (let init (lambda '(value) (MatchType item_type
+ 'Optional (lambda '() (ToList value))
+ 'Null (lambda '() (EmptyList))
+ (lambda '() (AsList value)))))
(let update (lambda '(value state) (block '(
- (let x (MatchType item_type
- 'Optional (lambda '() (IfPresent value (lambda '(value) (Insert state value)) state))
- 'Null (lambda '() (EmptyList))
- (lambda '() (Insert state value))))
+ (let x (MatchType item_type
+ 'Optional (lambda '() (IfPresent value (lambda '(value) (Insert state value)) state))
+ 'Null (lambda '() (EmptyList))
+ (lambda '() (Insert state value))))
(return (If (== limit (Uint64 '0)) x (Take x limit)))))))
(let shift (lambda '(value state) (Void)))
(let current (lambda '(state) state))
@@ -239,7 +239,7 @@
(let shift (lambda '(value state) (Void)))
(let current (lambda '(state) (Apply UdfSetGetResult state)))
- (return (WindowTraits value_type init update shift current (EmptyList)))
+ (return (WindowTraits value_type init update shift current (EmptyList)))
))))
# list_type:type n:ui32 buffer:ui32
@@ -259,7 +259,7 @@
(let shift (lambda '(value state) (Void)))
(let current (lambda '(state) (Apply UdfTopFreqGet state n)))
- (return (WindowTraits value_type init update shift current (EmptyList)))
+ (return (WindowTraits value_type init update shift current (EmptyList)))
))))
# list_type:type extractor:lambda count:ui32 is_top:atom
@@ -280,7 +280,7 @@
(let shift (lambda '(value state) (Void)))
(let current (lambda '(state) (Apply UdfTopGetResult state)))
- (return (WindowTraits value_type init update shift current (EmptyList)))
+ (return (WindowTraits value_type init update shift current (EmptyList)))
))))
# list_type:type key_extractor:lambda payload_extractor:lambda count:ui32 is_top:atom
@@ -304,7 +304,7 @@
(let shift (lambda '(value state) (Void)))
(let current (lambda '(state) (Apply UdfTopGetResult state)))
- (return (WindowTraits value_type init update shift current (List (ListType payload_type))))
+ (return (WindowTraits value_type init update shift current (List (ListType payload_type))))
))))
# list_type:type n:double
@@ -379,14 +379,14 @@
(let init_optional
(lambda '(value)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent value
(lambda '(value) (Just (Apply init value)))
(Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value)))))))
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply init value))
)
)
@@ -394,8 +394,8 @@
(let update_optional
(lambda '(value state)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent state
(lambda '(state)
(IfPresent value
@@ -406,7 +406,7 @@
(Apply init_optional value)
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply update value state))
)
)
@@ -415,7 +415,7 @@
# todo: fill the body
(let shift_optional (lambda '(value state) (Void)))
- (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
+ (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
(return (WindowTraits item_type init_optional update_optional shift_optional current_optional defval))
))))
@@ -432,14 +432,14 @@
(let init_optional
(lambda '(value parent)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent value
(lambda '(value) (Just (Apply init value parent)))
(Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply init value parent))
)
)
@@ -449,8 +449,8 @@
(let update_optional
(lambda '(value state parent)
- (MatchType item_type
- 'Optional (lambda '()
+ (MatchType item_type
+ 'Optional (lambda '()
(IfPresent state
(lambda '(state)
(IfPresent value
@@ -461,68 +461,68 @@
(Apply init_optional value parent)
)
)
- 'Null (lambda '() defval)
+ 'Null (lambda '() defval)
(lambda '() (Apply update value state parent))
)
)
)
- (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
+ (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (Map state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
+ (return (WindowTraits item_type init_optional update_optional shift_optional current_optional defval))
+))))
+
+# list_type:type factory:lambda
+# support optional values, init and update with parent
+(let flatten_traits_factory_parent (lambda '(list_type factory) (block '(
+ (let item_type (ListItemType list_type))
+ (let traits (Apply factory (MatchType item_type 'Optional (lambda '() (ListType (OptionalItemType item_type))) (lambda '() (ListType item_type)))))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let shift (NthArg '3 traits))
+ (let current (NthArg '4 traits))
+ (let defval (NthArg '5 traits))
+
+ (let init_optional
+ (lambda '(value parent)
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent value
+ (lambda '(value) (Just (Apply init value parent)))
+ (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply init value parent))
+ )
+ )
+ )
+
+ (let shift_optional (lambda '(value state) (Void)))
+
+ (let update_optional
+ (lambda '(value state parent)
+ (MatchType item_type
+ 'Optional (lambda '()
+ (IfPresent state
+ (lambda '(state)
+ (IfPresent value
+ (lambda '(value) (Just (Apply update value state parent)))
+ (Just state)
+ )
+ )
+ (Apply init_optional value parent)
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply update value state parent))
+ )
+ )
+ )
+
+ (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (FlatMap state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
(return (WindowTraits item_type init_optional update_optional shift_optional current_optional defval))
))))
-# list_type:type factory:lambda
-# support optional values, init and update with parent
-(let flatten_traits_factory_parent (lambda '(list_type factory) (block '(
- (let item_type (ListItemType list_type))
- (let traits (Apply factory (MatchType item_type 'Optional (lambda '() (ListType (OptionalItemType item_type))) (lambda '() (ListType item_type)))))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let shift (NthArg '3 traits))
- (let current (NthArg '4 traits))
- (let defval (NthArg '5 traits))
-
- (let init_optional
- (lambda '(value parent)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent value
- (lambda '(value) (Just (Apply init value parent)))
- (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (OptionalItemType (TypeOf value))) parent))))
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply init value parent))
- )
- )
- )
-
- (let shift_optional (lambda '(value state) (Void)))
-
- (let update_optional
- (lambda '(value state parent)
- (MatchType item_type
- 'Optional (lambda '()
- (IfPresent state
- (lambda '(state)
- (IfPresent value
- (lambda '(value) (Just (Apply update value state parent)))
- (Just state)
- )
- )
- (Apply init_optional value parent)
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply update value state parent))
- )
- )
- )
-
- (let current_optional (lambda '(state) (MatchType item_type 'Optional (lambda '() (FlatMap state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
- (return (WindowTraits item_type init_optional update_optional shift_optional current_optional defval))
-))))
-
# list_type:type
# support optional values
(let min_traits_factory_opt (lambda '(list_type) (Apply simple_traits_factory list_type (lambda '(one two) (AggrMin one two)))))
@@ -552,11 +552,11 @@
# list_type:type count:ui32
# support optional values
-(let set_traits_factory_opt (lambda '(list_type count) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply set_traits_factory_raw list_type count)))))
+(let set_traits_factory_opt (lambda '(list_type count) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply set_traits_factory_raw list_type count)))))
# list_type:type n:ui32 buffer:ui32
# support optional values
-(let topfreq_traits_factory_opt (lambda '(list_type n buffer) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply topfreq_traits_factory_raw list_type n buffer)))))
+(let topfreq_traits_factory_opt (lambda '(list_type n buffer) (Apply flatten_traits_factory_parent list_type (lambda '(list_type) (Apply topfreq_traits_factory_raw list_type n buffer)))))
# list_type:type
# support optional values
@@ -568,7 +568,7 @@
# list_type:type, factory:lambda, extractor:lambda
(let extractor_traits_factory (lambda '(list_type extractor factory) (block '(
- (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
+ (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
(let init (NthArg '1 traits))
(let update (NthArg '2 traits))
(let shift (NthArg '3 traits))
@@ -577,12 +577,12 @@
(let init_ext (lambda '(row) (Apply init (Apply extractor row))))
(let update_ext (lambda '(row state) (Apply update (Apply extractor row) state)))
(let shift_ext (lambda '(row state) (Apply shift (Apply extractor row) state)))
- (return (WindowTraits (ListItemType list_type) init_ext update_ext shift_ext current defval))
+ (return (WindowTraits (ListItemType list_type) init_ext update_ext shift_ext current defval))
))))
# list_type:type, factory:lambda, extractor:lambda
(let extractor_traits_factory_parent (lambda '(list_type extractor factory) (block '(
- (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
+ (let traits (Apply factory (ListType (TypeOf (Apply extractor (InstanceOf (ListItemType list_type)))))))
(let init (NthArg '1 traits))
(let update (NthArg '2 traits))
(let shift (NthArg '3 traits))
@@ -591,7 +591,7 @@
(let init_ext (lambda '(row parent) (Apply init (Apply extractor row) parent)))
(let update_ext (lambda '(row state parent) (Apply update (Apply extractor row) state parent)))
(let shift_ext (lambda '(row state) (Apply shift (Apply extractor row) state)))
- (return (WindowTraits (ListItemType list_type) init_ext update_ext shift_ext current defval))
+ (return (WindowTraits (ListItemType list_type) init_ext update_ext shift_ext current defval))
))))
# list_type:type, extractor:lambda
@@ -606,9 +606,9 @@
(let bit_and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_and_traits_factory_opt)))
(let bit_or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_or_traits_factory_opt)))
(let bit_xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor bit_xor_traits_factory_opt)))
-(let and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_and_traits_factory_opt)))
-(let or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_or_traits_factory_opt)))
-(let xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_xor_traits_factory_opt)))
+(let and_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_and_traits_factory_opt)))
+(let or_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_or_traits_factory_opt)))
+(let xor_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type (lambda '(v) (SafeCast (Apply extractor v) (DataType 'Bool))) bool_xor_traits_factory_opt)))
(let avg_traits_factory (lambda '(list_type extractor) (Apply extractor_traits_factory list_type extractor avg_traits_factory_opt)))
(let list_traits_factory (lambda '(list_type extractor limit) (Apply extractor_traits_factory list_type extractor (Apply list_traits_factory_opt_gen limit (Null)))))
(let list2_traits_factory (lambda '(list_type extractor limit) (Apply extractor_traits_factory list_type extractor (Apply list_traits_factory_opt_gen limit empty_list))))
@@ -742,49 +742,49 @@
(return (WindowTraits item_type init_opt update_opt shift_opt current_opt defval))
))))
-# factory:lambda list_type:type first:lambda second:lambda
-# support optional values, init and update has parent arg
-(let list_by_traits_factory_opt_parent (lambda '(factory list_type first second) (block '(
- (let item_type (ListItemType list_type))
- (let key_type (TypeOf (Apply first (InstanceOf item_type))))
- (let traits (Apply factory list_type first second))
- (let init (NthArg '1 traits))
- (let update (NthArg '2 traits))
- (let shift (NthArg '3 traits))
- (let current (NthArg '4 traits))
- (let defval (NthArg '5 traits))
-
- (let init_opt (lambda '(row parent) (MatchType key_type
- 'Optional (lambda '()
- (IfPresent (Apply first row)
- (lambda '(key) (Just (Apply init row parent)))
- (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (TypeOf row)) parent))))
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply init row parent))
- )))
- (let update_opt (lambda '(row state parent) (MatchType key_type
- 'Optional (lambda '()
- (IfPresent state
- (lambda '(state)
- (IfPresent (Apply first row)
- (lambda '(key) (Just (Apply update row state parent)))
- (Just state)
- )
- )
- (Apply init_opt row parent)
- )
- )
- 'Null (lambda '() defval)
- (lambda '() (Apply update row state parent))
- )))
-
- (let shift_opt (lambda '(value state) (Void)))
- (let current_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (FlatMap state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
- (return (WindowTraits item_type init_opt update_opt shift_opt current_opt defval))
-))))
-
+# factory:lambda list_type:type first:lambda second:lambda
+# support optional values, init and update has parent arg
+(let list_by_traits_factory_opt_parent (lambda '(factory list_type first second) (block '(
+ (let item_type (ListItemType list_type))
+ (let key_type (TypeOf (Apply first (InstanceOf item_type))))
+ (let traits (Apply factory list_type first second))
+ (let init (NthArg '1 traits))
+ (let update (NthArg '2 traits))
+ (let shift (NthArg '3 traits))
+ (let current (NthArg '4 traits))
+ (let defval (NthArg '5 traits))
+
+ (let init_opt (lambda '(row parent) (MatchType key_type
+ 'Optional (lambda '()
+ (IfPresent (Apply first row)
+ (lambda '(key) (Just (Apply init row parent)))
+ (Nothing (OptionalType (TypeOf (Apply init (InstanceOf (TypeOf row)) parent))))
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply init row parent))
+ )))
+ (let update_opt (lambda '(row state parent) (MatchType key_type
+ 'Optional (lambda '()
+ (IfPresent state
+ (lambda '(state)
+ (IfPresent (Apply first row)
+ (lambda '(key) (Just (Apply update row state parent)))
+ (Just state)
+ )
+ )
+ (Apply init_opt row parent)
+ )
+ )
+ 'Null (lambda '() defval)
+ (lambda '() (Apply update row state parent))
+ )))
+
+ (let shift_opt (lambda '(value state) (Void)))
+ (let current_opt (lambda '(state) (MatchType key_type 'Optional (lambda '() (FlatMap state current)) 'Null (lambda '() defval) (lambda '() (Apply current state)))))
+ (return (WindowTraits item_type init_opt update_opt shift_opt current_opt defval))
+))))
+
# list_type:type value:lambda weight:lambda intervals:integer
# support optional values
(let histogram_adaptive_ward_traits_factory (lambda '(list_type value weight intervals) (Apply double_traits_factory_opt_parent (lambda '(list_type value weight) (Apply histogram_adaptive_ward_traits_factory_raw list_type value weight intervals)) list_type value weight)))
@@ -834,7 +834,7 @@
(let top_bottom_traits_factory (lambda '(list_type extractor count is_top)
(Apply extractor_traits_factory_parent list_type extractor (lambda '(list_type)
- (Apply flatten_traits_factory_parent list_type (lambda '(list_type)
+ (Apply flatten_traits_factory_parent list_type (lambda '(list_type)
(Apply top_traits_factory_raw list_type extractor count is_top)))))))
(let top_traits_factory (lambda '(list_type extractor count)
@@ -844,7 +844,7 @@
(Apply top_bottom_traits_factory list_type extractor count '0)))
(let top_bottom_by_traits_factory (lambda '(list_type key_extractor payload_extractor count is_top)
- (Apply list_by_traits_factory_opt_parent (lambda '(list_type key_extractor payload_extractor)
+ (Apply list_by_traits_factory_opt_parent (lambda '(list_type key_extractor payload_extractor)
(Apply top_by_traits_factory_raw list_type key_extractor payload_extractor count is_top)) list_type key_extractor payload_extractor)))
(let top_by_traits_factory (lambda '(list_type key_extractor payload_extractor count)
diff --git a/ydb/library/yql/protos/ya.make b/ydb/library/yql/protos/ya.make
index ac78c14a78..c9200505fb 100644
--- a/ydb/library/yql/protos/ya.make
+++ b/ydb/library/yql/protos/ya.make
@@ -4,7 +4,7 @@ OWNER(g:yql)
SRCS(
common.proto
- yql_mount.proto
+ yql_mount.proto
clickhouse.proto
)
diff --git a/ydb/library/yql/protos/yql_mount.proto b/ydb/library/yql/protos/yql_mount.proto
index 83e8028dbe..45ab7d5b9e 100644
--- a/ydb/library/yql/protos/yql_mount.proto
+++ b/ydb/library/yql/protos/yql_mount.proto
@@ -1,12 +1,12 @@
-package NYqlMountConfig;
-option java_package = "ru.yandex.kikimr.proto";
-
-message TMountPoint {
- required string RootAlias = 1;
- required string MountPoint = 2;
- optional bool Library = 3 [default = false];
-}
-
-message TMountConfig {
- repeated TMountPoint MountPoints = 1;
-}
+package NYqlMountConfig;
+option java_package = "ru.yandex.kikimr.proto";
+
+message TMountPoint {
+ required string RootAlias = 1;
+ required string MountPoint = 2;
+ optional bool Library = 3 [default = false];
+}
+
+message TMountConfig {
+ repeated TMountPoint MountPoints = 1;
+}
diff --git a/ydb/library/yql/providers/clickhouse/actors/ya.make b/ydb/library/yql/providers/clickhouse/actors/ya.make
index 5b86d63238..9c8bc7cf16 100644
--- a/ydb/library/yql/providers/clickhouse/actors/ya.make
+++ b/ydb/library/yql/providers/clickhouse/actors/ya.make
@@ -1,24 +1,24 @@
-LIBRARY()
-
-OWNER(
- g:yq
- g:yql
-)
-
-SRCS(
- yql_ch_read_actor.cpp
- yql_ch_source_factory.cpp
-)
-
-PEERDIR(
+LIBRARY()
+
+OWNER(
+ g:yq
+ g:yql
+)
+
+SRCS(
+ yql_ch_read_actor.cpp
+ yql_ch_source_factory.cpp
+)
+
+PEERDIR(
ydb/library/yql/minikql/computation
ydb/library/yql/providers/common/token_accessor/client
ydb/library/yql/public/types
ydb/library/yql/dq/actors/compute
ydb/library/yql/providers/clickhouse/proto
ydb/library/yql/providers/common/http_gateway
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.cpp b/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.cpp
index 1eada24efd..ed8ec17ef2 100644
--- a/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.cpp
+++ b/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.cpp
@@ -1,165 +1,165 @@
-#include "yql_ch_read_actor.h"
-
+#include "yql_ch_read_actor.h"
+
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/utils/yql_panic.h>
#include <ydb/library/yql/providers/clickhouse/proto/range.pb.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/core/hfunc.h>
-
-#include <queue>
-
-namespace NYql::NDq {
-
-using namespace NActors;
-
-namespace {
-
-struct TEvPrivate {
- // Event ids
- enum EEv : ui32 {
- EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
-
- EvReadResult = EvBegin,
- EvReadError,
-
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- // Events
- struct TEvReadResult : public TEventLocal<TEvReadResult, EvReadResult> {
- TEvReadResult(IHTTPGateway::TContent&& result): Result(std::move(result)) {}
- IHTTPGateway::TContent Result;
- };
-
- struct TEvReadError : public TEventLocal<TEvReadError, EvReadError> {
- TEvReadError(TIssues&& error): Error(std::move(error)) {}
- TIssues Error;
- };
-};
-
-} // namespace
-
-class TClickHouseReadActor : public TActorBootstrapped<TClickHouseReadActor>, public IDqSourceActor {
-public:
- TClickHouseReadActor(ui64 inputIndex,
- IHTTPGateway::TPtr gateway,
- TString&& url,
- TString&& query,
- ICallbacks* callbacks
- ) : Gateway(std::move(gateway))
- , InputIndex(inputIndex)
- , Callbacks(callbacks)
- , ActorSystem(TActivationContext::ActorSystem())
- , Url(std::move(url))
- , Query(std::move(query))
- {}
-
- void Bootstrap() {
- Become(&TClickHouseReadActor::StateFunc);
- Gateway->Download(Url, {}, 0U, std::bind(&TClickHouseReadActor::OnDownloadFinished, ActorSystem, SelfId(), std::placeholders::_1), Query);
- }
-
- static constexpr char ActorName[] = "ClickHouse_READ_ACTOR";
-
-private:
- void SaveState(const NDqProto::TCheckpoint&, NDqProto::TSourceState&) final {}
- void LoadState(const NDqProto::TSourceState&) final {}
- void CommitState(const NDqProto::TCheckpoint&) final {}
- ui64 GetInputIndex() const final { return InputIndex; }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvPrivate::TEvReadResult, Handle);
- hFunc(TEvPrivate::TEvReadError, Handle);
- )
-
- static void OnDownloadFinished(TActorSystem* actorSystem, TActorId selfId, IHTTPGateway::TResult&& result) {
- switch (result.index()) {
- case 0U:
- actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadResult(std::get<IHTTPGateway::TContent>(std::move(result)))));
- return;
- case 1U:
- actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadError(std::get<TIssues>(std::move(result)))));
- return;
- default:
- break;
- }
- }
-
- i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
- if (Result) {
- const auto size = Result->size();
- buffer.emplace_back(NKikimr::NMiniKQL::MakeString(std::string_view(*Result)));
- freeSpace -= size;
- finished = true;
- Result.reset();
- return size;
- }
-
- return 0LL;
- }
-
- void Handle(TEvPrivate::TEvReadResult::TPtr& result) {
- Result.emplace(std::move(result->Get()->Result));
- Callbacks->OnNewSourceDataArrived(InputIndex);
- }
-
- void Handle(TEvPrivate::TEvReadError::TPtr& result) {
- Callbacks->OnSourceError(InputIndex, result->Get()->Error, true);
- }
-
- // IActor & IDqSourceActor
- void PassAway() override { // Is called from Compute Actor
- TActorBootstrapped<TClickHouseReadActor>::PassAway();
- }
-
-
- const IHTTPGateway::TPtr Gateway;
-
- const ui64 InputIndex;
- ICallbacks *const Callbacks;
-
- TActorSystem* const ActorSystem;
-
- const TString Url, Query;
- std::optional<IHTTPGateway::TContent> Result;
-};
-
-std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateClickHouseReadActor(
- IHTTPGateway::TPtr gateway,
- NCH::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
- NYql::NDq::IDqSourceActor::ICallbacks* callback,
- ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory)
-{
- const auto token = secureParams.Value(params.GetToken(), TString{});
- const auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(credentialsFactory, token);
- const auto authToken = credentialsProviderFactory->CreateProvider()->GetAuthInfo();
- const auto one = token.find('#'), two = token.rfind('#');
- YQL_ENSURE(one != TString::npos && two != TString::npos && one < two, "Bad token format:" << token);
-
- TStringBuilder part;
- if (const auto taskParamsIt = taskParams.find(ClickHouseProviderName); taskParamsIt != taskParams.cend()) {
- NCH::TRange range;
- TStringInput input(taskParamsIt->second);
- range.Load(&input);
- if (const auto& r = range.GetRange(); !r.empty())
- part << ' ' << r;
- }
- part << ';';
-
- TStringBuilder url;
- url << params.GetScheme() << token.substr(one + 1u, two - one - 1u) << ':' << token.substr(two + 1u) << '@' << params.GetEndpoint() << "/?default_format=Native";
- const auto actor = new TClickHouseReadActor(inputIndex, std::move(gateway), std::move(url), params.GetQuery() + part, callback);
- return {actor, actor};
-}
-
-} // namespace NYql::NDq
-
+
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/events.h>
+#include <library/cpp/actors/core/event_local.h>
+#include <library/cpp/actors/core/hfunc.h>
+
+#include <queue>
+
+namespace NYql::NDq {
+
+using namespace NActors;
+
+namespace {
+
+struct TEvPrivate {
+ // Event ids
+ enum EEv : ui32 {
+ EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
+
+ EvReadResult = EvBegin,
+ EvReadError,
+
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ // Events
+ struct TEvReadResult : public TEventLocal<TEvReadResult, EvReadResult> {
+ TEvReadResult(IHTTPGateway::TContent&& result): Result(std::move(result)) {}
+ IHTTPGateway::TContent Result;
+ };
+
+ struct TEvReadError : public TEventLocal<TEvReadError, EvReadError> {
+ TEvReadError(TIssues&& error): Error(std::move(error)) {}
+ TIssues Error;
+ };
+};
+
+} // namespace
+
+class TClickHouseReadActor : public TActorBootstrapped<TClickHouseReadActor>, public IDqSourceActor {
+public:
+ TClickHouseReadActor(ui64 inputIndex,
+ IHTTPGateway::TPtr gateway,
+ TString&& url,
+ TString&& query,
+ ICallbacks* callbacks
+ ) : Gateway(std::move(gateway))
+ , InputIndex(inputIndex)
+ , Callbacks(callbacks)
+ , ActorSystem(TActivationContext::ActorSystem())
+ , Url(std::move(url))
+ , Query(std::move(query))
+ {}
+
+ void Bootstrap() {
+ Become(&TClickHouseReadActor::StateFunc);
+ Gateway->Download(Url, {}, 0U, std::bind(&TClickHouseReadActor::OnDownloadFinished, ActorSystem, SelfId(), std::placeholders::_1), Query);
+ }
+
+ static constexpr char ActorName[] = "ClickHouse_READ_ACTOR";
+
+private:
+ void SaveState(const NDqProto::TCheckpoint&, NDqProto::TSourceState&) final {}
+ void LoadState(const NDqProto::TSourceState&) final {}
+ void CommitState(const NDqProto::TCheckpoint&) final {}
+ ui64 GetInputIndex() const final { return InputIndex; }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvPrivate::TEvReadResult, Handle);
+ hFunc(TEvPrivate::TEvReadError, Handle);
+ )
+
+ static void OnDownloadFinished(TActorSystem* actorSystem, TActorId selfId, IHTTPGateway::TResult&& result) {
+ switch (result.index()) {
+ case 0U:
+ actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadResult(std::get<IHTTPGateway::TContent>(std::move(result)))));
+ return;
+ case 1U:
+ actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadError(std::get<TIssues>(std::move(result)))));
+ return;
+ default:
+ break;
+ }
+ }
+
+ i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
+ if (Result) {
+ const auto size = Result->size();
+ buffer.emplace_back(NKikimr::NMiniKQL::MakeString(std::string_view(*Result)));
+ freeSpace -= size;
+ finished = true;
+ Result.reset();
+ return size;
+ }
+
+ return 0LL;
+ }
+
+ void Handle(TEvPrivate::TEvReadResult::TPtr& result) {
+ Result.emplace(std::move(result->Get()->Result));
+ Callbacks->OnNewSourceDataArrived(InputIndex);
+ }
+
+ void Handle(TEvPrivate::TEvReadError::TPtr& result) {
+ Callbacks->OnSourceError(InputIndex, result->Get()->Error, true);
+ }
+
+ // IActor & IDqSourceActor
+ void PassAway() override { // Is called from Compute Actor
+ TActorBootstrapped<TClickHouseReadActor>::PassAway();
+ }
+
+
+ const IHTTPGateway::TPtr Gateway;
+
+ const ui64 InputIndex;
+ ICallbacks *const Callbacks;
+
+ TActorSystem* const ActorSystem;
+
+ const TString Url, Query;
+ std::optional<IHTTPGateway::TContent> Result;
+};
+
+std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateClickHouseReadActor(
+ IHTTPGateway::TPtr gateway,
+ NCH::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
+ NYql::NDq::IDqSourceActor::ICallbacks* callback,
+ ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory)
+{
+ const auto token = secureParams.Value(params.GetToken(), TString{});
+ const auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(credentialsFactory, token);
+ const auto authToken = credentialsProviderFactory->CreateProvider()->GetAuthInfo();
+ const auto one = token.find('#'), two = token.rfind('#');
+ YQL_ENSURE(one != TString::npos && two != TString::npos && one < two, "Bad token format:" << token);
+
+ TStringBuilder part;
+ if (const auto taskParamsIt = taskParams.find(ClickHouseProviderName); taskParamsIt != taskParams.cend()) {
+ NCH::TRange range;
+ TStringInput input(taskParamsIt->second);
+ range.Load(&input);
+ if (const auto& r = range.GetRange(); !r.empty())
+ part << ' ' << r;
+ }
+ part << ';';
+
+ TStringBuilder url;
+ url << params.GetScheme() << token.substr(one + 1u, two - one - 1u) << ':' << token.substr(two + 1u) << '@' << params.GetEndpoint() << "/?default_format=Native";
+ const auto actor = new TClickHouseReadActor(inputIndex, std::move(gateway), std::move(url), params.GetQuery() + part, callback);
+ return {actor, actor};
+}
+
+} // namespace NYql::NDq
+
diff --git a/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.h b/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.h
index 5c16413924..c28ffa6990 100644
--- a/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.h
+++ b/ydb/library/yql/providers/clickhouse/actors/yql_ch_read_actor.h
@@ -1,21 +1,21 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
#include <ydb/library/yql/providers/clickhouse/proto/source.pb.h>
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
-#include <library/cpp/actors/core/actor.h>
-
-namespace NYql::NDq {
-
-std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateClickHouseReadActor(
- IHTTPGateway::TPtr gateway,
- NCH::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
- IDqSourceActor::ICallbacks* callback,
- ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory);
-
-} // namespace NYql::NDq
-
+#include <library/cpp/actors/core/actor.h>
+
+namespace NYql::NDq {
+
+std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateClickHouseReadActor(
+ IHTTPGateway::TPtr gateway,
+ NCH::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
+ IDqSourceActor::ICallbacks* callback,
+ ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory);
+
+} // namespace NYql::NDq
+
diff --git a/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.cpp b/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.cpp
index 4748cada74..88aea459c3 100644
--- a/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.cpp
+++ b/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.cpp
@@ -1,15 +1,15 @@
-#include "yql_ch_source_factory.h"
-#include "yql_ch_read_actor.h"
-
+#include "yql_ch_source_factory.h"
+#include "yql_ch_read_actor.h"
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
-namespace NYql::NDq {
-
-void RegisterClickHouseReadActorFactory(TDqSourceFactory& factory, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory, IHTTPGateway::TPtr gateway) {
- factory.Register<NCH::TSource>("ClickHouseSource",
+namespace NYql::NDq {
+
+void RegisterClickHouseReadActorFactory(TDqSourceFactory& factory, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory, IHTTPGateway::TPtr gateway) {
+ factory.Register<NCH::TSource>("ClickHouseSource",
[credentialsFactory, gateway](NCH::TSource&& settings, IDqSourceActorFactory::TArguments&& args) {
return CreateClickHouseReadActor(gateway, std::move(settings), args.InputIndex, args.SecureParams, args.TaskParams, args.Callback, credentialsFactory);
- });
-}
-
-}
+ });
+}
+
+}
diff --git a/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.h b/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.h
index 0b7e79e6da..2813cba4d3 100644
--- a/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.h
+++ b/ydb/library/yql/providers/clickhouse/actors/yql_ch_source_factory.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_io_actors_factory.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
-
+
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
-
+
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
-
-namespace NYql::NDq {
-
-void RegisterClickHouseReadActorFactory(TDqSourceFactory& factory, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory, IHTTPGateway::TPtr gateway = IHTTPGateway::Make());
-
-}
-
+
+namespace NYql::NDq {
+
+void RegisterClickHouseReadActorFactory(TDqSourceFactory& factory, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory, IHTTPGateway::TPtr gateway = IHTTPGateway::Make());
+
+}
+
diff --git a/ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.json b/ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.json
index f06cb24016..a3378a3981 100644
--- a/ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.json
+++ b/ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.json
@@ -35,16 +35,16 @@
{"Index": 3, "Name": "Columns", "Type": "TExprBase"},
{"Index": 4, "Name": "Timezone", "Type": "TCoAtom"}
]
- },
- {
- "Name": "TClSourceSettings",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "ClSourceSettings"},
- "Children": [
- {"Index": 0, "Name": "Table", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Token", "Type": "TCoSecureParam"},
- {"Index": 2, "Name": "Columns", "Type": "TCoAtomList"}
- ]
+ },
+ {
+ "Name": "TClSourceSettings",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "ClSourceSettings"},
+ "Children": [
+ {"Index": 0, "Name": "Table", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Token", "Type": "TCoSecureParam"},
+ {"Index": 2, "Name": "Columns", "Type": "TCoAtomList"}
+ ]
}
]
}
diff --git a/ydb/library/yql/providers/clickhouse/proto/range.proto b/ydb/library/yql/providers/clickhouse/proto/range.proto
index 32a8680446..91d9484f66 100644
--- a/ydb/library/yql/providers/clickhouse/proto/range.proto
+++ b/ydb/library/yql/providers/clickhouse/proto/range.proto
@@ -1,7 +1,7 @@
-syntax = "proto3";
-
-package NYql.NCH;
-
-message TRange {
- string Range = 1;
-}
+syntax = "proto3";
+
+package NYql.NCH;
+
+message TRange {
+ string Range = 1;
+}
diff --git a/ydb/library/yql/providers/clickhouse/proto/source.proto b/ydb/library/yql/providers/clickhouse/proto/source.proto
index 6da7346956..930bd71e28 100644
--- a/ydb/library/yql/providers/clickhouse/proto/source.proto
+++ b/ydb/library/yql/providers/clickhouse/proto/source.proto
@@ -1,11 +1,11 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package NYql.NCH;
-
-message TSource {
- string Scheme = 1;
- string Token = 2;
- string Endpoint = 3;
- string Query = 4;
-}
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package NYql.NCH;
+
+message TSource {
+ string Scheme = 1;
+ string Token = 2;
+ string Endpoint = 3;
+ string Query = 4;
+}
diff --git a/ydb/library/yql/providers/clickhouse/proto/ya.make b/ydb/library/yql/providers/clickhouse/proto/ya.make
index 474cdb3317..9d9bf5c2c6 100644
--- a/ydb/library/yql/providers/clickhouse/proto/ya.make
+++ b/ydb/library/yql/providers/clickhouse/proto/ya.make
@@ -1,18 +1,18 @@
-OWNER(
- g:yq
- g:yql
-)
-
-PROTO_LIBRARY()
-
-SRCS(
- source.proto
- range.proto
-)
-
-IF (NOT PY_PROTOS_FOR)
- EXCLUDE_TAGS(GO_PROTO)
-ENDIF()
-
-END()
-
+OWNER(
+ g:yq
+ g:yql
+)
+
+PROTO_LIBRARY()
+
+SRCS(
+ source.proto
+ range.proto
+)
+
+IF (NOT PY_PROTOS_FOR)
+ EXCLUDE_TAGS(GO_PROTO)
+ENDIF()
+
+END()
+
diff --git a/ydb/library/yql/providers/clickhouse/provider/ya.make b/ydb/library/yql/providers/clickhouse/provider/ya.make
index 1e95222521..05effd38eb 100644
--- a/ydb/library/yql/providers/clickhouse/provider/ya.make
+++ b/ydb/library/yql/providers/clickhouse/provider/ya.make
@@ -13,7 +13,7 @@ SRCS(
yql_clickhouse_load_meta.cpp
yql_clickhouse_logical_opt.cpp
yql_clickhouse_mkql_compiler.cpp
- yql_clickhouse_physical_opt.cpp
+ yql_clickhouse_physical_opt.cpp
yql_clickhouse_provider.cpp
yql_clickhouse_provider.h
yql_clickhouse_provider_impl.h
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasink.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasink.cpp
index 1270489f76..12275d23e1 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasink.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasink.cpp
@@ -13,8 +13,8 @@ namespace NYql {
using namespace NNodes;
-namespace {
-
+namespace {
+
class TClickHouseDataSink : public TDataProviderBase {
public:
TClickHouseDataSink(TClickHouseState::TPtr state)
@@ -22,7 +22,7 @@ public:
, TypeAnnotationTransformer_(CreateClickHouseDataSinkTypeAnnotationTransformer(State_))
, ExecutionTransformer_(CreateClickHouseDataSinkExecTransformer(State_))
, LogicalOptProposalTransformer_(CreateClickHouseLogicalOptProposalTransformer(State_))
- , PhysicalOptProposalTransformer_(CreateClickHousePhysicalOptProposalTransformer(State_))
+ , PhysicalOptProposalTransformer_(CreateClickHousePhysicalOptProposalTransformer(State_))
{
}
@@ -68,19 +68,19 @@ public:
return *LogicalOptProposalTransformer_;
}
- IGraphTransformer& GetPhysicalOptProposalTransformer() override {
- return *PhysicalOptProposalTransformer_;
- }
+ IGraphTransformer& GetPhysicalOptProposalTransformer() override {
+ return *PhysicalOptProposalTransformer_;
+ }
private:
- const TClickHouseState::TPtr State_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<TExecTransformerBase> ExecutionTransformer_;
- const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
- const THolder<IGraphTransformer> PhysicalOptProposalTransformer_;
+ const TClickHouseState::TPtr State_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<TExecTransformerBase> ExecutionTransformer_;
+ const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
+ const THolder<IGraphTransformer> PhysicalOptProposalTransformer_;
};
-}
-
+}
+
TIntrusivePtr<IDataProvider> CreateClickHouseDataSink(TClickHouseState::TPtr state) {
return new TClickHouseDataSink(state);
}
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource.cpp
index 4b75993e3b..e23600f80f 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource.cpp
@@ -13,17 +13,17 @@ namespace NYql {
using namespace NNodes;
-namespace {
-
+namespace {
+
class TClickHouseDataSource : public TDataProviderBase {
public:
- TClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway)
+ TClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway)
: State_(state)
, IODiscoveryTransformer_(CreateClickHouseIODiscoveryTransformer(State_))
- , LoadMetaDataTransformer_(CreateClickHouseLoadTableMetadataTransformer(State_, std::move(gateway)))
+ , LoadMetaDataTransformer_(CreateClickHouseLoadTableMetadataTransformer(State_, std::move(gateway)))
, TypeAnnotationTransformer_(CreateClickHouseDataSourceTypeAnnotationTransformer(State_))
- , DqIntegration_(CreateClickHouseDqIntegration(State_))
- {}
+ , DqIntegration_(CreateClickHouseDqIntegration(State_))
+ {}
TStringBuf GetName() const override {
return ClickHouseProviderName;
@@ -109,17 +109,17 @@ public:
private:
- const TClickHouseState::TPtr State_;
- const THolder<IGraphTransformer> IODiscoveryTransformer_;
- const THolder<IGraphTransformer> LoadMetaDataTransformer_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<IDqIntegration> DqIntegration_;
+ const TClickHouseState::TPtr State_;
+ const THolder<IGraphTransformer> IODiscoveryTransformer_;
+ const THolder<IGraphTransformer> LoadMetaDataTransformer_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<IDqIntegration> DqIntegration_;
};
}
-TIntrusivePtr<IDataProvider> CreateClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway) {
- return new TClickHouseDataSource(std::move(state), std::move(gateway));
-}
-
+TIntrusivePtr<IDataProvider> CreateClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway) {
+ return new TClickHouseDataSource(std::move(state), std::move(gateway));
+}
+
} // namespace NYql
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource_type_ann.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource_type_ann.cpp
index 57a9fe8ddf..fd18aa1286 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource_type_ann.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_datasource_type_ann.cpp
@@ -21,27 +21,27 @@ public:
{
using TSelf = TClickHouseDataSourceTypeAnnotationTransformer;
AddHandler({TClReadTable::CallableName()}, Hndl(&TSelf::HandleReadTable));
- AddHandler({TClSourceSettings::CallableName()}, Hndl(&TSelf::HandleSourceSettings));
+ AddHandler({TClSourceSettings::CallableName()}, Hndl(&TSelf::HandleSourceSettings));
+ }
+
+ TStatus HandleSourceSettings(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureArgsCount(*input, 3U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(TClSourceSettings::idx_Table), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TClSourceSettings::idx_Token && !TCoSecureParam::Match(input->Child(TClSourceSettings::idx_Token))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Child(TClSourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
+ return TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
+ return TStatus::Ok;
}
- TStatus HandleSourceSettings(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureArgsCount(*input, 3U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(TClSourceSettings::idx_Table), ctx)) {
- return TStatus::Error;
- }
-
- if (input->ChildrenSize() > TClSourceSettings::idx_Token && !TCoSecureParam::Match(input->Child(TClSourceSettings::idx_Token))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Child(TClSourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
- return TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
- return TStatus::Ok;
- }
-
TStatus HandleReadTable(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 5, ctx)) {
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.cpp
index a1c7a145c4..a882da93a0 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.cpp
@@ -14,113 +14,113 @@ namespace NYql {
using namespace NNodes;
-namespace {
-
+namespace {
+
class TClickHouseDqIntegration: public TDqIntegrationBase {
public:
- TClickHouseDqIntegration(TClickHouseState::TPtr state)
+ TClickHouseDqIntegration(TClickHouseState::TPtr state)
: State_(state)
- {}
+ {}
- TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool) override {
- if (TClReadTable::Match(&read)) {
+ TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool) override {
+ if (TClReadTable::Match(&read)) {
return 0ul; // TODO: return real size
}
return Nothing();
}
- TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
- if (const auto maybeClReadTable = TMaybeNode<TClReadTable>(read)) {
- const auto clReadTable = maybeClReadTable.Cast();
- const auto token = TString("cluster:default_") += clReadTable.DataSource().Cluster().StringValue();
- YQL_CLOG(INFO, ProviderClickHouse) << "Wrap " << read->Content() << " with token: " << token;
-
- const auto rowType = clReadTable.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
- auto columns = clReadTable.Columns().Ptr();
- if (!columns->IsList()) {
- const auto pos = columns->Pos();
- const auto& items = rowType->Cast<TStructExprType>()->GetItems();
- TExprNode::TListType cols;
- cols.reserve(items.size());
- std::transform(items.cbegin(), items.cend(), std::back_inserter(cols), [&](const TItemExprType* item) { return ctx.NewAtom(pos, item->GetName()); });
- columns = ctx.NewList(pos, std::move(cols));
- }
-
- return Build<TDqSourceWrap>(ctx, read->Pos())
- .Input<TClSourceSettings>()
- .Table(clReadTable.Table())
- .Token<TCoSecureParam>()
- .Name().Build(token)
- .Build()
- .Columns(std::move(columns))
- .Build()
- .RowType(ExpandType(clReadTable.Pos(), *rowType, ctx))
- .DataSource(clReadTable.DataSource().Cast<TCoDataSource>())
- .Done().Ptr();
+ TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
+ if (const auto maybeClReadTable = TMaybeNode<TClReadTable>(read)) {
+ const auto clReadTable = maybeClReadTable.Cast();
+ const auto token = TString("cluster:default_") += clReadTable.DataSource().Cluster().StringValue();
+ YQL_CLOG(INFO, ProviderClickHouse) << "Wrap " << read->Content() << " with token: " << token;
+
+ const auto rowType = clReadTable.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
+ auto columns = clReadTable.Columns().Ptr();
+ if (!columns->IsList()) {
+ const auto pos = columns->Pos();
+ const auto& items = rowType->Cast<TStructExprType>()->GetItems();
+ TExprNode::TListType cols;
+ cols.reserve(items.size());
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(cols), [&](const TItemExprType* item) { return ctx.NewAtom(pos, item->GetName()); });
+ columns = ctx.NewList(pos, std::move(cols));
+ }
+
+ return Build<TDqSourceWrap>(ctx, read->Pos())
+ .Input<TClSourceSettings>()
+ .Table(clReadTable.Table())
+ .Token<TCoSecureParam>()
+ .Name().Build(token)
+ .Build()
+ .Columns(std::move(columns))
+ .Build()
+ .RowType(ExpandType(clReadTable.Pos(), *rowType, ctx))
+ .DataSource(clReadTable.DataSource().Cast<TCoDataSource>())
+ .Done().Ptr();
}
return read;
}
- ui64 Partition(const TDqSettings&, size_t, const TExprNode&, TVector<TString>& partitions, TString*, TExprContext&, bool) override {
- partitions.clear();
- NCH::TRange range;
-// range.SetRange("limit 42 offset 42 order by ...."); // Possible set range like this.
- partitions.emplace_back();
- TStringOutput out(partitions.back());
- range.Save(&out);
- return 0ULL;
- }
-
- void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
- const TDqSource source(&node);
- if (const auto maySettings = source.Settings().Maybe<TClSourceSettings>()) {
- const auto settings = maySettings.Cast();
-
- const auto& cluster = source.DataSource().Cast<TClDataSource>().Cluster().StringValue();
- const auto& table = settings.Table().StringValue();
- const auto& token = settings.Token().Name().StringValue();
-
- const auto& connect = State_->Configuration->Urls[cluster];
-
- NCH::TSource srcDesc;
- switch (std::get<EHostScheme>(connect)) {
- case HS_HTTP: srcDesc.SetScheme("http://"); break;
- case HS_HTTPS: srcDesc.SetScheme("https://"); break;
- }
- srcDesc.SetEndpoint(std::get<TString>(connect) + ':' + ToString(std::get<ui16>(connect)));
- srcDesc.SetToken(token);
-
- TStringBuf db, dbTable;
- if (!TStringBuf(table).TrySplit('.', db, dbTable)) {
- db = "default";
- dbTable = table;
- }
-
- const auto& columns = settings.Columns();
- TStringBuilder query;
- query << "select " << columns.Item(0).StringValue();
- for (auto i = 1U; i < columns.Size(); ++i)
- query << ',' << columns.Item(i).StringValue();
- query << " from " << db << '.' << dbTable;
-
- srcDesc.SetQuery(query);
- protoSettings.PackFrom(srcDesc);
- sourceType = "ClickHouseSource";
- }
- }
-
+ ui64 Partition(const TDqSettings&, size_t, const TExprNode&, TVector<TString>& partitions, TString*, TExprContext&, bool) override {
+ partitions.clear();
+ NCH::TRange range;
+// range.SetRange("limit 42 offset 42 order by ...."); // Possible set range like this.
+ partitions.emplace_back();
+ TStringOutput out(partitions.back());
+ range.Save(&out);
+ return 0ULL;
+ }
+
+ void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
+ const TDqSource source(&node);
+ if (const auto maySettings = source.Settings().Maybe<TClSourceSettings>()) {
+ const auto settings = maySettings.Cast();
+
+ const auto& cluster = source.DataSource().Cast<TClDataSource>().Cluster().StringValue();
+ const auto& table = settings.Table().StringValue();
+ const auto& token = settings.Token().Name().StringValue();
+
+ const auto& connect = State_->Configuration->Urls[cluster];
+
+ NCH::TSource srcDesc;
+ switch (std::get<EHostScheme>(connect)) {
+ case HS_HTTP: srcDesc.SetScheme("http://"); break;
+ case HS_HTTPS: srcDesc.SetScheme("https://"); break;
+ }
+ srcDesc.SetEndpoint(std::get<TString>(connect) + ':' + ToString(std::get<ui16>(connect)));
+ srcDesc.SetToken(token);
+
+ TStringBuf db, dbTable;
+ if (!TStringBuf(table).TrySplit('.', db, dbTable)) {
+ db = "default";
+ dbTable = table;
+ }
+
+ const auto& columns = settings.Columns();
+ TStringBuilder query;
+ query << "select " << columns.Item(0).StringValue();
+ for (auto i = 1U; i < columns.Size(); ++i)
+ query << ',' << columns.Item(i).StringValue();
+ query << " from " << db << '.' << dbTable;
+
+ srcDesc.SetQuery(query);
+ protoSettings.PackFrom(srcDesc);
+ sourceType = "ClickHouseSource";
+ }
+ }
+
void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override {
- RegisterDqClickHouseMkqlCompilers(compiler, State_);
+ RegisterDqClickHouseMkqlCompilers(compiler, State_);
}
private:
- const TClickHouseState::TPtr State_;
+ const TClickHouseState::TPtr State_;
};
}
-THolder<IDqIntegration> CreateClickHouseDqIntegration(TClickHouseState::TPtr state) {
- return MakeHolder<TClickHouseDqIntegration>(state);
+THolder<IDqIntegration> CreateClickHouseDqIntegration(TClickHouseState::TPtr state) {
+ return MakeHolder<TClickHouseDqIntegration>(state);
+}
+
}
-
-}
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.h b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.h
index 600afcddd5..e23e896c75 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.h
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_dq_integration.h
@@ -8,6 +8,6 @@
namespace NYql {
-THolder<IDqIntegration> CreateClickHouseDqIntegration(TClickHouseState::TPtr state);
+THolder<IDqIntegration> CreateClickHouseDqIntegration(TClickHouseState::TPtr state);
}
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_load_meta.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_load_meta.cpp
index 163066d19d..eeaeffcffc 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_load_meta.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_load_meta.cpp
@@ -17,7 +17,7 @@
#include <ydb/library/yql/ast/yql_type_string.h>
#include <ydb/library/yql/ast/yql_expr.h>
#include <ydb/library/yql/core/type_ann/type_ann_expr.h>
-#include <library/cpp/json/json_reader.h>
+#include <library/cpp/json/json_reader.h>
namespace NYql {
@@ -26,10 +26,10 @@ using namespace NKikimr;
using namespace NKikimr::NMiniKQL;
class TClickHouseLoadTableMetadataTransformer : public TGraphTransformerBase {
- using TMapType = std::unordered_map<std::pair<TString, TString>, std::shared_ptr<std::optional<IHTTPGateway::TResult>>, THash<std::pair<TString, TString>>>;
+ using TMapType = std::unordered_map<std::pair<TString, TString>, std::shared_ptr<std::optional<IHTTPGateway::TResult>>, THash<std::pair<TString, TString>>>;
public:
- TClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway)
- : State_(std::move(state)), Gateway_(std::move(gateway))
+ TClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway)
+ : State_(std::move(state)), Gateway_(std::move(gateway))
{}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
@@ -39,260 +39,260 @@ public:
return TStatus::Ok;
}
- std::unordered_set<TMapType::key_type, TMapType::hasher> pendingTables;
- if (const auto& reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
- if (const auto maybeRead = TMaybeNode<TClRead>(node)) {
- return maybeRead.Cast().DataSource().Category().Value() == ClickHouseProviderName;
- }
- return false;
- }); !reads.empty()) {
- for (const auto& r : reads) {
- const TClRead read(r);
- if (!read.FreeArgs().Get(2).Ref().IsCallable("MrTableConcat")) {
- ctx.AddError(TIssue(ctx.GetPosition(read.FreeArgs().Get(0).Pos()), TStringBuilder() << "Expected Key"));
- return TStatus::Error;
+ std::unordered_set<TMapType::key_type, TMapType::hasher> pendingTables;
+ if (const auto& reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
+ if (const auto maybeRead = TMaybeNode<TClRead>(node)) {
+ return maybeRead.Cast().DataSource().Category().Value() == ClickHouseProviderName;
+ }
+ return false;
+ }); !reads.empty()) {
+ for (const auto& r : reads) {
+ const TClRead read(r);
+ if (!read.FreeArgs().Get(2).Ref().IsCallable("MrTableConcat")) {
+ ctx.AddError(TIssue(ctx.GetPosition(read.FreeArgs().Get(0).Pos()), TStringBuilder() << "Expected Key"));
+ return TStatus::Error;
+ }
+
+ const auto maybeKey = TExprBase(read.FreeArgs().Get(2).Ref().HeadPtr()).Maybe<TCoKey>();
+ if (!maybeKey) {
+ ctx.AddError(TIssue(ctx.GetPosition(read.FreeArgs().Get(0).Pos()), TStringBuilder() << "Expected Key"));
+ return TStatus::Error;
}
- const auto maybeKey = TExprBase(read.FreeArgs().Get(2).Ref().HeadPtr()).Maybe<TCoKey>();
- if (!maybeKey) {
- ctx.AddError(TIssue(ctx.GetPosition(read.FreeArgs().Get(0).Pos()), TStringBuilder() << "Expected Key"));
- return TStatus::Error;
- }
-
- const auto& keyArg = maybeKey.Cast().Ref().Head();
- if (!keyArg.IsList() || keyArg.ChildrenSize() != 2U
- || !keyArg.Head().IsAtom("table") || !keyArg.Tail().IsCallable(TCoString::CallableName())) {
- ctx.AddError(TIssue(ctx.GetPosition(keyArg.Pos()), TStringBuilder() << "Expected single table name"));
- return TStatus::Error;
- }
-
- const auto cluster = read.DataSource().Cluster().StringValue();
- const auto tableName = TString(keyArg.Tail().Head().Content());
- if (pendingTables.insert(std::make_pair(cluster, tableName)).second) {
- YQL_CLOG(INFO, ProviderClickHouse) << "Load table meta for: `" << cluster << "`.`" << tableName << "`";
- }
+ const auto& keyArg = maybeKey.Cast().Ref().Head();
+ if (!keyArg.IsList() || keyArg.ChildrenSize() != 2U
+ || !keyArg.Head().IsAtom("table") || !keyArg.Tail().IsCallable(TCoString::CallableName())) {
+ ctx.AddError(TIssue(ctx.GetPosition(keyArg.Pos()), TStringBuilder() << "Expected single table name"));
+ return TStatus::Error;
+ }
+
+ const auto cluster = read.DataSource().Cluster().StringValue();
+ const auto tableName = TString(keyArg.Tail().Head().Content());
+ if (pendingTables.insert(std::make_pair(cluster, tableName)).second) {
+ YQL_CLOG(INFO, ProviderClickHouse) << "Load table meta for: `" << cluster << "`.`" << tableName << "`";
+ }
}
- }
-
- std::vector<NThreading::TFuture<void>> handles;
- handles.reserve(pendingTables.size());
- Results_.reserve(pendingTables.size());
-
- for (const auto& item : pendingTables) {
- const auto& cluster = item.first;
- const auto it = State_->Configuration->Urls.find(cluster);
- YQL_ENSURE(State_->Configuration->Urls.cend() != it, "Cluster not found:" << cluster);
-
- TString token;
- if (const auto cred = State_->Types->FindCredential("default_" + cluster)) {
- token = cred->Content;
- } else {
- token = State_->Configuration->Tokens[cluster];
+ }
+
+ std::vector<NThreading::TFuture<void>> handles;
+ handles.reserve(pendingTables.size());
+ Results_.reserve(pendingTables.size());
+
+ for (const auto& item : pendingTables) {
+ const auto& cluster = item.first;
+ const auto it = State_->Configuration->Urls.find(cluster);
+ YQL_ENSURE(State_->Configuration->Urls.cend() != it, "Cluster not found:" << cluster);
+
+ TString token;
+ if (const auto cred = State_->Types->FindCredential("default_" + cluster)) {
+ token = cred->Content;
+ } else {
+ token = State_->Configuration->Tokens[cluster];
}
- const auto one = token.find('#'), two = token.rfind('#');
- YQL_ENSURE(one != TString::npos && two != TString::npos && one < two, "Bad token format:" << token);
+ const auto one = token.find('#'), two = token.rfind('#');
+ YQL_ENSURE(one != TString::npos && two != TString::npos && one < two, "Bad token format:" << token);
- TStringBuilder url;
- switch (std::get<EHostScheme>(it->second)) {
- case HS_HTTP: url << "http://"; break;
- case HS_HTTPS: url << "https://"; break;
+ TStringBuilder url;
+ switch (std::get<EHostScheme>(it->second)) {
+ case HS_HTTP: url << "http://"; break;
+ case HS_HTTPS: url << "https://"; break;
}
- url << token.substr(one + 1U, two - one - 1U) << ':' << token.substr(two + 1U) << '@' << std::get<TString>(it->second) << ':' << std::get<ui16>(it->second) << "/?default_format=JSONCompactEachRow";
+ url << token.substr(one + 1U, two - one - 1U) << ':' << token.substr(two + 1U) << '@' << std::get<TString>(it->second) << ':' << std::get<ui16>(it->second) << "/?default_format=JSONCompactEachRow";
- const auto& table = item.second;
- TStringBuf db, dbTable;
- if (!TStringBuf(table).TrySplit('.', db, dbTable)) {
- db = "default";
- dbTable = table;
+ const auto& table = item.second;
+ TStringBuf db, dbTable;
+ if (!TStringBuf(table).TrySplit('.', db, dbTable)) {
+ db = "default";
+ dbTable = table;
}
- TStringBuilder sql;
- sql << "select timezone(),groupArray((name,type)) from system.columns where database = " << EscapeChString(db) << " and table = " << EscapeChString(dbTable) << ';';
+ TStringBuilder sql;
+ sql << "select timezone(),groupArray((name,type)) from system.columns where database = " << EscapeChString(db) << " and table = " << EscapeChString(dbTable) << ';';
- auto promise = NThreading::NewPromise();
- handles.emplace_back(promise.GetFuture());
+ auto promise = NThreading::NewPromise();
+ handles.emplace_back(promise.GetFuture());
- Gateway_->Download(std::move(url), {}, 0U, std::bind(&TClickHouseLoadTableMetadataTransformer::OnDiscovery, Results_.emplace(item, std::make_shared<TMapType::mapped_type::element_type>()).first->second, std::placeholders::_1, std::move(promise)), std::move(sql));
+ Gateway_->Download(std::move(url), {}, 0U, std::bind(&TClickHouseLoadTableMetadataTransformer::OnDiscovery, Results_.emplace(item, std::make_shared<TMapType::mapped_type::element_type>()).first->second, std::placeholders::_1, std::move(promise)), std::move(sql));
}
- if (handles.empty()) {
- return TStatus::Ok;
+ if (handles.empty()) {
+ return TStatus::Ok;
}
- AsyncFuture_ = NThreading::WaitExceptionOrAll(handles);
- return TStatus::Async;
+ AsyncFuture_ = NThreading::WaitExceptionOrAll(handles);
+ return TStatus::Async;
}
- NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
+ NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
return AsyncFuture_;
}
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
YQL_ENSURE(AsyncFuture_.HasValue());
- const auto& reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
- if (const auto maybeRead = TMaybeNode<TClRead>(node)) {
- return maybeRead.Cast().DataSource().Category().Value() == ClickHouseProviderName;
- }
- return false;
- });
-
- TNodeOnNodeOwnedMap replaces(reads.size());
- bool bad = false;
- for (const auto r : reads) {
- const TClRead read(r);
- const auto cluster = read.DataSource().Cluster().StringValue();
- const auto& keyArg = TExprBase(read.FreeArgs().Get(2).Ref().HeadPtr()).Cast<TCoKey>().Ref().Head();
- const auto table = TString(keyArg.Tail().Head().Content());
-
- const auto it = Results_.find(std::make_pair(cluster, table));
- if (Results_.cend() != it && it->second && *it->second) {
- switch (const auto idx = (*it->second)->index()) {
- case 0U: {
- TClickHouseState::TTableMeta meta;
- if (const auto& parse = ParseTableMeta(std::get<IHTTPGateway::TContent>(std::move(**it->second)).Extract(), cluster, table, ctx, meta.ColumnOrder); parse.first) {
- meta.ItemType = parse.first;
- State_->Timezones[read.DataSource().Cluster().Value()] = ctx.AppendString(parse.second);
- if (const auto ins = replaces.emplace(read.Raw(), TExprNode::TPtr()); ins.second)
- ins.first->second = Build<TClReadTable>(ctx, read.Pos())
- .World(read.World())
- .DataSource(read.DataSource())
- .Table().Value(table).Build()
- .Columns<TCoVoid>().Build()
- .Timezone().Value(parse.second).Build()
- .Done().Ptr();
+ const auto& reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
+ if (const auto maybeRead = TMaybeNode<TClRead>(node)) {
+ return maybeRead.Cast().DataSource().Category().Value() == ClickHouseProviderName;
+ }
+ return false;
+ });
+
+ TNodeOnNodeOwnedMap replaces(reads.size());
+ bool bad = false;
+ for (const auto r : reads) {
+ const TClRead read(r);
+ const auto cluster = read.DataSource().Cluster().StringValue();
+ const auto& keyArg = TExprBase(read.FreeArgs().Get(2).Ref().HeadPtr()).Cast<TCoKey>().Ref().Head();
+ const auto table = TString(keyArg.Tail().Head().Content());
+
+ const auto it = Results_.find(std::make_pair(cluster, table));
+ if (Results_.cend() != it && it->second && *it->second) {
+ switch (const auto idx = (*it->second)->index()) {
+ case 0U: {
+ TClickHouseState::TTableMeta meta;
+ if (const auto& parse = ParseTableMeta(std::get<IHTTPGateway::TContent>(std::move(**it->second)).Extract(), cluster, table, ctx, meta.ColumnOrder); parse.first) {
+ meta.ItemType = parse.first;
+ State_->Timezones[read.DataSource().Cluster().Value()] = ctx.AppendString(parse.second);
+ if (const auto ins = replaces.emplace(read.Raw(), TExprNode::TPtr()); ins.second)
+ ins.first->second = Build<TClReadTable>(ctx, read.Pos())
+ .World(read.World())
+ .DataSource(read.DataSource())
+ .Table().Value(table).Build()
+ .Columns<TCoVoid>().Build()
+ .Timezone().Value(parse.second).Build()
+ .Done().Ptr();
State_->Tables.emplace(it->first, meta);
- } else
- bad = true;
- break;
- }
- case 1U:
- if (const auto issues = std::move(std::get<TIssues>(**it->second)))
- std::for_each(issues.begin(), issues.end(), std::bind(&TExprContext::AddError, std::ref(ctx), std::placeholders::_1));
- ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Error on load meta for " << cluster << '.' << table));
- bad = true;
- break;
- default:
- ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Unexpected variant index " << idx << " on load meta for " << cluster << '.' << table));
- bad = true;
- break;
- }
- } else {
- ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Not found result for " << cluster << '.' << table));
- bad = true;
+ } else
+ bad = true;
+ break;
+ }
+ case 1U:
+ if (const auto issues = std::move(std::get<TIssues>(**it->second)))
+ std::for_each(issues.begin(), issues.end(), std::bind(&TExprContext::AddError, std::ref(ctx), std::placeholders::_1));
+ ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Error on load meta for " << cluster << '.' << table));
+ bad = true;
+ break;
+ default:
+ ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Unexpected variant index " << idx << " on load meta for " << cluster << '.' << table));
+ bad = true;
+ break;
+ }
+ } else {
+ ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Not found result for " << cluster << '.' << table));
+ bad = true;
}
- }
-
-
- if (bad)
- return TStatus::Error;
-
- return RemapExpr(input, output, replaces, ctx, TOptimizeExprSettings(nullptr));
- }
-private:
- static void OnDiscovery(const TMapType::mapped_type& res, IHTTPGateway::TResult&& result, NThreading::TPromise<void>& promise) {
- *res = std::move(result);
- return promise.SetValue();
- }
-
- std::pair<const TStructExprType*, TString> ParseTableMeta(const std::string_view& blob, const std::string_view& cluster, const std::string_view& table, TExprContext& ctx, TVector<TString>& columnOrder) try {
- columnOrder.clear();
- NJson::TJsonValue json;
- if (!NJson::ReadJsonTree(blob, &json, false)) {
- ctx.AddError(TIssue({}, TStringBuilder() << "ClickHouse response: " << blob));
- return {nullptr, {}};
- }
-
- const auto& row = json.GetArray();
- auto timezone = row.front().GetString();
- if (!FindTimezoneId(timezone)) {
- ctx.AddWarning(TIssue({}, TStringBuilder() << "Unsupported timezone: " << timezone));
- timezone.clear();
- }
-
- const auto& cols = row.back().GetArray();
- if (cols.empty()) {
+ }
+
+
+ if (bad)
+ return TStatus::Error;
+
+ return RemapExpr(input, output, replaces, ctx, TOptimizeExprSettings(nullptr));
+ }
+private:
+ static void OnDiscovery(const TMapType::mapped_type& res, IHTTPGateway::TResult&& result, NThreading::TPromise<void>& promise) {
+ *res = std::move(result);
+ return promise.SetValue();
+ }
+
+ std::pair<const TStructExprType*, TString> ParseTableMeta(const std::string_view& blob, const std::string_view& cluster, const std::string_view& table, TExprContext& ctx, TVector<TString>& columnOrder) try {
+ columnOrder.clear();
+ NJson::TJsonValue json;
+ if (!NJson::ReadJsonTree(blob, &json, false)) {
+ ctx.AddError(TIssue({}, TStringBuilder() << "ClickHouse response: " << blob));
+ return {nullptr, {}};
+ }
+
+ const auto& row = json.GetArray();
+ auto timezone = row.front().GetString();
+ if (!FindTimezoneId(timezone)) {
+ ctx.AddWarning(TIssue({}, TStringBuilder() << "Unsupported timezone: " << timezone));
+ timezone.clear();
+ }
+
+ const auto& cols = row.back().GetArray();
+ if (cols.empty()) {
ctx.AddError(TIssue({}, TStringBuilder() << "Table " << cluster << '.' << table << " doesn't exist."));
- return {nullptr, {}};
- }
-
- TSmallVec<std::array<TString, 2U>> rawMeta;
- rawMeta.reserve(cols.size());
-
- std::transform(cols.cbegin(), cols.cend(), std::back_inserter(rawMeta),[](const NJson::TJsonValue& v) -> std::array<TString, 2U> {
- return {{v.GetArray().front().GetString(), v.GetArray().back().GetString()}};
- });
-
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pb(env, *State_->FunctionRegistry);
-
- TRuntimeNode::TList types;
- types.reserve(rawMeta.size());
- std::transform(rawMeta.cbegin(), rawMeta.cend(), std::back_inserter(types), [&](const std::array<TString, 2U>& c) { return pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(c.back()); });
-
- const auto strType = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
- const auto list = pb.NewList(strType, types);
- const auto zone = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(timezone);
- const auto root = pb.Map(list, [&](TRuntimeNode type) { return pb.Apply(pb.Udf("ClickHouseClient.ToYqlType"), {type, zone}); });
-
- auto randomProvider = CreateDefaultRandomProvider();
- auto timeProvider = CreateDefaultTimeProvider();
-
- TExploringNodeVisitor explorer;
- explorer.Walk(root.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(),
- State_->FunctionRegistry, NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
-
- std::vector<TNode*> entryPoints(1, root.GetNode());
- auto pattern = MakeComputationPattern(explorer, root, entryPoints, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- TBindTerminator bind(graph->GetTerminator());
-
- TVector<const TItemExprType*> items;
- items.reserve(rawMeta.size());
- const auto output = graph->GetValue();
- YQL_ENSURE(output.GetListLength() == rawMeta.size(), "Enexpected list size " << output.GetListLength() << " != " << rawMeta.size());
-
- for (auto i = 0U; i < rawMeta.size(); ++i) {
- if (const auto& e = output.GetElement(i)) {
- TMemoryPool pool(4096);
- TIssues issues;
- const auto parsedType = ParseType(e.AsStringRef(), pool, issues, {});
- YQL_ENSURE(parsedType, "Failed to parse type" << issues.ToString());
-
- const auto astRoot = TAstNode::NewList({}, pool,
- TAstNode::NewList({}, pool, TAstNode::NewLiteralAtom({}, TStringBuf("return"), pool), parsedType));
- TExprNode::TPtr exprRoot;
- YQL_ENSURE(CompileExpr(*astRoot, exprRoot, ctx, nullptr), "Failed to compile.");
-
- // TODO: Collect type annotation directly from AST.
- const auto callableTransformer = CreateExtCallableTypeAnnotationTransformer(*State_->Types);
- const auto typeTransformer = CreateTypeAnnotationTransformer(callableTransformer, *State_->Types);
- YQL_ENSURE(InstantTransform(*typeTransformer, exprRoot, ctx) == IGraphTransformer::TStatus::Ok, "Failed to type check.");
-
- const auto type = exprRoot->GetTypeAnn()->Cast<NYql::TTypeExprType>()->GetType();
- items.emplace_back(ctx.MakeType<TItemExprType>(rawMeta[i].front(), type));
- columnOrder.emplace_back(rawMeta[i].front());
+ return {nullptr, {}};
+ }
+
+ TSmallVec<std::array<TString, 2U>> rawMeta;
+ rawMeta.reserve(cols.size());
+
+ std::transform(cols.cbegin(), cols.cend(), std::back_inserter(rawMeta),[](const NJson::TJsonValue& v) -> std::array<TString, 2U> {
+ return {{v.GetArray().front().GetString(), v.GetArray().back().GetString()}};
+ });
+
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pb(env, *State_->FunctionRegistry);
+
+ TRuntimeNode::TList types;
+ types.reserve(rawMeta.size());
+ std::transform(rawMeta.cbegin(), rawMeta.cend(), std::back_inserter(types), [&](const std::array<TString, 2U>& c) { return pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(c.back()); });
+
+ const auto strType = pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id);
+ const auto list = pb.NewList(strType, types);
+ const auto zone = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>(timezone);
+ const auto root = pb.Map(list, [&](TRuntimeNode type) { return pb.Apply(pb.Udf("ClickHouseClient.ToYqlType"), {type, zone}); });
+
+ auto randomProvider = CreateDefaultRandomProvider();
+ auto timeProvider = CreateDefaultTimeProvider();
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(root.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(),
+ State_->FunctionRegistry, NUdf::EValidateMode::None, NUdf::EValidatePolicy::Exception, "OFF", EGraphPerProcess::Multi);
+
+ std::vector<TNode*> entryPoints(1, root.GetNode());
+ auto pattern = MakeComputationPattern(explorer, root, entryPoints, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ TBindTerminator bind(graph->GetTerminator());
+
+ TVector<const TItemExprType*> items;
+ items.reserve(rawMeta.size());
+ const auto output = graph->GetValue();
+ YQL_ENSURE(output.GetListLength() == rawMeta.size(), "Enexpected list size " << output.GetListLength() << " != " << rawMeta.size());
+
+ for (auto i = 0U; i < rawMeta.size(); ++i) {
+ if (const auto& e = output.GetElement(i)) {
+ TMemoryPool pool(4096);
+ TIssues issues;
+ const auto parsedType = ParseType(e.AsStringRef(), pool, issues, {});
+ YQL_ENSURE(parsedType, "Failed to parse type" << issues.ToString());
+
+ const auto astRoot = TAstNode::NewList({}, pool,
+ TAstNode::NewList({}, pool, TAstNode::NewLiteralAtom({}, TStringBuf("return"), pool), parsedType));
+ TExprNode::TPtr exprRoot;
+ YQL_ENSURE(CompileExpr(*astRoot, exprRoot, ctx, nullptr), "Failed to compile.");
+
+ // TODO: Collect type annotation directly from AST.
+ const auto callableTransformer = CreateExtCallableTypeAnnotationTransformer(*State_->Types);
+ const auto typeTransformer = CreateTypeAnnotationTransformer(callableTransformer, *State_->Types);
+ YQL_ENSURE(InstantTransform(*typeTransformer, exprRoot, ctx) == IGraphTransformer::TStatus::Ok, "Failed to type check.");
+
+ const auto type = exprRoot->GetTypeAnn()->Cast<NYql::TTypeExprType>()->GetType();
+ items.emplace_back(ctx.MakeType<TItemExprType>(rawMeta[i].front(), type));
+ columnOrder.emplace_back(rawMeta[i].front());
}
}
-
- return std::make_pair(ctx.MakeType<TStructExprType>(items), std::move(timezone));
- } catch (std::exception&) {
- ctx.AddError(TIssue({}, TStringBuilder() << "Failed to parse table metadata: " << CurrentExceptionMessage()));
- return {nullptr, {}};
+
+ return std::make_pair(ctx.MakeType<TStructExprType>(items), std::move(timezone));
+ } catch (std::exception&) {
+ ctx.AddError(TIssue({}, TStringBuilder() << "Failed to parse table metadata: " << CurrentExceptionMessage()));
+ return {nullptr, {}};
}
-private:
- const TClickHouseState::TPtr State_;
- const IHTTPGateway::TPtr Gateway_;
+private:
+ const TClickHouseState::TPtr State_;
+ const IHTTPGateway::TPtr Gateway_;
- TMapType Results_;
+ TMapType Results_;
NThreading::TFuture<void> AsyncFuture_;
};
-THolder<IGraphTransformer> CreateClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway) {
- return MakeHolder<TClickHouseLoadTableMetadataTransformer>(std::move(state), std::move(gateway));
+THolder<IGraphTransformer> CreateClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway) {
+ return MakeHolder<TClickHouseLoadTableMetadataTransformer>(std::move(state), std::move(gateway));
}
} // namespace NYql
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_logical_opt.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_logical_opt.cpp
index ce8d3d7f7f..7d3c31a45e 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_logical_opt.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_logical_opt.cpp
@@ -15,8 +15,8 @@ namespace NYql {
using namespace NNodes;
-namespace {
-
+namespace {
+
class TClickHouseLogicalOptProposalTransformer : public TOptimizeTransformerBase {
public:
TClickHouseLogicalOptProposalTransformer(TClickHouseState::TPtr state)
@@ -27,28 +27,28 @@ public:
AddHandler(0, &TCoLeft::Match, HNDL(TrimReadWorld));
AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembers));
AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembersOverDqWrap));
- AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembersOverDqSourceWrap));
+ AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembersOverDqSourceWrap));
#undef HNDL
}
TMaybeNode<TExprBase> TrimReadWorld(TExprBase node, TExprContext& ctx) const {
- if (const auto maybeRead = node.Cast<TCoLeft>().Input().Maybe<TClReadTable>())
- return TExprBase(ctx.NewWorld(node.Pos()));
- return node;
+ if (const auto maybeRead = node.Cast<TCoLeft>().Input().Maybe<TClReadTable>())
+ return TExprBase(ctx.NewWorld(node.Pos()));
+ return node;
}
TMaybeNode<TExprBase> ExtractMembers(TExprBase node, TExprContext& ctx) const {
- const auto extract = node.Cast<TCoExtractMembers>();
- const auto input = extract.Input();
- const auto read = input.Maybe<TCoRight>().Input().Maybe<TClReadTable>();
+ const auto extract = node.Cast<TCoExtractMembers>();
+ const auto input = extract.Input();
+ const auto read = input.Maybe<TCoRight>().Input().Maybe<TClReadTable>();
if (!read) {
return node;
}
return Build<TCoRight>(ctx, extract.Pos())
.Input<TClReadTable>()
- .InitFrom(read.Cast())
+ .InitFrom(read.Cast())
.Columns(extract.Members())
.Build()
.Done();
@@ -65,35 +65,35 @@ public:
return Build<TDqReadWrap>(ctx, node.Pos())
.InitFrom(input.Cast<TDqReadWrap>())
.Input<TClReadTable>()
- .InitFrom(read.Cast())
+ .InitFrom(read.Cast())
.Columns(extract.Members())
.Build()
.Done();
}
- TMaybeNode<TExprBase> ExtractMembersOverDqSourceWrap(TExprBase node, TExprContext& ctx) const {
- const auto extract = node.Cast<TCoExtractMembers>();
- const auto input = extract.Input();
- const auto read = input.Maybe<TDqSourceWrap>().Input().Maybe<TClSourceSettings>();
- if (!read) {
- return node;
- }
-
- return Build<TDqSourceWrap>(ctx, node.Pos())
- .Input<TClSourceSettings>()
- .InitFrom(read.Cast())
- .Columns(extract.Members())
- .Build()
- .DataSource(input.Cast<TDqSourceWrap>().DataSource())
- .RowType(ExpandType(node.Pos(), *GetSeqItemType(extract.Ref().GetTypeAnn()), ctx))
- .Done();
- }
+ TMaybeNode<TExprBase> ExtractMembersOverDqSourceWrap(TExprBase node, TExprContext& ctx) const {
+ const auto extract = node.Cast<TCoExtractMembers>();
+ const auto input = extract.Input();
+ const auto read = input.Maybe<TDqSourceWrap>().Input().Maybe<TClSourceSettings>();
+ if (!read) {
+ return node;
+ }
+
+ return Build<TDqSourceWrap>(ctx, node.Pos())
+ .Input<TClSourceSettings>()
+ .InitFrom(read.Cast())
+ .Columns(extract.Members())
+ .Build()
+ .DataSource(input.Cast<TDqSourceWrap>().DataSource())
+ .RowType(ExpandType(node.Pos(), *GetSeqItemType(extract.Ref().GetTypeAnn()), ctx))
+ .Done();
+ }
private:
- const TClickHouseState::TPtr State_;
+ const TClickHouseState::TPtr State_;
};
-}
-
+}
+
THolder<IGraphTransformer> CreateClickHouseLogicalOptProposalTransformer(TClickHouseState::TPtr state) {
return MakeHolder<TClickHouseLogicalOptProposalTransformer>(state);
}
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.cpp
index e87cc6a66f..5a380898e8 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.cpp
@@ -7,7 +7,7 @@
#include <ydb/library/yql/minikql/mkql_node.h>
#include <ydb/library/yql/core/yql_opt_utils.h>
-#include <library/cpp/json/json_writer.h>
+#include <library/cpp/json/json_writer.h>
#include <algorithm>
@@ -16,23 +16,23 @@ namespace NYql {
using namespace NKikimr::NMiniKQL;
using namespace NNodes;
-namespace {
-
-TRuntimeNode BuildNativeParseCall(TRuntimeNode input, TType* inputItemType, TType* outputItemType, const std::string_view& timezone, NCommon::TMkqlBuildContext& ctx)
-{
- const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({inputItemType}), ctx.ProgramBuilder.NewStructType({}), outputItemType});
- const auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFormat", {}, userType, "Native"), {input, ctx.ProgramBuilder.NewOptional(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Utf8>(timezone)) }));
- const auto structType = static_cast<const TStructType*>(outputItemType);
- return ctx.ProgramBuilder.ExpandMap(flow,
- [&](TRuntimeNode item) {
- TRuntimeNode::TList fields;
- fields.reserve(structType->GetMembersCount());
- auto j = 0U;
- std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
- return fields;
- });
-}
-
+namespace {
+
+TRuntimeNode BuildNativeParseCall(TRuntimeNode input, TType* inputItemType, TType* outputItemType, const std::string_view& timezone, NCommon::TMkqlBuildContext& ctx)
+{
+ const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({inputItemType}), ctx.ProgramBuilder.NewStructType({}), outputItemType});
+ const auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFormat", {}, userType, "Native"), {input, ctx.ProgramBuilder.NewOptional(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Utf8>(timezone)) }));
+ const auto structType = static_cast<const TStructType*>(outputItemType);
+ return ctx.ProgramBuilder.ExpandMap(flow,
+ [&](TRuntimeNode item) {
+ TRuntimeNode::TList fields;
+ fields.reserve(structType->GetMembersCount());
+ auto j = 0U;
+ std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
+ return fields;
+ });
+}
+
TRuntimeNode BuildClickHouseInputCall(
TType* outputType,
TType* itemType,
@@ -40,7 +40,7 @@ TRuntimeNode BuildClickHouseInputCall(
TStringBuf table,
TStringBuf timezone,
const TClickHouseState::TPtr& state,
- NCommon::TMkqlBuildContext& ctx)
+ NCommon::TMkqlBuildContext& ctx)
{
TStringBuf db, dbTable;
if (!table.TrySplit(".", db, dbTable)) {
@@ -52,58 +52,58 @@ TRuntimeNode BuildClickHouseInputCall(
auto endpoint = state->Configuration->Endpoints.FindPtr(cluster);
Y_ENSURE(endpoint);
- const auto host = endpoint->first;
- const auto colonPos = host.rfind(':');
- YQL_ENSURE(colonPos != TString::npos, "Missing port: " << host);
-
- const auto hostWithoutPort = host.substr(0, colonPos);
- const auto port = FromString<ui16>(host.substr(colonPos + 1));
- const bool secure = endpoint->second;
-
- TString typeConfig;
- TStringOutput stream(typeConfig);
- NJson::TJsonWriter writer(&stream, NJson::TJsonWriterConfig());
-
- writer.OpenMap();
-
- writer.Write("db", db);
- writer.Write("table", dbTable);
- writer.Write("secure", secure);
- writer.Write("host", hostWithoutPort);
- writer.Write("port", port);
- writer.Write("token", TString("cluster:default_") + cluster);
-
- writer.OpenArray("columns");
+ const auto host = endpoint->first;
+ const auto colonPos = host.rfind(':');
+ YQL_ENSURE(colonPos != TString::npos, "Missing port: " << host);
+
+ const auto hostWithoutPort = host.substr(0, colonPos);
+ const auto port = FromString<ui16>(host.substr(colonPos + 1));
+ const bool secure = endpoint->second;
+
+ TString typeConfig;
+ TStringOutput stream(typeConfig);
+ NJson::TJsonWriter writer(&stream, NJson::TJsonWriterConfig());
+
+ writer.OpenMap();
+
+ writer.Write("db", db);
+ writer.Write("table", dbTable);
+ writer.Write("secure", secure);
+ writer.Write("host", hostWithoutPort);
+ writer.Write("port", port);
+ writer.Write("token", TString("cluster:default_") + cluster);
+
+ writer.OpenArray("columns");
for (ui32 i = 0; i < structType->GetMembersCount(); ++i) {
- writer.Write(structType->GetMemberName(i));
+ writer.Write(structType->GetMemberName(i));
}
- writer.CloseArray();
+ writer.CloseArray();
- writer.CloseMap();
- writer.Flush();
+ writer.CloseMap();
+ writer.Flush();
- const auto voidType = ctx.ProgramBuilder.NewVoid().GetStaticType();
+ const auto voidType = ctx.ProgramBuilder.NewVoid().GetStaticType();
TCallableTypeBuilder callbackTypeBuilder(ctx.ProgramBuilder.GetTypeEnvironment(), "", voidType);
- const auto callbackType = callbackTypeBuilder.Build();
+ const auto callbackType = callbackTypeBuilder.Build();
- const auto strType = ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id);
- const auto argsType = ctx.ProgramBuilder.NewTupleType({ strType });
- const auto userType = ctx.ProgramBuilder.NewTupleType({ argsType });
- const auto retType = ctx.ProgramBuilder.NewStreamType(itemType);
+ const auto strType = ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id);
+ const auto argsType = ctx.ProgramBuilder.NewTupleType({ strType });
+ const auto userType = ctx.ProgramBuilder.NewTupleType({ argsType });
+ const auto retType = ctx.ProgramBuilder.NewStreamType(itemType);
TCallableTypeBuilder funcTypeBuilder(ctx.ProgramBuilder.GetTypeEnvironment(), "UDF", retType);
funcTypeBuilder.Add(strType);
- const auto funcType = funcTypeBuilder.Build();
+ const auto funcType = funcTypeBuilder.Build();
TCallableBuilder callbackBuilder(ctx.ProgramBuilder.GetTypeEnvironment(), "DqNotify", callbackType);
auto callback = TRuntimeNode(callbackBuilder.Build(), false);
auto flow = ctx.ProgramBuilder.ToFlow(
ctx.ProgramBuilder.Apply(
- ctx.ProgramBuilder.TypedUdf("ClickHouse.remoteSource", funcType,
- ctx.ProgramBuilder.NewVoid(), userType, typeConfig),
- TArrayRef<const TRuntimeNode>({ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(timezone)})
+ ctx.ProgramBuilder.TypedUdf("ClickHouse.remoteSource", funcType,
+ ctx.ProgramBuilder.NewVoid(), userType, typeConfig),
+ TArrayRef<const TRuntimeNode>({ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(timezone)})
));
if (!AS_TYPE(TFlowType, outputType)->GetItemType()->IsSameType(*itemType)) {
@@ -120,30 +120,30 @@ TRuntimeNode BuildClickHouseInputCall(
return flow;
}
-}
-
-void RegisterDqClickHouseMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TClickHouseState::TPtr& state) {
- compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
- [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
- if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == ClickHouseProviderName) {
- const auto input = MkqlBuildExpr(wrapper.Input().Ref(), ctx);
- const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *wrapper.Input().Ref().GetTypeAnn(), ctx.ProgramBuilder);
- const auto outputItemType = NCommon::BuildType(wrapper.RowType().Ref(), *wrapper.RowType().Ref().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- return BuildNativeParseCall(input, inputItemType, outputItemType, state->Timezones[wrapper.DataSource().Cast<TClDataSource>().Cluster().Value()], ctx);
- }
-
- return TRuntimeNode();
- });
-
- compiler.ChainCallable(TDqReadWideWrap::CallableName(),
- [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
- if (const auto wrapper = TDqReadWrapBase(&node); wrapper.Input().Maybe<TClReadTable>().IsValid()) {
- const auto clRead = wrapper.Input().Cast<TClReadTable>();
- const auto readType = clRead.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
- const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *GetSeqItemType(readType), ctx.ProgramBuilder);
- const auto cluster = clRead.DataSource().Cluster().StringValue();
+}
+
+void RegisterDqClickHouseMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TClickHouseState::TPtr& state) {
+ compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
+ [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
+ if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == ClickHouseProviderName) {
+ const auto input = MkqlBuildExpr(wrapper.Input().Ref(), ctx);
+ const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *wrapper.Input().Ref().GetTypeAnn(), ctx.ProgramBuilder);
+ const auto outputItemType = NCommon::BuildType(wrapper.RowType().Ref(), *wrapper.RowType().Ref().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ return BuildNativeParseCall(input, inputItemType, outputItemType, state->Timezones[wrapper.DataSource().Cast<TClDataSource>().Cluster().Value()], ctx);
+ }
+
+ return TRuntimeNode();
+ });
+
+ compiler.ChainCallable(TDqReadWideWrap::CallableName(),
+ [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
+ if (const auto wrapper = TDqReadWrapBase(&node); wrapper.Input().Maybe<TClReadTable>().IsValid()) {
+ const auto clRead = wrapper.Input().Cast<TClReadTable>();
+ const auto readType = clRead.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
+ const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *GetSeqItemType(readType), ctx.ProgramBuilder);
+ const auto cluster = clRead.DataSource().Cluster().StringValue();
const auto outputType = NCommon::BuildType(wrapper.Ref(), *wrapper.Ref().GetTypeAnn(), ctx.ProgramBuilder);
- return BuildClickHouseInputCall(outputType, inputItemType, cluster, clRead.Table(), clRead.Timezone(), state, ctx);
+ return BuildClickHouseInputCall(outputType, inputItemType, cluster, clRead.Table(), clRead.Timezone(), state, ctx);
}
return TRuntimeNode();
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.h b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.h
index 0721780d79..da2c2f1406 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.h
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_mkql_compiler.h
@@ -7,6 +7,6 @@
namespace NYql {
-void RegisterDqClickHouseMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TClickHouseState::TPtr& state);
+void RegisterDqClickHouseMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TClickHouseState::TPtr& state);
}
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_physical_opt.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_physical_opt.cpp
index 2dc1f95557..c37259936b 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_physical_opt.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_physical_opt.cpp
@@ -1,5 +1,5 @@
-#include "yql_clickhouse_provider_impl.h"
-
+#include "yql_clickhouse_provider_impl.h"
+
#include <ydb/library/yql/providers/clickhouse/expr_nodes/yql_clickhouse_expr_nodes.h>
#include <ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
@@ -8,114 +8,114 @@
#include <ydb/library/yql/providers/common/transform/yql_optimize.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/utils/log/log.h>
-
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-ui8 GetTypeWeight(const TTypeAnnotationNode& type) {
- switch (type.GetKind()) {
- case ETypeAnnotationKind::Data:
- switch (type.Cast<TDataExprType>()->GetSlot()) {
- case NUdf::EDataSlot::Bool:
- case NUdf::EDataSlot::Int8:
- case NUdf::EDataSlot::Uint8: return 1;
-
- case NUdf::EDataSlot::Int16:
- case NUdf::EDataSlot::Uint16:
- case NUdf::EDataSlot::Date: return 2;
-
- case NUdf::EDataSlot::TzDate: return 3;
-
- case NUdf::EDataSlot::Int32:
- case NUdf::EDataSlot::Uint32:
- case NUdf::EDataSlot::Float:
- case NUdf::EDataSlot::Datetime: return 4;
-
- case NUdf::EDataSlot::TzDatetime: return 5;
-
- case NUdf::EDataSlot::Int64:
- case NUdf::EDataSlot::Uint64:
- case NUdf::EDataSlot::Double:
- case NUdf::EDataSlot::Timestamp:
- case NUdf::EDataSlot::Interval: return 8;
-
- case NUdf::EDataSlot::TzTimestamp: return 9;
-
- case NUdf::EDataSlot::Decimal: return 15;
- case NUdf::EDataSlot::Uuid: return 16;
-
- default: return 32;
- }
- case ETypeAnnotationKind::Optional: return 1 + GetTypeWeight(*type.Cast<TOptionalExprType>()->GetItemType());
- default: return 255;
- }
-}
-
-TStringBuf GetLightColumn(const TStructExprType& type) {
- ui8 weight = 255;
- const TItemExprType* field = nullptr;
- for (const auto& item : type.GetItems()) {
-
- if (const auto w = GetTypeWeight(*item->GetItemType()); w < weight) {
- weight = w;
- field = item;
- }
- }
- return field->GetName();
-}
-
-class TClickHousePhysicalOptProposalTransformer : public TOptimizeTransformerBase {
-public:
- TClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state)
- : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
- , State_(state)
- {
-#define HNDL(name) "PhysicalOptimizer-"#name, Hndl(&TClickHousePhysicalOptProposalTransformer::name)
- AddHandler(0, &TCoNarrowMap::Match, HNDL(ReadZeroColumns));
-#undef HNDL
- }
-
- TMaybeNode<TExprBase> ReadZeroColumns(TExprBase node, TExprContext& ctx) const {
- const auto& narrow = node.Maybe<TCoNarrowMap>();
- if (const auto& wide = narrow.Cast().Input().Maybe<TDqReadWideWrap>()) {
- if (const auto& maybe = wide.Cast().Input().Maybe<TClReadTable>()) {
- if (!wide.Cast().Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>()->GetSize()) {
- const auto& read = maybe.Cast();
- const auto structType = State_->Tables[std::make_pair(read.DataSource().Cluster().Value(), read.Table().Value())].ItemType;
- auto columns = ctx.NewList(read.Pos(), {ctx.NewAtom(read.Pos(), GetLightColumn(*structType))});
- return Build<TCoNarrowMap>(ctx, narrow.Cast().Pos())
- .Input<TDqReadWideWrap>()
- .InitFrom(wide.Cast())
- .Input<TClReadTable>()
- .InitFrom(read)
- .Columns(std::move(columns))
- .Build()
- .Build()
- .Lambda()
- .Args({"stub"})
- .Body<TCoAsStruct>().Build()
- .Build()
- .Done();
- }
- }
- }
-
- return node;
- }
-private:
- const TClickHouseState::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state) {
- return MakeHolder<TClickHousePhysicalOptProposalTransformer>(state);
-}
-
-} // namespace NYql
-
-
+
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+ui8 GetTypeWeight(const TTypeAnnotationNode& type) {
+ switch (type.GetKind()) {
+ case ETypeAnnotationKind::Data:
+ switch (type.Cast<TDataExprType>()->GetSlot()) {
+ case NUdf::EDataSlot::Bool:
+ case NUdf::EDataSlot::Int8:
+ case NUdf::EDataSlot::Uint8: return 1;
+
+ case NUdf::EDataSlot::Int16:
+ case NUdf::EDataSlot::Uint16:
+ case NUdf::EDataSlot::Date: return 2;
+
+ case NUdf::EDataSlot::TzDate: return 3;
+
+ case NUdf::EDataSlot::Int32:
+ case NUdf::EDataSlot::Uint32:
+ case NUdf::EDataSlot::Float:
+ case NUdf::EDataSlot::Datetime: return 4;
+
+ case NUdf::EDataSlot::TzDatetime: return 5;
+
+ case NUdf::EDataSlot::Int64:
+ case NUdf::EDataSlot::Uint64:
+ case NUdf::EDataSlot::Double:
+ case NUdf::EDataSlot::Timestamp:
+ case NUdf::EDataSlot::Interval: return 8;
+
+ case NUdf::EDataSlot::TzTimestamp: return 9;
+
+ case NUdf::EDataSlot::Decimal: return 15;
+ case NUdf::EDataSlot::Uuid: return 16;
+
+ default: return 32;
+ }
+ case ETypeAnnotationKind::Optional: return 1 + GetTypeWeight(*type.Cast<TOptionalExprType>()->GetItemType());
+ default: return 255;
+ }
+}
+
+TStringBuf GetLightColumn(const TStructExprType& type) {
+ ui8 weight = 255;
+ const TItemExprType* field = nullptr;
+ for (const auto& item : type.GetItems()) {
+
+ if (const auto w = GetTypeWeight(*item->GetItemType()); w < weight) {
+ weight = w;
+ field = item;
+ }
+ }
+ return field->GetName();
+}
+
+class TClickHousePhysicalOptProposalTransformer : public TOptimizeTransformerBase {
+public:
+ TClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state)
+ : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
+ , State_(state)
+ {
+#define HNDL(name) "PhysicalOptimizer-"#name, Hndl(&TClickHousePhysicalOptProposalTransformer::name)
+ AddHandler(0, &TCoNarrowMap::Match, HNDL(ReadZeroColumns));
+#undef HNDL
+ }
+
+ TMaybeNode<TExprBase> ReadZeroColumns(TExprBase node, TExprContext& ctx) const {
+ const auto& narrow = node.Maybe<TCoNarrowMap>();
+ if (const auto& wide = narrow.Cast().Input().Maybe<TDqReadWideWrap>()) {
+ if (const auto& maybe = wide.Cast().Input().Maybe<TClReadTable>()) {
+ if (!wide.Cast().Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>()->GetSize()) {
+ const auto& read = maybe.Cast();
+ const auto structType = State_->Tables[std::make_pair(read.DataSource().Cluster().Value(), read.Table().Value())].ItemType;
+ auto columns = ctx.NewList(read.Pos(), {ctx.NewAtom(read.Pos(), GetLightColumn(*structType))});
+ return Build<TCoNarrowMap>(ctx, narrow.Cast().Pos())
+ .Input<TDqReadWideWrap>()
+ .InitFrom(wide.Cast())
+ .Input<TClReadTable>()
+ .InitFrom(read)
+ .Columns(std::move(columns))
+ .Build()
+ .Build()
+ .Lambda()
+ .Args({"stub"})
+ .Body<TCoAsStruct>().Build()
+ .Build()
+ .Done();
+ }
+ }
+ }
+
+ return node;
+ }
+private:
+ const TClickHouseState::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state) {
+ return MakeHolder<TClickHousePhysicalOptProposalTransformer>(state);
+}
+
+} // namespace NYql
+
+
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.cpp b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.cpp
index 7cfc2f0ce0..15c4d834e3 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.cpp
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.cpp
@@ -5,10 +5,10 @@
namespace NYql {
TDataProviderInitializer GetClickHouseDataProviderInitializer(
- IHTTPGateway::TPtr gateway,
+ IHTTPGateway::TPtr gateway,
const std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolverWithMeta)
{
- return [gateway, dbResolverWithMeta] (
+ return [gateway, dbResolverWithMeta] (
const TString& userName,
const TString& sessionId,
const TGatewaysConfig* gatewaysConfig,
@@ -37,7 +37,7 @@ TDataProviderInitializer GetClickHouseDataProviderInitializer(
TDataProviderInfo info;
info.Names.insert({TString{ClickHouseProviderName}});
- info.Source = CreateClickHouseDataSource(state, gateway);
+ info.Source = CreateClickHouseDataSource(state, gateway);
info.Sink = CreateClickHouseDataSink(state);
return info;
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.h b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.h
index c7202ab466..7184fe1ba3 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.h
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider.h
@@ -21,7 +21,7 @@ struct TClickHouseState : public TThrRefBase
};
THashMap<std::pair<TString, TString>, TTableMeta> Tables;
- std::unordered_map<std::string_view, std::string_view> Timezones;
+ std::unordered_map<std::string_view, std::string_view> Timezones;
TTypeAnnotationContext* Types = nullptr;
TClickHouseConfiguration::TPtr Configuration = MakeIntrusive<TClickHouseConfiguration>();
@@ -31,11 +31,11 @@ struct TClickHouseState : public TThrRefBase
};
TDataProviderInitializer GetClickHouseDataProviderInitializer(
- IHTTPGateway::TPtr gateway,
+ IHTTPGateway::TPtr gateway,
std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolverWithMeta = nullptr
);
-TIntrusivePtr<IDataProvider> CreateClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway);
+TIntrusivePtr<IDataProvider> CreateClickHouseDataSource(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway);
TIntrusivePtr<IDataProvider> CreateClickHouseDataSink(TClickHouseState::TPtr state);
} // namespace NYql
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider_impl.h b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider_impl.h
index c81feb5c3d..cdf5c20405 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider_impl.h
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_provider_impl.h
@@ -11,7 +11,7 @@
namespace NYql {
THolder<IGraphTransformer> CreateClickHouseIODiscoveryTransformer(TClickHouseState::TPtr state);
-THolder<IGraphTransformer> CreateClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway);
+THolder<IGraphTransformer> CreateClickHouseLoadTableMetadataTransformer(TClickHouseState::TPtr state, IHTTPGateway::TPtr gateway);
THolder<TVisitorTransformerBase> CreateClickHouseDataSourceTypeAnnotationTransformer(TClickHouseState::TPtr state);
THolder<TVisitorTransformerBase> CreateClickHouseDataSinkTypeAnnotationTransformer(TClickHouseState::TPtr state);
@@ -19,6 +19,6 @@ THolder<TVisitorTransformerBase> CreateClickHouseDataSinkTypeAnnotationTransform
THolder<TExecTransformerBase> CreateClickHouseDataSinkExecTransformer(TClickHouseState::TPtr state);
THolder<IGraphTransformer> CreateClickHouseLogicalOptProposalTransformer(TClickHouseState::TPtr state);
-THolder<IGraphTransformer> CreateClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state);
+THolder<IGraphTransformer> CreateClickHousePhysicalOptProposalTransformer(TClickHouseState::TPtr state);
} // namespace NYql
diff --git a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_settings.h b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_settings.h
index 1b4224cb14..8d0b094af4 100644
--- a/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_settings.h
+++ b/ydb/library/yql/providers/clickhouse/provider/yql_clickhouse_settings.h
@@ -48,7 +48,7 @@ struct TClickHouseConfiguration : public TClickHouseSettings, public NCommon::TS
}
Tokens[cluster.GetName()] = cluster.GetCHToken();
- // TODO: Drop later
+ // TODO: Drop later
TString endpoint;
if (cluster.HasCluster()) {
endpoint = cluster.GetCluster();
@@ -61,35 +61,35 @@ struct TClickHouseConfiguration : public TClickHouseSettings, public NCommon::TS
}
Endpoints[cluster.GetName()] = std::make_pair(
endpoint + ":" + ToString(cluster.GetNativeHostPort()), cluster.GetNativeSecure());
-
- auto& url = Urls[cluster.GetName()];
- auto& host = std::get<TString>(url);
- auto& scheme = std::get<EHostScheme>(url);
- auto& port = std::get<ui16>(url);
- host = cluster.GetCluster();
- while (host.EndsWith("/"))
- host = host.substr(0u, host.length() - 1u);
- if (host.StartsWith("http://")) {
- scheme = HS_HTTP;
- host = host.substr(7u);
- port = 80;
- } else {
- scheme = HS_HTTPS;
- port = 443;
- if (host.StartsWith("https://")) {
- host = host.substr(8u);
- }
- }
-
- if (const auto p = host.rfind(':'); TString::npos != p) {
- port = ::FromString<ui16>(host.substr(p + 1u));
- host = host.substr(0u, p);
- }
-
- if (cluster.HasHostScheme())
- scheme = cluster.GetHostScheme();
- if (cluster.HasHostPort())
- port = cluster.GetHostPort();
+
+ auto& url = Urls[cluster.GetName()];
+ auto& host = std::get<TString>(url);
+ auto& scheme = std::get<EHostScheme>(url);
+ auto& port = std::get<ui16>(url);
+ host = cluster.GetCluster();
+ while (host.EndsWith("/"))
+ host = host.substr(0u, host.length() - 1u);
+ if (host.StartsWith("http://")) {
+ scheme = HS_HTTP;
+ host = host.substr(7u);
+ port = 80;
+ } else {
+ scheme = HS_HTTPS;
+ port = 443;
+ if (host.StartsWith("https://")) {
+ host = host.substr(8u);
+ }
+ }
+
+ if (const auto p = host.rfind(':'); TString::npos != p) {
+ port = ::FromString<ui16>(host.substr(p + 1u));
+ host = host.substr(0u, p);
+ }
+
+ if (cluster.HasHostScheme())
+ scheme = cluster.GetHostScheme();
+ if (cluster.HasHostPort())
+ port = cluster.GetHostPort();
}
this->FreezeDefaults();
}
@@ -98,7 +98,7 @@ struct TClickHouseConfiguration : public TClickHouseSettings, public NCommon::TS
TClickHouseSettings::TConstPtr Snapshot() const;
THashMap<TString, TString> Tokens;
- THashMap<TString, std::tuple<TString, EHostScheme, ui16>> Urls;
+ THashMap<TString, std::tuple<TString, EHostScheme, ui16>> Urls;
THashMap<TString, std::pair<TString, bool>> Endpoints;
THashMap<TString, TVector<TString>> DbId2Clusters; // DatabaseId -> ClusterNames
};
diff --git a/ydb/library/yql/providers/clickhouse/ya.make b/ydb/library/yql/providers/clickhouse/ya.make
index 950111c858..eacab82215 100644
--- a/ydb/library/yql/providers/clickhouse/ya.make
+++ b/ydb/library/yql/providers/clickhouse/ya.make
@@ -1,6 +1,6 @@
RECURSE(
- actors
+ actors
expr_nodes
provider
- proto
+ proto
)
diff --git a/ydb/library/yql/providers/common/codec/yql_codec.cpp b/ydb/library/yql/providers/common/codec/yql_codec.cpp
index 3af631be6a..7587e188fa 100644
--- a/ydb/library/yql/providers/common/codec/yql_codec.cpp
+++ b/ydb/library/yql/providers/common/codec/yql_codec.cpp
@@ -96,13 +96,13 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod&
writer.OnStringScalar(value.AsStringRef());
return;
- case NUdf::TDataType<NUdf::TDecimal>::Id: {
- const auto params = static_cast<TDataDecimalType*>(type)->GetParams();
- const auto str = NDecimal::ToString(value.GetInt128(), params.first, params.second);
- const auto size = str ? std::strlen(str) : 0;
+ case NUdf::TDataType<NUdf::TDecimal>::Id: {
+ const auto params = static_cast<TDataDecimalType*>(type)->GetParams();
+ const auto str = NDecimal::ToString(value.GetInt128(), params.first, params.second);
+ const auto size = str ? std::strlen(str) : 0;
writer.OnUtf8StringScalar(TStringBuf(str, size));
return;
- }
+ }
case NUdf::TDataType<NUdf::TYson>::Id:
EncodeRestrictedYson(writer, value.AsStringRef());
return;
@@ -118,12 +118,12 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod&
case NUdf::TDataType<NUdf::TInterval>::Id:
writer.OnInt64Scalar(value.Get<i64>());
return;
- case NUdf::TDataType<NUdf::TTzDate>::Id:
- case NUdf::TDataType<NUdf::TTzDatetime>::Id:
+ case NUdf::TDataType<NUdf::TTzDate>::Id:
+ case NUdf::TDataType<NUdf::TTzDatetime>::Id:
case NUdf::TDataType<NUdf::TTzTimestamp>::Id:
case NUdf::TDataType<NUdf::TJsonDocument>::Id: {
const NUdf::TUnboxedValue out(ValueToString(*dataType->GetDataSlot(), value));
- writer.OnUtf8StringScalar(out.AsStringRef());
+ writer.OnUtf8StringScalar(out.AsStringRef());
return;
}
@@ -154,9 +154,9 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod&
{
writer.OnBeginList();
auto listType = AS_TYPE(TListType, type);
- const auto it = value.GetListIterator();
- for (NUdf::TUnboxedValue item; it.Next(item);) {
- writer.OnListItem();
+ const auto it = value.GetListIterator();
+ for (NUdf::TUnboxedValue item; it.Next(item);) {
+ writer.OnListItem();
WriteYsonValueImpl(writer, item, listType->GetItemType(), nullptr);
}
@@ -165,7 +165,7 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod&
}
case TType::EKind::Optional:
{
- if (!value) {
+ if (!value) {
writer.OnEntity();
} else {
writer.OnBeginList();
@@ -180,14 +180,14 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod&
{
writer.OnBeginList();
auto dictType = AS_TYPE(TDictType, type);
- const auto it = value.GetDictIterator();
- for (NUdf::TUnboxedValue key, payload; it.NextPair(key, payload);) {
- writer.OnListItem();
- writer.OnBeginList();
+ const auto it = value.GetDictIterator();
+ for (NUdf::TUnboxedValue key, payload; it.NextPair(key, payload);) {
+ writer.OnListItem();
+ writer.OnBeginList();
{
- writer.OnListItem();
+ writer.OnListItem();
WriteYsonValueImpl(writer, key, dictType->GetKeyType(), nullptr);
- writer.OnListItem();
+ writer.OnListItem();
WriteYsonValueImpl(writer, payload, dictType->GetPayloadType(), nullptr);
}
writer.OnEndList();
@@ -291,7 +291,7 @@ TMaybe<TVector<ui32>> CreateStructPositions(TType* inputType, const TVector<TStr
}
namespace {
-NYT::TNode DataValueToNode(const NKikimr::NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TType* type) {
+NYT::TNode DataValueToNode(const NKikimr::NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TType* type) {
YQL_ENSURE(type->GetKind() == TType::EKind::Data);
auto dataType = AS_TYPE(TDataType, type);
@@ -437,13 +437,13 @@ TString DataValueToString(const NKikimr::NUdf::TUnboxedValuePod& value, const TD
case NUdf::EDataSlot::Json:
case NUdf::EDataSlot::Uuid:
case NUdf::EDataSlot::Yson:
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
return ToString((TStringBuf)value.AsStringRef());
case NUdf::EDataSlot::Decimal:
{
const auto params = dynamic_cast<const TDataExprParamsType*>(type);
return NDecimal::ToString(value.GetInt128(), FromString<ui8>(params->GetParamOne()), FromString<ui8>(params->GetParamTwo()));
- }
+ }
case NUdf::EDataSlot::TzDate: {
TStringStream out;
out << value.Get<ui16>() << "," << NKikimr::NMiniKQL::GetTimezoneIANAName(value.GetTimezoneId());
@@ -773,7 +773,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
}
CHECK_EXPECTED(cmd, EndListSymbol);
- return holderFactory.CreateVariantHolder(value.Release(), index);
+ return holderFactory.CreateVariantHolder(value.Release(), index);
}
case TType::EKind::Data: {
@@ -858,19 +858,19 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
return ReadYsonStringInResultFormat(cmd, buf);
}
- case NUdf::TDataType<NUdf::TDecimal>::Id: {
+ case NUdf::TDataType<NUdf::TDecimal>::Id: {
auto nextString = ReadNextString(cmd, buf);
- if (isTableFormat) {
+ if (isTableFormat) {
const auto& des = NDecimal::Deserialize(nextString.data());
- YQL_ENSURE(nextString.size() == des.second);
- YQL_ENSURE(!NDecimal::IsError(des.first));
- return NUdf::TUnboxedValuePod(des.first);
- } else {
- const auto params = static_cast<TDataDecimalType*>(type)->GetParams();
- const auto val = NDecimal::FromString(nextString, params.first, params.second);
- YQL_ENSURE(!NDecimal::IsError(val));
- return NUdf::TUnboxedValuePod(val);
- }
+ YQL_ENSURE(nextString.size() == des.second);
+ YQL_ENSURE(!NDecimal::IsError(des.first));
+ return NUdf::TUnboxedValuePod(des.first);
+ } else {
+ const auto params = static_cast<TDataDecimalType*>(type)->GetParams();
+ const auto val = NDecimal::FromString(nextString, params.first, params.second);
+ YQL_ENSURE(!NDecimal::IsError(val));
+ return NUdf::TUnboxedValuePod(val);
+ }
}
case NUdf::TDataType<NUdf::TYson>::Id: {
@@ -919,13 +919,13 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
NUdf::TUnboxedValuePod data;
if (isTableFormat) {
ui16 value;
- ui16 tzId = 0;
+ ui16 tzId = 0;
YQL_ENSURE(DeserializeTzDate(nextString, value, tzId));
data = NUdf::TUnboxedValuePod(value);
- data.SetTimezoneId(tzId);
+ data.SetTimezoneId(tzId);
} else {
data = ValueFromString(NUdf::EDataSlot::TzDate, nextString);
- YQL_ENSURE(data, "incorrect tz date format for value " << nextString);
+ YQL_ENSURE(data, "incorrect tz date format for value " << nextString);
}
return data;
@@ -936,13 +936,13 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
NUdf::TUnboxedValuePod data;
if (isTableFormat) {
ui32 value;
- ui16 tzId = 0;
+ ui16 tzId = 0;
YQL_ENSURE(DeserializeTzDatetime(nextString, value, tzId));
data = NUdf::TUnboxedValuePod(value);
- data.SetTimezoneId(tzId);
+ data.SetTimezoneId(tzId);
} else {
- data = ValueFromString(NUdf::EDataSlot::TzDatetime, nextString);
- YQL_ENSURE(data, "incorrect tz datetime format for value " << nextString);
+ data = ValueFromString(NUdf::EDataSlot::TzDatetime, nextString);
+ YQL_ENSURE(data, "incorrect tz datetime format for value " << nextString);
}
return data;
@@ -953,13 +953,13 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
NUdf::TUnboxedValuePod data;
if (isTableFormat) {
ui64 value;
- ui16 tzId = 0;
+ ui16 tzId = 0;
YQL_ENSURE(DeserializeTzTimestamp(nextString, value, tzId));
data = NUdf::TUnboxedValuePod(value);
- data.SetTimezoneId(tzId);
+ data.SetTimezoneId(tzId);
} else {
- data = ValueFromString(NUdf::EDataSlot::TzTimestamp, nextString);
- YQL_ENSURE(data, "incorrect tz timestamp format for value " << nextString);
+ data = ValueFromString(NUdf::EDataSlot::TzTimestamp, nextString);
+ YQL_ENSURE(data, "incorrect tz timestamp format for value " << nextString);
}
return data;
@@ -1071,7 +1071,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
auto itemType = static_cast<TOptionalType*>(type)->GetItemType();
if (cmd != BeginListSymbol) {
auto value = ReadYsonValue(itemType, holderFactory, cmd, buf, isTableFormat);
- return value.Release().MakeOptional();
+ return value.Release().MakeOptional();
}
cmd = buf.Read();
@@ -1086,7 +1086,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type,
}
CHECK_EXPECTED(cmd, EndListSymbol);
- return value.Release().MakeOptional();
+ return value.Release().MakeOptional();
}
case TType::EKind::Dict: {
@@ -1308,7 +1308,7 @@ extern "C" void ReadYsonContainerValue(TType* type, const NKikimr::NMiniKQL::THo
value = std::move(tmp);
}
else {
- value = tmp.Release().MakeOptional();
+ value = tmp.Release().MakeOptional();
}
}
@@ -1789,14 +1789,14 @@ void WriteYsonValueInTableFormat(TOutputBuf& buf, TType* type, const NUdf::TUnbo
break;
}
- case NUdf::TDataType<NUdf::TDecimal>::Id: {
- char data[sizeof(NDecimal::TInt128)];
- const ui32 size = NDecimal::Serialize(value.GetInt128(), data);
- buf.Write(StringMarker);
- buf.WriteVarI32(size);
- buf.WriteMany(data, size);
+ case NUdf::TDataType<NUdf::TDecimal>::Id: {
+ char data[sizeof(NDecimal::TInt128)];
+ const ui32 size = NDecimal::Serialize(value.GetInt128(), data);
+ buf.Write(StringMarker);
+ buf.WriteVarI32(size);
+ buf.WriteMany(data, size);
break;
- }
+ }
case NUdf::TDataType<NUdf::TYson>::Id: {
// embed content
diff --git a/ydb/library/yql/providers/common/codec/yql_codec.h b/ydb/library/yql/providers/common/codec/yql_codec.h
index 8ceb54c9cd..512e01224c 100644
--- a/ydb/library/yql/providers/common/codec/yql_codec.h
+++ b/ydb/library/yql/providers/common/codec/yql_codec.h
@@ -26,13 +26,13 @@ namespace NCommon {
void WriteYsonValue(
NYson::TYsonConsumerBase& writer,
- const NKikimr::NUdf::TUnboxedValuePod& value,
+ const NKikimr::NUdf::TUnboxedValuePod& value,
NKikimr::NMiniKQL::TType* type,
const TVector<ui32>* structPositions = nullptr
);
TString WriteYsonValue(
- const NKikimr::NUdf::TUnboxedValuePod& value,
+ const NKikimr::NUdf::TUnboxedValuePod& value,
NKikimr::NMiniKQL::TType* type,
const TVector<ui32>* structPositions = nullptr,
NYson::EYsonFormat format = NYson::EYsonFormat::Binary
diff --git a/ydb/library/yql/providers/common/codec/yql_codec_results.cpp b/ydb/library/yql/providers/common/codec/yql_codec_results.cpp
index 47ebd40c8b..96c7d784ca 100644
--- a/ydb/library/yql/providers/common/codec/yql_codec_results.cpp
+++ b/ydb/library/yql/providers/common/codec/yql_codec_results.cpp
@@ -10,7 +10,7 @@ namespace NCommon {
constexpr TStringBuf TYsonResultWriter::VoidString;
void TYsonResultWriter::OnStringScalar(TStringBuf value) {
- if (!IsUtf8(value)) {
+ if (!IsUtf8(value)) {
TString encoded = Base64Encode(value);
Writer.OnBeginList();
Writer.OnListItem();
diff --git a/ydb/library/yql/providers/common/comp_nodes/ya.make b/ydb/library/yql/providers/common/comp_nodes/ya.make
index b47d7f9c2f..0498885783 100644
--- a/ydb/library/yql/providers/common/comp_nodes/ya.make
+++ b/ydb/library/yql/providers/common/comp_nodes/ya.make
@@ -48,12 +48,12 @@ PEERDIR(
IF (NOT MKQL_DISABLE_CODEGEN)
PEERDIR(
ydb/library/yql/minikql/codegen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/ExecutionEngine/MCJIT
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Transforms/IPO
)
ELSE()
CFLAGS(
diff --git a/ydb/library/yql/providers/common/comp_nodes/yql_makecode.cpp b/ydb/library/yql/providers/common/comp_nodes/yql_makecode.cpp
index 5bd5596687..7325d12ede 100644
--- a/ydb/library/yql/providers/common/comp_nodes/yql_makecode.cpp
+++ b/ydb/library/yql/providers/common/comp_nodes/yql_makecode.cpp
@@ -119,7 +119,7 @@ public:
inplace[i] = NUdf::TUnboxedValuePod(new TYqlCodeResource(exprCtxPtr, arg));
}
- dynamic_cast<IComputationExternalNode*>(Args_[1])->SetValue(ctx, std::move(array));
+ dynamic_cast<IComputationExternalNode*>(Args_[1])->SetValue(ctx, std::move(array));
}
// get body of lambda
diff --git a/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.cpp b/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.cpp
index ad6da66d65..4da4d13d03 100644
--- a/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.cpp
+++ b/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.cpp
@@ -5,7 +5,7 @@ namespace NYql {
ui64 TDqIntegrationBase::Partition(const TDqSettings& config, size_t maxPartitions, const TExprNode& node,
TVector<TString>& partitions, TString* clusterName, TExprContext& ctx, bool canFallback) {
Y_UNUSED(config);
- Y_UNUSED(maxPartitions);
+ Y_UNUSED(maxPartitions);
Y_UNUSED(node);
Y_UNUSED(partitions);
Y_UNUSED(clusterName);
@@ -14,14 +14,14 @@ ui64 TDqIntegrationBase::Partition(const TDqSettings& config, size_t maxPartitio
return 0;
}
-TMaybe<ui64> TDqIntegrationBase::CanRead(const TDqSettings&, const TExprNode& read, TExprContext& ctx, bool skipIssues) {
+TMaybe<ui64> TDqIntegrationBase::CanRead(const TDqSettings&, const TExprNode& read, TExprContext& ctx, bool skipIssues) {
Y_UNUSED(read);
Y_UNUSED(ctx);
Y_UNUSED(skipIssues);
return Nothing();
}
-TExprNode::TPtr TDqIntegrationBase::WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) {
+TExprNode::TPtr TDqIntegrationBase::WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) {
Y_UNUSED(read);
Y_UNUSED(ctx);
diff --git a/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h b/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h
index 1a7290f014..cd1c150ebf 100644
--- a/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h
+++ b/ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h
@@ -8,8 +8,8 @@ class TDqIntegrationBase: public IDqIntegration {
public:
ui64 Partition(const TDqSettings& config, size_t maxPartitions, const TExprNode& node,
TVector<TString>& partitions, TString* clusterName, TExprContext& ctx, bool canFallback) override;
- TMaybe<ui64> CanRead(const TDqSettings& config, const TExprNode& read, TExprContext& ctx, bool skipIssues) override;
- TExprNode::TPtr WrapRead(const TDqSettings& config, const TExprNode::TPtr& read, TExprContext& ctx) override;
+ TMaybe<ui64> CanRead(const TDqSettings& config, const TExprNode& read, TExprContext& ctx, bool skipIssues) override;
+ TExprNode::TPtr WrapRead(const TDqSettings& config, const TExprNode::TPtr& read, TExprContext& ctx) override;
void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override;
TMaybe<bool> CanWrite(const TDqSettings& config, const TExprNode& write, TExprContext& ctx) override;
bool CanFallback() override;
diff --git a/ydb/library/yql/providers/common/http_gateway/ya.make b/ydb/library/yql/providers/common/http_gateway/ya.make
index 1adeb821a6..f53489973e 100644
--- a/ydb/library/yql/providers/common/http_gateway/ya.make
+++ b/ydb/library/yql/providers/common/http_gateway/ya.make
@@ -1,22 +1,22 @@
-LIBRARY()
-
-OWNER(
+LIBRARY()
+
+OWNER(
g:yq
- g:yql
-)
-
-SRCS(
- yql_http_gateway.cpp
-)
-
-PEERDIR(
+ g:yql
+)
+
+SRCS(
+ yql_http_gateway.cpp
+)
+
+PEERDIR(
contrib/libs/curl
library/cpp/monlib/dynamic_counters
ydb/library/yql/providers/common/proto
ydb/library/yql/public/issue
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
-
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
+
diff --git a/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.cpp b/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.cpp
index fbb9234427..5c2a1451b4 100644
--- a/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.cpp
+++ b/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.cpp
@@ -1,136 +1,136 @@
-#include "yql_http_gateway.h"
-
-#include <contrib/libs/curl/include/curl/curl.h>
-#include <util/stream/str.h>
-#include <util/generic/size_literals.h>
-
-#include <thread>
-#include <mutex>
-#include <stack>
-#include <queue>
-
-namespace NYql {
-namespace {
-
-class TEasyCurl {
-public:
- using TPtr = std::shared_ptr<TEasyCurl>;
- using TWeakPtr = std::weak_ptr<TEasyCurl>;
-
- TEasyCurl(TString url, TString data, IHTTPGateway::THeaders headers, std::size_t expectedSize, IHTTPGateway::TOnResult callback)
- : ExpectedSize(expectedSize), Handle(curl_easy_init()), Data(std::move(data)), Input(Data), Output(Buffer)
- {
- Output.Reserve(expectedSize);
-
- curl_easy_setopt(Handle, CURLOPT_URL, url.c_str());
- curl_easy_setopt(Handle, CURLOPT_POST, Data.empty() ? 0L : 1L);
- curl_easy_setopt(Handle, CURLOPT_WRITEFUNCTION, &WriteMemoryCallback);
- curl_easy_setopt(Handle, CURLOPT_WRITEDATA, static_cast<void*>(&Output));
- curl_easy_setopt(Handle, CURLOPT_USERAGENT, "YQ HTTP gateway");
- curl_easy_setopt(Handle, CURLOPT_SSL_VERIFYPEER, 0L);
-
- if (!headers.empty()) {
- Headers = std::accumulate(headers.cbegin(), headers.cend(), Headers,
- std::bind(&curl_slist_append, std::placeholders::_1, std::bind(&TString::c_str, std::placeholders::_2)));
- curl_easy_setopt(Handle, CURLOPT_HTTPHEADER, Headers);
- }
-
- if (!Data.empty()) {
- curl_easy_setopt(Handle, CURLOPT_READFUNCTION, &ReadMemoryCallback);
- curl_easy_setopt(Handle, CURLOPT_READDATA, static_cast<void*>(&Input));
- }
-
- Callbacks.emplace(std::move(callback));
- }
-
- ~TEasyCurl() {
- curl_easy_cleanup(Handle);
- if (Headers) {
- curl_slist_free_all(Headers);
- }
- }
-
- static TPtr Make(TString url, TString data, IHTTPGateway::THeaders headers, std::size_t expectedSize, IHTTPGateway::TOnResult callback) {
- return std::make_shared<TEasyCurl>(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
- }
-
- std::size_t GetExpectedSize() const {
- return ExpectedSize;
- }
-
- CURL* GetHandle() const {
- return Handle;
- }
-
- void AddCallback(IHTTPGateway::TOnResult callback) {
- Callbacks.emplace(std::move(callback));
- }
-
- void Fail(TIssue error) {
- while (!Callbacks.empty()) {
- Callbacks.top()(TIssues{error});
- Callbacks.pop();
- }
- }
-
- void Done(CURLcode result) {
- if (CURLE_OK != result)
- return Fail(TIssue(curl_easy_strerror(result)));
-
- while (!Callbacks.empty()) {
- if (1U == Callbacks.size())
- Callbacks.top()(IHTTPGateway::TContent(std::move(Buffer)));
- else
- Callbacks.top()(IHTTPGateway::TContent(Buffer));
- Callbacks.pop();
- }
- }
-private:
- static size_t
- WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp)
- {
- const auto realsize = size * nmemb;
- static_cast<TStringOutput*>(userp)->Write(contents, realsize);
- return realsize;
- };
-
- static size_t
- ReadMemoryCallback(char *buffer, size_t size, size_t nmemb, void *userp)
- {
- return static_cast<TStringInput*>(userp)->Read(buffer, size * nmemb);
- };
-
- const std::size_t ExpectedSize;
- CURL *const Handle;
- curl_slist* Headers = nullptr;
- const TString Data;
- TString Buffer;
- TStringInput Input;
- TStringOutput Output;
- std::stack<IHTTPGateway::TOnResult> Callbacks;
-};
-
-using TKeyType = std::tuple<TString, IHTTPGateway::THeaders, TString>;
-
-class TKeyHash {
-public:
- TKeyHash() : Hash() {}
-
- size_t operator()(const TKeyType& key) const {
- const auto& headers = std::get<1U>(key);
- return std::accumulate(headers.cbegin(), headers.cend(), CombineHashes(Hash(std::get<0U>(key)), Hash(std::get<2U>(key))),
- [this](size_t hash, const TString& item) { return CombineHashes(hash, Hash(item)); });
- }
-private:
- const std::hash<TString> Hash;
-};
-
-class THTTPMultiGateway : public IHTTPGateway {
-friend class IHTTPGateway;
-public:
- using TPtr = std::shared_ptr<THTTPMultiGateway>;
- using TWeakPtr = std::weak_ptr<THTTPMultiGateway>;
-
+#include "yql_http_gateway.h"
+
+#include <contrib/libs/curl/include/curl/curl.h>
+#include <util/stream/str.h>
+#include <util/generic/size_literals.h>
+
+#include <thread>
+#include <mutex>
+#include <stack>
+#include <queue>
+
+namespace NYql {
+namespace {
+
+class TEasyCurl {
+public:
+ using TPtr = std::shared_ptr<TEasyCurl>;
+ using TWeakPtr = std::weak_ptr<TEasyCurl>;
+
+ TEasyCurl(TString url, TString data, IHTTPGateway::THeaders headers, std::size_t expectedSize, IHTTPGateway::TOnResult callback)
+ : ExpectedSize(expectedSize), Handle(curl_easy_init()), Data(std::move(data)), Input(Data), Output(Buffer)
+ {
+ Output.Reserve(expectedSize);
+
+ curl_easy_setopt(Handle, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(Handle, CURLOPT_POST, Data.empty() ? 0L : 1L);
+ curl_easy_setopt(Handle, CURLOPT_WRITEFUNCTION, &WriteMemoryCallback);
+ curl_easy_setopt(Handle, CURLOPT_WRITEDATA, static_cast<void*>(&Output));
+ curl_easy_setopt(Handle, CURLOPT_USERAGENT, "YQ HTTP gateway");
+ curl_easy_setopt(Handle, CURLOPT_SSL_VERIFYPEER, 0L);
+
+ if (!headers.empty()) {
+ Headers = std::accumulate(headers.cbegin(), headers.cend(), Headers,
+ std::bind(&curl_slist_append, std::placeholders::_1, std::bind(&TString::c_str, std::placeholders::_2)));
+ curl_easy_setopt(Handle, CURLOPT_HTTPHEADER, Headers);
+ }
+
+ if (!Data.empty()) {
+ curl_easy_setopt(Handle, CURLOPT_READFUNCTION, &ReadMemoryCallback);
+ curl_easy_setopt(Handle, CURLOPT_READDATA, static_cast<void*>(&Input));
+ }
+
+ Callbacks.emplace(std::move(callback));
+ }
+
+ ~TEasyCurl() {
+ curl_easy_cleanup(Handle);
+ if (Headers) {
+ curl_slist_free_all(Headers);
+ }
+ }
+
+ static TPtr Make(TString url, TString data, IHTTPGateway::THeaders headers, std::size_t expectedSize, IHTTPGateway::TOnResult callback) {
+ return std::make_shared<TEasyCurl>(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
+ }
+
+ std::size_t GetExpectedSize() const {
+ return ExpectedSize;
+ }
+
+ CURL* GetHandle() const {
+ return Handle;
+ }
+
+ void AddCallback(IHTTPGateway::TOnResult callback) {
+ Callbacks.emplace(std::move(callback));
+ }
+
+ void Fail(TIssue error) {
+ while (!Callbacks.empty()) {
+ Callbacks.top()(TIssues{error});
+ Callbacks.pop();
+ }
+ }
+
+ void Done(CURLcode result) {
+ if (CURLE_OK != result)
+ return Fail(TIssue(curl_easy_strerror(result)));
+
+ while (!Callbacks.empty()) {
+ if (1U == Callbacks.size())
+ Callbacks.top()(IHTTPGateway::TContent(std::move(Buffer)));
+ else
+ Callbacks.top()(IHTTPGateway::TContent(Buffer));
+ Callbacks.pop();
+ }
+ }
+private:
+ static size_t
+ WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp)
+ {
+ const auto realsize = size * nmemb;
+ static_cast<TStringOutput*>(userp)->Write(contents, realsize);
+ return realsize;
+ };
+
+ static size_t
+ ReadMemoryCallback(char *buffer, size_t size, size_t nmemb, void *userp)
+ {
+ return static_cast<TStringInput*>(userp)->Read(buffer, size * nmemb);
+ };
+
+ const std::size_t ExpectedSize;
+ CURL *const Handle;
+ curl_slist* Headers = nullptr;
+ const TString Data;
+ TString Buffer;
+ TStringInput Input;
+ TStringOutput Output;
+ std::stack<IHTTPGateway::TOnResult> Callbacks;
+};
+
+using TKeyType = std::tuple<TString, IHTTPGateway::THeaders, TString>;
+
+class TKeyHash {
+public:
+ TKeyHash() : Hash() {}
+
+ size_t operator()(const TKeyType& key) const {
+ const auto& headers = std::get<1U>(key);
+ return std::accumulate(headers.cbegin(), headers.cend(), CombineHashes(Hash(std::get<0U>(key)), Hash(std::get<2U>(key))),
+ [this](size_t hash, const TString& item) { return CombineHashes(hash, Hash(item)); });
+ }
+private:
+ const std::hash<TString> Hash;
+};
+
+class THTTPMultiGateway : public IHTTPGateway {
+friend class IHTTPGateway;
+public:
+ using TPtr = std::shared_ptr<THTTPMultiGateway>;
+ using TWeakPtr = std::weak_ptr<THTTPMultiGateway>;
+
explicit THTTPMultiGateway(
const THttpGatewayConfig* httpGatewaysCfg,
NMonitoring::TDynamicCounterPtr counters)
@@ -149,258 +149,258 @@ public:
MaxSimulatenousDownloadsSize = httpGatewaysCfg->GetMaxSimulatenousDownloadsSize();
}
}
-
- ~THTTPMultiGateway() {
- if (Handle)
- curl_multi_wakeup(Handle);
- Thread.join();
- }
-private:
+
+ ~THTTPMultiGateway() {
+ if (Handle)
+ curl_multi_wakeup(Handle);
+ Thread.join();
+ }
+private:
std::size_t MaxHandlers = 1024U;
std::size_t MaxSimulatenousDownloadsSize = 8_GB;
-
- static void Perform(const TWeakPtr& weak) {
- OutputSize.store(0ULL);
- curl_global_init(CURL_GLOBAL_ALL);
-
- if (const auto handle = curl_multi_init()) {
+
+ static void Perform(const TWeakPtr& weak) {
+ OutputSize.store(0ULL);
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ if (const auto handle = curl_multi_init()) {
if (const auto& initHandle = weak.lock()) {
initHandle->Handle = handle;
}
-
- for (size_t handlers = 0U;;) {
- if (const auto& self = weak.lock())
- handlers = self->FillHandlers();
- else
- break;
-
- int running = 0;
- if (const auto c = curl_multi_perform(handle, &running); CURLM_OK != c) {
- if (const auto& self = weak.lock()) {
- self->Fail(c);
- }
- break;
- }
-
- if (running < int(handlers)) {
- if (const auto& self = weak.lock()) {
- for (int messages = int(handlers) - running; messages;) {
- if (const auto msg = curl_multi_info_read(handle, &messages)) {
- if(msg->msg == CURLMSG_DONE) {
- self->Done(msg->easy_handle, msg->data.result);
- }
- }
- }
- }
- } else {
- if (const auto c = curl_multi_poll(handle, nullptr, 0, 1024, nullptr); CURLM_OK != c) {
- if (const auto& self = weak.lock()) {
- self->Fail(c);
- }
- break;
- }
- }
- }
-
- curl_multi_cleanup(handle);
- }
-
- curl_global_cleanup();
- }
-
- size_t FillHandlers() {
- const std::unique_lock lock(Sync);
- while (!Await.empty() && Allocated.size() < MaxHandlers && AllocatedSize + Await.front()->GetExpectedSize() <= MaxSimulatenousDownloadsSize) {
- AllocatedSize += Await.front()->GetExpectedSize();
- const auto handle = Await.front()->GetHandle();
- Allocated.emplace(handle, std::move(Await.front()));
- Await.pop();
- curl_multi_add_handle(Handle, handle);
- }
-
+
+ for (size_t handlers = 0U;;) {
+ if (const auto& self = weak.lock())
+ handlers = self->FillHandlers();
+ else
+ break;
+
+ int running = 0;
+ if (const auto c = curl_multi_perform(handle, &running); CURLM_OK != c) {
+ if (const auto& self = weak.lock()) {
+ self->Fail(c);
+ }
+ break;
+ }
+
+ if (running < int(handlers)) {
+ if (const auto& self = weak.lock()) {
+ for (int messages = int(handlers) - running; messages;) {
+ if (const auto msg = curl_multi_info_read(handle, &messages)) {
+ if(msg->msg == CURLMSG_DONE) {
+ self->Done(msg->easy_handle, msg->data.result);
+ }
+ }
+ }
+ }
+ } else {
+ if (const auto c = curl_multi_poll(handle, nullptr, 0, 1024, nullptr); CURLM_OK != c) {
+ if (const auto& self = weak.lock()) {
+ self->Fail(c);
+ }
+ break;
+ }
+ }
+ }
+
+ curl_multi_cleanup(handle);
+ }
+
+ curl_global_cleanup();
+ }
+
+ size_t FillHandlers() {
+ const std::unique_lock lock(Sync);
+ while (!Await.empty() && Allocated.size() < MaxHandlers && AllocatedSize + Await.front()->GetExpectedSize() <= MaxSimulatenousDownloadsSize) {
+ AllocatedSize += Await.front()->GetExpectedSize();
+ const auto handle = Await.front()->GetHandle();
+ Allocated.emplace(handle, std::move(Await.front()));
+ Await.pop();
+ curl_multi_add_handle(Handle, handle);
+ }
+
AllocatedMemory->Set(AllocatedSize);
- return Allocated.size();
- }
-
- void Done(CURL* handle, CURLcode result) {
- TEasyCurl::TPtr easy;
- {
- const std::unique_lock lock(Sync);
- if (const auto it = Allocated.find(handle); Allocated.cend() != it) {
- easy = std::move(it->second);
- AllocatedSize -= easy->GetExpectedSize();
- Allocated.erase(it);
- }
-
- if (Await.empty() && Allocated.empty())
- Requests.clear();
- }
+ return Allocated.size();
+ }
+
+ void Done(CURL* handle, CURLcode result) {
+ TEasyCurl::TPtr easy;
+ {
+ const std::unique_lock lock(Sync);
+ if (const auto it = Allocated.find(handle); Allocated.cend() != it) {
+ easy = std::move(it->second);
+ AllocatedSize -= easy->GetExpectedSize();
+ Allocated.erase(it);
+ }
+
+ if (Await.empty() && Allocated.empty())
+ Requests.clear();
+ }
if (easy) {
InFlight->Dec();
- easy->Done(result);
+ easy->Done(result);
+ }
+ }
+
+ void Fail(CURLMcode result) {
+ std::stack<TEasyCurl::TPtr> works;
+ {
+ const std::unique_lock lock(Sync);
+
+ for (const auto& item : Allocated) {
+ works.emplace(std::move(item.second));
+ AllocatedSize -= works.top()->GetExpectedSize();
+ }
+
+ AllocatedSize = 0ULL;
+ Allocated.clear();
+ if (Await.empty())
+ Requests.clear();
}
- }
-
- void Fail(CURLMcode result) {
- std::stack<TEasyCurl::TPtr> works;
- {
- const std::unique_lock lock(Sync);
-
- for (const auto& item : Allocated) {
- works.emplace(std::move(item.second));
- AllocatedSize -= works.top()->GetExpectedSize();
- }
-
- AllocatedSize = 0ULL;
- Allocated.clear();
- if (Await.empty())
- Requests.clear();
- }
-
- const TIssue error(curl_multi_strerror(result));
+
+ const TIssue error(curl_multi_strerror(result));
InFlight->Sub(works.size());
- while (!works.empty()) {
- works.top()->Fail(error);
- works.pop();
- }
- }
-
- void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data) final {
+ while (!works.empty()) {
+ works.top()->Fail(error);
+ works.pop();
+ }
+ }
+
+ void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data) final {
Rps->Inc();
InFlight->Inc();
- const std::unique_lock lock(Sync);
- auto& entry = Requests[TKeyType(url, headers, data)];
- if (const auto& easy = entry.lock())
- return easy->AddCallback(std::move(callback));
-
- auto easy = TEasyCurl::Make(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
- entry = easy;
- Await.emplace(std::move(easy));
- if (Allocated.size() < MaxHandlers && AllocatedSize + expectedSize + OutputSize.load() <= MaxSimulatenousDownloadsSize) {
- curl_multi_wakeup(Handle);
- }
- }
-
- CURLM* Handle = nullptr;
-
- std::queue<TEasyCurl::TPtr> Await;
-
- std::unordered_map<CURL*, TEasyCurl::TPtr> Allocated;
-
- std::unordered_map<TKeyType, TEasyCurl::TWeakPtr, TKeyHash> Requests;
-
- std::mutex Sync;
- std::thread Thread;
-
- std::size_t AllocatedSize = 0ULL;
- static std::atomic_size_t OutputSize;
-
- static std::mutex CreateSync;
- static TWeakPtr Singleton;
+ const std::unique_lock lock(Sync);
+ auto& entry = Requests[TKeyType(url, headers, data)];
+ if (const auto& easy = entry.lock())
+ return easy->AddCallback(std::move(callback));
+
+ auto easy = TEasyCurl::Make(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
+ entry = easy;
+ Await.emplace(std::move(easy));
+ if (Allocated.size() < MaxHandlers && AllocatedSize + expectedSize + OutputSize.load() <= MaxSimulatenousDownloadsSize) {
+ curl_multi_wakeup(Handle);
+ }
+ }
+
+ CURLM* Handle = nullptr;
+
+ std::queue<TEasyCurl::TPtr> Await;
+
+ std::unordered_map<CURL*, TEasyCurl::TPtr> Allocated;
+
+ std::unordered_map<TKeyType, TEasyCurl::TWeakPtr, TKeyHash> Requests;
+
+ std::mutex Sync;
+ std::thread Thread;
+
+ std::size_t AllocatedSize = 0ULL;
+ static std::atomic_size_t OutputSize;
+
+ static std::mutex CreateSync;
+ static TWeakPtr Singleton;
const NMonitoring::TDynamicCounterPtr Counters;
const NMonitoring::TDynamicCounters::TCounterPtr Rps;
const NMonitoring::TDynamicCounters::TCounterPtr InFlight;
const NMonitoring::TDynamicCounters::TCounterPtr AllocatedMemory;
-};
-
-std::atomic_size_t THTTPMultiGateway::OutputSize = 0ULL;
-std::mutex THTTPMultiGateway::CreateSync;
-THTTPMultiGateway::TWeakPtr THTTPMultiGateway::Singleton;
-
-class THTTPEasyGateway : public IHTTPGateway, private std::enable_shared_from_this<THTTPEasyGateway> {
-friend class IHTTPGateway;
-public:
- using TPtr = std::shared_ptr<THTTPEasyGateway>;
- using TWeakPtr = std::weak_ptr<THTTPEasyGateway>;
-
- THTTPEasyGateway() {
- curl_global_init(CURL_GLOBAL_ALL);
- }
-
- ~THTTPEasyGateway() {
- for (auto& item : Requests)
- item.second.second.join();
- Requests.clear();
- curl_global_cleanup();
- }
-private:
- static void Perform(const TWeakPtr& weak, const TEasyCurl::TPtr& easy) {
- const auto result = curl_easy_perform(easy->GetHandle());
- if (const auto& self = weak.lock())
- self->Done(easy, result);
- else
- easy->Done(result);
- }
-
- void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data) final {
- const std::unique_lock lock(Sync);
- auto& entry = Requests[TKeyType(url, headers, data)];
- if (const auto& easy = entry.first.lock())
- return easy->AddCallback(std::move(callback));
- auto easy = TEasyCurl::Make(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
- entry = std::make_pair(TEasyCurl::TWeakPtr(easy), std::thread(&THTTPEasyGateway::Perform, weak_from_this(), easy));
- }
-
- void Done(const TEasyCurl::TPtr& easy, CURLcode result) {
- const std::unique_lock lock(Sync);
- easy->Done(result);
- }
-
- std::unordered_map<TKeyType, std::pair<TEasyCurl::TWeakPtr, std::thread>, TKeyHash> Requests;
- std::mutex Sync;
-};
-
-}
-
-IHTTPGateway::TContent::TContent(TString&& data)
- : TString(std::move(data))
-{
- if (!empty()) {
- THTTPMultiGateway::OutputSize.fetch_add(size());
- }
-}
-
-IHTTPGateway::TContent::TContent(const TString& data)
- : TString(data)
-{
- if (!empty()) {
- THTTPMultiGateway::OutputSize.fetch_add(size());
- }
-}
-
-TString IHTTPGateway::TContent::Extract() {
- if (!empty()) {
- THTTPMultiGateway::OutputSize.fetch_sub(size());
- }
- return std::move(*this);
-}
-
-IHTTPGateway::TContent::~TContent()
-{
- if (!empty()) {
- THTTPMultiGateway::OutputSize.fetch_sub(size());
- }
-}
-
-template<>
-IHTTPGateway::TPtr
+};
+
+std::atomic_size_t THTTPMultiGateway::OutputSize = 0ULL;
+std::mutex THTTPMultiGateway::CreateSync;
+THTTPMultiGateway::TWeakPtr THTTPMultiGateway::Singleton;
+
+class THTTPEasyGateway : public IHTTPGateway, private std::enable_shared_from_this<THTTPEasyGateway> {
+friend class IHTTPGateway;
+public:
+ using TPtr = std::shared_ptr<THTTPEasyGateway>;
+ using TWeakPtr = std::weak_ptr<THTTPEasyGateway>;
+
+ THTTPEasyGateway() {
+ curl_global_init(CURL_GLOBAL_ALL);
+ }
+
+ ~THTTPEasyGateway() {
+ for (auto& item : Requests)
+ item.second.second.join();
+ Requests.clear();
+ curl_global_cleanup();
+ }
+private:
+ static void Perform(const TWeakPtr& weak, const TEasyCurl::TPtr& easy) {
+ const auto result = curl_easy_perform(easy->GetHandle());
+ if (const auto& self = weak.lock())
+ self->Done(easy, result);
+ else
+ easy->Done(result);
+ }
+
+ void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data) final {
+ const std::unique_lock lock(Sync);
+ auto& entry = Requests[TKeyType(url, headers, data)];
+ if (const auto& easy = entry.first.lock())
+ return easy->AddCallback(std::move(callback));
+ auto easy = TEasyCurl::Make(std::move(url), std::move(data), std::move(headers), expectedSize, std::move(callback));
+ entry = std::make_pair(TEasyCurl::TWeakPtr(easy), std::thread(&THTTPEasyGateway::Perform, weak_from_this(), easy));
+ }
+
+ void Done(const TEasyCurl::TPtr& easy, CURLcode result) {
+ const std::unique_lock lock(Sync);
+ easy->Done(result);
+ }
+
+ std::unordered_map<TKeyType, std::pair<TEasyCurl::TWeakPtr, std::thread>, TKeyHash> Requests;
+ std::mutex Sync;
+};
+
+}
+
+IHTTPGateway::TContent::TContent(TString&& data)
+ : TString(std::move(data))
+{
+ if (!empty()) {
+ THTTPMultiGateway::OutputSize.fetch_add(size());
+ }
+}
+
+IHTTPGateway::TContent::TContent(const TString& data)
+ : TString(data)
+{
+ if (!empty()) {
+ THTTPMultiGateway::OutputSize.fetch_add(size());
+ }
+}
+
+TString IHTTPGateway::TContent::Extract() {
+ if (!empty()) {
+ THTTPMultiGateway::OutputSize.fetch_sub(size());
+ }
+ return std::move(*this);
+}
+
+IHTTPGateway::TContent::~TContent()
+{
+ if (!empty()) {
+ THTTPMultiGateway::OutputSize.fetch_sub(size());
+ }
+}
+
+template<>
+IHTTPGateway::TPtr
IHTTPGateway::Make<true>(const THttpGatewayConfig* httpGatewaysCfg, NMonitoring::TDynamicCounterPtr counters) {
- const std::unique_lock lock(THTTPMultiGateway::CreateSync);
- if (const auto g = THTTPMultiGateway::Singleton.lock())
- return g;
-
+ const std::unique_lock lock(THTTPMultiGateway::CreateSync);
+ if (const auto g = THTTPMultiGateway::Singleton.lock())
+ return g;
+
const auto gateway = std::make_shared<THTTPMultiGateway>(httpGatewaysCfg, std::move(counters));
- THTTPMultiGateway::Singleton = gateway;
- gateway->Thread = std::thread(std::bind(&THTTPMultiGateway::Perform, THTTPMultiGateway::Singleton));
- return gateway;
-}
-
-template<>
-IHTTPGateway::TPtr
+ THTTPMultiGateway::Singleton = gateway;
+ gateway->Thread = std::thread(std::bind(&THTTPMultiGateway::Perform, THTTPMultiGateway::Singleton));
+ return gateway;
+}
+
+template<>
+IHTTPGateway::TPtr
IHTTPGateway::Make<false>(const THttpGatewayConfig*, NMonitoring::TDynamicCounterPtr) {
- return std::make_shared<THTTPEasyGateway>();
-}
-
-}
+ return std::make_shared<THTTPEasyGateway>();
+}
+
+}
diff --git a/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h b/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h
index cbfcc0fe1d..4e15aa9c78 100644
--- a/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h
+++ b/ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h
@@ -1,54 +1,54 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/providers/common/proto/gateways_config.pb.h>
#include <ydb/library/yql/public/issue/yql_issue.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
+#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-#include <variant>
-#include <functional>
-
-namespace NYql {
-
-class IHTTPGateway {
-public:
- using TPtr = std::shared_ptr<IHTTPGateway>;
- using TWeakPtr = std::weak_ptr<IHTTPGateway>;
-
- virtual ~IHTTPGateway() = default;
-
- template<bool SingleThread = true>
+
+#include <variant>
+#include <functional>
+
+namespace NYql {
+
+class IHTTPGateway {
+public:
+ using TPtr = std::shared_ptr<IHTTPGateway>;
+ using TWeakPtr = std::weak_ptr<IHTTPGateway>;
+
+ virtual ~IHTTPGateway() = default;
+
+ template<bool SingleThread = true>
static TPtr Make(
const THttpGatewayConfig* httpGatewaysCfg = nullptr,
NMonitoring::TDynamicCounterPtr counters = MakeIntrusive<NMonitoring::TDynamicCounters>());
-
- class TContent : private TString {
- friend class TEasyCurl;
- public:
- TContent(TString&& data);
- TContent(const TString& data);
-
- TString Extract();
- ~TContent();
-
- TContent(TContent&&) = default;
- TContent& operator=(TContent&&) = default;
-
- using TString::size;
- using TString::data;
-
- inline operator std::string_view() const { return { data(), size() }; }
- private:
- TContent(const TContent&) = delete;
- TContent& operator=(const TContent&) = delete;
- };
-
- using TResult = std::variant<TContent, TIssues>;
- using TOnResult = std::function<void(TResult&&)>;
- using THeaders = TSmallVec<TString>;
-
- virtual void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data = {}) = 0;
-};
-
-}
+
+ class TContent : private TString {
+ friend class TEasyCurl;
+ public:
+ TContent(TString&& data);
+ TContent(const TString& data);
+
+ TString Extract();
+ ~TContent();
+
+ TContent(TContent&&) = default;
+ TContent& operator=(TContent&&) = default;
+
+ using TString::size;
+ using TString::data;
+
+ inline operator std::string_view() const { return { data(), size() }; }
+ private:
+ TContent(const TContent&) = delete;
+ TContent& operator=(const TContent&) = delete;
+ };
+
+ using TResult = std::variant<TContent, TIssues>;
+ using TOnResult = std::function<void(TResult&&)>;
+ using THeaders = TSmallVec<TString>;
+
+ virtual void Download(TString url, THeaders headers, std::size_t expectedSize, TOnResult callback, TString data = {}) = 0;
+};
+
+}
diff --git a/ydb/library/yql/providers/common/mkql/parser.cpp b/ydb/library/yql/providers/common/mkql/parser.cpp
index cbc742bb53..bfdc26f5f8 100644
--- a/ydb/library/yql/providers/common/mkql/parser.cpp
+++ b/ydb/library/yql/providers/common/mkql/parser.cpp
@@ -100,29 +100,29 @@ TRuntimeNode BuildParseCall(
MKQL_ENSURE(1U == structType->GetMembersCount(), "Expected single column.");
bool isOptional;
const auto schemeType = UnpackOptionalData(structType->GetMemberType(0U), isOptional)->GetSchemeType();
- return ctx.ProgramBuilder.ExpandMap(ctx.ProgramBuilder.ToFlow(input),
- [&](TRuntimeNode item)->TRuntimeNode::TList {
- return { NUdf::TDataType<const char*>::Id == schemeType ?
- isOptional ? ctx.ProgramBuilder.NewOptional(item) : item :
- (ctx.ProgramBuilder.*(isOptional ? &TProgramBuilder::FromString : &TProgramBuilder::StrictFromString))
- (item, ctx.ProgramBuilder.NewDataType(schemeType, isOptional))
- };
- }
- );
- } else if (format == "json_list") {
- input = ctx.ProgramBuilder.FlatMap(ctx.ProgramBuilder.ToFlow(input),
- [&](TRuntimeNode blob) {
- const auto json = ctx.ProgramBuilder.StrictFromString(blob, ctx.ProgramBuilder.NewDataType(NUdf::TDataType<NUdf::TJson>::Id));
- const auto dom = ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("Yson2.ParseJson"), {json});
- const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({dom.GetStaticType()}), ctx.ProgramBuilder.NewStructType({}), ctx.ProgramBuilder.NewListType(outputItemType)});
- return ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("Yson2.ConvertTo", {}, userType), {dom});
- });
- } else {
- const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({inputItemType}), ctx.ProgramBuilder.NewStructType({}), outputItemType});
- input = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFormat", {}, userType, format), {input}));
+ return ctx.ProgramBuilder.ExpandMap(ctx.ProgramBuilder.ToFlow(input),
+ [&](TRuntimeNode item)->TRuntimeNode::TList {
+ return { NUdf::TDataType<const char*>::Id == schemeType ?
+ isOptional ? ctx.ProgramBuilder.NewOptional(item) : item :
+ (ctx.ProgramBuilder.*(isOptional ? &TProgramBuilder::FromString : &TProgramBuilder::StrictFromString))
+ (item, ctx.ProgramBuilder.NewDataType(schemeType, isOptional))
+ };
+ }
+ );
+ } else if (format == "json_list") {
+ input = ctx.ProgramBuilder.FlatMap(ctx.ProgramBuilder.ToFlow(input),
+ [&](TRuntimeNode blob) {
+ const auto json = ctx.ProgramBuilder.StrictFromString(blob, ctx.ProgramBuilder.NewDataType(NUdf::TDataType<NUdf::TJson>::Id));
+ const auto dom = ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("Yson2.ParseJson"), {json});
+ const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({dom.GetStaticType()}), ctx.ProgramBuilder.NewStructType({}), ctx.ProgramBuilder.NewListType(outputItemType)});
+ return ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("Yson2.ConvertTo", {}, userType), {dom});
+ });
+ } else {
+ const auto userType = ctx.ProgramBuilder.NewTupleType({ctx.ProgramBuilder.NewTupleType({inputItemType}), ctx.ProgramBuilder.NewStructType({}), outputItemType});
+ input = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFormat", {}, userType, format), {input}));
}
- return ctx.ProgramBuilder.ExpandMap(input,
+ return ctx.ProgramBuilder.ExpandMap(input,
[&](TRuntimeNode item) {
TRuntimeNode::TList fields;
fields.reserve(structType->GetMembersCount());
diff --git a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp
index 7793518ae8..dd1f162d78 100644
--- a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp
+++ b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp
@@ -14,7 +14,7 @@
#include <ydb/library/yql/minikql/mkql_type_ops.h>
#include <ydb/library/yql/public/decimal/yql_decimal.h>
-#include <util/stream/null.h>
+#include <util/stream/null.h>
#include <array>
@@ -24,17 +24,17 @@ using namespace NKikimr::NMiniKQL;
namespace NYql {
namespace NCommon {
-TRuntimeNode CombineByKeyImpl(const TExprNode& node, TMkqlBuildContext& ctx) {
- NNodes::TCoCombineByKey combine(&node);
+TRuntimeNode CombineByKeyImpl(const TExprNode& node, TMkqlBuildContext& ctx) {
+ NNodes::TCoCombineByKey combine(&node);
const bool isStreamOrFlow = combine.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Stream ||
combine.Ref().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Flow;
YQL_ENSURE(!isStreamOrFlow);
- const auto input = MkqlBuildExpr(combine.Input().Ref(), ctx);
+ const auto input = MkqlBuildExpr(combine.Input().Ref(), ctx);
TRuntimeNode preMapList = ctx.ProgramBuilder.FlatMap(input, [&](TRuntimeNode item) {
- return MkqlBuildLambda(combine.PreMapLambda().Ref(), ctx, {item});
+ return MkqlBuildLambda(combine.PreMapLambda().Ref(), ctx, {item});
});
const auto dict = ctx.ProgramBuilder.ToHashedDict(preMapList, true, [&](TRuntimeNode item) {
@@ -54,126 +54,126 @@ TRuntimeNode CombineByKeyImpl(const TExprNode& node, TMkqlBuildContext& ctx) {
});
auto res = ctx.ProgramBuilder.FlatMap(fold1, [&](TRuntimeNode state) {
return MkqlBuildLambda(combine.FinishHandlerLambda().Ref(), ctx, {key, state});
- });
+ });
return res;
});
-}
+}
namespace {
-std::array<TRuntimeNode, 2U> MkqlBuildSplitLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const std::initializer_list<TRuntimeNode>& args) {
- TMkqlBuildContext::TArgumentsMap innerArguments;
- innerArguments.reserve(args.size());
- auto it = args.begin();
- lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
- const auto& body = lambda.Tail();
- MKQL_ENSURE(body.IsList() && body.ChildrenSize() == 2U, "Expected pair of nodes.");
- return {{MkqlBuildExpr(body.Head(), innerCtx), MkqlBuildExpr(body.Tail(), innerCtx)}};
-}
-
-TMkqlBuildContext* GetNodeContext(const TExprNode& node, TMkqlBuildContext& ctx) {
- for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
- const auto knownNode = currCtx->Memoization.find(&node);
- if (currCtx->Memoization.cend() != knownNode) {
- return currCtx;
- }
- }
- return nullptr;
-}
-
-TMkqlBuildContext* GetNodeContextByLambda(const TExprNode& node, TMkqlBuildContext& ctx) {
- for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
- if (currCtx->LambdaId == node.UniqueId()) {
- return currCtx;
- }
- }
- return nullptr;
-}
-
-TMkqlBuildContext* GetContextForMemoizeInUnknowScope(const TExprNode& node, TMkqlBuildContext& ctx) {
- TMkqlBuildContext* result = nullptr;
- for (const auto& c : node.Children()) {
- const auto& child = c->IsLambda() ? c->Tail() : *c;
- if (!child.IsAtom()) {
- auto nodeCtx = GetNodeContext(child, ctx);
- if (!nodeCtx) {
- nodeCtx = GetContextForMemoizeInUnknowScope(child, ctx);
- }
-
- if (!result || result->Level < nodeCtx->Level) {
- result = nodeCtx;
- if (result == &ctx) {
- break;
- }
- }
- }
- }
-
- if (!result) {
- for (result = &ctx; result->ParentCtx; result = result->ParentCtx)
- continue;
- }
-
- return result;
-}
-
-TMkqlBuildContext* GetContextForMemoize(const TExprNode& node, TMkqlBuildContext& ctx) {
- if (const auto scope = node.GetDependencyScope()) {
- if (const auto lambda = scope->second) {
- return GetNodeContextByLambda(*lambda, ctx);
- }
- } else {
- return GetContextForMemoizeInUnknowScope(node, ctx);
- }
-
- auto result = &ctx;
- while (result->ParentCtx) {
- result = result->ParentCtx;
- }
-
- return result;
-}
-
-const TRuntimeNode& CheckTypeAndMemoize(const TExprNode& node, TMkqlBuildContext& ctx, const TRuntimeNode& runtime) {
- if (node.GetTypeAnn()) {
- TNullOutput null;
- if (const auto type = BuildType(*node.GetTypeAnn(), ctx.ProgramBuilder, null)) {
- if (!type->IsSameType(*runtime.GetStaticType())) {
+std::array<TRuntimeNode, 2U> MkqlBuildSplitLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const std::initializer_list<TRuntimeNode>& args) {
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ innerArguments.reserve(args.size());
+ auto it = args.begin();
+ lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
+ const auto& body = lambda.Tail();
+ MKQL_ENSURE(body.IsList() && body.ChildrenSize() == 2U, "Expected pair of nodes.");
+ return {{MkqlBuildExpr(body.Head(), innerCtx), MkqlBuildExpr(body.Tail(), innerCtx)}};
+}
+
+TMkqlBuildContext* GetNodeContext(const TExprNode& node, TMkqlBuildContext& ctx) {
+ for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
+ const auto knownNode = currCtx->Memoization.find(&node);
+ if (currCtx->Memoization.cend() != knownNode) {
+ return currCtx;
+ }
+ }
+ return nullptr;
+}
+
+TMkqlBuildContext* GetNodeContextByLambda(const TExprNode& node, TMkqlBuildContext& ctx) {
+ for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
+ if (currCtx->LambdaId == node.UniqueId()) {
+ return currCtx;
+ }
+ }
+ return nullptr;
+}
+
+TMkqlBuildContext* GetContextForMemoizeInUnknowScope(const TExprNode& node, TMkqlBuildContext& ctx) {
+ TMkqlBuildContext* result = nullptr;
+ for (const auto& c : node.Children()) {
+ const auto& child = c->IsLambda() ? c->Tail() : *c;
+ if (!child.IsAtom()) {
+ auto nodeCtx = GetNodeContext(child, ctx);
+ if (!nodeCtx) {
+ nodeCtx = GetContextForMemoizeInUnknowScope(child, ctx);
+ }
+
+ if (!result || result->Level < nodeCtx->Level) {
+ result = nodeCtx;
+ if (result == &ctx) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (!result) {
+ for (result = &ctx; result->ParentCtx; result = result->ParentCtx)
+ continue;
+ }
+
+ return result;
+}
+
+TMkqlBuildContext* GetContextForMemoize(const TExprNode& node, TMkqlBuildContext& ctx) {
+ if (const auto scope = node.GetDependencyScope()) {
+ if (const auto lambda = scope->second) {
+ return GetNodeContextByLambda(*lambda, ctx);
+ }
+ } else {
+ return GetContextForMemoizeInUnknowScope(node, ctx);
+ }
+
+ auto result = &ctx;
+ while (result->ParentCtx) {
+ result = result->ParentCtx;
+ }
+
+ return result;
+}
+
+const TRuntimeNode& CheckTypeAndMemoize(const TExprNode& node, TMkqlBuildContext& ctx, const TRuntimeNode& runtime) {
+ if (node.GetTypeAnn()) {
+ TNullOutput null;
+ if (const auto type = BuildType(*node.GetTypeAnn(), ctx.ProgramBuilder, null)) {
+ if (!type->IsSameType(*runtime.GetStaticType())) {
ythrow TNodeException(node) << "Expected: " << *type << " type, but got: " << *runtime.GetStaticType() << ".";
- }
- }
- }
-
- return GetContextForMemoize(node, ctx)->Memoization.emplace(&node, runtime).first->second;
-}
-
-std::vector<TRuntimeNode> GetAllArguments(const TExprNode& node, TMkqlBuildContext& ctx) {
- std::vector<TRuntimeNode> args;
- args.reserve(node.ChildrenSize());
- node.ForEachChild([&](const TExprNode& child){ args.emplace_back(MkqlBuildExpr(child, ctx)); });
- return args;
-}
-
-template <size_t From>
-std::vector<TRuntimeNode> GetArgumentsFrom(const TExprNode& node, TMkqlBuildContext& ctx) {
- std::vector<TRuntimeNode> args;
- args.reserve(node.ChildrenSize() - From);
- for (auto i = From; i < node.ChildrenSize(); ++i) {
- args.emplace_back(MkqlBuildExpr(*node.Child(i), ctx));
- }
- return args;
-}
-
-NUdf::TDataTypeId ParseDataType(const TExprNode& owner, const std::string_view& type) {
- if (const auto slot = NUdf::FindDataSlot(type)) {
+ }
+ }
+ }
+
+ return GetContextForMemoize(node, ctx)->Memoization.emplace(&node, runtime).first->second;
+}
+
+std::vector<TRuntimeNode> GetAllArguments(const TExprNode& node, TMkqlBuildContext& ctx) {
+ std::vector<TRuntimeNode> args;
+ args.reserve(node.ChildrenSize());
+ node.ForEachChild([&](const TExprNode& child){ args.emplace_back(MkqlBuildExpr(child, ctx)); });
+ return args;
+}
+
+template <size_t From>
+std::vector<TRuntimeNode> GetArgumentsFrom(const TExprNode& node, TMkqlBuildContext& ctx) {
+ std::vector<TRuntimeNode> args;
+ args.reserve(node.ChildrenSize() - From);
+ for (auto i = From; i < node.ChildrenSize(); ++i) {
+ args.emplace_back(MkqlBuildExpr(*node.Child(i), ctx));
+ }
+ return args;
+}
+
+NUdf::TDataTypeId ParseDataType(const TExprNode& owner, const std::string_view& type) {
+ if (const auto slot = NUdf::FindDataSlot(type)) {
return NUdf::GetDataTypeInfo(*slot).TypeId;
}
ythrow TNodeException(owner) << "Unsupported data type: " << type;
}
-EJoinKind GetJoinKind(const TExprNode& owner, const std::string_view& content) {
+EJoinKind GetJoinKind(const TExprNode& owner, const std::string_view& content) {
if (content == "Inner") {
return EJoinKind::Inner;
}
@@ -209,31 +209,31 @@ EJoinKind GetJoinKind(const TExprNode& owner, const std::string_view& content) {
}
}
-template<typename TLayout>
-std::pair<TLayout, ui16> CutTimezone(const std::string_view& atom) {
- const auto pos = atom.find(',');
- MKQL_ENSURE(std::string_view::npos != pos, "Expected two components.");
- return std::make_pair(::FromString<TLayout>(atom.substr(0, pos)), GetTimezoneId(atom.substr(pos + 1)));
-}
-
+template<typename TLayout>
+std::pair<TLayout, ui16> CutTimezone(const std::string_view& atom) {
+ const auto pos = atom.find(',');
+ MKQL_ENSURE(std::string_view::npos != pos, "Expected two components.");
+ return std::make_pair(::FromString<TLayout>(atom.substr(0, pos)), GetTimezoneId(atom.substr(pos + 1)));
+}
+
} // namespace
-bool TMkqlCallableCompilerBase::HasCallable(const std::string_view& name) const {
+bool TMkqlCallableCompilerBase::HasCallable(const std::string_view& name) const {
return Callables.contains(name);
}
-void TMkqlCallableCompilerBase::AddCallable(const std::string_view& name, TCompiler compiler) {
- const auto result = Callables.emplace(TString(name), compiler);
- YQL_ENSURE(result.second, "Callable already exists: " << name);
+void TMkqlCallableCompilerBase::AddCallable(const std::string_view& name, TCompiler compiler) {
+ const auto result = Callables.emplace(TString(name), compiler);
+ YQL_ENSURE(result.second, "Callable already exists: " << name);
}
-void TMkqlCallableCompilerBase::AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
- for (const auto& name : names) {
+void TMkqlCallableCompilerBase::AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
+ for (const auto& name : names) {
AddCallable(name, compiler);
}
}
-void TMkqlCallableCompilerBase::ChainCallable(const std::string_view& name, TCompiler compiler) {
+void TMkqlCallableCompilerBase::ChainCallable(const std::string_view& name, TCompiler compiler) {
auto prevCompiler = GetCallable(name);
auto chainedCompiler = [compiler = std::move(compiler), prevCompiler = std::move(prevCompiler)](const TExprNode& node, TMkqlBuildContext& ctx) -> NKikimr::NMiniKQL::TRuntimeNode {
if (auto res = compiler(node, ctx)) {
@@ -244,355 +244,355 @@ void TMkqlCallableCompilerBase::ChainCallable(const std::string_view& name, TCom
OverrideCallable(name, chainedCompiler);
}
-void TMkqlCallableCompilerBase::ChainCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
+void TMkqlCallableCompilerBase::ChainCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
for (const auto& name : names) {
ChainCallable(name, compiler);
}
}
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::UnaryFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- return (ctx.ProgramBuilder.*method)(arg);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::BinaryFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto one = MkqlBuildExpr(node.Head(), ctx);
- const auto two = MkqlBuildExpr(node.Tail(), ctx);
- return (ctx.ProgramBuilder.*method)(one, two);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::TernaryFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg1 = MkqlBuildExpr(node.Head(), ctx);
- const auto arg2 = MkqlBuildExpr(*node.Child(1U), ctx);
- const auto arg3 = MkqlBuildExpr(node.Tail(), ctx);
- return (ctx.ProgramBuilder.*method)(arg1, arg2, arg3);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::ArrayFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& args = GetAllArguments(node, ctx);
- return (ctx.ProgramBuilder.*method)(args);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::ProcessFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(node.Tail(), ctx, {item}); };
- return (ctx.ProgramBuilder.*method)(arg, lambda);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::NarrowFunctionMethod>>& callables) {
- for (const auto& callable : callables) {
- AddCallable(callable.first,
- [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildLambda(node.Tail(), ctx, items); };
- return (ctx.ProgramBuilder.*method)(arg, lambda);
- }
- );
- }
-}
-
-void TMkqlCallableCompilerBase::OverrideCallable(const std::string_view& name, TCompiler compiler) {
- const auto prevCompiler = Callables.find(name);
- YQL_ENSURE(Callables.cend() != prevCompiler, "Missed callable: " << name);
- prevCompiler->second = compiler;
- Callables[name] = compiler;
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::UnaryFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ return (ctx.ProgramBuilder.*method)(arg);
+ }
+ );
+ }
+}
+
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::BinaryFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto one = MkqlBuildExpr(node.Head(), ctx);
+ const auto two = MkqlBuildExpr(node.Tail(), ctx);
+ return (ctx.ProgramBuilder.*method)(one, two);
+ }
+ );
+ }
+}
+
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::TernaryFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg1 = MkqlBuildExpr(node.Head(), ctx);
+ const auto arg2 = MkqlBuildExpr(*node.Child(1U), ctx);
+ const auto arg3 = MkqlBuildExpr(node.Tail(), ctx);
+ return (ctx.ProgramBuilder.*method)(arg1, arg2, arg3);
+ }
+ );
+ }
+}
+
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::ArrayFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& args = GetAllArguments(node, ctx);
+ return (ctx.ProgramBuilder.*method)(args);
+ }
+ );
+ }
+}
+
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::ProcessFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(node.Tail(), ctx, {item}); };
+ return (ctx.ProgramBuilder.*method)(arg, lambda);
+ }
+ );
+ }
+}
+
+void TMkqlCallableCompilerBase::AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, TProgramBuilder::NarrowFunctionMethod>>& callables) {
+ for (const auto& callable : callables) {
+ AddCallable(callable.first,
+ [method=callable.second](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildLambda(node.Tail(), ctx, items); };
+ return (ctx.ProgramBuilder.*method)(arg, lambda);
+ }
+ );
+ }
}
-IMkqlCallableCompiler::TCompiler TMkqlCallableCompilerBase::GetCallable(const std::string_view& name) const {
- const auto compiler = Callables.find(name);
- YQL_ENSURE(Callables.cend() != compiler, "Missed callable: " << name);
- return compiler->second;
+void TMkqlCallableCompilerBase::OverrideCallable(const std::string_view& name, TCompiler compiler) {
+ const auto prevCompiler = Callables.find(name);
+ YQL_ENSURE(Callables.cend() != prevCompiler, "Missed callable: " << name);
+ prevCompiler->second = compiler;
+ Callables[name] = compiler;
}
-IMkqlCallableCompiler::TCompiler TMkqlCallableCompilerBase::FindCallable(const std::string_view& name) const {
- const auto compiler = Callables.find(name);
- return Callables.cend() != compiler ? compiler->second : IMkqlCallableCompiler::TCompiler();
+IMkqlCallableCompiler::TCompiler TMkqlCallableCompilerBase::GetCallable(const std::string_view& name) const {
+ const auto compiler = Callables.find(name);
+ YQL_ENSURE(Callables.cend() != compiler, "Missed callable: " << name);
+ return compiler->second;
}
-bool TMkqlCommonCallableCompiler::HasCallable(const std::string_view& name) const {
+IMkqlCallableCompiler::TCompiler TMkqlCallableCompilerBase::FindCallable(const std::string_view& name) const {
+ const auto compiler = Callables.find(name);
+ return Callables.cend() != compiler ? compiler->second : IMkqlCallableCompiler::TCompiler();
+}
+
+bool TMkqlCommonCallableCompiler::HasCallable(const std::string_view& name) const {
if (TMkqlCallableCompilerBase::HasCallable(name)) {
return true;
}
- return GetShared().HasCallable(name);
+ return GetShared().HasCallable(name);
}
-IMkqlCallableCompiler::TCompiler TMkqlCommonCallableCompiler::FindCallable(const std::string_view& name) const {
- if (const auto func = TMkqlCallableCompilerBase::FindCallable(name)) {
+IMkqlCallableCompiler::TCompiler TMkqlCommonCallableCompiler::FindCallable(const std::string_view& name) const {
+ if (const auto func = TMkqlCallableCompilerBase::FindCallable(name)) {
return func;
}
- return GetShared().FindCallable(name);
+ return GetShared().FindCallable(name);
}
-IMkqlCallableCompiler::TCompiler TMkqlCommonCallableCompiler::GetCallable(const std::string_view& name) const {
- if (const auto func = TMkqlCallableCompilerBase::FindCallable(name)) {
- return func;
+IMkqlCallableCompiler::TCompiler TMkqlCommonCallableCompiler::GetCallable(const std::string_view& name) const {
+ if (const auto func = TMkqlCallableCompilerBase::FindCallable(name)) {
+ return func;
}
- return GetShared().GetCallable(name);
+ return GetShared().GetCallable(name);
}
-void TMkqlCommonCallableCompiler::OverrideCallable(const std::string_view& name, TCompiler compiler) {
+void TMkqlCommonCallableCompiler::OverrideCallable(const std::string_view& name, TCompiler compiler) {
if (TMkqlCallableCompilerBase::HasCallable(name)) {
TMkqlCallableCompilerBase::OverrideCallable(name, compiler);
} else {
- YQL_ENSURE(GetShared().HasCallable(name));
+ YQL_ENSURE(GetShared().HasCallable(name));
TMkqlCallableCompilerBase::AddCallable(name, compiler);
}
}
-void TMkqlCommonCallableCompiler::AddCallable(const std::string_view& name, TCompiler compiler) {
- YQL_ENSURE(!GetShared().HasCallable(name), "Compiler already set for callable: " << name);
+void TMkqlCommonCallableCompiler::AddCallable(const std::string_view& name, TCompiler compiler) {
+ YQL_ENSURE(!GetShared().HasCallable(name), "Compiler already set for callable: " << name);
TMkqlCallableCompilerBase::AddCallable(name, compiler);
}
-void TMkqlCommonCallableCompiler::AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
- for (const auto& name : names) {
+void TMkqlCommonCallableCompiler::AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) {
+ for (const auto& name : names) {
AddCallable(name, compiler);
}
}
TMkqlCommonCallableCompiler::TShared::TShared() {
- AddSimpleCallables({
- {"Abs", &TProgramBuilder::Abs},
- {"Plus", &TProgramBuilder::Plus},
- {"Minus", &TProgramBuilder::Minus},
-
- {"Inc", &TProgramBuilder::Increment},
- {"Dec", &TProgramBuilder::Decrement},
- {"Not", &TProgramBuilder::Not},
-
- {"BitNot", &TProgramBuilder::BitNot},
-
- {"Size", &TProgramBuilder::Size},
-
- {"Way", &TProgramBuilder::Way},
- {"VariantItem", &TProgramBuilder::VariantItem},
-
- {"CountBits", &TProgramBuilder::CountBits},
-
- {"Ascending", &TProgramBuilder::Ascending},
- {"Descending", &TProgramBuilder::Descending},
-
- {"ToOptional", &TProgramBuilder::Head},
- {"Head", &TProgramBuilder::Head},
- {"Last", &TProgramBuilder::Last},
-
- {"ToList", &TProgramBuilder::ToList},
- {"ToFlow", &TProgramBuilder::ToFlow},
- {"FromFlow", &TProgramBuilder::FromFlow},
-
- {"Just", &TProgramBuilder::NewOptional},
- {"Exists", &TProgramBuilder::Exists},
-
- {"Pickle", &TProgramBuilder::Pickle},
- {"StablePickle", &TProgramBuilder::StablePickle},
-
- {"Collect", &TProgramBuilder::Collect},
- {"Discard", &TProgramBuilder::Discard},
- {"LazyList", &TProgramBuilder::LazyList},
- {"ForwardList", &TProgramBuilder::ForwardList},
-
- {"Length", &TProgramBuilder::Length},
- {"HasItems", &TProgramBuilder::HasItems},
-
- {"Reverse", &TProgramBuilder::Reverse},
- {"ToIndexDict", &TProgramBuilder::ToIndexDict},
-
- {"ToString", &TProgramBuilder::ToString},
- {"ToBytes", &TProgramBuilder::ToBytes},
-
- {"AggrCountInit", &TProgramBuilder::AggrCountInit},
-
- {"NewMTRand", &TProgramBuilder::NewMTRand},
- {"NextMTRand", &TProgramBuilder::NextMTRand},
-
- {"TimezoneId", &TProgramBuilder::TimezoneId},
- {"TimezoneName", &TProgramBuilder::TimezoneName},
- {"RemoveTimezone", &TProgramBuilder::RemoveTimezone},
-
- {"DictItems", &TProgramBuilder::DictItems},
- {"DictKeys", &TProgramBuilder::DictKeys},
- {"DictPayloads", &TProgramBuilder::DictPayloads},
-
- {"QueuePop", &TProgramBuilder::QueuePop}
- });
-
- AddSimpleCallables({
- {"+", &TProgramBuilder::Add},
- {"-", &TProgramBuilder::Sub},
- {"*", &TProgramBuilder::Mul},
- {"/", &TProgramBuilder::Div},
- {"%", &TProgramBuilder::Mod},
-
- {"Add", &TProgramBuilder::Add},
- {"Sub", &TProgramBuilder::Sub},
- {"Mul", &TProgramBuilder::Mul},
- {"Div", &TProgramBuilder::Div},
- {"Mod", &TProgramBuilder::Mod},
-
- {"DecimalMul", &TProgramBuilder::DecimalMul},
- {"DecimalDiv", &TProgramBuilder::DecimalDiv},
- {"DecimalMod", &TProgramBuilder::DecimalMod},
-
- {"==", &TProgramBuilder::Equals},
- {"!=", &TProgramBuilder::NotEquals},
- {"<", &TProgramBuilder::Less},
- {"<=", &TProgramBuilder::LessOrEqual},
- {">", &TProgramBuilder::Greater},
- {">=", &TProgramBuilder::GreaterOrEqual},
-
- {"Equals", &TProgramBuilder::Equals},
- {"NotEquals", &TProgramBuilder::NotEquals},
- {"Less", &TProgramBuilder::Less},
- {"LessOrEqual", &TProgramBuilder::LessOrEqual},
- {"Greater", &TProgramBuilder::Greater},
- {"GreaterOrEqual", &TProgramBuilder::GreaterOrEqual},
-
- {"AggrEquals", &TProgramBuilder::AggrEquals},
- {"AggrNotEquals", &TProgramBuilder::AggrNotEquals},
- {"AggrLess", &TProgramBuilder::AggrLess},
- {"AggrLessOrEqual", &TProgramBuilder::AggrLessOrEqual},
- {"AggrGreater", &TProgramBuilder::AggrGreater},
- {"AggrGreaterOrEqual", &TProgramBuilder::AggrGreaterOrEqual},
-
- {"AggrMin", &TProgramBuilder::AggrMin},
- {"AggrMax", &TProgramBuilder::AggrMax},
- {"AggrAdd", &TProgramBuilder::AggrAdd},
-
- {"AggrCountUpdate", &TProgramBuilder::AggrCountUpdate},
-
- {"BitOr", &TProgramBuilder::BitOr},
- {"BitAnd", &TProgramBuilder::BitAnd},
- {"BitXor", &TProgramBuilder::BitXor},
-
- {"ShiftLeft", &TProgramBuilder::ShiftLeft},
- {"ShiftRight", &TProgramBuilder::ShiftRight},
- {"RotLeft", &TProgramBuilder::RotLeft},
- {"RotRight", &TProgramBuilder::RotRight},
-
- {"ListIf", &TProgramBuilder::ListIf},
-
- {"Concat", &TProgramBuilder::Concat},
- {"AggrConcat", &TProgramBuilder::AggrConcat},
- {"ByteAt", &TProgramBuilder::ByteAt},
- {"Nanvl", &TProgramBuilder::Nanvl},
-
- {"Skip", &TProgramBuilder::Skip},
- {"Take", &TProgramBuilder::Take},
- {"Limit", &TProgramBuilder::Take},
-
- {"Append", &TProgramBuilder::Append},
- {"Insert", &TProgramBuilder::Append},
- {"Prepend", &TProgramBuilder::Prepend},
-
- {"Lookup", &TProgramBuilder::Lookup},
- {"Contains", &TProgramBuilder::Contains},
-
- {"AddTimezone", &TProgramBuilder::AddTimezone},
-
- {"StartsWith", &TProgramBuilder::StartsWith},
- {"EndsWith", &TProgramBuilder::EndsWith},
-
- {"SqueezeToList", &TProgramBuilder::SqueezeToList},
-
- {"QueuePush", &TProgramBuilder::QueuePush}
- });
-
- AddSimpleCallables({
- {"Substring", &TProgramBuilder::Substring},
- {"Find", &TProgramBuilder::Find},
- {"RFind", &TProgramBuilder::RFind},
-
- {"ListFromRange", &TProgramBuilder::ListFromRange},
-
- {"PreserveStream", &TProgramBuilder::PreserveStream}
- });
-
- AddSimpleCallables({
- {"If", &TProgramBuilder::If},
-
- {"Or", &TProgramBuilder::Or},
- {"And", &TProgramBuilder::And},
- {"Xor", &TProgramBuilder::Xor},
-
- {"Min", &TProgramBuilder::Min},
- {"Max", &TProgramBuilder::Max},
-
- {"AsList", &TProgramBuilder::AsList},
-
- {"Extend", &TProgramBuilder::Extend},
- {"OrderedExtend", &TProgramBuilder::Extend},
-
- {"Zip", &TProgramBuilder::Zip},
- {"ZipAll", &TProgramBuilder::ZipAll},
-
- {"Random", &TProgramBuilder::Random},
- {"RandomNumber", &TProgramBuilder::RandomNumber},
- {"RandomUuid", &TProgramBuilder::RandomUuid},
-
- {"Now", &TProgramBuilder::Now},
- {"CurrentUtcDate", &TProgramBuilder::CurrentUtcDate},
- {"CurrentUtcDatetime", &TProgramBuilder::CurrentUtcDatetime},
- {"CurrentUtcTimestamp", &TProgramBuilder::CurrentUtcTimestamp}
- });
-
- AddSimpleCallables({
- {"Map", &TProgramBuilder::Map},
- {"OrderedMap", &TProgramBuilder::OrderedMap},
-
- {"FlatMap", &TProgramBuilder::FlatMap},
- {"OrderedFlatMap", &TProgramBuilder::OrderedFlatMap},
-
- {"SkipWhile", &TProgramBuilder::SkipWhile},
- {"TakeWhile", &TProgramBuilder::TakeWhile},
-
- {"SkipWhileInclusive", &TProgramBuilder::SkipWhileInclusive},
- {"TakeWhileInclusive", &TProgramBuilder::TakeWhileInclusive},
- });
-
- AddSimpleCallables({
- {"NarrowMap", &TProgramBuilder::NarrowMap},
- {"NarrowFlatMap", &TProgramBuilder::NarrowFlatMap},
-
- {"WideSkipWhile", &TProgramBuilder::WideSkipWhile},
- {"WideTakeWhile", &TProgramBuilder::WideTakeWhile},
-
- {"WideSkipWhileInclusive", &TProgramBuilder::WideSkipWhileInclusive},
- {"WideTakeWhileInclusive", &TProgramBuilder::WideTakeWhileInclusive},
- });
-
+ AddSimpleCallables({
+ {"Abs", &TProgramBuilder::Abs},
+ {"Plus", &TProgramBuilder::Plus},
+ {"Minus", &TProgramBuilder::Minus},
+
+ {"Inc", &TProgramBuilder::Increment},
+ {"Dec", &TProgramBuilder::Decrement},
+ {"Not", &TProgramBuilder::Not},
+
+ {"BitNot", &TProgramBuilder::BitNot},
+
+ {"Size", &TProgramBuilder::Size},
+
+ {"Way", &TProgramBuilder::Way},
+ {"VariantItem", &TProgramBuilder::VariantItem},
+
+ {"CountBits", &TProgramBuilder::CountBits},
+
+ {"Ascending", &TProgramBuilder::Ascending},
+ {"Descending", &TProgramBuilder::Descending},
+
+ {"ToOptional", &TProgramBuilder::Head},
+ {"Head", &TProgramBuilder::Head},
+ {"Last", &TProgramBuilder::Last},
+
+ {"ToList", &TProgramBuilder::ToList},
+ {"ToFlow", &TProgramBuilder::ToFlow},
+ {"FromFlow", &TProgramBuilder::FromFlow},
+
+ {"Just", &TProgramBuilder::NewOptional},
+ {"Exists", &TProgramBuilder::Exists},
+
+ {"Pickle", &TProgramBuilder::Pickle},
+ {"StablePickle", &TProgramBuilder::StablePickle},
+
+ {"Collect", &TProgramBuilder::Collect},
+ {"Discard", &TProgramBuilder::Discard},
+ {"LazyList", &TProgramBuilder::LazyList},
+ {"ForwardList", &TProgramBuilder::ForwardList},
+
+ {"Length", &TProgramBuilder::Length},
+ {"HasItems", &TProgramBuilder::HasItems},
+
+ {"Reverse", &TProgramBuilder::Reverse},
+ {"ToIndexDict", &TProgramBuilder::ToIndexDict},
+
+ {"ToString", &TProgramBuilder::ToString},
+ {"ToBytes", &TProgramBuilder::ToBytes},
+
+ {"AggrCountInit", &TProgramBuilder::AggrCountInit},
+
+ {"NewMTRand", &TProgramBuilder::NewMTRand},
+ {"NextMTRand", &TProgramBuilder::NextMTRand},
+
+ {"TimezoneId", &TProgramBuilder::TimezoneId},
+ {"TimezoneName", &TProgramBuilder::TimezoneName},
+ {"RemoveTimezone", &TProgramBuilder::RemoveTimezone},
+
+ {"DictItems", &TProgramBuilder::DictItems},
+ {"DictKeys", &TProgramBuilder::DictKeys},
+ {"DictPayloads", &TProgramBuilder::DictPayloads},
+
+ {"QueuePop", &TProgramBuilder::QueuePop}
+ });
+
+ AddSimpleCallables({
+ {"+", &TProgramBuilder::Add},
+ {"-", &TProgramBuilder::Sub},
+ {"*", &TProgramBuilder::Mul},
+ {"/", &TProgramBuilder::Div},
+ {"%", &TProgramBuilder::Mod},
+
+ {"Add", &TProgramBuilder::Add},
+ {"Sub", &TProgramBuilder::Sub},
+ {"Mul", &TProgramBuilder::Mul},
+ {"Div", &TProgramBuilder::Div},
+ {"Mod", &TProgramBuilder::Mod},
+
+ {"DecimalMul", &TProgramBuilder::DecimalMul},
+ {"DecimalDiv", &TProgramBuilder::DecimalDiv},
+ {"DecimalMod", &TProgramBuilder::DecimalMod},
+
+ {"==", &TProgramBuilder::Equals},
+ {"!=", &TProgramBuilder::NotEquals},
+ {"<", &TProgramBuilder::Less},
+ {"<=", &TProgramBuilder::LessOrEqual},
+ {">", &TProgramBuilder::Greater},
+ {">=", &TProgramBuilder::GreaterOrEqual},
+
+ {"Equals", &TProgramBuilder::Equals},
+ {"NotEquals", &TProgramBuilder::NotEquals},
+ {"Less", &TProgramBuilder::Less},
+ {"LessOrEqual", &TProgramBuilder::LessOrEqual},
+ {"Greater", &TProgramBuilder::Greater},
+ {"GreaterOrEqual", &TProgramBuilder::GreaterOrEqual},
+
+ {"AggrEquals", &TProgramBuilder::AggrEquals},
+ {"AggrNotEquals", &TProgramBuilder::AggrNotEquals},
+ {"AggrLess", &TProgramBuilder::AggrLess},
+ {"AggrLessOrEqual", &TProgramBuilder::AggrLessOrEqual},
+ {"AggrGreater", &TProgramBuilder::AggrGreater},
+ {"AggrGreaterOrEqual", &TProgramBuilder::AggrGreaterOrEqual},
+
+ {"AggrMin", &TProgramBuilder::AggrMin},
+ {"AggrMax", &TProgramBuilder::AggrMax},
+ {"AggrAdd", &TProgramBuilder::AggrAdd},
+
+ {"AggrCountUpdate", &TProgramBuilder::AggrCountUpdate},
+
+ {"BitOr", &TProgramBuilder::BitOr},
+ {"BitAnd", &TProgramBuilder::BitAnd},
+ {"BitXor", &TProgramBuilder::BitXor},
+
+ {"ShiftLeft", &TProgramBuilder::ShiftLeft},
+ {"ShiftRight", &TProgramBuilder::ShiftRight},
+ {"RotLeft", &TProgramBuilder::RotLeft},
+ {"RotRight", &TProgramBuilder::RotRight},
+
+ {"ListIf", &TProgramBuilder::ListIf},
+
+ {"Concat", &TProgramBuilder::Concat},
+ {"AggrConcat", &TProgramBuilder::AggrConcat},
+ {"ByteAt", &TProgramBuilder::ByteAt},
+ {"Nanvl", &TProgramBuilder::Nanvl},
+
+ {"Skip", &TProgramBuilder::Skip},
+ {"Take", &TProgramBuilder::Take},
+ {"Limit", &TProgramBuilder::Take},
+
+ {"Append", &TProgramBuilder::Append},
+ {"Insert", &TProgramBuilder::Append},
+ {"Prepend", &TProgramBuilder::Prepend},
+
+ {"Lookup", &TProgramBuilder::Lookup},
+ {"Contains", &TProgramBuilder::Contains},
+
+ {"AddTimezone", &TProgramBuilder::AddTimezone},
+
+ {"StartsWith", &TProgramBuilder::StartsWith},
+ {"EndsWith", &TProgramBuilder::EndsWith},
+
+ {"SqueezeToList", &TProgramBuilder::SqueezeToList},
+
+ {"QueuePush", &TProgramBuilder::QueuePush}
+ });
+
+ AddSimpleCallables({
+ {"Substring", &TProgramBuilder::Substring},
+ {"Find", &TProgramBuilder::Find},
+ {"RFind", &TProgramBuilder::RFind},
+
+ {"ListFromRange", &TProgramBuilder::ListFromRange},
+
+ {"PreserveStream", &TProgramBuilder::PreserveStream}
+ });
+
+ AddSimpleCallables({
+ {"If", &TProgramBuilder::If},
+
+ {"Or", &TProgramBuilder::Or},
+ {"And", &TProgramBuilder::And},
+ {"Xor", &TProgramBuilder::Xor},
+
+ {"Min", &TProgramBuilder::Min},
+ {"Max", &TProgramBuilder::Max},
+
+ {"AsList", &TProgramBuilder::AsList},
+
+ {"Extend", &TProgramBuilder::Extend},
+ {"OrderedExtend", &TProgramBuilder::Extend},
+
+ {"Zip", &TProgramBuilder::Zip},
+ {"ZipAll", &TProgramBuilder::ZipAll},
+
+ {"Random", &TProgramBuilder::Random},
+ {"RandomNumber", &TProgramBuilder::RandomNumber},
+ {"RandomUuid", &TProgramBuilder::RandomUuid},
+
+ {"Now", &TProgramBuilder::Now},
+ {"CurrentUtcDate", &TProgramBuilder::CurrentUtcDate},
+ {"CurrentUtcDatetime", &TProgramBuilder::CurrentUtcDatetime},
+ {"CurrentUtcTimestamp", &TProgramBuilder::CurrentUtcTimestamp}
+ });
+
+ AddSimpleCallables({
+ {"Map", &TProgramBuilder::Map},
+ {"OrderedMap", &TProgramBuilder::OrderedMap},
+
+ {"FlatMap", &TProgramBuilder::FlatMap},
+ {"OrderedFlatMap", &TProgramBuilder::OrderedFlatMap},
+
+ {"SkipWhile", &TProgramBuilder::SkipWhile},
+ {"TakeWhile", &TProgramBuilder::TakeWhile},
+
+ {"SkipWhileInclusive", &TProgramBuilder::SkipWhileInclusive},
+ {"TakeWhileInclusive", &TProgramBuilder::TakeWhileInclusive},
+ });
+
+ AddSimpleCallables({
+ {"NarrowMap", &TProgramBuilder::NarrowMap},
+ {"NarrowFlatMap", &TProgramBuilder::NarrowFlatMap},
+
+ {"WideSkipWhile", &TProgramBuilder::WideSkipWhile},
+ {"WideTakeWhile", &TProgramBuilder::WideTakeWhile},
+
+ {"WideSkipWhileInclusive", &TProgramBuilder::WideSkipWhileInclusive},
+ {"WideTakeWhileInclusive", &TProgramBuilder::WideTakeWhileInclusive},
+ });
+
AddSimpleCallables({
{"RangeUnion", &TProgramBuilder::RangeUnion},
{"RangeIntersect", &TProgramBuilder::RangeIntersect},
@@ -614,190 +614,190 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
{"NextValue", &TProgramBuilder::NextValue},
});
- AddCallable({"MultiMap", "OrderedMultiMap"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode item) { return MkqlBuildWideLambda(node.Tail(), ctx, {item}); };
- return ctx.ProgramBuilder.MultiMap(arg, lambda);
- });
-
- AddCallable("ExpandMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode item) { return MkqlBuildWideLambda(node.Tail(), ctx, {item}); };
- return ctx.ProgramBuilder.ExpandMap(arg, lambda);
- });
-
- AddCallable("WideMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildWideLambda(node.Tail(), ctx, items); };
- return ctx.ProgramBuilder.WideMap(arg, lambda);
- });
-
- AddCallable("WideChain1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto flow = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.WideChain1Map(flow,
- [&](TRuntimeNode::TList items) {
- return MkqlBuildWideLambda(*node.Child(1), ctx, items);
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
- items.insert(items.cend(), state.cbegin(), state.cend());
- return MkqlBuildWideLambda(node.Tail(), ctx, items);
- });
- });
-
- AddCallable("NarrowMultiMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildWideLambda(node.Tail(), ctx, items); };
- return ctx.ProgramBuilder.NarrowMultiMap(arg, lambda);
- });
-
- AddCallable("WideFilter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildLambda(*node.Child(1), ctx, items); };
- if (node.ChildrenSize() > 2U) {
- const auto limit = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.WideFilter(arg, limit, lambda);
- } else {
- return ctx.ProgramBuilder.WideFilter(arg, lambda);
- }
- });
-
- AddCallable("WideCondense1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto flow = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.WideCondense1(flow,
- [&](TRuntimeNode::TList items) {
- return MkqlBuildWideLambda(*node.Child(1), ctx, items);
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
- items.insert(items.cend(), state.cbegin(), state.cend());
- return MkqlBuildLambda(*node.Child(2), ctx, items);
- },
- [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
- items.insert(items.cend(), state.cbegin(), state.cend());
- return MkqlBuildWideLambda(*node.Child(3), ctx, items);
- });
- });
-
- AddCallable("WideCombiner", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto flow = MkqlBuildExpr(node.Head(), ctx);
- ui64 memLimit = 0ULL;
- const bool withLimit = TryFromString<ui64>(node.Child(1U)->Content(), memLimit);
-
- const auto keyExtractor = [&](TRuntimeNode::TList items) {
- return MkqlBuildWideLambda(*node.Child(2U), ctx, items);
- };
- const auto init = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- keys.insert(keys.cend(), items.cbegin(), items.cend());
- return MkqlBuildWideLambda(*node.Child(3U), ctx, keys);
- };
- const auto update = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) {
- keys.insert(keys.cend(), items.cbegin(), items.cend());
- keys.insert(keys.cend(), state.cbegin(), state.cend());
- return MkqlBuildWideLambda(*node.Child(4U), ctx, keys);
- };
- const auto finish = [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) {
- keys.insert(keys.cend(), state.cbegin(), state.cend());
- return MkqlBuildWideLambda(node.Tail(), ctx, keys);
- };
-
- if (withLimit)
- return ctx.ProgramBuilder.WideCombiner(flow, memLimit, keyExtractor, init, update, finish);
- else
- return ctx.ProgramBuilder.WideLastCombiner(flow, keyExtractor, init, update, finish);
- });
-
- AddCallable("WideChopper", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto flow = MkqlBuildExpr(node.Head(), ctx);
-
- const auto keyExtractor = [&](TRuntimeNode::TList items) {
- return MkqlBuildWideLambda(*node.Child(1U), ctx, items);
- };
-
- const auto groupSwitch = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
- keys.insert(keys.cend(), items.cbegin(), items.cend());
- return MkqlBuildLambda(*node.Child(2U), ctx, keys);
- };
-
- const auto handler = [&](TRuntimeNode::TList keys, TRuntimeNode flow) {
- keys.emplace_back(flow);
- return MkqlBuildLambda(node.Tail(), ctx, keys);
- };
-
- return ctx.ProgramBuilder.WideChopper(flow, keyExtractor, groupSwitch, handler);
- });
-
+ AddCallable({"MultiMap", "OrderedMultiMap"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode item) { return MkqlBuildWideLambda(node.Tail(), ctx, {item}); };
+ return ctx.ProgramBuilder.MultiMap(arg, lambda);
+ });
+
+ AddCallable("ExpandMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode item) { return MkqlBuildWideLambda(node.Tail(), ctx, {item}); };
+ return ctx.ProgramBuilder.ExpandMap(arg, lambda);
+ });
+
+ AddCallable("WideMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildWideLambda(node.Tail(), ctx, items); };
+ return ctx.ProgramBuilder.WideMap(arg, lambda);
+ });
+
+ AddCallable("WideChain1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto flow = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.WideChain1Map(flow,
+ [&](TRuntimeNode::TList items) {
+ return MkqlBuildWideLambda(*node.Child(1), ctx, items);
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
+ items.insert(items.cend(), state.cbegin(), state.cend());
+ return MkqlBuildWideLambda(node.Tail(), ctx, items);
+ });
+ });
+
+ AddCallable("NarrowMultiMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildWideLambda(node.Tail(), ctx, items); };
+ return ctx.ProgramBuilder.NarrowMultiMap(arg, lambda);
+ });
+
+ AddCallable("WideFilter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode::TList items) { return MkqlBuildLambda(*node.Child(1), ctx, items); };
+ if (node.ChildrenSize() > 2U) {
+ const auto limit = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.WideFilter(arg, limit, lambda);
+ } else {
+ return ctx.ProgramBuilder.WideFilter(arg, lambda);
+ }
+ });
+
+ AddCallable("WideCondense1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto flow = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.WideCondense1(flow,
+ [&](TRuntimeNode::TList items) {
+ return MkqlBuildWideLambda(*node.Child(1), ctx, items);
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
+ items.insert(items.cend(), state.cbegin(), state.cend());
+ return MkqlBuildLambda(*node.Child(2), ctx, items);
+ },
+ [&](TRuntimeNode::TList items, TRuntimeNode::TList state) {
+ items.insert(items.cend(), state.cbegin(), state.cend());
+ return MkqlBuildWideLambda(*node.Child(3), ctx, items);
+ });
+ });
+
+ AddCallable("WideCombiner", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto flow = MkqlBuildExpr(node.Head(), ctx);
+ ui64 memLimit = 0ULL;
+ const bool withLimit = TryFromString<ui64>(node.Child(1U)->Content(), memLimit);
+
+ const auto keyExtractor = [&](TRuntimeNode::TList items) {
+ return MkqlBuildWideLambda(*node.Child(2U), ctx, items);
+ };
+ const auto init = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ keys.insert(keys.cend(), items.cbegin(), items.cend());
+ return MkqlBuildWideLambda(*node.Child(3U), ctx, keys);
+ };
+ const auto update = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items, TRuntimeNode::TList state) {
+ keys.insert(keys.cend(), items.cbegin(), items.cend());
+ keys.insert(keys.cend(), state.cbegin(), state.cend());
+ return MkqlBuildWideLambda(*node.Child(4U), ctx, keys);
+ };
+ const auto finish = [&](TRuntimeNode::TList keys, TRuntimeNode::TList state) {
+ keys.insert(keys.cend(), state.cbegin(), state.cend());
+ return MkqlBuildWideLambda(node.Tail(), ctx, keys);
+ };
+
+ if (withLimit)
+ return ctx.ProgramBuilder.WideCombiner(flow, memLimit, keyExtractor, init, update, finish);
+ else
+ return ctx.ProgramBuilder.WideLastCombiner(flow, keyExtractor, init, update, finish);
+ });
+
+ AddCallable("WideChopper", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto flow = MkqlBuildExpr(node.Head(), ctx);
+
+ const auto keyExtractor = [&](TRuntimeNode::TList items) {
+ return MkqlBuildWideLambda(*node.Child(1U), ctx, items);
+ };
+
+ const auto groupSwitch = [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
+ keys.insert(keys.cend(), items.cbegin(), items.cend());
+ return MkqlBuildLambda(*node.Child(2U), ctx, keys);
+ };
+
+ const auto handler = [&](TRuntimeNode::TList keys, TRuntimeNode flow) {
+ keys.emplace_back(flow);
+ return MkqlBuildLambda(node.Tail(), ctx, keys);
+ };
+
+ return ctx.ProgramBuilder.WideChopper(flow, keyExtractor, groupSwitch, handler);
+ });
+
AddCallable("Iterable", [](const TExprNode& node, TMkqlBuildContext& ctx) {
const auto lambda = [&]() { return MkqlBuildLambda(*node.Child(0), ctx, {}); };
return ctx.ProgramBuilder.Iterable(lambda);
});
- AddCallable("Filter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(*node.Child(1), ctx, {item}); };
- if (node.ChildrenSize() > 2U) {
- const auto limit = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.Filter(arg, limit, lambda);
- } else {
- return ctx.ProgramBuilder.Filter(arg, lambda);
- }
- });
-
- AddCallable("OrderedFilter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(*node.Child(1), ctx, {item}); };
- if (node.ChildrenSize() > 2U) {
- const auto limit = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.OrderedFilter(arg, limit, lambda);
- } else {
- return ctx.ProgramBuilder.OrderedFilter(arg, lambda);
- }
- });
-
- AddCallable("Member", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto structObj = MkqlBuildExpr(node.Head(), ctx);
- const auto name = node.Tail().Content();
- return ctx.ProgramBuilder.Member(structObj, name);
- });
-
- AddCallable("RemoveMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto structObj = MkqlBuildExpr(node.Head(), ctx);
- const auto name = node.Tail().Content();
- return ctx.ProgramBuilder.RemoveMember(structObj, name, false);
- });
-
- AddCallable("ForceRemoveMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto structObj = MkqlBuildExpr(node.Head(), ctx);
- const auto name = node.Tail().Content();
- return ctx.ProgramBuilder.RemoveMember(structObj, name, true);
- });
-
- AddCallable("Nth", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto tupleObj = MkqlBuildExpr(node.Head(), ctx);
- const auto index = FromString<ui32>(node.Tail().Content());
- return ctx.ProgramBuilder.Nth(tupleObj, index);
- });
-
- AddCallable("Guess", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto variantObj = MkqlBuildExpr(node.Head(), ctx);
- auto type = node.Head().GetTypeAnn();
+ AddCallable("Filter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(*node.Child(1), ctx, {item}); };
+ if (node.ChildrenSize() > 2U) {
+ const auto limit = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.Filter(arg, limit, lambda);
+ } else {
+ return ctx.ProgramBuilder.Filter(arg, lambda);
+ }
+ });
+
+ AddCallable("OrderedFilter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto lambda = [&](TRuntimeNode item) { return MkqlBuildLambda(*node.Child(1), ctx, {item}); };
+ if (node.ChildrenSize() > 2U) {
+ const auto limit = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.OrderedFilter(arg, limit, lambda);
+ } else {
+ return ctx.ProgramBuilder.OrderedFilter(arg, lambda);
+ }
+ });
+
+ AddCallable("Member", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto structObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto name = node.Tail().Content();
+ return ctx.ProgramBuilder.Member(structObj, name);
+ });
+
+ AddCallable("RemoveMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto structObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto name = node.Tail().Content();
+ return ctx.ProgramBuilder.RemoveMember(structObj, name, false);
+ });
+
+ AddCallable("ForceRemoveMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto structObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto name = node.Tail().Content();
+ return ctx.ProgramBuilder.RemoveMember(structObj, name, true);
+ });
+
+ AddCallable("Nth", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto tupleObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto index = FromString<ui32>(node.Tail().Content());
+ return ctx.ProgramBuilder.Nth(tupleObj, index);
+ });
+
+ AddCallable("Guess", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto variantObj = MkqlBuildExpr(node.Head(), ctx);
+ auto type = node.Head().GetTypeAnn();
if (type->GetKind() == ETypeAnnotationKind::Optional) {
type = type->Cast<TOptionalExprType>()->GetItemType();
}
auto varType = type->Cast<TVariantExprType>();
if (varType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
- auto index = FromString<ui32>(node.Child(1)->Content());
- return ctx.ProgramBuilder.Guess(variantObj, index);
+ auto index = FromString<ui32>(node.Child(1)->Content());
+ return ctx.ProgramBuilder.Guess(variantObj, index);
} else {
- return ctx.ProgramBuilder.Guess(variantObj, node.Child(1)->Content());
+ return ctx.ProgramBuilder.Guess(variantObj, node.Child(1)->Content());
}
});
- AddCallable("Visit", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto variantObj = MkqlBuildExpr(node.Head(), ctx);
- const auto type = node.Head().GetTypeAnn()->Cast<TVariantExprType>();
+ AddCallable("Visit", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto variantObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = node.Head().GetTypeAnn()->Cast<TVariantExprType>();
const TTupleExprType* tupleType = nullptr;
const TStructExprType* structType = nullptr;
- std::vector<TExprNode*> lambdas;
+ std::vector<TExprNode*> lambdas;
TRuntimeNode defaultValue;
if (type->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple) {
tupleType = type->GetUnderlyingType()->Cast<TTupleExprType>();
@@ -807,10 +807,10 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
lambdas.resize(structType->GetSize());
}
- for (ui32 index = 1; index < node.ChildrenSize(); ++index) {
- const auto child = node.Child(index);
+ for (ui32 index = 1; index < node.ChildrenSize(); ++index) {
+ const auto child = node.Child(index);
if (!child->IsAtom()) {
- defaultValue = MkqlBuildExpr(*child, ctx);
+ defaultValue = MkqlBuildExpr(*child, ctx);
continue;
}
@@ -823,17 +823,17 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
YQL_ENSURE(itemIndex < lambdas.size());
++index;
- lambdas[itemIndex] = node.Child(index);
+ lambdas[itemIndex] = node.Child(index);
}
- const auto handler = [&](ui32 index, TRuntimeNode item) {
- if (const auto lambda = lambdas[index]) {
- return MkqlBuildLambda(*lambda, ctx, {item});
+ const auto handler = [&](ui32 index, TRuntimeNode item) {
+ if (const auto lambda = lambdas[index]) {
+ return MkqlBuildLambda(*lambda, ctx, {item});
}
- return defaultValue;
+ return defaultValue;
};
- return ctx.ProgramBuilder.VisitAll(variantObj, handler);
+ return ctx.ProgramBuilder.VisitAll(variantObj, handler);
});
AddCallable("CurrentActorId", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -842,52 +842,52 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
return TRuntimeNode(call.Build(), false);
});
- AddCallable("Uint8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<ui8>(node.Head(), NUdf::EDataSlot::Uint8));
+ AddCallable("Uint8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<ui8>(node.Head(), NUdf::EDataSlot::Uint8));
});
- AddCallable("Int8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<i8>(node.Head(), NUdf::EDataSlot::Int8));
+ AddCallable("Int8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<i8>(node.Head(), NUdf::EDataSlot::Int8));
});
- AddCallable("Uint16", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<ui16>(node.Head(), NUdf::EDataSlot::Uint16));
+ AddCallable("Uint16", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<ui16>(node.Head(), NUdf::EDataSlot::Uint16));
});
- AddCallable("Int16", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<i16>(node.Head(), NUdf::EDataSlot::Int16));
+ AddCallable("Int16", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<i16>(node.Head(), NUdf::EDataSlot::Int16));
});
- AddCallable("Int32", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<i32>(node.Head(), NUdf::EDataSlot::Int32));
+ AddCallable("Int32", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<i32>(node.Head(), NUdf::EDataSlot::Int32));
});
- AddCallable("Uint32", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<ui32>(node.Head(), NUdf::EDataSlot::Uint32));
+ AddCallable("Uint32", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<ui32>(node.Head(), NUdf::EDataSlot::Uint32));
});
- AddCallable("Int64", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<i64>(node.Head(), NUdf::EDataSlot::Int64));
+ AddCallable("Int64", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<i64>(node.Head(), NUdf::EDataSlot::Int64));
});
- AddCallable("Uint64", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<ui64>(node.Head(), NUdf::EDataSlot::Uint64));
+ AddCallable("Uint64", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<ui64>(node.Head(), NUdf::EDataSlot::Uint64));
});
- AddCallable("String", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content());
+ AddCallable("String", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content());
});
- AddCallable("Utf8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Utf8>(node.Head().Content());
+ AddCallable("Utf8", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Utf8>(node.Head().Content());
});
- AddCallable("Yson", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Yson>(node.Head().Content());
+ AddCallable("Yson", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Yson>(node.Head().Content());
});
- AddCallable("Json", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Json>(node.Head().Content());
+ AddCallable("Json", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Json>(node.Head().Content());
});
AddCallable("JsonDocument", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -899,595 +899,595 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::JsonDocument>(jsonDocument.AsStringRef());
});
- AddCallable("Uuid", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Uuid>(node.Head().Content());
+ AddCallable("Uuid", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Uuid>(node.Head().Content());
+ });
+
+ AddCallable("Decimal", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto precision = FromString<ui8>(node.Child(1)->Content());
+ const auto scale = FromString<ui8>(node.Child(2)->Content());
+ MKQL_ENSURE(precision > 0, "Precision must be positive.");
+ MKQL_ENSURE(scale <= precision, "Scale too large.");
+ const auto data = NDecimal::FromString(node.Head().Content(), precision, scale);
+ MKQL_ENSURE(!NDecimal::IsError(data), "Bad decimal.");
+ return ctx.ProgramBuilder.NewDecimalLiteral(data, precision, scale);
});
- AddCallable("Decimal", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto precision = FromString<ui8>(node.Child(1)->Content());
- const auto scale = FromString<ui8>(node.Child(2)->Content());
- MKQL_ENSURE(precision > 0, "Precision must be positive.");
- MKQL_ENSURE(scale <= precision, "Scale too large.");
- const auto data = NDecimal::FromString(node.Head().Content(), precision, scale);
- MKQL_ENSURE(!NDecimal::IsError(data), "Bad decimal.");
- return ctx.ProgramBuilder.NewDecimalLiteral(data, precision, scale);
+ AddCallable("Bool", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<bool>(node.Head(), NUdf::EDataSlot::Bool));
});
- AddCallable("Bool", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<bool>(node.Head(), NUdf::EDataSlot::Bool));
+ AddCallable("Float", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<float>(node.Head(), NUdf::EDataSlot::Float));
});
- AddCallable("Float", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<float>(node.Head(), NUdf::EDataSlot::Float));
+ AddCallable("Double", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral(FromString<double>(node.Head(), NUdf::EDataSlot::Double));
});
- AddCallable("Double", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral(FromString<double>(node.Head(), NUdf::EDataSlot::Double));
+ AddCallable("DyNumber", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const NUdf::TUnboxedValue val = ValueFromString(NUdf::EDataSlot::DyNumber, node.Head().Content());
+ MKQL_ENSURE(val, "Bad DyNumber: " << TString(node.Head().Content()).Quote());
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::DyNumber>(val.AsStringRef());
});
- AddCallable("DyNumber", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const NUdf::TUnboxedValue val = ValueFromString(NUdf::EDataSlot::DyNumber, node.Head().Content());
- MKQL_ENSURE(val, "Bad DyNumber: " << TString(node.Head().Content()).Quote());
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::DyNumber>(val.AsStringRef());
- });
-
- AddCallable("Date", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto value = FromString<ui16>(node.Head(), NUdf::EDataSlot::Date);
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Date>(
- NUdf::TStringRef((const char*)&value, sizeof(value)));
+ AddCallable("Date", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto value = FromString<ui16>(node.Head(), NUdf::EDataSlot::Date);
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Date>(
+ NUdf::TStringRef((const char*)&value, sizeof(value)));
});
- AddCallable("Datetime", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto value = FromString<ui32>(node.Head(), NUdf::EDataSlot::Datetime);
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Datetime>(
- NUdf::TStringRef((const char*)&value, sizeof(value)));
+ AddCallable("Datetime", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto value = FromString<ui32>(node.Head(), NUdf::EDataSlot::Datetime);
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Datetime>(
+ NUdf::TStringRef((const char*)&value, sizeof(value)));
});
- AddCallable("Timestamp", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto value = FromString<ui64>(node.Head(), NUdf::EDataSlot::Timestamp);
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Timestamp>(
- NUdf::TStringRef((const char*)&value, sizeof(value)));
+ AddCallable("Timestamp", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto value = FromString<ui64>(node.Head(), NUdf::EDataSlot::Timestamp);
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Timestamp>(
+ NUdf::TStringRef((const char*)&value, sizeof(value)));
});
- AddCallable("Interval", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto value = FromString<i64>(node.Head(), NUdf::EDataSlot::Interval);
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Interval>(
- NUdf::TStringRef((const char*)&value, sizeof(value)));
+ AddCallable("Interval", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto value = FromString<i64>(node.Head(), NUdf::EDataSlot::Interval);
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Interval>(
+ NUdf::TStringRef((const char*)&value, sizeof(value)));
});
- AddCallable("TzDate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& parts = CutTimezone<ui16>(node.Head().Content());
- return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzDate>(parts.first, parts.second);
+ AddCallable("TzDate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& parts = CutTimezone<ui16>(node.Head().Content());
+ return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzDate>(parts.first, parts.second);
});
- AddCallable("TzDatetime", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& parts = CutTimezone<ui32>(node.Head().Content());
- return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzDatetime>(parts.first, parts.second);
+ AddCallable("TzDatetime", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& parts = CutTimezone<ui32>(node.Head().Content());
+ return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzDatetime>(parts.first, parts.second);
});
- AddCallable("TzTimestamp", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& parts = CutTimezone<ui64>(node.Head().Content());
- return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzTimestamp>(parts.first, parts.second);
+ AddCallable("TzTimestamp", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& parts = CutTimezone<ui64>(node.Head().Content());
+ return ctx.ProgramBuilder.NewTzDataLiteral<NUdf::TTzTimestamp>(parts.first, parts.second);
});
- AddCallable("FoldMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto state = MkqlBuildExpr(*node.Child(1), ctx);
- return ctx.ProgramBuilder.ChainMap(list, state, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildSplitLambda(*node.Child(2), ctx, {item, state});
- });
- });
+ AddCallable("FoldMap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto state = MkqlBuildExpr(*node.Child(1), ctx);
+ return ctx.ProgramBuilder.ChainMap(list, state, [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildSplitLambda(*node.Child(2), ctx, {item, state});
+ });
+ });
- AddCallable("Fold1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Chain1Map(list, [&](TRuntimeNode item) {
- return MkqlBuildSplitLambda(*node.Child(1), ctx, {item});
+ AddCallable("Fold1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Chain1Map(list, [&](TRuntimeNode item) {
+ return MkqlBuildSplitLambda(*node.Child(1), ctx, {item});
}, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildSplitLambda(*node.Child(2), ctx, {item, state});
- });
- });
-
- AddCallable("Chain1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Chain1Map(list,
- [&](TRuntimeNode item) -> std::array<TRuntimeNode, 2U> {
- const auto out = MkqlBuildLambda(*node.Child(1), ctx, {item});
- return {{out, out}};
- }, [&](TRuntimeNode item, TRuntimeNode state) -> std::array<TRuntimeNode, 2U> {
- const auto out = MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- return {{out, out}};
- });
- });
-
- AddCallable("Extract", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto name = node.Tail().Content();
- return ctx.ProgramBuilder.Extract(list, name);
- });
-
- AddCallable("OrderedExtract", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto name = node.Child(1)->Content();
- return ctx.ProgramBuilder.OrderedExtract(list, name);
- });
-
- AddCallable("Fold", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto state = MkqlBuildExpr(*node.Child(1), ctx);
- return ctx.ProgramBuilder.Fold(list, state, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- });
- });
-
- AddCallable("Fold1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Fold1(list, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ return MkqlBuildSplitLambda(*node.Child(2), ctx, {item, state});
+ });
+ });
+
+ AddCallable("Chain1Map", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Chain1Map(list,
+ [&](TRuntimeNode item) -> std::array<TRuntimeNode, 2U> {
+ const auto out = MkqlBuildLambda(*node.Child(1), ctx, {item});
+ return {{out, out}};
+ }, [&](TRuntimeNode item, TRuntimeNode state) -> std::array<TRuntimeNode, 2U> {
+ const auto out = MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ return {{out, out}};
+ });
+ });
+
+ AddCallable("Extract", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto name = node.Tail().Content();
+ return ctx.ProgramBuilder.Extract(list, name);
+ });
+
+ AddCallable("OrderedExtract", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto name = node.Child(1)->Content();
+ return ctx.ProgramBuilder.OrderedExtract(list, name);
+ });
+
+ AddCallable("Fold", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto state = MkqlBuildExpr(*node.Child(1), ctx);
+ return ctx.ProgramBuilder.Fold(list, state, [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ });
+ });
+
+ AddCallable("Fold1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Fold1(list, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
}, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- });
- });
-
- AddCallable("Condense", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- const auto state = MkqlBuildExpr(*node.Child(1), ctx);
- return ctx.ProgramBuilder.Condense(stream, state,
- [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(3), ctx, {item, state});
- });
- });
-
- AddCallable("Condense1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Condense1(stream,
- [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(3), ctx, {item, state});
- });
- });
-
- AddCallable("Squeeze", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- const auto state = MkqlBuildExpr(*node.Child(1), ctx);
- return ctx.ProgramBuilder.Squeeze(stream, state, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- }, node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(3), ctx, {state});
- }, node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(4), ctx, {state});
- });
- });
-
- AddCallable("Squeeze1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Squeeze1(stream, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ });
+ });
+
+ AddCallable("Condense", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ const auto state = MkqlBuildExpr(*node.Child(1), ctx);
+ return ctx.ProgramBuilder.Condense(stream, state,
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {item, state});
+ });
+ });
+
+ AddCallable("Condense1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Condense1(stream,
+ [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {item, state});
+ });
+ });
+
+ AddCallable("Squeeze", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ const auto state = MkqlBuildExpr(*node.Child(1), ctx);
+ return ctx.ProgramBuilder.Squeeze(stream, state, [&](TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ }, node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {state});
+ }, node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(4), ctx, {state});
+ });
+ });
+
+ AddCallable("Squeeze1", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Squeeze1(stream, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
}, [&](TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
- }, node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(3), ctx, {state});
- }, node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
- return MkqlBuildLambda(*node.Child(4), ctx, {state});
- });
- });
-
- AddCallable("Sort", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto ascending = MkqlBuildExpr(*node.Child(1), ctx);
- return ctx.ProgramBuilder.Sort(list, ascending, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item});
- });
- });
-
- AddCallable({"Top", "TopSort"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto count = MkqlBuildExpr(*node.Child(1), ctx);
- const auto ascending = MkqlBuildExpr(*node.Child(2), ctx);
- return (ctx.ProgramBuilder.*(node.Content() == "Top" ? &TProgramBuilder::Top : &TProgramBuilder::TopSort))
- (list, count, ascending, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(3), ctx, {item});
- });
- });
-
- AddCallable("KeepTop", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto count = MkqlBuildExpr(node.Head(), ctx);
- const auto list = MkqlBuildExpr(*node.Child(1), ctx);
- const auto item = MkqlBuildExpr(*node.Child(2), ctx);
- const auto ascending = MkqlBuildExpr(*node.Child(3), ctx);
- return ctx.ProgramBuilder.KeepTop(count, list, item, ascending, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(4), ctx, {item});
- });
- });
-
- AddCallable("Struct", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto structType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- const auto verifiedStructType = AS_TYPE(TStructType, structType);
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.reserve(verifiedStructType->GetMembersCount());
- node.ForEachChild([&](const TExprNode& child) {
- members.emplace_back(child.Head().Content(), MkqlBuildExpr(child.Tail(), ctx));
- });
-
- return ctx.ProgramBuilder.NewStruct(verifiedStructType, members);
- });
-
- AddCallable("AddMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto structObj = MkqlBuildExpr(node.Head(), ctx);
- const auto memberName = node.Child(1)->Content();
- const auto value = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.AddMember(structObj, memberName, value);
- });
-
- AddCallable("List", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto listType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
- const auto& items = GetArgumentsFrom<1U>(node, ctx);
- return ctx.ProgramBuilder.NewList(itemType, items);
- });
-
- AddCallable("FromString", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.FromString(arg, type);
- });
-
- AddCallable("StrictFromString", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.StrictFromString(arg, type);
- });
-
- AddCallable("FromBytes", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto schemeType = ParseDataType(node, node.Tail().Content());
- return ctx.ProgramBuilder.FromBytes(arg, schemeType);
- });
-
- AddCallable("Convert", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Convert(arg, type);
- });
-
- AddCallable("ToIntegral", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.ToIntegral(arg, type);
- });
-
- AddCallable("UnsafeTimestampCast", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Convert(arg, type);
- });
-
- AddCallable("SafeCast", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Cast(arg, type);
+ return MkqlBuildLambda(*node.Child(2), ctx, {item, state});
+ }, node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {state});
+ }, node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ return MkqlBuildLambda(*node.Child(4), ctx, {state});
+ });
+ });
+
+ AddCallable("Sort", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto ascending = MkqlBuildExpr(*node.Child(1), ctx);
+ return ctx.ProgramBuilder.Sort(list, ascending, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item});
+ });
+ });
+
+ AddCallable({"Top", "TopSort"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto count = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto ascending = MkqlBuildExpr(*node.Child(2), ctx);
+ return (ctx.ProgramBuilder.*(node.Content() == "Top" ? &TProgramBuilder::Top : &TProgramBuilder::TopSort))
+ (list, count, ascending, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {item});
+ });
+ });
+
+ AddCallable("KeepTop", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto count = MkqlBuildExpr(node.Head(), ctx);
+ const auto list = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto item = MkqlBuildExpr(*node.Child(2), ctx);
+ const auto ascending = MkqlBuildExpr(*node.Child(3), ctx);
+ return ctx.ProgramBuilder.KeepTop(count, list, item, ascending, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(4), ctx, {item});
+ });
+ });
+
+ AddCallable("Struct", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto structType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ const auto verifiedStructType = AS_TYPE(TStructType, structType);
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.reserve(verifiedStructType->GetMembersCount());
+ node.ForEachChild([&](const TExprNode& child) {
+ members.emplace_back(child.Head().Content(), MkqlBuildExpr(child.Tail(), ctx));
+ });
+
+ return ctx.ProgramBuilder.NewStruct(verifiedStructType, members);
+ });
+
+ AddCallable("AddMember", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto structObj = MkqlBuildExpr(node.Head(), ctx);
+ const auto memberName = node.Child(1)->Content();
+ const auto value = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.AddMember(structObj, memberName, value);
+ });
+
+ AddCallable("List", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto listType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ const auto itemType = AS_TYPE(TListType, listType)->GetItemType();
+ const auto& items = GetArgumentsFrom<1U>(node, ctx);
+ return ctx.ProgramBuilder.NewList(itemType, items);
+ });
+
+ AddCallable("FromString", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.FromString(arg, type);
+ });
+
+ AddCallable("StrictFromString", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.StrictFromString(arg, type);
+ });
+
+ AddCallable("FromBytes", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto schemeType = ParseDataType(node, node.Tail().Content());
+ return ctx.ProgramBuilder.FromBytes(arg, schemeType);
+ });
+
+ AddCallable("Convert", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Convert(arg, type);
+ });
+
+ AddCallable("ToIntegral", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.ToIntegral(arg, type);
+ });
+
+ AddCallable("UnsafeTimestampCast", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Convert(arg, type);
+ });
+
+ AddCallable("SafeCast", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto type = BuildType(node.Head(), *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Cast(arg, type);
});
- AddCallable("Default", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Default(type);
+ AddCallable("Default", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Default(type);
});
-
- AddCallable("Coalesce", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- auto ret = MkqlBuildExpr(node.Head(), ctx);
- for (ui32 i = 1; i < node.ChildrenSize(); ++i) {
- auto value = MkqlBuildExpr(*node.Child(i), ctx);
+
+ AddCallable("Coalesce", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ auto ret = MkqlBuildExpr(node.Head(), ctx);
+ for (ui32 i = 1; i < node.ChildrenSize(); ++i) {
+ auto value = MkqlBuildExpr(*node.Child(i), ctx);
ret = ctx.ProgramBuilder.Coalesce(ret, value);
}
- return ret;
+ return ret;
});
- AddCallable("Unwrap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto opt = MkqlBuildExpr(node.Head(), ctx);
- const auto message = node.ChildrenSize() > 1 ? MkqlBuildExpr(node.Tail(), ctx) : ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
+ AddCallable("Unwrap", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto opt = MkqlBuildExpr(node.Head(), ctx);
+ const auto message = node.ChildrenSize() > 1 ? MkqlBuildExpr(node.Tail(), ctx) : ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
return ctx.ProgramBuilder.Unwrap(opt, message, pos.File, pos.Row, pos.Column);
});
- AddCallable("Nothing", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto optType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.NewEmptyOptional(optType);
+ AddCallable("Nothing", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto optType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.NewEmptyOptional(optType);
});
- AddCallable("Unpickle", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- const auto serialized = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.Unpickle(type, serialized);
+ AddCallable("Unpickle", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ const auto serialized = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.Unpickle(type, serialized);
});
- AddCallable("Optional", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto optType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- const auto arg = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.NewOptional(optType, arg);
+ AddCallable("Optional", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto optType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ const auto arg = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.NewOptional(optType, arg);
});
- AddCallable("Iterator", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto& args = GetArgumentsFrom<1U>(node, ctx);
- return ctx.ProgramBuilder.Iterator(arg, args);
+ AddCallable("Iterator", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto& args = GetArgumentsFrom<1U>(node, ctx);
+ return ctx.ProgramBuilder.Iterator(arg, args);
});
- AddCallable("EmptyIterator", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto streamType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.EmptyIterator(streamType);
+ AddCallable("EmptyIterator", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto streamType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.EmptyIterator(streamType);
});
- AddCallable("Switch", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- std::vector<TSwitchInput> inputs;
- ui64 memoryLimitBytes = FromString<ui64>(node.Child(1)->Content());
+ AddCallable("Switch", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ std::vector<TSwitchInput> inputs;
+ ui64 memoryLimitBytes = FromString<ui64>(node.Child(1)->Content());
ui32 offset = 0;
- for (ui32 i = 2; i < node.ChildrenSize(); i += 2) {
+ for (ui32 i = 2; i < node.ChildrenSize(); i += 2) {
TSwitchInput input;
- for (auto& child : node.Child(i)->Children()) {
+ for (auto& child : node.Child(i)->Children()) {
input.Indicies.push_back(FromString<ui32>(child->Content()));
}
- const auto& lambda = *node.Child(i + 1);
- const auto& lambdaArg = lambda.Head().Head();
+ const auto& lambda = *node.Child(i + 1);
+ const auto& lambdaArg = lambda.Head().Head();
auto outputStreams = 1;
- const auto streamItemType = GetSeqItemType(lambda.Tail().GetTypeAnn());
+ const auto streamItemType = GetSeqItemType(lambda.Tail().GetTypeAnn());
if (streamItemType->GetKind() == ETypeAnnotationKind::Variant) {
outputStreams = streamItemType->Cast<TVariantExprType>()->GetUnderlyingType()->Cast<TTupleExprType>()->GetSize();
}
- if (node.ChildrenSize() > 4 || outputStreams != 1) {
+ if (node.ChildrenSize() > 4 || outputStreams != 1) {
input.ResultVariantOffset = offset;
}
offset += outputStreams;
- input.InputType = BuildType(lambdaArg, *lambdaArg.GetTypeAnn(), ctx.ProgramBuilder);
- inputs.emplace_back(input);
+ input.InputType = BuildType(lambdaArg, *lambdaArg.GetTypeAnn(), ctx.ProgramBuilder);
+ inputs.emplace_back(input);
+ }
+
+ const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Switch(stream, inputs, [&](ui32 index, TRuntimeNode item) -> TRuntimeNode {
+ return MkqlBuildLambda(*node.Child(2 + 2 * index + 1), ctx, {item});
+ }, memoryLimitBytes, returnType);
+ });
+
+ AddCallable("ToStream", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ const auto& args = GetArgumentsFrom<1U>(node, ctx);
+ return ctx.ProgramBuilder.Iterator(ctx.ProgramBuilder.ToList(arg), args);
+ });
+
+ AddCallable(LeftName, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Nth(arg, 0);
+ });
+
+ AddCallable(RightName, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ return ctx.ProgramBuilder.Nth(arg, 1);
+ });
+
+ AddCallable("FilterNullMembers", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ if (node.ChildrenSize() < 2U) {
+ return ctx.ProgramBuilder.FilterNullMembers(list);
+ } else {
+ std::vector<std::string_view> members;
+ members.reserve(node.Tail().ChildrenSize());
+ node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Content()); });
+ return ctx.ProgramBuilder.FilterNullMembers(list, members);
+ }
+ });
+
+ AddCallable("SkipNullMembers", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ if (node.ChildrenSize() < 2U) {
+ return ctx.ProgramBuilder.SkipNullMembers(list);
+ } else {
+ std::vector<std::string_view> members;
+ members.reserve(node.Tail().ChildrenSize());
+ node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Content()); });
+ return ctx.ProgramBuilder.SkipNullMembers(list, members);
+ }
+ });
+
+ AddCallable("FilterNullElements", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ if (node.ChildrenSize() < 2U) {
+ return ctx.ProgramBuilder.FilterNullElements(list);
+ } else {
+ std::vector<ui32> members;
+ members.reserve(node.Tail().ChildrenSize());
+ node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(FromString<ui32>(child.Content())); });
+ return ctx.ProgramBuilder.FilterNullElements(list, members);
+ }
+ });
+
+ AddCallable("SkipNullElements", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ if (node.ChildrenSize() < 2U) {
+ return ctx.ProgramBuilder.SkipNullElements(list);
+ } else {
+ std::vector<ui32> members;
+ members.reserve(node.Tail().ChildrenSize());
+ node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(FromString<ui32>(child.Content())); });
+ return ctx.ProgramBuilder.SkipNullElements(list, members);
+ }
+ });
+
+ AddCallable("MapJoinCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto dict = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto joinKind = GetJoinKind(node, node.Child(2)->Content());
+
+ const auto outputItemType = GetSeqItemType(node.GetTypeAnn());
+ auto rightItemType = node.Child(1U)->GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
+ if (ETypeAnnotationKind::List == rightItemType->GetKind()) {
+ rightItemType = rightItemType->Cast<TListExprType>()->GetItemType();
+ }
+
+ std::vector<ui32> leftKeyColumns, leftRenames, rightRenames;
+ switch (const auto inputItemType = GetSeqItemType(node.Head().GetTypeAnn()); inputItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct: {
+ const auto inputStructType = inputItemType->Cast<TStructExprType>();
+ const auto outputStructType = outputItemType->Cast<TStructExprType>();
+
+ node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
+ bool s = false;
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputStructType : *outputStructType, child.Content())); });
+
+ switch (rightItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct: {
+ const auto rightStructType = rightItemType->Cast<TStructExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back(*GetFieldPosition((s = !s) ? *rightStructType : *outputStructType, child.Content())); });
+ }
+ break;
+ case ETypeAnnotationKind::Tuple: {
+ const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightTupleType, child.Content()) : *GetFieldPosition(*outputStructType, child.Content())); });
+ }
+ break;
+ default:
+ MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Tuple: {
+ const auto inputTupleType = inputItemType->Cast<TTupleExprType>();
+ const auto outputTupleType = outputItemType->Cast<TTupleExprType>();
+
+ node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
+ bool s = false;
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputTupleType : *outputTupleType, child.Content())); });
+
+ switch (rightItemType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back(*GetFieldPosition((s = !s) ? *rightTupleType : *outputTupleType, child.Content())); });
+ }
+ break;
+ case ETypeAnnotationKind::Struct: {
+ const auto rightStructType = rightItemType->Cast<TStructExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightStructType, child.Content()) : *GetFieldPosition(*outputTupleType, child.Content())); });
+ }
+ break;
+ default:
+ MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
+ }
+ break;
+ }
+ case ETypeAnnotationKind::Multi: {
+ const auto inputMultiType = inputItemType->Cast<TMultiExprType>();
+ const auto outputMultiType = outputItemType->Cast<TMultiExprType>();
+
+ node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
+ bool s = false;
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputMultiType : *outputMultiType, child.Content())); });
+
+ switch (rightItemType->GetKind()) {
+ case ETypeAnnotationKind::Tuple: {
+ const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightTupleType, child.Content()) : *GetFieldPosition(*outputMultiType, child.Content())); });
+ }
+ break;
+ case ETypeAnnotationKind::Struct: {
+ const auto rightStructType = rightItemType->Cast<TStructExprType>();
+ node.Child(5)->ForEachChild([&](const TExprNode& child){
+ rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightStructType, child.Content()) : *GetFieldPosition(*outputMultiType, child.Content())); });
+ }
+ break;
+ default:
+ MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
+ }
+ break;
+ }
+ default:
+ ythrow TNodeException(node) << "Wrong MapJoinCore input item type: " << *inputItemType;
}
- const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Switch(stream, inputs, [&](ui32 index, TRuntimeNode item) -> TRuntimeNode {
- return MkqlBuildLambda(*node.Child(2 + 2 * index + 1), ctx, {item});
- }, memoryLimitBytes, returnType);
- });
-
- AddCallable("ToStream", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- const auto& args = GetArgumentsFrom<1U>(node, ctx);
- return ctx.ProgramBuilder.Iterator(ctx.ProgramBuilder.ToList(arg), args);
- });
-
- AddCallable(LeftName, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Nth(arg, 0);
- });
-
- AddCallable(RightName, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
- return ctx.ProgramBuilder.Nth(arg, 1);
- });
-
- AddCallable("FilterNullMembers", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- if (node.ChildrenSize() < 2U) {
- return ctx.ProgramBuilder.FilterNullMembers(list);
- } else {
- std::vector<std::string_view> members;
- members.reserve(node.Tail().ChildrenSize());
- node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Content()); });
- return ctx.ProgramBuilder.FilterNullMembers(list, members);
- }
- });
-
- AddCallable("SkipNullMembers", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- if (node.ChildrenSize() < 2U) {
- return ctx.ProgramBuilder.SkipNullMembers(list);
- } else {
- std::vector<std::string_view> members;
- members.reserve(node.Tail().ChildrenSize());
- node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Content()); });
- return ctx.ProgramBuilder.SkipNullMembers(list, members);
- }
- });
-
- AddCallable("FilterNullElements", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- if (node.ChildrenSize() < 2U) {
- return ctx.ProgramBuilder.FilterNullElements(list);
- } else {
- std::vector<ui32> members;
- members.reserve(node.Tail().ChildrenSize());
- node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(FromString<ui32>(child.Content())); });
- return ctx.ProgramBuilder.FilterNullElements(list, members);
- }
- });
-
- AddCallable("SkipNullElements", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- if (node.ChildrenSize() < 2U) {
- return ctx.ProgramBuilder.SkipNullElements(list);
- } else {
- std::vector<ui32> members;
- members.reserve(node.Tail().ChildrenSize());
- node.Tail().ForEachChild([&](const TExprNode& child){ members.emplace_back(FromString<ui32>(child.Content())); });
- return ctx.ProgramBuilder.SkipNullElements(list, members);
- }
- });
-
- AddCallable("MapJoinCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto dict = MkqlBuildExpr(*node.Child(1), ctx);
- const auto joinKind = GetJoinKind(node, node.Child(2)->Content());
-
- const auto outputItemType = GetSeqItemType(node.GetTypeAnn());
- auto rightItemType = node.Child(1U)->GetTypeAnn()->Cast<TDictExprType>()->GetPayloadType();
- if (ETypeAnnotationKind::List == rightItemType->GetKind()) {
- rightItemType = rightItemType->Cast<TListExprType>()->GetItemType();
- }
-
- std::vector<ui32> leftKeyColumns, leftRenames, rightRenames;
- switch (const auto inputItemType = GetSeqItemType(node.Head().GetTypeAnn()); inputItemType->GetKind()) {
- case ETypeAnnotationKind::Struct: {
- const auto inputStructType = inputItemType->Cast<TStructExprType>();
- const auto outputStructType = outputItemType->Cast<TStructExprType>();
-
- node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
- bool s = false;
- node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputStructType : *outputStructType, child.Content())); });
-
- switch (rightItemType->GetKind()) {
- case ETypeAnnotationKind::Struct: {
- const auto rightStructType = rightItemType->Cast<TStructExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back(*GetFieldPosition((s = !s) ? *rightStructType : *outputStructType, child.Content())); });
- }
- break;
- case ETypeAnnotationKind::Tuple: {
- const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightTupleType, child.Content()) : *GetFieldPosition(*outputStructType, child.Content())); });
- }
- break;
- default:
- MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
- }
- break;
- }
- case ETypeAnnotationKind::Tuple: {
- const auto inputTupleType = inputItemType->Cast<TTupleExprType>();
- const auto outputTupleType = outputItemType->Cast<TTupleExprType>();
-
- node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
- bool s = false;
- node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputTupleType : *outputTupleType, child.Content())); });
-
- switch (rightItemType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back(*GetFieldPosition((s = !s) ? *rightTupleType : *outputTupleType, child.Content())); });
- }
- break;
- case ETypeAnnotationKind::Struct: {
- const auto rightStructType = rightItemType->Cast<TStructExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightStructType, child.Content()) : *GetFieldPosition(*outputTupleType, child.Content())); });
- }
- break;
- default:
- MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
- }
- break;
- }
- case ETypeAnnotationKind::Multi: {
- const auto inputMultiType = inputItemType->Cast<TMultiExprType>();
- const auto outputMultiType = outputItemType->Cast<TMultiExprType>();
-
- node.Child(3)->ForEachChild([&](const TExprNode& child){ leftKeyColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
- bool s = false;
- node.Child(4)->ForEachChild([&](const TExprNode& child){ leftRenames.emplace_back(*GetFieldPosition((s = !s) ? *inputMultiType : *outputMultiType, child.Content())); });
-
- switch (rightItemType->GetKind()) {
- case ETypeAnnotationKind::Tuple: {
- const auto rightTupleType = rightItemType->Cast<TTupleExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightTupleType, child.Content()) : *GetFieldPosition(*outputMultiType, child.Content())); });
- }
- break;
- case ETypeAnnotationKind::Struct: {
- const auto rightStructType = rightItemType->Cast<TStructExprType>();
- node.Child(5)->ForEachChild([&](const TExprNode& child){
- rightRenames.emplace_back((s = !s) ? *GetFieldPosition(*rightStructType, child.Content()) : *GetFieldPosition(*outputMultiType, child.Content())); });
- }
- break;
- default:
- MKQL_ENSURE(!node.Child(5)->ChildrenSize(), "Expected empty right output columns.");
- }
- break;
- }
- default:
- ythrow TNodeException(node) << "Wrong MapJoinCore input item type: " << *inputItemType;
- }
-
- const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.MapJoinCore(list, dict, joinKind, leftKeyColumns, leftRenames, rightRenames, returnType);
- });
-
- AddCallable("CommonJoinCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto joinKind = GetJoinKind(node, node.Child(1)->Content());
-
- std::vector<ui32> leftColumns, rightColumns, requiredColumns, keyColumns;
- ui32 tableIndexFieldPos;
- switch (const auto inputItemType = GetSeqItemType(node.Head().GetTypeAnn()); inputItemType->GetKind()) {
- case ETypeAnnotationKind::Struct: {
- const auto inputStructType = inputItemType->Cast<TStructExprType>();
- const auto outputStructType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
- node.Child(2)->ForEachChild([&](const TExprNode& child){
- leftColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content()));
- leftColumns.emplace_back(*GetFieldPosition(*outputStructType, child.Content()));
- });
- node.Child(3)->ForEachChild([&](const TExprNode& child){
- rightColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content()));
- rightColumns.emplace_back(*GetFieldPosition(*outputStructType, child.Content()));
- });
- node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
- node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
- tableIndexFieldPos = *GetFieldPosition(*inputStructType, node.Tail().Content());
- break;
- }
- case ETypeAnnotationKind::Tuple: {
- const auto inputTupleType = inputItemType->Cast<TTupleExprType>();
- ui32 i = 0U;
- node.Child(2)->ForEachChild([&](const TExprNode& child){
- leftColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content()));
- leftColumns.emplace_back(i++);
- });
- node.Child(3)->ForEachChild([&](const TExprNode& child){
- rightColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content()));
- rightColumns.emplace_back(i++);
- });
- node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
- node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
- tableIndexFieldPos = *GetFieldPosition(*inputTupleType, node.Tail().Content());
- break;
- }
- case ETypeAnnotationKind::Multi: {
- const auto inputMultiType = inputItemType->Cast<TMultiExprType>();
- ui32 i = 0U;
- node.Child(2)->ForEachChild([&](const TExprNode& child){
- leftColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content()));
- leftColumns.emplace_back(i++);
- });
- node.Child(3)->ForEachChild([&](const TExprNode& child){
- rightColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content()));
- rightColumns.emplace_back(i++);
- });
- node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
- node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
- tableIndexFieldPos = *GetFieldPosition(*inputMultiType, node.Tail().Content());
- break;
- }
- default:
- ythrow TNodeException(node) << "Wrong CommonJoinCore input item type: " << *inputItemType;
- }
-
- ui64 memLimit = 0U;
- if (const auto memLimitSetting = GetSetting(*node.Child(6), "memLimit")) {
+ const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.MapJoinCore(list, dict, joinKind, leftKeyColumns, leftRenames, rightRenames, returnType);
+ });
+
+ AddCallable("CommonJoinCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto joinKind = GetJoinKind(node, node.Child(1)->Content());
+
+ std::vector<ui32> leftColumns, rightColumns, requiredColumns, keyColumns;
+ ui32 tableIndexFieldPos;
+ switch (const auto inputItemType = GetSeqItemType(node.Head().GetTypeAnn()); inputItemType->GetKind()) {
+ case ETypeAnnotationKind::Struct: {
+ const auto inputStructType = inputItemType->Cast<TStructExprType>();
+ const auto outputStructType = GetSeqItemType(node.GetTypeAnn())->Cast<TStructExprType>();
+ node.Child(2)->ForEachChild([&](const TExprNode& child){
+ leftColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content()));
+ leftColumns.emplace_back(*GetFieldPosition(*outputStructType, child.Content()));
+ });
+ node.Child(3)->ForEachChild([&](const TExprNode& child){
+ rightColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content()));
+ rightColumns.emplace_back(*GetFieldPosition(*outputStructType, child.Content()));
+ });
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
+ node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputStructType, child.Content())); });
+ tableIndexFieldPos = *GetFieldPosition(*inputStructType, node.Tail().Content());
+ break;
+ }
+ case ETypeAnnotationKind::Tuple: {
+ const auto inputTupleType = inputItemType->Cast<TTupleExprType>();
+ ui32 i = 0U;
+ node.Child(2)->ForEachChild([&](const TExprNode& child){
+ leftColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content()));
+ leftColumns.emplace_back(i++);
+ });
+ node.Child(3)->ForEachChild([&](const TExprNode& child){
+ rightColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content()));
+ rightColumns.emplace_back(i++);
+ });
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
+ node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputTupleType, child.Content())); });
+ tableIndexFieldPos = *GetFieldPosition(*inputTupleType, node.Tail().Content());
+ break;
+ }
+ case ETypeAnnotationKind::Multi: {
+ const auto inputMultiType = inputItemType->Cast<TMultiExprType>();
+ ui32 i = 0U;
+ node.Child(2)->ForEachChild([&](const TExprNode& child){
+ leftColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content()));
+ leftColumns.emplace_back(i++);
+ });
+ node.Child(3)->ForEachChild([&](const TExprNode& child){
+ rightColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content()));
+ rightColumns.emplace_back(i++);
+ });
+ node.Child(4)->ForEachChild([&](const TExprNode& child){ requiredColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
+ node.Child(5)->ForEachChild([&](const TExprNode& child){ keyColumns.emplace_back(*GetFieldPosition(*inputMultiType, child.Content())); });
+ tableIndexFieldPos = *GetFieldPosition(*inputMultiType, node.Tail().Content());
+ break;
+ }
+ default:
+ ythrow TNodeException(node) << "Wrong CommonJoinCore input item type: " << *inputItemType;
+ }
+
+ ui64 memLimit = 0U;
+ if (const auto memLimitSetting = GetSetting(*node.Child(6), "memLimit")) {
memLimit = FromString<ui64>(memLimitSetting->Child(1)->Content());
}
- std::optional<ui32> sortedTableOrder;
- if (const auto sortSetting = GetSetting(*node.Child(6), "sorted")) {
+ std::optional<ui32> sortedTableOrder;
+ if (const auto sortSetting = GetSetting(*node.Child(6), "sorted")) {
sortedTableOrder = sortSetting->Child(1)->Content() == "left" ? 0 : 1;
}
@@ -1500,43 +1500,43 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
}
}
- const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.CommonJoinCore(list, joinKind, leftColumns, rightColumns,
- requiredColumns, keyColumns, memLimit, sortedTableOrder, anyJoinSettings, tableIndexFieldPos, returnType);
+ const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.CommonJoinCore(list, joinKind, leftColumns, rightColumns,
+ requiredColumns, keyColumns, memLimit, sortedTableOrder, anyJoinSettings, tableIndexFieldPos, returnType);
});
- AddCallable("CombineCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- NNodes::TCoCombineCore core(&node);
+ AddCallable("CombineCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ NNodes::TCoCombineCore core(&node);
- const auto stream = MkqlBuildExpr(core.Input().Ref(), ctx);
- const auto memLimit = FromString<ui64>(core.MemLimit().Cast().Value());
+ const auto stream = MkqlBuildExpr(core.Input().Ref(), ctx);
+ const auto memLimit = FromString<ui64>(core.MemLimit().Cast().Value());
- const auto keyExtractor = [&](TRuntimeNode item) {
- return MkqlBuildLambda(core.KeyExtractor().Ref(), ctx, {item});
+ const auto keyExtractor = [&](TRuntimeNode item) {
+ return MkqlBuildLambda(core.KeyExtractor().Ref(), ctx, {item});
};
- const auto init = [&](TRuntimeNode key, TRuntimeNode item) {
- return MkqlBuildLambda(core.InitHandler().Ref(), ctx, {key, item});
+ const auto init = [&](TRuntimeNode key, TRuntimeNode item) {
+ return MkqlBuildLambda(core.InitHandler().Ref(), ctx, {key, item});
};
- const auto update = [&](TRuntimeNode key, TRuntimeNode item, TRuntimeNode state) {
- return MkqlBuildLambda(core.UpdateHandler().Ref(), ctx, {key, item, state});
+ const auto update = [&](TRuntimeNode key, TRuntimeNode item, TRuntimeNode state) {
+ return MkqlBuildLambda(core.UpdateHandler().Ref(), ctx, {key, item, state});
};
- const auto finish = [&](TRuntimeNode key, TRuntimeNode state) {
- return MkqlBuildLambda(core.FinishHandler().Ref(), ctx, {key, state});
+ const auto finish = [&](TRuntimeNode key, TRuntimeNode state) {
+ return MkqlBuildLambda(core.FinishHandler().Ref(), ctx, {key, state});
};
- return ctx.ProgramBuilder.CombineCore(stream, keyExtractor, init, update, finish, memLimit);
+ return ctx.ProgramBuilder.CombineCore(stream, keyExtractor, init, update, finish, memLimit);
});
- AddCallable("GroupingCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- NNodes::TCoGroupingCore core(&node);
+ AddCallable("GroupingCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ NNodes::TCoGroupingCore core(&node);
- const auto stream = MkqlBuildExpr(core.Input().Ref(), ctx);
+ const auto stream = MkqlBuildExpr(core.Input().Ref(), ctx);
- const auto groupSwitch = [&](TRuntimeNode key, TRuntimeNode item) {
- return MkqlBuildLambda(core.GroupSwitch().Ref(), ctx, {key, item});
+ const auto groupSwitch = [&](TRuntimeNode key, TRuntimeNode item) {
+ return MkqlBuildLambda(core.GroupSwitch().Ref(), ctx, {key, item});
};
- const auto keyExtractor = [&](TRuntimeNode item) {
- return MkqlBuildLambda(core.KeyExtractor().Ref(), ctx, {item});
+ const auto keyExtractor = [&](TRuntimeNode item) {
+ return MkqlBuildLambda(core.KeyExtractor().Ref(), ctx, {item});
};
TProgramBuilder::TUnaryLambda handler;
if (auto lambda = core.ConvertHandler()) {
@@ -1548,29 +1548,29 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
return ctx.ProgramBuilder.GroupingCore(stream, groupSwitch, keyExtractor, handler);
});
- AddCallable("Chopper", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
-
- const auto keyExtractor = [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1U), ctx, {item});
- };
-
- const auto groupSwitch = [&](TRuntimeNode key, TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(2U), ctx, {key, item});
- };
-
- const auto handler = [&](TRuntimeNode key, TRuntimeNode flow) {
- return MkqlBuildLambda(node.Tail(), ctx, {key, flow});
- };
-
- return ctx.ProgramBuilder.Chopper(stream, keyExtractor, groupSwitch, handler);
- });
-
- AddCallable("HoppingCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ AddCallable("Chopper", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+
+ const auto keyExtractor = [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1U), ctx, {item});
+ };
+
+ const auto groupSwitch = [&](TRuntimeNode key, TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(2U), ctx, {key, item});
+ };
+
+ const auto handler = [&](TRuntimeNode key, TRuntimeNode flow) {
+ return MkqlBuildLambda(node.Tail(), ctx, {key, flow});
+ };
+
+ return ctx.ProgramBuilder.Chopper(stream, keyExtractor, groupSwitch, handler);
+ });
+
+ AddCallable("HoppingCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
const auto timeExtractor = [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
};
const auto hop = MkqlBuildExpr(*node.Child(2), ctx);
const auto interval = MkqlBuildExpr(*node.Child(3), ctx);
@@ -1579,24 +1579,24 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
const auto init = [&](TRuntimeNode item) {
return MkqlBuildLambda(*node.Child(5), ctx, {item});
};
- const auto update = [&](TRuntimeNode item, TRuntimeNode state) {
+ const auto update = [&](TRuntimeNode item, TRuntimeNode state) {
return MkqlBuildLambda(*node.Child(6), ctx, {item, state});
};
- const auto save = node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ const auto save = node.Child(3)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
return MkqlBuildLambda(*node.Child(7), ctx, {state});
};
- const auto load = node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
+ const auto load = node.Child(4)->IsCallable("Void") ? std::function<TRuntimeNode(TRuntimeNode)>() : [&](TRuntimeNode state) {
return MkqlBuildLambda(*node.Child(8), ctx, {state});
};
- const auto merge = [&](TRuntimeNode state1, TRuntimeNode state2) {
+ const auto merge = [&](TRuntimeNode state1, TRuntimeNode state2) {
return MkqlBuildLambda(*node.Child(9), ctx, {state1, state2});
};
- const auto finish = [&](TRuntimeNode state, TRuntimeNode time) {
+ const auto finish = [&](TRuntimeNode state, TRuntimeNode time) {
return MkqlBuildLambda(*node.Child(10), ctx, {state, time});
};
- return ctx.ProgramBuilder.HoppingCore(
- stream, timeExtractor, init, update, save, load, merge, finish, hop, interval, delay);
+ return ctx.ProgramBuilder.HoppingCore(
+ stream, timeExtractor, init, update, save, load, merge, finish, hop, interval, delay);
});
AddCallable("MultiHoppingCore", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -1638,22 +1638,22 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
hop, interval, delay, dataWatermarks);
});
- AddCallable("ToDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
+ AddCallable("ToDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
TMaybe<bool> isMany;
TMaybe<bool> isHashed;
TMaybe<ui64> itemsCount;
bool isCompact;
if (const auto error = ParseToDictSettings(node, ctx.ExprCtx, isMany, isHashed, itemsCount, isCompact)) {
- ythrow TNodeException(node) << error->Message;
+ ythrow TNodeException(node) << error->Message;
}
- const auto factory = *isHashed ? &TProgramBuilder::ToHashedDict : &TProgramBuilder::ToSortedDict;
- return (ctx.ProgramBuilder.*factory)(list, *isMany, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
- }, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item});
- }, isCompact, itemsCount.GetOrElse(0));
+ const auto factory = *isHashed ? &TProgramBuilder::ToHashedDict : &TProgramBuilder::ToSortedDict;
+ return (ctx.ProgramBuilder.*factory)(list, *isMany, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ }, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item});
+ }, isCompact, itemsCount.GetOrElse(0));
});
AddCallable("SqueezeToDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -1674,153 +1674,153 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
}, isCompact, itemsCount.GetOrElse(0));
});
- AddCallable("NarrowSqueezeToDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto stream = MkqlBuildExpr(node.Head(), ctx);
- TMaybe<bool> isMany;
- TMaybe<bool> isHashed;
- TMaybe<ui64> itemsCount;
- bool isCompact;
- if (const auto error = ParseToDictSettings(node, ctx.ExprCtx, isMany, isHashed, itemsCount, isCompact)) {
- ythrow TNodeException(node) << error->Message;
- }
-
- const auto factory = *isHashed ? &TProgramBuilder::NarrowSqueezeToHashedDict : &TProgramBuilder::NarrowSqueezeToSortedDict;
- return (ctx.ProgramBuilder.*factory)(stream, *isMany, [&](TRuntimeNode::TList items) {
- return MkqlBuildLambda(*node.Child(1), ctx, items);
- }, [&](TRuntimeNode::TList items) {
- return MkqlBuildLambda(*node.Child(2), ctx, items);
- }, isCompact, itemsCount.GetOrElse(0));
- });
-
- AddCallable("GroupByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list = MkqlBuildExpr(node.Head(), ctx);
- const auto dict = ctx.ProgramBuilder.ToHashedDict(list, true, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(1), ctx, {item});
+ AddCallable("NarrowSqueezeToDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto stream = MkqlBuildExpr(node.Head(), ctx);
+ TMaybe<bool> isMany;
+ TMaybe<bool> isHashed;
+ TMaybe<ui64> itemsCount;
+ bool isCompact;
+ if (const auto error = ParseToDictSettings(node, ctx.ExprCtx, isMany, isHashed, itemsCount, isCompact)) {
+ ythrow TNodeException(node) << error->Message;
+ }
+
+ const auto factory = *isHashed ? &TProgramBuilder::NarrowSqueezeToHashedDict : &TProgramBuilder::NarrowSqueezeToSortedDict;
+ return (ctx.ProgramBuilder.*factory)(stream, *isMany, [&](TRuntimeNode::TList items) {
+ return MkqlBuildLambda(*node.Child(1), ctx, items);
+ }, [&](TRuntimeNode::TList items) {
+ return MkqlBuildLambda(*node.Child(2), ctx, items);
+ }, isCompact, itemsCount.GetOrElse(0));
+ });
+
+ AddCallable("GroupByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list = MkqlBuildExpr(node.Head(), ctx);
+ const auto dict = ctx.ProgramBuilder.ToHashedDict(list, true, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(1), ctx, {item});
}, [&](TRuntimeNode item) {
return item;
});
- const auto values = ctx.ProgramBuilder.DictItems(dict);
- return ctx.ProgramBuilder.FlatMap(values, [&](TRuntimeNode item) {
- const auto key = ctx.ProgramBuilder.Nth(item, 0);
- const auto payloadList = ctx.ProgramBuilder.Nth(item, 1);
- return MkqlBuildLambda(*node.Child(2), ctx, {key, payloadList});
- });
- });
-
- AddCallable("PartitionByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const NNodes::TCoPartitionByKey partition(&node);
- const auto input = MkqlBuildExpr(partition.Input().Ref(), ctx);
-
- const auto makePartitions = [&](TRuntimeNode list) {
- return ctx.ProgramBuilder.Map(
- ctx.ProgramBuilder.DictItems(ctx.ProgramBuilder.ToHashedDict(list, true,
- [&](TRuntimeNode item) { return MkqlBuildLambda(partition.KeySelectorLambda().Ref(), ctx, {item}); },
- [&](TRuntimeNode item) { return item; }
- )),
- [&](TRuntimeNode pair) {
- const auto payload = partition.SortDirections().Ref().IsCallable("Void") ?
- ctx.ProgramBuilder.Nth(pair, 1):
- ctx.ProgramBuilder.Sort(ctx.ProgramBuilder.Nth(pair, 1), MkqlBuildExpr(partition.SortDirections().Ref(), ctx),
- [&](TRuntimeNode item) {
- return MkqlBuildLambda(partition.SortKeySelectorLambda().Ref(), ctx, {item});
- }
- );
- return ctx.ProgramBuilder.NewTuple({ctx.ProgramBuilder.Nth(pair, 0), ctx.ProgramBuilder.Iterator(payload, {list})});
- }
- );
- };
-
- switch (const auto kind = partition.Ref().GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Flow:
- case ETypeAnnotationKind::Stream: {
- const auto sorted = ctx.ProgramBuilder.FlatMap(
- ctx.ProgramBuilder.Condense1(input,
- [&](TRuntimeNode item) { return ctx.ProgramBuilder.AsList(item); },
- [&](TRuntimeNode, TRuntimeNode) { return ctx.ProgramBuilder.NewDataLiteral(false); },
- [&](TRuntimeNode item, TRuntimeNode state) { return ctx.ProgramBuilder.Append(state, item); }
- ),
- makePartitions
- );
-
- return ETypeAnnotationKind::Stream == kind ?MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {sorted}):
- ctx.ProgramBuilder.ToFlow(MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {ctx.ProgramBuilder.FromFlow(sorted)}));
+ const auto values = ctx.ProgramBuilder.DictItems(dict);
+ return ctx.ProgramBuilder.FlatMap(values, [&](TRuntimeNode item) {
+ const auto key = ctx.ProgramBuilder.Nth(item, 0);
+ const auto payloadList = ctx.ProgramBuilder.Nth(item, 1);
+ return MkqlBuildLambda(*node.Child(2), ctx, {key, payloadList});
+ });
+ });
+
+ AddCallable("PartitionByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const NNodes::TCoPartitionByKey partition(&node);
+ const auto input = MkqlBuildExpr(partition.Input().Ref(), ctx);
+
+ const auto makePartitions = [&](TRuntimeNode list) {
+ return ctx.ProgramBuilder.Map(
+ ctx.ProgramBuilder.DictItems(ctx.ProgramBuilder.ToHashedDict(list, true,
+ [&](TRuntimeNode item) { return MkqlBuildLambda(partition.KeySelectorLambda().Ref(), ctx, {item}); },
+ [&](TRuntimeNode item) { return item; }
+ )),
+ [&](TRuntimeNode pair) {
+ const auto payload = partition.SortDirections().Ref().IsCallable("Void") ?
+ ctx.ProgramBuilder.Nth(pair, 1):
+ ctx.ProgramBuilder.Sort(ctx.ProgramBuilder.Nth(pair, 1), MkqlBuildExpr(partition.SortDirections().Ref(), ctx),
+ [&](TRuntimeNode item) {
+ return MkqlBuildLambda(partition.SortKeySelectorLambda().Ref(), ctx, {item});
+ }
+ );
+ return ctx.ProgramBuilder.NewTuple({ctx.ProgramBuilder.Nth(pair, 0), ctx.ProgramBuilder.Iterator(payload, {list})});
+ }
+ );
+ };
+
+ switch (const auto kind = partition.Ref().GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Flow:
+ case ETypeAnnotationKind::Stream: {
+ const auto sorted = ctx.ProgramBuilder.FlatMap(
+ ctx.ProgramBuilder.Condense1(input,
+ [&](TRuntimeNode item) { return ctx.ProgramBuilder.AsList(item); },
+ [&](TRuntimeNode, TRuntimeNode) { return ctx.ProgramBuilder.NewDataLiteral(false); },
+ [&](TRuntimeNode item, TRuntimeNode state) { return ctx.ProgramBuilder.Append(state, item); }
+ ),
+ makePartitions
+ );
+
+ return ETypeAnnotationKind::Stream == kind ?MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {sorted}):
+ ctx.ProgramBuilder.ToFlow(MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {ctx.ProgramBuilder.FromFlow(sorted)}));
}
- case ETypeAnnotationKind::List: {
- const auto sorted = ctx.ProgramBuilder.Iterator(makePartitions(input), {});
- return ctx.ProgramBuilder.Collect(MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {sorted}));
+ case ETypeAnnotationKind::List: {
+ const auto sorted = ctx.ProgramBuilder.Iterator(makePartitions(input), {});
+ return ctx.ProgramBuilder.Collect(MkqlBuildLambda(partition.ListHandlerLambda().Ref(), ctx, {sorted}));
}
- default: break;
+ default: break;
}
- Y_FAIL("Wrong case.");
+ Y_FAIL("Wrong case.");
});
- AddCallable("CombineByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ AddCallable("CombineByKey", [](const TExprNode& node, TMkqlBuildContext& ctx) {
return CombineByKeyImpl(node, ctx);
});
- AddCallable("Enumerate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto arg = MkqlBuildExpr(node.Head(), ctx);
+ AddCallable("Enumerate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto arg = MkqlBuildExpr(node.Head(), ctx);
TRuntimeNode start;
- if (node.ChildrenSize() > 1) {
- start = MkqlBuildExpr(*node.Child(1), ctx);
- } else {
- start = ctx.ProgramBuilder.NewDataLiteral<ui64>(0);
+ if (node.ChildrenSize() > 1) {
+ start = MkqlBuildExpr(*node.Child(1), ctx);
+ } else {
+ start = ctx.ProgramBuilder.NewDataLiteral<ui64>(0);
}
TRuntimeNode step;
- if (node.ChildrenSize() > 2) {
- step = MkqlBuildExpr(node.Tail(), ctx);
- } else {
- step = ctx.ProgramBuilder.NewDataLiteral<ui64>(1);
+ if (node.ChildrenSize() > 2) {
+ step = MkqlBuildExpr(node.Tail(), ctx);
+ } else {
+ step = ctx.ProgramBuilder.NewDataLiteral<ui64>(1);
}
- return ctx.ProgramBuilder.Enumerate(arg, start, step);
+ return ctx.ProgramBuilder.Enumerate(arg, start, step);
});
- AddCallable("Dict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto listType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- const auto dictType = AS_TYPE(TDictType, listType);
+ AddCallable("Dict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto listType = BuildType(node.Head(), *node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ const auto dictType = AS_TYPE(TDictType, listType);
- std::vector<std::pair<TRuntimeNode, TRuntimeNode>> items;
- for (size_t i = 1; i < node.ChildrenSize(); ++i) {
- const auto key = MkqlBuildExpr(node.Child(i)->Head(), ctx);
- const auto payload = MkqlBuildExpr(node.Child(i)->Tail(), ctx);
- items.emplace_back(key, payload);
+ std::vector<std::pair<TRuntimeNode, TRuntimeNode>> items;
+ for (size_t i = 1; i < node.ChildrenSize(); ++i) {
+ const auto key = MkqlBuildExpr(node.Child(i)->Head(), ctx);
+ const auto payload = MkqlBuildExpr(node.Child(i)->Tail(), ctx);
+ items.emplace_back(key, payload);
}
- return ctx.ProgramBuilder.NewDict(dictType, items);
+ return ctx.ProgramBuilder.NewDict(dictType, items);
});
- AddCallable("Variant", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto varType = node.Child(2)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TVariantExprType>();
- const auto type = BuildType(*node.Child(2), *varType, ctx.ProgramBuilder);
+ AddCallable("Variant", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto varType = node.Child(2)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TVariantExprType>();
+ const auto type = BuildType(*node.Child(2), *varType, ctx.ProgramBuilder);
- const auto item = MkqlBuildExpr(node.Head(), ctx);
- return varType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple ?
- ctx.ProgramBuilder.NewVariant(item, FromString<ui32>(node.Child(1)->Content()), type) :
- ctx.ProgramBuilder.NewVariant(item, node.Child(1)->Content(), type);
+ const auto item = MkqlBuildExpr(node.Head(), ctx);
+ return varType->GetUnderlyingType()->GetKind() == ETypeAnnotationKind::Tuple ?
+ ctx.ProgramBuilder.NewVariant(item, FromString<ui32>(node.Child(1)->Content()), type) :
+ ctx.ProgramBuilder.NewVariant(item, node.Child(1)->Content(), type);
});
- AddCallable("AsStruct", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- std::vector<std::pair<std::string_view, TRuntimeNode>> members;
- members.reserve(node.ChildrenSize());
- node.ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Head().Content(), MkqlBuildExpr(child.Tail(), ctx)); });
- return ctx.ProgramBuilder.NewStruct(members);
+ AddCallable("AsStruct", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ std::vector<std::pair<std::string_view, TRuntimeNode>> members;
+ members.reserve(node.ChildrenSize());
+ node.ForEachChild([&](const TExprNode& child){ members.emplace_back(child.Head().Content(), MkqlBuildExpr(child.Tail(), ctx)); });
+ return ctx.ProgramBuilder.NewStruct(members);
});
- AddCallable("AsDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- std::vector<std::pair<TRuntimeNode, TRuntimeNode>> items;
- items.reserve(node.ChildrenSize());
- node.ForEachChild([&](const TExprNode& child){ items.emplace_back(MkqlBuildExpr(*child.Child(0), ctx), MkqlBuildExpr(*child.Child(1), ctx)); });
- const auto dictType = ctx.ProgramBuilder.NewDictType(items[0].first.GetStaticType(), items[0].second.GetStaticType(), false);
- return ctx.ProgramBuilder.NewDict(dictType, items);
+ AddCallable("AsDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ std::vector<std::pair<TRuntimeNode, TRuntimeNode>> items;
+ items.reserve(node.ChildrenSize());
+ node.ForEachChild([&](const TExprNode& child){ items.emplace_back(MkqlBuildExpr(*child.Child(0), ctx), MkqlBuildExpr(*child.Child(1), ctx)); });
+ const auto dictType = ctx.ProgramBuilder.NewDictType(items[0].first.GetStaticType(), items[0].second.GetStaticType(), false);
+ return ctx.ProgramBuilder.NewDict(dictType, items);
});
- AddCallable("Ensure", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto value = MkqlBuildExpr(node.Head(), ctx);
- const auto predicate = MkqlBuildExpr(*node.Child(1), ctx);
- const auto message = node.ChildrenSize() > 2 ? MkqlBuildExpr(node.Tail(), ctx) : ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
+ AddCallable("Ensure", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto value = MkqlBuildExpr(node.Head(), ctx);
+ const auto predicate = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto message = node.ChildrenSize() > 2 ? MkqlBuildExpr(node.Tail(), ctx) : ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
return ctx.ProgramBuilder.Ensure(value, predicate, message, pos.File, pos.Row, pos.Column);
});
@@ -1832,16 +1832,16 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
return ctx.ProgramBuilder.Replicate(value, count, pos.File, pos.Row, pos.Column);
});
- AddCallable("IfPresent", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- TRuntimeNode::TList optionals;
- const auto width = node.ChildrenSize() - 2U;
- optionals.reserve(width);
- auto i = 0U;
- std::generate_n(std::back_inserter(optionals), width, [&](){ return MkqlBuildExpr(*node.Child(i++), ctx); });
- const auto elseBranch = MkqlBuildExpr(node.Tail(), ctx);
- return ctx.ProgramBuilder.IfPresent(optionals, [&](TRuntimeNode::TList items) {
- return MkqlBuildLambda(*node.Child(width), ctx, items);
- }, elseBranch);
+ AddCallable("IfPresent", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ TRuntimeNode::TList optionals;
+ const auto width = node.ChildrenSize() - 2U;
+ optionals.reserve(width);
+ auto i = 0U;
+ std::generate_n(std::back_inserter(optionals), width, [&](){ return MkqlBuildExpr(*node.Child(i++), ctx); });
+ const auto elseBranch = MkqlBuildExpr(node.Tail(), ctx);
+ return ctx.ProgramBuilder.IfPresent(optionals, [&](TRuntimeNode::TList items) {
+ return MkqlBuildLambda(*node.Child(width), ctx, items);
+ }, elseBranch);
});
AddCallable({"DataType",
@@ -1858,23 +1858,23 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
"ResourceType",
"TaggedType",
"VariantType",
- "StreamType",
+ "StreamType",
"FlowType",
"EmptyListType",
"EmptyDictType"},
- [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return TRuntimeNode(type, true);
+ [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return TRuntimeNode(type, true);
});
- AddCallable("ParseType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return TRuntimeNode(type, true);
+ AddCallable("ParseType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return TRuntimeNode(type, true);
});
- AddCallable("TypeOf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return TRuntimeNode(type, true);
+ AddCallable("TypeOf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return TRuntimeNode(type, true);
});
AddCallable("EmptyList", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -1897,27 +1897,27 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
}
});
- AddCallable("SourceOf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.SourceOf(type);
- });
-
- AddCallable("TypeHandle", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- const auto yson = WriteTypeToYson(type);
- const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
+ AddCallable("SourceOf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.SourceOf(type);
+ });
+
+ AddCallable("TypeHandle", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ const auto yson = WriteTypeToYson(type);
+ const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Yson>(yson));
- return TRuntimeNode(call.Build(), false);
+ return TRuntimeNode(call.Build(), false);
});
- AddCallable("ReprCode", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto type = node.Head().GetTypeAnn();
- const auto yson = WriteTypeToYson(type);
- const auto& args = GetAllArguments(node, ctx);
- const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ AddCallable("ReprCode", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto type = node.Head().GetTypeAnn();
+ const auto yson = WriteTypeToYson(type);
+ const auto& args = GetAllArguments(node, ctx);
+ const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(pos.File));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Row));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Column));
@@ -1927,7 +1927,7 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
}
call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::Yson>(yson));
- return TRuntimeNode(call.Build(), false);
+ return TRuntimeNode(call.Build(), false);
});
// safe and position unaware
@@ -1937,15 +1937,15 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
"FormatCode",
"FormatCodeWithPositions",
"SerializeCode",
- }, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& args = GetAllArguments(node, ctx);
- const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
+ }, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& args = GetAllArguments(node, ctx);
+ const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
for (auto arg : args) {
call.Add(arg);
}
- return TRuntimeNode(call.Build(), false);
+ return TRuntimeNode(call.Build(), false);
});
// with position
@@ -1982,11 +1982,11 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
"AtomCode",
"ListCode",
"FuncCode",
- }, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto& args = GetAllArguments(node, ctx);
- const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ }, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto& args = GetAllArguments(node, ctx);
+ const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(pos.File));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Row));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Column));
@@ -1995,19 +1995,19 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
call.Add(arg);
}
- return TRuntimeNode(call.Build(), false);
+ return TRuntimeNode(call.Build(), false);
});
- AddCallable("LambdaCode", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto lambda = node.Child(node.ChildrenSize() - 1);
- const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ AddCallable("LambdaCode", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto lambda = node.Child(node.ChildrenSize() - 1);
+ const auto retType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), retType);
call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(pos.File));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Row));
call.Add(ctx.ProgramBuilder.NewDataLiteral(pos.Column));
- if (node.ChildrenSize() == 2) {
- auto count = MkqlBuildExpr(node.Head(), ctx);
+ if (node.ChildrenSize() == 2) {
+ auto count = MkqlBuildExpr(node.Head(), ctx);
call.Add(count);
} else {
call.Add(ctx.ProgramBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui32>::Id));
@@ -2015,76 +2015,76 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
TRuntimeNode body;
{
- TMkqlBuildContext::TArgumentsMap innerArguments;
- innerArguments.reserve(lambda->Head().ChildrenSize());
- lambda->Head().ForEachChild([&](const TExprNode& argNode) {
- const auto argType = BuildType(argNode, *argNode.GetTypeAnn(), ctx.ProgramBuilder);
- const auto arg = ctx.ProgramBuilder.Arg(argType);
- innerArguments.emplace(&argNode, arg);
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ innerArguments.reserve(lambda->Head().ChildrenSize());
+ lambda->Head().ForEachChild([&](const TExprNode& argNode) {
+ const auto argType = BuildType(argNode, *argNode.GetTypeAnn(), ctx.ProgramBuilder);
+ const auto arg = ctx.ProgramBuilder.Arg(argType);
+ innerArguments.emplace(&argNode, arg);
call.Add(arg);
- });
+ });
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda->UniqueId());
- body = MkqlBuildExpr(*lambda->Child(1), innerCtx);
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda->UniqueId());
+ body = MkqlBuildExpr(*lambda->Child(1), innerCtx);
}
call.Add(body);
- return TRuntimeNode(call.Build(), false);
+ return TRuntimeNode(call.Build(), false);
});
- AddCallable("FormatType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ AddCallable("FormatType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
TRuntimeNode str;
- if (node.Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Resource) {
- auto handle = MkqlBuildExpr(node.Head(), ctx);
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
+ if (node.Head().GetTypeAnn()->GetKind() == ETypeAnnotationKind::Resource) {
+ auto handle = MkqlBuildExpr(node.Head(), ctx);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
call.Add(handle);
str = TRuntimeNode(call.Build(), false);
} else {
- str = ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(FormatType(node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType()));
+ str = ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(FormatType(node.Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType()));
}
- return str;
+ return str;
});
- AddCallable("Void", [](const TExprNode&, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewVoid();
+ AddCallable("Void", [](const TExprNode&, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewVoid();
});
- AddCallable("Null", [](const TExprNode&, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewNull();
+ AddCallable("Null", [](const TExprNode&, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewNull();
});
- AddCallable({"AsTagged","Untag"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return MkqlBuildExpr(node.Head(), ctx);
+ AddCallable({"AsTagged","Untag"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return MkqlBuildExpr(node.Head(), ctx);
});
AddCallable("Error", [](const TExprNode& node, TMkqlBuildContext& ctx)->NKikimr::NMiniKQL::TRuntimeNode {
- const auto err = node.GetTypeAnn()->Cast<TErrorExprType>()->GetError();
+ const auto err = node.GetTypeAnn()->Cast<TErrorExprType>()->GetError();
ythrow TNodeException(ctx.ExprCtx.AppendPosition(err.Position)) << err.Message;
});
AddCallable("ErrorType", [](const TExprNode& node, TMkqlBuildContext& ctx)->NKikimr::NMiniKQL::TRuntimeNode {
- const auto err = node.GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TErrorExprType>()->GetError();
+ const auto err = node.GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TErrorExprType>()->GetError();
ythrow TNodeException(ctx.ExprCtx.AppendPosition(err.Position)) << err.Message;
});
- AddCallable("Join", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto list1 = MkqlBuildExpr(node.Head(), ctx);
- const auto list2 = MkqlBuildExpr(*node.Child(1), ctx);
- const auto dict1 = ctx.ProgramBuilder.ToHashedDict(list1, true, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(2), ctx, {item});
+ AddCallable("Join", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto list1 = MkqlBuildExpr(node.Head(), ctx);
+ const auto list2 = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto dict1 = ctx.ProgramBuilder.ToHashedDict(list1, true, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(2), ctx, {item});
}, [&](TRuntimeNode item) {
return item;
});
- const auto dict2 = ctx.ProgramBuilder.ToHashedDict(list2, true, [&](TRuntimeNode item) {
- return MkqlBuildLambda(*node.Child(3), ctx, {item});
+ const auto dict2 = ctx.ProgramBuilder.ToHashedDict(list2, true, [&](TRuntimeNode item) {
+ return MkqlBuildLambda(*node.Child(3), ctx, {item});
}, [&](TRuntimeNode item) {
return item;
});
- const auto joinKind = GetJoinKind(node, node.Child(4)->Content());
- return ctx.ProgramBuilder.JoinDict(dict1, true, dict2, true, joinKind);
+ const auto joinKind = GetJoinKind(node, node.Child(4)->Content());
+ return ctx.ProgramBuilder.JoinDict(dict1, true, dict2, true, joinKind);
});
AddCallable("JoinDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -2092,103 +2092,103 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
const auto dict2 = MkqlBuildExpr(*node.Child(1), ctx);
const auto joinKind = GetJoinKind(node, node.Child(2)->Content());
- bool multi1 = true, multi2 = true;
- if (node.ChildrenSize() > 3) {
- node.Tail().ForEachChild([&](const TExprNode& flag){
- if (const auto& content = flag.Content(); content == "LeftUnique")
- multi1 = false;
- else if ( content == "RightUnique")
- multi2 = false;
- });
- }
-
- return ctx.ProgramBuilder.JoinDict(dict1, multi1, dict2, multi2, joinKind);
+ bool multi1 = true, multi2 = true;
+ if (node.ChildrenSize() > 3) {
+ node.Tail().ForEachChild([&](const TExprNode& flag){
+ if (const auto& content = flag.Content(); content == "LeftUnique")
+ multi1 = false;
+ else if ( content == "RightUnique")
+ multi2 = false;
+ });
+ }
+
+ return ctx.ProgramBuilder.JoinDict(dict1, multi1, dict2, multi2, joinKind);
});
AddCallable({"FilePath", "FileContent", "FolderPath"}, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
- call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content()));
- return TRuntimeNode(call.Build(), false);
+ TCallableBuilder call(ctx.ProgramBuilder.GetTypeEnvironment(), node.Content(), ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
+ call.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content()));
+ return TRuntimeNode(call.Build(), false);
});
- AddCallable("TablePath", [](const TExprNode&, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
+ AddCallable("TablePath", [](const TExprNode&, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>("");
});
- AddCallable("TableRecord", [](const TExprNode&, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<ui64>(0);
+ AddCallable("TableRecord", [](const TExprNode&, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<ui64>(0);
});
- AddCallable("Udf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- YQL_ENSURE(node.ChildrenSize() == 7);
- std::string_view function = node.Head().Content();
- const auto runConfig = MkqlBuildExpr(*node.Child(1), ctx);
+ AddCallable("Udf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ YQL_ENSURE(node.ChildrenSize() == 7);
+ std::string_view function = node.Head().Content();
+ const auto runConfig = MkqlBuildExpr(*node.Child(1), ctx);
const auto userType = BuildType(*node.Child(2), *node.Child(2)->GetTypeAnn(), ctx.ProgramBuilder, true);
- const auto typeConfig = node.Child(3)->Content();
- const auto callableType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ const auto typeConfig = node.Child(3)->Content();
+ const auto callableType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- return ctx.ProgramBuilder.TypedUdf(function, callableType, runConfig, userType, typeConfig,
+ return ctx.ProgramBuilder.TypedUdf(function, callableType, runConfig, userType, typeConfig,
pos.File, pos.Row, pos.Column);
});
- AddCallable("ScriptUdf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- EScriptType scriptType = ScriptTypeFromStr(node.Head().Content());
+ AddCallable("ScriptUdf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ EScriptType scriptType = ScriptTypeFromStr(node.Head().Content());
if (scriptType == EScriptType::Unknown) {
- ythrow TNodeException(node.Head())
+ ythrow TNodeException(node.Head())
<< "Unknown script type '"
- << node.Head().Content() << '\'';
+ << node.Head().Content() << '\'';
}
- std::string_view funcName = node.Child(1)->Content();
- const auto typeNode = node.Child(2);
- const auto funcType = BuildType(*typeNode, *typeNode->GetTypeAnn(), ctx.ProgramBuilder);
- const auto script = MkqlBuildExpr(*node.Child(3), ctx);
+ std::string_view funcName = node.Child(1)->Content();
+ const auto typeNode = node.Child(2);
+ const auto funcType = BuildType(*typeNode, *typeNode->GetTypeAnn(), ctx.ProgramBuilder);
+ const auto script = MkqlBuildExpr(*node.Child(3), ctx);
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- return ctx.ProgramBuilder.ScriptUdf(scriptType, funcName, funcType, script,
+ return ctx.ProgramBuilder.ScriptUdf(scriptType, funcName, funcType, script,
pos.File, pos.Row, pos.Column);
});
- AddCallable("Apply", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ AddCallable("Apply", [](const TExprNode& node, TMkqlBuildContext& ctx) {
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- const auto callable = MkqlBuildExpr(node.Head(), ctx);
- const auto& args = GetArgumentsFrom<1U>(node, ctx);
+ const auto callable = MkqlBuildExpr(node.Head(), ctx);
+ const auto& args = GetArgumentsFrom<1U>(node, ctx);
return ctx.ProgramBuilder.Apply(callable, args, pos.File, pos.Row, pos.Column);
});
- AddCallable("NamedApply", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ AddCallable("NamedApply", [](const TExprNode& node, TMkqlBuildContext& ctx) {
const auto pos = ctx.ExprCtx.GetPosition(node.Pos());
- const auto callable = MkqlBuildExpr(node.Head(), ctx);
- const auto positionalArgs = MkqlBuildExpr(*node.Child(1), ctx);
- const auto namedArgs = MkqlBuildExpr(*node.Child(2), ctx);
- const auto dependentNodes = node.ChildrenSize() - 3;
- const auto callableType = node.Head().GetTypeAnn()->Cast<TCallableExprType>();
- const auto tupleType = node.Child(1)->GetTypeAnn()->Cast<TTupleExprType>();
- const auto structType = node.Child(2)->GetTypeAnn()->Cast<TStructExprType>();
- std::vector<TRuntimeNode> args(callableType->GetArgumentsSize() + dependentNodes);
+ const auto callable = MkqlBuildExpr(node.Head(), ctx);
+ const auto positionalArgs = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto namedArgs = MkqlBuildExpr(*node.Child(2), ctx);
+ const auto dependentNodes = node.ChildrenSize() - 3;
+ const auto callableType = node.Head().GetTypeAnn()->Cast<TCallableExprType>();
+ const auto tupleType = node.Child(1)->GetTypeAnn()->Cast<TTupleExprType>();
+ const auto structType = node.Child(2)->GetTypeAnn()->Cast<TStructExprType>();
+ std::vector<TRuntimeNode> args(callableType->GetArgumentsSize() + dependentNodes);
for (size_t i = 0; i < tupleType->GetSize(); ++i) {
- args[i] = node.Child(1)->IsList() ?
- MkqlBuildExpr(*node.Child(1)->Child(i), ctx):
- ctx.ProgramBuilder.Nth(positionalArgs, i);
+ args[i] = node.Child(1)->IsList() ?
+ MkqlBuildExpr(*node.Child(1)->Child(i), ctx):
+ ctx.ProgramBuilder.Nth(positionalArgs, i);
}
for (size_t i = 0; i < structType->GetSize(); ++i) {
auto memberName = structType->GetItems()[i]->GetName();
auto index = callableType->ArgumentIndexByName(memberName);
if (!index || *index < tupleType->GetSize()) {
- ythrow TNodeException(node.Child(2)) << "Wrong named argument: " << memberName;
+ ythrow TNodeException(node.Child(2)) << "Wrong named argument: " << memberName;
}
TRuntimeNode arg;
- if (node.Child(2)->IsCallable("AsStruct")) {
- for (auto& child : node.Child(2)->Children()) {
- if (child->Head().Content() == memberName) {
- arg = MkqlBuildExpr(child->Tail(), ctx);
+ if (node.Child(2)->IsCallable("AsStruct")) {
+ for (auto& child : node.Child(2)->Children()) {
+ if (child->Head().Content() == memberName) {
+ arg = MkqlBuildExpr(child->Tail(), ctx);
break;
}
}
if (!arg.GetNode()) {
- ythrow TNodeException(node.Child(2)) << "Missing argument: " << memberName;
+ ythrow TNodeException(node.Child(2)) << "Missing argument: " << memberName;
}
}
else {
@@ -2204,45 +2204,45 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
continue;
}
- auto mkqlType = BuildType(node, *callableType->GetArguments()[i].Type, ctx.ProgramBuilder);
+ auto mkqlType = BuildType(node, *callableType->GetArguments()[i].Type, ctx.ProgramBuilder);
arg = ctx.ProgramBuilder.NewEmptyOptional(mkqlType);
}
for (ui32 i = 0; i < dependentNodes; ++i) {
- args[callableType->GetArgumentsSize() + i] = MkqlBuildExpr(*node.Child(3 + i), ctx);
+ args[callableType->GetArgumentsSize() + i] = MkqlBuildExpr(*node.Child(3 + i), ctx);
}
return ctx.ProgramBuilder.Apply(callable, args, pos.File, pos.Row, pos.Column, dependentNodes);
});
- AddCallable("Callable", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto callableType = BuildType(node.Head(), *node.Head().GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.Callable(callableType, [&](const TArrayRef<const TRuntimeNode>& args) {
- const auto& lambda = node.Tail();
- TMkqlBuildContext::TArgumentsMap innerArguments;
- innerArguments.reserve(lambda.Head().ChildrenSize());
- MKQL_ENSURE(args.size() == lambda.Head().ChildrenSize(), "Mismatch of lambda arguments count");
- auto it = args.cbegin();
- lambda.Head().ForEachChild([&](const TExprNode& arg){ innerArguments.emplace(&arg, *it++); });
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
- return MkqlBuildExpr(lambda.Tail(), innerCtx);
- });
+ AddCallable("Callable", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto callableType = BuildType(node.Head(), *node.Head().GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.Callable(callableType, [&](const TArrayRef<const TRuntimeNode>& args) {
+ const auto& lambda = node.Tail();
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ innerArguments.reserve(lambda.Head().ChildrenSize());
+ MKQL_ENSURE(args.size() == lambda.Head().ChildrenSize(), "Mismatch of lambda arguments count");
+ auto it = args.cbegin();
+ lambda.Head().ForEachChild([&](const TExprNode& arg){ innerArguments.emplace(&arg, *it++); });
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
+ return MkqlBuildExpr(lambda.Tail(), innerCtx);
+ });
});
- AddCallable("QueueCreate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto initCapacity = MkqlBuildExpr(*node.Child(1), ctx);
- const auto initSize = MkqlBuildExpr(*node.Child(2), ctx);
- const auto& args = GetArgumentsFrom<3U>(node, ctx);
- const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.QueueCreate(initCapacity, initSize, args, returnType);
+ AddCallable("QueueCreate", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto initCapacity = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto initSize = MkqlBuildExpr(*node.Child(2), ctx);
+ const auto& args = GetArgumentsFrom<3U>(node, ctx);
+ const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.QueueCreate(initCapacity, initSize, args, returnType);
});
- AddCallable("QueuePeek", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto resource = MkqlBuildExpr(node.Head(), ctx);
- const auto index = MkqlBuildExpr(*node.Child(1), ctx);
- const auto& args = GetArgumentsFrom<2U>(node, ctx);
- const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
- return ctx.ProgramBuilder.QueuePeek(resource, index, args, returnType);
+ AddCallable("QueuePeek", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto resource = MkqlBuildExpr(node.Head(), ctx);
+ const auto index = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto& args = GetArgumentsFrom<2U>(node, ctx);
+ const auto returnType = BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder);
+ return ctx.ProgramBuilder.QueuePeek(resource, index, args, returnType);
});
AddCallable("QueueRange", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -2260,35 +2260,35 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
return ctx.ProgramBuilder.Seq(args, returnType);
});
- AddCallable("FromYsonSimpleType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto input = MkqlBuildExpr(node.Head(), ctx);
- const auto schemeType = ParseDataType(node, node.Child(1)->Content());
- return ctx.ProgramBuilder.FromYsonSimpleType(input, schemeType);
+ AddCallable("FromYsonSimpleType", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto input = MkqlBuildExpr(node.Head(), ctx);
+ const auto schemeType = ParseDataType(node, node.Child(1)->Content());
+ return ctx.ProgramBuilder.FromYsonSimpleType(input, schemeType);
});
- AddCallable("TryWeakMemberFromDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const auto other = MkqlBuildExpr(node.Head(), ctx);
- const auto rest = MkqlBuildExpr(*node.Child(1), ctx);
- const auto schemeType = ParseDataType(node, node.Child(2)->Content());
- const auto member = node.Child(3)->Content();
- return ctx.ProgramBuilder.TryWeakMemberFromDict(other, rest, schemeType, member);
+ AddCallable("TryWeakMemberFromDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const auto other = MkqlBuildExpr(node.Head(), ctx);
+ const auto rest = MkqlBuildExpr(*node.Child(1), ctx);
+ const auto schemeType = ParseDataType(node, node.Child(2)->Content());
+ const auto member = node.Child(3)->Content();
+ return ctx.ProgramBuilder.TryWeakMemberFromDict(other, rest, schemeType, member);
});
- AddCallable("DependsOn", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return MkqlBuildExpr(node.Head(), ctx);
+ AddCallable("DependsOn", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return MkqlBuildExpr(node.Head(), ctx);
});
- AddCallable("Parameter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- const NNodes::TCoParameter parameter(&node);
- return ctx.ProgramBuilder.Member(ctx.Parameters, parameter.Name());
+ AddCallable("Parameter", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ const NNodes::TCoParameter parameter(&node);
+ return ctx.ProgramBuilder.Member(ctx.Parameters, parameter.Name());
});
- AddCallable("SecureParam", [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content());
+ AddCallable("SecureParam", [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(node.Head().Content());
});
- AddCallable(SkippableCallables, [](const TExprNode& node, TMkqlBuildContext& ctx) {
- return MkqlBuildExpr(node.Head(), ctx);
+ AddCallable(SkippableCallables, [](const TExprNode& node, TMkqlBuildContext& ctx) {
+ return MkqlBuildExpr(node.Head(), ctx);
});
AddCallable("Merge", [](const TExprNode& node, TMkqlBuildContext& ctx) {
@@ -2296,18 +2296,18 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
auto extend = ctx.ProgramBuilder.Extend(args);
if (auto sortConstr = node.GetConstraint<TSortedConstraintNode>()) {
- const auto input = MkqlBuildExpr(node.Head(), ctx);
- const auto& content = sortConstr->GetContent();
+ const auto input = MkqlBuildExpr(node.Head(), ctx);
+ const auto& content = sortConstr->GetContent();
std::vector<TRuntimeNode> ascending;
- ascending.reserve(content.size());
- for (const auto& c: content) {
- ascending.push_back(ctx.ProgramBuilder.NewDataLiteral(c.second));
+ ascending.reserve(content.size());
+ for (const auto& c: content) {
+ ascending.push_back(ctx.ProgramBuilder.NewDataLiteral(c.second));
}
TProgramBuilder::TUnaryLambda keyExractor = [&](TRuntimeNode item) {
std::vector<TRuntimeNode> keys;
- keys.reserve(content.size());
- for (const auto& c : content) {
- keys.push_back(ctx.ProgramBuilder.Member(item, c.first.front()));
+ keys.reserve(content.size());
+ for (const auto& c : content) {
+ keys.push_back(ctx.ProgramBuilder.Member(item, c.first.front()));
}
return ctx.ProgramBuilder.NewTuple(keys);
};
@@ -2319,47 +2319,47 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
});
}
-TRuntimeNode MkqlBuildLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const TRuntimeNode::TList& args) {
- MKQL_ENSURE(2U == lambda.ChildrenSize(), "Wide lambda isn't supported.");
- TMkqlBuildContext::TArgumentsMap innerArguments;
- innerArguments.reserve(args.size());
- auto it = args.begin();
- lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
- return MkqlBuildExpr(lambda.Tail(), innerCtx);
-}
-
-TRuntimeNode::TList MkqlBuildWideLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const TRuntimeNode::TList& args) {
- MKQL_ENSURE(0U < lambda.ChildrenSize(), "Empty lambda.");
- TMkqlBuildContext::TArgumentsMap innerArguments;
- innerArguments.reserve(args.size());
- auto it = args.begin();
- lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
- TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
- TRuntimeNode::TList result;
- result.reserve(lambda.ChildrenSize() - 1U);
- for (ui32 i = 1U; i < lambda.ChildrenSize(); ++i)
- result.emplace_back(MkqlBuildExpr(*lambda.Child(i), innerCtx));
- return result;
-}
-
-TRuntimeNode MkqlBuildExpr(const TExprNode& node, TMkqlBuildContext& ctx) {
- for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
- const auto knownNode = currCtx->Memoization.find(&node);
- if (currCtx->Memoization.cend() != knownNode) {
- return knownNode->second;
+TRuntimeNode MkqlBuildLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const TRuntimeNode::TList& args) {
+ MKQL_ENSURE(2U == lambda.ChildrenSize(), "Wide lambda isn't supported.");
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ innerArguments.reserve(args.size());
+ auto it = args.begin();
+ lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
+ return MkqlBuildExpr(lambda.Tail(), innerCtx);
+}
+
+TRuntimeNode::TList MkqlBuildWideLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const TRuntimeNode::TList& args) {
+ MKQL_ENSURE(0U < lambda.ChildrenSize(), "Empty lambda.");
+ TMkqlBuildContext::TArgumentsMap innerArguments;
+ innerArguments.reserve(args.size());
+ auto it = args.begin();
+ lambda.Head().ForEachChild([&](const TExprNode& child){ innerArguments.emplace(&child, *it++); });
+ TMkqlBuildContext innerCtx(ctx, std::move(innerArguments), lambda.UniqueId());
+ TRuntimeNode::TList result;
+ result.reserve(lambda.ChildrenSize() - 1U);
+ for (ui32 i = 1U; i < lambda.ChildrenSize(); ++i)
+ result.emplace_back(MkqlBuildExpr(*lambda.Child(i), innerCtx));
+ return result;
+}
+
+TRuntimeNode MkqlBuildExpr(const TExprNode& node, TMkqlBuildContext& ctx) {
+ for (auto currCtx = &ctx; currCtx; currCtx = currCtx->ParentCtx) {
+ const auto knownNode = currCtx->Memoization.find(&node);
+ if (currCtx->Memoization.cend() != knownNode) {
+ return knownNode->second;
}
}
- switch (const auto type = node.Type()) {
- case TExprNode::List:
- return CheckTypeAndMemoize(node, ctx, ctx.ProgramBuilder.NewTuple(GetAllArguments(node, ctx)));
- case TExprNode::Callable:
- return CheckTypeAndMemoize(node, ctx, ctx.MkqlCompiler.GetCallable(node.Content())(node, ctx));
- case TExprNode::Argument:
- ythrow TNodeException(node) << "Unexpected argument: " << node.Content();
- default:
- ythrow TNodeException(node) << "Unexpected node type: " << type;
+ switch (const auto type = node.Type()) {
+ case TExprNode::List:
+ return CheckTypeAndMemoize(node, ctx, ctx.ProgramBuilder.NewTuple(GetAllArguments(node, ctx)));
+ case TExprNode::Callable:
+ return CheckTypeAndMemoize(node, ctx, ctx.MkqlCompiler.GetCallable(node.Content())(node, ctx));
+ case TExprNode::Argument:
+ ythrow TNodeException(node) << "Unexpected argument: " << node.Content();
+ default:
+ ythrow TNodeException(node) << "Unexpected node type: " << type;
}
}
diff --git a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.h b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.h
index e017992adc..a25c03b488 100644
--- a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.h
+++ b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.h
@@ -11,78 +11,78 @@ class IMkqlCallableCompiler;
struct TMkqlBuildContext {
using TArgumentsMap = TNodeMap<NKikimr::NMiniKQL::TRuntimeNode>;
- using TMemoizedNodesMap = TArgumentsMap;
+ using TMemoizedNodesMap = TArgumentsMap;
const IMkqlCallableCompiler& MkqlCompiler;
NKikimr::NMiniKQL::TProgramBuilder& ProgramBuilder;
TExprContext& ExprCtx;
- TMemoizedNodesMap Memoization;
- TMkqlBuildContext *const ParentCtx = nullptr;
- const size_t Level = 0ULL;
- const ui64 LambdaId = 0ULL;
+ TMemoizedNodesMap Memoization;
+ TMkqlBuildContext *const ParentCtx = nullptr;
+ const size_t Level = 0ULL;
+ const ui64 LambdaId = 0ULL;
NKikimr::NMiniKQL::TRuntimeNode Parameters;
- TMkqlBuildContext(const IMkqlCallableCompiler& mkqlCompiler, NKikimr::NMiniKQL::TProgramBuilder& builder, TExprContext& exprCtx, ui64 lambdaId = 0ULL, TArgumentsMap&& args = {})
+ TMkqlBuildContext(const IMkqlCallableCompiler& mkqlCompiler, NKikimr::NMiniKQL::TProgramBuilder& builder, TExprContext& exprCtx, ui64 lambdaId = 0ULL, TArgumentsMap&& args = {})
: MkqlCompiler(mkqlCompiler)
, ProgramBuilder(builder)
, ExprCtx(exprCtx)
- , Memoization(std::move(args))
- , LambdaId(lambdaId)
- {}
-
- TMkqlBuildContext(TMkqlBuildContext& parent, TArgumentsMap&& args, ui64 lambdaId)
- : MkqlCompiler(parent.MkqlCompiler)
- , ProgramBuilder(parent.ProgramBuilder)
+ , Memoization(std::move(args))
+ , LambdaId(lambdaId)
+ {}
+
+ TMkqlBuildContext(TMkqlBuildContext& parent, TArgumentsMap&& args, ui64 lambdaId)
+ : MkqlCompiler(parent.MkqlCompiler)
+ , ProgramBuilder(parent.ProgramBuilder)
, ExprCtx(parent.ExprCtx)
- , Memoization(std::move(args))
- , ParentCtx(&parent)
- , Level(parent.Level + 1U)
- , LambdaId(lambdaId)
+ , Memoization(std::move(args))
+ , ParentCtx(&parent)
+ , Level(parent.Level + 1U)
+ , LambdaId(lambdaId)
, Parameters(parent.Parameters)
- {}
+ {}
};
class IMkqlCallableCompiler : public TThrRefBase {
public:
- typedef std::function<NKikimr::NMiniKQL::TRuntimeNode(const TExprNode&, TMkqlBuildContext&)> TCompiler;
- virtual bool HasCallable(const std::string_view& name) const = 0;
- virtual TCompiler FindCallable(const std::string_view& name) const = 0;
- virtual TCompiler GetCallable(const std::string_view& name) const = 0;
+ typedef std::function<NKikimr::NMiniKQL::TRuntimeNode(const TExprNode&, TMkqlBuildContext&)> TCompiler;
+ virtual bool HasCallable(const std::string_view& name) const = 0;
+ virtual TCompiler FindCallable(const std::string_view& name) const = 0;
+ virtual TCompiler GetCallable(const std::string_view& name) const = 0;
virtual ~IMkqlCallableCompiler() {}
};
class TMkqlCallableCompilerBase : public IMkqlCallableCompiler {
public:
- bool HasCallable(const std::string_view& name) const override;
- TCompiler FindCallable(const std::string_view& name) const override;
- TCompiler GetCallable(const std::string_view& name) const override;
- virtual void AddCallable(const std::string_view& name, TCompiler compiler);
- virtual void AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler);
- virtual void ChainCallable(const std::string_view& name, TCompiler compiler);
- virtual void ChainCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler);
- virtual void OverrideCallable(const std::string_view& name, TCompiler compiler);
+ bool HasCallable(const std::string_view& name) const override;
+ TCompiler FindCallable(const std::string_view& name) const override;
+ TCompiler GetCallable(const std::string_view& name) const override;
+ virtual void AddCallable(const std::string_view& name, TCompiler compiler);
+ virtual void AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler);
+ virtual void ChainCallable(const std::string_view& name, TCompiler compiler);
+ virtual void ChainCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler);
+ virtual void OverrideCallable(const std::string_view& name, TCompiler compiler);
private:
THashMap<TString, TCompiler> Callables;
-
-protected:
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::UnaryFunctionMethod>>& callables);
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::BinaryFunctionMethod>>& callables);
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::TernaryFunctionMethod>>& callables);
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::ArrayFunctionMethod>>& callables);
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::ProcessFunctionMethod>>& callables);
- void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::NarrowFunctionMethod>>& callables);
+
+protected:
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::UnaryFunctionMethod>>& callables);
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::BinaryFunctionMethod>>& callables);
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::TernaryFunctionMethod>>& callables);
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::ArrayFunctionMethod>>& callables);
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::ProcessFunctionMethod>>& callables);
+ void AddSimpleCallables(const std::initializer_list<std::pair<std::string_view, NKikimr::NMiniKQL::TProgramBuilder::NarrowFunctionMethod>>& callables);
};
class TMkqlCommonCallableCompiler : public TMkqlCallableCompilerBase {
public:
- bool HasCallable(const std::string_view& name) const override;
- TCompiler FindCallable(const std::string_view& name) const override;
- TCompiler GetCallable(const std::string_view& name) const override;
- void AddCallable(const std::string_view& name, TCompiler compiler) override;
- void AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) override;
- void OverrideCallable(const std::string_view& name, TCompiler compiler) override;
+ bool HasCallable(const std::string_view& name) const override;
+ TCompiler FindCallable(const std::string_view& name) const override;
+ TCompiler GetCallable(const std::string_view& name) const override;
+ void AddCallable(const std::string_view& name, TCompiler compiler) override;
+ void AddCallable(const std::initializer_list<std::string_view>& names, TCompiler compiler) override;
+ void OverrideCallable(const std::string_view& name, TCompiler compiler) override;
private:
class TShared : public TMkqlCallableCompilerBase {
@@ -95,10 +95,10 @@ private:
}
};
-NKikimr::NMiniKQL::TRuntimeNode CombineByKeyImpl(const TExprNode& node, TMkqlBuildContext& ctx);
-NKikimr::NMiniKQL::TRuntimeNode MkqlBuildExpr(const TExprNode& node, TMkqlBuildContext& ctx);
-NKikimr::NMiniKQL::TRuntimeNode MkqlBuildLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const NKikimr::NMiniKQL::TRuntimeNode::TList& args);
-NKikimr::NMiniKQL::TRuntimeNode::TList MkqlBuildWideLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const NKikimr::NMiniKQL::TRuntimeNode::TList& args);
-
+NKikimr::NMiniKQL::TRuntimeNode CombineByKeyImpl(const TExprNode& node, TMkqlBuildContext& ctx);
+NKikimr::NMiniKQL::TRuntimeNode MkqlBuildExpr(const TExprNode& node, TMkqlBuildContext& ctx);
+NKikimr::NMiniKQL::TRuntimeNode MkqlBuildLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const NKikimr::NMiniKQL::TRuntimeNode::TList& args);
+NKikimr::NMiniKQL::TRuntimeNode::TList MkqlBuildWideLambda(const TExprNode& lambda, TMkqlBuildContext& ctx, const NKikimr::NMiniKQL::TRuntimeNode::TList& args);
+
} // namespace NCommon
} // namespace NYql
diff --git a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
index 8597840079..4ba0e6d740 100644
--- a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
+++ b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
@@ -24,16 +24,16 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki
auto slot = data->GetSlot();
const auto schemeType = NUdf::GetDataTypeInfo(slot).TypeId;
if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- const auto params = static_cast<const TDataExprParamsType&>(annotation);
- return pgmBuilder.NewDecimalType(FromString<ui8>(params.GetParamOne()), FromString<ui8>(params.GetParamTwo()));
- } else {
- return pgmBuilder.NewDataType(schemeType);
- }
+ const auto params = static_cast<const TDataExprParamsType&>(annotation);
+ return pgmBuilder.NewDecimalType(FromString<ui8>(params.GetParamOne()), FromString<ui8>(params.GetParamTwo()));
+ } else {
+ return pgmBuilder.NewDataType(schemeType);
+ }
}
case ETypeAnnotationKind::Struct: {
auto structObj = annotation.Cast<TStructExprType>();
- std::vector<std::pair<std::string_view, NKikimr::NMiniKQL::TType*>> members;
+ std::vector<std::pair<std::string_view, NKikimr::NMiniKQL::TType*>> members;
members.reserve(structObj->GetItems().size());
for (auto& item : structObj->GetItems()) {
@@ -77,19 +77,19 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki
return pgmBuilder.NewTupleType(elements);
}
- case ETypeAnnotationKind::Multi: {
- auto multi = annotation.Cast<TMultiExprType>();
- TVector<NKikimr::NMiniKQL::TType*> elements;
- elements.reserve(multi->GetItems().size());
- for (auto& child : multi->GetItems()) {
- elements.push_back(BuildType(*child, pgmBuilder, err, withTagged));
- if (!elements.back()) {
- return nullptr;
- }
- }
- return pgmBuilder.NewTupleType(elements);
- }
-
+ case ETypeAnnotationKind::Multi: {
+ auto multi = annotation.Cast<TMultiExprType>();
+ TVector<NKikimr::NMiniKQL::TType*> elements;
+ elements.reserve(multi->GetItems().size());
+ for (auto& child : multi->GetItems()) {
+ elements.push_back(BuildType(*child, pgmBuilder, err, withTagged));
+ if (!elements.back()) {
+ return nullptr;
+ }
+ }
+ return pgmBuilder.NewTupleType(elements);
+ }
+
case ETypeAnnotationKind::Dict: {
auto dictType = annotation.Cast<TDictExprType>();
auto keyType = BuildType(*dictType->GetKeyType(), pgmBuilder, err, withTagged);
@@ -110,7 +110,7 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki
}
case ETypeAnnotationKind::Null: {
- return pgmBuilder.NewNull().GetStaticType();
+ return pgmBuilder.NewNull().GetStaticType();
}
case ETypeAnnotationKind::Callable: {
@@ -171,15 +171,15 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki
return pgmBuilder.NewStreamType(itemType);
}
- case ETypeAnnotationKind::Flow: {
- auto flow = annotation.Cast<TFlowExprType>();
+ case ETypeAnnotationKind::Flow: {
+ auto flow = annotation.Cast<TFlowExprType>();
auto itemType = BuildType(*flow->GetItemType(), pgmBuilder, err, withTagged);
- if (!itemType) {
- return nullptr;
- }
- return pgmBuilder.NewFlowType(itemType);
- }
-
+ if (!itemType) {
+ return nullptr;
+ }
+ return pgmBuilder.NewFlowType(itemType);
+ }
+
case ETypeAnnotationKind::EmptyList: {
if (NKikimr::NMiniKQL::RuntimeVersion < 11) {
auto voidType = pgmBuilder.NewVoid().GetStaticType();
@@ -231,13 +231,13 @@ const TTypeAnnotationNode* ConvertMiniKQLType(TPosition position, NKikimr::NMini
auto slot = NUdf::FindDataSlot(dataType->GetSchemeType());
YQL_ENSURE(slot, "Unknown datatype: " << dataType->GetSchemeType());
if (*slot == EDataSlot::Decimal) {
- const auto params = static_cast<TDataDecimalType*>(dataType)->GetParams();
+ const auto params = static_cast<TDataDecimalType*>(dataType)->GetParams();
auto ret = ctx.MakeType<TDataExprParamsType>(*slot, ToString(params.first), ToString(params.second));
YQL_ENSURE(ret->Validate(position, ctx));
return ret;
- } else {
+ } else {
return ctx.MakeType<TDataExprType>(*slot);
- }
+ }
}
case TType::EKind::Struct:
diff --git a/ydb/library/yql/providers/common/proto/gateways_config.proto b/ydb/library/yql/providers/common/proto/gateways_config.proto
index ee7942572d..8561fe2536 100644
--- a/ydb/library/yql/providers/common/proto/gateways_config.proto
+++ b/ydb/library/yql/providers/common/proto/gateways_config.proto
@@ -77,8 +77,8 @@ message TYtGatewayConfig {
optional string MrJobBin = 6; // Path to mrjob executable. If not set then main executable will be used
optional string MrJobBinMd5 = 13; // MD5 checksum of mrjob executable. Should not be specified directly
optional string MrJobUdfsDir = 7; // Path to linux udfs. If not set then loaded into main executable will be used
- optional bool ExecuteUdfLocallyIfPossible = 8; // Turns on local execution mode for calc job with UDF.
- optional bool LocalChainTest = 9 [default = false]; // Chain local execution jobs for test purpose.
+ optional bool ExecuteUdfLocallyIfPossible = 8; // Turns on local execution mode for calc job with UDF.
+ optional bool LocalChainTest = 9 [default = false]; // Chain local execution jobs for test purpose.
optional string YtDebugLogFile = 10; // File for full YT debug log
optional uint64 YtDebugLogSize = 11 [default = 0]; // Max YT debug log size
optional bool YtDebugLogAlwaysWrite = 12 [default = false]; // Write YT debug log always or on error only
@@ -139,30 +139,30 @@ message TKikimrMvpGatewayConfig {
repeated TKikimrMvpProxyConfig ProxyMapping = 1;
}
-///////////////////////////// Ydb /////////////////////////////
-
-message TYdbClusterConfig {
- optional string Name = 1;
- optional string Endpoint = 2;
- optional string Token = 3;
- optional TKikimrGrpcData Grpc = 4;
- optional uint32 TvmId = 5 [default = 0];
+///////////////////////////// Ydb /////////////////////////////
+
+message TYdbClusterConfig {
+ optional string Name = 1;
+ optional string Endpoint = 2;
+ optional string Token = 3;
+ optional TKikimrGrpcData Grpc = 4;
+ optional uint32 TvmId = 5 [default = 0];
optional string Database = 6;
optional string Id = 7;
optional bool Secure = 8;
optional string ServiceAccountId = 9;
optional string ServiceAccountIdSignature = 10;
optional bool AddBearerToToken = 11; // whether to use prefix "Bearer " in token
- repeated TAttr Settings = 100;
-}
-
-message TYdbGatewayConfig {
- repeated TYdbClusterConfig ClusterMapping = 1;
- optional string DefaultEndpoint = 2;
- optional string DefaultToken = 3;
- repeated TAttr DefaultSettings = 4;
-}
-
+ repeated TAttr Settings = 100;
+}
+
+message TYdbGatewayConfig {
+ repeated TYdbClusterConfig ClusterMapping = 1;
+ optional string DefaultEndpoint = 2;
+ optional string DefaultToken = 3;
+ repeated TAttr DefaultSettings = 4;
+}
+
///////////////////////////// ClickHouse /////////////////////////////
message TClickHouseClusterConfig {
@@ -310,27 +310,27 @@ message TChytGatewayConfig {
repeated TChytClusterConfig ClusterMapping = 1;
}
-///////////////////////////// S3 /////////////////////////////
-
-message TS3ClusterConfig {
- optional string Name = 1; // Short cluster name
- optional string Url = 2;
- optional string Token = 3;
+///////////////////////////// S3 /////////////////////////////
+
+message TS3ClusterConfig {
+ optional string Name = 1; // Short cluster name
+ optional string Url = 2;
+ optional string Token = 3;
optional string ServiceAccountId = 4;
optional string ServiceAccountIdSignature = 5;
- repeated TAttr Settings = 100;
-}
-
-message TS3GatewayConfig {
- repeated TS3ClusterConfig ClusterMapping = 1;
-
- optional uint64 FileSizeLimit = 2;
- optional uint32 MaxFilesPerQuery = 3;
- optional uint64 MaxReadSizePerQuery = 4;
-
- repeated TAttr DefaultSettings = 100;
-}
-
+ repeated TAttr Settings = 100;
+}
+
+message TS3GatewayConfig {
+ repeated TS3ClusterConfig ClusterMapping = 1;
+
+ optional uint64 FileSizeLimit = 2;
+ optional uint32 MaxFilesPerQuery = 3;
+ optional uint64 MaxReadSizePerQuery = 4;
+
+ repeated TAttr DefaultSettings = 100;
+}
+
///////////////////////////// Solomon /////////////////////////////
message TSolomonClusterConfig {
@@ -450,8 +450,8 @@ message TGatewaysConfig {
optional TSqlCoreConfig SqlCore = 12;
optional TDqGatewayConfig Dq = 13;
optional TMysqlGatewayConfig Mysql = 14;
- optional TYdbGatewayConfig Ydb = 15;
+ optional TYdbGatewayConfig Ydb = 15;
optional TPqGatewayConfig Pq = 16;
- optional TS3GatewayConfig S3 = 17;
+ optional TS3GatewayConfig S3 = 17;
optional THttpGatewayConfig HttpGateway = 18;
}
diff --git a/ydb/library/yql/providers/common/provider/yql_provider.cpp b/ydb/library/yql/providers/common/provider/yql_provider.cpp
index f1a558c243..aa782ee93f 100644
--- a/ydb/library/yql/providers/common/provider/yql_provider.cpp
+++ b/ydb/library/yql/providers/common/provider/yql_provider.cpp
@@ -78,7 +78,7 @@ TCoNameValueTupleList TCommitSettings::BuildNode(TExprContext& ctx) const {
return ret;
}
-const TStructExprType* BuildCommonTableListType(TExprContext& ctx) {
+const TStructExprType* BuildCommonTableListType(TExprContext& ctx) {
TVector<const TItemExprType*> items;
auto stringType = ctx.MakeType<TDataExprType>(EDataSlot::String);
auto listOfString = ctx.MakeType<TListExprType>(stringType);
@@ -98,7 +98,7 @@ bool HasResOrPullOption(const TExprNode& node, const TStringBuf& option) {
if (node.Content() == "Result" || node.Content() == "Pull") {
auto options = node.Child(4);
for (auto setting : options->Children()) {
- if (setting->Head().Content() == option) {
+ if (setting->Head().Content() == option) {
return true;
}
}
@@ -110,7 +110,7 @@ TVector<TString> GetResOrPullColumnHints(const TExprNode& node) {
TVector<TString> columns;
auto setting = GetSetting(*node.Child(4), "columns");
if (setting) {
- auto type = node.Head().GetTypeAnn();
+ auto type = node.Head().GetTypeAnn();
if (type->GetKind() != ETypeAnnotationKind::EmptyList) {
auto structType = type->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
for (ui32 i = 0; i < structType->GetSize(); ++i) {
@@ -423,7 +423,7 @@ bool FillUsedFilesImpl(
TUserDataTable& files,
const TTypeAnnotationContext& types,
TExprContext& ctx,
- const TUserDataTable& crutches,
+ const TUserDataTable& crutches,
TNodeSet& visited)
{
if (!visited.insert(&node).second) {
@@ -431,7 +431,7 @@ bool FillUsedFilesImpl(
}
if (node.IsCallable("FilePath") || node.IsCallable("FileContent")) {
- const auto& name = node.Head().Content();
+ const auto& name = node.Head().Content();
const auto block = types.UserDataStorage->FindUserDataBlock(name);
if (!block) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "File not found: " << name));
@@ -444,7 +444,7 @@ bool FillUsedFilesImpl(
}
if (node.IsCallable("FolderPath")) {
- const auto& name = node.Head().Content();
+ const auto& name = node.Head().Content();
auto blocks = types.UserDataStorage->FindUserDataFolder(name);
if (!blocks) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder() << "Folder not found: " << name));
@@ -458,10 +458,10 @@ bool FillUsedFilesImpl(
}
if (node.IsCallable("Udf") || node.IsCallable("ScriptUdf")) {
- TStringBuf moduleName = node.Head().Content();
+ TStringBuf moduleName = node.Head().Content();
if (node.IsCallable("Udf")) {
TStringBuf funcName;
- YQL_ENSURE(SplitUdfName(node.Head().Content(), moduleName, funcName));
+ YQL_ENSURE(SplitUdfName(node.Head().Content(), moduleName, funcName));
}
auto scriptType = NKikimr::NMiniKQL::ScriptTypeFromStr(moduleName);
@@ -489,9 +489,9 @@ bool FillUsedFilesImpl(
return false;
} else {
files.emplace(TUserDataStorage::ComposeUserDataKey(fileAlias), *block).first->second.Usage.Set(EUserDataBlockUsage::Udf);
- }
+ }
}
-
+
if (moduleName == TStringBuf("Geo")) {
const auto geobase = TUserDataKey::File(TStringBuf("/home/geodata6.bin"));
if (const auto block = types.UserDataStorage->FindUserDataBlock(geobase)) {
@@ -539,7 +539,7 @@ bool FillUsedFilesImpl(
bool childrenOk = true;
for (auto& child : node.Children()) {
- childrenOk = FillUsedFilesImpl(*child, files, types, ctx, crutches, visited) && childrenOk;
+ childrenOk = FillUsedFilesImpl(*child, files, types, ctx, crutches, visited) && childrenOk;
}
return childrenOk;
@@ -618,14 +618,14 @@ bool FillUsedFiles(
const TExprNode& node,
TUserDataTable& files,
const TTypeAnnotationContext& types,
- TExprContext& ctx,
- const TUserDataTable& crutches) {
+ TExprContext& ctx,
+ const TUserDataTable& crutches) {
TNodeSet visited;
- return FillUsedFilesImpl(node, files, types, ctx, crutches, visited);
+ return FillUsedFilesImpl(node, files, types, ctx, crutches, visited);
}
-std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture> FreezeUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const std::function<bool(const TString&)>& urlDownloadFilter, const TUserDataTable& crutches) {
- if (!FillUsedFiles(node, files, types, ctx, crutches)) {
+std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture> FreezeUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const std::function<bool(const TString&)>& urlDownloadFilter, const TUserDataTable& crutches) {
+ if (!FillUsedFiles(node, files, types, ctx, crutches)) {
return SyncError();
}
@@ -771,28 +771,28 @@ void WriteStream(NYson::TYsonWriter& writer, const TExprNode* node, const TExprN
writer.OnBeginList();
writer.OnListItem();
writer.OnBeginList();
- WriteStream(writer, node->Child(1)->Child(1), node->Child(1)->Head().Child(0));
+ WriteStream(writer, node->Child(1)->Child(1), node->Child(1)->Head().Child(0));
+ writer.OnEndList();
+ writer.OnEndList();
+ }
+
+ if (TCoChopper::Match(node) || node->IsCallable("WideChopper")) {
+ writer.OnKeyedItem("Children");
+ writer.OnBeginList();
+ writer.OnListItem();
+ writer.OnBeginList();
+ WriteStream(writer, &node->Tail().Tail(), &node->Tail().Head().Head());
writer.OnEndList();
writer.OnEndList();
}
- if (TCoChopper::Match(node) || node->IsCallable("WideChopper")) {
- writer.OnKeyedItem("Children");
- writer.OnBeginList();
- writer.OnListItem();
- writer.OnBeginList();
- WriteStream(writer, &node->Tail().Tail(), &node->Tail().Head().Head());
- writer.OnEndList();
- writer.OnEndList();
- }
-
if (TCoSwitch::Match(node)) {
writer.OnKeyedItem("Children");
writer.OnBeginList();
for (size_t i = 3; i < node->ChildrenSize(); i += 2) {
writer.OnListItem();
writer.OnBeginList();
- WriteStream(writer, node->Child(i)->Child(1), node->Child(i)->Head().Child(0));
+ WriteStream(writer, node->Child(i)->Child(1), node->Child(i)->Head().Child(0));
writer.OnEndList();
}
@@ -874,28 +874,28 @@ double GetDataReplicationFactor(double factor, const TExprNode* node, const TExp
}
if (TCoFlatMapBase::Match(node)) {
- // TODO: check MapJoinCore input unique using constraints
- if (const auto& lambda = node->Tail(); node->Head().IsCallable("SqueezeToDict") && lambda.Tail().IsCallable("MapJoinCore") && lambda.Tail().Child(1U) == &lambda.Head().Head()) {
- TMaybe<bool> isMany;
- TMaybe<bool> isHashed;
- bool isCompact = false;
- TMaybe<ui64> itemsCount;
- ParseToDictSettings(node->Head(), ctx, isMany, isHashed, itemsCount, isCompact);
- if (isMany.GetOrElse(true)) {
- factor *= 5.0;
- }
- } else {
- switch (lambda.GetTypeAnn()->GetKind()) {
- case ETypeAnnotationKind::Stream:
- case ETypeAnnotationKind::Flow:
- factor = GetDataReplicationFactor(factor, &lambda.Tail(), &lambda.Head().Head(), ctx);
- break;
- case ETypeAnnotationKind::List:
- factor *= 2.0;
- break;
- default:
- break;
- }
+ // TODO: check MapJoinCore input unique using constraints
+ if (const auto& lambda = node->Tail(); node->Head().IsCallable("SqueezeToDict") && lambda.Tail().IsCallable("MapJoinCore") && lambda.Tail().Child(1U) == &lambda.Head().Head()) {
+ TMaybe<bool> isMany;
+ TMaybe<bool> isHashed;
+ bool isCompact = false;
+ TMaybe<ui64> itemsCount;
+ ParseToDictSettings(node->Head(), ctx, isMany, isHashed, itemsCount, isCompact);
+ if (isMany.GetOrElse(true)) {
+ factor *= 5.0;
+ }
+ } else {
+ switch (lambda.GetTypeAnn()->GetKind()) {
+ case ETypeAnnotationKind::Stream:
+ case ETypeAnnotationKind::Flow:
+ factor = GetDataReplicationFactor(factor, &lambda.Tail(), &lambda.Head().Head(), ctx);
+ break;
+ case ETypeAnnotationKind::List:
+ factor *= 2.0;
+ break;
+ default:
+ break;
+ }
}
}
else if (node->IsCallable("CommonJoinCore")) {
@@ -917,7 +917,7 @@ double GetDataReplicationFactor(double factor, const TExprNode* node, const TExp
else if (TCoSwitch::Match(node)) {
double switchFactor = 0.0;
for (size_t i = 3; i < node->ChildrenSize(); i += 2) {
- switchFactor += GetDataReplicationFactor(factor, node->Child(i)->Child(1), node->Child(i)->Head().Child(0), ctx);
+ switchFactor += GetDataReplicationFactor(factor, node->Child(i)->Child(1), node->Child(i)->Head().Child(0), ctx);
}
factor = Max(1.0, switchFactor);
}
@@ -928,7 +928,7 @@ double GetDataReplicationFactor(double factor, const TExprNode* node, const TExp
}
factor = Max(1.0, extendFactor);
}
- else if (TCoChopper::Match(node) || node->IsCallable("WideChopper")) {
+ else if (TCoChopper::Match(node) || node->IsCallable("WideChopper")) {
factor = GetDataReplicationFactor(factor, &node->Child(TCoChopper::idx_Handler)->Tail(), &node->Child(TCoChopper::idx_Handler)->Head().Tail(), ctx);
}
@@ -936,7 +936,7 @@ double GetDataReplicationFactor(double factor, const TExprNode* node, const TExp
}
double GetDataReplicationFactor(const TExprNode& lambda, TExprContext& ctx) {
- return GetDataReplicationFactor(1.0, lambda.Child(1), lambda.Head().ChildrenSize() > 0 ? lambda.Head().Child(0) : nullptr, ctx);
+ return GetDataReplicationFactor(1.0, lambda.Child(1), lambda.Head().ChildrenSize() > 0 ? lambda.Head().Child(0) : nullptr, ctx);
}
void WriteStatistics(NYson::TYsonWriter& writer, bool totalOnly, const THashMap<ui32, TOperationStatistics>& statistics) {
diff --git a/ydb/library/yql/providers/common/provider/yql_provider.h b/ydb/library/yql/providers/common/provider/yql_provider.h
index da36de5db9..9e80cfd135 100644
--- a/ydb/library/yql/providers/common/provider/yql_provider.h
+++ b/ydb/library/yql/providers/common/provider/yql_provider.h
@@ -77,7 +77,7 @@ struct TCommitSettings
bool EnsureOtherEmpty(TExprContext& ctx);
};
-const TStructExprType* BuildCommonTableListType(TExprContext& ctx);
+const TStructExprType* BuildCommonTableListType(TExprContext& ctx);
TExprNode::TPtr BuildTypeExpr(TPositionHandle pos, const TTypeAnnotationNode& ann, TExprContext& ctx);
@@ -102,10 +102,10 @@ void TransformerStatsToYson(const TString& name, const IGraphTransformer::TStati
void FillSecureParams(const TExprNode::TPtr& node, const TTypeAnnotationContext& types, THashMap<TString, TString>& secureParams);
-bool FillUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const TUserDataTable& crutches = {});
+bool FillUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const TUserDataTable& crutches = {});
+
+std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture> FreezeUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const std::function<bool(const TString&)>& urlDownloadFilter, const TUserDataTable& crutches = {});
-std::pair<IGraphTransformer::TStatus, TAsyncTransformCallbackFuture> FreezeUsedFiles(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const std::function<bool(const TString&)>& urlDownloadFilter, const TUserDataTable& crutches = {});
-
bool FreezeUsedFilesSync(const TExprNode& node, TUserDataTable& files, const TTypeAnnotationContext& types, TExprContext& ctx, const std::function<bool(const TString&)>& urlDownloadFilter);
void WriteColumns(NYson::TYsonWriter& writer, const NNodes::TExprBase& columns);
diff --git a/ydb/library/yql/providers/common/provider/yql_provider_names.h b/ydb/library/yql/providers/common/provider/yql_provider_names.h
index 9ecf230634..7cf29b4c1d 100644
--- a/ydb/library/yql/providers/common/provider/yql_provider_names.h
+++ b/ydb/library/yql/providers/common/provider/yql_provider_names.h
@@ -5,21 +5,21 @@
namespace NYql {
-constexpr TStringBuf ConfigProviderName = "config";
-constexpr TStringBuf KikimrProviderName = "kikimr";
-constexpr TStringBuf ResultProviderName = "result";
-constexpr TStringBuf YtProviderName = "yt";
-constexpr TStringBuf RtmrProviderName = "rtmr";
-constexpr TStringBuf StatProviderName = "statface";
-constexpr TStringBuf SolomonProviderName = "solomon";
-constexpr TStringBuf DqProviderName = "dq";
-constexpr TStringBuf ClickHouseProviderName = "clickhouse";
-constexpr TStringBuf YdbProviderName = "ydb";
-constexpr TStringBuf PqProviderName = "pq";
-constexpr TStringBuf S3ProviderName = "s3";
+constexpr TStringBuf ConfigProviderName = "config";
+constexpr TStringBuf KikimrProviderName = "kikimr";
+constexpr TStringBuf ResultProviderName = "result";
+constexpr TStringBuf YtProviderName = "yt";
+constexpr TStringBuf RtmrProviderName = "rtmr";
+constexpr TStringBuf StatProviderName = "statface";
+constexpr TStringBuf SolomonProviderName = "solomon";
+constexpr TStringBuf DqProviderName = "dq";
+constexpr TStringBuf ClickHouseProviderName = "clickhouse";
+constexpr TStringBuf YdbProviderName = "ydb";
+constexpr TStringBuf PqProviderName = "pq";
+constexpr TStringBuf S3ProviderName = "s3";
-constexpr std::array<const TStringBuf, 11> Providers = {
- {ConfigProviderName, YtProviderName, KikimrProviderName, RtmrProviderName, S3ProviderName,
+constexpr std::array<const TStringBuf, 11> Providers = {
+ {ConfigProviderName, YtProviderName, KikimrProviderName, RtmrProviderName, S3ProviderName,
StatProviderName, SolomonProviderName, DqProviderName, ClickHouseProviderName, YdbProviderName,
PqProviderName}
};
diff --git a/ydb/library/yql/providers/common/provider/yql_table_lookup.cpp b/ydb/library/yql/providers/common/provider/yql_table_lookup.cpp
index 87267658bc..93b84f6db0 100644
--- a/ydb/library/yql/providers/common/provider/yql_table_lookup.cpp
+++ b/ydb/library/yql/providers/common/provider/yql_table_lookup.cpp
@@ -1,7 +1,7 @@
#include "yql_table_lookup.h"
#include <ydb/library/yql/ast/yql_expr.h>
-#include <array>
+#include <array>
namespace NYql {
namespace NCommon {
@@ -40,7 +40,7 @@ TExprBase BuildColumnCompare(TExprBase row, const TString& columnName, TExprBase
TMaybeNode<TExprBase> CombinePredicatesAnd(TMaybeNode<TExprBase> left, TMaybeNode<TExprBase> right, TExprContext& ctx) {
if (left && right) {
return Build<TCoAnd>(ctx, left.Cast().Pos())
- .Add({left.Cast(), right.Cast()})
+ .Add({left.Cast(), right.Cast()})
.Done();
} else if (left) {
return left;
@@ -54,7 +54,7 @@ TMaybeNode<TExprBase> CombinePredicatesAnd(TMaybeNode<TExprBase> left, TMaybeNod
TMaybeNode<TExprBase> CombinePredicatesOr(TMaybeNode<TExprBase> left, TMaybeNode<TExprBase> right, TExprContext& ctx) {
if (left && right) {
return Build<TCoOr>(ctx, left.Cast().Pos())
- .Add({left.Cast(), right.Cast()})
+ .Add({left.Cast(), right.Cast()})
.Done();
}
@@ -112,7 +112,7 @@ TMaybeNode<TExprBase> BuildColumnRangePredicate(const TString& column, const TCo
if (fromPredicate && toPredicate) {
return Build<TCoAnd>(ctx, row.Pos())
- .Add({fromPredicate.Cast(), toPredicate.Cast()})
+ .Add({fromPredicate.Cast(), toPredicate.Cast()})
.Done();
} else if (fromPredicate) {
return fromPredicate.Cast();
@@ -564,85 +564,85 @@ TKeyRangeBuilder CombineKeyRangesAnd(TExprBase row, const TVector<TString>& keyC
}
TTableLookupBuilder CombineLookupsAnd(TExprBase row, const TVector<TString>& keyColumns,
- const TTableLookupBuilder* builders, size_t size, const TLookupContext& ctx)
+ const TTableLookupBuilder* builders, size_t size, const TLookupContext& ctx)
{
- switch (size) {
- case 0U: Y_FAIL("Wrong case");
- case 1U: return *builders;
- case 2U: {
- const auto& left = builders[0U];
- const auto& right = builders[1U];
- if (left.IsSingleRange() && right.IsSingleRange()) {
- auto combinedKeyRange = CombineKeyRangesAnd(row, keyColumns, left.GetKeyRangeBuilder(),
- right.GetKeyRangeBuilder(), ctx);
- return TTableLookupBuilder(keyColumns, combinedKeyRange);
- } else {
- auto combineRanges =
- [&keyColumns, row, &ctx] (const TTableLookupBuilder& lookup, const TTableLookupBuilder& residual) {
- auto& residualKeyRanges = residual.GetKeyRangeBuilders();
- auto residualPredicate = CombinePredicateListOr(residualKeyRanges, ctx.ExprCtx,
- [&keyColumns, row, &ctx](const TKeyRangeBuilder& keyRange) {
- return keyRange.BuildPredicate(keyColumns, row, ctx.ExprCtx);
- });
-
- TVector<TKeyRangeBuilder> newKeyRanges;
- for (auto& keyRange : lookup.GetKeyRangeBuilders()) {
- auto newResidualPredicate = CombinePredicatesAnd(keyRange.GetResidualPredicate(),
- residualPredicate, ctx.ExprCtx);
- auto newRange = TKeyRangeBuilder(keyRange, newResidualPredicate);
- newKeyRanges.push_back(newRange);
- }
-
- return TTableLookupBuilder(keyColumns, newKeyRanges);
- };
-
- const bool keepRight = right.HasNonFullscanRanges() && !left.HasNonFullscanRanges();
- return keepRight ? combineRanges(right, left) : combineRanges(left, right);
- }
- }
- default: break;
- }
-
- const auto half = (size + 1U) >> 1U;
- const std::array<TTableLookupBuilder, 2U> pair = {{
- CombineLookupsAnd(row, keyColumns, builders, half, ctx),
- CombineLookupsAnd(row, keyColumns, builders + half, size - half, ctx)
- }};
- return CombineLookupsAnd(row, keyColumns, pair.data(), pair.size(), ctx);
+ switch (size) {
+ case 0U: Y_FAIL("Wrong case");
+ case 1U: return *builders;
+ case 2U: {
+ const auto& left = builders[0U];
+ const auto& right = builders[1U];
+ if (left.IsSingleRange() && right.IsSingleRange()) {
+ auto combinedKeyRange = CombineKeyRangesAnd(row, keyColumns, left.GetKeyRangeBuilder(),
+ right.GetKeyRangeBuilder(), ctx);
+ return TTableLookupBuilder(keyColumns, combinedKeyRange);
+ } else {
+ auto combineRanges =
+ [&keyColumns, row, &ctx] (const TTableLookupBuilder& lookup, const TTableLookupBuilder& residual) {
+ auto& residualKeyRanges = residual.GetKeyRangeBuilders();
+ auto residualPredicate = CombinePredicateListOr(residualKeyRanges, ctx.ExprCtx,
+ [&keyColumns, row, &ctx](const TKeyRangeBuilder& keyRange) {
+ return keyRange.BuildPredicate(keyColumns, row, ctx.ExprCtx);
+ });
+
+ TVector<TKeyRangeBuilder> newKeyRanges;
+ for (auto& keyRange : lookup.GetKeyRangeBuilders()) {
+ auto newResidualPredicate = CombinePredicatesAnd(keyRange.GetResidualPredicate(),
+ residualPredicate, ctx.ExprCtx);
+ auto newRange = TKeyRangeBuilder(keyRange, newResidualPredicate);
+ newKeyRanges.push_back(newRange);
+ }
+
+ return TTableLookupBuilder(keyColumns, newKeyRanges);
+ };
+
+ const bool keepRight = right.HasNonFullscanRanges() && !left.HasNonFullscanRanges();
+ return keepRight ? combineRanges(right, left) : combineRanges(left, right);
+ }
+ }
+ default: break;
+ }
+
+ const auto half = (size + 1U) >> 1U;
+ const std::array<TTableLookupBuilder, 2U> pair = {{
+ CombineLookupsAnd(row, keyColumns, builders, half, ctx),
+ CombineLookupsAnd(row, keyColumns, builders + half, size - half, ctx)
+ }};
+ return CombineLookupsAnd(row, keyColumns, pair.data(), pair.size(), ctx);
}
-TTableLookupBuilder CombineLookupsOr(TExprBase, const TVector<TString>& keyColumns,
- const TTableLookupBuilder* builders, size_t size, const TLookupContext&)
+TTableLookupBuilder CombineLookupsOr(TExprBase, const TVector<TString>& keyColumns,
+ const TTableLookupBuilder* builders, size_t size, const TLookupContext&)
{
- TVector<TKeyRangeBuilder> newKeyRanges;
- newKeyRanges.reserve(size);
- for (size_t i = 0U; i < size; ++i) {
- newKeyRanges.insert(newKeyRanges.end(), builders[i].GetKeyRangeBuilders().cbegin(), builders[i].GetKeyRangeBuilders().cend());
- }
+ TVector<TKeyRangeBuilder> newKeyRanges;
+ newKeyRanges.reserve(size);
+ for (size_t i = 0U; i < size; ++i) {
+ newKeyRanges.insert(newKeyRanges.end(), builders[i].GetKeyRangeBuilders().cbegin(), builders[i].GetKeyRangeBuilders().cend());
+ }
return TTableLookupBuilder(keyColumns, newKeyRanges);
}
TTableLookupBuilder CollectLookups(TExprBase row, TExprBase predicate,
const TVector<TString>& keyColumns, const TLookupContext& ctx)
{
- if (const auto maybeAnd = predicate.Maybe<TCoAnd>()) {
- const auto size = maybeAnd.Cast().Args().size();
- std::vector<TTableLookupBuilder> builders;
- builders.reserve(size);
- for (auto i = 0U; i < size; ++i) {
- builders.emplace_back(CollectLookups(row, maybeAnd.Cast().Arg(i), keyColumns, ctx));
- }
- return CombineLookupsAnd(row, keyColumns, builders.data(), builders.size(), ctx);
+ if (const auto maybeAnd = predicate.Maybe<TCoAnd>()) {
+ const auto size = maybeAnd.Cast().Args().size();
+ std::vector<TTableLookupBuilder> builders;
+ builders.reserve(size);
+ for (auto i = 0U; i < size; ++i) {
+ builders.emplace_back(CollectLookups(row, maybeAnd.Cast().Arg(i), keyColumns, ctx));
+ }
+ return CombineLookupsAnd(row, keyColumns, builders.data(), builders.size(), ctx);
}
- if (const auto maybeOr = predicate.Maybe<TCoOr>()) {
- const auto size = maybeOr.Cast().Args().size();
- std::vector<TTableLookupBuilder> builders;
- builders.reserve(size);
- for (auto i = 0U; i < size; ++i) {
- builders.emplace_back(CollectLookups(row, maybeOr.Cast().Arg(i), keyColumns, ctx));
- }
- return CombineLookupsOr(row, keyColumns, builders.data(), builders.size(), ctx);
+ if (const auto maybeOr = predicate.Maybe<TCoOr>()) {
+ const auto size = maybeOr.Cast().Args().size();
+ std::vector<TTableLookupBuilder> builders;
+ builders.reserve(size);
+ for (auto i = 0U; i < size; ++i) {
+ builders.emplace_back(CollectLookups(row, maybeOr.Cast().Arg(i), keyColumns, ctx));
+ }
+ return CombineLookupsOr(row, keyColumns, builders.data(), builders.size(), ctx);
}
TMaybeNode<TCoCompare> maybeCompare = predicate.Maybe<TCoCompare>();
diff --git a/ydb/library/yql/providers/common/provider/yql_table_lookup.h b/ydb/library/yql/providers/common/provider/yql_table_lookup.h
index 4e1280873d..988fb5b4ba 100644
--- a/ydb/library/yql/providers/common/provider/yql_table_lookup.h
+++ b/ydb/library/yql/providers/common/provider/yql_table_lookup.h
@@ -56,7 +56,7 @@ public:
{
Point = From.IsDefined() && To.IsDefined() &&
From.IsInclusive() && To.IsInclusive() &&
- From.GetValue().Raw() == To.GetValue().Raw();
+ From.GetValue().Raw() == To.GetValue().Raw();
}
TColumnRange()
diff --git a/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp b/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp
index c567c41254..0bbaf5c339 100644
--- a/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp
+++ b/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp
@@ -157,11 +157,11 @@ public:
void Save(const TTypeAnnotationNode* type) {
switch (type->GetKind()) {
- case ETypeAnnotationKind::Data: {
- const auto dataType = type->Cast<TDataExprType>();
- if (const auto dataParamsType = dynamic_cast<const TDataExprParamsType*>(dataType)) {
+ case ETypeAnnotationKind::Data: {
+ const auto dataType = type->Cast<TDataExprType>();
+ if (const auto dataParamsType = dynamic_cast<const TDataExprParamsType*>(dataType)) {
TBase::SaveDataTypeParams(dataType->GetName(), dataParamsType->GetParamOne(), dataParamsType->GetParamTwo());
- } else
+ } else
TBase::SaveDataType(dataType->GetName());
}
break;
@@ -269,7 +269,7 @@ struct TExprTypeLoader {
{
}
TMaybe<TType> LoadVoidType(ui32 /*level*/) {
- return Ctx.MakeType<TVoidExprType>();
+ return Ctx.MakeType<TVoidExprType>();
}
TMaybe<TType> LoadNullType(ui32 /*level*/) {
return Ctx.MakeType<TNullExprType>();
diff --git a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
index 7bb39c7c78..0a34105714 100644
--- a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
+++ b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp
@@ -99,12 +99,12 @@ public:
}
auto dataType = NUdf::GetDataTypeInfo(*slot).Name;
- if (NKikimr::NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
- const auto params = static_cast<const TDataDecimalType*>(type)->GetParams();
+ if (NKikimr::NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
+ const auto params = static_cast<const TDataDecimalType*>(type)->GetParams();
TBase::SaveDataTypeParams(dataType, ToString(params.first), ToString(params.second));
- } else {
- TBase::SaveDataType(dataType);
- }
+ } else {
+ TBase::SaveDataType(dataType);
+ }
break;
}
case TType::EKind::Struct:
@@ -206,21 +206,21 @@ struct TRuntimeTypeLoader {
return Nothing();
}
- if (NKikimr::NUdf::EDataSlot::Decimal == slot) {
+ if (NKikimr::NUdf::EDataSlot::Decimal == slot) {
Err << "Decimal type without parameters.";
return Nothing();
}
-
+
return Builder.NewDataType(NUdf::GetDataTypeInfo(*slot).TypeId);
}
-
+
TMaybe<TType> LoadDataTypeParams(const TString& dataType, const TString& paramOne, const TString& paramTwo, ui32 /*level*/) {
const auto slot = NUdf::FindDataSlot(dataType);
if (!slot) {
Err << "Unsupported data type: " << dataType;
return Nothing();
- }
-
+ }
+
if (NKikimr::NUdf::EDataSlot::Decimal != slot) {
Err << "Unexpected parameters for type: " << dataType;
return Nothing();
diff --git a/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp b/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp
index 27ea8f4e6e..2461a17094 100644
--- a/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp
+++ b/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp
@@ -64,7 +64,7 @@ struct TSkiffTypeLoader {
case NUdf::EDataSlot::Utf8:
case NUdf::EDataSlot::Json:
case NUdf::EDataSlot::Uuid:
- case NUdf::EDataSlot::DyNumber:
+ case NUdf::EDataSlot::DyNumber:
case NUdf::EDataSlot::JsonDocument:
return NYT::TNode()("wire_type", "string32");
case NUdf::EDataSlot::Yson:
diff --git a/ydb/library/yql/providers/common/ya.make b/ydb/library/yql/providers/common/ya.make
index c6f7ae0d62..66778b0bcf 100644
--- a/ydb/library/yql/providers/common/ya.make
+++ b/ydb/library/yql/providers/common/ya.make
@@ -3,7 +3,7 @@ RECURSE(
config
dq
gateway
- http_gateway
+ http_gateway
metrics
mkql
comp_nodes
diff --git a/ydb/library/yql/providers/config/yql_config_provider.cpp b/ydb/library/yql/providers/config/yql_config_provider.cpp
index b6f4653576..6952e96cf0 100644
--- a/ydb/library/yql/providers/config/yql_config_provider.cpp
+++ b/ydb/library/yql/providers/config/yql_config_provider.cpp
@@ -34,19 +34,19 @@ namespace {
}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
- YQL_ENSURE(input->Type() == TExprNode::Callable);
- if (input->Content() == "Pull") {
- auto requireStatus = RequireChild(*input, 0);
+ output = input;
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
+ if (input->Content() == "Pull") {
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
}
- IDataProvider::TFillSettings fillSettings = NCommon::GetFillSettings(*input);
+ IDataProvider::TFillSettings fillSettings = NCommon::GetFillSettings(*input);
YQL_ENSURE(fillSettings.Format == IDataProvider::EResultFormat::Yson);
NYson::EYsonFormat ysonFormat = NCommon::GetYsonFormat(fillSettings);
- auto nodeToPull = input->Child(0)->Child(0);
+ auto nodeToPull = input->Child(0)->Child(0);
if (nodeToPull->IsCallable(ConfReadName)) {
auto key = nodeToPull->Child(2);
auto tag = key->Child(0)->Child(0)->Content();
@@ -74,7 +74,7 @@ namespace {
writer.OnEndList();
writer.OnEndMap();
- input->SetResult(ctx.NewAtom(input->Pos(), out.Str()));
+ input->SetResult(ctx.NewAtom(input->Pos(), out.Str()));
input->SetState(TExprNode::EState::ExecutionComplete);
return TStatus::Ok;
} else {
@@ -88,25 +88,25 @@ namespace {
return TStatus::Error;
}
- if (input->Content() == ConfReadName) {
- auto requireStatus = RequireChild(*input, 0);
+ if (input->Content() == ConfReadName) {
+ auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
}
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return TStatus::Ok;
}
- if (input->Content() == ConfigureName) {
+ if (input->Content() == ConfigureName) {
auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return requireStatus;
}
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld(input->Pos()));
+ input->SetResult(ctx.NewWorld(input->Pos()));
return TStatus::Ok;
}
@@ -183,8 +183,8 @@ namespace {
}
ConfigurationTransformer = CreateFunctorTransformer(
- [this](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
- output = input;
+ [this](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
+ output = input;
if (ctx.Step.IsDone(TExprStep::Configure)) {
return IGraphTransformer::TStatus::Ok;
}
@@ -192,26 +192,26 @@ namespace {
bool hasPendingEvaluations = false;
TOptimizeExprSettings settings(nullptr);
settings.VisitChanges = true;
- auto status = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ auto status = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
auto res = node;
if (!hasPendingEvaluations && node->Content() == ConfigureName) {
- if (!EnsureMinArgsCount(*node, 2, ctx)) {
+ if (!EnsureMinArgsCount(*node, 2, ctx)) {
return {};
}
- if (!node->Child(1)->IsCallable("DataSource")) {
- return node;
+ if (!node->Child(1)->IsCallable("DataSource")) {
+ return node;
}
- if (node->Child(1)->Child(0)->Content() != ConfigProviderName) {
- return node;
+ if (node->Child(1)->Child(0)->Content() != ConfigProviderName) {
+ return node;
}
- if (!EnsureMinArgsCount(*node, 3, ctx)) {
+ if (!EnsureMinArgsCount(*node, 3, ctx)) {
return {};
}
- if (!EnsureAtom(*node->Child(2), ctx)) {
+ if (!EnsureAtom(*node->Child(2), ctx)) {
return {};
}
@@ -252,18 +252,18 @@ namespace {
Y_UNUSED(instantOnly);
if (!TypeAnnotationTransformer) {
TypeAnnotationTransformer = CreateFunctorTransformer(
- [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
- output = input;
- if (input->Content() == ConfReadName) {
- if (!EnsureWorldType(*input->Child(0), ctx)) {
+ [&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
+ output = input;
+ if (input->Content() == ConfReadName) {
+ if (!EnsureWorldType(*input->Child(0), ctx)) {
return IGraphTransformer::TStatus::Error;
}
- if (!EnsureSpecificDataSource(*input->Child(1), ConfigProviderName, ctx)) {
+ if (!EnsureSpecificDataSource(*input->Child(1), ConfigProviderName, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto key = input->Child(2);
+ auto key = input->Child(2);
if (!key->IsCallable("Key")) {
ctx.AddError(TIssue(ctx.GetPosition(key->Pos()), "Expected key"));
return IGraphTransformer::TStatus::Error;
@@ -285,7 +285,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto fields = input->Child(3);
+ auto fields = input->Child(3);
if (!EnsureTuple(*fields, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -300,7 +300,7 @@ namespace {
return IGraphTransformer::TStatus::Error;
}
- auto settings = input->Child(4);
+ auto settings = input->Child(4);
if (!EnsureTuple(*settings, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -325,8 +325,8 @@ namespace {
input->SetTypeAnn(tupleAnn);
return IGraphTransformer::TStatus::Ok;
}
- else if (input->Content() == ConfigureName) {
- if (!EnsureWorldType(*input->Child(0), ctx)) {
+ else if (input->Content() == ConfigureName) {
+ if (!EnsureWorldType(*input->Child(0), ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -342,8 +342,8 @@ namespace {
return *TypeAnnotationTransformer;
}
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- auto read = node->Child(0);
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ auto read = node->Child(0);
TString newName;
if (read->Content() == ReadName) {
newName = ConfReadName;
@@ -353,17 +353,17 @@ namespace {
}
YQL_CLOG(INFO, ProviderConfig) << "RewriteIO";
- auto newRead = ctx.RenameNode(*read, newName);
+ auto newRead = ctx.RenameNode(*read, newName);
auto retChildren = node->ChildrenList();
retChildren[0] = newRead;
- return ctx.ChangeChildren(*node, std::move(retChildren));
+ return ctx.ChangeChildren(*node, std::move(retChildren));
}
- bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
+ bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
Y_UNUSED(syncList);
- if (node.IsCallable(RightName)) {
- if (node.Child(0)->IsCallable(ConfReadName)) {
+ if (node.IsCallable(RightName)) {
+ if (node.Child(0)->IsCallable(ConfReadName)) {
canRef = false;
return true;
}
@@ -393,17 +393,17 @@ namespace {
bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
Y_UNUSED(compact);
if (CanExecute(node)) {
- children.push_back(node.ChildPtr(0));
+ children.push_back(node.ChildPtr(0));
}
return false;
}
void WritePullDetails(const TExprNode& node, NYson::TYsonWriter& writer) override {
- YQL_ENSURE(node.IsCallable(RightName));
+ YQL_ENSURE(node.IsCallable(RightName));
writer.OnKeyedItem("PullOperation");
- writer.OnStringScalar(node.Child(0)->Content());
+ writer.OnStringScalar(node.Child(0)->Content());
}
TString GetProviderPath(const TExprNode& node) override {
diff --git a/ydb/library/yql/providers/dq/actors/executer_actor.cpp b/ydb/library/yql/providers/dq/actors/executer_actor.cpp
index 1cb4683723..91f1caee74 100644
--- a/ydb/library/yql/providers/dq/actors/executer_actor.cpp
+++ b/ydb/library/yql/providers/dq/actors/executer_actor.cpp
@@ -40,7 +40,7 @@ public:
TDqExecuter(
const NActors::TActorId& gwmActorId,
const NActors::TActorId& printerId,
- const TString& traceId, const TString& username,
+ const TString& traceId, const TString& username,
const TDqConfiguration::TPtr& settings,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
TInstant requestStartTime,
@@ -50,7 +50,7 @@ public:
, PrinterId(printerId)
, Settings(settings)
, TraceId(traceId)
- , Username(username)
+ , Username(username)
, Counters(counters) // root, component=dq
, LongWorkersAllocationCounter(Counters->GetSubgroup("component", "ServiceProxyActor")->GetCounter("LongWorkersAllocation"))
, ExecutionTimeoutCounter(Counters->GetSubgroup("component", "ServiceProxyActor")->GetCounter("ExecutionTimeout", /*derivative=*/ true))
@@ -182,7 +182,7 @@ private:
Counters,
enableComputeActor ? tasks : TVector<NYql::NDqProto::TDqTask>(),
computeActorType));
- auto allocateRequest = MakeHolder<TEvAllocateWorkersRequest>(workerCount, Username);
+ auto allocateRequest = MakeHolder<TEvAllocateWorkersRequest>(workerCount, Username);
allocateRequest->Record.SetTraceId(TraceId);
allocateRequest->Record.SetCreateComputeActor(enableComputeActor);
allocateRequest->Record.SetComputeActorType(computeActorType);
@@ -453,7 +453,7 @@ private:
THolder<IDqsExecutionPlanner> ExecutionPlanner;
ui64 ResourceId = 0;
const TString TraceId;
- const TString Username;
+ const TString Username;
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
TDynamicCounters::TCounterPtr LongWorkersAllocationCounter;
TDynamicCounters::TCounterPtr ExecutionTimeoutCounter;
@@ -479,7 +479,7 @@ private:
NActors::IActor* MakeDqExecuter(
const NActors::TActorId& gwmActorId,
const NActors::TActorId& printerId,
- const TString& traceId, const TString& username,
+ const TString& traceId, const TString& username,
const TDqConfiguration::TPtr& settings,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
TInstant requestStartTime,
diff --git a/ydb/library/yql/providers/dq/actors/executer_actor.h b/ydb/library/yql/providers/dq/actors/executer_actor.h
index 753d15c86e..fae7d1cdbf 100644
--- a/ydb/library/yql/providers/dq/actors/executer_actor.h
+++ b/ydb/library/yql/providers/dq/actors/executer_actor.h
@@ -11,7 +11,7 @@ namespace NDq {
NActors::IActor* MakeDqExecuter(
const NActors::TActorId& gwmActorId,
const NActors::TActorId& printerId,
- const TString& traceId, const TString& username,
+ const TString& traceId, const TString& username,
const TDqConfiguration::TPtr& settings,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
TInstant requestStartTime = TInstant::Now(),
diff --git a/ydb/library/yql/providers/dq/api/protos/dqs.proto b/ydb/library/yql/providers/dq/api/protos/dqs.proto
index 58f5d79a85..09aecfcf92 100644
--- a/ydb/library/yql/providers/dq/api/protos/dqs.proto
+++ b/ydb/library/yql/providers/dq/api/protos/dqs.proto
@@ -23,8 +23,8 @@ message TAllocateWorkersRequest {
string TraceId = 6;
// repeated Yql.DqsProto.DatabaseDescription Databases = 7; // unused
-
- string User = 8;
+
+ string User = 8;
repeated Yql.DqsProto.TWorkerFilter WorkerFilterPerTask = 9;
diff --git a/ydb/library/yql/providers/dq/api/protos/service.proto b/ydb/library/yql/providers/dq/api/protos/service.proto
index b3d10405d5..b91351e5d1 100644
--- a/ydb/library/yql/providers/dq/api/protos/service.proto
+++ b/ydb/library/yql/providers/dq/api/protos/service.proto
@@ -98,7 +98,7 @@ message SvnRevisionResponse {
message OpenSessionRequest {
string Session = 1;
- string Username = 2;
+ string Username = 2;
}
message OpenSessionResponse {
@@ -317,7 +317,7 @@ message ConfigureFailureInjectorRequest {
message ConfigureFailureInjectorResponse {
bool success = 1;
-}
+}
message IsReadyRequest {
repeated TFile Files = 1;
diff --git a/ydb/library/yql/providers/dq/common/yql_dq_settings.cpp b/ydb/library/yql/providers/dq/common/yql_dq_settings.cpp
index 8de73dea20..f9ba89a33d 100644
--- a/ydb/library/yql/providers/dq/common/yql_dq_settings.cpp
+++ b/ydb/library/yql/providers/dq/common/yql_dq_settings.cpp
@@ -20,7 +20,7 @@ TDqConfiguration::TDqConfiguration() {
REGISTER_SETTING(*this, PullRequestTimeoutMs);
REGISTER_SETTING(*this, PingTimeoutMs);
REGISTER_SETTING(*this, UseSimpleYtReader);
- REGISTER_SETTING(*this, OptLLVM);
+ REGISTER_SETTING(*this, OptLLVM);
REGISTER_SETTING(*this, ChannelBufferSize);
REGISTER_SETTING(*this, OutputChunkMaxSize);
REGISTER_SETTING(*this, MemoryLimit);
diff --git a/ydb/library/yql/providers/dq/common/yql_dq_settings.h b/ydb/library/yql/providers/dq/common/yql_dq_settings.h
index fdbbeb226f..3c37e4d48f 100644
--- a/ydb/library/yql/providers/dq/common/yql_dq_settings.h
+++ b/ydb/library/yql/providers/dq/common/yql_dq_settings.h
@@ -13,10 +13,10 @@
namespace NYql {
struct TDqSettings {
-
- struct TDefault {
- static constexpr ui32 MaxTasksPerStage = 20U;
- static constexpr ui32 MaxTasksPerOperation = 70U;
+
+ struct TDefault {
+ static constexpr ui32 MaxTasksPerStage = 20U;
+ static constexpr ui32 MaxTasksPerOperation = 70U;
static constexpr ui64 PortoMemoryLimit = 3_GB;
static constexpr bool EnablePorto = false;
static constexpr ui64 DataSizePerJob = 128_MB;
@@ -25,8 +25,8 @@ struct TDqSettings {
static constexpr ui64 LiteralTimeout = 60000; // 1 minutes
static constexpr ui64 TableTimeout = 600000; // 10 minutes
static constexpr ui32 CloudFunctionConcurrency = 10;
- };
-
+ };
+
using TPtr = std::shared_ptr<TDqSettings>;
NCommon::TConfSetting<ui64, false> DataSizePerJob;
@@ -46,7 +46,7 @@ struct TDqSettings {
NCommon::TConfSetting<ui64, false> PullRequestTimeoutMs;
NCommon::TConfSetting<ui64, false> PingTimeoutMs;
NCommon::TConfSetting<bool, false> UseSimpleYtReader;
- NCommon::TConfSetting<TString, false> OptLLVM;
+ NCommon::TConfSetting<TString, false> OptLLVM;
NCommon::TConfSetting<ui64, false> ChannelBufferSize;
NCommon::TConfSetting<ui64, false> OutputChunkMaxSize;
NCommon::TConfSetting<NSize::TSize, false> MemoryLimit;
@@ -87,7 +87,7 @@ struct TDqSettings {
SAVE_SETTING(CollectCoreDumps);
SAVE_SETTING(PullRequestTimeoutMs);
SAVE_SETTING(PingTimeoutMs);
- SAVE_SETTING(OptLLVM);
+ SAVE_SETTING(OptLLVM);
SAVE_SETTING(ChannelBufferSize);
SAVE_SETTING(OutputChunkMaxSize);
SAVE_SETTING(MemoryLimit);
diff --git a/ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.json b/ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.json
index d3059abbfa..566f8d0503 100644
--- a/ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.json
+++ b/ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.json
@@ -12,8 +12,8 @@
"Builder": {"Generate": "None"},
"Children": [
{"Index": 0, "Name": "Input", "Type": "TExprBase"},
- {"Index": 1, "Name": "Token", "Type": "TCoSecureParam", "Optional": true},
- {"Index": 2, "Name": "Flags", "Type": "TCoAtomList", "Optional": true}
+ {"Index": 1, "Name": "Token", "Type": "TCoSecureParam", "Optional": true},
+ {"Index": 2, "Name": "Flags", "Type": "TCoAtomList", "Optional": true}
]
},
{
@@ -22,9 +22,9 @@
"Match": {"Type": "Callable", "Name": "DqReadWrap"}
},
{
- "Name": "TDqReadWideWrap",
- "Base": "TDqReadWrapBase",
- "Match": {"Type": "Callable", "Name": "DqReadWideWrap"}
+ "Name": "TDqReadWideWrap",
+ "Base": "TDqReadWrapBase",
+ "Match": {"Type": "Callable", "Name": "DqReadWideWrap"}
},
{
"Name": "TDqWrite",
@@ -35,27 +35,27 @@
{"Index": 1, "Name": "Provider", "Type": "TCoAtom"},
{"Index": 2, "Name": "Settings", "Type": "TCoNameValueTupleList", "Optional": true}
]
- },
- {
- "Name": "TDqSourceWrapBase",
- "Base": "TExprBase",
- "Match": {"Type": "CallableBase"},
- "Children": [
- {"Index": 0, "Name": "Input", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSource", "Type": "TCoDataSource"},
- {"Index": 2, "Name": "RowType", "Type": "TExprBase"},
- {"Index": 3, "Name": "Settings", "Type": "TExprBase", "Optional": true}
- ]
- },
- {
- "Name": "TDqSourceWrap",
- "Base": "TDqSourceWrapBase",
- "Match": {"Type": "Callable", "Name": "DqSourceWrap"}
- },
- {
- "Name": "TDqSourceWideWrap",
- "Base": "TDqSourceWrapBase",
- "Match": {"Type": "Callable", "Name": "DqSourceWideWrap"}
+ },
+ {
+ "Name": "TDqSourceWrapBase",
+ "Base": "TExprBase",
+ "Match": {"Type": "CallableBase"},
+ "Children": [
+ {"Index": 0, "Name": "Input", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSource", "Type": "TCoDataSource"},
+ {"Index": 2, "Name": "RowType", "Type": "TExprBase"},
+ {"Index": 3, "Name": "Settings", "Type": "TExprBase", "Optional": true}
+ ]
+ },
+ {
+ "Name": "TDqSourceWrap",
+ "Base": "TDqSourceWrapBase",
+ "Match": {"Type": "Callable", "Name": "DqSourceWrap"}
+ },
+ {
+ "Name": "TDqSourceWideWrap",
+ "Base": "TDqSourceWrapBase",
+ "Match": {"Type": "Callable", "Name": "DqSourceWideWrap"}
}
]
}
diff --git a/ydb/library/yql/providers/dq/interface/yql_dq_integration.h b/ydb/library/yql/providers/dq/interface/yql_dq_integration.h
index 0a336b2a99..ee1938e698 100644
--- a/ydb/library/yql/providers/dq/interface/yql_dq_integration.h
+++ b/ydb/library/yql/providers/dq/interface/yql_dq_integration.h
@@ -28,8 +28,8 @@ public:
virtual ui64 Partition(const TDqSettings& config, size_t maxPartitions, const TExprNode& node,
TVector<TString>& partitions, TString* clusterName, TExprContext& ctx, bool canFallback) = 0;
- virtual TMaybe<ui64> CanRead(const TDqSettings& config, const TExprNode& read, TExprContext& ctx, bool skipIssues = true) = 0;
- virtual TExprNode::TPtr WrapRead(const TDqSettings& config, const TExprNode::TPtr& read, TExprContext& ctx) = 0;
+ virtual TMaybe<ui64> CanRead(const TDqSettings& config, const TExprNode& read, TExprContext& ctx, bool skipIssues = true) = 0;
+ virtual TExprNode::TPtr WrapRead(const TDqSettings& config, const TExprNode::TPtr& read, TExprContext& ctx) = 0;
virtual TMaybe<bool> CanWrite(const TDqSettings& config, const TExprNode& write, TExprContext& ctx) = 0;
virtual void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) = 0;
virtual bool CanFallback() = 0;
diff --git a/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.cpp b/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.cpp
index 9692728fda..1a8d3172e4 100644
--- a/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.cpp
+++ b/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.cpp
@@ -26,12 +26,12 @@ using NDqs::MakeWorkerManagerActorID;
namespace {
// TODO: Use the only driver for both sources.
- NDq::IDqSourceActorFactory::TPtr CreateSourceActorFactory(const NYdb::TDriver& driver, IHTTPGateway::TPtr httpGateway) {
+ NDq::IDqSourceActorFactory::TPtr CreateSourceActorFactory(const NYdb::TDriver& driver, IHTTPGateway::TPtr httpGateway) {
auto factory = MakeIntrusive<NYql::NDq::TDqSourceFactory>();
RegisterDqPqReadActorFactory(*factory, driver, nullptr);
RegisterYdbReadActorFactory(*factory, driver, nullptr);
- RegisterS3ReadActorFactory(*factory, nullptr, httpGateway);
- RegisterClickHouseReadActorFactory(*factory, nullptr, httpGateway);
+ RegisterS3ReadActorFactory(*factory, nullptr, httpGateway);
+ RegisterClickHouseReadActorFactory(*factory, nullptr, httpGateway);
return factory;
}
@@ -44,7 +44,7 @@ namespace {
class TLocalServiceHolder {
public:
- TLocalServiceHolder(NYdb::TDriver driver, IHTTPGateway::TPtr httpGateway, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry, NKikimr::NMiniKQL::TComputationNodeFactory compFactory,
+ TLocalServiceHolder(NYdb::TDriver driver, IHTTPGateway::TPtr httpGateway, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry, NKikimr::NMiniKQL::TComputationNodeFactory compFactory,
TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories, NBus::TBindResult interconnectPort, NBus::TBindResult grpcPort)
{
ui32 nodeId = 1;
@@ -107,8 +107,8 @@ public:
, Gateway(gateway)
{ }
- NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) override {
- return Gateway->OpenSession(sessionId, username);
+ NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) override {
+ return Gateway->OpenSession(sessionId, username);
}
void CloseSession(const TString& sessionId) override {
@@ -130,18 +130,18 @@ private:
IDqGateway::TPtr Gateway;
};
-THolder<TLocalServiceHolder> CreateLocalServiceHolder(NYdb::TDriver driver, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
+THolder<TLocalServiceHolder> CreateLocalServiceHolder(NYdb::TDriver driver, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
NKikimr::NMiniKQL::TComputationNodeFactory compFactory,
- TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories, IHTTPGateway::TPtr gateway,
+ TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories, IHTTPGateway::TPtr gateway,
NBus::TBindResult interconnectPort, NBus::TBindResult grpcPort)
{
return MakeHolder<TLocalServiceHolder>(driver, std::move(gateway), functionRegistry, compFactory, taskTransformFactory, dqTaskPreprocessorFactories, interconnectPort, grpcPort);
}
-TIntrusivePtr<IDqGateway> CreateLocalDqGateway(NYdb::TDriver driver, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
+TIntrusivePtr<IDqGateway> CreateLocalDqGateway(NYdb::TDriver driver, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
NKikimr::NMiniKQL::TComputationNodeFactory compFactory,
TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories,
- IHTTPGateway::TPtr gateway)
+ IHTTPGateway::TPtr gateway)
{
int startPort = 31337;
TRangeWalker<int> portWalker(startPort, startPort+100);
diff --git a/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.h b/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.h
index dff932f49b..b248e7c833 100644
--- a/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.h
+++ b/ydb/library/yql/providers/dq/local_gateway/yql_dq_gateway_local.h
@@ -7,6 +7,6 @@ namespace NYql {
TIntrusivePtr<IDqGateway> CreateLocalDqGateway(NYdb::TDriver driver, const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
NKikimr::NMiniKQL::TComputationNodeFactory compFactory,
- TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories, IHTTPGateway::TPtr gateway = {});
+ TTaskTransformFactory taskTransformFactory, const TDqTaskPreprocessorFactoryCollection& dqTaskPreprocessorFactories, IHTTPGateway::TPtr gateway = {});
} // namespace NYql
diff --git a/ydb/library/yql/providers/dq/mkql/dqs_mkql_compiler.cpp b/ydb/library/yql/providers/dq/mkql/dqs_mkql_compiler.cpp
index 2bc8584941..77820d1d5e 100644
--- a/ydb/library/yql/providers/dq/mkql/dqs_mkql_compiler.cpp
+++ b/ydb/library/yql/providers/dq/mkql/dqs_mkql_compiler.cpp
@@ -10,24 +10,24 @@ using namespace NKikimr::NMiniKQL;
using namespace NNodes;
void RegisterDqsMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TTypeAnnotationContext& ctx) {
- compiler.AddCallable({TDqSourceWideWrap::CallableName(), TDqReadWideWrap::CallableName()},
- [](const TExprNode& node, NCommon::TMkqlBuildContext&) {
+ compiler.AddCallable({TDqSourceWideWrap::CallableName(), TDqReadWideWrap::CallableName()},
+ [](const TExprNode& node, NCommon::TMkqlBuildContext&) {
YQL_ENSURE(false, "Unsupported reader: " << node.Head().Content());
return TRuntimeNode();
});
- std::unordered_set<IDqIntegration*> integrations(ctx.DataSources.size() + ctx.DataSinks.size());
- for (const auto& ds: ctx.DataSources) {
- if (const auto dq = ds->GetDqIntegration()) {
- integrations.emplace(dq);
+ std::unordered_set<IDqIntegration*> integrations(ctx.DataSources.size() + ctx.DataSinks.size());
+ for (const auto& ds: ctx.DataSources) {
+ if (const auto dq = ds->GetDqIntegration()) {
+ integrations.emplace(dq);
}
}
- for (const auto& ds: ctx.DataSinks) {
- if (const auto dq = ds->GetDqIntegration()) {
- integrations.emplace(dq);
+ for (const auto& ds: ctx.DataSinks) {
+ if (const auto dq = ds->GetDqIntegration()) {
+ integrations.emplace(dq);
}
}
- std::for_each(integrations.cbegin(), integrations.cend(), std::bind(&IDqIntegration::RegisterMkqlCompiler, std::placeholders::_1, std::ref(compiler)));
+ std::for_each(integrations.cbegin(), integrations.cend(), std::bind(&IDqIntegration::RegisterMkqlCompiler, std::placeholders::_1, std::ref(compiler)));
}
}
diff --git a/ydb/library/yql/providers/dq/opt/physical_optimize.cpp b/ydb/library/yql/providers/dq/opt/physical_optimize.cpp
index 9352459615..858e3da45a 100644
--- a/ydb/library/yql/providers/dq/opt/physical_optimize.cpp
+++ b/ydb/library/yql/providers/dq/opt/physical_optimize.cpp
@@ -21,7 +21,7 @@ public:
: TOptimizeTransformerBase(typeCtx, NLog::EComponent::ProviderDq, {})
{
#define HNDL(name) "DqsPhy-"#name, Hndl(&TDqsPhysicalOptProposalTransformer::name)
- AddHandler(0, &TDqSourceWrap::Match, HNDL(BuildStageWithSourceWrap));
+ AddHandler(0, &TDqSourceWrap::Match, HNDL(BuildStageWithSourceWrap));
AddHandler(0, &TDqReadWrap::Match, HNDL(BuildStageWithReadWrap));
AddHandler(0, &TCoSkipNullMembers::Match, HNDL(PushSkipNullMembersToStage<false>));
AddHandler(0, &TCoExtractMembers::Match, HNDL(PushExtractMembersToStage<false>));
@@ -69,122 +69,122 @@ public:
}
protected:
- TMaybeNode<TExprBase> BuildStageWithSourceWrap(TExprBase node, TExprContext& ctx) {
- const auto wrap = node.Cast<TDqSourceWrap>();
- const auto& items = GetSeqItemType(wrap.Ref().GetTypeAnn())->Cast<TStructExprType>()->GetItems();
- auto narrow = wrap.Settings() ?
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("source")
- .Callable("NarrowMap")
- .Callable(0, TDqSourceWideWrap::CallableName())
- .Arg(0, "source")
- .Add(1, wrap.DataSource().Ptr())
- .Add(2, wrap.RowType().Ptr())
- .Add(3, wrap.Settings().Cast().Ptr())
- .Seal()
- .Lambda(1)
- .Params("fields", items.size())
- .Callable(TCoAsStruct::CallableName())
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : items) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build():
- ctx.Builder(node.Pos())
- .Lambda()
- .Param("source")
- .Callable("NarrowMap")
- .Callable(0, TDqSourceWideWrap::CallableName())
- .Arg(0, "source")
- .Add(1, wrap.DataSource().Ptr())
- .Add(2, wrap.RowType().Ptr())
- .Seal()
- .Lambda(1)
- .Params("fields", items.size())
- .Callable(TCoAsStruct::CallableName())
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : items) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-
- return Build<TDqCnUnionAll>(ctx, node.Pos())
- .Output()
- .Stage<TDqStage>()
- .Inputs()
- .Add<TDqSource>()
- .DataSource(wrap.DataSource())
- .Settings(wrap.Input())
- .Build()
- .Build()
- .Program(narrow)
- .Settings(TDqStageSettings().BuildNode(ctx, node.Pos()))
- .Build()
- .Index().Build("0")
- .Build().Done();
- }
-
+ TMaybeNode<TExprBase> BuildStageWithSourceWrap(TExprBase node, TExprContext& ctx) {
+ const auto wrap = node.Cast<TDqSourceWrap>();
+ const auto& items = GetSeqItemType(wrap.Ref().GetTypeAnn())->Cast<TStructExprType>()->GetItems();
+ auto narrow = wrap.Settings() ?
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("source")
+ .Callable("NarrowMap")
+ .Callable(0, TDqSourceWideWrap::CallableName())
+ .Arg(0, "source")
+ .Add(1, wrap.DataSource().Ptr())
+ .Add(2, wrap.RowType().Ptr())
+ .Add(3, wrap.Settings().Cast().Ptr())
+ .Seal()
+ .Lambda(1)
+ .Params("fields", items.size())
+ .Callable(TCoAsStruct::CallableName())
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : items) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build():
+ ctx.Builder(node.Pos())
+ .Lambda()
+ .Param("source")
+ .Callable("NarrowMap")
+ .Callable(0, TDqSourceWideWrap::CallableName())
+ .Arg(0, "source")
+ .Add(1, wrap.DataSource().Ptr())
+ .Add(2, wrap.RowType().Ptr())
+ .Seal()
+ .Lambda(1)
+ .Params("fields", items.size())
+ .Callable(TCoAsStruct::CallableName())
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : items) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
+ return Build<TDqCnUnionAll>(ctx, node.Pos())
+ .Output()
+ .Stage<TDqStage>()
+ .Inputs()
+ .Add<TDqSource>()
+ .DataSource(wrap.DataSource())
+ .Settings(wrap.Input())
+ .Build()
+ .Build()
+ .Program(narrow)
+ .Settings(TDqStageSettings().BuildNode(ctx, node.Pos()))
+ .Build()
+ .Index().Build("0")
+ .Build().Done();
+ }
+
TMaybeNode<TExprBase> BuildStageWithReadWrap(TExprBase node, TExprContext& ctx) {
- const auto wrap = node.Cast<TDqReadWrap>();
- const auto read = Build<TDqReadWideWrap>(ctx, node.Pos())
- .Input(wrap.Input())
- .Token(wrap.Token())
- .Done();
-
- const auto structType = GetSeqItemType(wrap.Ref().GetTypeAnn())->Cast<TStructExprType>();
- auto narrow = ctx.Builder(node.Pos())
- .Lambda()
- .Callable("NarrowMap")
- .Add(0, read.Ptr())
- .Lambda(1)
- .Params("fields", structType->GetSize())
- .Callable("AsStruct")
- .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 i = 0U;
- for (const auto& item : structType->GetItems()) {
- parent.List(i)
- .Atom(0, item->GetName())
- .Arg(1, "fields", i)
- .Seal();
- ++i;
- }
- return parent;
- })
- .Seal()
- .Seal()
- .Seal()
- .Seal().Build();
-
+ const auto wrap = node.Cast<TDqReadWrap>();
+ const auto read = Build<TDqReadWideWrap>(ctx, node.Pos())
+ .Input(wrap.Input())
+ .Token(wrap.Token())
+ .Done();
+
+ const auto structType = GetSeqItemType(wrap.Ref().GetTypeAnn())->Cast<TStructExprType>();
+ auto narrow = ctx.Builder(node.Pos())
+ .Lambda()
+ .Callable("NarrowMap")
+ .Add(0, read.Ptr())
+ .Lambda(1)
+ .Params("fields", structType->GetSize())
+ .Callable("AsStruct")
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
+ ui32 i = 0U;
+ for (const auto& item : structType->GetItems()) {
+ parent.List(i)
+ .Atom(0, item->GetName())
+ .Arg(1, "fields", i)
+ .Seal();
+ ++i;
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal().Build();
+
return Build<TDqCnUnionAll>(ctx, node.Pos())
.Output()
- .Stage<TDqStage>()
- .Inputs().Build()
- .Program(narrow)
+ .Stage<TDqStage>()
+ .Inputs().Build()
+ .Program(narrow)
.Settings(TDqStageSettings().BuildNode(ctx, node.Pos()))
- .Build()
+ .Build()
.Index().Build("0")
- .Build() .Done();
+ .Build() .Done();
}
template <bool IsGlobal>
@@ -203,10 +203,10 @@ protected:
}
template <bool IsGlobal>
- TMaybeNode<TExprBase> PushOrderedLMapToStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx, const TGetParents& getParents) {
+ TMaybeNode<TExprBase> PushOrderedLMapToStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx, const TGetParents& getParents) {
return DqPushOrderedLMapToStage(node, ctx, optCtx, *getParents(), IsGlobal);
- }
-
+ }
+
template <bool IsGlobal>
TMaybeNode<TExprBase> PushLMapToStage(TExprBase node, TExprContext& ctx, IOptimizationContext& optCtx, const TGetParents& getParents) {
return DqPushLMapToStage(node, ctx, optCtx, *getParents(), IsGlobal);
diff --git a/ydb/library/yql/providers/dq/planner/execution_planner.cpp b/ydb/library/yql/providers/dq/planner/execution_planner.cpp
index 394780cf04..ec404c0a6d 100644
--- a/ydb/library/yql/providers/dq/planner/execution_planner.cpp
+++ b/ydb/library/yql/providers/dq/planner/execution_planner.cpp
@@ -63,7 +63,7 @@ namespace NYql::NDqs {
bool HasReadWraps(const TExprNode::TPtr& node) {
bool result = false;
VisitExpr(node, [&result](const TExprNode::TPtr& exprNode) {
- result |= TMaybeNode<TDqReadWrapBase>(exprNode).IsValid();
+ result |= TMaybeNode<TDqReadWrapBase>(exprNode).IsValid();
return !result;
});
@@ -429,23 +429,23 @@ namespace NYql::NDqs {
}
YQL_ENSURE(dqSourceInputIndex < stageInfo.InputsCount);
} else {
- if (const auto& wrap = FindNode(stage.Program().Ptr(), [](const TExprNode::TPtr& exprNode) {
- if (const auto wrap = TMaybeNode<TDqReadWrapBase>(exprNode)) {
- if (const auto flags = wrap.Cast().Flags())
- for (const auto& flag : flags.Cast())
- if (flag.Value() == "Solid")
- return false;
-
- return true;
+ if (const auto& wrap = FindNode(stage.Program().Ptr(), [](const TExprNode::TPtr& exprNode) {
+ if (const auto wrap = TMaybeNode<TDqReadWrapBase>(exprNode)) {
+ if (const auto flags = wrap.Cast().Flags())
+ for (const auto& flag : flags.Cast())
+ if (flag.Value() == "Solid")
+ return false;
+
+ return true;
}
- return false;
+ return false;
})) {
- read = wrap->Child(TDqReadWrapBase::idx_Input);
+ read = wrap->Child(TDqReadWrapBase::idx_Input);
} else {
- return false;
+ return false;
}
}
-
+
const ui32 dataSourceChildIndex = dqSource ? 0 : 1;
YQL_ENSURE(read->ChildrenSize() > 1);
YQL_ENSURE(read->Child(dataSourceChildIndex)->IsCallable("DataSource"));
@@ -453,7 +453,7 @@ namespace NYql::NDqs {
auto dataSourceName = read->Child(dataSourceChildIndex)->Child(0)->Content();
auto datasource = TypeContext->DataSourceMap.FindPtr(dataSourceName);
YQL_ENSURE(datasource);
- const auto stageSettings = TDqStageSettings::Parse(stage);
+ const auto stageSettings = TDqStageSettings::Parse(stage);
auto tasksPerStage = settings->MaxTasksPerStage.Get().GetOrElse(TDqSettings::TDefault::MaxTasksPerStage);
if (stageSettings.IsExternalFunction) {
tasksPerStage = Min(tasksPerStage, stageSettings.MaxTransformConcurrency());
diff --git a/ydb/library/yql/providers/dq/provider/exec/yql_dq_exectransformer.cpp b/ydb/library/yql/providers/dq/provider/exec/yql_dq_exectransformer.cpp
index c2e68c20b7..8759f44221 100644
--- a/ydb/library/yql/providers/dq/provider/exec/yql_dq_exectransformer.cpp
+++ b/ydb/library/yql/providers/dq/provider/exec/yql_dq_exectransformer.cpp
@@ -58,8 +58,8 @@ using namespace NCommon;
using namespace NKikimr::NMiniKQL;
using namespace NNodes;
-namespace {
-
+namespace {
+
using TUploadList = IDqGateway::TUploadList;
// TODO: move this to separate file
@@ -206,18 +206,18 @@ private:
TDqStatePtr State;
};
-struct TDqsPipelineConfigurator : public IPipelineConfigurator {
-private:
- void AfterCreate(TTransformationPipeline*) const final {}
-
- void AfterTypeAnnotation(TTransformationPipeline* pipeline) const final {
+struct TDqsPipelineConfigurator : public IPipelineConfigurator {
+private:
+ void AfterCreate(TTransformationPipeline*) const final {}
+
+ void AfterTypeAnnotation(TTransformationPipeline* pipeline) const final {
pipeline->Add(NDq::CreateDqBuildPhyStagesTransformer(false), "Build-Phy");
pipeline->Add(NDqs::CreateDqsRewritePhyCallablesTransformer(), "Rewrite-Phy-Callables");
- }
-
- void AfterOptimize(TTransformationPipeline*) const final {}
-};
-
+ }
+
+ void AfterOptimize(TTransformationPipeline*) const final {}
+};
+
class TInMemoryExecTransformer: public TExecTransformerBase, TCounters
{
public:
@@ -248,11 +248,11 @@ private:
}
}
- TExprNode::TPtr GetLambdaBody(int& level, TExprNode::TPtr&& node, TExprContext& ctx) const {
- const auto kind = node->GetTypeAnn()->GetKind();
- const bool data = kind != ETypeAnnotationKind::Flow && kind != ETypeAnnotationKind::List && kind != ETypeAnnotationKind::Stream && kind != ETypeAnnotationKind::Optional;
- level = data ? 1 : 0;
- return ctx.WrapByCallableIf(kind != ETypeAnnotationKind::Stream, "ToStream", ctx.WrapByCallableIf(data, "Just", std::move(node)));
+ TExprNode::TPtr GetLambdaBody(int& level, TExprNode::TPtr&& node, TExprContext& ctx) const {
+ const auto kind = node->GetTypeAnn()->GetKind();
+ const bool data = kind != ETypeAnnotationKind::Flow && kind != ETypeAnnotationKind::List && kind != ETypeAnnotationKind::Stream && kind != ETypeAnnotationKind::Optional;
+ level = data ? 1 : 0;
+ return ctx.WrapByCallableIf(kind != ETypeAnnotationKind::Stream, "ToStream", ctx.WrapByCallableIf(data, "Just", std::move(node)));
}
std::tuple<TString, TString> GetPathAndObjectId(const TString& path, const TString& objectId, const TString& md5) const {
@@ -474,21 +474,21 @@ private:
TUploadList* uploadList,
const TResult& result, TExprContext& ctx, bool hasGraphParams) const
{
- auto input = Build<TDqPhyStage>(ctx, result.Pos())
- .Inputs()
- .Build()
- .Program<TCoLambda>()
- .Args({})
- .Body(GetLambdaBody(*level, result.Input().Ptr(), ctx))
- .Build()
- .Settings().Build()
- .Done().Ptr();
-
+ auto input = Build<TDqPhyStage>(ctx, result.Pos())
+ .Inputs()
+ .Build()
+ .Program<TCoLambda>()
+ .Args({})
+ .Body(GetLambdaBody(*level, result.Input().Ptr(), ctx))
+ .Build()
+ .Settings().Build()
+ .Done().Ptr();
+
{
auto block = MeasureBlock("PeepHole");
bool hasNonDeterministicFunctions = false;
- if (const auto status = PeepHoleOptimizeNode<true>(input, input, ctx, *State->TypeCtx, nullptr, hasNonDeterministicFunctions); status.Level != TStatus::Ok) {
+ if (const auto status = PeepHoleOptimizeNode<true>(input, input, ctx, *State->TypeCtx, nullptr, hasNonDeterministicFunctions); status.Level != TStatus::Ok) {
return SyncStatus(status);
}
}
@@ -497,7 +497,7 @@ private:
TUserDataTable crutches = State->TypeCtx->UserDataStorageCrutches;
TUserDataTable files;
StartCounter("FreezeUsedFiles");
- if (const auto filesRes = NCommon::FreezeUsedFiles(*input, files, *State->TypeCtx, ctx, [](const TString&){return true;}, crutches); filesRes.first.Level != TStatus::Ok) {
+ if (const auto filesRes = NCommon::FreezeUsedFiles(*input, files, *State->TypeCtx, ctx, [](const TString&){return true;}, crutches); filesRes.first.Level != TStatus::Ok) {
if (filesRes.first.Level != TStatus::Error) {
YQL_LOG(DEBUG) << "Freezing files for " << input->Content() << " (UniqueId=" << input->UniqueId() << ")";
}
@@ -512,7 +512,7 @@ private:
{
auto block = MeasureBlock("BuildProgram");
- auto programLambda = TDqPhyStage(input).Program();
+ auto programLambda = TDqPhyStage(input).Program();
TVector<TExprBase> fakeReads;
auto paramsType = NDq::CollectParameters(programLambda, ctx);
@@ -656,13 +656,13 @@ private:
return lambdaResult;
}
- THashMap<ui32, ui32> allPublicIds;
+ THashMap<ui32, ui32> allPublicIds;
bool hasStageError = false;
VisitExpr(result.Ptr(), [&](const TExprNode::TPtr& node) {
const TExprBase expr(node);
if (expr.Maybe<TResFill>()) {
if (auto publicId = State->TypeCtx->TranslateOperationId(node->UniqueId())) {
- allPublicIds.emplace(*publicId, 0U);
+ allPublicIds.emplace(*publicId, 0U);
}
}
return true;
@@ -729,9 +729,9 @@ private:
if (res.Fallback) {
if (state->Settings->FallbackPolicy.Get().GetOrElse("default") == "never" || state->TypeCtx->ForceDq) {
- auto issues = TIssues{TIssue(ctx.GetPosition(input->Pos()), "Gateway Error").SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING)};
- issues.AddIssues(res.Issues);
- ctx.AssociativeIssues.emplace(input.Get(), std::move(issues));
+ auto issues = TIssues{TIssue(ctx.GetPosition(input->Pos()), "Gateway Error").SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING)};
+ issues.AddIssues(res.Issues);
+ ctx.AssociativeIssues.emplace(input.Get(), std::move(issues));
return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Error);
}
@@ -821,13 +821,13 @@ private:
}
}
- TStatusCallbackPair FallbackWithMessage(const TExprNode& node, const TString& message, TExprContext& ctx) {
+ TStatusCallbackPair FallbackWithMessage(const TExprNode& node, const TString& message, TExprContext& ctx) {
if (State->Metrics) {
State->Metrics->IncCounter("dq", "Fallback");
}
State->Statistics[State->MetricId++].Entries.push_back(TOperationStatistics::TEntry("Fallback", 0, 0, 0, 0, 1));
- auto issue = TIssue(ctx.GetPosition(node.Pos()), message).SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING);
- ctx.AssociativeIssues.emplace(&node, TIssues{std::move(issue)});
+ auto issue = TIssue(ctx.GetPosition(node.Pos()), message).SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING);
+ ctx.AssociativeIssues.emplace(&node, TIssues{std::move(issue)});
return SyncStatus(IGraphTransformer::TStatus(IGraphTransformer::TStatus::Error));
}
@@ -847,24 +847,24 @@ private:
const bool oneGraphPerQuery = State->Settings->_OneGraphPerQuery.Get().GetOrElse(false);
size_t graphsCount = 0;
- THashMap<ui32, ui32> allPublicIds;
+ THashMap<ui32, ui32> allPublicIds;
THashMap<ui64, ui32> stage2publicId;
bool hasStageError = false;
VisitExpr(pull.Ptr(), [&](const TExprNode::TPtr& node) {
- if (TResTransientBase::Match(node.Get()))
- return false;
- if (const TExprBase expr(node); expr.Maybe<TDqConnection>()) {
- if (const auto publicId = State->TypeCtx->TranslateOperationId(node->UniqueId())) {
- allPublicIds.emplace(*publicId, 0U);
+ if (TResTransientBase::Match(node.Get()))
+ return false;
+ if (const TExprBase expr(node); expr.Maybe<TDqConnection>()) {
+ if (const auto publicId = State->TypeCtx->TranslateOperationId(node->UniqueId())) {
+ allPublicIds.emplace(*publicId, 0U);
}
- } else if (const auto& maybeStage = expr.Maybe<TDqStage>()) {
+ } else if (const auto& maybeStage = expr.Maybe<TDqStage>()) {
const auto& stage = maybeStage.Cast();
if (!(stage.Ref().StartsExecution() || stage.Ref().HasResult())) {
- if (const auto publicId = State->TypeCtx->TranslateOperationId(node->UniqueId())) {
- if (const auto settings = NDq::TDqStageSettings::Parse(maybeStage.Cast()); settings.LogicalId) {
- stage2publicId[settings.LogicalId] = *publicId;
- }
- allPublicIds.emplace(*publicId, 0U);
+ if (const auto publicId = State->TypeCtx->TranslateOperationId(node->UniqueId())) {
+ if (const auto settings = NDq::TDqStageSettings::Parse(maybeStage.Cast()); settings.LogicalId) {
+ stage2publicId[settings.LogicalId] = *publicId;
+ }
+ allPublicIds.emplace(*publicId, 0U);
}
}
} else if (oneGraphPerQuery) {
@@ -888,7 +888,7 @@ private:
optimizedInput->SetTypeAnn(pull.Input().Ref().GetTypeAnn());
optimizedInput->CopyConstraints(pull.Input().Ref());
- TDqsPipelineConfigurator peepholeConfig;
+ TDqsPipelineConfigurator peepholeConfig;
TPeepholeSettings peepholeSettings;
peepholeSettings.CommonConfig = &peepholeConfig;
bool hasNonDeterministicFunctions;
@@ -923,8 +923,8 @@ private:
executionPlanner->SetPublicIds(stage2publicId);
auto settings = std::make_shared<TDqSettings>(*State->Settings);
- auto tasksPerStage = settings->MaxTasksPerStage.Get().GetOrElse(TDqSettings::TDefault::MaxTasksPerStage);
- const auto maxTasksPerOperation = State->Settings->MaxTasksPerOperation.Get().GetOrElse(TDqSettings::TDefault::MaxTasksPerOperation);
+ auto tasksPerStage = settings->MaxTasksPerStage.Get().GetOrElse(TDqSettings::TDefault::MaxTasksPerStage);
+ const auto maxTasksPerOperation = State->Settings->MaxTasksPerOperation.Get().GetOrElse(TDqSettings::TDefault::MaxTasksPerOperation);
auto maxDataSizePerJob = settings->MaxDataSizePerJob.Get().GetOrElse(TDqSettings::TDefault::MaxDataSizePerJob);
auto stagesCount = executionPlanner->StagesCount();
@@ -937,7 +937,7 @@ private:
if (stagesCount > maxTasksPerOperation && canFallback) {
return FallbackWithMessage(
- pull.Ref(),
+ pull.Ref(),
TStringBuilder()
<< "Too many stages: "
<< stagesCount << " > "
@@ -960,7 +960,7 @@ private:
bool fallbackFlag = false;
if (executionPlanner->MaxDataSizePerJob() > maxDataSizePerJob && canFallback) {
return FallbackWithMessage(
- pull.Ref(),
+ pull.Ref(),
TStringBuilder()
<< "MaxDataSizePerJob reached: "
<< executionPlanner->MaxDataSizePerJob() << " > "
@@ -971,7 +971,7 @@ private:
auto& tasks = executionPlanner->GetTasks();
if (tasks.size() > maxTasksPerOperation && canFallback) {
return FallbackWithMessage(
- pull.Ref(),
+ pull.Ref(),
TStringBuilder()
<< "Too many tasks: "
<< tasks.size() << " > "
@@ -990,27 +990,27 @@ private:
t.MutableProgram()->SetRaw(lambda);
Yql::DqsProto::TTaskMeta taskMeta;
- t.MutableMeta()->UnpackTo(&taskMeta);
+ t.MutableMeta()->UnpackTo(&taskMeta);
for (const auto& file : uploadList) {
*taskMeta.AddFiles() = file;
}
- t.MutableMeta()->PackFrom(taskMeta);
- if (const auto it = allPublicIds.find(taskMeta.GetStageId()); allPublicIds.cend() != it)
- ++it->second;
+ t.MutableMeta()->PackFrom(taskMeta);
+ if (const auto it = allPublicIds.find(taskMeta.GetStageId()); allPublicIds.cend() != it)
+ ++it->second;
}
}
MarkProgressStarted(allPublicIds, State->ProgressWriter);
if (fallbackFlag) {
- return FallbackWithMessage(pull.Ref(), "Too big attachment", ctx);
+ return FallbackWithMessage(pull.Ref(), "Too big attachment", ctx);
}
IDataProvider::TFillSettings fillSettings = NCommon::GetFillSettings(pull.Ref());
settings = settings->WithFillSettings(fillSettings);
if (const auto optLLVM = State->TypeCtx->OptLLVM) {
- settings->OptLLVM = *optLLVM;
+ settings->OptLLVM = *optLLVM;
}
auto graphParams = GatherGraphParams(optimizedInput);
@@ -1040,7 +1040,7 @@ private:
}
IDqGateway::TDqProgressWriter progressWriter = MakeDqProgressWriter(allPublicIds);
-
+
auto future = State->DqGateway->ExecutePlan(State->SessionId, *executionPlanner.Get(), columns, secureParams, graphParams,
settings, progressWriter, ModulesMapping, fillSettings.Discard);
@@ -1075,9 +1075,9 @@ private:
}
state->Statistics[state->MetricId++].Entries.push_back(TOperationStatistics::TEntry("Fallback", 0, 0, 0, 0, 1));
// never fallback will be captured in yql_facade
- auto issues = TIssues{TIssue(ctx.GetPosition(input->Pos()), "Gateway Error").SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING)};
- issues.AddIssues(res.Issues);
- ctx.AssociativeIssues.emplace(input.Get(), std::move(issues));
+ auto issues = TIssues{TIssue(ctx.GetPosition(input->Pos()), "Gateway Error").SetCode(TIssuesIds::DQ_GATEWAY_NEED_FALLBACK_ERROR, TSeverityIds::S_WARNING)};
+ issues.AddIssues(res.Issues);
+ ctx.AssociativeIssues.emplace(input.Get(), std::move(issues));
return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Error);
}
@@ -1171,39 +1171,39 @@ private:
}, "");
}
- IDqGateway::TDqProgressWriter MakeDqProgressWriter(const THashMap<ui32, ui32>& allPublicIds) const {
+ IDqGateway::TDqProgressWriter MakeDqProgressWriter(const THashMap<ui32, ui32>& allPublicIds) const {
IDqGateway::TDqProgressWriter dqProgressWriter = [progressWriter = State->ProgressWriter, allPublicIds](const TString& stage) {
for (const auto& publicId : allPublicIds) {
- auto p = TOperationProgress(TString(DqProviderName), publicId.first, TOperationProgress::EState::InProgress, stage);
- if (publicId.second) {
- p.Counters.ConstructInPlace();
- p.Counters->Running = p.Counters->Total = publicId.second;
- }
+ auto p = TOperationProgress(TString(DqProviderName), publicId.first, TOperationProgress::EState::InProgress, stage);
+ if (publicId.second) {
+ p.Counters.ConstructInPlace();
+ p.Counters->Running = p.Counters->Total = publicId.second;
+ }
progressWriter(p);
}
};
return dqProgressWriter;
}
- static void MarkProgressStarted(const THashMap<ui32, ui32>& allPublicIds, const TOperationProgressWriter& progressWriter) {
- for(const auto& publicId : allPublicIds) {
- auto p = TOperationProgress(TString(DqProviderName), publicId.first, TOperationProgress::EState::InProgress);
- if (publicId.second) {
- p.Counters.ConstructInPlace();
- p.Counters->Running = p.Counters->Total = publicId.second;
- }
+ static void MarkProgressStarted(const THashMap<ui32, ui32>& allPublicIds, const TOperationProgressWriter& progressWriter) {
+ for(const auto& publicId : allPublicIds) {
+ auto p = TOperationProgress(TString(DqProviderName), publicId.first, TOperationProgress::EState::InProgress);
+ if (publicId.second) {
+ p.Counters.ConstructInPlace();
+ p.Counters->Running = p.Counters->Total = publicId.second;
+ }
progressWriter(p);
}
}
- static void MarkProgressFinished(const THashMap<ui32, ui32>& allPublicIds, bool success, const TOperationProgressWriter& progressWriter) {
- for(const auto& publicId : allPublicIds) {
+ static void MarkProgressFinished(const THashMap<ui32, ui32>& allPublicIds, bool success, const TOperationProgressWriter& progressWriter) {
+ for(const auto& publicId : allPublicIds) {
auto state = success ? TOperationProgress::EState::Finished : TOperationProgress::EState::Failed;
- auto p = TOperationProgress(TString(DqProviderName), publicId.first, state);
- if (publicId.second) {
- p.Counters.ConstructInPlace();
- (success ? p.Counters->Completed : p.Counters->Failed) = p.Counters->Total = publicId.second;
- }
+ auto p = TOperationProgress(TString(DqProviderName), publicId.first, state);
+ if (publicId.second) {
+ p.Counters.ConstructInPlace();
+ (success ? p.Counters->Completed : p.Counters->Failed) = p.Counters->Total = publicId.second;
+ }
progressWriter(p);
}
}
@@ -1260,8 +1260,8 @@ private:
mutable THashMap<TString, TString> ModulesMapping;
};
-}
-
+}
+
IGraphTransformer* CreateInMemoryExecTransformer(const TDqStatePtr& state) {
return new TInMemoryExecTransformer(state);
}
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasink.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasink.cpp
index 6acb054a26..a8b5e598a0 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_datasink.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasink.cpp
@@ -211,7 +211,7 @@ public:
if (TDqConnection::Match(&node)) {
children.push_back(node.ChildPtr(TDqConnection::idx_Output)->ChildPtr(TDqOutput::idx_Stage));
- return false;
+ return false;
}
if (TDqStageBase::Match(&node)) {
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasink_type_ann.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasink_type_ann.cpp
index f25957aeff..c8d9786a7a 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_datasink_type_ann.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasink_type_ann.cpp
@@ -37,7 +37,7 @@ public:
}
private:
- TStatus AnnotateDqWrite(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ TStatus AnnotateDqWrite(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
if (!EnsureMinArgsCount(*input, 2, ctx)) {
return TStatus::Error;
}
@@ -46,7 +46,7 @@ private:
return TStatus::Error;
}
- if (!EnsureNewSeqType<false, false, true>(input->Head(), ctx)){
+ if (!EnsureNewSeqType<false, false, true>(input->Head(), ctx)){
return TStatus::Error;
}
@@ -54,16 +54,16 @@ private:
return TStatus::Error;
}
- auto providerName = TString(input->Child(1)->Content());
+ auto providerName = TString(input->Child(1)->Content());
- if (!TypeCtx->DataSinkMap.FindPtr(providerName)) {
+ if (!TypeCtx->DataSinkMap.FindPtr(providerName)) {
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "No datasink defined for provider name " << providerName));
return TStatus::Error;
}
- providerName.front() = std::toupper(providerName.front());
- output = ctx.NewCallable(input->Pos(), providerName += TDqWrite::CallableName(), {input->HeadPtr(), input->TailPtr()});
- return TStatus::Repeat;
+ providerName.front() = std::toupper(providerName.front());
+ output = ctx.NewCallable(input->Pos(), providerName += TDqWrite::CallableName(), {input->HeadPtr(), input->TailPtr()});
+ return TStatus::Repeat;
}
TTypeAnnotationContext* TypeCtx;
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
index f6f08ba8f5..aea55435de 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
@@ -73,25 +73,25 @@ public:
return {};
}
- TExprNode::TListType worlds;
- VisitExpr(node, [&worlds] (const TExprNode::TPtr& item) {
- if (ETypeAnnotationKind::World == item->GetTypeAnn()->GetKind()) {
- worlds.emplace_back(item);
- return false;
- }
- return true;
- });
-
- const auto newWorld = ctx.NewWorld(node->Pos());
- TNodeOnNodeOwnedMap replaces(worlds.size());
- for (const auto& w : worlds)
- replaces.emplace(w.Get(), newWorld);
-
+ TExprNode::TListType worlds;
+ VisitExpr(node, [&worlds] (const TExprNode::TPtr& item) {
+ if (ETypeAnnotationKind::World == item->GetTypeAnn()->GetKind()) {
+ worlds.emplace_back(item);
+ return false;
+ }
+ return true;
+ });
+
+ const auto newWorld = ctx.NewWorld(node->Pos());
+ TNodeOnNodeOwnedMap replaces(worlds.size());
+ for (const auto& w : worlds)
+ replaces.emplace(w.Get(), newWorld);
+
return Build<TDqCnResult>(ctx, node->Pos())
.Output()
.Stage<TDqStage>()
.Inputs()
- .Add(ctx.ReplaceNodes(TExprNode::TPtr(node), std::move(replaces)))
+ .Add(ctx.ReplaceNodes(TExprNode::TPtr(node), std::move(replaces)))
.Build()
.Program()
.Args({"row"})
@@ -108,9 +108,9 @@ public:
bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
if (!TDqCnUnionAll::Match(&node)) {
- return false;
+ return false;
}
-
+
if (auto type = GetItemType(*node.GetTypeAnn()); !type || type->GetKind() != ETypeAnnotationKind::Struct) {
return false;
}
@@ -124,15 +124,15 @@ public:
}
}
- for (const auto& child : node.ChildrenList())
- VisitExpr(child, [&syncList] (const TExprNode::TPtr& item) {
- if (ETypeAnnotationKind::World == item->GetTypeAnn()->GetKind()) {
- syncList.emplace(item, syncList.size());
- return false;
- }
- return true;
- });
- return true;
+ for (const auto& child : node.ChildrenList())
+ VisitExpr(child, [&syncList] (const TExprNode::TPtr& item) {
+ if (ETypeAnnotationKind::World == item->GetTypeAnn()->GetKind()) {
+ syncList.emplace(item, syncList.size());
+ return false;
+ }
+ return true;
+ });
+ return true;
}
bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasource_type_ann.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasource_type_ann.cpp
index ffbf8676bb..6e03017ccb 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_datasource_type_ann.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasource_type_ann.cpp
@@ -18,21 +18,21 @@ public:
TDqsDataSourceTypeAnnotationTransformer()
: TVisitorTransformerBase(true)
{
- AddHandler({TDqSourceWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleSourceWrap<false>));
- AddHandler({TDqSourceWideWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleSourceWrap<true>));
- AddHandler({TDqReadWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleReadWrap));
- AddHandler({TDqReadWideWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleWideReadWrap));
+ AddHandler({TDqSourceWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleSourceWrap<false>));
+ AddHandler({TDqSourceWideWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleSourceWrap<true>));
+ AddHandler({TDqReadWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleReadWrap));
+ AddHandler({TDqReadWideWrap::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleWideReadWrap));
AddHandler({TCoConfigure::CallableName()}, Hndl(&TDqsDataSourceTypeAnnotationTransformer::HandleConfig));
AddHandler({TDqSource::CallableName()}, Hndl(&NDq::AnnotateDqSource));
}
private:
TStatus HandleReadWrap(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 3, ctx)) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 3, ctx)) {
return TStatus::Error;
}
- if (input->ChildrenSize() > TDqReadWrapBase::idx_Token) {
+ if (input->ChildrenSize() > TDqReadWrapBase::idx_Token) {
if (!EnsureCallable(*input->Child(TDqReadWrapBase::idx_Token), ctx)) {
return TStatus::Error;
}
@@ -43,100 +43,100 @@ private:
}
}
- if (input->ChildrenSize() > TDqReadWrapBase::idx_Flags && !EnsureTupleOfAtoms(*input->Child(TDqReadWrapBase::idx_Flags), ctx)) {
- return TStatus::Error;
- }
-
+ if (input->ChildrenSize() > TDqReadWrapBase::idx_Flags && !EnsureTupleOfAtoms(*input->Child(TDqReadWrapBase::idx_Flags), ctx)) {
+ return TStatus::Error;
+ }
+
if (!EnsureTupleTypeSize(input->Head(), 2, ctx)) {
return TStatus::Error;
}
- const auto readerType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
+ const auto readerType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
if (!EnsureListType(input->Head().Pos(), *readerType, ctx)) {
return TStatus::Error;
}
- input->SetTypeAnn(readerType);
+ input->SetTypeAnn(readerType);
+ return TStatus::Ok;
+ }
+
+ template<bool Wide>
+ TStatus HandleSourceWrap(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 3U, 4U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureNewSeqType<false>(input->Head(), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureDataSource(*input->Child(TDqSourceWrapBase::idx_DataSource), ctx)) {
+ return TStatus::Error;
+ }
+
+ const auto& rowType = *input->Child(TDqSourceWrapBase::idx_RowType);
+ if (!EnsureType(rowType, ctx)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto type = input->Child(TDqSourceWrapBase::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ if (!EnsureStructType(rowType.Pos(), *type, ctx)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TDqSourceWrapBase::idx_Settings && !EnsureTuple(*input->Child(TDqSourceWrapBase::idx_Settings), ctx)) {
+ return TStatus::Error;
+ }
+
+ if constexpr (Wide) {
+ const auto& items = type->Cast<TStructExprType>()->GetItems();
+ TTypeAnnotationNode::TListType types;
+ types.reserve(items.size());
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(types), std::bind(&TItemExprType::GetItemType, std::placeholders::_1));
+ input->SetTypeAnn(ctx.MakeType<TFlowExprType>(ctx.MakeType<TMultiExprType>(types)));
+ } else {
+ input->SetTypeAnn(ctx.MakeType<TListExprType>(input->Child(TDqSourceWrapBase::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()));
+ }
+
+ return TStatus::Ok;
+ }
+
+ TStatus HandleWideReadWrap(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1, 3, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TDqReadWrapBase::idx_Token) {
+ if (!EnsureCallable(*input->Child(TDqReadWrapBase::idx_Token), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!TCoSecureParam::Match(input->Child(TDqReadWrapBase::idx_Token))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Child(TDqReadWrapBase::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
+ return TStatus::Error;
+ }
+ }
+
+ if (input->ChildrenSize() > TDqReadWrapBase::idx_Flags && !EnsureTupleOfAtoms(*input->Child(TDqReadWrapBase::idx_Flags), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureTupleTypeSize(input->Head(), 2, ctx)) {
+ return TStatus::Error;
+ }
+ const auto readerType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
+ if (!EnsureListType(input->Head().Pos(), *readerType, ctx)) {
+ return TStatus::Error;
+ }
+
+ const auto structType = readerType->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
+ TTypeAnnotationNode::TListType types;
+ const auto& items = structType->GetItems();
+ types.reserve(items.size());
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(types), std::bind(&TItemExprType::GetItemType, std::placeholders::_1));
+
+ input->SetTypeAnn(ctx.MakeType<TFlowExprType>(ctx.MakeType<TMultiExprType>(types)));
return TStatus::Ok;
}
- template<bool Wide>
- TStatus HandleSourceWrap(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 3U, 4U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureNewSeqType<false>(input->Head(), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureDataSource(*input->Child(TDqSourceWrapBase::idx_DataSource), ctx)) {
- return TStatus::Error;
- }
-
- const auto& rowType = *input->Child(TDqSourceWrapBase::idx_RowType);
- if (!EnsureType(rowType, ctx)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- const auto type = input->Child(TDqSourceWrapBase::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- if (!EnsureStructType(rowType.Pos(), *type, ctx)) {
- return IGraphTransformer::TStatus::Error;
- }
-
- if (input->ChildrenSize() > TDqSourceWrapBase::idx_Settings && !EnsureTuple(*input->Child(TDqSourceWrapBase::idx_Settings), ctx)) {
- return TStatus::Error;
- }
-
- if constexpr (Wide) {
- const auto& items = type->Cast<TStructExprType>()->GetItems();
- TTypeAnnotationNode::TListType types;
- types.reserve(items.size());
- std::transform(items.cbegin(), items.cend(), std::back_inserter(types), std::bind(&TItemExprType::GetItemType, std::placeholders::_1));
- input->SetTypeAnn(ctx.MakeType<TFlowExprType>(ctx.MakeType<TMultiExprType>(types)));
- } else {
- input->SetTypeAnn(ctx.MakeType<TListExprType>(input->Child(TDqSourceWrapBase::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()));
- }
-
- return TStatus::Ok;
- }
-
- TStatus HandleWideReadWrap(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1, 3, ctx)) {
- return TStatus::Error;
- }
-
- if (input->ChildrenSize() > TDqReadWrapBase::idx_Token) {
- if (!EnsureCallable(*input->Child(TDqReadWrapBase::idx_Token), ctx)) {
- return TStatus::Error;
- }
-
- if (!TCoSecureParam::Match(input->Child(TDqReadWrapBase::idx_Token))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Child(TDqReadWrapBase::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
- return TStatus::Error;
- }
- }
-
- if (input->ChildrenSize() > TDqReadWrapBase::idx_Flags && !EnsureTupleOfAtoms(*input->Child(TDqReadWrapBase::idx_Flags), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureTupleTypeSize(input->Head(), 2, ctx)) {
- return TStatus::Error;
- }
- const auto readerType = input->Head().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
- if (!EnsureListType(input->Head().Pos(), *readerType, ctx)) {
- return TStatus::Error;
- }
-
- const auto structType = readerType->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
- TTypeAnnotationNode::TListType types;
- const auto& items = structType->GetItems();
- types.reserve(items.size());
- std::transform(items.cbegin(), items.cend(), std::back_inserter(types), std::bind(&TItemExprType::GetItemType, std::placeholders::_1));
-
- input->SetTypeAnn(ctx.MakeType<TFlowExprType>(ctx.MakeType<TMultiExprType>(types)));
- return TStatus::Ok;
- }
-
TStatus HandleConfig(const TExprNode::TPtr& input, TExprContext& ctx) {
if (!EnsureMinArgsCount(*input, 2, ctx)) {
return TStatus::Error;
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_gateway.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_gateway.cpp
index 3f2e4546e7..2341b28ad4 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_gateway.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_gateway.cpp
@@ -292,12 +292,12 @@ public:
modulesMapping);
}
- NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) override {
+ NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) override {
YQL_LOG_CTX_SCOPE(sessionId);
YQL_CLOG(INFO, ProviderDq) << "OpenSession";
Yql::DqsProto::OpenSessionRequest request;
request.SetSession(sessionId);
- request.SetUsername(username);
+ request.SetUsername(username);
NGrpc::TCallMeta meta;
meta.Timeout = OpenSessionTimeout;
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_gateway.h b/ydb/library/yql/providers/dq/provider/yql_dq_gateway.h
index 090d50af37..d562776033 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_gateway.h
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_gateway.h
@@ -59,7 +59,7 @@ public:
virtual ~IDqGateway() = default;
- virtual NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) = 0;
+ virtual NThreading::TFuture<void> OpenSession(const TString& sessionId, const TString& username) = 0;
virtual void CloseSession(const TString& sessionId) = 0;
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_provider.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_provider.cpp
index 9a2ec39ec5..69788c5c76 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_provider.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_provider.cpp
@@ -77,7 +77,7 @@ TDataProviderInitializer GetDqDataProviderInitializer(
if (dqGateway) { // nullptr in yqlrun
auto t = TInstant::Now();
YQL_LOG(DEBUG) << "OpenSession " << sessionId;
- auto future = dqGateway->OpenSession(sessionId, username);
+ auto future = dqGateway->OpenSession(sessionId, username);
future.Subscribe([sessionId, t] (const auto& ) {
YQL_LOG(DEBUG) << "OpenSession " << sessionId << " complete in " << (TInstant::Now()-t).MilliSeconds();
});
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_recapture.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_recapture.cpp
index c917d4055c..90e8af759c 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_recapture.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_recapture.cpp
@@ -21,9 +21,9 @@ using namespace NNodes;
namespace {
-const THashSet<TStringBuf> VALID_SOURCES = {DqProviderName, ConfigProviderName, YtProviderName, ClickHouseProviderName, YdbProviderName};
+const THashSet<TStringBuf> VALID_SOURCES = {DqProviderName, ConfigProviderName, YtProviderName, ClickHouseProviderName, YdbProviderName};
const THashSet<TStringBuf> VALID_SINKS = {ResultProviderName, YtProviderName};
-const THashSet<TStringBuf> UNSUPPORTED_CALLABLE = { TCoForwardList::CallableName() };
+const THashSet<TStringBuf> UNSUPPORTED_CALLABLE = { TCoForwardList::CallableName() };
}
@@ -104,7 +104,7 @@ public:
auto dataSource = State_->TypeCtx->DataSourceMap.FindPtr(dataSourceName);
YQL_ENSURE(dataSource);
if (auto dqIntegration = (*dataSource)->GetDqIntegration()) {
- auto newRead = dqIntegration->WrapRead(*State_->Settings, maybeRead.Cast().Ptr(), ctx);
+ auto newRead = dqIntegration->WrapRead(*State_->Settings, maybeRead.Cast().Ptr(), ctx);
if (newRead.Get() != maybeRead.Raw()) {
return newRead;
}
@@ -154,7 +154,7 @@ private:
} else if (node.IsCallable(UNSUPPORTED_CALLABLE)) {
AddInfo(ctx, TStringBuilder() << "unsupported callable '" << node.Content() << "'");
good = false;
- } else if (node.IsCallable(TCoCollect::CallableName())) {
+ } else if (node.IsCallable(TCoCollect::CallableName())) {
if (ETypeAnnotationKind::List != node.Head().GetTypeAnn()->GetKind()) {
AddInfo(ctx, TStringBuilder() << "unsupported callable '" << node.Content() << "' over stream/flow");
good = false;
@@ -181,7 +181,7 @@ private:
auto datasource = State_->TypeCtx->DataSourceMap.FindPtr(dataSourceName);
YQL_ENSURE(datasource);
if (auto dqIntegration = (*datasource)->GetDqIntegration()) {
- if (auto size = dqIntegration->CanRead(*State_->Settings, node, ctx, /*skipIssues = */ false)) {
+ if (auto size = dqIntegration->CanRead(*State_->Settings, node, ctx, /*skipIssues = */ false)) {
dataSize += *size;
} else {
good = false;
diff --git a/ydb/library/yql/providers/dq/service/grpc_service.cpp b/ydb/library/yql/providers/dq/service/grpc_service.cpp
index 1d982131fc..65a9e500d9 100644
--- a/ydb/library/yql/providers/dq/service/grpc_service.cpp
+++ b/ydb/library/yql/providers/dq/service/grpc_service.cpp
@@ -74,7 +74,7 @@ namespace NYql::NDqs {
, ErrorCounter(ServiceProxyActorCounters->GetCounter("UnrecoverableError", /*derivative=*/ true))
, Request(dynamic_cast<const RequestType*>(ctx->GetRequest()))
, TraceId(traceId)
- , Username(username)
+ , Username(username)
, Promise(NewPromise<void>())
{
Settings->Dispatch(Request->GetSettings());
@@ -233,7 +233,7 @@ namespace NYql::NDqs {
const RequestType* Request;
const TString TraceId;
- const TString Username;
+ const TString Username;
TPromise<void> Promise;
const TInstant RequestStartTime = TInstant::Now();
diff --git a/ydb/library/yql/providers/dq/task_runner/tasks_runner_local.cpp b/ydb/library/yql/providers/dq/task_runner/tasks_runner_local.cpp
index 06a3777b28..ab8769f44e 100644
--- a/ydb/library/yql/providers/dq/task_runner/tasks_runner_local.cpp
+++ b/ydb/library/yql/providers/dq/task_runner/tasks_runner_local.cpp
@@ -263,9 +263,9 @@ public:
task.GetMeta().UnpackTo(&taskMeta);
for (const auto& s : taskMeta.GetSettings()) {
- if ("OptLLVM" == s.GetName())
- settings.OptLLVM = s.GetValue();
- }
+ if ("OptLLVM" == s.GetName())
+ settings.OptLLVM = s.GetValue();
+ }
for (const auto& x : taskMeta.GetSecureParams()) {
settings.SecureParams[x.first] = x.second;
}
diff --git a/ydb/library/yql/providers/dq/worker_manager/interface/events.cpp b/ydb/library/yql/providers/dq/worker_manager/interface/events.cpp
index 6a9a93520a..9044dc47e3 100644
--- a/ydb/library/yql/providers/dq/worker_manager/interface/events.cpp
+++ b/ydb/library/yql/providers/dq/worker_manager/interface/events.cpp
@@ -8,11 +8,11 @@ namespace NYql::NCommonAttrs {
namespace NYql::NDqs {
TEvAllocateWorkersRequest::TEvAllocateWorkersRequest(
ui32 count,
- const TString& user,
+ const TString& user,
const TMaybe<ui64>& globalResourceId)
{
Record.SetCount(count);
- Record.SetUser(user);
+ Record.SetUser(user);
if (globalResourceId) {
Record.SetResourceId(*globalResourceId);
}
diff --git a/ydb/library/yql/providers/dq/worker_manager/interface/events.h b/ydb/library/yql/providers/dq/worker_manager/interface/events.h
index bcc70420a5..a2d0c9f540 100644
--- a/ydb/library/yql/providers/dq/worker_manager/interface/events.h
+++ b/ydb/library/yql/providers/dq/worker_manager/interface/events.h
@@ -23,7 +23,7 @@ using TDqResManEvents = NDq::TBaseDqResManEvents<NActors::TEvents::EEventSpace::
explicit TEvAllocateWorkersRequest(
ui32 count,
- const TString& user,
+ const TString& user,
const TMaybe<ui64>& globalResourceId = TMaybe<ui64>());
};
diff --git a/ydb/library/yql/providers/pq/provider/yql_pq_dq_integration.cpp b/ydb/library/yql/providers/pq/provider/yql_pq_dq_integration.cpp
index 00ab0e4fa6..ea67ffd422 100644
--- a/ydb/library/yql/providers/pq/provider/yql_pq_dq_integration.cpp
+++ b/ydb/library/yql/providers/pq/provider/yql_pq_dq_integration.cpp
@@ -68,7 +68,7 @@ public:
return 0;
}
- TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
+ TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
if (const auto& maybePqReadTopic = TMaybeNode<TPqReadTopic>(read)) {
const auto& pqReadTopic = maybePqReadTopic.Cast();
diff --git a/ydb/library/yql/providers/result/provider/yql_result_provider.cpp b/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
index 4230160499..13bfd5e0f7 100644
--- a/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
+++ b/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
@@ -194,23 +194,23 @@ namespace {
class TResultCallableExecutionTransformer : public TGraphTransformerBase {
public:
- TResultCallableExecutionTransformer(const TIntrusivePtr<TResultProviderConfig>& config)
+ TResultCallableExecutionTransformer(const TIntrusivePtr<TResultProviderConfig>& config)
: Config(config)
{
YQL_ENSURE(!Config->Types.AvailablePureResultDataSources.empty());
}
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
TString uniqId = TStringBuilder() << '#' << input->UniqueId();
YQL_LOG_CTX_SCOPE(uniqId);
- YQL_ENSURE(input->Type() == TExprNode::Callable);
+ YQL_ENSURE(input->Type() == TExprNode::Callable);
TExprBase node(input);
if (node.Maybe<TResFill>() || node.Maybe<TResPull>() || node.Maybe<TResIf>() || node.Maybe<TResFor>()) {
auto provider = Config->Types.DataSourceMap.FindPtr(input->Child(5)->Content());
- Y_ENSURE(provider, "DataSource not exist: " << input->Child(5)->Content());
+ Y_ENSURE(provider, "DataSource not exist: " << input->Child(5)->Content());
if (node.Maybe<TResPull>()) {
return HandleFillOrPull<TPull>(node, output, ctx, *(*provider));
} else {
@@ -218,7 +218,7 @@ namespace {
}
}
- if (input->Content() == CommitName) {
+ if (input->Content() == CommitName) {
if (ResultWriter) {
TExprBase commitChild(input->ChildPtr(0));
@@ -235,7 +235,7 @@ namespace {
}
input->SetState(TExprNode::EState::ExecutionComplete);
- input->SetResult(ctx.NewWorld (input->Pos()));
+ input->SetResult(ctx.NewWorld (input->Pos()));
return TStatus::Ok;
}
@@ -256,9 +256,9 @@ namespace {
}
TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
+ output = input;
auto status = DelegatedProvider->GetCallableExecutionTransformer()
- .ApplyAsyncChanges(DelegatedNode, DelegatedNodeOutput, ctx);
+ .ApplyAsyncChanges(DelegatedNode, DelegatedNodeOutput, ctx);
if (status == TStatus::Repeat && input != DelegatedNodeOutput->TailPtr()) {
output = DelegatedNodeOutput->TailPtr();
} else {
@@ -313,11 +313,11 @@ namespace {
auto total = FromString<ui32>(forNode.Total().Value());
auto current = FromString<ui32>(forNode.Current().Value());
if ((current > total) || (total && current >= total)) {
- auto zero = ctx.NewAtom(TPositionHandle(), "0", TNodeFlags::Default);
+ auto zero = ctx.NewAtom(TPositionHandle(), "0", TNodeFlags::Default);
zero->SetTypeAnn(ctx.MakeType<TUnitExprType>());
zero->SetState(TExprNode::EState::ConstrComplete);
- zero->SetDependencyScope(nullptr, nullptr); // HOTFIX for CSEE
- input.Ptr()->ChildRef(TResFor::idx_Current) = std::move(zero); //FIXME: Don't use ChilfRef
+ zero->SetDependencyScope(nullptr, nullptr); // HOTFIX for CSEE
+ input.Ptr()->ChildRef(TResFor::idx_Current) = std::move(zero); //FIXME: Don't use ChilfRef
input.Ptr()->SetResult(ctx.NewWorld(input.Pos()));
input.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
return TStatus::Ok;
@@ -330,7 +330,7 @@ namespace {
if (total == 0) {
// use else block
const auto& elseLambda = forNode.Else();
- active = ctx.ReplaceNode(elseLambda.Body().Ptr(), elseLambda.Args().Arg(0).Ref(), forNode.World().Ptr());
+ active = ctx.ReplaceNode(elseLambda.Body().Ptr(), elseLambda.Args().Arg(0).Ref(), forNode.World().Ptr());
} else {
// use some list item
auto listNode = items.Raw();
@@ -345,9 +345,9 @@ namespace {
auto listElem = listNode->Child(index);
const auto& iterLambda = forNode.Iter();
- active = ctx.ReplaceNodes(iterLambda.Body().Ptr(), { {
+ active = ctx.ReplaceNodes(iterLambda.Body().Ptr(), { {
iterLambda.Args().Arg(0).Raw(), forNode.World().Ptr()
- }, { iterLambda.Args().Arg(1).Raw(), listElem } });
+ }, { iterLambda.Args().Arg(1).Raw(), listElem } });
}
output = Build<TResFor>(ctx, forNode.Pos())
@@ -552,7 +552,7 @@ namespace {
DelegatedNode->Child(idx)->SetState(TExprNode::EState::ConstrComplete);
}
- DelegatedNode->SetTypeAnn(input.Ref().GetTypeAnn());
+ DelegatedNode->SetTypeAnn(input.Ref().GetTypeAnn());
DelegatedNode->SetState(TExprNode::EState::ConstrComplete);
input.Ptr()->SetState(TExprNode::EState::ExecutionInProgress);
auto status = DelegatedProvider->GetCallableExecutionTransformer().Transform(DelegatedNode, DelegatedNodeOutput, ctx);
@@ -565,7 +565,7 @@ namespace {
void FinishNode(TExprNode& input, TExprContext& ctx, IGraphTransformer::TStatus status) {
if (status.Level == TStatus::Ok) {
- auto data = DelegatedNode->GetResult().Content();
+ auto data = DelegatedNode->GetResult().Content();
const bool needWriter = input.Content() != TResIf::CallableName()
&& input.Content() != TResFor::CallableName();
if (needWriter) {
@@ -577,11 +577,11 @@ namespace {
input.SetResult(ctx.NewAtom(input.Pos(), data));
input.SetState(TExprNode::EState::ExecutionRequired);
}
- } else if (status.Level == TStatus::Error) {
- if (const auto issies = ctx.AssociativeIssues.extract(DelegatedNode.Get())) {
- ctx.IssueManager.RaiseIssues(issies.mapped());
- }
- } else {
+ } else if (status.Level == TStatus::Error) {
+ if (const auto issies = ctx.AssociativeIssues.extract(DelegatedNode.Get())) {
+ ctx.IssueManager.RaiseIssues(issies.mapped());
+ }
+ } else {
input.SetState(TExprNode::EState::ExecutionRequired);
}
@@ -593,8 +593,8 @@ namespace {
private:
const TIntrusivePtr<TResultProviderConfig> Config;
IDataProvider* DelegatedProvider = nullptr;
- TExprNode::TPtr DelegatedNode;
- TExprNode::TPtr DelegatedNodeOutput;
+ TExprNode::TPtr DelegatedNode;
+ TExprNode::TPtr DelegatedNodeOutput;
ui64 CommittedPullSize = 0;
bool PullOverflow = false;
@@ -873,7 +873,7 @@ namespace {
}
};
- TResultProvider(const TIntrusivePtr<TResultProviderConfig>& config)
+ TResultProvider(const TIntrusivePtr<TResultProviderConfig>& config)
: Config(config)
, TrackableNodeProcessor(config)
{}
@@ -904,7 +904,7 @@ namespace {
if (!TypeAnnotationTransformer) {
TypeAnnotationTransformer = CreateFunctorTransformer(
[&](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx)->IGraphTransformer::TStatus {
- output = input;
+ output = input;
if (auto maybeRes = TMaybeNode<TResWriteBase>(input)) {
auto res = maybeRes.Cast();
@@ -1086,7 +1086,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
else if (auto maybeIf = TMaybeNode<TResIf>(input)) {
- if (!EnsureArgsCount(*input, 7, ctx)) {
+ if (!EnsureArgsCount(*input, 7, ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1316,9 +1316,9 @@ namespace {
return *TypeAnnotationTransformer;
}
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
auto ret = node;
- if (node->Content() == WriteName) {
+ if (node->Content() == WriteName) {
ret = ctx.RenameNode(*ret, TResWrite::CallableName());
ret = ctx.ChangeChild(*ret, TResWrite::idx_Data,
ctx.Builder(node->Pos())
@@ -1373,7 +1373,7 @@ namespace {
IGraphTransformer& GetCallableExecutionTransformer() override {
if (!CallableExecutionTransformer) {
- CallableExecutionTransformer = new TResultCallableExecutionTransformer(Config);
+ CallableExecutionTransformer = new TResultCallableExecutionTransformer(Config);
}
return *CallableExecutionTransformer;
@@ -1389,7 +1389,7 @@ namespace {
bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
if (CanExecute(node)) {
- children.push_back(node.ChildPtr(0));
+ children.push_back(node.ChildPtr(0));
if (auto resPull = TMaybeNode<TResPull>(&node)) {
children.push_back(resPull.Cast().Data().Ptr());
} else if (auto resIf = TMaybeNode<TResIf>(&node)) {
@@ -1465,8 +1465,8 @@ TIntrusivePtr<IResultWriter> CreateYsonResultWriter(NYson::EYsonFormat format) {
return MakeIntrusive<TYsonResultWriter>(format);
}
-TIntrusivePtr<IDataProvider> CreateResultProvider(const TIntrusivePtr<TResultProviderConfig>& config) {
- return new TResultProvider(config);
+TIntrusivePtr<IDataProvider> CreateResultProvider(const TIntrusivePtr<TResultProviderConfig>& config) {
+ return new TResultProvider(config);
}
const THashSet<TStringBuf>& ResultProviderFunctions() {
diff --git a/ydb/library/yql/providers/result/provider/yql_result_provider.h b/ydb/library/yql/providers/result/provider/yql_result_provider.h
index 1a6423dc92..ee5bb5a9f6 100644
--- a/ydb/library/yql/providers/result/provider/yql_result_provider.h
+++ b/ydb/library/yql/providers/result/provider/yql_result_provider.h
@@ -43,7 +43,7 @@ struct TResultProviderConfig : TThrRefBase {
bool SupportsResultPosition = false;
};
-TIntrusivePtr<IDataProvider> CreateResultProvider(const TIntrusivePtr<TResultProviderConfig>& config);
+TIntrusivePtr<IDataProvider> CreateResultProvider(const TIntrusivePtr<TResultProviderConfig>& config);
const THashSet<TStringBuf>& ResultProviderFunctions();
}
diff --git a/ydb/library/yql/providers/s3/actors/ya.make b/ydb/library/yql/providers/s3/actors/ya.make
index 3850aae9d2..e23702313d 100644
--- a/ydb/library/yql/providers/s3/actors/ya.make
+++ b/ydb/library/yql/providers/s3/actors/ya.make
@@ -1,24 +1,24 @@
-LIBRARY()
-
-OWNER(
+LIBRARY()
+
+OWNER(
g:yq
- g:yql
-)
-
-SRCS(
- yql_s3_read_actor.cpp
- yql_s3_source_factory.cpp
-)
-
-PEERDIR(
+ g:yql
+)
+
+SRCS(
+ yql_s3_read_actor.cpp
+ yql_s3_source_factory.cpp
+)
+
+PEERDIR(
ydb/library/yql/minikql/computation
ydb/library/yql/providers/common/token_accessor/client
ydb/library/yql/public/types
ydb/library/yql/dq/actors/compute
ydb/library/yql/providers/common/http_gateway
ydb/library/yql/providers/s3/proto
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.cpp b/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.cpp
index db4169ea88..eb5410a24e 100644
--- a/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.cpp
+++ b/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.cpp
@@ -1,58 +1,58 @@
-#include "yql_s3_read_actor.h"
-
+#include "yql_s3_read_actor.h"
+
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/utils/yql_panic.h>
#include <ydb/library/yql/providers/s3/proto/range.pb.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/core/hfunc.h>
-
-#include <queue>
-
-namespace NYql::NDq {
-
-using namespace NActors;
-
-namespace {
-
-struct TEvPrivate {
- // Event ids
- enum EEv : ui32 {
- EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
-
- EvReadResult = EvBegin,
- EvReadError,
+
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/events.h>
+#include <library/cpp/actors/core/event_local.h>
+#include <library/cpp/actors/core/hfunc.h>
+
+#include <queue>
+
+namespace NYql::NDq {
+
+using namespace NActors;
+
+namespace {
+
+struct TEvPrivate {
+ // Event ids
+ enum EEv : ui32 {
+ EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
+
+ EvReadResult = EvBegin,
+ EvReadError,
EvRetry,
-
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- // Events
- struct TEvReadResult : public TEventLocal<TEvReadResult, EvReadResult> {
- TEvReadResult(IHTTPGateway::TContent&& result): Result(std::move(result)) {}
- IHTTPGateway::TContent Result;
- };
-
- struct TEvReadError : public TEventLocal<TEvReadError, EvReadError> {
+
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ // Events
+ struct TEvReadResult : public TEventLocal<TEvReadResult, EvReadResult> {
+ TEvReadResult(IHTTPGateway::TContent&& result): Result(std::move(result)) {}
+ IHTTPGateway::TContent Result;
+ };
+
+ struct TEvReadError : public TEventLocal<TEvReadError, EvReadError> {
TEvReadError(TIssues&& error, size_t pathInd): Error(std::move(error)), PathIndex(pathInd) {}
- TIssues Error;
+ TIssues Error;
size_t PathIndex = 0;
- };
+ };
struct TEvRetryEvent : public NActors::TEventLocal<TEvRetryEvent, EvRetry> {
explicit TEvRetryEvent(size_t pathIndex) : PathIndex(pathIndex) {}
size_t PathIndex = 0;
};
-};
-
-} // namespace
-
-class TS3ReadActor : public TActorBootstrapped<TS3ReadActor>, public IDqSourceActor {
+};
+
+} // namespace
+
+class TS3ReadActor : public TActorBootstrapped<TS3ReadActor>, public IDqSourceActor {
private:
class TRetryParams {
public:
@@ -84,33 +84,33 @@ private:
TDuration DelayMs = TDuration::MilliSeconds(100);
double Epsilon = 0.1;
};
-public:
-using TPath = std::tuple<TString, size_t>;
-using TPathList = std::vector<TPath>;
-
- TS3ReadActor(ui64 inputIndex,
- IHTTPGateway::TPtr gateway,
- const TString& url,
- const TString& token,
- TPathList&& paths,
+public:
+using TPath = std::tuple<TString, size_t>;
+using TPathList = std::vector<TPath>;
+
+ TS3ReadActor(ui64 inputIndex,
+ IHTTPGateway::TPtr gateway,
+ const TString& url,
+ const TString& token,
+ TPathList&& paths,
ICallbacks* callbacks,
const std::shared_ptr<NS3::TRetryConfig>& retryConfig
- ) : Gateway(std::move(gateway))
- , InputIndex(inputIndex)
- , Callbacks(callbacks)
- , ActorSystem(TActivationContext::ActorSystem())
- , Url(url)
- , Headers(MakeHeader(token))
- , Paths(std::move(paths))
+ ) : Gateway(std::move(gateway))
+ , InputIndex(inputIndex)
+ , Callbacks(callbacks)
+ , ActorSystem(TActivationContext::ActorSystem())
+ , Url(url)
+ , Headers(MakeHeader(token))
+ , Paths(std::move(paths))
, RetryConfig(retryConfig)
{
if (RetryConfig) {
MaxRetriesPerPath = RetryConfig->GetMaxRetriesPerPath() ? RetryConfig->GetMaxRetriesPerPath() : MaxRetriesPerPath;
}
}
-
- void Bootstrap() {
- Become(&TS3ReadActor::StateFunc);
+
+ void Bootstrap() {
+ Become(&TS3ReadActor::StateFunc);
RetriesPerPath.resize(Paths.size(), TRetryParams(RetryConfig));
for (size_t pathInd = 0; pathInd < Paths.size(); ++pathInd) {
const TPath& path = Paths[pathInd];
@@ -118,62 +118,62 @@ using TPathList = std::vector<TPath>;
Headers, std::get<size_t>(path),
std::bind(&TS3ReadActor::OnDownloadFinished, ActorSystem, SelfId(), std::placeholders::_1, pathInd));
};
- }
+ }
static constexpr char ActorName[] = "S3_READ_ACTOR";
-private:
+private:
void SaveState(const NDqProto::TCheckpoint&, NDqProto::TSourceState&) final {}
void LoadState(const NDqProto::TSourceState&) final {}
- void CommitState(const NDqProto::TCheckpoint&) final {}
- ui64 GetInputIndex() const final { return InputIndex; }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvPrivate::TEvReadResult, Handle);
- hFunc(TEvPrivate::TEvReadError, Handle);
+ void CommitState(const NDqProto::TCheckpoint&) final {}
+ ui64 GetInputIndex() const final { return InputIndex; }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvPrivate::TEvReadResult, Handle);
+ hFunc(TEvPrivate::TEvReadError, Handle);
hFunc(TEvPrivate::TEvRetryEvent, HandleRetry);
- )
-
+ )
+
static void OnDownloadFinished(TActorSystem* actorSystem, TActorId selfId, IHTTPGateway::TResult&& result, size_t pathInd) {
- switch (result.index()) {
- case 0U:
- actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadResult(std::get<IHTTPGateway::TContent>(std::move(result)))));
- return;
- case 1U:
+ switch (result.index()) {
+ case 0U:
+ actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadResult(std::get<IHTTPGateway::TContent>(std::move(result)))));
+ return;
+ case 1U:
actorSystem->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvReadError(std::get<TIssues>(std::move(result)), pathInd)));
- return;
- default:
- break;
- }
- }
-
- i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
- i64 total = 0LL;
- if (!Blocks.empty()) {
- buffer.reserve(buffer.size() + Blocks.size());
- do {
- const auto size = Blocks.front().size();
- buffer.emplace_back(NKikimr::NMiniKQL::MakeString(std::string_view(Blocks.front())));
- Blocks.pop();
- total += size;
- freeSpace -= size;
- } while (!Blocks.empty() && freeSpace > 0LL);
- }
-
- if (Blocks.empty() && IsDoneCounter == Paths.size()) {
- finished = true;
- }
-
- return total;
- }
-
-
- void Handle(TEvPrivate::TEvReadResult::TPtr& result) {
- ++IsDoneCounter;
- Blocks.emplace(std::move(result->Get()->Result));
- Callbacks->OnNewSourceDataArrived(InputIndex);
- }
-
+ return;
+ default:
+ break;
+ }
+ }
+
+ i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
+ i64 total = 0LL;
+ if (!Blocks.empty()) {
+ buffer.reserve(buffer.size() + Blocks.size());
+ do {
+ const auto size = Blocks.front().size();
+ buffer.emplace_back(NKikimr::NMiniKQL::MakeString(std::string_view(Blocks.front())));
+ Blocks.pop();
+ total += size;
+ freeSpace -= size;
+ } while (!Blocks.empty() && freeSpace > 0LL);
+ }
+
+ if (Blocks.empty() && IsDoneCounter == Paths.size()) {
+ finished = true;
+ }
+
+ return total;
+ }
+
+
+ void Handle(TEvPrivate::TEvReadResult::TPtr& result) {
+ ++IsDoneCounter;
+ Blocks.emplace(std::move(result->Get()->Result));
+ Callbacks->OnNewSourceDataArrived(InputIndex);
+ }
+
void HandleRetry(TEvPrivate::TEvRetryEvent::TPtr& ev) {
const auto pathInd = ev->Get()->PathIndex;
RetriesPerPath[pathInd].IncRetries();
@@ -182,80 +182,80 @@ private:
std::bind(&TS3ReadActor::OnDownloadFinished, ActorSystem, SelfId(), std::placeholders::_1, pathInd));
}
- void Handle(TEvPrivate::TEvReadError::TPtr& result) {
+ void Handle(TEvPrivate::TEvReadError::TPtr& result) {
const auto pathInd = result->Get()->PathIndex;
Y_VERIFY(pathInd < RetriesPerPath.size());
if (auto nextDelayMs = RetriesPerPath[pathInd].GetNextDelay(MaxRetriesPerPath)) {
Schedule(nextDelayMs, new TEvPrivate::TEvRetryEvent(pathInd));
return;
}
- ++IsDoneCounter;
+ ++IsDoneCounter;
Callbacks->OnSourceError(InputIndex, result->Get()->Error, true);
- }
-
+ }
+
// IActor & IDqSourceActor
void PassAway() override { // Is called from Compute Actor
TActorBootstrapped<TS3ReadActor>::PassAway();
}
- static IHTTPGateway::THeaders MakeHeader(const TString& token) {
- return token.empty() ? IHTTPGateway::THeaders() : IHTTPGateway::THeaders{TString("X-YaCloud-SubjectToken:") += token};
- }
-
+ static IHTTPGateway::THeaders MakeHeader(const TString& token) {
+ return token.empty() ? IHTTPGateway::THeaders() : IHTTPGateway::THeaders{TString("X-YaCloud-SubjectToken:") += token};
+ }
+
private:
- size_t IsDoneCounter = 0U;
-
- const IHTTPGateway::TPtr Gateway;
-
- const ui64 InputIndex;
- ICallbacks *const Callbacks;
-
- TActorSystem* const ActorSystem;
-
- const TString Url;
- const IHTTPGateway::THeaders Headers;
- const TPathList Paths;
-
- std::queue<IHTTPGateway::TContent> Blocks;
+ size_t IsDoneCounter = 0U;
+
+ const IHTTPGateway::TPtr Gateway;
+
+ const ui64 InputIndex;
+ ICallbacks *const Callbacks;
+
+ TActorSystem* const ActorSystem;
+
+ const TString Url;
+ const IHTTPGateway::THeaders Headers;
+ const TPathList Paths;
+
+ std::queue<IHTTPGateway::TContent> Blocks;
std::vector<TRetryParams> RetriesPerPath;
const std::shared_ptr<NS3::TRetryConfig> RetryConfig;
ui32 MaxRetriesPerPath = 3;
-};
-
-std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateS3ReadActor(
- IHTTPGateway::TPtr gateway,
- NS3::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
+};
+
+std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateS3ReadActor(
+ IHTTPGateway::TPtr gateway,
+ NS3::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
NYql::NDq::IDqSourceActor::ICallbacks* callback,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
const std::shared_ptr<NS3::TRetryConfig>& retryConfig)
-{
- std::unordered_map<TString, size_t> map(params.GetPath().size());
- for (auto i = 0; i < params.GetPath().size(); ++i)
- map.emplace(params.GetPath().Get(i).GetPath(), params.GetPath().Get(i).GetSize());
-
- TS3ReadActor::TPathList paths;
- paths.reserve(map.size());
- if (const auto taskParamsIt = taskParams.find(S3ProviderName); taskParamsIt != taskParams.cend()) {
- NS3::TRange range;
- TStringInput input(taskParamsIt->second);
- range.Load(&input);
- for (auto i = 0; i < range.GetPath().size(); ++i) {
- const auto& path = range.GetPath().Get(i);
- paths.emplace_back(path, map[path]);
- }
- } else
- while (auto item = map.extract(map.cbegin()))
- paths.emplace_back(std::move(item.key()), std::move(item.mapped()));
-
- const auto token = secureParams.Value(params.GetToken(), TString{});
- const auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(credentialsFactory, token);
- const auto authToken = credentialsProviderFactory->CreateProvider()->GetAuthInfo();
+{
+ std::unordered_map<TString, size_t> map(params.GetPath().size());
+ for (auto i = 0; i < params.GetPath().size(); ++i)
+ map.emplace(params.GetPath().Get(i).GetPath(), params.GetPath().Get(i).GetSize());
+
+ TS3ReadActor::TPathList paths;
+ paths.reserve(map.size());
+ if (const auto taskParamsIt = taskParams.find(S3ProviderName); taskParamsIt != taskParams.cend()) {
+ NS3::TRange range;
+ TStringInput input(taskParamsIt->second);
+ range.Load(&input);
+ for (auto i = 0; i < range.GetPath().size(); ++i) {
+ const auto& path = range.GetPath().Get(i);
+ paths.emplace_back(path, map[path]);
+ }
+ } else
+ while (auto item = map.extract(map.cbegin()))
+ paths.emplace_back(std::move(item.key()), std::move(item.mapped()));
+
+ const auto token = secureParams.Value(params.GetToken(), TString{});
+ const auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(credentialsFactory, token);
+ const auto authToken = credentialsProviderFactory->CreateProvider()->GetAuthInfo();
const auto actor = new TS3ReadActor(inputIndex, std::move(gateway), params.GetUrl(), authToken, std::move(paths), callback, retryConfig);
- return {actor, actor};
-}
-
-} // namespace NYql::NDq
+ return {actor, actor};
+}
+
+} // namespace NYql::NDq
diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.h b/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.h
index 872a9418cd..9280e9ba2e 100644
--- a/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.h
+++ b/ydb/library/yql/providers/s3/actors/yql_s3_read_actor.h
@@ -1,22 +1,22 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
#include <ydb/library/yql/providers/s3/proto/retry_config.pb.h>
#include <ydb/library/yql/providers/s3/proto/source.pb.h>
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
-#include <library/cpp/actors/core/actor.h>
-
-namespace NYql::NDq {
-
-std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateS3ReadActor(
- IHTTPGateway::TPtr gateway,
- NS3::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
+#include <library/cpp/actors/core/actor.h>
+
+namespace NYql::NDq {
+
+std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateS3ReadActor(
+ IHTTPGateway::TPtr gateway,
+ NS3::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
IDqSourceActor::ICallbacks* callback,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
const std::shared_ptr<NYql::NS3::TRetryConfig>& retryConfig = nullptr);
-
-} // namespace NYql::NDq
+
+} // namespace NYql::NDq
diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.cpp b/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.cpp
index 9b1e0f9925..fb78240498 100644
--- a/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.cpp
+++ b/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.cpp
@@ -1,19 +1,19 @@
-#include "yql_s3_source_factory.h"
-#include "yql_s3_read_actor.h"
-
+#include "yql_s3_source_factory.h"
+#include "yql_s3_read_actor.h"
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
-namespace NYql::NDq {
-
+namespace NYql::NDq {
+
void RegisterS3ReadActorFactory(
TDqSourceFactory& factory,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
IHTTPGateway::TPtr gateway,
const std::shared_ptr<NYql::NS3::TRetryConfig>& retryConfig) {
- factory.Register<NS3::TSource>("S3Source",
+ factory.Register<NS3::TSource>("S3Source",
[credentialsFactory, gateway, retryConfig](NS3::TSource&& settings, IDqSourceActorFactory::TArguments&& args) {
return CreateS3ReadActor(gateway, std::move(settings), args.InputIndex, args.SecureParams, args.TaskParams, args.Callback, credentialsFactory, retryConfig);
- });
-}
-
-}
+ });
+}
+
+}
diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.h b/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.h
index 307f74b66b..2df0a312b1 100644
--- a/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.h
+++ b/ydb/library/yql/providers/s3/actors/yql_s3_source_factory.h
@@ -1,19 +1,19 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_io_actors_factory.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
#include <ydb/library/yql/providers/s3/proto/retry_config.pb.h>
-
-namespace NYql::NDq {
-
+
+namespace NYql::NDq {
+
void RegisterS3ReadActorFactory(
TDqSourceFactory& factory,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
IHTTPGateway::TPtr gateway = IHTTPGateway::Make(),
const std::shared_ptr<NYql::NS3::TRetryConfig>& retryConfig = nullptr);
-
-}
+
+}
diff --git a/ydb/library/yql/providers/s3/expr_nodes/ya.make b/ydb/library/yql/providers/s3/expr_nodes/ya.make
index b86b1d07f9..6d3003f148 100644
--- a/ydb/library/yql/providers/s3/expr_nodes/ya.make
+++ b/ydb/library/yql/providers/s3/expr_nodes/ya.make
@@ -1,38 +1,38 @@
-LIBRARY()
-
-OWNER(
+LIBRARY()
+
+OWNER(
g:yq
- g:yql
-)
-
-SRCS(
- yql_s3_expr_nodes.cpp
-)
-
-PEERDIR(
+ g:yql
+)
+
+SRCS(
+ yql_s3_expr_nodes.cpp
+)
+
+PEERDIR(
ydb/library/yql/core/expr_nodes
ydb/library/yql/providers/common/provider
-)
-
-SRCDIR(
+)
+
+SRCDIR(
ydb/library/yql/core/expr_nodes_gen
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
ydb/library/yql/core/expr_nodes_gen/gen
- yql_expr_nodes_gen.jnj
- yql_s3_expr_nodes.json
- yql_s3_expr_nodes.gen.h
- yql_s3_expr_nodes.decl.inl.h
- yql_s3_expr_nodes.defs.inl.h
- IN yql_expr_nodes_gen.jnj
- IN yql_s3_expr_nodes.json
- OUT yql_s3_expr_nodes.gen.h
- OUT yql_s3_expr_nodes.decl.inl.h
- OUT yql_s3_expr_nodes.defs.inl.h
- OUTPUT_INCLUDES
+ yql_expr_nodes_gen.jnj
+ yql_s3_expr_nodes.json
+ yql_s3_expr_nodes.gen.h
+ yql_s3_expr_nodes.decl.inl.h
+ yql_s3_expr_nodes.defs.inl.h
+ IN yql_expr_nodes_gen.jnj
+ IN yql_s3_expr_nodes.json
+ OUT yql_s3_expr_nodes.gen.h
+ OUT yql_s3_expr_nodes.decl.inl.h
+ OUT yql_s3_expr_nodes.defs.inl.h
+ OUTPUT_INCLUDES
${ARCADIA_ROOT}/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h
- ${ARCADIA_ROOT}/util/generic/hash_set.h
-)
-
-END()
+ ${ARCADIA_ROOT}/util/generic/hash_set.h
+)
+
+END()
diff --git a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.cpp b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.cpp
index 69e46638ea..50cb76fa1e 100644
--- a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.cpp
+++ b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.cpp
@@ -1 +1 @@
-#include "yql_s3_expr_nodes.h"
+#include "yql_s3_expr_nodes.h"
diff --git a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h
index 802884c8af..67cd124f88 100644
--- a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h
+++ b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h
@@ -1,61 +1,61 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.gen.h>
-
-namespace NYql {
-namespace NNodes {
-
+
+namespace NYql {
+namespace NNodes {
+
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.decl.inl.h>
-
-class TS3DataSource: public NGenerated::TS3DataSourceStub<TExprBase, TCallable, TCoAtom> {
-public:
- explicit TS3DataSource(const TExprNode* node)
- : TS3DataSourceStub(node)
- {
- }
-
- explicit TS3DataSource(const TExprNode::TPtr& node)
- : TS3DataSourceStub(node)
- {
- }
-
- static bool Match(const TExprNode* node) {
- if (!TS3DataSourceStub::Match(node)) {
- return false;
- }
-
- if (node->Head().Content() != S3ProviderName) {
- return false;
- }
-
- return true;
- }
-};
-
-class TS3DataSink : public NGenerated::TS3DataSinkStub<TExprBase, TCallable, TCoAtom> {
-public:
- explicit TS3DataSink(const TExprNode* node)
- : TS3DataSinkStub(node) {}
-
- explicit TS3DataSink(const TExprNode::TPtr& node)
- : TS3DataSinkStub(node) {}
-
- static bool Match(const TExprNode* node) {
- if (!TS3DataSinkStub::Match(node)) {
- return false;
- }
-
- if (node->Head().Content() != S3ProviderName) {
- return false;
- }
-
- return true;
- }
-};
-
+
+class TS3DataSource: public NGenerated::TS3DataSourceStub<TExprBase, TCallable, TCoAtom> {
+public:
+ explicit TS3DataSource(const TExprNode* node)
+ : TS3DataSourceStub(node)
+ {
+ }
+
+ explicit TS3DataSource(const TExprNode::TPtr& node)
+ : TS3DataSourceStub(node)
+ {
+ }
+
+ static bool Match(const TExprNode* node) {
+ if (!TS3DataSourceStub::Match(node)) {
+ return false;
+ }
+
+ if (node->Head().Content() != S3ProviderName) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+class TS3DataSink : public NGenerated::TS3DataSinkStub<TExprBase, TCallable, TCoAtom> {
+public:
+ explicit TS3DataSink(const TExprNode* node)
+ : TS3DataSinkStub(node) {}
+
+ explicit TS3DataSink(const TExprNode::TPtr& node)
+ : TS3DataSinkStub(node) {}
+
+ static bool Match(const TExprNode* node) {
+ if (!TS3DataSinkStub::Match(node)) {
+ return false;
+ }
+
+ if (node->Head().Content() != S3ProviderName) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.defs.inl.h>
-
-} // namespace NNodes
-} // namespace NYql
+
+} // namespace NNodes
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.json b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.json
index baa77b0c6f..ffb5fb8035 100644
--- a/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.json
+++ b/ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.json
@@ -1,82 +1,82 @@
-{
- "NodeRootType": "TExprBase",
- "NodeBuilderBase": "TNodeBuilderBase",
- "ListBuilderBase": "TListBuilderBase",
- "FreeArgCallableBase": "TFreeArgCallable",
- "FreeArgBuilderBase": "TFreeArgCallableBuilderBase",
- "Nodes": [
- {
- "Name": "TS3DataSource",
- "Base": "TCallable",
- "Definition": "Custom",
- "Match": {"Type": "Callable", "Name": "DataSource"},
- "Children": [
- {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TS3DataSink",
- "Base": "TCallable",
- "Definition": "Custom",
- "Match": {"Type": "Callable", "Name": "DataSink"},
- "Children": [
- {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TS3Path",
- "Base": "TExprBase",
- "Match": {"Type": "Tuple"},
- "Children": [
- {"Index": 0, "Name": "Path", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Size", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TS3Paths",
- "ListBase": "TS3Path"
- },
- {
- "Name": "TS3SourceSettings",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "S3SourceSettings"},
- "Children": [
- {"Index": 0, "Name": "Paths", "Type": "TS3Paths"},
+{
+ "NodeRootType": "TExprBase",
+ "NodeBuilderBase": "TNodeBuilderBase",
+ "ListBuilderBase": "TListBuilderBase",
+ "FreeArgCallableBase": "TFreeArgCallable",
+ "FreeArgBuilderBase": "TFreeArgCallableBuilderBase",
+ "Nodes": [
+ {
+ "Name": "TS3DataSource",
+ "Base": "TCallable",
+ "Definition": "Custom",
+ "Match": {"Type": "Callable", "Name": "DataSource"},
+ "Children": [
+ {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TS3DataSink",
+ "Base": "TCallable",
+ "Definition": "Custom",
+ "Match": {"Type": "Callable", "Name": "DataSink"},
+ "Children": [
+ {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TS3Path",
+ "Base": "TExprBase",
+ "Match": {"Type": "Tuple"},
+ "Children": [
+ {"Index": 0, "Name": "Path", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Size", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TS3Paths",
+ "ListBase": "TS3Path"
+ },
+ {
+ "Name": "TS3SourceSettings",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "S3SourceSettings"},
+ "Children": [
+ {"Index": 0, "Name": "Paths", "Type": "TS3Paths"},
{"Index": 1, "Name": "Token", "Type": "TCoSecureParam"}
- ]
- },
- {
- "Name": "TS3Read",
- "Base": "TFreeArgCallable",
- "Match": {"Type": "Callable", "Name": "Read!"},
- "Children": [
- {"Index": 0, "Name": "World", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSource", "Type": "TS3DataSource"}
- ]
- },
- {
- "Name": "TS3Object",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "S3Object"},
- "Children": [
- {"Index": 0, "Name": "Paths", "Type": "TS3Paths"},
- {"Index": 1, "Name": "Format", "Type": "TCoAtom"},
- {"Index": 2, "Name": "Settings", "Type": "TExprBase", "Optional": true}
- ]
- },
- {
- "Name": "TS3ReadObject",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "S3ReadObject!"},
- "Children": [
- {"Index": 0, "Name": "World", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSource", "Type": "TS3DataSource"},
- {"Index": 2, "Name": "Object", "Type": "TS3Object"},
- {"Index": 3, "Name": "RowType", "Type": "TExprBase"},
- {"Index": 4, "Name": "ColumnOrder", "Type": "TExprBase", "Optional": true}
- ]
- }
- ]
-}
+ ]
+ },
+ {
+ "Name": "TS3Read",
+ "Base": "TFreeArgCallable",
+ "Match": {"Type": "Callable", "Name": "Read!"},
+ "Children": [
+ {"Index": 0, "Name": "World", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSource", "Type": "TS3DataSource"}
+ ]
+ },
+ {
+ "Name": "TS3Object",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "S3Object"},
+ "Children": [
+ {"Index": 0, "Name": "Paths", "Type": "TS3Paths"},
+ {"Index": 1, "Name": "Format", "Type": "TCoAtom"},
+ {"Index": 2, "Name": "Settings", "Type": "TExprBase", "Optional": true}
+ ]
+ },
+ {
+ "Name": "TS3ReadObject",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "S3ReadObject!"},
+ "Children": [
+ {"Index": 0, "Name": "World", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSource", "Type": "TS3DataSource"},
+ {"Index": 2, "Name": "Object", "Type": "TS3Object"},
+ {"Index": 3, "Name": "RowType", "Type": "TExprBase"},
+ {"Index": 4, "Name": "ColumnOrder", "Type": "TExprBase", "Optional": true}
+ ]
+ }
+ ]
+}
diff --git a/ydb/library/yql/providers/s3/proto/range.proto b/ydb/library/yql/providers/s3/proto/range.proto
index 58f90cf987..7da7cf6136 100644
--- a/ydb/library/yql/providers/s3/proto/range.proto
+++ b/ydb/library/yql/providers/s3/proto/range.proto
@@ -1,8 +1,8 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package NYql.NS3;
-
-message TRange {
- repeated string Path = 2;
-}
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package NYql.NS3;
+
+message TRange {
+ repeated string Path = 2;
+}
diff --git a/ydb/library/yql/providers/s3/proto/source.proto b/ydb/library/yql/providers/s3/proto/source.proto
index 79eb38e8d2..bb8786851d 100644
--- a/ydb/library/yql/providers/s3/proto/source.proto
+++ b/ydb/library/yql/providers/s3/proto/source.proto
@@ -1,15 +1,15 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package NYql.NS3;
-
-message TPath {
- string Path = 1;
- uint64 Size = 2;
-}
-
-message TSource {
- string Url = 1;
- string Token = 2;
- repeated TPath Path = 3;
-}
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package NYql.NS3;
+
+message TPath {
+ string Path = 1;
+ uint64 Size = 2;
+}
+
+message TSource {
+ string Url = 1;
+ string Token = 2;
+ repeated TPath Path = 3;
+}
diff --git a/ydb/library/yql/providers/s3/proto/ya.make b/ydb/library/yql/providers/s3/proto/ya.make
index f8d9f5f3d3..48215f2ab5 100644
--- a/ydb/library/yql/providers/s3/proto/ya.make
+++ b/ydb/library/yql/providers/s3/proto/ya.make
@@ -2,19 +2,19 @@ OWNER(
g:yq
g:yql
)
-
-PROTO_LIBRARY()
-
-SRCS(
- range.proto
+
+PROTO_LIBRARY()
+
+SRCS(
+ range.proto
retry_config.proto
- source.proto
-)
-
-IF (NOT PY_PROTOS_FOR)
- EXCLUDE_TAGS(GO_PROTO)
-ENDIF()
-
-END()
-
-
+ source.proto
+)
+
+IF (NOT PY_PROTOS_FOR)
+ EXCLUDE_TAGS(GO_PROTO)
+ENDIF()
+
+END()
+
+
diff --git a/ydb/library/yql/providers/s3/provider/ya.make b/ydb/library/yql/providers/s3/provider/ya.make
index 0266f52ff5..075bad7b0b 100644
--- a/ydb/library/yql/providers/s3/provider/ya.make
+++ b/ydb/library/yql/providers/s3/provider/ya.make
@@ -1,27 +1,27 @@
-LIBRARY()
-
-OWNER(
+LIBRARY()
+
+OWNER(
g:yq
- g:yql
-)
-
-SRCS(
- yql_s3_datasink.cpp
- yql_s3_datasink_execution.cpp
- yql_s3_datasink_type_ann.cpp
- yql_s3_datasource.cpp
- yql_s3_datasource_type_ann.cpp
- yql_s3_dq_integration.cpp
- yql_s3_exec.cpp
- yql_s3_io_discovery.cpp
- yql_s3_logical_opt.cpp
- yql_s3_mkql_compiler.cpp
- yql_s3_provider.cpp
- yql_s3_provider_impl.cpp
- yql_s3_settings.cpp
-)
-
-PEERDIR(
+ g:yql
+)
+
+SRCS(
+ yql_s3_datasink.cpp
+ yql_s3_datasink_execution.cpp
+ yql_s3_datasink_type_ann.cpp
+ yql_s3_datasource.cpp
+ yql_s3_datasource_type_ann.cpp
+ yql_s3_dq_integration.cpp
+ yql_s3_exec.cpp
+ yql_s3_io_discovery.cpp
+ yql_s3_logical_opt.cpp
+ yql_s3_mkql_compiler.cpp
+ yql_s3_provider.cpp
+ yql_s3_provider_impl.cpp
+ yql_s3_settings.cpp
+)
+
+PEERDIR(
contrib/libs/re2
library/cpp/json
library/cpp/random_provider
@@ -51,8 +51,8 @@ PEERDIR(
ydb/library/yql/providers/result/expr_nodes
ydb/library/yql/providers/s3/expr_nodes
ydb/library/yql/providers/s3/proto
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_datasink.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_datasink.cpp
index cb485f518e..92c99b1f24 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_datasink.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_datasink.cpp
@@ -1,85 +1,85 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSinkProvider : public TDataProviderBase {
-public:
- TS3DataSinkProvider(TS3State::TPtr state)
- : State_(state)
- , TypeAnnotationTransformer_(CreateS3DataSinkTypeAnnotationTransformer(State_))
- , ExecutionTransformer_(CreateS3DataSinkExecTransformer(State_))
- , LogicalOptProposalTransformer_(CreateS3LogicalOptProposalTransformer(State_))
- {
- }
-
- TStringBuf GetName() const override {
- return S3ProviderName;
- }
-
- bool CanParse(const TExprNode& node) override {
- if (node.IsCallable(TCoWrite::CallableName())) {
- return TS3DataSink::Match(node.Child(1));
- }
-
- return TypeAnnotationTransformer_->CanParse(node);
- }
-
- IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
- Y_UNUSED(instantOnly);
- return *TypeAnnotationTransformer_;
- }
-
- IGraphTransformer& GetCallableExecutionTransformer() override {
- return *ExecutionTransformer_;
- }
-
- bool CanExecute(const TExprNode& node) override {
- return ExecutionTransformer_->CanExec(node);
- }
-
- bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
- if (node.IsCallable(TCoDataSink::CallableName())) {
- if (node.Head().Content() == S3ProviderName) {
- if (const auto clusterName = node.Child(1)->Content(); State_->Configuration->HasCluster(clusterName)) {
- cluster = clusterName;
- return true;
- } else {
- ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() << "Unknown cluster name: " << clusterName));
- return false;
- }
- }
- }
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid S3 DataSink parameters"));
- return false;
- }
-
- IGraphTransformer& GetLogicalOptProposalTransformer() override {
- return *LogicalOptProposalTransformer_;
- }
-private:
- const TS3State::TPtr State_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<TExecTransformerBase> ExecutionTransformer_;
- const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
-};
-
-}
-
-TIntrusivePtr<IDataProvider> CreateS3DataSink(TS3State::TPtr state) {
- return new TS3DataSinkProvider(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSinkProvider : public TDataProviderBase {
+public:
+ TS3DataSinkProvider(TS3State::TPtr state)
+ : State_(state)
+ , TypeAnnotationTransformer_(CreateS3DataSinkTypeAnnotationTransformer(State_))
+ , ExecutionTransformer_(CreateS3DataSinkExecTransformer(State_))
+ , LogicalOptProposalTransformer_(CreateS3LogicalOptProposalTransformer(State_))
+ {
+ }
+
+ TStringBuf GetName() const override {
+ return S3ProviderName;
+ }
+
+ bool CanParse(const TExprNode& node) override {
+ if (node.IsCallable(TCoWrite::CallableName())) {
+ return TS3DataSink::Match(node.Child(1));
+ }
+
+ return TypeAnnotationTransformer_->CanParse(node);
+ }
+
+ IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
+ Y_UNUSED(instantOnly);
+ return *TypeAnnotationTransformer_;
+ }
+
+ IGraphTransformer& GetCallableExecutionTransformer() override {
+ return *ExecutionTransformer_;
+ }
+
+ bool CanExecute(const TExprNode& node) override {
+ return ExecutionTransformer_->CanExec(node);
+ }
+
+ bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
+ if (node.IsCallable(TCoDataSink::CallableName())) {
+ if (node.Head().Content() == S3ProviderName) {
+ if (const auto clusterName = node.Child(1)->Content(); State_->Configuration->HasCluster(clusterName)) {
+ cluster = clusterName;
+ return true;
+ } else {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() << "Unknown cluster name: " << clusterName));
+ return false;
+ }
+ }
+ }
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid S3 DataSink parameters"));
+ return false;
+ }
+
+ IGraphTransformer& GetLogicalOptProposalTransformer() override {
+ return *LogicalOptProposalTransformer_;
+ }
+private:
+ const TS3State::TPtr State_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<TExecTransformerBase> ExecutionTransformer_;
+ const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
+};
+
+}
+
+TIntrusivePtr<IDataProvider> CreateS3DataSink(TS3State::TPtr state) {
+ return new TS3DataSinkProvider(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_datasink_execution.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_datasink_execution.cpp
index 12d3d53ba1..1eb216e5a5 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_datasink_execution.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_datasink_execution.cpp
@@ -1,36 +1,36 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSinkExecTransformer : public TExecTransformerBase {
-public:
- TS3DataSinkExecTransformer(TS3State::TPtr state)
- : State_(state)
- {
- AddHandler({TCoCommit::CallableName()}, RequireFirst(), Pass());
- }
-
-private:
- TS3State::TPtr State_;
-};
-
-}
-
-THolder<TExecTransformerBase> CreateS3DataSinkExecTransformer(TS3State::TPtr state) {
- return THolder(new TS3DataSinkExecTransformer(state));
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSinkExecTransformer : public TExecTransformerBase {
+public:
+ TS3DataSinkExecTransformer(TS3State::TPtr state)
+ : State_(state)
+ {
+ AddHandler({TCoCommit::CallableName()}, RequireFirst(), Pass());
+ }
+
+private:
+ TS3State::TPtr State_;
+};
+
+}
+
+THolder<TExecTransformerBase> CreateS3DataSinkExecTransformer(TS3State::TPtr state) {
+ return THolder(new TS3DataSinkExecTransformer(state));
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_datasink_type_ann.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_datasink_type_ann.cpp
index a792427374..30196b3f4a 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_datasink_type_ann.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_datasink_type_ann.cpp
@@ -1,44 +1,44 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSinkTypeAnnotationTransformer : public TVisitorTransformerBase {
-public:
- TS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TS3DataSinkTypeAnnotationTransformer;
- AddHandler({TCoCommit::CallableName()}, Hndl(&TSelf::HandleCommit));
- }
-
- TStatus HandleCommit(TExprBase input, TExprContext&) {
- const auto commit = input.Cast<TCoCommit>();
- input.Ptr()->SetTypeAnn(commit.World().Ref().GetTypeAnn());
- return TStatus::Ok;
- }
-
-private:
- const TS3State::TPtr State_;
-};
-
-}
-
-THolder<TVisitorTransformerBase> CreateS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state) {
- return MakeHolder<TS3DataSinkTypeAnnotationTransformer>(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSinkTypeAnnotationTransformer : public TVisitorTransformerBase {
+public:
+ TS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TS3DataSinkTypeAnnotationTransformer;
+ AddHandler({TCoCommit::CallableName()}, Hndl(&TSelf::HandleCommit));
+ }
+
+ TStatus HandleCommit(TExprBase input, TExprContext&) {
+ const auto commit = input.Cast<TCoCommit>();
+ input.Ptr()->SetTypeAnn(commit.World().Ref().GetTypeAnn());
+ return TStatus::Ok;
+ }
+
+private:
+ const TS3State::TPtr State_;
+};
+
+}
+
+THolder<TVisitorTransformerBase> CreateS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state) {
+ return MakeHolder<TS3DataSinkTypeAnnotationTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_datasource.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_datasource.cpp
index 5c9c278f59..8f77b7bfe9 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_datasource.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_datasource.cpp
@@ -1,6 +1,6 @@
-#include "yql_s3_provider_impl.h"
-#include "yql_s3_dq_integration.h"
-
+#include "yql_s3_provider_impl.h"
+#include "yql_s3_dq_integration.h"
+
#include <ydb/library/yql/providers/common/config/yql_setting.h>
#include <ydb/library/yql/providers/common/config/yql_configuration_transformer.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
@@ -8,127 +8,127 @@
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSourceProvider : public TDataProviderBase {
-public:
- TS3DataSourceProvider(TS3State::TPtr state, IHTTPGateway::TPtr gateway)
- : State_(std::move(state))
- , IODiscoveryTransformer_(CreateS3IODiscoveryTransformer(State_, std::move(gateway)))
- , ConfigurationTransformer_(MakeHolder<NCommon::TProviderConfigurationTransformer>(State_->Configuration, *State_->Types, TString{S3ProviderName}))
- , CallableExecutionTransformer_(CreateS3SourceCallableExecutionTransformer(State_))
- , TypeAnnotationTransformer_(CreateS3DataSourceTypeAnnotationTransformer(State_))
- , DqIntegration_(CreateS3DqIntegration(State_))
- {}
-
- TStringBuf GetName() const override {
- return S3ProviderName;
- }
-
- bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
- if (node.IsCallable(TCoDataSource::CallableName())) {
- if (node.Head().Content() == S3ProviderName) {
- if (const auto& clusterName = node.Tail().Content(); NCommon::ALL_CLUSTERS != clusterName && !State_->Configuration->HasCluster(clusterName)) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Tail().Pos()), TStringBuilder() <<
- "Unknown s3 cluster name: " << clusterName));
- return false;
- } else {
- cluster = clusterName;
- return true;
- }
- }
- }
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid S3 DataSource parameters"));
- return false;
- }
-
- bool CanParse(const TExprNode& node) override {
- if (node.IsCallable(TCoRead::CallableName())) {
- return NNodes::TS3DataSource::Match(node.Child(1));
- }
- return TypeAnnotationTransformer_->CanParse(node);
- }
-
- IGraphTransformer& GetIODiscoveryTransformer() override {
- return *IODiscoveryTransformer_;
- }
-
- IGraphTransformer& GetConfigurationTransformer() override {
- return *ConfigurationTransformer_;
- }
-
- IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
- Y_UNUSED(instantOnly);
- return *TypeAnnotationTransformer_;
- }
-
- IGraphTransformer& GetCallableExecutionTransformer() override {
- return *CallableExecutionTransformer_;
- }
-
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- Y_UNUSED(ctx);
- YQL_CLOG(INFO, ProviderS3) << "RewriteIO";
- return node;
- }
-
- bool CanPullResult(const TExprNode&, TSyncMap& syncList, bool& canRef) override {
- Y_UNUSED(syncList);
- canRef = false;
- return false;
- }
-
- bool CanExecute(const TExprNode&) override {
- return false;
- }
-
- const THashMap<TString, TString>* GetClusterTokens() override {
- return &State_->Configuration->Tokens;
- }
-
- bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
- Y_UNUSED(compact);
-
- for (auto& child : node.Children()) {
- children.push_back(child.Get());
- }
-
- if (TMaybeNode<TS3ReadObject>(&node)) {
- return true;
- }
- return false;
- }
-
- void GetInputs(const TExprNode& node, TVector<TPinInfo>&) override {
- if (auto maybeRead = TMaybeNode<TS3ReadObject>(&node)) {
- }
- }
-
- IDqIntegration* GetDqIntegration() override {
- return DqIntegration_.Get();
- }
-
-
-private:
- const TS3State::TPtr State_;
- const THolder<IGraphTransformer> IODiscoveryTransformer_;
- const THolder<IGraphTransformer> ConfigurationTransformer_;
- const THolder<IGraphTransformer> CallableExecutionTransformer_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<IDqIntegration> DqIntegration_;
-};
-
-}
-
-TIntrusivePtr<IDataProvider> CreateS3DataSource(TS3State::TPtr state, IHTTPGateway::TPtr gateway) {
- return new TS3DataSourceProvider(std::move(state), std::move(gateway));
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSourceProvider : public TDataProviderBase {
+public:
+ TS3DataSourceProvider(TS3State::TPtr state, IHTTPGateway::TPtr gateway)
+ : State_(std::move(state))
+ , IODiscoveryTransformer_(CreateS3IODiscoveryTransformer(State_, std::move(gateway)))
+ , ConfigurationTransformer_(MakeHolder<NCommon::TProviderConfigurationTransformer>(State_->Configuration, *State_->Types, TString{S3ProviderName}))
+ , CallableExecutionTransformer_(CreateS3SourceCallableExecutionTransformer(State_))
+ , TypeAnnotationTransformer_(CreateS3DataSourceTypeAnnotationTransformer(State_))
+ , DqIntegration_(CreateS3DqIntegration(State_))
+ {}
+
+ TStringBuf GetName() const override {
+ return S3ProviderName;
+ }
+
+ bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
+ if (node.IsCallable(TCoDataSource::CallableName())) {
+ if (node.Head().Content() == S3ProviderName) {
+ if (const auto& clusterName = node.Tail().Content(); NCommon::ALL_CLUSTERS != clusterName && !State_->Configuration->HasCluster(clusterName)) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Tail().Pos()), TStringBuilder() <<
+ "Unknown s3 cluster name: " << clusterName));
+ return false;
+ } else {
+ cluster = clusterName;
+ return true;
+ }
+ }
+ }
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid S3 DataSource parameters"));
+ return false;
+ }
+
+ bool CanParse(const TExprNode& node) override {
+ if (node.IsCallable(TCoRead::CallableName())) {
+ return NNodes::TS3DataSource::Match(node.Child(1));
+ }
+ return TypeAnnotationTransformer_->CanParse(node);
+ }
+
+ IGraphTransformer& GetIODiscoveryTransformer() override {
+ return *IODiscoveryTransformer_;
+ }
+
+ IGraphTransformer& GetConfigurationTransformer() override {
+ return *ConfigurationTransformer_;
+ }
+
+ IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
+ Y_UNUSED(instantOnly);
+ return *TypeAnnotationTransformer_;
+ }
+
+ IGraphTransformer& GetCallableExecutionTransformer() override {
+ return *CallableExecutionTransformer_;
+ }
+
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ Y_UNUSED(ctx);
+ YQL_CLOG(INFO, ProviderS3) << "RewriteIO";
+ return node;
+ }
+
+ bool CanPullResult(const TExprNode&, TSyncMap& syncList, bool& canRef) override {
+ Y_UNUSED(syncList);
+ canRef = false;
+ return false;
+ }
+
+ bool CanExecute(const TExprNode&) override {
+ return false;
+ }
+
+ const THashMap<TString, TString>* GetClusterTokens() override {
+ return &State_->Configuration->Tokens;
+ }
+
+ bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
+ Y_UNUSED(compact);
+
+ for (auto& child : node.Children()) {
+ children.push_back(child.Get());
+ }
+
+ if (TMaybeNode<TS3ReadObject>(&node)) {
+ return true;
+ }
+ return false;
+ }
+
+ void GetInputs(const TExprNode& node, TVector<TPinInfo>&) override {
+ if (auto maybeRead = TMaybeNode<TS3ReadObject>(&node)) {
+ }
+ }
+
+ IDqIntegration* GetDqIntegration() override {
+ return DqIntegration_.Get();
+ }
+
+
+private:
+ const TS3State::TPtr State_;
+ const THolder<IGraphTransformer> IODiscoveryTransformer_;
+ const THolder<IGraphTransformer> ConfigurationTransformer_;
+ const THolder<IGraphTransformer> CallableExecutionTransformer_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<IDqIntegration> DqIntegration_;
+};
+
+}
+
+TIntrusivePtr<IDataProvider> CreateS3DataSource(TS3State::TPtr state, IHTTPGateway::TPtr gateway) {
+ return new TS3DataSourceProvider(std::move(state), std::move(gateway));
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_datasource_type_ann.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_datasource_type_ann.cpp
index fb7f8ab774..810942ee56 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_datasource_type_ann.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_datasource_type_ann.cpp
@@ -1,138 +1,138 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSourceTypeAnnotationTransformer : public TVisitorTransformerBase {
-public:
- TS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TS3DataSourceTypeAnnotationTransformer;
- AddHandler({TS3ReadObject::CallableName()}, Hndl(&TSelf::HandleRead));
- AddHandler({TS3Object::CallableName()}, Hndl(&TSelf::HandleObject));
- AddHandler({TS3SourceSettings::CallableName()}, Hndl(&TSelf::HandleS3SourceSettings));
- AddHandler({TCoConfigure::CallableName()}, Hndl(&TSelf::HandleConfig));
- }
-
- TStatus HandleS3SourceSettings(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 1U, 2U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureTuple(*input->Child(TS3SourceSettings::idx_Paths), ctx)) {
- return TStatus::Error;
- }
-
- if (input->ChildrenSize() > TS3SourceSettings::idx_Token && !TCoSecureParam::Match(input->Child(TS3SourceSettings::idx_Token))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Child(TS3SourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
- return TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
- return TStatus::Ok;
- }
-
- TStatus HandleRead(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 4U, 5U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureWorldType(*input->Child(TS3ReadObject::idx_World), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureSpecificDataSource(*input->Child(TS3ReadObject::idx_DataSource), S3ProviderName, ctx)) {
- return TStatus::Error;
- }
-
- if (TS3ReadObject::Match(input->Child(TS3ReadObject::idx_Object))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Child(TS3ReadObject::idx_Object)->Pos()), "Expected S3 object."));
- return TStatus::Error;
- }
-
- if (!EnsureType(*input->Child(TS3ReadObject::idx_RowType), ctx)) {
- return TStatus::Error;
- }
-
- const auto itemType = input->Child(TS3ReadObject::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
- input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
- input->Child(TS3ReadObject::idx_World)->GetTypeAnn(),
- ctx.MakeType<TListExprType>(itemType)
- }));
-
- if (input->ChildrenSize() > TS3ReadObject::idx_ColumnOrder) {
- const auto& order = *input->Child(TS3ReadObject::idx_ColumnOrder);
- if (!EnsureTupleOfAtoms(order, ctx)) {
- return TStatus::Error;
- }
- TVector<TString> columnOrder;
- columnOrder.reserve(order.ChildrenSize());
- order.ForEachChild([&columnOrder](const TExprNode& child) { columnOrder.emplace_back(child.Content()); });
- return State_->Types->SetColumnOrder(*input, columnOrder, ctx);
- }
-
- return TStatus::Ok;
- }
-
- TStatus HandleConfig(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinArgsCount(*input, 2, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureWorldType(*input->Child(TCoConfigure::idx_World), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureSpecificDataSource(*input->Child(TCoConfigure::idx_DataSource), S3ProviderName, ctx)) {
- return TStatus::Error;
- }
-
- input->SetTypeAnn(input->Child(TCoConfigure::idx_World)->GetTypeAnn());
- return TStatus::Ok;
- }
-
- TStatus HandleObject(const TExprNode::TPtr& input, TExprContext& ctx) {
- if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureTuple(*input->Child(TS3Object::idx_Paths), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(TS3Object::idx_Format), ctx)) {
- return TStatus::Error;
- }
-
- if (input->ChildrenSize() > TS3Object::idx_Settings && !EnsureTuple(*input->Child(TS3Object::idx_Settings), ctx)) {
- return TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.MakeType<TUnitExprType>());
- return TStatus::Ok;
- }
-private:
- const TS3State::TPtr State_;
-};
-
-}
-
-THolder<TVisitorTransformerBase> CreateS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state) {
- return MakeHolder<TS3DataSourceTypeAnnotationTransformer>(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSourceTypeAnnotationTransformer : public TVisitorTransformerBase {
+public:
+ TS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TS3DataSourceTypeAnnotationTransformer;
+ AddHandler({TS3ReadObject::CallableName()}, Hndl(&TSelf::HandleRead));
+ AddHandler({TS3Object::CallableName()}, Hndl(&TSelf::HandleObject));
+ AddHandler({TS3SourceSettings::CallableName()}, Hndl(&TSelf::HandleS3SourceSettings));
+ AddHandler({TCoConfigure::CallableName()}, Hndl(&TSelf::HandleConfig));
+ }
+
+ TStatus HandleS3SourceSettings(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 1U, 2U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureTuple(*input->Child(TS3SourceSettings::idx_Paths), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TS3SourceSettings::idx_Token && !TCoSecureParam::Match(input->Child(TS3SourceSettings::idx_Token))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Child(TS3SourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
+ return TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
+ return TStatus::Ok;
+ }
+
+ TStatus HandleRead(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 4U, 5U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureWorldType(*input->Child(TS3ReadObject::idx_World), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureSpecificDataSource(*input->Child(TS3ReadObject::idx_DataSource), S3ProviderName, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (TS3ReadObject::Match(input->Child(TS3ReadObject::idx_Object))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Child(TS3ReadObject::idx_Object)->Pos()), "Expected S3 object."));
+ return TStatus::Error;
+ }
+
+ if (!EnsureType(*input->Child(TS3ReadObject::idx_RowType), ctx)) {
+ return TStatus::Error;
+ }
+
+ const auto itemType = input->Child(TS3ReadObject::idx_RowType)->GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+ input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
+ input->Child(TS3ReadObject::idx_World)->GetTypeAnn(),
+ ctx.MakeType<TListExprType>(itemType)
+ }));
+
+ if (input->ChildrenSize() > TS3ReadObject::idx_ColumnOrder) {
+ const auto& order = *input->Child(TS3ReadObject::idx_ColumnOrder);
+ if (!EnsureTupleOfAtoms(order, ctx)) {
+ return TStatus::Error;
+ }
+ TVector<TString> columnOrder;
+ columnOrder.reserve(order.ChildrenSize());
+ order.ForEachChild([&columnOrder](const TExprNode& child) { columnOrder.emplace_back(child.Content()); });
+ return State_->Types->SetColumnOrder(*input, columnOrder, ctx);
+ }
+
+ return TStatus::Ok;
+ }
+
+ TStatus HandleConfig(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinArgsCount(*input, 2, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureWorldType(*input->Child(TCoConfigure::idx_World), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureSpecificDataSource(*input->Child(TCoConfigure::idx_DataSource), S3ProviderName, ctx)) {
+ return TStatus::Error;
+ }
+
+ input->SetTypeAnn(input->Child(TCoConfigure::idx_World)->GetTypeAnn());
+ return TStatus::Ok;
+ }
+
+ TStatus HandleObject(const TExprNode::TPtr& input, TExprContext& ctx) {
+ if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureTuple(*input->Child(TS3Object::idx_Paths), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(TS3Object::idx_Format), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TS3Object::idx_Settings && !EnsureTuple(*input->Child(TS3Object::idx_Settings), ctx)) {
+ return TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TUnitExprType>());
+ return TStatus::Ok;
+ }
+private:
+ const TS3State::TPtr State_;
+};
+
+}
+
+THolder<TVisitorTransformerBase> CreateS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state) {
+ return MakeHolder<TS3DataSourceTypeAnnotationTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.cpp
index 216b131ac8..539272add6 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.cpp
@@ -1,6 +1,6 @@
-#include "yql_s3_dq_integration.h"
-#include "yql_s3_mkql_compiler.h"
-
+#include "yql_s3_dq_integration.h"
+#include "yql_s3_mkql_compiler.h"
+
#include <ydb/library/yql/dq/expr_nodes/dq_expr_nodes.h>
#include <ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h>
#include <ydb/library/yql/providers/dq/common/yql_dq_settings.h>
@@ -9,151 +9,151 @@
#include <ydb/library/yql/providers/s3/proto/range.pb.h>
#include <ydb/library/yql/providers/s3/proto/source.pb.h>
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DqIntegration: public TDqIntegrationBase {
-public:
- TS3DqIntegration(TS3State::TPtr state)
- : State_(state)
- {
- }
-
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DqIntegration: public TDqIntegrationBase {
+public:
+ TS3DqIntegration(TS3State::TPtr state)
+ : State_(state)
+ {
+ }
+
ui64 Partition(const TDqSettings&, size_t maxPartitions, const TExprNode& node, TVector<TString>& partitions, TString*, TExprContext&, bool) override {
- TString cluster;
- std::vector<std::vector<TString>> parts;
- if (const TMaybeNode<TDqSource> source = &node) {
- cluster = source.Cast().DataSource().Cast<TS3DataSource>().Cluster().Value();
- const auto settings = source.Cast().Settings().Cast<TS3SourceSettings>();
- parts.reserve(settings.Paths().Size());
- for (auto i = 0u; i < settings.Paths().Size(); ++i)
- parts.emplace_back(std::vector<TString>(1U, settings.Paths().Item(i).Path().StringValue()));
- }
-
- if (maxPartitions && parts.size() > maxPartitions) {
- if (const auto extraParts = parts.size() - maxPartitions; extraParts > maxPartitions) {
- const auto partsPerTask = (parts.size() - 1ULL) / maxPartitions + 1ULL;
- for (auto it = parts.begin(); parts.end() > it;) {
- const auto to = it;
- const auto up = to + std::min<std::size_t>(partsPerTask, std::distance(to, parts.end()));
- for (auto jt = ++it; jt < up; ++jt)
- std::move(jt->begin(), jt->end(), std::back_inserter(*to));
- it = parts.erase(it, up);
- }
- } else {
- const auto dropEachPart = maxPartitions / extraParts;
- for (auto it = parts.begin(); parts.size() > maxPartitions;) {
- const auto to = it + dropEachPart;
- it = to - 1U;
- std::move(to->begin(), to->end(), std::back_inserter(*it));
- it = parts.erase(to);
- }
- }
- }
-
- partitions.reserve(parts.size());
- for (const auto& part : parts) {
- NS3::TRange range;
- std::for_each(part.cbegin(), part.cend(), [&range](const TString& path) { range.AddPath(path); });
-
- partitions.emplace_back();
- TStringOutput out(partitions.back());
- range.Save(&out);
- }
-
- return 0;
- }
-
- TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool) override {
- if (TS3ReadObject::Match(&read)) {
- return 0ul; // TODO: return real size
- }
-
- return Nothing();
- }
-
- TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
- if (const auto& maybeS3ReadObject = TMaybeNode<TS3ReadObject>(read)) {
- const auto& s3ReadObject = maybeS3ReadObject.Cast();
-
- const auto rowType = s3ReadObject.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
- const auto& clusterName = s3ReadObject.DataSource().Cluster().StringValue();
-
- TExprNode::TListType settings(1U,
- ctx.Builder(s3ReadObject.Object().Pos())
- .List()
- .Atom(0, "format", TNodeFlags::Default)
- .Add(1, s3ReadObject.Object().Format().Ptr())
- .Seal().Build()
- );
-
- if (const auto& objectSettings = s3ReadObject.Object().Settings()) {
- settings.emplace_back(
- ctx.Builder(objectSettings.Cast().Pos())
- .List()
- .Atom(0, "settings", TNodeFlags::Default)
- .Add(1, objectSettings.Cast().Ptr())
- .Seal().Build()
- );
- }
-
+ TString cluster;
+ std::vector<std::vector<TString>> parts;
+ if (const TMaybeNode<TDqSource> source = &node) {
+ cluster = source.Cast().DataSource().Cast<TS3DataSource>().Cluster().Value();
+ const auto settings = source.Cast().Settings().Cast<TS3SourceSettings>();
+ parts.reserve(settings.Paths().Size());
+ for (auto i = 0u; i < settings.Paths().Size(); ++i)
+ parts.emplace_back(std::vector<TString>(1U, settings.Paths().Item(i).Path().StringValue()));
+ }
+
+ if (maxPartitions && parts.size() > maxPartitions) {
+ if (const auto extraParts = parts.size() - maxPartitions; extraParts > maxPartitions) {
+ const auto partsPerTask = (parts.size() - 1ULL) / maxPartitions + 1ULL;
+ for (auto it = parts.begin(); parts.end() > it;) {
+ const auto to = it;
+ const auto up = to + std::min<std::size_t>(partsPerTask, std::distance(to, parts.end()));
+ for (auto jt = ++it; jt < up; ++jt)
+ std::move(jt->begin(), jt->end(), std::back_inserter(*to));
+ it = parts.erase(it, up);
+ }
+ } else {
+ const auto dropEachPart = maxPartitions / extraParts;
+ for (auto it = parts.begin(); parts.size() > maxPartitions;) {
+ const auto to = it + dropEachPart;
+ it = to - 1U;
+ std::move(to->begin(), to->end(), std::back_inserter(*it));
+ it = parts.erase(to);
+ }
+ }
+ }
+
+ partitions.reserve(parts.size());
+ for (const auto& part : parts) {
+ NS3::TRange range;
+ std::for_each(part.cbegin(), part.cend(), [&range](const TString& path) { range.AddPath(path); });
+
+ partitions.emplace_back();
+ TStringOutput out(partitions.back());
+ range.Save(&out);
+ }
+
+ return 0;
+ }
+
+ TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool) override {
+ if (TS3ReadObject::Match(&read)) {
+ return 0ul; // TODO: return real size
+ }
+
+ return Nothing();
+ }
+
+ TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
+ if (const auto& maybeS3ReadObject = TMaybeNode<TS3ReadObject>(read)) {
+ const auto& s3ReadObject = maybeS3ReadObject.Cast();
+
+ const auto rowType = s3ReadObject.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
+ const auto& clusterName = s3ReadObject.DataSource().Cluster().StringValue();
+
+ TExprNode::TListType settings(1U,
+ ctx.Builder(s3ReadObject.Object().Pos())
+ .List()
+ .Atom(0, "format", TNodeFlags::Default)
+ .Add(1, s3ReadObject.Object().Format().Ptr())
+ .Seal().Build()
+ );
+
+ if (const auto& objectSettings = s3ReadObject.Object().Settings()) {
+ settings.emplace_back(
+ ctx.Builder(objectSettings.Cast().Pos())
+ .List()
+ .Atom(0, "settings", TNodeFlags::Default)
+ .Add(1, objectSettings.Cast().Ptr())
+ .Seal().Build()
+ );
+ }
+
const auto token = "cluster:default_" + clusterName;
YQL_CLOG(INFO, ProviderS3) << "Wrap " << read->Content() << " with token: " << token;
-
- return Build<TDqSourceWrap>(ctx, read->Pos())
- .Input<TS3SourceSettings>()
- .Paths(s3ReadObject.Object().Paths())
- .Token<TCoSecureParam>()
+
+ return Build<TDqSourceWrap>(ctx, read->Pos())
+ .Input<TS3SourceSettings>()
+ .Paths(s3ReadObject.Object().Paths())
+ .Token<TCoSecureParam>()
.Name().Build(token)
- .Build()
- .Build()
- .RowType(ExpandType(s3ReadObject.Pos(), *rowType, ctx))
- .DataSource(s3ReadObject.DataSource().Cast<TCoDataSource>())
- .Settings(ctx.NewList(s3ReadObject.Object().Pos(), std::move(settings)))
- .Done().Ptr();
- }
- return read;
- }
-
- void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
- const TDqSource source(&node);
- if (const auto maySettings = source.Settings().Maybe<TS3SourceSettings>()) {
- const auto settings = maySettings.Cast();
- const auto& cluster = source.DataSource().Cast<TS3DataSource>().Cluster().StringValue();
+ .Build()
+ .Build()
+ .RowType(ExpandType(s3ReadObject.Pos(), *rowType, ctx))
+ .DataSource(s3ReadObject.DataSource().Cast<TCoDataSource>())
+ .Settings(ctx.NewList(s3ReadObject.Object().Pos(), std::move(settings)))
+ .Done().Ptr();
+ }
+ return read;
+ }
+
+ void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
+ const TDqSource source(&node);
+ if (const auto maySettings = source.Settings().Maybe<TS3SourceSettings>()) {
+ const auto settings = maySettings.Cast();
+ const auto& cluster = source.DataSource().Cast<TS3DataSource>().Cluster().StringValue();
const auto& connect = State_->Configuration->Clusters.at(cluster);
-
- NS3::TSource srcDesc;
- srcDesc.SetUrl(connect.Url);
- srcDesc.SetToken(settings.Token().Name().StringValue());
-
- const auto& paths = settings.Paths();
- for (auto i = 0U; i < paths.Size(); ++i) {
- const auto p = srcDesc.AddPath();
- p->SetPath(paths.Item(i).Path().StringValue());
- p->SetSize(FromString<ui64>(paths.Item(i).Size().Value()));
- }
-
- protoSettings.PackFrom(srcDesc);
- sourceType = "S3Source";
- }
- }
-
- void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override {
- RegisterDqS3MkqlCompilers(compiler, State_);
- }
-
-private:
- const TS3State::TPtr State_;
-};
-
-}
-
-THolder<IDqIntegration> CreateS3DqIntegration(TS3State::TPtr state) {
+
+ NS3::TSource srcDesc;
+ srcDesc.SetUrl(connect.Url);
+ srcDesc.SetToken(settings.Token().Name().StringValue());
+
+ const auto& paths = settings.Paths();
+ for (auto i = 0U; i < paths.Size(); ++i) {
+ const auto p = srcDesc.AddPath();
+ p->SetPath(paths.Item(i).Path().StringValue());
+ p->SetSize(FromString<ui64>(paths.Item(i).Size().Value()));
+ }
+
+ protoSettings.PackFrom(srcDesc);
+ sourceType = "S3Source";
+ }
+ }
+
+ void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override {
+ RegisterDqS3MkqlCompilers(compiler, State_);
+ }
+
+private:
+ const TS3State::TPtr State_;
+};
+
+}
+
+THolder<IDqIntegration> CreateS3DqIntegration(TS3State::TPtr state) {
return MakeHolder<TS3DqIntegration>(state);
-}
-
-}
+}
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.h b/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.h
index ce1a036128..09ecd4fbfb 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.h
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_dq_integration.h
@@ -1,13 +1,13 @@
-#pragma once
-
-#include "yql_s3_provider.h"
-
+#pragma once
+
+#include "yql_s3_provider.h"
+
#include <ydb/library/yql/providers/dq/interface/yql_dq_integration.h>
-
-#include <util/generic/ptr.h>
-
-namespace NYql {
-
-THolder<IDqIntegration> CreateS3DqIntegration(TS3State::TPtr state);
-
-}
+
+#include <util/generic/ptr.h>
+
+namespace NYql {
+
+THolder<IDqIntegration> CreateS3DqIntegration(TS3State::TPtr state);
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_exec.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_exec.cpp
index c2330c0242..b143ebc732 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_exec.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_exec.cpp
@@ -1,46 +1,46 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
#include <ydb/library/yql/providers/result/expr_nodes/yql_res_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3DataSourceExecutionTransformer : public TVisitorTransformerBase {
-public:
- TS3DataSourceExecutionTransformer(TS3State::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TS3DataSourceExecutionTransformer;
- AddHandler({TPull::CallableName()}, Hndl(&TSelf::HandlePull));
-
- }
-
- TStatus HandlePull(TExprBase node, TExprContext&) {
- node.Ptr()->SetResult(TExprNode::GetResult(node.Ref().Head().HeadPtr()));
- node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
- return IGraphTransformer::TStatus::Ok;
- }
-private:
- const TS3State::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateS3SourceCallableExecutionTransformer(TS3State::TPtr state) {
- return MakeHolder<TS3DataSourceExecutionTransformer>(state);
-}
-
-} // namespace NYql
-
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3DataSourceExecutionTransformer : public TVisitorTransformerBase {
+public:
+ TS3DataSourceExecutionTransformer(TS3State::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TS3DataSourceExecutionTransformer;
+ AddHandler({TPull::CallableName()}, Hndl(&TSelf::HandlePull));
+
+ }
+
+ TStatus HandlePull(TExprBase node, TExprContext&) {
+ node.Ptr()->SetResult(TExprNode::GetResult(node.Ref().Head().HeadPtr()));
+ node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
+ return IGraphTransformer::TStatus::Ok;
+ }
+private:
+ const TS3State::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateS3SourceCallableExecutionTransformer(TS3State::TPtr state) {
+ return MakeHolder<TS3DataSourceExecutionTransformer>(state);
+}
+
+} // namespace NYql
+
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
index 02e7d99951..3e0384c9d7 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
@@ -1,36 +1,36 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
#include <ydb/library/yql/core/yql_expr_optimize.h>
#include <ydb/library/yql/utils/log/log.h>
-
-#include <util/generic/size_literals.h>
-
-#include <library/cpp/string_utils/quote/quote.h>
-#include <contrib/libs/re2/re2/re2.h>
-
-#ifdef THROW
-#undef THROW
-#endif
-#include <library/cpp/xml/document/xml-document.h>
-
-namespace NYql {
-
-namespace {
-
-using namespace NNodes;
-
-std::array<TExprNode::TPtr, 2U> GetSchema(const TExprNode& settings) {
- for (auto i = 0U; i < settings.ChildrenSize(); ++i)
- if (settings.Child(i)->Head().IsAtom("userschema"))
- return {settings.Child(i)->ChildPtr(1), settings.Child(i)->ChildrenSize() > 2 ? settings.Child(i)->TailPtr() : TExprNode::TPtr()};
-
- return {};
-}
-
-using TItemsMap = std::map<TString, std::size_t>;
-using TPendingBuckets = std::unordered_map<std::tuple<TString, TString, TString>, std::tuple<TNodeSet, TItemsMap, TIssues>, THash<std::tuple<TString, TString, TString>>>;
-
+
+#include <util/generic/size_literals.h>
+
+#include <library/cpp/string_utils/quote/quote.h>
+#include <contrib/libs/re2/re2/re2.h>
+
+#ifdef THROW
+#undef THROW
+#endif
+#include <library/cpp/xml/document/xml-document.h>
+
+namespace NYql {
+
+namespace {
+
+using namespace NNodes;
+
+std::array<TExprNode::TPtr, 2U> GetSchema(const TExprNode& settings) {
+ for (auto i = 0U; i < settings.ChildrenSize(); ++i)
+ if (settings.Child(i)->Head().IsAtom("userschema"))
+ return {settings.Child(i)->ChildPtr(1), settings.Child(i)->ChildrenSize() > 2 ? settings.Child(i)->TailPtr() : TExprNode::TPtr()};
+
+ return {};
+}
+
+using TItemsMap = std::map<TString, std::size_t>;
+using TPendingBuckets = std::unordered_map<std::tuple<TString, TString, TString>, std::tuple<TNodeSet, TItemsMap, TIssues>, THash<std::tuple<TString, TString, TString>>>;
+
void OnDiscovery(
IHTTPGateway::TWeakPtr gateway,
TPosition pos,
@@ -45,307 +45,307 @@ void OnDiscovery(
return;
}
TString logMsg = TStringBuilder() << "promise #" << promiseInd << ": ";
- switch (result.index()) {
- case 0U: try {
+ switch (result.index()) {
+ case 0U: try {
logMsg += "Result received";
- const NXml::TDocument xml(std::get<IHTTPGateway::TContent>(std::move(result)).Extract(), NXml::TDocument::String);
- if (const auto& root = xml.Root(); root.Name() == "Error") {
- const auto& code = root.Node("Code", true).Value<TString>();
- const auto& message = root.Node("Message", true).Value<TString>();
- std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << message << ", error: code: " << code)};
- break;
- } else if (root.Name() != "ListBucketResult") {
- std::get<TIssues>(output) = { TIssue(pos, TStringBuilder() << "Unexpected response '" << root.Name() << "' on discovery.") };
- break;
- } else if (const NXml::TNamespacesForXPath nss(1U, {"s3", "http://s3.amazonaws.com/doc/2006-03-01/"});
- root.Node("s3:KeyCount", false, nss).Value<unsigned>() > 0U) {
- const auto& contents = root.XPath("s3:Contents", false, nss);
- auto& items = std::get<TItemsMap>(output);
- if (items.size() + contents.size() > 9000ULL) {
- std::get<TIssues>(output) = { TIssue(pos, TStringBuilder() << "It's over nine thousand items under '" << std::get<0U>(keys) << std::get<1U>(keys) << "'!")};
+ const NXml::TDocument xml(std::get<IHTTPGateway::TContent>(std::move(result)).Extract(), NXml::TDocument::String);
+ if (const auto& root = xml.Root(); root.Name() == "Error") {
+ const auto& code = root.Node("Code", true).Value<TString>();
+ const auto& message = root.Node("Message", true).Value<TString>();
+ std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << message << ", error: code: " << code)};
+ break;
+ } else if (root.Name() != "ListBucketResult") {
+ std::get<TIssues>(output) = { TIssue(pos, TStringBuilder() << "Unexpected response '" << root.Name() << "' on discovery.") };
+ break;
+ } else if (const NXml::TNamespacesForXPath nss(1U, {"s3", "http://s3.amazonaws.com/doc/2006-03-01/"});
+ root.Node("s3:KeyCount", false, nss).Value<unsigned>() > 0U) {
+ const auto& contents = root.XPath("s3:Contents", false, nss);
+ auto& items = std::get<TItemsMap>(output);
+ if (items.size() + contents.size() > 9000ULL) {
+ std::get<TIssues>(output) = { TIssue(pos, TStringBuilder() << "It's over nine thousand items under '" << std::get<0U>(keys) << std::get<1U>(keys) << "'!")};
break;
- }
-
- for (const auto& content : contents) {
- items.emplace(content.Node("s3:Key", false, nss).Value<TString>(), content.Node("s3:Size", false, nss).Value<unsigned>());
- }
-
- if (root.Node("s3:IsTruncated", false, nss).Value<bool>()) {
- if (const auto g = gateway.lock()) {
- const auto& next = root.Node("s3:NextContinuationToken", false, nss).Value<TString>();
- const auto& maxKeys = root.Node("s3:MaxKeys", false, nss).Value<TString>();
- TString prefix(std::get<1U>(keys));
- CGIEscape(prefix);
- IHTTPGateway::THeaders headers;
- if (const auto& token = std::get<2U>(keys); !token.empty())
- headers.emplace_back(token);
- return g->Download(std::get<0U>(keys) + "?list-type=2&prefix=" + prefix + "&continuation-token=" + next + "&max-keys=" + maxKeys, std::move(headers), 0U,
+ }
+
+ for (const auto& content : contents) {
+ items.emplace(content.Node("s3:Key", false, nss).Value<TString>(), content.Node("s3:Size", false, nss).Value<unsigned>());
+ }
+
+ if (root.Node("s3:IsTruncated", false, nss).Value<bool>()) {
+ if (const auto g = gateway.lock()) {
+ const auto& next = root.Node("s3:NextContinuationToken", false, nss).Value<TString>();
+ const auto& maxKeys = root.Node("s3:MaxKeys", false, nss).Value<TString>();
+ TString prefix(std::get<1U>(keys));
+ CGIEscape(prefix);
+ IHTTPGateway::THeaders headers;
+ if (const auto& token = std::get<2U>(keys); !token.empty())
+ headers.emplace_back(token);
+ return g->Download(std::get<0U>(keys) + "?list-type=2&prefix=" + prefix + "&continuation-token=" + next + "&max-keys=" + maxKeys, std::move(headers), 0U,
std::bind(&OnDiscovery, gateway, pos, std::placeholders::_1, std::cref(keys), std::ref(output), std::move(promise), pendingBucketsWPtr, promiseInd));
}
YQL_CLOG(INFO, ProviderS3) << "Gateway disappeared.";
}
- }
+ }
- break;
- } catch (const std::exception& ex) {
+ break;
+ } catch (const std::exception& ex) {
logMsg += TStringBuilder() << "Exception occurred: " << ex.what();
- std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << "Error '" << ex.what() << "' on parse discovery response.")};
- break;
- }
- case 1U:
+ std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << "Error '" << ex.what() << "' on parse discovery response.")};
+ break;
+ }
+ case 1U:
logMsg += TStringBuilder() << "Issues occurred: " << std::get<TIssues>(result).ToString();
- std::get<TIssues>(output) = std::get<TIssues>(std::move(result));
- break;
- default:
+ std::get<TIssues>(output) = std::get<TIssues>(std::move(result));
+ break;
+ default:
logMsg += TStringBuilder() << "Undefined variant index: " << result.index();
- std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << "Unexpected variant index " << result.index() << " on discovery.")};
- break;
- }
-
+ std::get<TIssues>(output) = {TIssue(pos, TStringBuilder() << "Unexpected variant index " << result.index() << " on discovery.")};
+ break;
+ }
+
YQL_CLOG(DEBUG, ProviderS3) << "Set promise with log message: " << logMsg;
promise.SetValue();
-}
-
-
-TString RegexFromWildcards(const std::string_view& pattern) {
- const auto& escaped = RE2::QuoteMeta(re2::StringPiece(pattern));
- TStringBuilder result;
- result << "(?s)";
- bool slash = false;
- bool group = false;
-
- for (const char& c : escaped) {
- switch (c) {
- case '{':
- result << '(';
- group = true;
- slash = false;
- break;
- case '}':
- result << ')';
- group = false;
- slash = false;
- break;
- case ',':
- if (group)
- result << '|';
- else
- result << "\\,";
- slash = false;
- break;
- case '\\':
- if (slash)
- result << "\\\\";
- slash = !slash;
- break;
- case '*':
- result << ".*";
- slash = false;
- break;
- case '?':
- result << '.';
- slash = false;
- break;
- default:
- if (slash)
- result << '\\';
- result << c;
- slash = false;
- break;
- }
- }
- return result;
-}
-
-class TS3IODiscoveryTransformer : public TGraphTransformerBase {
-public:
- TS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway)
- : State_(std::move(state)), Gateway_(std::move(gateway))
- {}
-
- TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
- if (ctx.Step.IsDone(TExprStep::DiscoveryIO)) {
- return TStatus::Ok;
- }
-
- if (auto reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
- if (const auto maybeRead = TMaybeNode<TS3Read>(node)) {
- if (maybeRead.DataSource()) {
- return maybeRead.Cast().Arg(2).Ref().IsCallable("MrObject");
- }
- }
- return false;
- }); !reads.empty()) {
- for (auto& r : reads) {
- const TS3Read read(std::move(r));
- const auto& object = read.Arg(2).Ref();
- const std::string_view& path = object.Head().Content();
- const auto& prefix = path.substr(0U, path.find_first_of("*?{"));
+}
+
+
+TString RegexFromWildcards(const std::string_view& pattern) {
+ const auto& escaped = RE2::QuoteMeta(re2::StringPiece(pattern));
+ TStringBuilder result;
+ result << "(?s)";
+ bool slash = false;
+ bool group = false;
+
+ for (const char& c : escaped) {
+ switch (c) {
+ case '{':
+ result << '(';
+ group = true;
+ slash = false;
+ break;
+ case '}':
+ result << ')';
+ group = false;
+ slash = false;
+ break;
+ case ',':
+ if (group)
+ result << '|';
+ else
+ result << "\\,";
+ slash = false;
+ break;
+ case '\\':
+ if (slash)
+ result << "\\\\";
+ slash = !slash;
+ break;
+ case '*':
+ result << ".*";
+ slash = false;
+ break;
+ case '?':
+ result << '.';
+ slash = false;
+ break;
+ default:
+ if (slash)
+ result << '\\';
+ result << c;
+ slash = false;
+ break;
+ }
+ }
+ return result;
+}
+
+class TS3IODiscoveryTransformer : public TGraphTransformerBase {
+public:
+ TS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway)
+ : State_(std::move(state)), Gateway_(std::move(gateway))
+ {}
+
+ TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
+ output = input;
+ if (ctx.Step.IsDone(TExprStep::DiscoveryIO)) {
+ return TStatus::Ok;
+ }
+
+ if (auto reads = FindNodes(input, [&](const TExprNode::TPtr& node) {
+ if (const auto maybeRead = TMaybeNode<TS3Read>(node)) {
+ if (maybeRead.DataSource()) {
+ return maybeRead.Cast().Arg(2).Ref().IsCallable("MrObject");
+ }
+ }
+ return false;
+ }); !reads.empty()) {
+ for (auto& r : reads) {
+ const TS3Read read(std::move(r));
+ const auto& object = read.Arg(2).Ref();
+ const std::string_view& path = object.Head().Content();
+ const auto& prefix = path.substr(0U, path.find_first_of("*?{"));
const auto& connect = State_->Configuration->Clusters.at(read.DataSource().Cluster().StringValue());
const auto& token = State_->Configuration->Tokens.at(read.DataSource().Cluster().StringValue());
const auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(State_->CredentialsFactory, token);
const auto authToken = credentialsProviderFactory->CreateProvider()->GetAuthInfo();
std::get<TNodeSet>((*PendingBuckets_)[std::make_tuple(connect.Url, TString(prefix), authToken.empty() ? TString() : TString("X-YaCloud-SubjectToken:") += authToken)]).emplace(read.Raw());
- }
- }
-
- std::vector<NThreading::TFuture<void>> handles;
+ }
+ }
+
+ std::vector<NThreading::TFuture<void>> handles;
handles.reserve(PendingBuckets_->size());
-
+
int i = 0;
for (auto& bucket : *PendingBuckets_) {
- auto promise = NThreading::NewPromise();
- handles.emplace_back(promise.GetFuture());
- TString prefix(std::get<1U>(bucket.first));
- CGIEscape(prefix);
- IHTTPGateway::THeaders headers;
- if (const auto& token = std::get<2U>(bucket.first); !token.empty())
- headers.emplace_back(token);
+ auto promise = NThreading::NewPromise();
+ handles.emplace_back(promise.GetFuture());
+ TString prefix(std::get<1U>(bucket.first));
+ CGIEscape(prefix);
+ IHTTPGateway::THeaders headers;
+ if (const auto& token = std::get<2U>(bucket.first); !token.empty())
+ headers.emplace_back(token);
std::weak_ptr<TPendingBuckets> pendingBucketsWPtr = PendingBuckets_;
- Gateway_->Download(std::get<0U>(bucket.first) + "?list-type=2&prefix=" + prefix, headers, 0U, std::bind(&OnDiscovery,
+ Gateway_->Download(std::get<0U>(bucket.first) + "?list-type=2&prefix=" + prefix, headers, 0U, std::bind(&OnDiscovery,
IHTTPGateway::TWeakPtr(Gateway_), ctx.GetPosition((*std::get<TNodeSet>(bucket.second).cbegin())->Pos()), std::placeholders::_1,
std::cref(bucket.first), std::ref(bucket.second), std::move(promise), pendingBucketsWPtr, i++));
- YQL_CLOG(INFO, ProviderS3) << "Enumerate items in " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first);
- }
-
- if (handles.empty()) {
- return TStatus::Ok;
- }
-
- AllFuture_ = NThreading::WaitExceptionOrAll(handles);
- return TStatus::Async;
- }
-
- NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
- return AllFuture_;
- }
-
- TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
+ YQL_CLOG(INFO, ProviderS3) << "Enumerate items in " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first);
+ }
+
+ if (handles.empty()) {
+ return TStatus::Ok;
+ }
+
+ AllFuture_ = NThreading::WaitExceptionOrAll(handles);
+ return TStatus::Async;
+ }
+
+ NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
+ return AllFuture_;
+ }
+
+ TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
// Raise errors if any
AllFuture_.GetValue();
TNodeOnNodeOwnedMap replaces(PendingBuckets_->size());
auto buckets = std::move(*PendingBuckets_);
- auto count = 0ULL;
- auto readSize = 0ULL;
- for (auto& bucket : buckets) {
- if (const auto issues = std::move(std::get<TIssues>(bucket.second))) {
- YQL_CLOG(INFO, ProviderS3) << "Discovery " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first) << " error " << issues.ToString();
- std::for_each(issues.begin(), issues.end(), std::bind(&TExprContext::AddError, std::ref(ctx), std::placeholders::_1));
+ auto count = 0ULL;
+ auto readSize = 0ULL;
+ for (auto& bucket : buckets) {
+ if (const auto issues = std::move(std::get<TIssues>(bucket.second))) {
+ YQL_CLOG(INFO, ProviderS3) << "Discovery " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first) << " error " << issues.ToString();
+ std::for_each(issues.begin(), issues.end(), std::bind(&TExprContext::AddError, std::ref(ctx), std::placeholders::_1));
return TStatus::Error;
}
const auto nodes = std::move(std::get<TNodeSet>(bucket.second));
for (const auto r : nodes) {
- const TS3Read read(r);
- const auto& object = read.Arg(2).Ref();
- const std::string_view& path = object.Head().Content();
- const auto& items = std::get<TItemsMap>(bucket.second);
- YQL_CLOG(INFO, ProviderS3) << "Discovered " << items.size() << " items in " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first);
-
- TExprNode::TListType paths;
- if (std::string_view::npos != path.find_first_of("?*{")) {
- const RE2 re(re2::StringPiece(RegexFromWildcards(path)), RE2::Options());
- paths.reserve(items.size());
- auto total = 0ULL;
- for (const auto& item : items) {
- if (const re2::StringPiece piece(item.first); re.Match(piece, 0, item.first.size(), RE2::ANCHOR_BOTH, nullptr, 0)) {
- if (item.second > State_->Configuration->FileSizeLimit) {
- ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << item.first << " size " << item.second << " is too large."));
- return TStatus::Error;
- }
-
- total += item.second;
- ++count;
- paths.emplace_back(
- ctx.Builder(object.Pos())
- .List()
- .Atom(0, item.first)
- .Atom(1, ToString(item.second), TNodeFlags::Default)
- .Seal()
- .Build()
- );
- }
- }
-
- readSize += total;
-
- if (paths.empty()) {
- ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << path << " has no items."));
- return TStatus::Error;
- }
- YQL_CLOG(INFO, ProviderS3) << "Object " << path << " has " << paths.size() << " items with total size " << total;
- } else if (const auto f = items.find(TString(path)); items.cend() == f) {
+ const TS3Read read(r);
+ const auto& object = read.Arg(2).Ref();
+ const std::string_view& path = object.Head().Content();
+ const auto& items = std::get<TItemsMap>(bucket.second);
+ YQL_CLOG(INFO, ProviderS3) << "Discovered " << items.size() << " items in " << std::get<0U>(bucket.first) << std::get<1U>(bucket.first);
+
+ TExprNode::TListType paths;
+ if (std::string_view::npos != path.find_first_of("?*{")) {
+ const RE2 re(re2::StringPiece(RegexFromWildcards(path)), RE2::Options());
+ paths.reserve(items.size());
+ auto total = 0ULL;
+ for (const auto& item : items) {
+ if (const re2::StringPiece piece(item.first); re.Match(piece, 0, item.first.size(), RE2::ANCHOR_BOTH, nullptr, 0)) {
+ if (item.second > State_->Configuration->FileSizeLimit) {
+ ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << item.first << " size " << item.second << " is too large."));
+ return TStatus::Error;
+ }
+
+ total += item.second;
+ ++count;
+ paths.emplace_back(
+ ctx.Builder(object.Pos())
+ .List()
+ .Atom(0, item.first)
+ .Atom(1, ToString(item.second), TNodeFlags::Default)
+ .Seal()
+ .Build()
+ );
+ }
+ }
+
+ readSize += total;
+
+ if (paths.empty()) {
+ ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << path << " has no items."));
+ return TStatus::Error;
+ }
+ YQL_CLOG(INFO, ProviderS3) << "Object " << path << " has " << paths.size() << " items with total size " << total;
+ } else if (const auto f = items.find(TString(path)); items.cend() == f) {
ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << path << " doesn't exist."));
- return TStatus::Error;
- } else if (const auto size = f->second; size > State_->Configuration->FileSizeLimit) {
- ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << path << " size " << size << " is too large."));
- return TStatus::Error;
- } else {
- YQL_CLOG(INFO, ProviderS3) << "Object " << path << " size is " << size;
- readSize += size;
- ++count;
- paths.emplace_back(
- ctx.Builder(object.Pos())
- .List()
- .Add(0, object.HeadPtr())
- .Atom(1, ToString(size), TNodeFlags::Default)
- .Seal()
- .Build()
- );
- }
-
- auto children = object.ChildrenList();
- children.front() = ctx.NewList(object.Pos(), std::move(paths));
- auto s3Object = ctx.NewCallable(object.Pos(), TS3Object::CallableName(), std::move(children));
- auto userSchema = GetSchema(*read.Ref().Child(4));
-
- replaces.emplace(r, userSchema.back() ?
- Build<TS3ReadObject>(ctx, read.Pos())
- .World(read.World())
- .DataSource(read.DataSource())
- .Object(std::move(s3Object))
- .RowType(std::move(userSchema.front()))
- .ColumnOrder(std::move(userSchema.back()))
- .Done().Ptr():
- Build<TS3ReadObject>(ctx, read.Pos())
- .World(read.World())
- .DataSource(read.DataSource())
- .Object(std::move(s3Object))
- .RowType(std::move(userSchema.front()))
- .Done().Ptr());
- }
- }
-
- YQL_CLOG(INFO, ProviderS3) << "Read " << count << " objects with total size is " << readSize;
-
- if (count > State_->Configuration->MaxFilesPerQuery) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Too many objects to read: " << count));
- return TStatus::Error;
- }
-
- if (readSize > State_->Configuration->MaxReadSizePerQuery) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Too large objects to read: " << readSize));
- return TStatus::Error;
- }
-
- return RemapExpr(input, output, replaces, ctx, TOptimizeExprSettings(nullptr));
- }
-private:
- const TS3State::TPtr State_;
- const IHTTPGateway::TPtr Gateway_;
-
+ return TStatus::Error;
+ } else if (const auto size = f->second; size > State_->Configuration->FileSizeLimit) {
+ ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << path << " size " << size << " is too large."));
+ return TStatus::Error;
+ } else {
+ YQL_CLOG(INFO, ProviderS3) << "Object " << path << " size is " << size;
+ readSize += size;
+ ++count;
+ paths.emplace_back(
+ ctx.Builder(object.Pos())
+ .List()
+ .Add(0, object.HeadPtr())
+ .Atom(1, ToString(size), TNodeFlags::Default)
+ .Seal()
+ .Build()
+ );
+ }
+
+ auto children = object.ChildrenList();
+ children.front() = ctx.NewList(object.Pos(), std::move(paths));
+ auto s3Object = ctx.NewCallable(object.Pos(), TS3Object::CallableName(), std::move(children));
+ auto userSchema = GetSchema(*read.Ref().Child(4));
+
+ replaces.emplace(r, userSchema.back() ?
+ Build<TS3ReadObject>(ctx, read.Pos())
+ .World(read.World())
+ .DataSource(read.DataSource())
+ .Object(std::move(s3Object))
+ .RowType(std::move(userSchema.front()))
+ .ColumnOrder(std::move(userSchema.back()))
+ .Done().Ptr():
+ Build<TS3ReadObject>(ctx, read.Pos())
+ .World(read.World())
+ .DataSource(read.DataSource())
+ .Object(std::move(s3Object))
+ .RowType(std::move(userSchema.front()))
+ .Done().Ptr());
+ }
+ }
+
+ YQL_CLOG(INFO, ProviderS3) << "Read " << count << " objects with total size is " << readSize;
+
+ if (count > State_->Configuration->MaxFilesPerQuery) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Too many objects to read: " << count));
+ return TStatus::Error;
+ }
+
+ if (readSize > State_->Configuration->MaxReadSizePerQuery) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Too large objects to read: " << readSize));
+ return TStatus::Error;
+ }
+
+ return RemapExpr(input, output, replaces, ctx, TOptimizeExprSettings(nullptr));
+ }
+private:
+ const TS3State::TPtr State_;
+ const IHTTPGateway::TPtr Gateway_;
+
const std::shared_ptr<TPendingBuckets> PendingBuckets_ = std::make_shared<TPendingBuckets>();
-
- NThreading::TFuture<void> AllFuture_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway) {
- return THolder(new TS3IODiscoveryTransformer(std::move(state), std::move(gateway)));
-}
-
-}
+
+ NThreading::TFuture<void> AllFuture_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway) {
+ return THolder(new TS3IODiscoveryTransformer(std::move(state), std::move(gateway)));
+}
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_logical_opt.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_logical_opt.cpp
index bd641909e9..a36f3bf686 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_logical_opt.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_logical_opt.cpp
@@ -1,5 +1,5 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
#include <ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
@@ -9,41 +9,41 @@
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/core/yql_opt_utils.h>
#include <ydb/library/yql/utils/log/log.h>
-
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TS3LogicalOptProposalTransformer : public TOptimizeTransformerBase {
-public:
- TS3LogicalOptProposalTransformer(TS3State::TPtr state)
- : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderS3, {})
- , State_(state)
- {
-#define HNDL(name) "LogicalOptimizer-"#name, Hndl(&TS3LogicalOptProposalTransformer::name)
- AddHandler(0, &TCoLeft::Match, HNDL(TrimReadWorld));
-#undef HNDL
- }
-
- TMaybeNode<TExprBase> TrimReadWorld(TExprBase node, TExprContext& ctx) const {
- const auto& maybeRead = node.Cast<TCoLeft>().Input().Maybe<TS3ReadObject>();
- if (!maybeRead) {
- return node;
- }
-
- return TExprBase(ctx.NewWorld(node.Pos()));
- }
-private:
- const TS3State::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateS3LogicalOptProposalTransformer(TS3State::TPtr state) {
- return MakeHolder<TS3LogicalOptProposalTransformer>(state);
-}
-
-} // namespace NYql
+
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TS3LogicalOptProposalTransformer : public TOptimizeTransformerBase {
+public:
+ TS3LogicalOptProposalTransformer(TS3State::TPtr state)
+ : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderS3, {})
+ , State_(state)
+ {
+#define HNDL(name) "LogicalOptimizer-"#name, Hndl(&TS3LogicalOptProposalTransformer::name)
+ AddHandler(0, &TCoLeft::Match, HNDL(TrimReadWorld));
+#undef HNDL
+ }
+
+ TMaybeNode<TExprBase> TrimReadWorld(TExprBase node, TExprContext& ctx) const {
+ const auto& maybeRead = node.Cast<TCoLeft>().Input().Maybe<TS3ReadObject>();
+ if (!maybeRead) {
+ return node;
+ }
+
+ return TExprBase(ctx.NewWorld(node.Pos()));
+ }
+private:
+ const TS3State::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateS3LogicalOptProposalTransformer(TS3State::TPtr state) {
+ return MakeHolder<TS3LogicalOptProposalTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.cpp
index 5686bba2f6..fab2d6d0f7 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.cpp
@@ -1,27 +1,27 @@
-#include "yql_s3_mkql_compiler.h"
-
+#include "yql_s3_mkql_compiler.h"
+
#include <ydb/library/yql/providers/s3/expr_nodes/yql_s3_expr_nodes.h>
#include <ydb/library/yql/providers/common/mkql/parser.h>
-
-#include <util/stream/str.h>
-
-namespace NYql {
-
-using namespace NKikimr::NMiniKQL;
-using namespace NNodes;
-
-void RegisterDqS3MkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TS3State::TPtr&) {
- compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
- [](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
- if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == S3ProviderName) {
+
+#include <util/stream/str.h>
+
+namespace NYql {
+
+using namespace NKikimr::NMiniKQL;
+using namespace NNodes;
+
+void RegisterDqS3MkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TS3State::TPtr&) {
+ compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
+ [](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
+ if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == S3ProviderName) {
const auto wrapped = TryWrapWithParser(wrapper, ctx);
if (wrapped) {
return *wrapped;
}
- }
-
- return TRuntimeNode();
- });
-}
-
-}
+ }
+
+ return TRuntimeNode();
+ });
+}
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.h b/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.h
index 63e6a3faf1..a51235d2a0 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.h
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_mkql_compiler.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "yql_s3_provider.h"
-
+#pragma once
+
+#include "yql_s3_provider.h"
+
#include <ydb/library/yql/providers/common/mkql/yql_provider_mkql.h>
-
-namespace NYql {
-
-void RegisterDqS3MkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TS3State::TPtr& state);
-
-}
+
+namespace NYql {
+
+void RegisterDqS3MkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TS3State::TPtr& state);
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_provider.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_provider.cpp
index c5e87f3a1f..4d70add3c0 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_provider.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_provider.cpp
@@ -1,44 +1,44 @@
-#include "yql_s3_provider.h"
+#include "yql_s3_provider.h"
#include <ydb/library/yql/providers/common/proto/gateways_config.pb.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
-
-namespace NYql {
-
-TDataProviderInitializer GetS3DataProviderInitializer(IHTTPGateway::TPtr gateway, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory) {
- return [gateway, credentialsFactory] (
- const TString& userName,
- const TString& sessionId,
- const TGatewaysConfig* gatewaysConfig,
- const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
- TIntrusivePtr<IRandomProvider> randomProvider,
- TIntrusivePtr<TTypeAnnotationContext> typeCtx,
- const TOperationProgressWriter& progressWriter,
- const TYqlOperationOptions& operationOptions)
- {
- Y_UNUSED(sessionId);
- Y_UNUSED(userName);
- Y_UNUSED(functionRegistry);
- Y_UNUSED(randomProvider);
- Y_UNUSED(progressWriter);
- Y_UNUSED(operationOptions);
-
- auto state = MakeIntrusive<TS3State>();
-
- state->Types = typeCtx.Get();
- state->FunctionRegistry = functionRegistry;
+
+namespace NYql {
+
+TDataProviderInitializer GetS3DataProviderInitializer(IHTTPGateway::TPtr gateway, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory) {
+ return [gateway, credentialsFactory] (
+ const TString& userName,
+ const TString& sessionId,
+ const TGatewaysConfig* gatewaysConfig,
+ const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
+ TIntrusivePtr<IRandomProvider> randomProvider,
+ TIntrusivePtr<TTypeAnnotationContext> typeCtx,
+ const TOperationProgressWriter& progressWriter,
+ const TYqlOperationOptions& operationOptions)
+ {
+ Y_UNUSED(sessionId);
+ Y_UNUSED(userName);
+ Y_UNUSED(functionRegistry);
+ Y_UNUSED(randomProvider);
+ Y_UNUSED(progressWriter);
+ Y_UNUSED(operationOptions);
+
+ auto state = MakeIntrusive<TS3State>();
+
+ state->Types = typeCtx.Get();
+ state->FunctionRegistry = functionRegistry;
state->CredentialsFactory = credentialsFactory;
- if (gatewaysConfig) {
+ if (gatewaysConfig) {
state->Configuration->Init(gatewaysConfig->GetS3(), typeCtx);
- }
-
- TDataProviderInfo info;
-
- info.Names.insert({TString{S3ProviderName}});
- info.Source = CreateS3DataSource(state, gateway);
- info.Sink = CreateS3DataSink(state);
-
- return info;
- };
-}
-
-} // namespace NYql
+ }
+
+ TDataProviderInfo info;
+
+ info.Names.insert({TString{S3ProviderName}});
+ info.Source = CreateS3DataSource(state, gateway);
+ info.Sink = CreateS3DataSink(state);
+
+ return info;
+ };
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_provider.h b/ydb/library/yql/providers/s3/provider/yql_s3_provider.h
index 367b0f455a..12cd74f805 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_provider.h
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_provider.h
@@ -1,37 +1,37 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/core/yql_data_provider.h>
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
-
-#include "yql_s3_settings.h"
-
-namespace NKikimr::NMiniKQL {
- class IFunctionRegistry;
-}
-
-namespace NYql {
-
-struct TS3State : public TThrRefBase
-{
- using TPtr = TIntrusivePtr<TS3State>;
-
- struct TTableMeta {
- const TStructExprType* ItemType = nullptr;
- TVector<TString> ColumnOrder;
- };
-
- std::unordered_map<std::pair<TString, TString>, TTableMeta, THash<std::pair<TString, TString>>> Tables;
-
- TTypeAnnotationContext* Types = nullptr;
- TS3Configuration::TPtr Configuration = MakeIntrusive<TS3Configuration>();
- const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry = nullptr;
+
+#include "yql_s3_settings.h"
+
+namespace NKikimr::NMiniKQL {
+ class IFunctionRegistry;
+}
+
+namespace NYql {
+
+struct TS3State : public TThrRefBase
+{
+ using TPtr = TIntrusivePtr<TS3State>;
+
+ struct TTableMeta {
+ const TStructExprType* ItemType = nullptr;
+ TVector<TString> ColumnOrder;
+ };
+
+ std::unordered_map<std::pair<TString, TString>, TTableMeta, THash<std::pair<TString, TString>>> Tables;
+
+ TTypeAnnotationContext* Types = nullptr;
+ TS3Configuration::TPtr Configuration = MakeIntrusive<TS3Configuration>();
+ const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry = nullptr;
ISecuredServiceAccountCredentialsFactory::TPtr CredentialsFactory;
-};
-
-TDataProviderInitializer GetS3DataProviderInitializer(IHTTPGateway::TPtr gateway, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory = nullptr);
-
-TIntrusivePtr<IDataProvider> CreateS3DataSource(TS3State::TPtr state, IHTTPGateway::TPtr gateway);
-TIntrusivePtr<IDataProvider> CreateS3DataSink(TS3State::TPtr state);
-
-} // namespace NYql
+};
+
+TDataProviderInitializer GetS3DataProviderInitializer(IHTTPGateway::TPtr gateway, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory = nullptr);
+
+TIntrusivePtr<IDataProvider> CreateS3DataSource(TS3State::TPtr state, IHTTPGateway::TPtr gateway);
+TIntrusivePtr<IDataProvider> CreateS3DataSink(TS3State::TPtr state);
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.cpp
index 643fa812c2..6c59efc837 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.cpp
@@ -1,7 +1,7 @@
-#include "yql_s3_provider_impl.h"
-
+#include "yql_s3_provider_impl.h"
+
#include <ydb/library/yql/providers/common/schema/expr/yql_expr_schema.h>
-
-namespace NYql {
-
-}
+
+namespace NYql {
+
+}
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.h b/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.h
index 2f7d5be153..732615b23f 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.h
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_provider_impl.h
@@ -1,24 +1,24 @@
-#pragma once
-
-#include "yql_s3_provider.h"
+#pragma once
+
+#include "yql_s3_provider.h"
#include <ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
-
+
#include <ydb/library/yql/core/yql_graph_transformer.h>
#include <ydb/library/yql/providers/common/transform/yql_exec.h>
#include <ydb/library/yql/providers/common/transform/yql_visit.h>
-
-#include <util/generic/ptr.h>
-
-namespace NYql {
-
-THolder<TVisitorTransformerBase> CreateS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state);
-THolder<TVisitorTransformerBase> CreateS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state);
-
-THolder<TExecTransformerBase> CreateS3DataSinkExecTransformer(TS3State::TPtr state);
-
-THolder<IGraphTransformer> CreateS3LogicalOptProposalTransformer(TS3State::TPtr state);
-THolder<IGraphTransformer> CreateS3SourceCallableExecutionTransformer(TS3State::TPtr state);
-THolder<IGraphTransformer> CreateS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway);
-
-
-} // namespace NYql
+
+#include <util/generic/ptr.h>
+
+namespace NYql {
+
+THolder<TVisitorTransformerBase> CreateS3DataSourceTypeAnnotationTransformer(TS3State::TPtr state);
+THolder<TVisitorTransformerBase> CreateS3DataSinkTypeAnnotationTransformer(TS3State::TPtr state);
+
+THolder<TExecTransformerBase> CreateS3DataSinkExecTransformer(TS3State::TPtr state);
+
+THolder<IGraphTransformer> CreateS3LogicalOptProposalTransformer(TS3State::TPtr state);
+THolder<IGraphTransformer> CreateS3SourceCallableExecutionTransformer(TS3State::TPtr state);
+THolder<IGraphTransformer> CreateS3IODiscoveryTransformer(TS3State::TPtr state, IHTTPGateway::TPtr gateway);
+
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_settings.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_settings.cpp
index f37947d2ff..99c308eaf3 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_settings.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_settings.cpp
@@ -1,49 +1,49 @@
-#include "yql_s3_settings.h"
+#include "yql_s3_settings.h"
#include <ydb/library/yql/providers/common/structured_token/yql_token_builder.h>
-#include <util/generic/size_literals.h>
-
-namespace NYql {
-
-using namespace NCommon;
-
-TS3Configuration::TS3Configuration()
-{
- REGISTER_SETTING(*this, SourceActor);
-}
-
-TS3Settings::TConstPtr TS3Configuration::Snapshot() const {
+#include <util/generic/size_literals.h>
+
+namespace NYql {
+
+using namespace NCommon;
+
+TS3Configuration::TS3Configuration()
+{
+ REGISTER_SETTING(*this, SourceActor);
+}
+
+TS3Settings::TConstPtr TS3Configuration::Snapshot() const {
return std::make_shared<const TS3Settings>(*this);
-}
-
-bool TS3Configuration::HasCluster(TStringBuf cluster) const {
- return ValidClusters.contains(cluster);
-}
-
+}
+
+bool TS3Configuration::HasCluster(TStringBuf cluster) const {
+ return ValidClusters.contains(cluster);
+}
+
void TS3Configuration::Init(const TS3GatewayConfig& config, TIntrusivePtr<TTypeAnnotationContext> typeCtx)
-{
- FileSizeLimit = config.HasFileSizeLimit() ? config.GetFileSizeLimit() : 2_GB;
- MaxFilesPerQuery = config.HasMaxFilesPerQuery() ? config.GetMaxFilesPerQuery() : 7000;
- MaxReadSizePerQuery = config.HasMaxReadSizePerQuery() ? config.GetMaxReadSizePerQuery() : 4_GB;
-
- TVector<TString> clusters(Reserve(config.ClusterMappingSize()));
- for (auto& cluster: config.GetClusterMapping()) {
- clusters.push_back(cluster.GetName());
- }
-
- this->SetValidClusters(clusters);
- this->Dispatch(config.GetDefaultSettings());
-
- for (const auto& cluster: config.GetClusterMapping()) {
- this->Dispatch(cluster.GetName(), cluster.GetSettings());
- auto& settings = Clusters[cluster.GetName()];
- settings.Url = cluster.GetUrl();
+{
+ FileSizeLimit = config.HasFileSizeLimit() ? config.GetFileSizeLimit() : 2_GB;
+ MaxFilesPerQuery = config.HasMaxFilesPerQuery() ? config.GetMaxFilesPerQuery() : 7000;
+ MaxReadSizePerQuery = config.HasMaxReadSizePerQuery() ? config.GetMaxReadSizePerQuery() : 4_GB;
+
+ TVector<TString> clusters(Reserve(config.ClusterMappingSize()));
+ for (auto& cluster: config.GetClusterMapping()) {
+ clusters.push_back(cluster.GetName());
+ }
+
+ this->SetValidClusters(clusters);
+ this->Dispatch(config.GetDefaultSettings());
+
+ for (const auto& cluster: config.GetClusterMapping()) {
+ this->Dispatch(cluster.GetName(), cluster.GetSettings());
+ auto& settings = Clusters[cluster.GetName()];
+ settings.Url = cluster.GetUrl();
TString authToken;
- if (const auto& token = cluster.GetToken()) {
- authToken = typeCtx->FindCredentialContent("cluster:default_" + cluster.GetName(), "", token);
+ if (const auto& token = cluster.GetToken()) {
+ authToken = typeCtx->FindCredentialContent("cluster:default_" + cluster.GetName(), "", token);
}
Tokens[cluster.GetName()] = ComposeStructuredTokenJsonForServiceAccount(cluster.GetServiceAccountId(), cluster.GetServiceAccountIdSignature(), authToken);
- }
- this->FreezeDefaults();
-}
-
-} // NYql
+ }
+ this->FreezeDefaults();
+}
+
+} // NYql
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_settings.h b/ydb/library/yql/providers/s3/provider/yql_s3_settings.h
index 67d6a6c6bd..9bbcb72c87 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_settings.h
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_settings.h
@@ -1,39 +1,39 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/providers/common/config/yql_dispatch.h>
#include <ydb/library/yql/providers/common/config/yql_setting.h>
-
+
#include <ydb/library/yql/providers/common/proto/gateways_config.pb.h>
-
-namespace NYql {
-
-struct TS3Settings {
+
+namespace NYql {
+
+struct TS3Settings {
using TConstPtr = std::shared_ptr<const TS3Settings>;
-
- NCommon::TConfSetting<bool, false> SourceActor;
-};
-
-struct TS3ClusterSettings {
- TString Url, Token;
-};
-
-struct TS3Configuration : public TS3Settings, public NCommon::TSettingDispatcher {
- using TPtr = TIntrusivePtr<TS3Configuration>;
-
- TS3Configuration();
- TS3Configuration(const TS3Configuration&) = delete;
-
+
+ NCommon::TConfSetting<bool, false> SourceActor;
+};
+
+struct TS3ClusterSettings {
+ TString Url, Token;
+};
+
+struct TS3Configuration : public TS3Settings, public NCommon::TSettingDispatcher {
+ using TPtr = TIntrusivePtr<TS3Configuration>;
+
+ TS3Configuration();
+ TS3Configuration(const TS3Configuration&) = delete;
+
void Init(const TS3GatewayConfig& config, TIntrusivePtr<TTypeAnnotationContext> typeCtx);
-
- bool HasCluster(TStringBuf cluster) const;
-
- TS3Settings::TConstPtr Snapshot() const;
- THashMap<TString, TString> Tokens;
- std::unordered_map<TString, TS3ClusterSettings> Clusters;
-
- ui64 FileSizeLimit;
- ui32 MaxFilesPerQuery;
- ui64 MaxReadSizePerQuery;
-};
-
-} // NYql
+
+ bool HasCluster(TStringBuf cluster) const;
+
+ TS3Settings::TConstPtr Snapshot() const;
+ THashMap<TString, TString> Tokens;
+ std::unordered_map<TString, TS3ClusterSettings> Clusters;
+
+ ui64 FileSizeLimit;
+ ui32 MaxFilesPerQuery;
+ ui64 MaxReadSizePerQuery;
+};
+
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/actors/ya.make b/ydb/library/yql/providers/ydb/actors/ya.make
index 668ee16517..78cee743d6 100644
--- a/ydb/library/yql/providers/ydb/actors/ya.make
+++ b/ydb/library/yql/providers/ydb/actors/ya.make
@@ -1,13 +1,13 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(g:yql)
-
-SRCS(
- yql_ydb_read_actor.cpp
- yql_ydb_source_factory.cpp
-)
-
-PEERDIR(
+
+SRCS(
+ yql_ydb_read_actor.cpp
+ yql_ydb_source_factory.cpp
+)
+
+PEERDIR(
ydb/core/scheme
ydb/library/yql/minikql/computation
ydb/library/yql/providers/common/token_accessor/client
@@ -17,8 +17,8 @@ PEERDIR(
ydb/public/sdk/cpp/client/ydb_driver
ydb/library/yql/dq/actors/compute
ydb/library/yql/providers/ydb/proto
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.cpp b/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.cpp
index 657b95a8dd..7ab55cfcfc 100644
--- a/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.cpp
+++ b/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.cpp
@@ -1,268 +1,268 @@
-#include "yql_ydb_read_actor.h"
-
+#include "yql_ydb_read_actor.h"
+
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/utils/yql_panic.h>
#include <ydb/library/yql/providers/ydb/proto/range.pb.h>
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/core/hfunc.h>
-
+
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/events.h>
+#include <library/cpp/actors/core/event_local.h>
+#include <library/cpp/actors/core/hfunc.h>
+
#include <ydb/public/lib/experimental/ydb_clickhouse_internal.h>
#include <ydb/public/lib/experimental/ydb_experimental.h>
#include <ydb/core/scheme/scheme_tablecell.h>
-#include <util/generic/size_literals.h>
-
-#include <queue>
-
-namespace NYql::NDq {
-
-using namespace NActors;
-
-namespace {
-
-struct TEvPrivate {
- // Event ids
- enum EEv : ui32 {
- EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
-
- EvScanResult = EvBegin,
- EvRetryTime,
-
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
-
- // Events
- struct TEvScanResult : public TEventLocal<TEvScanResult, EvScanResult>, public ::NYdb::NClickhouseInternal::TScanResult {
- TEvScanResult(::NYdb::NClickhouseInternal::TScanResult&& result): TScanResult(std::move(result)) {}
- };
-
- struct TEvRetryTime : public TEventLocal<TEvRetryTime, EvRetryTime> {};
-};
-
-bool IsRetriable(::NYdb::EStatus status) {
- switch (status) {
- case ::NYdb::EStatus::BAD_REQUEST:
- case ::NYdb::EStatus::SCHEME_ERROR:
- case ::NYdb::EStatus::UNAUTHORIZED:
- case ::NYdb::EStatus::NOT_FOUND:
- return false;
- default:
- return true;
- }
-}
-
-bool RangeFinished(const TString& lastReadKey, const TString& endKey, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes) {
- if (lastReadKey.empty())
- return true;
-
- if (endKey.empty())
- return false;
-
- const NKikimr::TSerializedCellVec last(lastReadKey), end(endKey);
- return NKikimr::CompareTypedCellVectors(last.GetCells().data(), end.GetCells().data(), keyColumnTypes.data(), last.GetCells().size(), end.GetCells().size()) >= 0;
-}
-
-} // namespace
-
-class TYdbReadActor : public TActorBootstrapped<TYdbReadActor>, public IDqSourceActor {
-public:
- TYdbReadActor(
- ui64 inputIndex,
- const TString& database,
- const TString& endpoint,
+#include <util/generic/size_literals.h>
+
+#include <queue>
+
+namespace NYql::NDq {
+
+using namespace NActors;
+
+namespace {
+
+struct TEvPrivate {
+ // Event ids
+ enum EEv : ui32 {
+ EvBegin = EventSpaceBegin(TEvents::ES_PRIVATE),
+
+ EvScanResult = EvBegin,
+ EvRetryTime,
+
+ EvEnd
+ };
+
+ static_assert(EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
+
+ // Events
+ struct TEvScanResult : public TEventLocal<TEvScanResult, EvScanResult>, public ::NYdb::NClickhouseInternal::TScanResult {
+ TEvScanResult(::NYdb::NClickhouseInternal::TScanResult&& result): TScanResult(std::move(result)) {}
+ };
+
+ struct TEvRetryTime : public TEventLocal<TEvRetryTime, EvRetryTime> {};
+};
+
+bool IsRetriable(::NYdb::EStatus status) {
+ switch (status) {
+ case ::NYdb::EStatus::BAD_REQUEST:
+ case ::NYdb::EStatus::SCHEME_ERROR:
+ case ::NYdb::EStatus::UNAUTHORIZED:
+ case ::NYdb::EStatus::NOT_FOUND:
+ return false;
+ default:
+ return true;
+ }
+}
+
+bool RangeFinished(const TString& lastReadKey, const TString& endKey, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes) {
+ if (lastReadKey.empty())
+ return true;
+
+ if (endKey.empty())
+ return false;
+
+ const NKikimr::TSerializedCellVec last(lastReadKey), end(endKey);
+ return NKikimr::CompareTypedCellVectors(last.GetCells().data(), end.GetCells().data(), keyColumnTypes.data(), last.GetCells().size(), end.GetCells().size()) >= 0;
+}
+
+} // namespace
+
+class TYdbReadActor : public TActorBootstrapped<TYdbReadActor>, public IDqSourceActor {
+public:
+ TYdbReadActor(
+ ui64 inputIndex,
+ const TString& database,
+ const TString& endpoint,
std::shared_ptr<::NYdb::ICredentialsProviderFactory> credentialsProviderFactory,
- bool secure,
- const TString& path,
- ::NYdb::TDriver driver,
- ICallbacks* callbacks,
- const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo
- )
- : InputIndex(inputIndex)
- , Callbacks(callbacks)
- , ActorSystem(TActivationContext::ActorSystem())
- , Path(path), Columns(columns), KeyColumnTypes(keyColumnTypes)
- , MaxRows(maxRowsInRequest), MaxBytes(maxBytesInRequest)
- , EndKey(keyTo)
+ bool secure,
+ const TString& path,
+ ::NYdb::TDriver driver,
+ ICallbacks* callbacks,
+ const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo
+ )
+ : InputIndex(inputIndex)
+ , Callbacks(callbacks)
+ , ActorSystem(TActivationContext::ActorSystem())
+ , Path(path), Columns(columns), KeyColumnTypes(keyColumnTypes)
+ , MaxRows(maxRowsInRequest), MaxBytes(maxBytesInRequest)
+ , EndKey(keyTo)
, Connection(driver, ::NYdb::TCommonClientSettings().Database(database).DiscoveryEndpoint(endpoint).CredentialsProviderFactory(credentialsProviderFactory).DiscoveryMode(::NYdb::EDiscoveryMode::Async).EnableSsl(secure))
- , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
- , LastReadKeyInclusive(false)
- , Retried(0U)
- , WakeUpTime(TMonotonic::Now())
- , RequestSent(false)
- , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
- , MemoryUsed(0U)
- {}
-
- void Bootstrap() {
- Become(&TYdbReadActor::StateFunc);
- SendRequest();
- }
+ , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
+ , LastReadKeyInclusive(false)
+ , Retried(0U)
+ , WakeUpTime(TMonotonic::Now())
+ , RequestSent(false)
+ , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
+ , MemoryUsed(0U)
+ {}
+
+ void Bootstrap() {
+ Become(&TYdbReadActor::StateFunc);
+ SendRequest();
+ }
static constexpr char ActorName[] = "YQL_YDB_READ_ACTOR";
-private:
+private:
void SaveState(const NDqProto::TCheckpoint&, NDqProto::TSourceState&) final {}
void LoadState(const NDqProto::TSourceState&) final {}
- void CommitState(const NDqProto::TCheckpoint&) final {}
- ui64 GetInputIndex() const final { return InputIndex; }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvPrivate::TEvScanResult, Handle);
- hFunc(TEvPrivate::TEvRetryTime, Handle);
- )
-
- void Handle(TEvPrivate::TEvRetryTime::TPtr&) {
- SendRequest();
- }
-
+ void CommitState(const NDqProto::TCheckpoint&) final {}
+ ui64 GetInputIndex() const final { return InputIndex; }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvPrivate::TEvScanResult, Handle);
+ hFunc(TEvPrivate::TEvRetryTime, Handle);
+ )
+
+ void Handle(TEvPrivate::TEvRetryTime::TPtr&) {
+ SendRequest();
+ }
+
// IActor & IDqSourceActor
void PassAway() override { // Is called from Compute Actor
- RequestsDone = true;
+ RequestsDone = true;
TActorBootstrapped<TYdbReadActor>::PassAway();
- }
-
- i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
- i64 total = 0LL;
- if (!Blocks.empty()) {
- buffer.reserve(buffer.size() + Blocks.size());
- do {
- const auto size = Blocks.front().size();
- buffer.emplace_back(NKikimr::NMiniKQL::MakeString(Blocks.front()));
- Blocks.pop();
- total += size;
- freeSpace -= size;
- MemoryUsed -= size;
- } while (!Blocks.empty() && freeSpace > 0LL);
- }
-
- if (RequestsDone && Blocks.empty()) {
- finished = true;
- }
-
- SendRequest();
- return total;
- }
-
- void SendRequest() {
- if (!RequestsDone && !RequestSent && MemoryUsed < MaxQueueVolume && WakeUpTime <= TMonotonic::Now()) {
- RequestSent = true;
- Connection.Scan(Path, Columns, MaxRows, MaxBytes, LastReadKey, !LastReadKeyInclusive, Settings).Subscribe(std::bind(&TYdbReadActor::OnRespond, ActorSystem, SelfId(), std::placeholders::_1));
- }
- }
-
- static void OnRespond(TActorSystem* ass, const TActorId& selfId, const ::NYdb::NClickhouseInternal::TAsyncScanResult& result) {
- ass->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvScanResult(const_cast<::NYdb::NClickhouseInternal::TAsyncScanResult&>(result).ExtractValueSync())));
- }
-
- void Handle(TEvPrivate::TEvScanResult::TPtr& result) {
- if (const auto& res = *result->Get(); res.GetStatus() == ::NYdb::EStatus::SUCCESS)
- ProcessResult(res);
- else
- ProcessError(res);
- }
-
- void ProcessResult(const ::NYdb::NClickhouseInternal::TScanResult& res) {
- RequestSent = false;
- Retried = 0U;
-
- const auto bc = res.GetBuffersCount();
- const bool notify = Blocks.empty();
- for (size_t i = 0U; i < bc; ++i) {
- if (auto block = res.GetBuffer(i); !block.empty()) {
- MemoryUsed += block.size();
- Blocks.emplace(std::move(block));
- }
- }
-
- std::tie(LastReadKey, LastReadKeyInclusive) = res.GetLastKey();
- RequestsDone = res.IsEos() || RangeFinished(LastReadKey, EndKey, KeyColumnTypes);
- SendRequest();
- if (notify)
- Callbacks->OnNewSourceDataArrived(InputIndex);
- }
-
- void ProcessError(const ::NYdb::NClickhouseInternal::TScanResult& res) {
- RequestSent = false;
- if (!IsRetriable(res.GetStatus()) || Retried > MaxRetries) {
- RequestsDone = true;
- while(!Blocks.empty())
- Blocks.pop();
+ }
+
+ i64 GetSourceData(NKikimr::NMiniKQL::TUnboxedValueVector& buffer, bool& finished, i64 freeSpace) final {
+ i64 total = 0LL;
+ if (!Blocks.empty()) {
+ buffer.reserve(buffer.size() + Blocks.size());
+ do {
+ const auto size = Blocks.front().size();
+ buffer.emplace_back(NKikimr::NMiniKQL::MakeString(Blocks.front()));
+ Blocks.pop();
+ total += size;
+ freeSpace -= size;
+ MemoryUsed -= size;
+ } while (!Blocks.empty() && freeSpace > 0LL);
+ }
+
+ if (RequestsDone && Blocks.empty()) {
+ finished = true;
+ }
+
+ SendRequest();
+ return total;
+ }
+
+ void SendRequest() {
+ if (!RequestsDone && !RequestSent && MemoryUsed < MaxQueueVolume && WakeUpTime <= TMonotonic::Now()) {
+ RequestSent = true;
+ Connection.Scan(Path, Columns, MaxRows, MaxBytes, LastReadKey, !LastReadKeyInclusive, Settings).Subscribe(std::bind(&TYdbReadActor::OnRespond, ActorSystem, SelfId(), std::placeholders::_1));
+ }
+ }
+
+ static void OnRespond(TActorSystem* ass, const TActorId& selfId, const ::NYdb::NClickhouseInternal::TAsyncScanResult& result) {
+ ass->Send(new IEventHandle(selfId, TActorId(), new TEvPrivate::TEvScanResult(const_cast<::NYdb::NClickhouseInternal::TAsyncScanResult&>(result).ExtractValueSync())));
+ }
+
+ void Handle(TEvPrivate::TEvScanResult::TPtr& result) {
+ if (const auto& res = *result->Get(); res.GetStatus() == ::NYdb::EStatus::SUCCESS)
+ ProcessResult(res);
+ else
+ ProcessError(res);
+ }
+
+ void ProcessResult(const ::NYdb::NClickhouseInternal::TScanResult& res) {
+ RequestSent = false;
+ Retried = 0U;
+
+ const auto bc = res.GetBuffersCount();
+ const bool notify = Blocks.empty();
+ for (size_t i = 0U; i < bc; ++i) {
+ if (auto block = res.GetBuffer(i); !block.empty()) {
+ MemoryUsed += block.size();
+ Blocks.emplace(std::move(block));
+ }
+ }
+
+ std::tie(LastReadKey, LastReadKeyInclusive) = res.GetLastKey();
+ RequestsDone = res.IsEos() || RangeFinished(LastReadKey, EndKey, KeyColumnTypes);
+ SendRequest();
+ if (notify)
+ Callbacks->OnNewSourceDataArrived(InputIndex);
+ }
+
+ void ProcessError(const ::NYdb::NClickhouseInternal::TScanResult& res) {
+ RequestSent = false;
+ if (!IsRetriable(res.GetStatus()) || Retried > MaxRetries) {
+ RequestsDone = true;
+ while(!Blocks.empty())
+ Blocks.pop();
Callbacks->OnSourceError(InputIndex, res.GetIssues(), true);
- } else {
- WakeUpTime = TMonotonic::Now() + Min(TDuration::Seconds(3), TDuration::MilliSeconds(0x30U * (1U << ++Retried)));
- ActorSystem->Schedule(WakeUpTime, new IEventHandle(SelfId(), TActorId(), new TEvPrivate::TEvRetryTime));
- }
- }
-
- static constexpr auto MaxRetries = 0x10U;
- static constexpr auto MaxQueueVolume = 4_MB;
-
- const ui64 InputIndex;
- ICallbacks *const Callbacks;
-
- TActorSystem* const ActorSystem;
-
- const TString Path;
- const TVector<TString> Columns;
- const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
- const ui64 MaxRows;
- const ui64 MaxBytes;
- const TString EndKey;
- const ::NYdb::NClickhouseInternal::TScanSettings Settings;
-
- ::NYdb::NClickhouseInternal::TScanClient Connection;
-
- TString LastReadKey;
- bool LastReadKeyInclusive;
- size_t Retried;
-
- TMonotonic WakeUpTime;
- bool RequestSent;
- bool RequestsDone;
- size_t MemoryUsed;
-
- std::queue<TString> Blocks;
-};
-
-std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateYdbReadActor(
- NYql::NYdb::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
- NYql::NDq::IDqSourceActor::ICallbacks* callback,
+ } else {
+ WakeUpTime = TMonotonic::Now() + Min(TDuration::Seconds(3), TDuration::MilliSeconds(0x30U * (1U << ++Retried)));
+ ActorSystem->Schedule(WakeUpTime, new IEventHandle(SelfId(), TActorId(), new TEvPrivate::TEvRetryTime));
+ }
+ }
+
+ static constexpr auto MaxRetries = 0x10U;
+ static constexpr auto MaxQueueVolume = 4_MB;
+
+ const ui64 InputIndex;
+ ICallbacks *const Callbacks;
+
+ TActorSystem* const ActorSystem;
+
+ const TString Path;
+ const TVector<TString> Columns;
+ const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
+ const ui64 MaxRows;
+ const ui64 MaxBytes;
+ const TString EndKey;
+ const ::NYdb::NClickhouseInternal::TScanSettings Settings;
+
+ ::NYdb::NClickhouseInternal::TScanClient Connection;
+
+ TString LastReadKey;
+ bool LastReadKeyInclusive;
+ size_t Retried;
+
+ TMonotonic WakeUpTime;
+ bool RequestSent;
+ bool RequestsDone;
+ size_t MemoryUsed;
+
+ std::queue<TString> Blocks;
+};
+
+std::pair<NYql::NDq::IDqSourceActor*, IActor*> CreateYdbReadActor(
+ NYql::NYdb::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
+ NYql::NDq::IDqSourceActor::ICallbacks* callback,
::NYdb::TDriver driver,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory)
-{
- TString keyFrom, keyTo;
- if (const auto taskParamsIt = taskParams.find("ydb"); taskParamsIt != taskParams.cend()) {
- NYql::NYdb::TKeyRange range;
- TStringInput input(taskParamsIt->second);
- range.Load(&input);
- keyFrom = range.Getfrom_key();
- keyTo = range.Getto_key();
- }
-
+{
+ TString keyFrom, keyTo;
+ if (const auto taskParamsIt = taskParams.find("ydb"); taskParamsIt != taskParams.cend()) {
+ NYql::NYdb::TKeyRange range;
+ TStringInput input(taskParamsIt->second);
+ range.Load(&input);
+ keyFrom = range.Getfrom_key();
+ keyTo = range.Getto_key();
+ }
+
auto token = secureParams.Value(params.GetToken(), TString{});
auto credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(credentialsFactory, token, params.GetAddBearerToToken());
- TVector<TString> columns;
- columns.reserve(params.GetColumns().size());
- for (auto i = 0; i < params.GetColumns().size(); ++i)
- columns.emplace_back(params.GetColumns().Get(i));
-
- TVector<NKikimr::NScheme::TTypeId> keyColumnTypes;
- keyColumnTypes.reserve(params.GetKeyColumnTypes().size());
- for (auto i = 0; i < params.GetKeyColumnTypes().size(); ++i)
- keyColumnTypes.emplace_back(params.GetKeyColumnTypes().Get(i));
-
- ui64 maxRowsInRequest = 0ULL;
- ui64 maxBytesInRequest = 0ULL;
+ TVector<TString> columns;
+ columns.reserve(params.GetColumns().size());
+ for (auto i = 0; i < params.GetColumns().size(); ++i)
+ columns.emplace_back(params.GetColumns().Get(i));
+
+ TVector<NKikimr::NScheme::TTypeId> keyColumnTypes;
+ keyColumnTypes.reserve(params.GetKeyColumnTypes().size());
+ for (auto i = 0; i < params.GetKeyColumnTypes().size(); ++i)
+ keyColumnTypes.emplace_back(params.GetKeyColumnTypes().Get(i));
+
+ ui64 maxRowsInRequest = 0ULL;
+ ui64 maxBytesInRequest = 0ULL;
const auto actor = new TYdbReadActor(inputIndex, params.GetDatabase(), params.GetEndpoint(), credentialsProviderFactory, params.GetSecure(), params.GetTable(), std::move(driver), callback, columns, keyColumnTypes, maxRowsInRequest, maxBytesInRequest, keyFrom, keyTo);
- return {actor, actor};
-}
-
-} // namespace NYql::NDq
+ return {actor, actor};
+}
+
+} // namespace NYql::NDq
diff --git a/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.h b/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.h
index c84d9c50aa..67ff7ed699 100644
--- a/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.h
+++ b/ydb/library/yql/providers/ydb/actors/yql_ydb_read_actor.h
@@ -1,21 +1,21 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
#include <ydb/library/yql/providers/ydb/proto/source.pb.h>
-#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/actor.h>
#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
-
-namespace NYql::NDq {
-
-std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateYdbReadActor(
- NYql::NYdb::TSource&& params,
- ui64 inputIndex,
- const THashMap<TString, TString>& secureParams,
- const THashMap<TString, TString>& taskParams,
- NYql::NDq::IDqSourceActor::ICallbacks* callback,
+
+namespace NYql::NDq {
+
+std::pair<NYql::NDq::IDqSourceActor*, NActors::IActor*> CreateYdbReadActor(
+ NYql::NYdb::TSource&& params,
+ ui64 inputIndex,
+ const THashMap<TString, TString>& secureParams,
+ const THashMap<TString, TString>& taskParams,
+ NYql::NDq::IDqSourceActor::ICallbacks* callback,
::NYdb::TDriver driver,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory);
-
-} // namespace NYql::NDq
+
+} // namespace NYql::NDq
diff --git a/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.cpp b/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.cpp
index f20c037221..022df27783 100644
--- a/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.cpp
+++ b/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.cpp
@@ -1,15 +1,15 @@
-#include "yql_ydb_source_factory.h"
-#include "yql_ydb_read_actor.h"
-
+#include "yql_ydb_source_factory.h"
+#include "yql_ydb_read_actor.h"
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
-namespace NYql::NDq {
-
+namespace NYql::NDq {
+
void RegisterYdbReadActorFactory(NYql::NDq::TDqSourceFactory& factory, ::NYdb::TDriver driver, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory) {
- factory.Register<NYql::NYdb::TSource>("YdbSource",
+ factory.Register<NYql::NYdb::TSource>("YdbSource",
[driver, credentialsFactory](NYql::NYdb::TSource&& settings, IDqSourceActorFactory::TArguments&& args) {
return CreateYdbReadActor(std::move(settings), args.InputIndex, args.SecureParams, args.TaskParams, args.Callback, driver, credentialsFactory);
- });
-}
-
-}
+ });
+}
+
+}
diff --git a/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.h b/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.h
index 7ff0f603a7..6bf59880dd 100644
--- a/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.h
+++ b/ydb/library/yql/providers/ydb/actors/yql_ydb_source_factory.h
@@ -1,14 +1,14 @@
-#pragma once
-
+#pragma once
+
#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_io_actors_factory.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor_sources.h>
-
+
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
-namespace NYql::NDq {
-
+namespace NYql::NDq {
+
void RegisterYdbReadActorFactory(NYql::NDq::TDqSourceFactory& factory, NYdb::TDriver driver, ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory);
-
-}
+
+}
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/ya.make b/ydb/library/yql/providers/ydb/comp_nodes/ya.make
index dd5215f904..7ec0702507 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/ya.make
+++ b/ydb/library/yql/providers/ydb/comp_nodes/ya.make
@@ -1,8 +1,8 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(g:yql)
-
-PEERDIR(
+
+PEERDIR(
ydb/core/scheme
ydb/library/yql/minikql
ydb/library/yql/minikql/computation
@@ -10,14 +10,14 @@ PEERDIR(
ydb/public/lib/experimental
ydb/public/sdk/cpp/client/ydb_driver
ydb/library/yql/providers/ydb/proto
-)
-
-SRCS(
- yql_kik_scan.cpp
- yql_ydb_factory.cpp
- yql_ydb_dq_transform.cpp
-)
-
-YQL_LAST_ABI_VERSION()
-
-END()
+)
+
+SRCS(
+ yql_kik_scan.cpp
+ yql_ydb_factory.cpp
+ yql_ydb_dq_transform.cpp
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.cpp b/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.cpp
index 023962b666..43343ab228 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.cpp
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.cpp
@@ -1,263 +1,263 @@
-#include "yql_kik_scan.h"
-
+#include "yql_kik_scan.h"
+
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor.h>
#include <ydb/library/yql/providers/common/structured_token/yql_token_builder.h>
-
+
#include <ydb/public/lib/experimental/ydb_clickhouse_internal.h>
#include <ydb/public/lib/experimental/ydb_experimental.h>
-
+
#include <ydb/core/scheme/scheme_tablecell.h>
-
-#include <library/cpp/actors/core/actor.h>
-
-#include <queue>
-#include <mutex>
-
-namespace NYql::NDqs {
-using namespace NKikimr::NMiniKQL;
-
-namespace {
-
-bool IsRetriable(NYdb::EStatus status) {
- switch (status) {
- case NYdb::EStatus::BAD_REQUEST:
- case NYdb::EStatus::SCHEME_ERROR:
- case NYdb::EStatus::UNAUTHORIZED:
- case NYdb::EStatus::NOT_FOUND:
- return false;
- default:
- return true;
- }
-}
-
-bool RangeFinished(const TString& lastReadKey, const TString& endKey, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes) {
- if (lastReadKey.empty())
- return true;
-
- if (endKey.empty())
- return false;
-
- const NKikimr::TSerializedCellVec last(lastReadKey), end(endKey);
- return NKikimr::CompareTypedCellVectors(last.GetCells().data(), end.GetCells().data(), keyColumnTypes.data(), last.GetCells().size(), end.GetCells().size()) >= 0;
-}
-
-template<bool Async>
-class TKikScan : public TMutableComputationNode<TKikScan<Async>> {
-using TBaseComputation = TMutableComputationNode<TKikScan<Async>>;
- class TStream: public TComputationValue<TStream> {
- public:
- TStream(TMemoryUsageInfo* memInfo, NYdb::NClickhouseInternal::TScanIterator iterator)
- : TComputationValue<TStream>(memInfo), Iterator_(std::move(iterator))
- {}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final try {
- if (const auto blocks = Iterator_.GetBlocks(); !blocks.empty()) {
- result = MakeString(blocks);
- return NUdf::EFetchStatus::Ok;
- }
-
- return NUdf::EFetchStatus::Finish;
- } catch (const std::exception& ex) {
- UdfTerminate(ex.what());
- }
-
- NYdb::NClickhouseInternal::TScanIterator Iterator_;
- };
-
- class TAsyncStream: public TComputationValue<TAsyncStream> {
- class TAsyncState : public std::enable_shared_from_this<TAsyncState> {
- public:
- using TPtr = std::shared_ptr<TAsyncState>;
- using TWeakPtr = std::weak_ptr<TAsyncState>;
-
- static TPtr Make(const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings) {
- const auto ptr = std::make_shared<TAsyncState>(driver, database, endpoint, token, path, secure, columns, keyColumnTypes, maxRowsInRequest, maxBytesInRequest, keyFrom, keyTo, settings);
- ptr->SendRequest();
- return ptr;
- }
-
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) {
- const std::unique_lock lock(Sync);
- if (!Blocks.empty()) {
- const auto& block = Blocks.front();
- MemoryUsed -= block.size();
- result = MakeString(block);
- Blocks.pop();
- SendRequest();
- return NUdf::EFetchStatus::Ok;
- }
-
- if (RequestsDone)
- return NUdf::EFetchStatus::Finish;
-
- if (Issues)
- UdfTerminate(Issues.ToString().c_str());
-
- SendRequest();
- return NUdf::EFetchStatus::Yield;
- }
-
- TAsyncState(const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings)
- : ActorSystem(NActors::TActivationContext::ActorSystem())
- , CurrentActorId(NActors::TActivationContext::AsActorContext().SelfID)
- , Path(path)
- , Columns(columns)
- , KeyColumnTypes(keyColumnTypes)
- , MaxRows(maxRowsInRequest)
- , MaxBytes(maxBytesInRequest)
- , EndKey(keyTo)
- , Settings(settings)
- , Connection(driver, NYdb::TCommonClientSettings().Database(database).DiscoveryEndpoint(endpoint).AuthToken(token).DiscoveryMode(NYdb::EDiscoveryMode::Async).EnableSsl(secure))
- , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
- , LastReadKeyInclusive(false)
- , Retried(0U)
- , WakeUpTime(NActors::TMonotonic::Now())
- , RequestSent(false)
- , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
- , MemoryUsed(0U)
- {}
- private:
- void SendRequest() {
- if (!RequestsDone && !RequestSent && MemoryUsed < MaxQueueVolume && WakeUpTime <= NActors::TMonotonic::Now()) {
- RequestSent = true;
- Connection.Scan(Path, Columns, MaxRows, MaxBytes, LastReadKey, !LastReadKeyInclusive, Settings).Subscribe(std::bind(&TAsyncState::OnRespondWrap, this->weak_from_this(), std::placeholders::_1));
- }
- }
-
- static void OnRespondWrap(const TWeakPtr& weak, const NYdb::NClickhouseInternal::TAsyncScanResult& result) {
- if (const auto& self = weak.lock())
- self->OnRespond(result);
- }
-
- void OnRespond(const NYdb::NClickhouseInternal::TAsyncScanResult& result) {
- if (const auto& res = result.GetValueSync(); res.GetStatus() == NYdb::EStatus::SUCCESS) {
- ProcessResult(res);
- ActorSystem->Send(new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
- } else if (!IsRetriable(res.GetStatus()) || Retried > MaxRetries) {
- ProcessError(res);
- ActorSystem->Send(new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
- } else {
- ActorSystem->Schedule(ProcessRetry(), new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
- }
- }
-
- void ProcessResult(const NYdb::NClickhouseInternal::TScanResult& res) {
- const std::unique_lock lock(Sync);
- RequestSent = false;
-
- Retried = 0U;
-
- const auto bc = res.GetBuffersCount();
- for (size_t i = 0U; i < bc; ++i) {
- if (auto block = res.GetBuffer(i); !block.empty()) {
- MemoryUsed += block.size();
- Blocks.emplace(std::move(block));
- }
- }
-
- std::tie(LastReadKey, LastReadKeyInclusive) = res.GetLastKey();
- RequestsDone = res.IsEos() || RangeFinished(LastReadKey, EndKey, KeyColumnTypes);
- SendRequest();
- }
-
- void ProcessError(const NYdb::NClickhouseInternal::TScanResult& res) {
- const std::unique_lock lock(Sync);
- RequestSent = false;
- Issues = res.GetIssues();
- while (!Blocks.empty())
- Blocks.pop();
- }
-
- NActors::TMonotonic ProcessRetry() {
- const std::unique_lock lock(Sync);
- RequestSent = false;
- return WakeUpTime = NActors::TMonotonic::Now() + Min(TDuration::Seconds(3), TDuration::MilliSeconds(0x30U * (1U << ++Retried)));
- }
-
- static constexpr auto MaxRetries = 0x10U;
- static constexpr auto MaxQueueVolume = 4_MB;
-
- NActors::TActorSystem* const ActorSystem;
- NActors::TActorId const CurrentActorId;
-
- const TString Path;
- const TVector<TString> Columns;
- const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
- const ui64 MaxRows;
- const ui64 MaxBytes;
- const TString EndKey;
- const NYdb::NClickhouseInternal::TScanSettings Settings;
-
- NYdb::NClickhouseInternal::TScanClient Connection;
-
- TString LastReadKey;
- bool LastReadKeyInclusive;
- size_t Retried;
-
- NActors::TMonotonic WakeUpTime;
- bool RequestSent;
- bool RequestsDone;
- size_t MemoryUsed;
-
- std::mutex Sync;
- std::queue<TString> Blocks;
- TIssues Issues;
- };
- public:
- TAsyncStream(TMemoryUsageInfo* memInfo, const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings)
- : TComputationValue<TAsyncStream>(memInfo), State(TAsyncState::Make(driver, database, endpoint, token, path, secure, columns, keyColumnTypes, maxRowsInRequest, maxBytesInRequest, keyFrom, keyTo, settings))
- {}
- private:
- NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
- return State->Fetch(result);
- }
-
- const typename TAsyncState::TPtr State;
- };
-public:
- TKikScan(
- TComputationMutables& mutables,
- const NYdb::TDriver driver,
- const std::string_view& table,
- const std::string_view& database,
- const std::string_view& endpoint,
- const std::string_view& token,
- const std::string_view& snapshot,
- bool secure,
- TVector<TString>&& columns,
- TVector<NKikimr::NScheme::TTypeId>&& keyColumnTypes,
- const std::string_view& keyFrom,
- const std::string_view& keyTo,
- IComputationNode* rows
- ) : TBaseComputation(mutables)
- , Driver(driver)
- , Table(table), Database(database)
- , Endpoint(endpoint)
- , Token(token)
- , Snapshot(snapshot)
- , Secure(secure)
- , Columns(std::move(columns))
- , KeyColumnTypes(std::move(keyColumnTypes))
- , KeyFrom(keyFrom)
- , KeyTo(keyTo)
- , Rows(rows)
- {}
-
- NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
- auto token = Token;
-
- if (NUdf::TStringRef tokenRef(token); ctx.Builder->GetSecureParam(tokenRef, tokenRef)) {
- token = tokenRef;
- } else {
- UdfTerminate((TString("Unable to get token ") += Token).c_str());
- }
-
+
+#include <library/cpp/actors/core/actor.h>
+
+#include <queue>
+#include <mutex>
+
+namespace NYql::NDqs {
+using namespace NKikimr::NMiniKQL;
+
+namespace {
+
+bool IsRetriable(NYdb::EStatus status) {
+ switch (status) {
+ case NYdb::EStatus::BAD_REQUEST:
+ case NYdb::EStatus::SCHEME_ERROR:
+ case NYdb::EStatus::UNAUTHORIZED:
+ case NYdb::EStatus::NOT_FOUND:
+ return false;
+ default:
+ return true;
+ }
+}
+
+bool RangeFinished(const TString& lastReadKey, const TString& endKey, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes) {
+ if (lastReadKey.empty())
+ return true;
+
+ if (endKey.empty())
+ return false;
+
+ const NKikimr::TSerializedCellVec last(lastReadKey), end(endKey);
+ return NKikimr::CompareTypedCellVectors(last.GetCells().data(), end.GetCells().data(), keyColumnTypes.data(), last.GetCells().size(), end.GetCells().size()) >= 0;
+}
+
+template<bool Async>
+class TKikScan : public TMutableComputationNode<TKikScan<Async>> {
+using TBaseComputation = TMutableComputationNode<TKikScan<Async>>;
+ class TStream: public TComputationValue<TStream> {
+ public:
+ TStream(TMemoryUsageInfo* memInfo, NYdb::NClickhouseInternal::TScanIterator iterator)
+ : TComputationValue<TStream>(memInfo), Iterator_(std::move(iterator))
+ {}
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final try {
+ if (const auto blocks = Iterator_.GetBlocks(); !blocks.empty()) {
+ result = MakeString(blocks);
+ return NUdf::EFetchStatus::Ok;
+ }
+
+ return NUdf::EFetchStatus::Finish;
+ } catch (const std::exception& ex) {
+ UdfTerminate(ex.what());
+ }
+
+ NYdb::NClickhouseInternal::TScanIterator Iterator_;
+ };
+
+ class TAsyncStream: public TComputationValue<TAsyncStream> {
+ class TAsyncState : public std::enable_shared_from_this<TAsyncState> {
+ public:
+ using TPtr = std::shared_ptr<TAsyncState>;
+ using TWeakPtr = std::weak_ptr<TAsyncState>;
+
+ static TPtr Make(const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings) {
+ const auto ptr = std::make_shared<TAsyncState>(driver, database, endpoint, token, path, secure, columns, keyColumnTypes, maxRowsInRequest, maxBytesInRequest, keyFrom, keyTo, settings);
+ ptr->SendRequest();
+ return ptr;
+ }
+
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) {
+ const std::unique_lock lock(Sync);
+ if (!Blocks.empty()) {
+ const auto& block = Blocks.front();
+ MemoryUsed -= block.size();
+ result = MakeString(block);
+ Blocks.pop();
+ SendRequest();
+ return NUdf::EFetchStatus::Ok;
+ }
+
+ if (RequestsDone)
+ return NUdf::EFetchStatus::Finish;
+
+ if (Issues)
+ UdfTerminate(Issues.ToString().c_str());
+
+ SendRequest();
+ return NUdf::EFetchStatus::Yield;
+ }
+
+ TAsyncState(const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings)
+ : ActorSystem(NActors::TActivationContext::ActorSystem())
+ , CurrentActorId(NActors::TActivationContext::AsActorContext().SelfID)
+ , Path(path)
+ , Columns(columns)
+ , KeyColumnTypes(keyColumnTypes)
+ , MaxRows(maxRowsInRequest)
+ , MaxBytes(maxBytesInRequest)
+ , EndKey(keyTo)
+ , Settings(settings)
+ , Connection(driver, NYdb::TCommonClientSettings().Database(database).DiscoveryEndpoint(endpoint).AuthToken(token).DiscoveryMode(NYdb::EDiscoveryMode::Async).EnableSsl(secure))
+ , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
+ , LastReadKeyInclusive(false)
+ , Retried(0U)
+ , WakeUpTime(NActors::TMonotonic::Now())
+ , RequestSent(false)
+ , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
+ , MemoryUsed(0U)
+ {}
+ private:
+ void SendRequest() {
+ if (!RequestsDone && !RequestSent && MemoryUsed < MaxQueueVolume && WakeUpTime <= NActors::TMonotonic::Now()) {
+ RequestSent = true;
+ Connection.Scan(Path, Columns, MaxRows, MaxBytes, LastReadKey, !LastReadKeyInclusive, Settings).Subscribe(std::bind(&TAsyncState::OnRespondWrap, this->weak_from_this(), std::placeholders::_1));
+ }
+ }
+
+ static void OnRespondWrap(const TWeakPtr& weak, const NYdb::NClickhouseInternal::TAsyncScanResult& result) {
+ if (const auto& self = weak.lock())
+ self->OnRespond(result);
+ }
+
+ void OnRespond(const NYdb::NClickhouseInternal::TAsyncScanResult& result) {
+ if (const auto& res = result.GetValueSync(); res.GetStatus() == NYdb::EStatus::SUCCESS) {
+ ProcessResult(res);
+ ActorSystem->Send(new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
+ } else if (!IsRetriable(res.GetStatus()) || Retried > MaxRetries) {
+ ProcessError(res);
+ ActorSystem->Send(new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
+ } else {
+ ActorSystem->Schedule(ProcessRetry(), new NActors::IEventHandle(CurrentActorId, NActors::TActorId(), new NDq::TEvDqCompute::TEvResumeExecution()));
+ }
+ }
+
+ void ProcessResult(const NYdb::NClickhouseInternal::TScanResult& res) {
+ const std::unique_lock lock(Sync);
+ RequestSent = false;
+
+ Retried = 0U;
+
+ const auto bc = res.GetBuffersCount();
+ for (size_t i = 0U; i < bc; ++i) {
+ if (auto block = res.GetBuffer(i); !block.empty()) {
+ MemoryUsed += block.size();
+ Blocks.emplace(std::move(block));
+ }
+ }
+
+ std::tie(LastReadKey, LastReadKeyInclusive) = res.GetLastKey();
+ RequestsDone = res.IsEos() || RangeFinished(LastReadKey, EndKey, KeyColumnTypes);
+ SendRequest();
+ }
+
+ void ProcessError(const NYdb::NClickhouseInternal::TScanResult& res) {
+ const std::unique_lock lock(Sync);
+ RequestSent = false;
+ Issues = res.GetIssues();
+ while (!Blocks.empty())
+ Blocks.pop();
+ }
+
+ NActors::TMonotonic ProcessRetry() {
+ const std::unique_lock lock(Sync);
+ RequestSent = false;
+ return WakeUpTime = NActors::TMonotonic::Now() + Min(TDuration::Seconds(3), TDuration::MilliSeconds(0x30U * (1U << ++Retried)));
+ }
+
+ static constexpr auto MaxRetries = 0x10U;
+ static constexpr auto MaxQueueVolume = 4_MB;
+
+ NActors::TActorSystem* const ActorSystem;
+ NActors::TActorId const CurrentActorId;
+
+ const TString Path;
+ const TVector<TString> Columns;
+ const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
+ const ui64 MaxRows;
+ const ui64 MaxBytes;
+ const TString EndKey;
+ const NYdb::NClickhouseInternal::TScanSettings Settings;
+
+ NYdb::NClickhouseInternal::TScanClient Connection;
+
+ TString LastReadKey;
+ bool LastReadKeyInclusive;
+ size_t Retried;
+
+ NActors::TMonotonic WakeUpTime;
+ bool RequestSent;
+ bool RequestsDone;
+ size_t MemoryUsed;
+
+ std::mutex Sync;
+ std::queue<TString> Blocks;
+ TIssues Issues;
+ };
+ public:
+ TAsyncStream(TMemoryUsageInfo* memInfo, const NYdb::TDriver& driver, const TString& database, const TString& endpoint, const TString& token, const TString& path, bool secure, const TVector<TString>& columns, const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest, const TString& keyFrom, const TString& keyTo, const NYdb::NClickhouseInternal::TScanSettings& settings)
+ : TComputationValue<TAsyncStream>(memInfo), State(TAsyncState::Make(driver, database, endpoint, token, path, secure, columns, keyColumnTypes, maxRowsInRequest, maxBytesInRequest, keyFrom, keyTo, settings))
+ {}
+ private:
+ NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) final {
+ return State->Fetch(result);
+ }
+
+ const typename TAsyncState::TPtr State;
+ };
+public:
+ TKikScan(
+ TComputationMutables& mutables,
+ const NYdb::TDriver driver,
+ const std::string_view& table,
+ const std::string_view& database,
+ const std::string_view& endpoint,
+ const std::string_view& token,
+ const std::string_view& snapshot,
+ bool secure,
+ TVector<TString>&& columns,
+ TVector<NKikimr::NScheme::TTypeId>&& keyColumnTypes,
+ const std::string_view& keyFrom,
+ const std::string_view& keyTo,
+ IComputationNode* rows
+ ) : TBaseComputation(mutables)
+ , Driver(driver)
+ , Table(table), Database(database)
+ , Endpoint(endpoint)
+ , Token(token)
+ , Snapshot(snapshot)
+ , Secure(secure)
+ , Columns(std::move(columns))
+ , KeyColumnTypes(std::move(keyColumnTypes))
+ , KeyFrom(keyFrom)
+ , KeyTo(keyTo)
+ , Rows(rows)
+ {}
+
+ NUdf::TUnboxedValuePod DoCalculate(TComputationContext& ctx) const {
+ auto token = Token;
+
+ if (NUdf::TStringRef tokenRef(token); ctx.Builder->GetSecureParam(tokenRef, tokenRef)) {
+ token = tokenRef;
+ } else {
+ UdfTerminate((TString("Unable to get token ") += Token).c_str());
+ }
+
auto parser = CreateStructuredTokenParser(token);
if (!parser.HasIAMToken()) {
UdfTerminate("Structured token does not contan YDB token");
@@ -265,68 +265,68 @@ public:
token = parser.GetIAMToken();
- const auto settings = NYdb::NClickhouseInternal::TScanSettings().SnapshotId(Snapshot);
- const auto rows = Rows->GetValue(ctx).GetOrDefault<ui64>(0ULL);
-
- if constexpr (Async) {
- return ctx.HolderFactory.Create<TAsyncStream>(Driver, Database, Endpoint, token, Table, Secure, Columns, KeyColumnTypes, rows, 0ULL, KeyFrom, KeyTo, settings);
- } else {
- return ctx.HolderFactory.Create<TStream>(NYdb::NClickhouseInternal::TScanIterator(Driver, Database, Endpoint, token, Secure, Table, Columns, KeyColumnTypes, rows, 0ULL, KeyFrom, KeyTo, settings));
- }
- }
-private:
- void RegisterDependencies() const final {
- this->DependsOn(Rows);
- }
-
- const NYdb::TDriver Driver;
-
- const TString Table;
- const TString Database;
- const TString Endpoint;
- const TString Token;
- const TString Snapshot;
- const bool Secure;
- const TVector<TString> Columns;
- const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
- const TString KeyFrom;
- const TString KeyTo;
- IComputationNode* const Rows;
-};
-
-}
-
-template<bool Async>
-IComputationNode* WrapKikScan(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver) {
- MKQL_ENSURE(callable.GetInputsCount() >= 10 && callable.GetInputsCount() <= 11, "Expected 10 or 11 arguments.");
- const auto table = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef();
- const auto database = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().AsStringRef();
- const auto endpoint = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
- const auto token = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().AsStringRef();
- const auto snapshot = AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().AsStringRef();
-
- const auto columnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
- TVector<TString> columns;
- columns.reserve(columnsNode->GetValuesCount());
- for (ui32 i = 0; i < columnsNode->GetValuesCount(); ++i) {
- columns.emplace_back(AS_VALUE(TDataLiteral, columnsNode->GetValue(i))->AsValue().AsStringRef());
- }
-
- const auto keysNode = AS_VALUE(TTupleLiteral, callable.GetInput(6));
- TVector<NKikimr::NScheme::TTypeId> keyColumnTypes;
- keyColumnTypes.reserve(keysNode->GetValuesCount());
- for (ui32 i = 0; i < keysNode->GetValuesCount(); ++i) {
- keyColumnTypes.emplace_back(AS_VALUE(TDataLiteral, keysNode->GetValue(i))->AsValue().Get<ui16>());
- }
-
- const auto keyFrom = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().AsStringRef();
- const auto keyTo = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().AsStringRef();
- const auto rows = LocateNode(ctx.NodeLocator, callable, 9);
- const bool secure = callable.GetInputsCount() >= 11 && AS_VALUE(TDataLiteral, callable.GetInput(10))->AsValue().Get<bool>();
- return new TKikScan<Async>(ctx.Mutables, driver, table, database, endpoint, token, snapshot, secure, std::move(columns), std::move(keyColumnTypes), keyFrom, keyTo, rows);
-}
-
-template IComputationNode* WrapKikScan<true>(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
-template IComputationNode* WrapKikScan<false>(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
-
-} // NYql
+ const auto settings = NYdb::NClickhouseInternal::TScanSettings().SnapshotId(Snapshot);
+ const auto rows = Rows->GetValue(ctx).GetOrDefault<ui64>(0ULL);
+
+ if constexpr (Async) {
+ return ctx.HolderFactory.Create<TAsyncStream>(Driver, Database, Endpoint, token, Table, Secure, Columns, KeyColumnTypes, rows, 0ULL, KeyFrom, KeyTo, settings);
+ } else {
+ return ctx.HolderFactory.Create<TStream>(NYdb::NClickhouseInternal::TScanIterator(Driver, Database, Endpoint, token, Secure, Table, Columns, KeyColumnTypes, rows, 0ULL, KeyFrom, KeyTo, settings));
+ }
+ }
+private:
+ void RegisterDependencies() const final {
+ this->DependsOn(Rows);
+ }
+
+ const NYdb::TDriver Driver;
+
+ const TString Table;
+ const TString Database;
+ const TString Endpoint;
+ const TString Token;
+ const TString Snapshot;
+ const bool Secure;
+ const TVector<TString> Columns;
+ const TVector<NKikimr::NScheme::TTypeId> KeyColumnTypes;
+ const TString KeyFrom;
+ const TString KeyTo;
+ IComputationNode* const Rows;
+};
+
+}
+
+template<bool Async>
+IComputationNode* WrapKikScan(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver) {
+ MKQL_ENSURE(callable.GetInputsCount() >= 10 && callable.GetInputsCount() <= 11, "Expected 10 or 11 arguments.");
+ const auto table = AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef();
+ const auto database = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().AsStringRef();
+ const auto endpoint = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
+ const auto token = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().AsStringRef();
+ const auto snapshot = AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().AsStringRef();
+
+ const auto columnsNode = AS_VALUE(TTupleLiteral, callable.GetInput(5));
+ TVector<TString> columns;
+ columns.reserve(columnsNode->GetValuesCount());
+ for (ui32 i = 0; i < columnsNode->GetValuesCount(); ++i) {
+ columns.emplace_back(AS_VALUE(TDataLiteral, columnsNode->GetValue(i))->AsValue().AsStringRef());
+ }
+
+ const auto keysNode = AS_VALUE(TTupleLiteral, callable.GetInput(6));
+ TVector<NKikimr::NScheme::TTypeId> keyColumnTypes;
+ keyColumnTypes.reserve(keysNode->GetValuesCount());
+ for (ui32 i = 0; i < keysNode->GetValuesCount(); ++i) {
+ keyColumnTypes.emplace_back(AS_VALUE(TDataLiteral, keysNode->GetValue(i))->AsValue().Get<ui16>());
+ }
+
+ const auto keyFrom = AS_VALUE(TDataLiteral, callable.GetInput(7))->AsValue().AsStringRef();
+ const auto keyTo = AS_VALUE(TDataLiteral, callable.GetInput(8))->AsValue().AsStringRef();
+ const auto rows = LocateNode(ctx.NodeLocator, callable, 9);
+ const bool secure = callable.GetInputsCount() >= 11 && AS_VALUE(TDataLiteral, callable.GetInput(10))->AsValue().Get<bool>();
+ return new TKikScan<Async>(ctx.Mutables, driver, table, database, endpoint, token, snapshot, secure, std::move(columns), std::move(keyColumnTypes), keyFrom, keyTo, rows);
+}
+
+template IComputationNode* WrapKikScan<true>(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
+template IComputationNode* WrapKikScan<false>(TCallable& callable, const TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
+
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.h b/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.h
index 58ecacaa5b..d70c273b7a 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.h
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_kik_scan.h
@@ -1,12 +1,12 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
#include <ydb/library/yql/minikql/mkql_node.h>
#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
-
-namespace NYql::NDqs {
-
-template<bool Async>
-NKikimr::NMiniKQL::IComputationNode* WrapKikScan(NKikimr::NMiniKQL::TCallable& callable, const NKikimr::NMiniKQL::TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
-
-} // NYql
+
+namespace NYql::NDqs {
+
+template<bool Async>
+NKikimr::NMiniKQL::IComputationNode* WrapKikScan(NKikimr::NMiniKQL::TCallable& callable, const NKikimr::NMiniKQL::TComputationNodeFactoryContext& ctx, const NYdb::TDriver& driver);
+
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.cpp b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.cpp
index bb7fb1f86e..bb82020e9e 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.cpp
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.cpp
@@ -1,60 +1,60 @@
-#include "yql_ydb_dq_transform.h"
-
+#include "yql_ydb_dq_transform.h"
+
#include <ydb/library/yql/minikql/mkql_program_builder.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_function_registry.h>
#include <ydb/library/yql/providers/ydb/proto/range.pb.h>
-
-namespace NYql {
-
-using namespace NKikimr::NMiniKQL;
-
-class TYdbDqTaskTransform {
-public:
- TYdbDqTaskTransform(const THashMap<TString, TString>& taskParams, const IFunctionRegistry& functionRegistry)
- : TaskParams(std::move(taskParams))
- , FunctionRegistry(functionRegistry)
- {
- }
-
- TCallableVisitFunc operator()(TInternName name) {
- if (TaskParams.contains("ydb") && name.Str().starts_with("KikScan")) {
- return [this](TCallable& callable, const TTypeEnvironment& env) {
- const auto part = TaskParams.Value("ydb", TString());
- TStringInput in(part);
- NYdb::TKeyRange range;
- range.Load(&in);
-
- TProgramBuilder pgmBuilder(env, FunctionRegistry);
- TCallableBuilder callableBuilder(env, callable.GetType()->GetName(), callable.GetType()->GetReturnType(), false);
- callableBuilder.Add(callable.GetInput(0));
- callableBuilder.Add(callable.GetInput(1));
- callableBuilder.Add(callable.GetInput(2));
- callableBuilder.Add(callable.GetInput(3));
- callableBuilder.Add(callable.GetInput(4));
- callableBuilder.Add(callable.GetInput(5));
- callableBuilder.Add(callable.GetInput(6));
- callableBuilder.Add(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(range.from_key()));
- callableBuilder.Add(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(range.to_key()));
- callableBuilder.Add(callable.GetInput(9));
-
- return TRuntimeNode(callableBuilder.Build(), false);
- };
- }
-
- return TCallableVisitFunc();
- }
-
-private:
- const THashMap<TString, TString> TaskParams;
- const IFunctionRegistry& FunctionRegistry;
-};
-
-TTaskTransformFactory CreateYdbDqTaskTransformFactory() {
- return [] (const THashMap<TString, TString>& taskParams, const IFunctionRegistry* funcRegistry) -> TCallableVisitFuncProvider {
- return TYdbDqTaskTransform(taskParams, *funcRegistry);
- };
-}
-
-} // NYql
-
+
+namespace NYql {
+
+using namespace NKikimr::NMiniKQL;
+
+class TYdbDqTaskTransform {
+public:
+ TYdbDqTaskTransform(const THashMap<TString, TString>& taskParams, const IFunctionRegistry& functionRegistry)
+ : TaskParams(std::move(taskParams))
+ , FunctionRegistry(functionRegistry)
+ {
+ }
+
+ TCallableVisitFunc operator()(TInternName name) {
+ if (TaskParams.contains("ydb") && name.Str().starts_with("KikScan")) {
+ return [this](TCallable& callable, const TTypeEnvironment& env) {
+ const auto part = TaskParams.Value("ydb", TString());
+ TStringInput in(part);
+ NYdb::TKeyRange range;
+ range.Load(&in);
+
+ TProgramBuilder pgmBuilder(env, FunctionRegistry);
+ TCallableBuilder callableBuilder(env, callable.GetType()->GetName(), callable.GetType()->GetReturnType(), false);
+ callableBuilder.Add(callable.GetInput(0));
+ callableBuilder.Add(callable.GetInput(1));
+ callableBuilder.Add(callable.GetInput(2));
+ callableBuilder.Add(callable.GetInput(3));
+ callableBuilder.Add(callable.GetInput(4));
+ callableBuilder.Add(callable.GetInput(5));
+ callableBuilder.Add(callable.GetInput(6));
+ callableBuilder.Add(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(range.from_key()));
+ callableBuilder.Add(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(range.to_key()));
+ callableBuilder.Add(callable.GetInput(9));
+
+ return TRuntimeNode(callableBuilder.Build(), false);
+ };
+ }
+
+ return TCallableVisitFunc();
+ }
+
+private:
+ const THashMap<TString, TString> TaskParams;
+ const IFunctionRegistry& FunctionRegistry;
+};
+
+TTaskTransformFactory CreateYdbDqTaskTransformFactory() {
+ return [] (const THashMap<TString, TString>& taskParams, const IFunctionRegistry* funcRegistry) -> TCallableVisitFuncProvider {
+ return TYdbDqTaskTransform(taskParams, *funcRegistry);
+ };
+}
+
+} // NYql
+
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.h b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.h
index 02f83ef87a..0055de7aa2 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.h
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_dq_transform.h
@@ -1,10 +1,10 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/providers/dq/interface/yql_dq_task_transform.h>
-
-namespace NYql {
-
-TTaskTransformFactory CreateYdbDqTaskTransformFactory();
-
-}
-
+
+namespace NYql {
+
+TTaskTransformFactory CreateYdbDqTaskTransformFactory();
+
+}
+
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.cpp b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.cpp
index 1b928f9597..44fe4ca21c 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.cpp
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.cpp
@@ -1,20 +1,20 @@
-#include "yql_ydb_factory.h"
-#include "yql_kik_scan.h"
-
-namespace NYql {
-
-using namespace NKikimr::NMiniKQL;
-
-TComputationNodeFactory GetDqYdbFactory(NYdb::TDriver driver) {
- return [driver] (TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
- if (const auto& name = callable.GetType()->GetName(); name == "KikScan") {
- return NDqs::WrapKikScan<false>(callable, ctx, driver);
- } else if (name == "KikScanAsync") {
- return NDqs::WrapKikScan<true>(callable, ctx, driver);
- }
-
- return nullptr;
- };
-}
-
-} // NYql
+#include "yql_ydb_factory.h"
+#include "yql_kik_scan.h"
+
+namespace NYql {
+
+using namespace NKikimr::NMiniKQL;
+
+TComputationNodeFactory GetDqYdbFactory(NYdb::TDriver driver) {
+ return [driver] (TCallable& callable, const TComputationNodeFactoryContext& ctx) -> IComputationNode* {
+ if (const auto& name = callable.GetType()->GetName(); name == "KikScan") {
+ return NDqs::WrapKikScan<false>(callable, ctx, driver);
+ } else if (name == "KikScanAsync") {
+ return NDqs::WrapKikScan<true>(callable, ctx, driver);
+ }
+
+ return nullptr;
+ };
+}
+
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.h b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.h
index 91350ea20b..6643cae082 100644
--- a/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.h
+++ b/ydb/library/yql/providers/ydb/comp_nodes/yql_ydb_factory.h
@@ -1,11 +1,11 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/minikql/computation/mkql_computation_node.h>
#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
-
-namespace NYql {
-
-NKikimr::NMiniKQL::TComputationNodeFactory GetDqYdbFactory(NYdb::TDriver driver);
-
-}
-
+
+namespace NYql {
+
+NKikimr::NMiniKQL::TComputationNodeFactory GetDqYdbFactory(NYdb::TDriver driver);
+
+}
+
diff --git a/ydb/library/yql/providers/ydb/expr_nodes/ya.make b/ydb/library/yql/providers/ydb/expr_nodes/ya.make
index 9412b5104f..bb380fcd16 100644
--- a/ydb/library/yql/providers/ydb/expr_nodes/ya.make
+++ b/ydb/library/yql/providers/ydb/expr_nodes/ya.make
@@ -1,37 +1,37 @@
-LIBRARY()
-
-OWNER(
- g:yql
-)
-
-SRCS(
- yql_ydb_expr_nodes.cpp
-)
-
-PEERDIR(
+LIBRARY()
+
+OWNER(
+ g:yql
+)
+
+SRCS(
+ yql_ydb_expr_nodes.cpp
+)
+
+PEERDIR(
ydb/library/yql/core/expr_nodes
ydb/library/yql/providers/common/provider
-)
-
-SRCDIR(
+)
+
+SRCDIR(
ydb/library/yql/core/expr_nodes_gen
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
ydb/library/yql/core/expr_nodes_gen/gen
- yql_expr_nodes_gen.jnj
- yql_ydb_expr_nodes.json
- yql_ydb_expr_nodes.gen.h
- yql_ydb_expr_nodes.decl.inl.h
- yql_ydb_expr_nodes.defs.inl.h
- IN yql_expr_nodes_gen.jnj
- IN yql_ydb_expr_nodes.json
- OUT yql_ydb_expr_nodes.gen.h
- OUT yql_ydb_expr_nodes.decl.inl.h
- OUT yql_ydb_expr_nodes.defs.inl.h
- OUTPUT_INCLUDES
+ yql_expr_nodes_gen.jnj
+ yql_ydb_expr_nodes.json
+ yql_ydb_expr_nodes.gen.h
+ yql_ydb_expr_nodes.decl.inl.h
+ yql_ydb_expr_nodes.defs.inl.h
+ IN yql_expr_nodes_gen.jnj
+ IN yql_ydb_expr_nodes.json
+ OUT yql_ydb_expr_nodes.gen.h
+ OUT yql_ydb_expr_nodes.decl.inl.h
+ OUT yql_ydb_expr_nodes.defs.inl.h
+ OUTPUT_INCLUDES
${ARCADIA_ROOT}/ydb/library/yql/core/expr_nodes_gen/yql_expr_nodes_gen.h
- ${ARCADIA_ROOT}/util/generic/hash_set.h
-)
-
-END()
+ ${ARCADIA_ROOT}/util/generic/hash_set.h
+)
+
+END()
diff --git a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.cpp b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.cpp
index eb9d7710b0..550b4922c9 100644
--- a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.cpp
+++ b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.cpp
@@ -1 +1 @@
-#include "yql_ydb_expr_nodes.h"
+#include "yql_ydb_expr_nodes.h"
diff --git a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h
index bed3351a2b..aaee76adbf 100644
--- a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h
+++ b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h
@@ -1,61 +1,61 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.gen.h>
-
-namespace NYql {
-namespace NNodes {
-
+
+namespace NYql {
+namespace NNodes {
+
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.decl.inl.h>
-
-class TYdbDataSource: public NGenerated::TYdbDataSourceStub<TExprBase, TCallable, TCoAtom> {
-public:
- explicit TYdbDataSource(const TExprNode* node)
- : TYdbDataSourceStub(node)
- {
- }
-
- explicit TYdbDataSource(const TExprNode::TPtr& node)
- : TYdbDataSourceStub(node)
- {
- }
-
- static bool Match(const TExprNode* node) {
- if (!TYdbDataSourceStub::Match(node)) {
- return false;
- }
-
- if (node->Head().Content() != YdbProviderName) {
- return false;
- }
-
- return true;
- }
-};
-
-class TYdbDataSink : public NGenerated::TYdbDataSinkStub<TExprBase, TCallable, TCoAtom> {
-public:
- explicit TYdbDataSink(const TExprNode* node)
- : TYdbDataSinkStub(node) {}
-
- explicit TYdbDataSink(const TExprNode::TPtr& node)
- : TYdbDataSinkStub(node) {}
-
- static bool Match(const TExprNode* node) {
- if (!TYdbDataSinkStub::Match(node)) {
- return false;
- }
-
- if (node->Head().Content() != YdbProviderName) {
- return false;
- }
-
- return true;
- }
-};
-
+
+class TYdbDataSource: public NGenerated::TYdbDataSourceStub<TExprBase, TCallable, TCoAtom> {
+public:
+ explicit TYdbDataSource(const TExprNode* node)
+ : TYdbDataSourceStub(node)
+ {
+ }
+
+ explicit TYdbDataSource(const TExprNode::TPtr& node)
+ : TYdbDataSourceStub(node)
+ {
+ }
+
+ static bool Match(const TExprNode* node) {
+ if (!TYdbDataSourceStub::Match(node)) {
+ return false;
+ }
+
+ if (node->Head().Content() != YdbProviderName) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+class TYdbDataSink : public NGenerated::TYdbDataSinkStub<TExprBase, TCallable, TCoAtom> {
+public:
+ explicit TYdbDataSink(const TExprNode* node)
+ : TYdbDataSinkStub(node) {}
+
+ explicit TYdbDataSink(const TExprNode::TPtr& node)
+ : TYdbDataSinkStub(node) {}
+
+ static bool Match(const TExprNode* node) {
+ if (!TYdbDataSinkStub::Match(node)) {
+ return false;
+ }
+
+ if (node->Head().Content() != YdbProviderName) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.defs.inl.h>
-
-} // namespace NNodes
-} // namespace NYql
+
+} // namespace NNodes
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.json b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.json
index b1bafd4eed..534f097ec3 100644
--- a/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.json
+++ b/ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.json
@@ -1,95 +1,95 @@
-{
- "NodeRootType": "TExprBase",
- "NodeBuilderBase": "TNodeBuilderBase",
- "ListBuilderBase": "TListBuilderBase",
- "FreeArgCallableBase": "TFreeArgCallable",
- "FreeArgBuilderBase": "TFreeArgCallableBuilderBase",
- "Nodes": [
- {
- "Name": "TYdbDataSource",
- "Base": "TCallable",
- "Definition": "Custom",
- "Match": {"Type": "Callable", "Name": "DataSource"},
- "Children": [
- {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TYdbDataSink",
- "Base": "TCallable",
- "Definition": "Custom",
- "Match": {"Type": "Callable", "Name": "DataSink"},
- "Children": [
- {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TYdbSourceSettings",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "YdbSourceSettings"},
- "Children": [
- {"Index": 0, "Name": "Table", "Type": "TCoAtom"},
- {"Index": 1, "Name": "Token", "Type": "TCoSecureParam"},
- {"Index": 2, "Name": "Columns", "Type": "TCoAtomList"}
- ]
- },
- {
- "Name": "TYdbRead",
- "Base": "TFreeArgCallable",
- "Match": {"Type": "Callable", "Name": "Read!"},
- "Children": [
- {"Index": 0, "Name": "World", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSource", "Type": "TYdbDataSource"}
- ]
- },
- {
- "Name": "TYdbReadBase",
- "Base": "TCallable",
- "Match": {"Type": "CallableBase"},
- "Builder": {"Generate": "None"},
- "Children": [
- {"Index": 0, "Name": "World", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSource", "Type": "TYdbDataSource"},
- {"Index": 2, "Name": "Table", "Type": "TCoAtom"}
- ]
- },
- {
- "Name": "TYdbReadTableScheme",
- "Base": "TYdbReadBase",
- "Match": {"Type": "Callable", "Name": "YdbReadTableScheme!"}
- },
- {
- "Name": "TYdbReadTable",
- "Base": "TYdbReadBase",
- "Match": {"Type": "Callable", "Name": "YdbReadTable!"},
- "Children": [
- {"Index": 3, "Name": "Columns", "Type": "TExprBase"},
- {"Index": 4, "Name": "LimitHint", "Type": "TExprBase", "Optional": true}
- ]
- },
- {
- "Name": "TYdbWriteTable",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "YdbWriteTable!"},
- "Children": [
- {"Index": 0, "Name": "World", "Type": "TExprBase"},
- {"Index": 1, "Name": "DataSink", "Type": "TYdbDataSink"},
- {"Index": 2, "Name": "Table", "Type": "TCoAtom"},
- {"Index": 3, "Name": "Input", "Type": "TExprBase"},
- {"Index": 4, "Name": "Mode", "Type": "TCoAtom"},
- {"Index": 5, "Name": "Settings", "Type": "TCoNameValueTupleList"}
- ]
- },
- {
- "Name": "TYdbClusterConfig",
- "Base": "TCallable",
- "Match": {"Type": "Callable", "Name": "YdbClusterConfig"},
- "Children": [
- {"Index": 0, "Name": "Locators", "Type": "TCoAtomList"},
- {"Index": 1, "Name": "TvmId", "Type": "TCoAtom"}
- ]
- }
- ]
-}
+{
+ "NodeRootType": "TExprBase",
+ "NodeBuilderBase": "TNodeBuilderBase",
+ "ListBuilderBase": "TListBuilderBase",
+ "FreeArgCallableBase": "TFreeArgCallable",
+ "FreeArgBuilderBase": "TFreeArgCallableBuilderBase",
+ "Nodes": [
+ {
+ "Name": "TYdbDataSource",
+ "Base": "TCallable",
+ "Definition": "Custom",
+ "Match": {"Type": "Callable", "Name": "DataSource"},
+ "Children": [
+ {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TYdbDataSink",
+ "Base": "TCallable",
+ "Definition": "Custom",
+ "Match": {"Type": "Callable", "Name": "DataSink"},
+ "Children": [
+ {"Index": 0, "Name": "Category", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Cluster", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TYdbSourceSettings",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "YdbSourceSettings"},
+ "Children": [
+ {"Index": 0, "Name": "Table", "Type": "TCoAtom"},
+ {"Index": 1, "Name": "Token", "Type": "TCoSecureParam"},
+ {"Index": 2, "Name": "Columns", "Type": "TCoAtomList"}
+ ]
+ },
+ {
+ "Name": "TYdbRead",
+ "Base": "TFreeArgCallable",
+ "Match": {"Type": "Callable", "Name": "Read!"},
+ "Children": [
+ {"Index": 0, "Name": "World", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSource", "Type": "TYdbDataSource"}
+ ]
+ },
+ {
+ "Name": "TYdbReadBase",
+ "Base": "TCallable",
+ "Match": {"Type": "CallableBase"},
+ "Builder": {"Generate": "None"},
+ "Children": [
+ {"Index": 0, "Name": "World", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSource", "Type": "TYdbDataSource"},
+ {"Index": 2, "Name": "Table", "Type": "TCoAtom"}
+ ]
+ },
+ {
+ "Name": "TYdbReadTableScheme",
+ "Base": "TYdbReadBase",
+ "Match": {"Type": "Callable", "Name": "YdbReadTableScheme!"}
+ },
+ {
+ "Name": "TYdbReadTable",
+ "Base": "TYdbReadBase",
+ "Match": {"Type": "Callable", "Name": "YdbReadTable!"},
+ "Children": [
+ {"Index": 3, "Name": "Columns", "Type": "TExprBase"},
+ {"Index": 4, "Name": "LimitHint", "Type": "TExprBase", "Optional": true}
+ ]
+ },
+ {
+ "Name": "TYdbWriteTable",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "YdbWriteTable!"},
+ "Children": [
+ {"Index": 0, "Name": "World", "Type": "TExprBase"},
+ {"Index": 1, "Name": "DataSink", "Type": "TYdbDataSink"},
+ {"Index": 2, "Name": "Table", "Type": "TCoAtom"},
+ {"Index": 3, "Name": "Input", "Type": "TExprBase"},
+ {"Index": 4, "Name": "Mode", "Type": "TCoAtom"},
+ {"Index": 5, "Name": "Settings", "Type": "TCoNameValueTupleList"}
+ ]
+ },
+ {
+ "Name": "TYdbClusterConfig",
+ "Base": "TCallable",
+ "Match": {"Type": "Callable", "Name": "YdbClusterConfig"},
+ "Children": [
+ {"Index": 0, "Name": "Locators", "Type": "TCoAtomList"},
+ {"Index": 1, "Name": "TvmId", "Type": "TCoAtom"}
+ ]
+ }
+ ]
+}
diff --git a/ydb/library/yql/providers/ydb/proto/range.proto b/ydb/library/yql/providers/ydb/proto/range.proto
index bedbc33a0e..c41d3cbc63 100644
--- a/ydb/library/yql/providers/ydb/proto/range.proto
+++ b/ydb/library/yql/providers/ydb/proto/range.proto
@@ -1,8 +1,8 @@
-syntax = "proto3";
-
-package NYql.NYdb;
-
-message TKeyRange {
- bytes from_key = 1;
- bytes to_key = 2;
-}
+syntax = "proto3";
+
+package NYql.NYdb;
+
+message TKeyRange {
+ bytes from_key = 1;
+ bytes to_key = 2;
+}
diff --git a/ydb/library/yql/providers/ydb/proto/source.proto b/ydb/library/yql/providers/ydb/proto/source.proto
index 06c0b4008a..7e6c3e68b7 100644
--- a/ydb/library/yql/providers/ydb/proto/source.proto
+++ b/ydb/library/yql/providers/ydb/proto/source.proto
@@ -1,15 +1,15 @@
-syntax = "proto3";
-option cc_enable_arenas = true;
-
-package NYql.NYdb;
-
-message TSource {
- string Table = 1;
- string Endpoint = 3;
- string Token = 4;
- string Database = 5;
- bool Secure = 6;
- repeated string Columns = 7;
- repeated uint32 KeyColumnTypes = 8;
+syntax = "proto3";
+option cc_enable_arenas = true;
+
+package NYql.NYdb;
+
+message TSource {
+ string Table = 1;
+ string Endpoint = 3;
+ string Token = 4;
+ string Database = 5;
+ bool Secure = 6;
+ repeated string Columns = 7;
+ repeated uint32 KeyColumnTypes = 8;
bool AddBearerToToken = 9;
-}
+}
diff --git a/ydb/library/yql/providers/ydb/proto/ya.make b/ydb/library/yql/providers/ydb/proto/ya.make
index a56b07af4e..9bffdc706b 100644
--- a/ydb/library/yql/providers/ydb/proto/ya.make
+++ b/ydb/library/yql/providers/ydb/proto/ya.make
@@ -1,15 +1,15 @@
-OWNER(g:yql)
-
-PROTO_LIBRARY()
-
-SRCS(
- range.proto
- source.proto
-)
-
-IF (NOT PY_PROTOS_FOR)
- EXCLUDE_TAGS(GO_PROTO)
-ENDIF()
-
-END()
-
+OWNER(g:yql)
+
+PROTO_LIBRARY()
+
+SRCS(
+ range.proto
+ source.proto
+)
+
+IF (NOT PY_PROTOS_FOR)
+ EXCLUDE_TAGS(GO_PROTO)
+ENDIF()
+
+END()
+
diff --git a/ydb/library/yql/providers/ydb/provider/ya.make b/ydb/library/yql/providers/ydb/provider/ya.make
index d6caa14a2a..b220766ee5 100644
--- a/ydb/library/yql/providers/ydb/provider/ya.make
+++ b/ydb/library/yql/providers/ydb/provider/ya.make
@@ -1,26 +1,26 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(g:yql)
-
-SRCS(
- yql_ydb_datasink.cpp
- yql_ydb_datasink_execution.cpp
- yql_ydb_datasink_type_ann.cpp
- yql_ydb_datasource.cpp
- yql_ydb_datasource_type_ann.cpp
- yql_ydb_dq_integration.cpp
- yql_ydb_exec.cpp
+
+SRCS(
+ yql_ydb_datasink.cpp
+ yql_ydb_datasink_execution.cpp
+ yql_ydb_datasink_type_ann.cpp
+ yql_ydb_datasource.cpp
+ yql_ydb_datasource_type_ann.cpp
+ yql_ydb_dq_integration.cpp
+ yql_ydb_exec.cpp
yql_ydb_io_discovery.cpp
- yql_ydb_load_meta.cpp
- yql_ydb_logical_opt.cpp
- yql_ydb_physical_opt.cpp
- yql_ydb_mkql_compiler.cpp
- yql_ydb_provider.cpp
- yql_ydb_provider_impl.cpp
- yql_ydb_settings.cpp
-)
-
-PEERDIR(
+ yql_ydb_load_meta.cpp
+ yql_ydb_logical_opt.cpp
+ yql_ydb_physical_opt.cpp
+ yql_ydb_mkql_compiler.cpp
+ yql_ydb_provider.cpp
+ yql_ydb_provider_impl.cpp
+ yql_ydb_settings.cpp
+)
+
+PEERDIR(
library/cpp/random_provider
library/cpp/time_provider
library/cpp/yson/node
@@ -51,8 +51,8 @@ PEERDIR(
ydb/library/yql/providers/result/expr_nodes
ydb/library/yql/providers/ydb/expr_nodes
ydb/library/yql/providers/ydb/proto
-)
-
-YQL_LAST_ABI_VERSION()
+)
+
+YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink.cpp
index 59d1b7c4c3..ecc8885220 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink.cpp
@@ -1,133 +1,133 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSinkProvider : public TDataProviderBase {
-public:
- TYdbDataSinkProvider(TYdbState::TPtr state)
- : State_(state)
- , TypeAnnotationTransformer_(CreateYdbDataSinkTypeAnnotationTransformer(State_))
- , ExecutionTransformer_(CreateYdbDataSinkExecTransformer(State_))
- , LogicalOptProposalTransformer_(CreateYdbLogicalOptProposalTransformer(State_))
- , PhysicalOptProposalTransformer_(CreateYdbPhysicalOptProposalTransformer(State_))
- {
- }
-
- TStringBuf GetName() const override {
- return YdbProviderName;
- }
-
- bool CanParse(const TExprNode& node) override {
- if (node.IsCallable(TCoWrite::CallableName())) {
- return TYdbDataSink::Match(node.Child(1));
- }
-
- return TypeAnnotationTransformer_->CanParse(node);
- }
-
- IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
- Y_UNUSED(instantOnly);
- return *TypeAnnotationTransformer_;
- }
-
- IGraphTransformer& GetCallableExecutionTransformer() override {
- return *ExecutionTransformer_;
- }
-
- bool CanExecute(const TExprNode& node) override {
- return ExecutionTransformer_->CanExec(node);
- }
-
- bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
- if (node.IsCallable(TCoDataSink::CallableName())) {
- if (node.Head().Content() == YdbProviderName) {
- if (const auto clusterName = node.Child(1)->Content(); State_->Configuration->HasCluster(clusterName)) {
- cluster = clusterName;
- return true;
- } else {
- ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() << "Unknown cluster name: " << clusterName));
- return false;
- }
- }
- }
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid Ydb DataSink parameters"));
- return false;
- }
-
- IGraphTransformer& GetLogicalOptProposalTransformer() override {
- return *LogicalOptProposalTransformer_;
- }
-
- IGraphTransformer& GetPhysicalOptProposalTransformer() override {
- return *PhysicalOptProposalTransformer_;
- }
-
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- YQL_CLOG(INFO, ProviderYdb) << "Rewrite " << node->Content();
- const TCoWrite write(node);
- TYdbKey key;
- YQL_ENSURE(key.Extract(*node->Child(2), ctx), "Failed to extract table key.");
- const auto settings = NCommon::ParseWriteTableSettings(TExprList(node->Child(4)), ctx);
- return Build<TYdbWriteTable>(ctx, node->Pos())
- .World(write.World())
- .DataSink(write.DataSink().Ptr())
- .Table().Build(key.GetTablePath())
- .Input(node->Child(3))
- .Mode(settings.Mode.Cast())
- .Settings(settings.Other)
- .Done()
- .Ptr();
- }
-
- TExprNode::TPtr GetClusterInfo(const TString& cluster, TExprContext& ctx) override {
- const auto find = State_->Configuration->Clusters.find(cluster);
- if (State_->Configuration->Clusters.cend() == find) {
- return {};
- }
-
- const auto& config = find->second.Raw;
-
- TPositionHandle pos;
-
- TVector<TExprBase> locators;
- const auto& grpcData = config.GetGrpc();
- for (size_t index = 0; index < grpcData.LocatorsSize(); ++index) {
- locators.push_back(Build<TCoAtom>(ctx, pos)
- .Value(grpcData.GetLocators(index))
- .Done());
- }
-
- return Build<NNodes::TYdbClusterConfig>(ctx, pos)
- .Locators<TCoAtomList>().Add(locators).Build()
- .TvmId<TCoAtom>().Build(ToString(config.GetTvmId()))
- .Done().Ptr();
- }
-
-private:
- const TYdbState::TPtr State_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<TExecTransformerBase> ExecutionTransformer_;
- const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
- const THolder<IGraphTransformer> PhysicalOptProposalTransformer_;
-};
-
-}
-
-TIntrusivePtr<IDataProvider> CreateYdbDataSink(TYdbState::TPtr state) {
- return new TYdbDataSinkProvider(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSinkProvider : public TDataProviderBase {
+public:
+ TYdbDataSinkProvider(TYdbState::TPtr state)
+ : State_(state)
+ , TypeAnnotationTransformer_(CreateYdbDataSinkTypeAnnotationTransformer(State_))
+ , ExecutionTransformer_(CreateYdbDataSinkExecTransformer(State_))
+ , LogicalOptProposalTransformer_(CreateYdbLogicalOptProposalTransformer(State_))
+ , PhysicalOptProposalTransformer_(CreateYdbPhysicalOptProposalTransformer(State_))
+ {
+ }
+
+ TStringBuf GetName() const override {
+ return YdbProviderName;
+ }
+
+ bool CanParse(const TExprNode& node) override {
+ if (node.IsCallable(TCoWrite::CallableName())) {
+ return TYdbDataSink::Match(node.Child(1));
+ }
+
+ return TypeAnnotationTransformer_->CanParse(node);
+ }
+
+ IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
+ Y_UNUSED(instantOnly);
+ return *TypeAnnotationTransformer_;
+ }
+
+ IGraphTransformer& GetCallableExecutionTransformer() override {
+ return *ExecutionTransformer_;
+ }
+
+ bool CanExecute(const TExprNode& node) override {
+ return ExecutionTransformer_->CanExec(node);
+ }
+
+ bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
+ if (node.IsCallable(TCoDataSink::CallableName())) {
+ if (node.Head().Content() == YdbProviderName) {
+ if (const auto clusterName = node.Child(1)->Content(); State_->Configuration->HasCluster(clusterName)) {
+ cluster = clusterName;
+ return true;
+ } else {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() << "Unknown cluster name: " << clusterName));
+ return false;
+ }
+ }
+ }
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid Ydb DataSink parameters"));
+ return false;
+ }
+
+ IGraphTransformer& GetLogicalOptProposalTransformer() override {
+ return *LogicalOptProposalTransformer_;
+ }
+
+ IGraphTransformer& GetPhysicalOptProposalTransformer() override {
+ return *PhysicalOptProposalTransformer_;
+ }
+
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ YQL_CLOG(INFO, ProviderYdb) << "Rewrite " << node->Content();
+ const TCoWrite write(node);
+ TYdbKey key;
+ YQL_ENSURE(key.Extract(*node->Child(2), ctx), "Failed to extract table key.");
+ const auto settings = NCommon::ParseWriteTableSettings(TExprList(node->Child(4)), ctx);
+ return Build<TYdbWriteTable>(ctx, node->Pos())
+ .World(write.World())
+ .DataSink(write.DataSink().Ptr())
+ .Table().Build(key.GetTablePath())
+ .Input(node->Child(3))
+ .Mode(settings.Mode.Cast())
+ .Settings(settings.Other)
+ .Done()
+ .Ptr();
+ }
+
+ TExprNode::TPtr GetClusterInfo(const TString& cluster, TExprContext& ctx) override {
+ const auto find = State_->Configuration->Clusters.find(cluster);
+ if (State_->Configuration->Clusters.cend() == find) {
+ return {};
+ }
+
+ const auto& config = find->second.Raw;
+
+ TPositionHandle pos;
+
+ TVector<TExprBase> locators;
+ const auto& grpcData = config.GetGrpc();
+ for (size_t index = 0; index < grpcData.LocatorsSize(); ++index) {
+ locators.push_back(Build<TCoAtom>(ctx, pos)
+ .Value(grpcData.GetLocators(index))
+ .Done());
+ }
+
+ return Build<NNodes::TYdbClusterConfig>(ctx, pos)
+ .Locators<TCoAtomList>().Add(locators).Build()
+ .TvmId<TCoAtom>().Build(ToString(config.GetTvmId()))
+ .Done().Ptr();
+ }
+
+private:
+ const TYdbState::TPtr State_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<TExecTransformerBase> ExecutionTransformer_;
+ const THolder<IGraphTransformer> LogicalOptProposalTransformer_;
+ const THolder<IGraphTransformer> PhysicalOptProposalTransformer_;
+};
+
+}
+
+TIntrusivePtr<IDataProvider> CreateYdbDataSink(TYdbState::TPtr state) {
+ return new TYdbDataSinkProvider(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_execution.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_execution.cpp
index 56cc972bed..69502127cc 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_execution.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_execution.cpp
@@ -1,36 +1,36 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSinkExecTransformer : public TExecTransformerBase {
-public:
- TYdbDataSinkExecTransformer(TYdbState::TPtr state)
- : State_(state)
- {
- AddHandler({TCoCommit::CallableName()}, RequireFirst(), Pass());
- }
-
-private:
- TYdbState::TPtr State_;
-};
-
-}
-
-THolder<TExecTransformerBase> CreateYdbDataSinkExecTransformer(TYdbState::TPtr state) {
- return THolder(new TYdbDataSinkExecTransformer(state));
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSinkExecTransformer : public TExecTransformerBase {
+public:
+ TYdbDataSinkExecTransformer(TYdbState::TPtr state)
+ : State_(state)
+ {
+ AddHandler({TCoCommit::CallableName()}, RequireFirst(), Pass());
+ }
+
+private:
+ TYdbState::TPtr State_;
+};
+
+}
+
+THolder<TExecTransformerBase> CreateYdbDataSinkExecTransformer(TYdbState::TPtr state) {
+ return THolder(new TYdbDataSinkExecTransformer(state));
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_type_ann.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_type_ann.cpp
index 3ff4aea1f8..a4104bc9f1 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_type_ann.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasink_type_ann.cpp
@@ -1,65 +1,65 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSinkTypeAnnotationTransformer : public TVisitorTransformerBase {
-public:
- TYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TYdbDataSinkTypeAnnotationTransformer;
- AddHandler({TCoCommit::CallableName()}, Hndl(&TSelf::HandleCommit));
- AddHandler({TYdbWriteTable::CallableName()}, Hndl(&TSelf::HandleWriteTable));
- AddHandler({NNodes::TYdbClusterConfig::CallableName()}, Hndl(&TSelf::HandleClusterConfig));
- }
-
- TStatus HandleCommit(TExprBase input, TExprContext&) {
- const auto commit = input.Cast<TCoCommit>();
- input.Ptr()->SetTypeAnn(commit.World().Ref().GetTypeAnn());
- return TStatus::Ok;
- }
-
- TStatus HandleWriteTable(TExprBase input, TExprContext&) {
- const auto write = input.Cast<TYdbWriteTable>();
- input.Ptr()->SetTypeAnn(write.World().Ref().GetTypeAnn());
- return TStatus::Ok;
- }
-
- TStatus HandleClusterConfig(TExprBase input, TExprContext& ctx) {
- const auto config = input.Cast<NNodes::TYdbClusterConfig>();
- if (!EnsureTupleOfAtoms(config.Locators().Ref(), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(config.TvmId().Ref(), ctx)) {
- return TStatus::Error;
- }
-
- input.Ptr()->SetTypeAnn(ctx.MakeType<TUnitExprType>());
- return TStatus::Ok;
- }
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<TVisitorTransformerBase> CreateYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state) {
- return MakeHolder<TYdbDataSinkTypeAnnotationTransformer>(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSinkTypeAnnotationTransformer : public TVisitorTransformerBase {
+public:
+ TYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TYdbDataSinkTypeAnnotationTransformer;
+ AddHandler({TCoCommit::CallableName()}, Hndl(&TSelf::HandleCommit));
+ AddHandler({TYdbWriteTable::CallableName()}, Hndl(&TSelf::HandleWriteTable));
+ AddHandler({NNodes::TYdbClusterConfig::CallableName()}, Hndl(&TSelf::HandleClusterConfig));
+ }
+
+ TStatus HandleCommit(TExprBase input, TExprContext&) {
+ const auto commit = input.Cast<TCoCommit>();
+ input.Ptr()->SetTypeAnn(commit.World().Ref().GetTypeAnn());
+ return TStatus::Ok;
+ }
+
+ TStatus HandleWriteTable(TExprBase input, TExprContext&) {
+ const auto write = input.Cast<TYdbWriteTable>();
+ input.Ptr()->SetTypeAnn(write.World().Ref().GetTypeAnn());
+ return TStatus::Ok;
+ }
+
+ TStatus HandleClusterConfig(TExprBase input, TExprContext& ctx) {
+ const auto config = input.Cast<NNodes::TYdbClusterConfig>();
+ if (!EnsureTupleOfAtoms(config.Locators().Ref(), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(config.TvmId().Ref(), ctx)) {
+ return TStatus::Error;
+ }
+
+ input.Ptr()->SetTypeAnn(ctx.MakeType<TUnitExprType>());
+ return TStatus::Ok;
+ }
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<TVisitorTransformerBase> CreateYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state) {
+ return MakeHolder<TYdbDataSinkTypeAnnotationTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource.cpp
index 4ac42a1168..3dfe4e856b 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource.cpp
@@ -1,156 +1,156 @@
-#include "yql_ydb_provider_impl.h"
-#include "yql_ydb_dq_integration.h"
-
+#include "yql_ydb_provider_impl.h"
+#include "yql_ydb_dq_integration.h"
+
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSourceProvider : public TDataProviderBase {
-public:
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSourceProvider : public TDataProviderBase {
+public:
TYdbDataSourceProvider(
TYdbState::TPtr state,
NYdb::TDriver driver)
- : State_(state)
+ : State_(state)
, IODiscoveryTransformer_(CreateYdbIODiscoveryTransformer(State_))
- , LoadMetaDataTransformer_(CreateYdbLoadTableMetadataTransformer(State_, driver))
- , CallableExecutionTransformer_(CreateYdbSourceCallableExecutionTransformer(State_))
- , TypeAnnotationTransformer_(CreateYdbDataSourceTypeAnnotationTransformer(State_))
- , DqIntegration_(CreateYdbDqIntegration(State_))
- {}
-
- TStringBuf GetName() const override {
- return YdbProviderName;
- }
-
- bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
- if (node.IsCallable(TCoDataSource::CallableName())) {
- if (node.Child(0)->Content() == YdbProviderName) {
- auto clusterName = node.Child(1)->Content();
- if (!State_->Configuration->HasCluster(clusterName)) {
- ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() <<
- "Unknown cluster name: " << clusterName));
- return false;
- }
- cluster = clusterName;
- return true;
- }
- }
- ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid Ydb DataSource parameters"));
- return false;
- }
-
- bool CanParse(const TExprNode& node) override {
- if (node.IsCallable(TCoRead::CallableName())) {
- return NNodes::TYdbDataSource::Match(node.Child(1));
- }
- return TypeAnnotationTransformer_->CanParse(node);
- }
-
+ , LoadMetaDataTransformer_(CreateYdbLoadTableMetadataTransformer(State_, driver))
+ , CallableExecutionTransformer_(CreateYdbSourceCallableExecutionTransformer(State_))
+ , TypeAnnotationTransformer_(CreateYdbDataSourceTypeAnnotationTransformer(State_))
+ , DqIntegration_(CreateYdbDqIntegration(State_))
+ {}
+
+ TStringBuf GetName() const override {
+ return YdbProviderName;
+ }
+
+ bool ValidateParameters(TExprNode& node, TExprContext& ctx, TMaybe<TString>& cluster) override {
+ if (node.IsCallable(TCoDataSource::CallableName())) {
+ if (node.Child(0)->Content() == YdbProviderName) {
+ auto clusterName = node.Child(1)->Content();
+ if (!State_->Configuration->HasCluster(clusterName)) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Child(1)->Pos()), TStringBuilder() <<
+ "Unknown cluster name: " << clusterName));
+ return false;
+ }
+ cluster = clusterName;
+ return true;
+ }
+ }
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Invalid Ydb DataSource parameters"));
+ return false;
+ }
+
+ bool CanParse(const TExprNode& node) override {
+ if (node.IsCallable(TCoRead::CallableName())) {
+ return NNodes::TYdbDataSource::Match(node.Child(1));
+ }
+ return TypeAnnotationTransformer_->CanParse(node);
+ }
+
IGraphTransformer& GetIODiscoveryTransformer() override {
return *IODiscoveryTransformer_;
}
- IGraphTransformer& GetLoadTableMetadataTransformer() override {
- return *LoadMetaDataTransformer_;
- }
-
- IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
- Y_UNUSED(instantOnly);
- return *TypeAnnotationTransformer_;
- }
-
- IGraphTransformer& GetCallableExecutionTransformer() override {
- return *CallableExecutionTransformer_;
- }
-
- TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
- Y_UNUSED(ctx);
- YQL_CLOG(INFO, ProviderYdb) << "RewriteIO";
- return node;
- }
-
- bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
- Y_UNUSED(syncList);
- canRef = false;
-
- if (node.IsCallable(TCoRight::CallableName())) {
- if (node.Head().IsCallable(TYdbReadTableScheme::CallableName())) {
- return true;
- }
- }
-
- return false;
- }
-
- bool CanExecute(const TExprNode& node) override {
- if (node.IsCallable(TYdbReadTableScheme::CallableName())) {
- return true;
- }
-
- return false;
- }
-
- const THashMap<TString, TString>* GetClusterTokens() override {
- return &State_->Configuration->Tokens;
- }
-
- bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
- Y_UNUSED(compact);
-
- for (auto& child : node.Children()) {
- children.push_back(child.Get());
- }
-
- if (TMaybeNode<TYdbReadTable>(&node)) {
- return true;
- }
- return false;
- }
-
- void GetInputs(const TExprNode& node, TVector<TPinInfo>& inputs) override {
- if (auto maybeRead = TMaybeNode<TYdbReadTable>(&node)) {
- if (auto maybeTable = maybeRead.Table()) {
- TStringBuilder tableNameBuilder;
- if (auto dataSource = maybeRead.DataSource().Maybe<NNodes::TYdbDataSource>()) {
- auto cluster = dataSource.Cast().Cluster();
- tableNameBuilder << cluster.Value() << ".";
- }
- tableNameBuilder << '`' << maybeTable.Cast().Value() << '`';
- inputs.push_back(TPinInfo(maybeRead.DataSource().Raw(), nullptr, maybeTable.Cast().Raw(), tableNameBuilder, false));
- }
- }
- }
-
- IDqIntegration* GetDqIntegration() override {
- return DqIntegration_.Get();
- }
-
-
-private:
- const TYdbState::TPtr State_;
+ IGraphTransformer& GetLoadTableMetadataTransformer() override {
+ return *LoadMetaDataTransformer_;
+ }
+
+ IGraphTransformer& GetTypeAnnotationTransformer(bool instantOnly) override {
+ Y_UNUSED(instantOnly);
+ return *TypeAnnotationTransformer_;
+ }
+
+ IGraphTransformer& GetCallableExecutionTransformer() override {
+ return *CallableExecutionTransformer_;
+ }
+
+ TExprNode::TPtr RewriteIO(const TExprNode::TPtr& node, TExprContext& ctx) override {
+ Y_UNUSED(ctx);
+ YQL_CLOG(INFO, ProviderYdb) << "RewriteIO";
+ return node;
+ }
+
+ bool CanPullResult(const TExprNode& node, TSyncMap& syncList, bool& canRef) override {
+ Y_UNUSED(syncList);
+ canRef = false;
+
+ if (node.IsCallable(TCoRight::CallableName())) {
+ if (node.Head().IsCallable(TYdbReadTableScheme::CallableName())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool CanExecute(const TExprNode& node) override {
+ if (node.IsCallable(TYdbReadTableScheme::CallableName())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ const THashMap<TString, TString>* GetClusterTokens() override {
+ return &State_->Configuration->Tokens;
+ }
+
+ bool GetDependencies(const TExprNode& node, TExprNode::TListType& children, bool compact) override {
+ Y_UNUSED(compact);
+
+ for (auto& child : node.Children()) {
+ children.push_back(child.Get());
+ }
+
+ if (TMaybeNode<TYdbReadTable>(&node)) {
+ return true;
+ }
+ return false;
+ }
+
+ void GetInputs(const TExprNode& node, TVector<TPinInfo>& inputs) override {
+ if (auto maybeRead = TMaybeNode<TYdbReadTable>(&node)) {
+ if (auto maybeTable = maybeRead.Table()) {
+ TStringBuilder tableNameBuilder;
+ if (auto dataSource = maybeRead.DataSource().Maybe<NNodes::TYdbDataSource>()) {
+ auto cluster = dataSource.Cast().Cluster();
+ tableNameBuilder << cluster.Value() << ".";
+ }
+ tableNameBuilder << '`' << maybeTable.Cast().Value() << '`';
+ inputs.push_back(TPinInfo(maybeRead.DataSource().Raw(), nullptr, maybeTable.Cast().Raw(), tableNameBuilder, false));
+ }
+ }
+ }
+
+ IDqIntegration* GetDqIntegration() override {
+ return DqIntegration_.Get();
+ }
+
+
+private:
+ const TYdbState::TPtr State_;
const THolder<IGraphTransformer> IODiscoveryTransformer_;
- const THolder<IGraphTransformer> LoadMetaDataTransformer_;
- const THolder<IGraphTransformer> CallableExecutionTransformer_;
- const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
- const THolder<IDqIntegration> DqIntegration_;
-};
-
-}
-
+ const THolder<IGraphTransformer> LoadMetaDataTransformer_;
+ const THolder<IGraphTransformer> CallableExecutionTransformer_;
+ const THolder<TVisitorTransformerBase> TypeAnnotationTransformer_;
+ const THolder<IDqIntegration> DqIntegration_;
+};
+
+}
+
TIntrusivePtr<IDataProvider> CreateYdbDataSource(
TYdbState::TPtr state,
NYdb::TDriver driver) {
- return new TYdbDataSourceProvider(state, driver);
-}
-
-} // namespace NYql
+ return new TYdbDataSourceProvider(state, driver);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource_type_ann.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource_type_ann.cpp
index fecaf57cb5..edbc95c25e 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource_type_ann.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_datasource_type_ann.cpp
@@ -1,174 +1,174 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSourceTypeAnnotationTransformer : public TVisitorTransformerBase {
-public:
- TYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TYdbDataSourceTypeAnnotationTransformer;
- AddHandler({TYdbReadTable::CallableName()}, Hndl(&TSelf::HandleReadTable));
- AddHandler({TYdbReadTableScheme::CallableName()}, Hndl(&TSelf::HandleReadTableScheme));
- AddHandler({TYdbSourceSettings::CallableName()}, Hndl(&TSelf::HandleYdbSourceSettings));
- }
-
- TStatus HandleYdbSourceSettings(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(TYdbSourceSettings::idx_Table), ctx)) {
- return TStatus::Error;
- }
-
- if (!TCoSecureParam::Match(input->Child(TYdbSourceSettings::idx_Token))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Child(TYdbSourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
- return TStatus::Error;
- }
-
- if (const auto columns = input->Child(TYdbSourceSettings::idx_Columns); !columns->IsCallable(TCoVoid::CallableName())) {
- if (!EnsureTupleOfAtoms(*columns, ctx)) {
- return TStatus::Error;
- }
-
- std::unordered_set<std::string_view> columnsSet(columns->ChildrenSize());
- for (const auto& child : columns->Children()) {
- if (const auto& name = child->Content(); !columnsSet.emplace(name).second) {
- ctx.AddError(TIssue(ctx.GetPosition(child->Pos()), TStringBuilder() << "Duplicate column name: " << name));
- return TStatus::Error;
- }
- }
- }
-
- input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
- return TStatus::Ok;
- }
-
- TStatus HandleReadTable(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureMinMaxArgsCount(*input, 4U, 5U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureWorldType(*input->Child(TYdbReadTable::idx_World), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureSpecificDataSource(*input->Child(TYdbReadTable::idx_DataSource), YdbProviderName, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(TYdbReadTable::idx_Table), ctx)) {
- return TStatus::Error;
- }
-
- if (input->ChildrenSize() > TYdbReadTable::idx_LimitHint && !EnsureSpecificDataType(*input->Child(TYdbReadTable::idx_LimitHint), EDataSlot::Uint64, ctx)) {
- return TStatus::Error;
- }
-
- std::optional<std::unordered_set<std::string_view>> columnsSet;
- if (const auto columns = input->Child(TYdbReadTable::idx_Columns); !columns->IsCallable(TCoVoid::CallableName())) {
- if (!EnsureTuple(*columns, ctx)) {
- return TStatus::Error;
- }
-
- columnsSet.emplace(columns->ChildrenSize());
- for (const auto& child : columns->Children()) {
- if (!EnsureAtom(*child, ctx)) {
- return TStatus::Error;
- }
-
- if (const auto& name = child->Content(); !columnsSet->emplace(name).second) {
- ctx.AddError(TIssue(ctx.GetPosition(child->Pos()), TStringBuilder() << "Duplicate column name: " << name));
- return TStatus::Error;
- }
- }
- }
-
- TString cluster{ input->Child(TYdbReadTable::idx_DataSource)->Child(1)->Content() };
- TString table{ input->Child(TYdbReadTable::idx_Table)->Content() };
- const auto found = State_->Tables.find(std::make_pair(cluster, table));
- if (State_->Tables.cend() == found) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() <<
- "No metadata for table: `" << cluster << "`.`" << table << "`"));
- return TStatus::Error;
- }
-
- auto itemType = found->second.ItemType;
- auto columnOrder = found->second.ColumnOrder;
- if (columnsSet) {
- auto items = itemType->GetItems();
- EraseIf(items, [&](const TItemExprType* item) { return !columnsSet->contains(item->GetName()); });
- EraseIf(columnOrder, [&](const TString& col) { return !columnsSet->contains(col); });
- itemType = ctx.MakeType<TStructExprType>(items);
- }
-
- input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
- input->Child(TYdbReadTable::idx_World)->GetTypeAnn(),
- ctx.MakeType<TListExprType>(itemType)
- }));
-
- return State_->Types->SetColumnOrder(*input, columnOrder, ctx);
- }
-
- TStatus HandleReadTableScheme(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
- Y_UNUSED(output);
- if (!EnsureArgsCount(*input, 3U, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureWorldType(*input->Child(TYdbReadTable::idx_World), ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureSpecificDataSource(*input->Child(TYdbReadTable::idx_DataSource), YdbProviderName, ctx)) {
- return TStatus::Error;
- }
-
- if (!EnsureAtom(*input->Child(TYdbReadTable::idx_Table), ctx)) {
- return TStatus::Error;
- }
-
-
- TString cluster{ input->Child(TYdbReadTable::idx_DataSource)->Child(1)->Content() };
- TString table{ input->Child(TYdbReadTable::idx_Table)->Content() };
- if (!State_->Tables.contains(std::make_pair(cluster, table))) {
- ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() <<
- "No metadata for table: `" << cluster << "`.`" << table << "`"));
- return TStatus::Error;
- }
-
- input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
- input->Child(TYdbReadTable::idx_World)->GetTypeAnn(),
- ctx.MakeType<TDataExprType>(EDataSlot::Yson)
- }));
-
- return TStatus::Ok;
- }
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<TVisitorTransformerBase> CreateYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state) {
- return MakeHolder<TYdbDataSourceTypeAnnotationTransformer>(state);
-}
-
-} // namespace NYql
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSourceTypeAnnotationTransformer : public TVisitorTransformerBase {
+public:
+ TYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TYdbDataSourceTypeAnnotationTransformer;
+ AddHandler({TYdbReadTable::CallableName()}, Hndl(&TSelf::HandleReadTable));
+ AddHandler({TYdbReadTableScheme::CallableName()}, Hndl(&TSelf::HandleReadTableScheme));
+ AddHandler({TYdbSourceSettings::CallableName()}, Hndl(&TSelf::HandleYdbSourceSettings));
+ }
+
+ TStatus HandleYdbSourceSettings(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 3U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(TYdbSourceSettings::idx_Table), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!TCoSecureParam::Match(input->Child(TYdbSourceSettings::idx_Token))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Child(TYdbSourceSettings::idx_Token)->Pos()), TStringBuilder() << "Expected " << TCoSecureParam::CallableName()));
+ return TStatus::Error;
+ }
+
+ if (const auto columns = input->Child(TYdbSourceSettings::idx_Columns); !columns->IsCallable(TCoVoid::CallableName())) {
+ if (!EnsureTupleOfAtoms(*columns, ctx)) {
+ return TStatus::Error;
+ }
+
+ std::unordered_set<std::string_view> columnsSet(columns->ChildrenSize());
+ for (const auto& child : columns->Children()) {
+ if (const auto& name = child->Content(); !columnsSet.emplace(name).second) {
+ ctx.AddError(TIssue(ctx.GetPosition(child->Pos()), TStringBuilder() << "Duplicate column name: " << name));
+ return TStatus::Error;
+ }
+ }
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TStreamExprType>(ctx.MakeType<TDataExprType>(EDataSlot::String)));
+ return TStatus::Ok;
+ }
+
+ TStatus HandleReadTable(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureMinMaxArgsCount(*input, 4U, 5U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureWorldType(*input->Child(TYdbReadTable::idx_World), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureSpecificDataSource(*input->Child(TYdbReadTable::idx_DataSource), YdbProviderName, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(TYdbReadTable::idx_Table), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (input->ChildrenSize() > TYdbReadTable::idx_LimitHint && !EnsureSpecificDataType(*input->Child(TYdbReadTable::idx_LimitHint), EDataSlot::Uint64, ctx)) {
+ return TStatus::Error;
+ }
+
+ std::optional<std::unordered_set<std::string_view>> columnsSet;
+ if (const auto columns = input->Child(TYdbReadTable::idx_Columns); !columns->IsCallable(TCoVoid::CallableName())) {
+ if (!EnsureTuple(*columns, ctx)) {
+ return TStatus::Error;
+ }
+
+ columnsSet.emplace(columns->ChildrenSize());
+ for (const auto& child : columns->Children()) {
+ if (!EnsureAtom(*child, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (const auto& name = child->Content(); !columnsSet->emplace(name).second) {
+ ctx.AddError(TIssue(ctx.GetPosition(child->Pos()), TStringBuilder() << "Duplicate column name: " << name));
+ return TStatus::Error;
+ }
+ }
+ }
+
+ TString cluster{ input->Child(TYdbReadTable::idx_DataSource)->Child(1)->Content() };
+ TString table{ input->Child(TYdbReadTable::idx_Table)->Content() };
+ const auto found = State_->Tables.find(std::make_pair(cluster, table));
+ if (State_->Tables.cend() == found) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() <<
+ "No metadata for table: `" << cluster << "`.`" << table << "`"));
+ return TStatus::Error;
+ }
+
+ auto itemType = found->second.ItemType;
+ auto columnOrder = found->second.ColumnOrder;
+ if (columnsSet) {
+ auto items = itemType->GetItems();
+ EraseIf(items, [&](const TItemExprType* item) { return !columnsSet->contains(item->GetName()); });
+ EraseIf(columnOrder, [&](const TString& col) { return !columnsSet->contains(col); });
+ itemType = ctx.MakeType<TStructExprType>(items);
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
+ input->Child(TYdbReadTable::idx_World)->GetTypeAnn(),
+ ctx.MakeType<TListExprType>(itemType)
+ }));
+
+ return State_->Types->SetColumnOrder(*input, columnOrder, ctx);
+ }
+
+ TStatus HandleReadTableScheme(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
+ Y_UNUSED(output);
+ if (!EnsureArgsCount(*input, 3U, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureWorldType(*input->Child(TYdbReadTable::idx_World), ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureSpecificDataSource(*input->Child(TYdbReadTable::idx_DataSource), YdbProviderName, ctx)) {
+ return TStatus::Error;
+ }
+
+ if (!EnsureAtom(*input->Child(TYdbReadTable::idx_Table), ctx)) {
+ return TStatus::Error;
+ }
+
+
+ TString cluster{ input->Child(TYdbReadTable::idx_DataSource)->Child(1)->Content() };
+ TString table{ input->Child(TYdbReadTable::idx_Table)->Content() };
+ if (!State_->Tables.contains(std::make_pair(cluster, table))) {
+ ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() <<
+ "No metadata for table: `" << cluster << "`.`" << table << "`"));
+ return TStatus::Error;
+ }
+
+ input->SetTypeAnn(ctx.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{
+ input->Child(TYdbReadTable::idx_World)->GetTypeAnn(),
+ ctx.MakeType<TDataExprType>(EDataSlot::Yson)
+ }));
+
+ return TStatus::Ok;
+ }
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<TVisitorTransformerBase> CreateYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state) {
+ return MakeHolder<TYdbDataSourceTypeAnnotationTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.cpp
index acb579dcaa..ecb85e824b 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.cpp
@@ -1,6 +1,6 @@
-#include "yql_ydb_dq_integration.h"
-#include "yql_ydb_mkql_compiler.h"
-
+#include "yql_ydb_dq_integration.h"
+#include "yql_ydb_mkql_compiler.h"
+
#include <ydb/library/yql/dq/expr_nodes/dq_expr_nodes.h>
#include <ydb/library/yql/providers/common/dq/yql_dq_integration_impl.h>
#include <ydb/library/yql/providers/dq/common/yql_dq_settings.h>
@@ -9,150 +9,150 @@
#include <ydb/library/yql/providers/ydb/proto/range.pb.h>
#include <ydb/library/yql/providers/ydb/proto/source.pb.h>
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDqIntegration: public TDqIntegrationBase {
-public:
- TYdbDqIntegration(TYdbState::TPtr state)
- : State_(state)
- {
- }
-
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDqIntegration: public TDqIntegrationBase {
+public:
+ TYdbDqIntegration(TYdbState::TPtr state)
+ : State_(state)
+ {
+ }
+
ui64 Partition(const TDqSettings& settings, size_t maxPartitions, const TExprNode& node,
TVector<TString>& partitions, TString*, TExprContext&, bool) override {
- TString cluster, table;
- if (const TMaybeNode<TDqSource> source = &node) {
- cluster = source.Cast().DataSource().Cast<TYdbDataSource>().Cluster().Value();
- table = source.Cast().Settings().Cast<TYdbSourceSettings>().Table().Value();
- } else if (const TMaybeNode<TYdbReadTable> read = &node) {
- cluster = read.Cast().DataSource().Cluster().Value();
- table = read.Cast().Table().Value();
- }
-
- auto& meta = State_->Tables[std::make_pair(cluster, table)];
- meta.ReadAsync = settings.EnableComputeActor.Get().GetOrElse(false); // TODO: Use special method for get settings.
- auto parts = meta.Partitions;
-
- if (maxPartitions && parts.size() > maxPartitions) {
- if (const auto extraParts = parts.size() - maxPartitions; extraParts > maxPartitions) {
- const auto dropsPerTask = (parts.size() - 1ULL) / maxPartitions;
- for (auto it = parts.begin(); parts.end() > it;) {
- auto to = it + std::min(dropsPerTask, std::distance(it, parts.end()) - 1ULL);
- it->back() = std::move(to->back());
- it = parts.erase(++it, ++to);
- }
- } else {
- const auto dropEachPart = maxPartitions / extraParts;
- for (auto it = parts.begin(); parts.size() > maxPartitions;) {
- const auto to = it + dropEachPart;
- it = to - 1U;
- it->back() = std::move(to->back());
- it = parts.erase(to);
- }
- }
- }
-
- partitions.reserve(parts.size());
- for (const auto& part : parts) {
- NYdb::TKeyRange range;
- range.set_from_key(part.front());
- range.set_to_key(part.back());
- partitions.emplace_back();
- TStringOutput out(partitions.back());
- range.Save(&out);
- }
+ TString cluster, table;
+ if (const TMaybeNode<TDqSource> source = &node) {
+ cluster = source.Cast().DataSource().Cast<TYdbDataSource>().Cluster().Value();
+ table = source.Cast().Settings().Cast<TYdbSourceSettings>().Table().Value();
+ } else if (const TMaybeNode<TYdbReadTable> read = &node) {
+ cluster = read.Cast().DataSource().Cluster().Value();
+ table = read.Cast().Table().Value();
+ }
+
+ auto& meta = State_->Tables[std::make_pair(cluster, table)];
+ meta.ReadAsync = settings.EnableComputeActor.Get().GetOrElse(false); // TODO: Use special method for get settings.
+ auto parts = meta.Partitions;
+
+ if (maxPartitions && parts.size() > maxPartitions) {
+ if (const auto extraParts = parts.size() - maxPartitions; extraParts > maxPartitions) {
+ const auto dropsPerTask = (parts.size() - 1ULL) / maxPartitions;
+ for (auto it = parts.begin(); parts.end() > it;) {
+ auto to = it + std::min(dropsPerTask, std::distance(it, parts.end()) - 1ULL);
+ it->back() = std::move(to->back());
+ it = parts.erase(++it, ++to);
+ }
+ } else {
+ const auto dropEachPart = maxPartitions / extraParts;
+ for (auto it = parts.begin(); parts.size() > maxPartitions;) {
+ const auto to = it + dropEachPart;
+ it = to - 1U;
+ it->back() = std::move(to->back());
+ it = parts.erase(to);
+ }
+ }
+ }
+
+ partitions.reserve(parts.size());
+ for (const auto& part : parts) {
+ NYdb::TKeyRange range;
+ range.set_from_key(part.front());
+ range.set_to_key(part.back());
+ partitions.emplace_back();
+ TStringOutput out(partitions.back());
+ range.Save(&out);
+ }
return 0;
- }
-
- TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool ) override {
- if (TYdbReadTable::Match(&read)) {
- return 0ul; // TODO: return real size
- }
-
- return Nothing();
- }
-
- TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
- if (const auto& maybeYdbReadTable = TMaybeNode<TYdbReadTable>(read)) {
- const auto& ydbReadTable = maybeYdbReadTable.Cast();
- const auto& clusterName = ydbReadTable.DataSource().Cluster().Value();
+ }
+
+ TMaybe<ui64> CanRead(const TDqSettings&, const TExprNode& read, TExprContext&, bool ) override {
+ if (TYdbReadTable::Match(&read)) {
+ return 0ul; // TODO: return real size
+ }
+
+ return Nothing();
+ }
+
+ TExprNode::TPtr WrapRead(const TDqSettings&, const TExprNode::TPtr& read, TExprContext& ctx) override {
+ if (const auto& maybeYdbReadTable = TMaybeNode<TYdbReadTable>(read)) {
+ const auto& ydbReadTable = maybeYdbReadTable.Cast();
+ const auto& clusterName = ydbReadTable.DataSource().Cluster().Value();
const auto token = "cluster:default_" + TString(clusterName);
YQL_CLOG(INFO, ProviderYdb) << "Wrap " << read->Content() << " with token: " << token;
-
- const auto rowType = ydbReadTable.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
- auto columns = ydbReadTable.Columns().Ptr();
- if (!columns->IsList()) {
- const auto pos = columns->Pos();
- const auto& items = rowType->Cast<TStructExprType>()->GetItems();
- TExprNode::TListType cols;
- cols.reserve(items.size());
- std::transform(items.cbegin(), items.cend(), std::back_inserter(cols), [&](const TItemExprType* item) { return ctx.NewAtom(pos, item->GetName()); });
- columns = ctx.NewList(pos, std::move(cols));
- }
-
- return Build<TDqSourceWrap>(ctx, read->Pos())
- .Input<TYdbSourceSettings>()
- .Table(ydbReadTable.Table())
- .Token<TCoSecureParam>()
+
+ const auto rowType = ydbReadTable.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back()->Cast<TListExprType>()->GetItemType();
+ auto columns = ydbReadTable.Columns().Ptr();
+ if (!columns->IsList()) {
+ const auto pos = columns->Pos();
+ const auto& items = rowType->Cast<TStructExprType>()->GetItems();
+ TExprNode::TListType cols;
+ cols.reserve(items.size());
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(cols), [&](const TItemExprType* item) { return ctx.NewAtom(pos, item->GetName()); });
+ columns = ctx.NewList(pos, std::move(cols));
+ }
+
+ return Build<TDqSourceWrap>(ctx, read->Pos())
+ .Input<TYdbSourceSettings>()
+ .Table(ydbReadTable.Table())
+ .Token<TCoSecureParam>()
.Name().Build(token)
- .Build()
- .Columns(std::move(columns))
- .Build()
- .RowType(ExpandType(ydbReadTable.Pos(), *rowType, ctx))
- .DataSource(ydbReadTable.DataSource().Cast<TCoDataSource>())
- .Done().Ptr();
- }
- return read;
- }
-
- void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
- const TDqSource source(&node);
- if (const auto maySettings = source.Settings().Maybe<TYdbSourceSettings>()) {
- const auto settings = maySettings.Cast();
-
- const auto& cluster = source.DataSource().Cast<TYdbDataSource>().Cluster().StringValue();
- const auto& table = settings.Table().StringValue();
- const auto& token = settings.Token().Name().StringValue();
-
- const auto& connect = State_->Configuration->Clusters[cluster];
-
- NYdb::TSource srcDesc;
- srcDesc.SetTable(table);
- srcDesc.SetDatabase(connect.Database);
- srcDesc.SetEndpoint(connect.Endpoint);
- srcDesc.SetSecure(connect.Secure);
+ .Build()
+ .Columns(std::move(columns))
+ .Build()
+ .RowType(ExpandType(ydbReadTable.Pos(), *rowType, ctx))
+ .DataSource(ydbReadTable.DataSource().Cast<TCoDataSource>())
+ .Done().Ptr();
+ }
+ return read;
+ }
+
+ void FillSourceSettings(const TExprNode& node, ::google::protobuf::Any& protoSettings, TString& sourceType) override {
+ const TDqSource source(&node);
+ if (const auto maySettings = source.Settings().Maybe<TYdbSourceSettings>()) {
+ const auto settings = maySettings.Cast();
+
+ const auto& cluster = source.DataSource().Cast<TYdbDataSource>().Cluster().StringValue();
+ const auto& table = settings.Table().StringValue();
+ const auto& token = settings.Token().Name().StringValue();
+
+ const auto& connect = State_->Configuration->Clusters[cluster];
+
+ NYdb::TSource srcDesc;
+ srcDesc.SetTable(table);
+ srcDesc.SetDatabase(connect.Database);
+ srcDesc.SetEndpoint(connect.Endpoint);
+ srcDesc.SetSecure(connect.Secure);
srcDesc.SetAddBearerToToken(connect.AddBearerToToken);
- srcDesc.SetToken(token);
-
- const auto& columns = settings.Columns();
- for (auto i = 0U; i < columns.Size(); ++i)
- srcDesc.AddColumns(columns.Item(i).StringValue());
-
- for (const auto type : State_->Tables[std::make_pair(cluster, table)].KeyTypes)
- srcDesc.AddKeyColumnTypes(type);
-
- protoSettings.PackFrom(srcDesc);
- sourceType = "YdbSource";
- }
- }
-
- void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override {
- RegisterDqYdbMkqlCompilers(compiler, State_);
- }
-
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<IDqIntegration> CreateYdbDqIntegration(TYdbState::TPtr state) {
+ srcDesc.SetToken(token);
+
+ const auto& columns = settings.Columns();
+ for (auto i = 0U; i < columns.Size(); ++i)
+ srcDesc.AddColumns(columns.Item(i).StringValue());
+
+ for (const auto type : State_->Tables[std::make_pair(cluster, table)].KeyTypes)
+ srcDesc.AddKeyColumnTypes(type);
+
+ protoSettings.PackFrom(srcDesc);
+ sourceType = "YdbSource";
+ }
+ }
+
+ void RegisterMkqlCompiler(NCommon::TMkqlCallableCompilerBase& compiler) override {
+ RegisterDqYdbMkqlCompilers(compiler, State_);
+ }
+
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<IDqIntegration> CreateYdbDqIntegration(TYdbState::TPtr state) {
return MakeHolder<TYdbDqIntegration>(state);
-}
-
-}
+}
+
+}
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.h b/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.h
index 69afc1051d..417e977923 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.h
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_dq_integration.h
@@ -1,13 +1,13 @@
-#pragma once
-
-#include "yql_ydb_provider.h"
-
+#pragma once
+
+#include "yql_ydb_provider.h"
+
#include <ydb/library/yql/providers/dq/interface/yql_dq_integration.h>
-
-#include <util/generic/ptr.h>
-
-namespace NYql {
-
-THolder<IDqIntegration> CreateYdbDqIntegration(TYdbState::TPtr state);
-
-}
+
+#include <util/generic/ptr.h>
+
+namespace NYql {
+
+THolder<IDqIntegration> CreateYdbDqIntegration(TYdbState::TPtr state);
+
+}
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_exec.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_exec.cpp
index 65b63106af..e798551e6e 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_exec.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_exec.cpp
@@ -1,61 +1,61 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
#include <ydb/library/yql/providers/result/expr_nodes/yql_res_expr_nodes.h>
-
+
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbDataSourceExecutionTransformer : public TVisitorTransformerBase {
-public:
- TYdbDataSourceExecutionTransformer(TYdbState::TPtr state)
- : TVisitorTransformerBase(true)
- , State_(state)
- {
- using TSelf = TYdbDataSourceExecutionTransformer;
- AddHandler({TPull::CallableName()}, Hndl(&TSelf::HandlePull));
- AddHandler({TYdbReadTableScheme::CallableName()}, Hndl(&TSelf::HandleReadTableScheme));
-
- }
-
- TStatus HandleReadTableScheme(TExprBase node, TExprContext& ctx) {
- const TYdbReadTableScheme read(node.Ptr());
- const auto& table = TString(read.Table().Value());
- const auto& cluster = TString(read.DataSource().Cluster().Value());
-
- TStringStream out;
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbDataSourceExecutionTransformer : public TVisitorTransformerBase {
+public:
+ TYdbDataSourceExecutionTransformer(TYdbState::TPtr state)
+ : TVisitorTransformerBase(true)
+ , State_(state)
+ {
+ using TSelf = TYdbDataSourceExecutionTransformer;
+ AddHandler({TPull::CallableName()}, Hndl(&TSelf::HandlePull));
+ AddHandler({TYdbReadTableScheme::CallableName()}, Hndl(&TSelf::HandleReadTableScheme));
+
+ }
+
+ TStatus HandleReadTableScheme(TExprBase node, TExprContext& ctx) {
+ const TYdbReadTableScheme read(node.Ptr());
+ const auto& table = TString(read.Table().Value());
+ const auto& cluster = TString(read.DataSource().Cluster().Value());
+
+ TStringStream out;
NYson::TYsonWriter writer(&out, NYson::EYsonFormat::Binary);
- MetaToYson(cluster, table, State_, writer);
-
- node.Ptr()->SetResult(ctx.NewAtom(node.Pos(), out.Str()));
- node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
- return IGraphTransformer::TStatus::Ok;
- }
-
- TStatus HandlePull(TExprBase node, TExprContext&) {
- node.Ptr()->SetResult(TExprNode::GetResult(node.Ref().Head().HeadPtr()));
- node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
- return IGraphTransformer::TStatus::Ok;
- }
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateYdbSourceCallableExecutionTransformer(TYdbState::TPtr state) {
- return MakeHolder<TYdbDataSourceExecutionTransformer>(state);
-}
-
-} // namespace NYql
-
+ MetaToYson(cluster, table, State_, writer);
+
+ node.Ptr()->SetResult(ctx.NewAtom(node.Pos(), out.Str()));
+ node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
+ return IGraphTransformer::TStatus::Ok;
+ }
+
+ TStatus HandlePull(TExprBase node, TExprContext&) {
+ node.Ptr()->SetResult(TExprNode::GetResult(node.Ref().Head().HeadPtr()));
+ node.Ptr()->SetState(TExprNode::EState::ExecutionComplete);
+ return IGraphTransformer::TStatus::Ok;
+ }
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateYdbSourceCallableExecutionTransformer(TYdbState::TPtr state) {
+ return MakeHolder<TYdbDataSourceExecutionTransformer>(state);
+}
+
+} // namespace NYql
+
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_load_meta.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_load_meta.cpp
index 0e77e7ec88..607b3ba7a8 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_load_meta.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_load_meta.cpp
@@ -1,282 +1,282 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
-
+
#include <ydb/library/yql/core/yql_expr_optimize.h>
#include <ydb/library/yql/core/yql_graph_transformer.h>
-
+
#include <ydb/library/yql/utils/log/log.h>
#include <ydb/library/yql/public/udf/udf_types.h>
#include <ydb/library/yql/ast/yql_expr.h>
-
+
#include <ydb/public/lib/experimental/ydb_clickhouse_internal.h>
#include <ydb/public/lib/experimental/ydb_experimental.h>
-
-namespace NYql {
-
-using namespace NNodes;
-using namespace NYdb::NClickhouseInternal;
-
-namespace {
-
-const TTypeAnnotationNode* MakeYqlType(NYdb::TTypeParser&& type, TExprContext& ctx) {
- switch (type.GetKind()) {
- case NYdb::TTypeParser::ETypeKind::Optional: {
- type.OpenOptional();
- return ctx.MakeType<TOptionalExprType>(MakeYqlType(std::move(type), ctx));
- }
- case NYdb::TTypeParser::ETypeKind::Decimal: {
- const auto decimal = type.GetDecimal();
- return ctx.MakeType<TDataExprParamsType>(NUdf::GetDataSlot(static_cast<NUdf::TDataTypeId>(type.GetPrimitive())), ToString(decimal.Precision), ToString(decimal.Scale));
- }
- case NYdb::TTypeParser::ETypeKind::Primitive:
- if (const auto typeId = static_cast<NUdf::TDataTypeId>(type.GetPrimitive()); NUdf::TDataType<NUdf::TDecimal>::Id == typeId)
- return ctx.MakeType<TDataExprParamsType>(NUdf::EDataSlot::Decimal, "22", "9");
- else
- return ctx.MakeType<TDataExprType>(NUdf::GetDataSlot(static_cast<NUdf::TDataTypeId>(type.GetPrimitive())));
- default:
- return nullptr;
- }
-}
-
-NUdf::TDataTypeId GetYqlTypeId(NYdb::TTypeParser&& type, TExprContext& ctx) {
- switch (type.GetKind()) {
- case NYdb::TTypeParser::ETypeKind::Optional: {
- type.OpenOptional();
- return GetYqlTypeId(std::move(type), ctx);
- }
- case NYdb::TTypeParser::ETypeKind::Decimal:
- case NYdb::TTypeParser::ETypeKind::Primitive:
- return static_cast<NUdf::TDataTypeId>(type.GetPrimitive());
- default:
- return 0;
- }
-}
-
-class TYdbLoadTableMetadataTransformer : public TGraphTransformerBase {
+
+namespace NYql {
+
+using namespace NNodes;
+using namespace NYdb::NClickhouseInternal;
+
+namespace {
+
+const TTypeAnnotationNode* MakeYqlType(NYdb::TTypeParser&& type, TExprContext& ctx) {
+ switch (type.GetKind()) {
+ case NYdb::TTypeParser::ETypeKind::Optional: {
+ type.OpenOptional();
+ return ctx.MakeType<TOptionalExprType>(MakeYqlType(std::move(type), ctx));
+ }
+ case NYdb::TTypeParser::ETypeKind::Decimal: {
+ const auto decimal = type.GetDecimal();
+ return ctx.MakeType<TDataExprParamsType>(NUdf::GetDataSlot(static_cast<NUdf::TDataTypeId>(type.GetPrimitive())), ToString(decimal.Precision), ToString(decimal.Scale));
+ }
+ case NYdb::TTypeParser::ETypeKind::Primitive:
+ if (const auto typeId = static_cast<NUdf::TDataTypeId>(type.GetPrimitive()); NUdf::TDataType<NUdf::TDecimal>::Id == typeId)
+ return ctx.MakeType<TDataExprParamsType>(NUdf::EDataSlot::Decimal, "22", "9");
+ else
+ return ctx.MakeType<TDataExprType>(NUdf::GetDataSlot(static_cast<NUdf::TDataTypeId>(type.GetPrimitive())));
+ default:
+ return nullptr;
+ }
+}
+
+NUdf::TDataTypeId GetYqlTypeId(NYdb::TTypeParser&& type, TExprContext& ctx) {
+ switch (type.GetKind()) {
+ case NYdb::TTypeParser::ETypeKind::Optional: {
+ type.OpenOptional();
+ return GetYqlTypeId(std::move(type), ctx);
+ }
+ case NYdb::TTypeParser::ETypeKind::Decimal:
+ case NYdb::TTypeParser::ETypeKind::Primitive:
+ return static_cast<NUdf::TDataTypeId>(type.GetPrimitive());
+ default:
+ return 0;
+ }
+}
+
+class TYdbLoadTableMetadataTransformer : public TGraphTransformerBase {
using TCluster2ClientPerSnapshotHandle = std::unordered_map<std::string_view, std::pair<TMetaClient, std::optional<TCreateSnapshotHandleResult>>>;
using TTableKey2DescribeTableResult = std::unordered_map<std::pair<TString, TString>, std::optional<TDescribeTableResult>, THash<std::pair<TString, TString>>>;
-public:
- TYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver)
- : Driver_(std::move(driver)), State_(std::move(state))
- {}
-
- TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- output = input;
-
- if (ctx.Step.IsDone(TExprStep::LoadTablesMetadata)) {
- return TStatus::Ok;
- }
-
+public:
+ TYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver)
+ : Driver_(std::move(driver)), State_(std::move(state))
+ {}
+
+ TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
+ output = input;
+
+ if (ctx.Step.IsDone(TExprStep::LoadTablesMetadata)) {
+ return TStatus::Ok;
+ }
+
Y_VERIFY(Clients_, "Clients_ was destroyed");
Y_VERIFY(PendingTables_, "PendingTables_ was destroyed");
- std::unordered_map<TString, std::unordered_set<TString>> tablesFromCluster;
-
- TOptimizeExprSettings settings{ nullptr };
- settings.VisitChanges = true;
- const auto status = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
- const TExprBase nodeExpr(node);
- if (const auto left = nodeExpr.Maybe<TCoLeft>()) {
- if (const auto read = left.Input().Maybe<TYdbReadTable>()) {
- if (const auto world = read.World().Cast().Ptr()) {
- return world;
- }
- }
- }
-
- if (!nodeExpr.Maybe<TYdbRead>()) {
- return node;
- }
-
- const TYdbRead read(node);
- if (read.DataSource().Category().Value() != YdbProviderName) {
- return node;
- }
-
- TIssueScopeGuard issueScopeRead(ctx.IssueManager, [&]() {
- return MakeIntrusive<TIssue>(ctx.GetPosition(read.Pos()), TStringBuilder() << "At function: " << TCoRead::CallableName());
- });
-
- TYdbKey key;
- if (!key.Extract(read.FreeArgs().Get(2).Ref(), ctx))
- return nullptr;
-
- const auto& cluster = read.DataSource().Cluster().StringValue();
- const auto& database = State_->Configuration->Clusters[cluster].Database;
- auto table = TString(key.GetTablePath());
- if (table.front() != '/')
+ std::unordered_map<TString, std::unordered_set<TString>> tablesFromCluster;
+
+ TOptimizeExprSettings settings{ nullptr };
+ settings.VisitChanges = true;
+ const auto status = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ const TExprBase nodeExpr(node);
+ if (const auto left = nodeExpr.Maybe<TCoLeft>()) {
+ if (const auto read = left.Input().Maybe<TYdbReadTable>()) {
+ if (const auto world = read.World().Cast().Ptr()) {
+ return world;
+ }
+ }
+ }
+
+ if (!nodeExpr.Maybe<TYdbRead>()) {
+ return node;
+ }
+
+ const TYdbRead read(node);
+ if (read.DataSource().Category().Value() != YdbProviderName) {
+ return node;
+ }
+
+ TIssueScopeGuard issueScopeRead(ctx.IssueManager, [&]() {
+ return MakeIntrusive<TIssue>(ctx.GetPosition(read.Pos()), TStringBuilder() << "At function: " << TCoRead::CallableName());
+ });
+
+ TYdbKey key;
+ if (!key.Extract(read.FreeArgs().Get(2).Ref(), ctx))
+ return nullptr;
+
+ const auto& cluster = read.DataSource().Cluster().StringValue();
+ const auto& database = State_->Configuration->Clusters[cluster].Database;
+ auto table = TString(key.GetTablePath());
+ if (table.front() != '/')
table = database + '/' + table;
- const auto& tableKey = std::make_pair(cluster, table);
- if (State_->Tables.cend() == State_->Tables.find(tableKey)) {
+ const auto& tableKey = std::make_pair(cluster, table);
+ if (State_->Tables.cend() == State_->Tables.find(tableKey)) {
PendingTables_->emplace(tableKey, std::nullopt);
tablesFromCluster[tableKey.first].emplace(tableKey.second);
- }
-
- switch (key.GetKeyType()) {
- case TYdbKey::Type::Table:
- return Build<TYdbReadTable>(ctx, read.Pos())
- .World(read.World())
- .DataSource(read.DataSource())
- .Table().Value(table).Build()
- .Columns<TCoVoid>().Build()
- .Done().Ptr();
- case TYdbKey::Type::TableScheme:
- return Build<TYdbReadTableScheme>(ctx, read.Pos())
- .World(read.World())
- .DataSource(read.DataSource())
- .Table().Value(table).Build()
- .Done().Ptr();
- default:
- ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), "Unsupported key type for Ydb."));
- return nullptr;
- }
- }, ctx, settings);
-
+ }
+
+ switch (key.GetKeyType()) {
+ case TYdbKey::Type::Table:
+ return Build<TYdbReadTable>(ctx, read.Pos())
+ .World(read.World())
+ .DataSource(read.DataSource())
+ .Table().Value(table).Build()
+ .Columns<TCoVoid>().Build()
+ .Done().Ptr();
+ case TYdbKey::Type::TableScheme:
+ return Build<TYdbReadTableScheme>(ctx, read.Pos())
+ .World(read.World())
+ .DataSource(read.DataSource())
+ .Table().Value(table).Build()
+ .Done().Ptr();
+ default:
+ ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), "Unsupported key type for Ydb."));
+ return nullptr;
+ }
+ }, ctx, settings);
+
if (status == TStatus::Error || PendingTables_->empty()) {
- return status;
- }
-
- std::vector<NThreading::TFuture<void>> handles;
+ return status;
+ }
+
+ std::vector<NThreading::TFuture<void>> handles;
handles.reserve(PendingTables_->size() + tablesFromCluster.size());
-
- for (const auto& item : tablesFromCluster) {
- const auto& cluster = item.first;
+
+ for (const auto& item : tablesFromCluster) {
+ const auto& cluster = item.first;
TString token = State_->Configuration->Tokens.at(cluster);
-
- const auto& config = State_->Configuration->Clusters[cluster];
+
+ const auto& config = State_->Configuration->Clusters[cluster];
std::shared_ptr<NYdb::ICredentialsProviderFactory> credentialsProviderFactory = CreateCredentialsProviderFactoryForStructuredToken(State_->CredentialsFactory, token, config.AddBearerToToken);
const auto ins = Clients_->emplace(cluster, std::pair<TMetaClient, std::optional<TCreateSnapshotHandleResult>>{{Driver_, NYdb::TCommonClientSettings()
- .Database(config.Database)
- .DiscoveryEndpoint(config.Endpoint)
- .EnableSsl(config.Secure)
+ .Database(config.Database)
+ .DiscoveryEndpoint(config.Endpoint)
+ .EnableSsl(config.Secure)
.CredentialsProviderFactory(credentialsProviderFactory)
- .DiscoveryMode(NYdb::EDiscoveryMode::Async)}, std::nullopt});
-
- YQL_CLOG(INFO, ProviderYdb) << "Take snapshot for: `" << cluster << "` from " << config.Endpoint;
-
+ .DiscoveryMode(NYdb::EDiscoveryMode::Async)}, std::nullopt});
+
+ YQL_CLOG(INFO, ProviderYdb) << "Take snapshot for: `" << cluster << "` from " << config.Endpoint;
+
std::optional<TCreateSnapshotHandleResult>& snapshot = ins.first->second.second;
std::weak_ptr<TCluster2ClientPerSnapshotHandle> clients = Clients_;
handles.emplace_back(ins.first->second.first.CreateSnapshotHandle(TVector<TString>(item.second.cbegin(), item.second.cend())).Apply([clients, &snapshot]
- (const NThreading::TFuture<TCreateSnapshotHandleResult>& future) {
+ (const NThreading::TFuture<TCreateSnapshotHandleResult>& future) {
if (future.HasException()) {
const_cast<NThreading::TFuture<TCreateSnapshotHandleResult>&>(future).ExtractValue();
} else if (clients.lock()) {
snapshot.emplace(const_cast<NThreading::TFuture<TCreateSnapshotHandleResult>&>(future).ExtractValue());
}
- }));
- }
-
+ }));
+ }
+
for (auto& pair : *PendingTables_) {
const auto find = Clients_->find(pair.first.first);
- const auto& table = pair.first.second;
- YQL_CLOG(INFO, ProviderYdb) << "Load table meta for: `" << table << "`";
-
+ const auto& table = pair.first.second;
+ YQL_CLOG(INFO, ProviderYdb) << "Load table meta for: `" << table << "`";
+
std::optional<TDescribeTableResult>& meta = pair.second;
std::weak_ptr<TTableKey2DescribeTableResult> pendingTables = PendingTables_;
handles.emplace_back(find->second.first.GetTableDescription(table, true).Apply([pendingTables, &meta]
- (const NThreading::TFuture<TDescribeTableResult>& future) {
+ (const NThreading::TFuture<TDescribeTableResult>& future) {
if (future.HasException()) {
const_cast<NThreading::TFuture<TDescribeTableResult>&>(future).ExtractValue();
} else if (pendingTables.lock()) {
meta.emplace(const_cast<NThreading::TFuture<TDescribeTableResult>&>(future).ExtractValue());
}
- }));
- }
-
- if (handles.empty()) {
- return TStatus::Ok;
- }
-
- AsyncFuture_ = NThreading::WaitExceptionOrAll(handles);
- return TStatus::Async;
- }
-
- NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
- return AsyncFuture_;
- }
-
- TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
- YQL_ENSURE(AsyncFuture_.HasValue());
- output = input;
-
+ }));
+ }
+
+ if (handles.empty()) {
+ return TStatus::Ok;
+ }
+
+ AsyncFuture_ = NThreading::WaitExceptionOrAll(handles);
+ return TStatus::Async;
+ }
+
+ NThreading::TFuture<void> DoGetAsyncFuture(const TExprNode&) final {
+ return AsyncFuture_;
+ }
+
+ TStatus DoApplyAsyncChanges(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final {
+ YQL_ENSURE(AsyncFuture_.HasValue());
+ output = input;
+
Y_VERIFY(Clients_, "Clients_ was destroyed");
Y_VERIFY(PendingTables_, "PendingTables_ was destroyed");
- bool failed = false;
+ bool failed = false;
std::unordered_map<std::string_view, TSnapshotHandle> snapshots(Clients_->size());
for (auto& client : *Clients_) {
- auto& snapshot = *client.second.second;
- if (snapshot.IsSuccess()) {
- snapshots.emplace(client.first, snapshot.ExtractResult());
- } else {
- failed = true;
+ auto& snapshot = *client.second.second;
+ if (snapshot.IsSuccess()) {
+ snapshots.emplace(client.first, snapshot.ExtractResult());
+ } else {
+ failed = true;
const auto& config = State_->Configuration->Clusters[TString(client.first)];
ctx.AddError(TIssue({}, TStringBuilder() << "Failed to take snapshot for: `" << client.first << "`, endpoint: " << config.Endpoint << ", status: " << snapshot.GetStatus()));
- for (const auto& issue : snapshot.GetIssues())
- ctx.AddError(issue);
- }
- }
-
+ for (const auto& issue : snapshot.GetIssues())
+ ctx.AddError(issue);
+ }
+ }
+
for (auto& pair : *PendingTables_) {
- const auto& result = *pair.second;
- auto& meta = State_->Tables[pair.first];
- meta.Snapshot = snapshots[pair.first.first];
- if (result.IsSuccess()) {
- const auto& tableDescription = result.GetDescription();
- const auto& columns = tableDescription.columns();
- std::unordered_map<std::string_view, NUdf::TDataTypeId> map(columns.size());
- TVector<const TItemExprType*> items;
- items.reserve(columns.size());
- std::transform(columns.cbegin(), columns.cend(), std::back_inserter(items), [&map, &ctx] (const Ydb::Table::ColumnMeta& col) {
- map.emplace(col.Getname(), GetYqlTypeId(NYdb::TTypeParser(col.Gettype()), ctx));
- return ctx.MakeType<TItemExprType>(ctx.AppendString(col.Getname()), MakeYqlType(NYdb::TTypeParser(col.Gettype()), ctx));
- });
- meta.ItemType = ctx.MakeType<TStructExprType>(items);
-
- const auto& pKey = tableDescription.primary_key();
- meta.KeyTypes.reserve(pKey.size());
- std::transform(pKey.cbegin(), pKey.cend(), std::back_inserter(meta.KeyTypes), [&map] (const std::string_view& col) { return map[col]; });
-
- const auto& partitions = tableDescription.partitions();
- YQL_CLOG(INFO, ProviderYdb) << "Table " << pair.first.second << " has " << partitions.size() << " partitions by " << tableDescription.primary_key();
- TString endKey;
- meta.Partitions.reserve(partitions.size());
- for (const auto& part : partitions) {
- meta.Partitions.emplace_back(std::array<TString,2U>{{std::move(endKey), part.end_key()}});
- endKey = meta.Partitions.back().back();
- }
- meta.Partitions.back().back().clear();
- } else {
- failed = true;
+ const auto& result = *pair.second;
+ auto& meta = State_->Tables[pair.first];
+ meta.Snapshot = snapshots[pair.first.first];
+ if (result.IsSuccess()) {
+ const auto& tableDescription = result.GetDescription();
+ const auto& columns = tableDescription.columns();
+ std::unordered_map<std::string_view, NUdf::TDataTypeId> map(columns.size());
+ TVector<const TItemExprType*> items;
+ items.reserve(columns.size());
+ std::transform(columns.cbegin(), columns.cend(), std::back_inserter(items), [&map, &ctx] (const Ydb::Table::ColumnMeta& col) {
+ map.emplace(col.Getname(), GetYqlTypeId(NYdb::TTypeParser(col.Gettype()), ctx));
+ return ctx.MakeType<TItemExprType>(ctx.AppendString(col.Getname()), MakeYqlType(NYdb::TTypeParser(col.Gettype()), ctx));
+ });
+ meta.ItemType = ctx.MakeType<TStructExprType>(items);
+
+ const auto& pKey = tableDescription.primary_key();
+ meta.KeyTypes.reserve(pKey.size());
+ std::transform(pKey.cbegin(), pKey.cend(), std::back_inserter(meta.KeyTypes), [&map] (const std::string_view& col) { return map[col]; });
+
+ const auto& partitions = tableDescription.partitions();
+ YQL_CLOG(INFO, ProviderYdb) << "Table " << pair.first.second << " has " << partitions.size() << " partitions by " << tableDescription.primary_key();
+ TString endKey;
+ meta.Partitions.reserve(partitions.size());
+ for (const auto& part : partitions) {
+ meta.Partitions.emplace_back(std::array<TString,2U>{{std::move(endKey), part.end_key()}});
+ endKey = meta.Partitions.back().back();
+ }
+ meta.Partitions.back().back().clear();
+ } else {
+ failed = true;
ctx.AddError(TIssue({}, TStringBuilder() << "Failed to load table metadata for: `" << pair.first.second << ", status: " << result.GetStatus() << "`\n"));
- for (const auto& issue : result.GetIssues())
- ctx.AddError(issue);
- }
- }
-
+ for (const auto& issue : result.GetIssues())
+ ctx.AddError(issue);
+ }
+ }
+
Clients_->clear();
PendingTables_->clear();
- return failed ? TStatus::Error : TStatus::Ok;
- }
-
-private:
- const NYdb::TDriver Driver_;
- const TYdbState::TPtr State_;
+ return failed ? TStatus::Error : TStatus::Ok;
+ }
+
+private:
+ const NYdb::TDriver Driver_;
+ const TYdbState::TPtr State_;
std::shared_ptr<TCluster2ClientPerSnapshotHandle> Clients_ = std::make_shared<TCluster2ClientPerSnapshotHandle>();
std::shared_ptr<TTableKey2DescribeTableResult > PendingTables_ = std::make_shared<TTableKey2DescribeTableResult>();
- NThreading::TFuture<void> AsyncFuture_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver) {
- return MakeHolder<TYdbLoadTableMetadataTransformer>(state, driver);
-}
-
-} // namespace NYql
+ NThreading::TFuture<void> AsyncFuture_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver) {
+ return MakeHolder<TYdbLoadTableMetadataTransformer>(state, driver);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_logical_opt.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_logical_opt.cpp
index 6a654a48a6..178ff9f207 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_logical_opt.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_logical_opt.cpp
@@ -1,5 +1,5 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
#include <ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.h>
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
@@ -9,89 +9,89 @@
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/core/yql_opt_utils.h>
#include <ydb/library/yql/utils/log/log.h>
-
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-class TYdbLogicalOptProposalTransformer : public TOptimizeTransformerBase {
-public:
- TYdbLogicalOptProposalTransformer(TYdbState::TPtr state)
- : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
- , State_(state)
- {
-#define HNDL(name) "LogicalOptimizer-"#name, Hndl(&TYdbLogicalOptProposalTransformer::name)
- AddHandler(0, &TCoLeft::Match, HNDL(TrimReadWorld));
- AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembers));
- AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembersOverDqWrap));
-#undef HNDL
- }
-
- TMaybeNode<TExprBase> TrimReadWorld(TExprBase node, TExprContext& ctx) const {
- const auto& maybeRead = node.Cast<TCoLeft>().Input().Maybe<TYdbReadTable>();
- if (!maybeRead) {
- return node;
- }
-
- return TExprBase(ctx.NewWorld(node.Pos()));
- }
-
- TMaybeNode<TExprBase> ExtractMembers(TExprBase node, TExprContext& ctx) const {
- const auto& extract = node.Cast<TCoExtractMembers>();
- const auto& read = extract.Input().Maybe<TCoRight>().Input().Maybe<TYdbReadTable>();
- if (!read) {
- return node;
- }
-
- const auto& cast = read.Cast();
- return Build<TCoRight>(ctx, extract.Pos())
- .Input<TYdbReadTable>()
- .World(cast.World())
- .DataSource(cast.DataSource())
- .Table(cast.Table())
- .Columns(extract.Members())
- .Build()
- .Done();
- }
-
- TMaybeNode<TExprBase> ExtractMembersOverDqWrap(TExprBase node, TExprContext& ctx) const {
- const auto& extract = node.Cast<TCoExtractMembers>();
- const auto& input = extract.Input();
- if (const auto& read = input.Maybe<TDqSourceWrap>().Input().Maybe<TYdbSourceSettings>()) {
- const auto& cast = read.Cast();
- return Build<TDqSourceWrap>(ctx, node.Pos())
- .Input<TYdbSourceSettings>()
- .InitFrom(cast)
- .Columns(extract.Members())
- .Build()
- .DataSource(input.Cast<TDqSourceWrap>().DataSource())
- .RowType(ExpandType(node.Pos(), *GetSeqItemType(extract.Ref().GetTypeAnn()), ctx))
- .Done();
- }
- if (const auto& read = input.Maybe<TDqReadWrap>().Input().Maybe<TYdbReadTable>()) {
- const auto& cast = read.Cast();
- return Build<TDqReadWrap>(ctx, node.Pos())
- .InitFrom(input.Cast<TDqReadWrap>())
- .Input<TYdbReadTable>()
- .InitFrom(cast)
- .Columns(extract.Members())
- .Build()
- .Done();
- }
- return node;
-
- }
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateYdbLogicalOptProposalTransformer(TYdbState::TPtr state) {
- return MakeHolder<TYdbLogicalOptProposalTransformer>(state);
-}
-
-} // namespace NYql
+
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+class TYdbLogicalOptProposalTransformer : public TOptimizeTransformerBase {
+public:
+ TYdbLogicalOptProposalTransformer(TYdbState::TPtr state)
+ : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
+ , State_(state)
+ {
+#define HNDL(name) "LogicalOptimizer-"#name, Hndl(&TYdbLogicalOptProposalTransformer::name)
+ AddHandler(0, &TCoLeft::Match, HNDL(TrimReadWorld));
+ AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembers));
+ AddHandler(0, &TCoExtractMembers::Match, HNDL(ExtractMembersOverDqWrap));
+#undef HNDL
+ }
+
+ TMaybeNode<TExprBase> TrimReadWorld(TExprBase node, TExprContext& ctx) const {
+ const auto& maybeRead = node.Cast<TCoLeft>().Input().Maybe<TYdbReadTable>();
+ if (!maybeRead) {
+ return node;
+ }
+
+ return TExprBase(ctx.NewWorld(node.Pos()));
+ }
+
+ TMaybeNode<TExprBase> ExtractMembers(TExprBase node, TExprContext& ctx) const {
+ const auto& extract = node.Cast<TCoExtractMembers>();
+ const auto& read = extract.Input().Maybe<TCoRight>().Input().Maybe<TYdbReadTable>();
+ if (!read) {
+ return node;
+ }
+
+ const auto& cast = read.Cast();
+ return Build<TCoRight>(ctx, extract.Pos())
+ .Input<TYdbReadTable>()
+ .World(cast.World())
+ .DataSource(cast.DataSource())
+ .Table(cast.Table())
+ .Columns(extract.Members())
+ .Build()
+ .Done();
+ }
+
+ TMaybeNode<TExprBase> ExtractMembersOverDqWrap(TExprBase node, TExprContext& ctx) const {
+ const auto& extract = node.Cast<TCoExtractMembers>();
+ const auto& input = extract.Input();
+ if (const auto& read = input.Maybe<TDqSourceWrap>().Input().Maybe<TYdbSourceSettings>()) {
+ const auto& cast = read.Cast();
+ return Build<TDqSourceWrap>(ctx, node.Pos())
+ .Input<TYdbSourceSettings>()
+ .InitFrom(cast)
+ .Columns(extract.Members())
+ .Build()
+ .DataSource(input.Cast<TDqSourceWrap>().DataSource())
+ .RowType(ExpandType(node.Pos(), *GetSeqItemType(extract.Ref().GetTypeAnn()), ctx))
+ .Done();
+ }
+ if (const auto& read = input.Maybe<TDqReadWrap>().Input().Maybe<TYdbReadTable>()) {
+ const auto& cast = read.Cast();
+ return Build<TDqReadWrap>(ctx, node.Pos())
+ .InitFrom(input.Cast<TDqReadWrap>())
+ .Input<TYdbReadTable>()
+ .InitFrom(cast)
+ .Columns(extract.Members())
+ .Build()
+ .Done();
+ }
+ return node;
+
+ }
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateYdbLogicalOptProposalTransformer(TYdbState::TPtr state) {
+ return MakeHolder<TYdbLogicalOptProposalTransformer>(state);
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.cpp
index 8caab049bd..b76d3b0007 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.cpp
@@ -1,153 +1,153 @@
-#include "yql_ydb_mkql_compiler.h"
-
+#include "yql_ydb_mkql_compiler.h"
+
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
#include <ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.h>
#include <ydb/library/yql/providers/common/mkql/yql_type_mkql.h>
#include <ydb/library/yql/minikql/mkql_node_cast.h>
#include <ydb/library/yql/minikql/mkql_node.h>
#include <ydb/library/yql/core/yql_opt_utils.h>
-
-#include <library/cpp/yson/node/node.h>
-#include <library/cpp/yson/node/node_io.h>
-
-#include <algorithm>
-
-namespace NYql {
-
-using namespace NKikimr::NMiniKQL;
-using namespace NNodes;
-
-namespace {
-
-TRuntimeNode BuildYdbParseCall(TRuntimeNode input, TType* itemType, NCommon::TMkqlBuildContext& ctx)
-{
- const auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFromYdb", {}, itemType), {input}));
- const auto structType = static_cast<const TStructType*>(itemType);
- return ctx.ProgramBuilder.ExpandMap(flow,
- [&](TRuntimeNode item) {
- TRuntimeNode::TList fields;
- fields.reserve(structType->GetMembersCount());
- auto j = 0U;
- std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
- return fields;
- });
-}
-
-template<bool Async>
-TRuntimeNode BuildYdbInputCall(
- const TType* outputType,
- TType* itemType,
+
+#include <library/cpp/yson/node/node.h>
+#include <library/cpp/yson/node/node_io.h>
+
+#include <algorithm>
+
+namespace NYql {
+
+using namespace NKikimr::NMiniKQL;
+using namespace NNodes;
+
+namespace {
+
+TRuntimeNode BuildYdbParseCall(TRuntimeNode input, TType* itemType, NCommon::TMkqlBuildContext& ctx)
+{
+ const auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFromYdb", {}, itemType), {input}));
+ const auto structType = static_cast<const TStructType*>(itemType);
+ return ctx.ProgramBuilder.ExpandMap(flow,
+ [&](TRuntimeNode item) {
+ TRuntimeNode::TList fields;
+ fields.reserve(structType->GetMembersCount());
+ auto j = 0U;
+ std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
+ return fields;
+ });
+}
+
+template<bool Async>
+TRuntimeNode BuildYdbInputCall(
+ const TType* outputType,
+ TType* itemType,
const std::string_view& database,
- const std::string_view& endpoint,
- bool secure,
- const std::string_view& token,
- const std::string_view& table,
- const std::string_view& snapshot,
- const std::vector<NUdf::TDataTypeId>& keysTypes,
- TRuntimeNode limit,
- NCommon::TMkqlBuildContext& ctx)
-{
- const auto streamType = ctx.ProgramBuilder.NewStreamType(ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
- const auto structType = static_cast<const TStructType*>(itemType);
-
- TRuntimeNode::TList columns;
- columns.reserve(structType->GetMembersCount());
- auto i = 0U;
- std::generate_n(std::back_inserter(columns), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(structType->GetMemberName(i++)); });
-
- TRuntimeNode::TList keys;
- keys.reserve(keysTypes.size());
- std::transform(keysTypes.cbegin(), keysTypes.cend(), std::back_inserter(keys), [&ctx](const NUdf::TDataTypeId id){ return ctx.ProgramBuilder.NewDataLiteral(id); });
-
- TCallableBuilder scan(ctx.ProgramBuilder.GetTypeEnvironment(), Async ? "KikScanAsync" : "KikScan", streamType);
-
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(table));
+ const std::string_view& endpoint,
+ bool secure,
+ const std::string_view& token,
+ const std::string_view& table,
+ const std::string_view& snapshot,
+ const std::vector<NUdf::TDataTypeId>& keysTypes,
+ TRuntimeNode limit,
+ NCommon::TMkqlBuildContext& ctx)
+{
+ const auto streamType = ctx.ProgramBuilder.NewStreamType(ctx.ProgramBuilder.NewDataType(NUdf::TDataType<char*>::Id));
+ const auto structType = static_cast<const TStructType*>(itemType);
+
+ TRuntimeNode::TList columns;
+ columns.reserve(structType->GetMembersCount());
+ auto i = 0U;
+ std::generate_n(std::back_inserter(columns), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(structType->GetMemberName(i++)); });
+
+ TRuntimeNode::TList keys;
+ keys.reserve(keysTypes.size());
+ std::transform(keysTypes.cbegin(), keysTypes.cend(), std::back_inserter(keys), [&ctx](const NUdf::TDataTypeId id){ return ctx.ProgramBuilder.NewDataLiteral(id); });
+
+ TCallableBuilder scan(ctx.ProgramBuilder.GetTypeEnvironment(), Async ? "KikScanAsync" : "KikScan", streamType);
+
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(table));
scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(database));
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(endpoint));
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(token));
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(snapshot));
- scan.Add(ctx.ProgramBuilder.NewTuple(columns));
- scan.Add(ctx.ProgramBuilder.NewTuple(keys));
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""));
- scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""));
- scan.Add(limit);
- scan.Add(ctx.ProgramBuilder.NewDataLiteral(secure));
-
- auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFromYdb", {}, itemType), {TRuntimeNode(scan.Build(), false)}));
-
- if (!AS_TYPE(TFlowType, outputType)->GetItemType()->IsSameType(*itemType)) {
- flow = ctx.ProgramBuilder.ExpandMap(flow,
- [&](TRuntimeNode item) {
- TRuntimeNode::TList fields;
- fields.reserve(structType->GetMembersCount());
- auto j = 0U;
- std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
- return fields;
- });
- }
-
- return flow;
-}
-
-}
-
-void RegisterDqYdbMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TYdbState::TPtr& state) {
- compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
- [](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
- if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == YdbProviderName) {
- const auto input = MkqlBuildExpr(wrapper.Input().Ref(), ctx);
- const auto inputItemType = NCommon::BuildType(wrapper.RowType().Ref(), *wrapper.RowType().Ref().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
- return BuildYdbParseCall(input, inputItemType, ctx);
- }
-
- return TRuntimeNode();
- });
-
- compiler.ChainCallable(TDqReadWideWrap::CallableName(),
- [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
- if (const auto wrapper = TDqReadWrapBase(&node); wrapper.Input().Maybe<TYdbReadTable>().IsValid()) {
- const auto read = wrapper.Input().Cast<TYdbReadTable>();
- const auto cluster = read.DataSource().Cluster().StringValue();
- const auto readType = read.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
- const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *GetSeqItemType(readType), ctx.ProgramBuilder);
- const auto outputType = NCommon::BuildType(wrapper.Ref(), *wrapper.Ref().GetTypeAnn(), ctx.ProgramBuilder);
- const auto limit = read.LimitHint() ?
- ctx.ProgramBuilder.NewOptional(MkqlBuildExpr(read.LimitHint().Cast().Ref(), ctx)):
- ctx.ProgramBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
- const auto& meta = state->Tables[std::make_pair(cluster, read.Table().StringValue())];
- const auto& config = state->Configuration->Clusters[cluster];
- if (meta.ReadAsync)
- return BuildYdbInputCall<true>(
- outputType,
- inputItemType,
- config.Database,
- config.Endpoint,
- config.Secure,
- wrapper.Token().Name().Cast().Value(),
- read.Table(),
- meta.Snapshot.GetSnapshotId(),
- meta.KeyTypes,
- limit,
- ctx
- );
- else
- return BuildYdbInputCall<false>(
- outputType,
- inputItemType,
- config.Database,
- config.Endpoint,
- config.Secure,
- wrapper.Token().Name().Cast().Value(),
- read.Table(),
- meta.Snapshot.GetSnapshotId(),
- meta.KeyTypes,
- limit,
- ctx
- );
- }
-
- return TRuntimeNode();
- });
-}
-
-}
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(endpoint));
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(token));
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(snapshot));
+ scan.Add(ctx.ProgramBuilder.NewTuple(columns));
+ scan.Add(ctx.ProgramBuilder.NewTuple(keys));
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral<NUdf::EDataSlot::String>(""));
+ scan.Add(limit);
+ scan.Add(ctx.ProgramBuilder.NewDataLiteral(secure));
+
+ auto flow = ctx.ProgramBuilder.ToFlow(ctx.ProgramBuilder.Apply(ctx.ProgramBuilder.Udf("ClickHouseClient.ParseFromYdb", {}, itemType), {TRuntimeNode(scan.Build(), false)}));
+
+ if (!AS_TYPE(TFlowType, outputType)->GetItemType()->IsSameType(*itemType)) {
+ flow = ctx.ProgramBuilder.ExpandMap(flow,
+ [&](TRuntimeNode item) {
+ TRuntimeNode::TList fields;
+ fields.reserve(structType->GetMembersCount());
+ auto j = 0U;
+ std::generate_n(std::back_inserter(fields), structType->GetMembersCount(), [&](){ return ctx.ProgramBuilder.Member(item, structType->GetMemberName(j++)); });
+ return fields;
+ });
+ }
+
+ return flow;
+}
+
+}
+
+void RegisterDqYdbMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TYdbState::TPtr& state) {
+ compiler.ChainCallable(TDqSourceWideWrap::CallableName(),
+ [](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
+ if (const auto wrapper = TDqSourceWideWrap(&node); wrapper.DataSource().Category().Value() == YdbProviderName) {
+ const auto input = MkqlBuildExpr(wrapper.Input().Ref(), ctx);
+ const auto inputItemType = NCommon::BuildType(wrapper.RowType().Ref(), *wrapper.RowType().Ref().GetTypeAnn()->Cast<TTypeExprType>()->GetType(), ctx.ProgramBuilder);
+ return BuildYdbParseCall(input, inputItemType, ctx);
+ }
+
+ return TRuntimeNode();
+ });
+
+ compiler.ChainCallable(TDqReadWideWrap::CallableName(),
+ [state](const TExprNode& node, NCommon::TMkqlBuildContext& ctx) {
+ if (const auto wrapper = TDqReadWrapBase(&node); wrapper.Input().Maybe<TYdbReadTable>().IsValid()) {
+ const auto read = wrapper.Input().Cast<TYdbReadTable>();
+ const auto cluster = read.DataSource().Cluster().StringValue();
+ const auto readType = read.Ref().GetTypeAnn()->Cast<TTupleExprType>()->GetItems().back();
+ const auto inputItemType = NCommon::BuildType(wrapper.Input().Ref(), *GetSeqItemType(readType), ctx.ProgramBuilder);
+ const auto outputType = NCommon::BuildType(wrapper.Ref(), *wrapper.Ref().GetTypeAnn(), ctx.ProgramBuilder);
+ const auto limit = read.LimitHint() ?
+ ctx.ProgramBuilder.NewOptional(MkqlBuildExpr(read.LimitHint().Cast().Ref(), ctx)):
+ ctx.ProgramBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
+ const auto& meta = state->Tables[std::make_pair(cluster, read.Table().StringValue())];
+ const auto& config = state->Configuration->Clusters[cluster];
+ if (meta.ReadAsync)
+ return BuildYdbInputCall<true>(
+ outputType,
+ inputItemType,
+ config.Database,
+ config.Endpoint,
+ config.Secure,
+ wrapper.Token().Name().Cast().Value(),
+ read.Table(),
+ meta.Snapshot.GetSnapshotId(),
+ meta.KeyTypes,
+ limit,
+ ctx
+ );
+ else
+ return BuildYdbInputCall<false>(
+ outputType,
+ inputItemType,
+ config.Database,
+ config.Endpoint,
+ config.Secure,
+ wrapper.Token().Name().Cast().Value(),
+ read.Table(),
+ meta.Snapshot.GetSnapshotId(),
+ meta.KeyTypes,
+ limit,
+ ctx
+ );
+ }
+
+ return TRuntimeNode();
+ });
+}
+
+}
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.h b/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.h
index d63450c068..9ea3a2d6c9 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.h
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_mkql_compiler.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "yql_ydb_provider.h"
-
+#pragma once
+
+#include "yql_ydb_provider.h"
+
#include <ydb/library/yql/providers/common/mkql/yql_provider_mkql.h>
-
-namespace NYql {
-
-void RegisterDqYdbMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TYdbState::TPtr& state);
-
-}
+
+namespace NYql {
+
+void RegisterDqYdbMkqlCompilers(NCommon::TMkqlCallableCompilerBase& compiler, const TYdbState::TPtr& state);
+
+}
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_physical_opt.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_physical_opt.cpp
index a887fce8c4..0ca6ab9078 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_physical_opt.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_physical_opt.cpp
@@ -1,5 +1,5 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/dq/expr_nodes/dq_expr_nodes.h>
#include <ydb/library/yql/providers/ydb/expr_nodes/yql_ydb_expr_nodes.h>
#include <ydb/library/yql/providers/dq/expr_nodes/dqs_expr_nodes.h>
@@ -9,191 +9,191 @@
#include <ydb/library/yql/providers/common/transform/yql_optimize.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/utils/log/log.h>
-
-
-namespace NYql {
-
-using namespace NNodes;
-
-namespace {
-
-ui8 GetTypeWeight(const TTypeAnnotationNode& type) {
- switch (type.GetKind()) {
- case ETypeAnnotationKind::Data:
- switch (type.Cast<TDataExprType>()->GetSlot()) {
- case NUdf::EDataSlot::Bool:
- case NUdf::EDataSlot::Int8:
- case NUdf::EDataSlot::Uint8: return 1;
-
- case NUdf::EDataSlot::Int16:
- case NUdf::EDataSlot::Uint16:
- case NUdf::EDataSlot::Date: return 2;
-
- case NUdf::EDataSlot::TzDate: return 3;
-
- case NUdf::EDataSlot::Int32:
- case NUdf::EDataSlot::Uint32:
- case NUdf::EDataSlot::Float:
- case NUdf::EDataSlot::Datetime: return 4;
-
- case NUdf::EDataSlot::TzDatetime: return 5;
-
- case NUdf::EDataSlot::Int64:
- case NUdf::EDataSlot::Uint64:
- case NUdf::EDataSlot::Double:
- case NUdf::EDataSlot::Timestamp:
- case NUdf::EDataSlot::Interval: return 8;
-
- case NUdf::EDataSlot::TzTimestamp: return 9;
-
- case NUdf::EDataSlot::Decimal: return 15;
- case NUdf::EDataSlot::Uuid: return 16;
-
- default: return 32;
- }
- case ETypeAnnotationKind::Optional: return 1 + GetTypeWeight(*type.Cast<TOptionalExprType>()->GetItemType());
- default: return 255;
- }
-}
-
-const TItemExprType* GetLightColumn(const TStructExprType& type) {
- ui8 weight = 255;
- const TItemExprType* field = nullptr;
- for (const auto& item : type.GetItems()) {
-
- if (const auto w = GetTypeWeight(*item->GetItemType()); w < weight) {
- weight = w;
- field = item;
- }
- }
- return field;
-}
-
-class TYdbPhysicalOptProposalTransformer : public TOptimizeTransformerBase {
-public:
- TYdbPhysicalOptProposalTransformer(TYdbState::TPtr state)
- : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
- , State_(state)
- {
-#define HNDL(name) "PhysicalOptimizer-"#name, Hndl(&TYdbPhysicalOptProposalTransformer::name)
- AddHandler(0, &TCoTake::Match, HNDL(Take));
- AddHandler(0, &TCoNarrowMap::Match, HNDL(ReadZeroColumns));
- AddHandler(0, &TDqStage::Match, HNDL(SourceZeroColumns));
-#undef HNDL
- }
-
- TMaybeNode<TExprBase> Take(TExprBase node, TExprContext& ctx) const {
- const auto& take = node.Cast<TCoTake>();
- const auto& wrap = take.Input().Maybe<TDqReadWrap>();
- if (!wrap) {
- return node;
- }
-
- const auto& dqrw = wrap.Cast();
- const auto& read = dqrw.Input().Maybe<TYdbReadTable>();
- if (!read) {
- return node;
- }
-
- const auto& cast = read.Cast();
- if (cast.LimitHint()) {
- return node;
- }
-
- return Build<TCoTake>(ctx, take.Pos())
- .Input<TDqReadWrap>()
- .InitFrom(dqrw)
- .Input<TYdbReadTable>()
- .InitFrom(cast)
- .LimitHint(take.Count())
- .Build()
- .Build()
- .Count(take.Count())
- .Done();
- }
-
- TMaybeNode<TExprBase> ReadZeroColumns(TExprBase node, TExprContext& ctx) const {
- const auto& narrow = node.Maybe<TCoNarrowMap>();
- if (const auto& wide = narrow.Cast().Input().Maybe<TDqReadWideWrap>()) {
- if (const auto& maybe = wide.Cast().Input().Maybe<TYdbReadTable>()) {
- if (!wide.Cast().Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>()->GetSize()) {
- const auto& read = maybe.Cast();
- const auto structType = State_->Tables[std::make_pair(read.DataSource().Cluster().StringValue(), read.Table().StringValue())].ItemType;
- auto columns = ctx.NewList(read.Pos(), {ctx.NewAtom(read.Pos(), GetLightColumn(*structType)->GetName())});
- return Build<TCoNarrowMap>(ctx, narrow.Cast().Pos())
- .Input<TDqReadWideWrap>()
- .InitFrom(wide.Cast())
- .Input<TYdbReadTable>()
- .InitFrom(read)
- .Columns(std::move(columns))
- .Build()
- .Build()
- .Lambda()
- .Args({"stub"})
- .Body<TCoAsStruct>().Build()
- .Build()
- .Done();
- }
- }
- }
-
- return node;
- }
-
- TMaybeNode<TExprBase> SourceZeroColumns(TExprBase node, TExprContext& ctx) const {
- if (const auto& stage = node.Cast<TDqStage>(); stage.Inputs().Size() == 1U) {
- if (const auto& maySource = stage.Inputs().Item(0).Maybe<TDqSource>()) {
- if (const auto& source = maySource.Cast(); const auto& settings = source.Settings().Maybe<TYdbSourceSettings>()) {
- if (const auto& cast = settings.Cast(); cast.Columns().Empty()) {
- const auto& prog = stage.Program();
- const auto narrow = FindNode(prog.Ptr(), [arg = prog.Args().Arg(0).Raw()] (const TExprNode::TPtr& node) {
- return node->IsCallable(TCoNarrowMap::CallableName()) && node->Head().IsCallable(TDqSourceWideWrap::CallableName()) && arg == &node->Head().Head();
- });
-
- const auto lightField = GetLightColumn(*State_->Tables[std::make_pair(source.DataSource().Cast<TYdbDataSource>().Cluster().StringValue(), cast.Table().StringValue())].ItemType);
- auto newNarrow = Build<TCoNarrowMap>(ctx, narrow->Pos())
- .Input<TDqSourceWideWrap>()
- .Input(prog.Args().Arg(0))
- .DataSource(source.DataSource().Cast<TCoDataSource>())
- .RowType(ExpandType(narrow->Pos(), *ctx.MakeType<TStructExprType>(TVector<const TItemExprType*>{lightField}), ctx))
- .Build()
- .Lambda()
- .Args({"stub"})
- .Body<TCoAsStruct>().Build()
- .Build()
- .Done()
- .Ptr();
-
- return Build<TDqStage>(ctx, stage.Pos())
- .Inputs()
- .Add<TDqSource>()
- .DataSource(source.DataSource())
- .Settings<TYdbSourceSettings>()
- .InitFrom(cast)
- .Columns().Add().Build(lightField->GetName()).Build()
- .Build()
- .Build()
- .Build()
- .Program(ctx.DeepCopyLambda(prog.Ref(), ctx.ReplaceNode(prog.Body().Ptr(), *narrow, std::move(newNarrow))))
- .Settings(stage.Settings())
- .Done();
-
- }
- }
- }
- }
-
- return node;
- }
-private:
- const TYdbState::TPtr State_;
-};
-
-}
-
-THolder<IGraphTransformer> CreateYdbPhysicalOptProposalTransformer(TYdbState::TPtr state) {
- return MakeHolder<TYdbPhysicalOptProposalTransformer>(state);
-}
-
-} // namespace NYql
-
+
+
+namespace NYql {
+
+using namespace NNodes;
+
+namespace {
+
+ui8 GetTypeWeight(const TTypeAnnotationNode& type) {
+ switch (type.GetKind()) {
+ case ETypeAnnotationKind::Data:
+ switch (type.Cast<TDataExprType>()->GetSlot()) {
+ case NUdf::EDataSlot::Bool:
+ case NUdf::EDataSlot::Int8:
+ case NUdf::EDataSlot::Uint8: return 1;
+
+ case NUdf::EDataSlot::Int16:
+ case NUdf::EDataSlot::Uint16:
+ case NUdf::EDataSlot::Date: return 2;
+
+ case NUdf::EDataSlot::TzDate: return 3;
+
+ case NUdf::EDataSlot::Int32:
+ case NUdf::EDataSlot::Uint32:
+ case NUdf::EDataSlot::Float:
+ case NUdf::EDataSlot::Datetime: return 4;
+
+ case NUdf::EDataSlot::TzDatetime: return 5;
+
+ case NUdf::EDataSlot::Int64:
+ case NUdf::EDataSlot::Uint64:
+ case NUdf::EDataSlot::Double:
+ case NUdf::EDataSlot::Timestamp:
+ case NUdf::EDataSlot::Interval: return 8;
+
+ case NUdf::EDataSlot::TzTimestamp: return 9;
+
+ case NUdf::EDataSlot::Decimal: return 15;
+ case NUdf::EDataSlot::Uuid: return 16;
+
+ default: return 32;
+ }
+ case ETypeAnnotationKind::Optional: return 1 + GetTypeWeight(*type.Cast<TOptionalExprType>()->GetItemType());
+ default: return 255;
+ }
+}
+
+const TItemExprType* GetLightColumn(const TStructExprType& type) {
+ ui8 weight = 255;
+ const TItemExprType* field = nullptr;
+ for (const auto& item : type.GetItems()) {
+
+ if (const auto w = GetTypeWeight(*item->GetItemType()); w < weight) {
+ weight = w;
+ field = item;
+ }
+ }
+ return field;
+}
+
+class TYdbPhysicalOptProposalTransformer : public TOptimizeTransformerBase {
+public:
+ TYdbPhysicalOptProposalTransformer(TYdbState::TPtr state)
+ : TOptimizeTransformerBase(state->Types, NLog::EComponent::ProviderYdb, {})
+ , State_(state)
+ {
+#define HNDL(name) "PhysicalOptimizer-"#name, Hndl(&TYdbPhysicalOptProposalTransformer::name)
+ AddHandler(0, &TCoTake::Match, HNDL(Take));
+ AddHandler(0, &TCoNarrowMap::Match, HNDL(ReadZeroColumns));
+ AddHandler(0, &TDqStage::Match, HNDL(SourceZeroColumns));
+#undef HNDL
+ }
+
+ TMaybeNode<TExprBase> Take(TExprBase node, TExprContext& ctx) const {
+ const auto& take = node.Cast<TCoTake>();
+ const auto& wrap = take.Input().Maybe<TDqReadWrap>();
+ if (!wrap) {
+ return node;
+ }
+
+ const auto& dqrw = wrap.Cast();
+ const auto& read = dqrw.Input().Maybe<TYdbReadTable>();
+ if (!read) {
+ return node;
+ }
+
+ const auto& cast = read.Cast();
+ if (cast.LimitHint()) {
+ return node;
+ }
+
+ return Build<TCoTake>(ctx, take.Pos())
+ .Input<TDqReadWrap>()
+ .InitFrom(dqrw)
+ .Input<TYdbReadTable>()
+ .InitFrom(cast)
+ .LimitHint(take.Count())
+ .Build()
+ .Build()
+ .Count(take.Count())
+ .Done();
+ }
+
+ TMaybeNode<TExprBase> ReadZeroColumns(TExprBase node, TExprContext& ctx) const {
+ const auto& narrow = node.Maybe<TCoNarrowMap>();
+ if (const auto& wide = narrow.Cast().Input().Maybe<TDqReadWideWrap>()) {
+ if (const auto& maybe = wide.Cast().Input().Maybe<TYdbReadTable>()) {
+ if (!wide.Cast().Ref().GetTypeAnn()->Cast<TFlowExprType>()->GetItemType()->Cast<TMultiExprType>()->GetSize()) {
+ const auto& read = maybe.Cast();
+ const auto structType = State_->Tables[std::make_pair(read.DataSource().Cluster().StringValue(), read.Table().StringValue())].ItemType;
+ auto columns = ctx.NewList(read.Pos(), {ctx.NewAtom(read.Pos(), GetLightColumn(*structType)->GetName())});
+ return Build<TCoNarrowMap>(ctx, narrow.Cast().Pos())
+ .Input<TDqReadWideWrap>()
+ .InitFrom(wide.Cast())
+ .Input<TYdbReadTable>()
+ .InitFrom(read)
+ .Columns(std::move(columns))
+ .Build()
+ .Build()
+ .Lambda()
+ .Args({"stub"})
+ .Body<TCoAsStruct>().Build()
+ .Build()
+ .Done();
+ }
+ }
+ }
+
+ return node;
+ }
+
+ TMaybeNode<TExprBase> SourceZeroColumns(TExprBase node, TExprContext& ctx) const {
+ if (const auto& stage = node.Cast<TDqStage>(); stage.Inputs().Size() == 1U) {
+ if (const auto& maySource = stage.Inputs().Item(0).Maybe<TDqSource>()) {
+ if (const auto& source = maySource.Cast(); const auto& settings = source.Settings().Maybe<TYdbSourceSettings>()) {
+ if (const auto& cast = settings.Cast(); cast.Columns().Empty()) {
+ const auto& prog = stage.Program();
+ const auto narrow = FindNode(prog.Ptr(), [arg = prog.Args().Arg(0).Raw()] (const TExprNode::TPtr& node) {
+ return node->IsCallable(TCoNarrowMap::CallableName()) && node->Head().IsCallable(TDqSourceWideWrap::CallableName()) && arg == &node->Head().Head();
+ });
+
+ const auto lightField = GetLightColumn(*State_->Tables[std::make_pair(source.DataSource().Cast<TYdbDataSource>().Cluster().StringValue(), cast.Table().StringValue())].ItemType);
+ auto newNarrow = Build<TCoNarrowMap>(ctx, narrow->Pos())
+ .Input<TDqSourceWideWrap>()
+ .Input(prog.Args().Arg(0))
+ .DataSource(source.DataSource().Cast<TCoDataSource>())
+ .RowType(ExpandType(narrow->Pos(), *ctx.MakeType<TStructExprType>(TVector<const TItemExprType*>{lightField}), ctx))
+ .Build()
+ .Lambda()
+ .Args({"stub"})
+ .Body<TCoAsStruct>().Build()
+ .Build()
+ .Done()
+ .Ptr();
+
+ return Build<TDqStage>(ctx, stage.Pos())
+ .Inputs()
+ .Add<TDqSource>()
+ .DataSource(source.DataSource())
+ .Settings<TYdbSourceSettings>()
+ .InitFrom(cast)
+ .Columns().Add().Build(lightField->GetName()).Build()
+ .Build()
+ .Build()
+ .Build()
+ .Program(ctx.DeepCopyLambda(prog.Ref(), ctx.ReplaceNode(prog.Body().Ptr(), *narrow, std::move(newNarrow))))
+ .Settings(stage.Settings())
+ .Done();
+
+ }
+ }
+ }
+ }
+
+ return node;
+ }
+private:
+ const TYdbState::TPtr State_;
+};
+
+}
+
+THolder<IGraphTransformer> CreateYdbPhysicalOptProposalTransformer(TYdbState::TPtr state) {
+ return MakeHolder<TYdbPhysicalOptProposalTransformer>(state);
+}
+
+} // namespace NYql
+
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.cpp
index f210785399..d17e353d3e 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.cpp
@@ -1,48 +1,48 @@
-#include "yql_ydb_provider.h"
+#include "yql_ydb_provider.h"
#include <ydb/library/yql/providers/common/proto/gateways_config.pb.h>
#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
-
-namespace NYql {
-
+
+namespace NYql {
+
TDataProviderInitializer GetYdbDataProviderInitializer(
NYdb::TDriver driver,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory,
std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolverWithMeta) {
return [driver, credentialsFactory, dbResolverWithMeta] (
- const TString& userName,
- const TString& sessionId,
- const TGatewaysConfig* gatewaysConfig,
- const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
- TIntrusivePtr<IRandomProvider> randomProvider,
- TIntrusivePtr<TTypeAnnotationContext> typeCtx,
- const TOperationProgressWriter& progressWriter,
- const TYqlOperationOptions& operationOptions)
- {
- Y_UNUSED(sessionId);
- Y_UNUSED(userName);
- Y_UNUSED(functionRegistry);
- Y_UNUSED(randomProvider);
- Y_UNUSED(progressWriter);
- Y_UNUSED(operationOptions);
-
- auto state = MakeIntrusive<TYdbState>();
-
- state->Types = typeCtx.Get();
- state->FunctionRegistry = functionRegistry;
+ const TString& userName,
+ const TString& sessionId,
+ const TGatewaysConfig* gatewaysConfig,
+ const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
+ TIntrusivePtr<IRandomProvider> randomProvider,
+ TIntrusivePtr<TTypeAnnotationContext> typeCtx,
+ const TOperationProgressWriter& progressWriter,
+ const TYqlOperationOptions& operationOptions)
+ {
+ Y_UNUSED(sessionId);
+ Y_UNUSED(userName);
+ Y_UNUSED(functionRegistry);
+ Y_UNUSED(randomProvider);
+ Y_UNUSED(progressWriter);
+ Y_UNUSED(operationOptions);
+
+ auto state = MakeIntrusive<TYdbState>();
+
+ state->Types = typeCtx.Get();
+ state->FunctionRegistry = functionRegistry;
state->CredentialsFactory = credentialsFactory;
state->DbResolver = dbResolverWithMeta;
- if (gatewaysConfig) {
+ if (gatewaysConfig) {
state->Configuration->Init(gatewaysConfig->GetYdb(), typeCtx, state->DbResolver, state->DatabaseIds);
- }
-
- TDataProviderInfo info;
-
- info.Names.insert({TString{YdbProviderName}});
- info.Source = CreateYdbDataSource(state, driver);
- info.Sink = CreateYdbDataSink(state);
-
- return info;
- };
-}
-
-} // namespace NYql
+ }
+
+ TDataProviderInfo info;
+
+ info.Names.insert({TString{YdbProviderName}});
+ info.Source = CreateYdbDataSource(state, driver);
+ info.Sink = CreateYdbDataSink(state);
+
+ return info;
+ };
+}
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.h b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.h
index b22b54c996..ac9d00d145 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.h
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider.h
@@ -1,53 +1,53 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/core/yql_data_provider.h>
-#include "yql_ydb_settings.h"
-
+#include "yql_ydb_settings.h"
+
#include <ydb/library/yql/providers/common/token_accessor/client/factory.h>
#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
#include <ydb/public/lib/experimental/ydb_clickhouse_internal.h>
#include <ydb/core/yq/libs/db_resolver/db_async_resolver_with_meta.h>
-
-namespace NKikimr::NMiniKQL {
- class IFunctionRegistry;
-}
-
-namespace NYql {
-
-struct TYdbState : public TThrRefBase
-{
- using TPtr = TIntrusivePtr<TYdbState>;
-
- struct TTableMeta {
- const TStructExprType* ItemType = nullptr;
- std::vector<NUdf::TDataTypeId> KeyTypes;
- TVector<TString> ColumnOrder;
- NYdb::NClickhouseInternal::TSnapshotHandle Snapshot;
- std::vector<std::array<TString, 2U>> Partitions;
- bool ReadAsync = false;
- };
-
- std::unordered_map<std::pair<TString, TString>, TTableMeta, THash<std::pair<TString, TString>>> Tables;
-
- TTypeAnnotationContext* Types = nullptr;
- TYdbConfiguration::TPtr Configuration = MakeIntrusive<TYdbConfiguration>();
- const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry = nullptr;
+
+namespace NKikimr::NMiniKQL {
+ class IFunctionRegistry;
+}
+
+namespace NYql {
+
+struct TYdbState : public TThrRefBase
+{
+ using TPtr = TIntrusivePtr<TYdbState>;
+
+ struct TTableMeta {
+ const TStructExprType* ItemType = nullptr;
+ std::vector<NUdf::TDataTypeId> KeyTypes;
+ TVector<TString> ColumnOrder;
+ NYdb::NClickhouseInternal::TSnapshotHandle Snapshot;
+ std::vector<std::array<TString, 2U>> Partitions;
+ bool ReadAsync = false;
+ };
+
+ std::unordered_map<std::pair<TString, TString>, TTableMeta, THash<std::pair<TString, TString>>> Tables;
+
+ TTypeAnnotationContext* Types = nullptr;
+ TYdbConfiguration::TPtr Configuration = MakeIntrusive<TYdbConfiguration>();
+ const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry = nullptr;
ISecuredServiceAccountCredentialsFactory::TPtr CredentialsFactory;
THashMap<std::pair<TString, NYq::DatabaseType>, NYq::TEvents::TDatabaseAuth> DatabaseIds;
std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> DbResolver;
-};
-
+};
+
TDataProviderInitializer GetYdbDataProviderInitializer(
NYdb::TDriver driver,
ISecuredServiceAccountCredentialsFactory::TPtr credentialsFactory = nullptr,
const std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolverWithMeta = nullptr
);
-
+
TIntrusivePtr<IDataProvider> CreateYdbDataSource(
TYdbState::TPtr state,
NYdb::TDriver driver
);
-TIntrusivePtr<IDataProvider> CreateYdbDataSink(TYdbState::TPtr state);
-
-} // namespace NYql
+TIntrusivePtr<IDataProvider> CreateYdbDataSink(TYdbState::TPtr state);
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.cpp
index fe94a1ed28..80a9e5c14d 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.cpp
@@ -1,137 +1,137 @@
-#include "yql_ydb_provider_impl.h"
-
+#include "yql_ydb_provider_impl.h"
+
#include <ydb/library/yql/providers/common/schema/expr/yql_expr_schema.h>
-
-namespace NYql {
-
-bool TYdbKey::Extract(const TExprNode& key, TExprContext& ctx) {
- if (key.IsCallable("MrTableConcat")) {
- ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "CONCAT is not supported on Ydb clusters."));
- return false;
- }
-
- if (!key.IsCallable("Key")) {
- ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "Expected key"));
- return false;
- }
-
- if (const auto& tagName = key.Head().Head().Content(); tagName == "table") {
- KeyType = Type::Table;
- const auto nameNode = key.Head().Child(1);
- if (nameNode->IsCallable({"MrTableRange", "MrTableRangeStrict"})) {
- ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "RANGE is not supported on Ydb clusters."));
- return false;
- }
-
- if (!nameNode->IsCallable("String")) {
- ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "Expected String as table key."));
- return false;
- }
-
+
+namespace NYql {
+
+bool TYdbKey::Extract(const TExprNode& key, TExprContext& ctx) {
+ if (key.IsCallable("MrTableConcat")) {
+ ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "CONCAT is not supported on Ydb clusters."));
+ return false;
+ }
+
+ if (!key.IsCallable("Key")) {
+ ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "Expected key"));
+ return false;
+ }
+
+ if (const auto& tagName = key.Head().Head().Content(); tagName == "table") {
+ KeyType = Type::Table;
+ const auto nameNode = key.Head().Child(1);
+ if (nameNode->IsCallable({"MrTableRange", "MrTableRangeStrict"})) {
+ ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "RANGE is not supported on Ydb clusters."));
+ return false;
+ }
+
+ if (!nameNode->IsCallable("String")) {
+ ctx.AddError(TIssue(ctx.GetPosition(key.Pos()), "Expected String as table key."));
+ return false;
+ }
+
Target = nameNode->Head().Content();
- } else if (tagName == "tablescheme") {
- KeyType = Type::TableScheme;
+ } else if (tagName == "tablescheme") {
+ KeyType = Type::TableScheme;
Target = key.Head().Child(1)->Head().Content();
- } else if (tagName == "tablelist") {
- KeyType = Type::TableList;
+ } else if (tagName == "tablelist") {
+ KeyType = Type::TableList;
Target = key.Head().Child(1)->Head().Content();
} else if (tagName == "role") {
KeyType = Type::Role;
Target = key.Head().Child(1)->Head().Content();
- } else {
+ } else {
ctx.AddError(TIssue(ctx.GetPosition(key.Head().Pos()), TString("Unexpected tag for YDB key: ") += tagName));
- return false;
- }
-
- if (key.ChildrenSize() > 1) {
- for (ui32 i = 1; i < key.ChildrenSize(); ++i) {
- if (const auto& tag = key.Child(i)->Head(); tag.Content() == "view") {
- const auto viewNode = key.Child(i)->Child(1);
- if (!viewNode->IsCallable("String")) {
- ctx.AddError(TIssue(ctx.GetPosition(viewNode->Pos()), "Expected String"));
- return false;
- }
-
- if (viewNode->ChildrenSize() != 1 || !EnsureAtom(viewNode->Head(), ctx)) {
- ctx.AddError(TIssue(ctx.GetPosition(viewNode->Head().Pos()), "Dynamic views names are not supported"));
- return false;
- }
- if (viewNode->Head().Content().empty()) {
- ctx.AddError(TIssue(ctx.GetPosition(viewNode->Head().Pos()), "Secondary index name must not be empty"));
- return false;
- }
- View = viewNode->Head().Content();
-
- } else {
+ return false;
+ }
+
+ if (key.ChildrenSize() > 1) {
+ for (ui32 i = 1; i < key.ChildrenSize(); ++i) {
+ if (const auto& tag = key.Child(i)->Head(); tag.Content() == "view") {
+ const auto viewNode = key.Child(i)->Child(1);
+ if (!viewNode->IsCallable("String")) {
+ ctx.AddError(TIssue(ctx.GetPosition(viewNode->Pos()), "Expected String"));
+ return false;
+ }
+
+ if (viewNode->ChildrenSize() != 1 || !EnsureAtom(viewNode->Head(), ctx)) {
+ ctx.AddError(TIssue(ctx.GetPosition(viewNode->Head().Pos()), "Dynamic views names are not supported"));
+ return false;
+ }
+ if (viewNode->Head().Content().empty()) {
+ ctx.AddError(TIssue(ctx.GetPosition(viewNode->Head().Pos()), "Secondary index name must not be empty"));
+ return false;
+ }
+ View = viewNode->Head().Content();
+
+ } else {
ctx.AddError(TIssue(ctx.GetPosition(tag.Pos()), TString("Unexpected tag for YDB key child: ") += tag.Content()));
- return false;
- }
- }
- }
- return true;
-}
-
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
void MetaToYson(const TString& cluster, const TString& table, TYdbState::TPtr state, NYson::TYsonWriter& writer) {
- const auto& meta = state->Tables[std::make_pair(cluster, table)];
- writer.OnBeginMap();
- writer.OnKeyedItem("Data");
-
- writer.OnBeginMap();
- writer.OnKeyedItem(TStringBuf("Cluster"));
- writer.OnStringScalar(cluster);
- writer.OnKeyedItem(TStringBuf("Name"));
- writer.OnStringScalar(table);
-
-
- writer.OnKeyedItem(TStringBuf("DoesExist"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("IsSorted"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("IsDynamic"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("UniqueKeys"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("CanWrite"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("IsRealData"));
- writer.OnBooleanScalar(true);
- writer.OnKeyedItem(TStringBuf("YqlCompatibleSchema"));
- writer.OnBooleanScalar(true);
-
- writer.OnKeyedItem("Fields");
- writer.OnBeginList();
- {
- for (auto& item: meta.ItemType->GetItems()) {
- writer.OnListItem();
-
- auto name = item->GetName();
- writer.OnBeginMap();
-
- writer.OnKeyedItem("Name");
- writer.OnStringScalar(name);
-
- writer.OnKeyedItem("Type");
- NCommon::WriteTypeToYson(writer, item->GetItemType());
-
- writer.OnKeyedItem("ClusterSortOrder");
- writer.OnBeginList();
- writer.OnEndList();
-
- writer.OnKeyedItem("Ascending");
- writer.OnBeginList();
-
- writer.OnEndList();
-
- writer.OnEndMap();
- }
- }
- writer.OnEndList();
-
- writer.OnKeyedItem("RowType");
- NCommon::WriteTypeToYson(writer, meta.ItemType);
-
- writer.OnEndMap();
- writer.OnEndMap();
-}
-
-}
+ const auto& meta = state->Tables[std::make_pair(cluster, table)];
+ writer.OnBeginMap();
+ writer.OnKeyedItem("Data");
+
+ writer.OnBeginMap();
+ writer.OnKeyedItem(TStringBuf("Cluster"));
+ writer.OnStringScalar(cluster);
+ writer.OnKeyedItem(TStringBuf("Name"));
+ writer.OnStringScalar(table);
+
+
+ writer.OnKeyedItem(TStringBuf("DoesExist"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("IsSorted"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("IsDynamic"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("UniqueKeys"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("CanWrite"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("IsRealData"));
+ writer.OnBooleanScalar(true);
+ writer.OnKeyedItem(TStringBuf("YqlCompatibleSchema"));
+ writer.OnBooleanScalar(true);
+
+ writer.OnKeyedItem("Fields");
+ writer.OnBeginList();
+ {
+ for (auto& item: meta.ItemType->GetItems()) {
+ writer.OnListItem();
+
+ auto name = item->GetName();
+ writer.OnBeginMap();
+
+ writer.OnKeyedItem("Name");
+ writer.OnStringScalar(name);
+
+ writer.OnKeyedItem("Type");
+ NCommon::WriteTypeToYson(writer, item->GetItemType());
+
+ writer.OnKeyedItem("ClusterSortOrder");
+ writer.OnBeginList();
+ writer.OnEndList();
+
+ writer.OnKeyedItem("Ascending");
+ writer.OnBeginList();
+
+ writer.OnEndList();
+
+ writer.OnEndMap();
+ }
+ }
+ writer.OnEndList();
+
+ writer.OnKeyedItem("RowType");
+ NCommon::WriteTypeToYson(writer, meta.ItemType);
+
+ writer.OnEndMap();
+ writer.OnEndMap();
+}
+
+}
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.h b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.h
index 7d32026b28..454c019d58 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.h
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_provider_impl.h
@@ -1,67 +1,67 @@
-#pragma once
-
-#include "yql_ydb_provider.h"
-
+#pragma once
+
+#include "yql_ydb_provider.h"
+
#include <ydb/library/yql/core/yql_graph_transformer.h>
#include <ydb/library/yql/providers/common/transform/yql_exec.h>
#include <ydb/library/yql/providers/common/transform/yql_visit.h>
-
+
#include <ydb/public/sdk/cpp/client/ydb_table/table.h>
-
-#include <util/generic/ptr.h>
-
-namespace NYql {
-
+
+#include <util/generic/ptr.h>
+
+namespace NYql {
+
THolder<IGraphTransformer> CreateYdbIODiscoveryTransformer(TYdbState::TPtr state);
-THolder<IGraphTransformer> CreateYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver);
-
-THolder<TVisitorTransformerBase> CreateYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state);
-THolder<TVisitorTransformerBase> CreateYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state);
-
-THolder<TExecTransformerBase> CreateYdbDataSinkExecTransformer(TYdbState::TPtr state);
-
-THolder<IGraphTransformer> CreateYdbLogicalOptProposalTransformer(TYdbState::TPtr state);
-THolder<IGraphTransformer> CreateYdbPhysicalOptProposalTransformer(TYdbState::TPtr state);
-THolder<IGraphTransformer> CreateYdbSourceCallableExecutionTransformer(TYdbState::TPtr state);
-
+THolder<IGraphTransformer> CreateYdbLoadTableMetadataTransformer(TYdbState::TPtr state, NYdb::TDriver driver);
+
+THolder<TVisitorTransformerBase> CreateYdbDataSourceTypeAnnotationTransformer(TYdbState::TPtr state);
+THolder<TVisitorTransformerBase> CreateYdbDataSinkTypeAnnotationTransformer(TYdbState::TPtr state);
+
+THolder<TExecTransformerBase> CreateYdbDataSinkExecTransformer(TYdbState::TPtr state);
+
+THolder<IGraphTransformer> CreateYdbLogicalOptProposalTransformer(TYdbState::TPtr state);
+THolder<IGraphTransformer> CreateYdbPhysicalOptProposalTransformer(TYdbState::TPtr state);
+THolder<IGraphTransformer> CreateYdbSourceCallableExecutionTransformer(TYdbState::TPtr state);
+
void MetaToYson(const TString& cluster, const TString& table, TYdbState::TPtr state, NYson::TYsonWriter& writer);
-
-class TYdbKey {
-public:
- enum class Type {
- Table,
- TableList,
+
+class TYdbKey {
+public:
+ enum class Type {
+ Table,
+ TableList,
TableScheme,
Role
- };
-
-public:
- TYdbKey() = default;
-
- Type GetKeyType() const {
- return *KeyType;
- }
-
- std::string_view GetTablePath() const {
- Y_VERIFY_DEBUG(KeyType == Type::Table || KeyType == Type::TableScheme);
+ };
+
+public:
+ TYdbKey() = default;
+
+ Type GetKeyType() const {
+ return *KeyType;
+ }
+
+ std::string_view GetTablePath() const {
+ Y_VERIFY_DEBUG(KeyType == Type::Table || KeyType == Type::TableScheme);
return Target;
- }
-
- std::string_view GetFolderPath() const {
- Y_VERIFY_DEBUG(KeyType == Type::TableList);
+ }
+
+ std::string_view GetFolderPath() const {
+ Y_VERIFY_DEBUG(KeyType == Type::TableList);
return Target;
- }
-
- const std::optional<std::string_view>& GetView() const {
- return View;
- }
-
- bool Extract(const TExprNode& key, TExprContext& ctx);
-
-private:
- std::optional<Type> KeyType;
+ }
+
+ const std::optional<std::string_view>& GetView() const {
+ return View;
+ }
+
+ bool Extract(const TExprNode& key, TExprContext& ctx);
+
+private:
+ std::optional<Type> KeyType;
std::string_view Target;
- std::optional<std::string_view> View;
-};
-
-} // namespace NYql
+ std::optional<std::string_view> View;
+};
+
+} // namespace NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.cpp b/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.cpp
index 53a8e937c7..06d1919027 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.cpp
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.cpp
@@ -1,41 +1,41 @@
-#include "yql_ydb_settings.h"
+#include "yql_ydb_settings.h"
#include <ydb/library/yql/providers/common/structured_token/yql_token_builder.h>
-
-namespace NYql {
-
-using namespace NCommon;
-
-TYdbConfiguration::TYdbConfiguration()
-{
-}
-
-TYdbSettings::TConstPtr TYdbConfiguration::Snapshot() const {
+
+namespace NYql {
+
+using namespace NCommon;
+
+TYdbConfiguration::TYdbConfiguration()
+{
+}
+
+TYdbSettings::TConstPtr TYdbConfiguration::Snapshot() const {
return std::make_shared<const TYdbSettings>(*this);
-}
-
-bool TYdbConfiguration::HasCluster(TStringBuf cluster) const {
- return ValidClusters.contains(cluster);
-}
-
+}
+
+bool TYdbConfiguration::HasCluster(TStringBuf cluster) const {
+ return ValidClusters.contains(cluster);
+}
+
void TYdbConfiguration::Init(
const TYdbGatewayConfig& config,
TIntrusivePtr<TTypeAnnotationContext> typeCtx,
const std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolver,
THashMap<std::pair<TString, NYq::DatabaseType>, NYq::TEvents::TDatabaseAuth>& databaseIds)
-{
- TVector<TString> clusters(Reserve(config.ClusterMappingSize()));
- for (auto& cluster: config.GetClusterMapping()) {
- clusters.push_back(cluster.GetName());
- }
-
- this->SetValidClusters(clusters);
-
- this->Dispatch(config.GetDefaultSettings());
-
- const auto& endpoint = config.GetDefaultEndpoint();
-
+{
+ TVector<TString> clusters(Reserve(config.ClusterMappingSize()));
+ for (auto& cluster: config.GetClusterMapping()) {
+ clusters.push_back(cluster.GetName());
+ }
+
+ this->SetValidClusters(clusters);
+
+ this->Dispatch(config.GetDefaultSettings());
+
+ const auto& endpoint = config.GetDefaultEndpoint();
+
for (const auto& cluster : config.GetClusterMapping()) {
- this->Dispatch(cluster.GetName(), cluster.GetSettings());
+ this->Dispatch(cluster.GetName(), cluster.GetSettings());
if (dbResolver) {
dbResolver->TryAddDbIdToResolve(cluster.HasEndpoint(), cluster.GetName(), cluster.GetId(), NYq::DatabaseType::Ydb, databaseIds);
@@ -44,22 +44,22 @@ void TYdbConfiguration::Init(
}
}
- auto& settings = Clusters[cluster.GetName()];
- settings.Endpoint = cluster.HasEndpoint() ? cluster.GetEndpoint() : endpoint;
- settings.Database = cluster.GetDatabase().empty() ? cluster.GetName() : cluster.GetDatabase();
+ auto& settings = Clusters[cluster.GetName()];
+ settings.Endpoint = cluster.HasEndpoint() ? cluster.GetEndpoint() : endpoint;
+ settings.Database = cluster.GetDatabase().empty() ? cluster.GetName() : cluster.GetDatabase();
if (cluster.GetId())
settings.DatabaseId = cluster.GetId();
- if (cluster.HasSecure())
- settings.Secure = cluster.GetSecure();
+ if (cluster.HasSecure())
+ settings.Secure = cluster.GetSecure();
if (cluster.HasAddBearerToToken())
settings.AddBearerToToken = cluster.GetAddBearerToToken();
const TString authToken = typeCtx->FindCredentialContent("cluster:default_" + cluster.GetName(), "default_ydb", cluster.GetToken());
Tokens[cluster.GetName()] = ComposeStructuredTokenJsonForServiceAccount(cluster.GetServiceAccountId(), cluster.GetServiceAccountIdSignature(), authToken);
- settings.Raw = cluster;
+ settings.Raw = cluster;
+
+ }
+ this->FreezeDefaults();
+}
- }
- this->FreezeDefaults();
-}
-
-} // NYql
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.h b/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.h
index 010dd4649a..fc6fb03ced 100644
--- a/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.h
+++ b/ydb/library/yql/providers/ydb/provider/yql_ydb_settings.h
@@ -1,50 +1,50 @@
-#pragma once
-
+#pragma once
+
#include <ydb/library/yql/providers/common/config/yql_dispatch.h>
#include <ydb/library/yql/providers/common/config/yql_setting.h>
-
+
#include <ydb/library/yql/providers/common/proto/gateways_config.pb.h>
-
+
#include <ydb/core/yq/libs/events/events.h>
#include <ydb/core/yq/libs/db_resolver/db_async_resolver_with_meta.h>
#include <ydb/core/yq/libs/common/database_token_builder.h>
-namespace NYql {
-
-struct TYdbSettings {
+namespace NYql {
+
+struct TYdbSettings {
using TConstPtr = std::shared_ptr<const TYdbSettings>;
-};
-
-struct TClusterMainSettings {
- TString Endpoint;
- TString Database;
+};
+
+struct TClusterMainSettings {
+ TString Endpoint;
+ TString Database;
TString DatabaseId;
- bool Secure = false;
+ bool Secure = false;
bool AddBearerToToken = false;
-
- TYdbClusterConfig Raw;
-};
-
-struct TYdbConfiguration : public TYdbSettings, public NCommon::TSettingDispatcher {
- using TPtr = TIntrusivePtr<TYdbConfiguration>;
-
- TYdbConfiguration();
- TYdbConfiguration(const TYdbConfiguration&) = delete;
-
+
+ TYdbClusterConfig Raw;
+};
+
+struct TYdbConfiguration : public TYdbSettings, public NCommon::TSettingDispatcher {
+ using TPtr = TIntrusivePtr<TYdbConfiguration>;
+
+ TYdbConfiguration();
+ TYdbConfiguration(const TYdbConfiguration&) = delete;
+
void Init(
const TYdbGatewayConfig& config,
TIntrusivePtr<TTypeAnnotationContext> typeCtx,
const std::shared_ptr<NYq::TDatabaseAsyncResolverWithMeta> dbResolver,
THashMap<std::pair<TString, NYq::DatabaseType>, NYq::TEvents::TDatabaseAuth>& databaseIds
);
-
- bool HasCluster(TStringBuf cluster) const;
-
- TYdbSettings::TConstPtr Snapshot() const;
- THashMap<TString, TString> Tokens;
- std::unordered_map<TString, TClusterMainSettings> Clusters;
+
+ bool HasCluster(TStringBuf cluster) const;
+
+ TYdbSettings::TConstPtr Snapshot() const;
+ THashMap<TString, TString> Tokens;
+ std::unordered_map<TString, TClusterMainSettings> Clusters;
THashMap<TString, TVector<TString>> DbId2Clusters; // DatabaseId -> ClusterNames
-};
-
-} // NYql
+};
+
+} // NYql
diff --git a/ydb/library/yql/providers/ydb/ya.make b/ydb/library/yql/providers/ydb/ya.make
index c563f09aa6..a79e0f4cfc 100644
--- a/ydb/library/yql/providers/ydb/ya.make
+++ b/ydb/library/yql/providers/ydb/ya.make
@@ -1,7 +1,7 @@
-RECURSE(
+RECURSE(
actors
comp_nodes
- expr_nodes
+ expr_nodes
proto
- provider
-)
+ provider
+)
diff --git a/ydb/library/yql/public/decimal/ut/ya.make b/ydb/library/yql/public/decimal/ut/ya.make
index bb6ba658e8..f27b33c3b0 100644
--- a/ydb/library/yql/public/decimal/ut/ya.make
+++ b/ydb/library/yql/public/decimal/ut/ya.make
@@ -1,10 +1,10 @@
UNITTEST_FOR(ydb/library/yql/public/decimal)
-
-OWNER(
- a-romanov
- g:yql
-)
-
-SRCS(yql_decimal_ut.cpp yql_wide_int_ut.cpp)
-
-END()
+
+OWNER(
+ a-romanov
+ g:yql
+)
+
+SRCS(yql_decimal_ut.cpp yql_wide_int_ut.cpp)
+
+END()
diff --git a/ydb/library/yql/public/decimal/ut/yql_decimal_ut.cpp b/ydb/library/yql/public/decimal/ut/yql_decimal_ut.cpp
index c60a750ea5..9c263c2b0b 100644
--- a/ydb/library/yql/public/decimal/ut/yql_decimal_ut.cpp
+++ b/ydb/library/yql/public/decimal/ut/yql_decimal_ut.cpp
@@ -3,14 +3,14 @@
#include <library/cpp/testing/unittest/registar.h>
-namespace NYql {
+namespace NYql {
namespace NDecimal {
-Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
+Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
void SimplePositiveTest(TInt128 v, ui8 precision, ui8 scale, const TString& expected) {
TString result = ToString(v, precision, scale);
UNIT_ASSERT_VALUES_EQUAL(result, expected);
TInt128 parsed = FromString(result, precision, scale);
- UNIT_ASSERT(parsed == v);
+ UNIT_ASSERT(parsed == v);
}
void SimpleNegativeFormatTest(TInt128 v, ui8 precision, ui8 scale) {
@@ -18,42 +18,42 @@ Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
UNIT_ASSERT_VALUES_EQUAL(result, "");
}
- void SimpleSerializeAndDeserialize(TInt128 v, size_t expectedSize) {
- char buff[sizeof(TInt128)];
- const auto s = Serialize(v, buff);
- UNIT_ASSERT_VALUES_EQUAL(s, expectedSize);
- const auto& des = Deserialize(buff);
- UNIT_ASSERT_VALUES_EQUAL(des.second, expectedSize);
- UNIT_ASSERT(des.first == v);
- }
-
- template<ui8 Precision, ui8 Scale>
- void CheckMulAndRescale(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
- const auto l = FromString(lhs, Precision, Scale);
- const auto r = FromString(rhs, Precision, Scale);
- const auto m = MulAndDivNormalDivider(l, r, GetDivider<Scale>());
- const auto result = ToString(m, Precision, Scale);
- UNIT_ASSERT_VALUES_EQUAL(result, expected);
- }
-
- template<ui8 Precision, ui8 Scale>
- void CheckDivAndRescale(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
- const auto l = FromString(lhs, Precision, Scale);
- const auto r = FromString(rhs, Precision, Scale);
- const auto m = MulAndDivNormalMultiplier(l, GetDivider<Scale>(), r);
- const auto result = ToString(m, Precision, Scale);
- UNIT_ASSERT_VALUES_EQUAL(result, expected);
- }
-
- template<ui8 Precision, ui8 Scale = 0>
- void CheckMul(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
- const auto l = FromString(lhs, Precision, Scale);
- const auto r = FromString(rhs, Precision, Scale);
- const auto m = Mul(l, r);
- const auto result = ToString(m, Precision, Scale);
- UNIT_ASSERT_VALUES_EQUAL(result, expected);
- }
-
+ void SimpleSerializeAndDeserialize(TInt128 v, size_t expectedSize) {
+ char buff[sizeof(TInt128)];
+ const auto s = Serialize(v, buff);
+ UNIT_ASSERT_VALUES_EQUAL(s, expectedSize);
+ const auto& des = Deserialize(buff);
+ UNIT_ASSERT_VALUES_EQUAL(des.second, expectedSize);
+ UNIT_ASSERT(des.first == v);
+ }
+
+ template<ui8 Precision, ui8 Scale>
+ void CheckMulAndRescale(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
+ const auto l = FromString(lhs, Precision, Scale);
+ const auto r = FromString(rhs, Precision, Scale);
+ const auto m = MulAndDivNormalDivider(l, r, GetDivider<Scale>());
+ const auto result = ToString(m, Precision, Scale);
+ UNIT_ASSERT_VALUES_EQUAL(result, expected);
+ }
+
+ template<ui8 Precision, ui8 Scale>
+ void CheckDivAndRescale(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
+ const auto l = FromString(lhs, Precision, Scale);
+ const auto r = FromString(rhs, Precision, Scale);
+ const auto m = MulAndDivNormalMultiplier(l, GetDivider<Scale>(), r);
+ const auto result = ToString(m, Precision, Scale);
+ UNIT_ASSERT_VALUES_EQUAL(result, expected);
+ }
+
+ template<ui8 Precision, ui8 Scale = 0>
+ void CheckMul(const TStringBuf& lhs, const TStringBuf& rhs, const TStringBuf& expected) {
+ const auto l = FromString(lhs, Precision, Scale);
+ const auto r = FromString(rhs, Precision, Scale);
+ const auto m = Mul(l, r);
+ const auto result = ToString(m, Precision, Scale);
+ UNIT_ASSERT_VALUES_EQUAL(result, expected);
+ }
+
Y_UNIT_TEST(TestZeroFormat) {
UNIT_ASSERT_VALUES_EQUAL(ToString(0, 1, 0), "0");
UNIT_ASSERT_VALUES_EQUAL(ToString(0, 15, 6), "0");
@@ -90,9 +90,9 @@ Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
SimplePositiveTest(10000000, 15, 6, "10");
SimplePositiveTest(100000000, 15, 6, "100");
- SimplePositiveTest(2020000, 15, 6, "2.02");
- SimplePositiveTest(3003000, 15, 6, "3.003");
-
+ SimplePositiveTest(2020000, 15, 6, "2.02");
+ SimplePositiveTest(3003000, 15, 6, "3.003");
+
// negative numbers
SimplePositiveTest(-1, 15, 6, "-0.000001");
SimplePositiveTest(-10, 15, 6, "-0.00001");
@@ -104,9 +104,9 @@ Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
SimplePositiveTest(-10000000, 15, 6, "-10");
SimplePositiveTest(-100000000, 15, 6, "-100");
- SimplePositiveTest(-2020000, 15, 6, "-2.02");
- SimplePositiveTest(-3003000, 15, 6, "-3.003");
-
+ SimplePositiveTest(-2020000, 15, 6, "-2.02");
+ SimplePositiveTest(-3003000, 15, 6, "-3.003");
+
SimplePositiveTest(1, 15, 6, "0.000001");
SimplePositiveTest(12, 15, 6, "0.000012");
SimplePositiveTest(123, 15, 6, "0.000123");
@@ -123,127 +123,127 @@ Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
Y_UNIT_TEST(TestHugeNumberFormat) {
TInt128 max120 = Inf() - 1;
- const char max120String[] = "99999999999999999999999999999999999"; // 35 digits
+ const char max120String[] = "99999999999999999999999999999999999"; // 35 digits
static_assert(sizeof(max120String) == 36, "sizeof(max120String) == 36");
- SimplePositiveTest(max120, MaxPrecision, 0, max120String);
- SimplePositiveTest(max120 + 1, MaxPrecision, 0, "inf");
+ SimplePositiveTest(max120, MaxPrecision, 0, max120String);
+ SimplePositiveTest(max120 + 1, MaxPrecision, 0, "inf");
- TInt128 min120 = -Inf() + 1;
- const char min120String[] = "-99999999999999999999999999999999999";
+ TInt128 min120 = -Inf() + 1;
+ const char min120String[] = "-99999999999999999999999999999999999";
static_assert(sizeof(min120String) == 37, "sizeof(min120String) == 37");
- SimplePositiveTest(min120, MaxPrecision, 0, min120String);
- SimplePositiveTest(min120 - 1, MaxPrecision, 0, "-inf");
+ SimplePositiveTest(min120, MaxPrecision, 0, min120String);
+ SimplePositiveTest(min120 - 1, MaxPrecision, 0, "-inf");
// take spot for sign and zero before dot
- const char min120StringAfterDot[] = "-0.99999999999999999999999999999999999"; // 35 by nine + leading zero
+ const char min120StringAfterDot[] = "-0.99999999999999999999999999999999999"; // 35 by nine + leading zero
static_assert(sizeof(min120StringAfterDot) == 39, "sizeof(min120StringAfterDot) == 39");
- SimplePositiveTest(min120, MaxPrecision, MaxPrecision, min120StringAfterDot);
+ SimplePositiveTest(min120, MaxPrecision, MaxPrecision, min120StringAfterDot);
- SimpleNegativeFormatTest(1, MaxPrecision + 1, MaxPrecision + 1);
+ SimpleNegativeFormatTest(1, MaxPrecision + 1, MaxPrecision + 1);
SimpleNegativeFormatTest(1, MaxPrecision + 1, 0);
- SimpleNegativeFormatTest(1, 2, 3);
+ SimpleNegativeFormatTest(1, 2, 3);
+ }
+
+ Y_UNIT_TEST(TestFormStringRoundToEven) {
+ UNIT_ASSERT(FromString(".51", 1, 0) == 1);
+ UNIT_ASSERT(FromString("-0.51", 1, 0) == -1);
+
+ UNIT_ASSERT(FromString("+00000008.5", 1, 0) == 8);
+ UNIT_ASSERT(FromString("-8.5000000000000000000000000000000", 1, 0) == -8);
+
+ UNIT_ASSERT(FromString("00008.51", 1, 0) == 9);
+ UNIT_ASSERT(FromString("-8.5000000000000000000000000000001", 1, 0) == -9);
+
+ UNIT_ASSERT(FromString("09.499999999999999999999999999999999999999999999999999999999", 1, 0) == 9);
+ UNIT_ASSERT(FromString("-9.499999999999999999999999999999999999999999999999999999999", 1, 0) == -9);
+
+ UNIT_ASSERT(FromString("9.50", 2, 0) == 10);
+ UNIT_ASSERT(FromString("-9.5", 2, 0) == -10);
+
+ UNIT_ASSERT(FromString("+0.9949", 2, 2) == 99);
+ UNIT_ASSERT(FromString("-0.9949", 2, 2) == -99);
+ }
+
+ Y_UNIT_TEST(TestInfinityValues) {
+ UNIT_ASSERT(FromString("+1", 1, 1) == Inf());
+ UNIT_ASSERT(FromString("-1", 1, 1) == -Inf());
+
+ UNIT_ASSERT(FromString("10.000", 1, 0) == Inf());
+ UNIT_ASSERT(FromString("-10.000", 1, 0) == -Inf());
+
+ UNIT_ASSERT(FromString("9.500", 1, 0) == Inf());
+ UNIT_ASSERT(FromString("-9.500", 1, 0) == -Inf());
+
+ UNIT_ASSERT(FromString("+0.950", 1, 1) == Inf());
+ UNIT_ASSERT(FromString("-0.950", 1, 1) == -Inf());
+
+ UNIT_ASSERT(FromString("+0.9950", 2, 2) == Inf());
+ UNIT_ASSERT(FromString("-0.9950", 2, 2) == -Inf());
+
+ UNIT_ASSERT(FromString("9999999999999999999999999999999999999.5", 35, 0) == Inf());
+ UNIT_ASSERT(FromString("-9999999999999999999999999999999999999.5", 35, 0) == -Inf());
+ }
+
+ Y_UNIT_TEST(TestInvalidValues) {
+ UNIT_ASSERT(IsValid("+999999999999999991234567890.039493804903849038490312345678909999999999999999990"));
+
+ UNIT_ASSERT(!IsValid("")); // empty
+ UNIT_ASSERT(!IsValid("12.2.3")); // double dot
+ UNIT_ASSERT(!IsValid("+-12")); // extra sign
+ UNIT_ASSERT(!IsValid("463786378O74674")); // letter inside
+
+ UNIT_ASSERT(IsError(FromString("", 35, 15))); // empty
+ UNIT_ASSERT(IsError(FromString("12.2.3", 35, 15))); // double dot
+ UNIT_ASSERT(IsError(FromString("+-12", 35, 15))); // extra sign
+ UNIT_ASSERT(IsError(FromString("463786378O74674", 35, 15))); // letter inside
+ UNIT_ASSERT(IsError(FromString("+7.039493804E1", 35, 5))); // letter in tail after scale
+ }
+
+ Y_UNIT_TEST(TestFormStringEx) {
+ UNIT_ASSERT(FromStringEx("NAN", 13, 1) == Nan());
+ UNIT_ASSERT(FromStringEx("+inf", 11, 7) == Inf());
+ UNIT_ASSERT(FromStringEx("-inf", 7, 7) == -Inf());
+
+ UNIT_ASSERT(FromStringEx("0.1E3", 10, 1) == 1000);
+ UNIT_ASSERT(FromStringEx("0.51e-3", 10, 3) == 1);
+
+ UNIT_ASSERT(FromStringEx("1E30", 10, 0) == Inf());
+ UNIT_ASSERT(FromStringEx("1e-30", 10, 0) == 0);
+ UNIT_ASSERT(FromStringEx("-1E+99", 10, 2) == -Inf());
+ UNIT_ASSERT(FromStringEx("-1e-99", 10, 2) == 0);
+ UNIT_ASSERT(FromStringEx("-510e-3", 1, 0) == -1);
+ UNIT_ASSERT(FromStringEx("+99E3", 5, 0) == 99000);
+ }
+
+ Y_UNIT_TEST(TestFormStringExInvalidValues) {
+ UNIT_ASSERT(IsError(FromStringEx("", 35, 15))); // empty
+ UNIT_ASSERT(IsError(FromStringEx("12.2.3", 35, 15))); // double dot
+ UNIT_ASSERT(IsError(FromStringEx("+-12", 35, 15))); // extra sign
+ UNIT_ASSERT(IsError(FromStringEx("463786378O74674", 35, 15))); // letter inside
+
+ UNIT_ASSERT(IsError(FromStringEx("E2", 35, 15))); // empty
+ UNIT_ASSERT(IsError(FromStringEx("E2E4", 35, 15))); // empty
+ UNIT_ASSERT(IsError(FromStringEx("12E0", 35, 15))); // zero isn't avail
+ UNIT_ASSERT(IsError(FromStringEx("NANE5", 35, 15))); // nan with exp
+ }
+
+ Y_UNIT_TEST(TestSpecialAsString) {
+ UNIT_ASSERT(IsValid("+Nan"));
+ UNIT_ASSERT(IsValid("-nAn"));
+ UNIT_ASSERT(IsValid("INF"));
+ UNIT_ASSERT(IsValid("-inf"));
+
+ UNIT_ASSERT_VALUES_EQUAL(ToString(+Nan(), 10, 2), "nan");
+ UNIT_ASSERT_VALUES_EQUAL(ToString(-Nan(), 10, 2), "-nan");
+
+ UNIT_ASSERT_VALUES_EQUAL(ToString(+Inf(), 10, 2), "inf");
+ UNIT_ASSERT_VALUES_EQUAL(ToString(-Inf(), 10, 2), "-inf");
+
+ UNIT_ASSERT(IsNan(FromString("nan", 10, 2)));
+ UNIT_ASSERT(IsNan(FromString("-nAN", 12, 7)));
+ UNIT_ASSERT(IsInf(FromString("+INf", MaxPrecision, 6)));
+ UNIT_ASSERT(IsInf(FromString("-inF", 4, 2)));
}
-
- Y_UNIT_TEST(TestFormStringRoundToEven) {
- UNIT_ASSERT(FromString(".51", 1, 0) == 1);
- UNIT_ASSERT(FromString("-0.51", 1, 0) == -1);
-
- UNIT_ASSERT(FromString("+00000008.5", 1, 0) == 8);
- UNIT_ASSERT(FromString("-8.5000000000000000000000000000000", 1, 0) == -8);
-
- UNIT_ASSERT(FromString("00008.51", 1, 0) == 9);
- UNIT_ASSERT(FromString("-8.5000000000000000000000000000001", 1, 0) == -9);
-
- UNIT_ASSERT(FromString("09.499999999999999999999999999999999999999999999999999999999", 1, 0) == 9);
- UNIT_ASSERT(FromString("-9.499999999999999999999999999999999999999999999999999999999", 1, 0) == -9);
-
- UNIT_ASSERT(FromString("9.50", 2, 0) == 10);
- UNIT_ASSERT(FromString("-9.5", 2, 0) == -10);
-
- UNIT_ASSERT(FromString("+0.9949", 2, 2) == 99);
- UNIT_ASSERT(FromString("-0.9949", 2, 2) == -99);
- }
-
- Y_UNIT_TEST(TestInfinityValues) {
- UNIT_ASSERT(FromString("+1", 1, 1) == Inf());
- UNIT_ASSERT(FromString("-1", 1, 1) == -Inf());
-
- UNIT_ASSERT(FromString("10.000", 1, 0) == Inf());
- UNIT_ASSERT(FromString("-10.000", 1, 0) == -Inf());
-
- UNIT_ASSERT(FromString("9.500", 1, 0) == Inf());
- UNIT_ASSERT(FromString("-9.500", 1, 0) == -Inf());
-
- UNIT_ASSERT(FromString("+0.950", 1, 1) == Inf());
- UNIT_ASSERT(FromString("-0.950", 1, 1) == -Inf());
-
- UNIT_ASSERT(FromString("+0.9950", 2, 2) == Inf());
- UNIT_ASSERT(FromString("-0.9950", 2, 2) == -Inf());
-
- UNIT_ASSERT(FromString("9999999999999999999999999999999999999.5", 35, 0) == Inf());
- UNIT_ASSERT(FromString("-9999999999999999999999999999999999999.5", 35, 0) == -Inf());
- }
-
- Y_UNIT_TEST(TestInvalidValues) {
- UNIT_ASSERT(IsValid("+999999999999999991234567890.039493804903849038490312345678909999999999999999990"));
-
- UNIT_ASSERT(!IsValid("")); // empty
- UNIT_ASSERT(!IsValid("12.2.3")); // double dot
- UNIT_ASSERT(!IsValid("+-12")); // extra sign
- UNIT_ASSERT(!IsValid("463786378O74674")); // letter inside
-
- UNIT_ASSERT(IsError(FromString("", 35, 15))); // empty
- UNIT_ASSERT(IsError(FromString("12.2.3", 35, 15))); // double dot
- UNIT_ASSERT(IsError(FromString("+-12", 35, 15))); // extra sign
- UNIT_ASSERT(IsError(FromString("463786378O74674", 35, 15))); // letter inside
- UNIT_ASSERT(IsError(FromString("+7.039493804E1", 35, 5))); // letter in tail after scale
- }
-
- Y_UNIT_TEST(TestFormStringEx) {
- UNIT_ASSERT(FromStringEx("NAN", 13, 1) == Nan());
- UNIT_ASSERT(FromStringEx("+inf", 11, 7) == Inf());
- UNIT_ASSERT(FromStringEx("-inf", 7, 7) == -Inf());
-
- UNIT_ASSERT(FromStringEx("0.1E3", 10, 1) == 1000);
- UNIT_ASSERT(FromStringEx("0.51e-3", 10, 3) == 1);
-
- UNIT_ASSERT(FromStringEx("1E30", 10, 0) == Inf());
- UNIT_ASSERT(FromStringEx("1e-30", 10, 0) == 0);
- UNIT_ASSERT(FromStringEx("-1E+99", 10, 2) == -Inf());
- UNIT_ASSERT(FromStringEx("-1e-99", 10, 2) == 0);
- UNIT_ASSERT(FromStringEx("-510e-3", 1, 0) == -1);
- UNIT_ASSERT(FromStringEx("+99E3", 5, 0) == 99000);
- }
-
- Y_UNIT_TEST(TestFormStringExInvalidValues) {
- UNIT_ASSERT(IsError(FromStringEx("", 35, 15))); // empty
- UNIT_ASSERT(IsError(FromStringEx("12.2.3", 35, 15))); // double dot
- UNIT_ASSERT(IsError(FromStringEx("+-12", 35, 15))); // extra sign
- UNIT_ASSERT(IsError(FromStringEx("463786378O74674", 35, 15))); // letter inside
-
- UNIT_ASSERT(IsError(FromStringEx("E2", 35, 15))); // empty
- UNIT_ASSERT(IsError(FromStringEx("E2E4", 35, 15))); // empty
- UNIT_ASSERT(IsError(FromStringEx("12E0", 35, 15))); // zero isn't avail
- UNIT_ASSERT(IsError(FromStringEx("NANE5", 35, 15))); // nan with exp
- }
-
- Y_UNIT_TEST(TestSpecialAsString) {
- UNIT_ASSERT(IsValid("+Nan"));
- UNIT_ASSERT(IsValid("-nAn"));
- UNIT_ASSERT(IsValid("INF"));
- UNIT_ASSERT(IsValid("-inf"));
-
- UNIT_ASSERT_VALUES_EQUAL(ToString(+Nan(), 10, 2), "nan");
- UNIT_ASSERT_VALUES_EQUAL(ToString(-Nan(), 10, 2), "-nan");
-
- UNIT_ASSERT_VALUES_EQUAL(ToString(+Inf(), 10, 2), "inf");
- UNIT_ASSERT_VALUES_EQUAL(ToString(-Inf(), 10, 2), "-inf");
-
- UNIT_ASSERT(IsNan(FromString("nan", 10, 2)));
- UNIT_ASSERT(IsNan(FromString("-nAN", 12, 7)));
- UNIT_ASSERT(IsInf(FromString("+INf", MaxPrecision, 6)));
- UNIT_ASSERT(IsInf(FromString("-inF", 4, 2)));
- }
Y_UNIT_TEST(TestToStringOfNonNormal) {
// above Inf
@@ -258,88 +258,88 @@ Y_UNIT_TEST_SUITE(TYqlDecimalTest) {
UNIT_ASSERT(ToString(i, MaxPrecision, 0) == nullptr);
}
}
-
- Y_UNIT_TEST(TestSerializeAndDeserialize) {
- SimpleSerializeAndDeserialize(-Nan(), 1U);
- SimpleSerializeAndDeserialize(-Inf(), 1U);
-
- SimpleSerializeAndDeserialize(-Inf() + 1, 16U);
- SimpleSerializeAndDeserialize(-Inf() + 2, 16U);
-
- SimpleSerializeAndDeserialize(-65537, 4U);
- SimpleSerializeAndDeserialize(-65536, 3U);
-
- SimpleSerializeAndDeserialize(-257, 3U);
- SimpleSerializeAndDeserialize(-256, 2U);
-
- SimpleSerializeAndDeserialize(-3, 2U);
- SimpleSerializeAndDeserialize(-2, 2U);
-
- SimpleSerializeAndDeserialize(-1, 1U);
- SimpleSerializeAndDeserialize(0, 1U);
-
- SimpleSerializeAndDeserialize(+1, 2U);
- SimpleSerializeAndDeserialize(+2, 2U);
-
- SimpleSerializeAndDeserialize(+255, 2U);
- SimpleSerializeAndDeserialize(+256, 3U);
-
- SimpleSerializeAndDeserialize(+65535, 3U);
- SimpleSerializeAndDeserialize(+65536, 4U);
-
- SimpleSerializeAndDeserialize(+Inf() - 2, 16U);
- SimpleSerializeAndDeserialize(+Inf() - 1, 16U);
-
- SimpleSerializeAndDeserialize(+Inf(), 1U);
- SimpleSerializeAndDeserialize(+Nan(), 1U);
- }
-
- Y_UNIT_TEST(TestMulAndRescale) {
- CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "-0.99999999999999999999999999999999999", "-0.99999999999999999999999999999999998");
- CheckMulAndRescale<35,35>("-0.99999999999999999999999999999999999", "0.33333333333333333333333333333333333", "-0.33333333333333333333333333333333333");
- CheckMulAndRescale<35,35>("0.33333333333333333333333333333333333", "0.33333333333333333333333333333333333", "0.11111111111111111111111111111111111");
- CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "0.000000000000001", "0.000000000000001");
- CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "0.00000000000000101010101", "0.00000000000000101010101");
- CheckMulAndRescale<35,35>("0.12345678901234567890123456789012345", "0.12345678901234567890123456789012345", "0.01524157875323883675049535156256668");
-
- CheckMulAndRescale<35,34>("9.9999999999999999999999999999999999", "-1.9999999999999999999999999999999999", "-inf");
- CheckMulAndRescale<35,34>("3.3333333333333333333333333333333333", "3.3333333333333333333333333333333333", "inf");
- CheckMulAndRescale<35,34>("3.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "4.4444444444444444444444444444444443");
- CheckMulAndRescale<35,34>("-1.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "-1.7777777777777777777777777777777777");
-
- CheckMulAndRescale<35,34>("-7", "0", "0");
- CheckMulAndRescale<35,34>("inf", "nan", "nan");
- CheckMulAndRescale<35,34>("inf", "0", "nan");
- CheckMulAndRescale<35,34>("-inf", "-inf", "inf");
- }
-
- Y_UNIT_TEST(TestDivAndRescale) {
- CheckDivAndRescale<35,35>("-0.99999999999999999999999999999999999", "0.33333333333333333333333333333333333", "-inf");
- CheckDivAndRescale<35,35>("0.33333333333333333333333333333333333", "-0.33333333333333333333333333333333333", "-inf");
- CheckDivAndRescale<35,35>("0.12345678901234567890123456789012345", "0.12345678901234567890123456789012345", "inf");
-
- CheckDivAndRescale<35,34>("9.9999999999999999999999999999999999", "-1.9999999999999999999999999999999999", "-5.0000000000000000000000000000000002");
- CheckDivAndRescale<35,34>("3.3333333333333333333333333333333333", "3.3333333333333333333333333333333333", "1");
- CheckDivAndRescale<35,34>("3.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "2.5");
- CheckDivAndRescale<35,34>("-1.7777777777777777777777777777777777", "1.3333333333333333333333333333333333", "-1.3333333333333333333333333333333333");
-
- CheckDivAndRescale<35,34>("-7", "0", "-inf");
- CheckDivAndRescale<35,34>("inf", "0", "inf");
- CheckDivAndRescale<35,34>("inf", "0", "inf");
- CheckDivAndRescale<35,34>("-inf", "inf", "nan");
- }
-
- Y_UNIT_TEST(TestWideMul) {
- CheckMul<35>("999999999999999", "99999999999999999999", "99999999999999899999000000000000001");
- CheckMul<35>("9999999999999999", "99999999999999999999", "inf");
- CheckMul<35>("-99999999999999999999999999999999999", "10000000000000000000000000000000000", "-inf");
- CheckMul<35>("-99999999999999999999999999999999999", "-1", "99999999999999999999999999999999999");
- CheckMul<35>("-99999999999999999999999999999999999", "-2", "inf");
-
- CheckMul<35>("nan", "0", "nan");
- CheckMul<35>("inf", "-inf", "-inf");
- CheckMul<35>("inf", "nan", "nan");
- }
+
+ Y_UNIT_TEST(TestSerializeAndDeserialize) {
+ SimpleSerializeAndDeserialize(-Nan(), 1U);
+ SimpleSerializeAndDeserialize(-Inf(), 1U);
+
+ SimpleSerializeAndDeserialize(-Inf() + 1, 16U);
+ SimpleSerializeAndDeserialize(-Inf() + 2, 16U);
+
+ SimpleSerializeAndDeserialize(-65537, 4U);
+ SimpleSerializeAndDeserialize(-65536, 3U);
+
+ SimpleSerializeAndDeserialize(-257, 3U);
+ SimpleSerializeAndDeserialize(-256, 2U);
+
+ SimpleSerializeAndDeserialize(-3, 2U);
+ SimpleSerializeAndDeserialize(-2, 2U);
+
+ SimpleSerializeAndDeserialize(-1, 1U);
+ SimpleSerializeAndDeserialize(0, 1U);
+
+ SimpleSerializeAndDeserialize(+1, 2U);
+ SimpleSerializeAndDeserialize(+2, 2U);
+
+ SimpleSerializeAndDeserialize(+255, 2U);
+ SimpleSerializeAndDeserialize(+256, 3U);
+
+ SimpleSerializeAndDeserialize(+65535, 3U);
+ SimpleSerializeAndDeserialize(+65536, 4U);
+
+ SimpleSerializeAndDeserialize(+Inf() - 2, 16U);
+ SimpleSerializeAndDeserialize(+Inf() - 1, 16U);
+
+ SimpleSerializeAndDeserialize(+Inf(), 1U);
+ SimpleSerializeAndDeserialize(+Nan(), 1U);
+ }
+
+ Y_UNIT_TEST(TestMulAndRescale) {
+ CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "-0.99999999999999999999999999999999999", "-0.99999999999999999999999999999999998");
+ CheckMulAndRescale<35,35>("-0.99999999999999999999999999999999999", "0.33333333333333333333333333333333333", "-0.33333333333333333333333333333333333");
+ CheckMulAndRescale<35,35>("0.33333333333333333333333333333333333", "0.33333333333333333333333333333333333", "0.11111111111111111111111111111111111");
+ CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "0.000000000000001", "0.000000000000001");
+ CheckMulAndRescale<35,35>("0.99999999999999999999999999999999999", "0.00000000000000101010101", "0.00000000000000101010101");
+ CheckMulAndRescale<35,35>("0.12345678901234567890123456789012345", "0.12345678901234567890123456789012345", "0.01524157875323883675049535156256668");
+
+ CheckMulAndRescale<35,34>("9.9999999999999999999999999999999999", "-1.9999999999999999999999999999999999", "-inf");
+ CheckMulAndRescale<35,34>("3.3333333333333333333333333333333333", "3.3333333333333333333333333333333333", "inf");
+ CheckMulAndRescale<35,34>("3.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "4.4444444444444444444444444444444443");
+ CheckMulAndRescale<35,34>("-1.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "-1.7777777777777777777777777777777777");
+
+ CheckMulAndRescale<35,34>("-7", "0", "0");
+ CheckMulAndRescale<35,34>("inf", "nan", "nan");
+ CheckMulAndRescale<35,34>("inf", "0", "nan");
+ CheckMulAndRescale<35,34>("-inf", "-inf", "inf");
+ }
+
+ Y_UNIT_TEST(TestDivAndRescale) {
+ CheckDivAndRescale<35,35>("-0.99999999999999999999999999999999999", "0.33333333333333333333333333333333333", "-inf");
+ CheckDivAndRescale<35,35>("0.33333333333333333333333333333333333", "-0.33333333333333333333333333333333333", "-inf");
+ CheckDivAndRescale<35,35>("0.12345678901234567890123456789012345", "0.12345678901234567890123456789012345", "inf");
+
+ CheckDivAndRescale<35,34>("9.9999999999999999999999999999999999", "-1.9999999999999999999999999999999999", "-5.0000000000000000000000000000000002");
+ CheckDivAndRescale<35,34>("3.3333333333333333333333333333333333", "3.3333333333333333333333333333333333", "1");
+ CheckDivAndRescale<35,34>("3.3333333333333333333333333333333333", "1.3333333333333333333333333333333333", "2.5");
+ CheckDivAndRescale<35,34>("-1.7777777777777777777777777777777777", "1.3333333333333333333333333333333333", "-1.3333333333333333333333333333333333");
+
+ CheckDivAndRescale<35,34>("-7", "0", "-inf");
+ CheckDivAndRescale<35,34>("inf", "0", "inf");
+ CheckDivAndRescale<35,34>("inf", "0", "inf");
+ CheckDivAndRescale<35,34>("-inf", "inf", "nan");
+ }
+
+ Y_UNIT_TEST(TestWideMul) {
+ CheckMul<35>("999999999999999", "99999999999999999999", "99999999999999899999000000000000001");
+ CheckMul<35>("9999999999999999", "99999999999999999999", "inf");
+ CheckMul<35>("-99999999999999999999999999999999999", "10000000000000000000000000000000000", "-inf");
+ CheckMul<35>("-99999999999999999999999999999999999", "-1", "99999999999999999999999999999999999");
+ CheckMul<35>("-99999999999999999999999999999999999", "-2", "inf");
+
+ CheckMul<35>("nan", "0", "nan");
+ CheckMul<35>("inf", "-inf", "-inf");
+ CheckMul<35>("inf", "nan", "nan");
+ }
}
}
diff --git a/ydb/library/yql/public/decimal/ut/yql_wide_int_ut.cpp b/ydb/library/yql/public/decimal/ut/yql_wide_int_ut.cpp
index 6097e01c27..29ec766caf 100644
--- a/ydb/library/yql/public/decimal/ut/yql_wide_int_ut.cpp
+++ b/ydb/library/yql/public/decimal/ut/yql_wide_int_ut.cpp
@@ -1,465 +1,465 @@
#include <ydb/library/yql/public/decimal/yql_wide_int.h>
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NYql {
-Y_UNIT_TEST_SUITE(TYqlWideIntTest) {
- template<typename T>
- void TestUnary(const T aa) {
- using Test = TWide<typename THalfOf<T>::Type>;
- const Test at(aa);
- static_assert(sizeof(at) == sizeof(aa), "Bad wide int size!");
-
- UNIT_ASSERT_VALUES_EQUAL(static_cast<i8>(aa), static_cast<i8>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<ui8>(aa), static_cast<ui8>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<i16>(aa), static_cast<i16>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<ui16>(aa), static_cast<ui16>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<i32>(aa), static_cast<i32>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<ui32>(aa), static_cast<ui32>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<i64>(aa), static_cast<i64>(at));
- UNIT_ASSERT_VALUES_EQUAL(static_cast<ui64>(aa), static_cast<ui64>(at));
-#ifndef _win_
- UNIT_ASSERT(static_cast<i128_t>(aa) == static_cast<i128_t>(at));
- UNIT_ASSERT(static_cast<ui128_t>(aa) == static_cast<ui128_t>(at));
-#endif
-
- {
- const auto exp = ~aa;
- const auto tst = ~at;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = +aa;
- const auto tst = +at;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = -aa;
- const auto tst = -at;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- auto exp = aa;
- auto tst = at;
- ++exp;
- ++tst;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- auto exp = aa;
- auto tst = at;
- --exp;
- --tst;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- auto exp = aa;
- auto tst = at;
- exp++;
- tst++;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- auto exp = aa;
- auto tst = at;
- exp--;
- tst--;
- UNIT_ASSERT(T(tst) == T(exp));
- }
- }
-
- template<typename T>
- void TestBinary(const T ll, const T rr) {
- using Test = TWide<typename THalfOf<T>::Type>;
- const Test lt(ll), rt(rr);
-
- {
- const auto exp = ll & rr;
- const auto tst = lt & rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll | rr;
- const auto tst = lt | rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll ^ rr;
- const auto tst = lt ^ rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll + rr;
- const auto tst = lt + rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll - rr;
- const auto tst = lt - rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- if (rr > 0 && rr < T(sizeof(T) << 3U))
- {
- const auto exp = ll >> rr;
- const auto tst = lt >> rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- if (rr > 0 && rr < T(sizeof(T) << 3U))
- {
- const auto exp = ll << rr;
- const auto tst = lt << rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll * rr;
- const auto tst = lt * rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- if (rr)
- {
- const auto exp = ll / rr;
- const auto tst = lt / rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- if (rr)
- {
- const auto exp = ll % rr;
- const auto tst = lt % rt;
- UNIT_ASSERT(T(tst) == T(exp));
- }
-
- {
- const auto exp = ll == rr;
- const auto tst = lt == rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
-
- {
- const auto exp = ll != rr;
- const auto tst = lt != rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
-
- {
- const auto exp = ll > rr;
- const auto tst = lt > rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
-
- {
- const auto exp = ll < rr;
- const auto tst = lt < rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
-
- {
- const auto exp = ll >= rr;
- const auto tst = lt >= rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
-
- {
- const auto exp = ll <= rr;
- const auto tst = lt <= rt;
- UNIT_ASSERT_VALUES_EQUAL(tst, exp);
- }
- }
-
- template<typename T>
- void TestsForUnsignedType() {
- static_assert(std::is_unsigned<T>::value, "Tests for unsigned type.");
- TestUnary<T>(2U);
- TestUnary<T>(4U);
- TestUnary<T>(17U);
- TestUnary<T>(42U);
- TestUnary<T>(127U);
- TestUnary<T>(128U);
- TestUnary<T>(129U);
- TestUnary<T>(200U);
- TestUnary<T>(255U);
- TestUnary<T>(256U);
- TestUnary<T>(257U);
-
- TestUnary<T>(std::numeric_limits<T>::min());
- TestUnary<T>(std::numeric_limits<T>::max());
- TestUnary<T>(std::numeric_limits<T>::max() - 1U);
- TestUnary<T>(std::numeric_limits<T>::max() >> 1U);
- TestUnary<T>(std::numeric_limits<T>::max() >> 3U);
- TestUnary<T>(std::numeric_limits<T>::max() >> 7U);
-
-
- TestUnary<T>(std::numeric_limits<T>::min() + 1U);
- TestUnary<T>(std::numeric_limits<T>::max() - 1U);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 3U);
- TestUnary<T>(std::numeric_limits<T>::max() - 3U);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 7U);
- TestUnary<T>(std::numeric_limits<T>::max() - 7U);
-
-
- TestBinary<T>(1U, 1U);
- TestBinary<T>(7U, 31U);
- TestBinary<T>(30000U, 13U);
- TestBinary<T>(127U, 13U);
- TestBinary<T>(128U, 19U);
- TestBinary<T>(129U, 17U);
-
-
- TestBinary<T>(std::numeric_limits<T>::min(), 7U);
- TestBinary<T>(std::numeric_limits<T>::max(), 7U);
-
- TestBinary<T>(std::numeric_limits<T>::min(), 8U);
- TestBinary<T>(std::numeric_limits<T>::max(), 8U);
-
- TestBinary<T>(std::numeric_limits<T>::min(), 9U);
- TestBinary<T>(std::numeric_limits<T>::max(), 9U);
-
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() + 1U);
-
-
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
-
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() + 1U);
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() + 1U);
-
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::min() + 1U, std::numeric_limits<T>::min());
-
- TestBinary<T>(std::numeric_limits<T>::max(), 1U);
- TestBinary<T>(std::numeric_limits<T>::min(), 1U);
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, 1U);
- TestBinary<T>(std::numeric_limits<T>::min() + 1U, 1U);
-
- TestBinary<T>(std::numeric_limits<T>::max(), 7U);
- TestBinary<T>(std::numeric_limits<T>::min(), 7U);
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, 7U);
- TestBinary<T>(std::numeric_limits<T>::min() + 1U, 7U);
-
- TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min() >> 1U);
- TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min() + 1U);
- TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() >> 1U);
- TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 1U);
-
- TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min() >> 3U);
- TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min() + 3U);
- TestBinary<T>(std::numeric_limits<T>::max() - 3U, std::numeric_limits<T>::min() >> 3U);
- TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 3U);
- }
-
- template<typename T>
- void TestsForSignedType() {
- static_assert(std::is_signed<T>::value, "Tests for signed type.");
- TestUnary<T>(0);
-
- TestUnary<T>(1);
- TestUnary<T>(-1);
-
- TestUnary<T>(2);
- TestUnary<T>(-2);
-
- TestUnary<T>(3);
- TestUnary<T>(-3);
-
- TestUnary<T>(4);
- TestUnary<T>(-4);
-
- TestUnary<T>(17);
- TestUnary<T>(-17);
-
- TestUnary<T>(42);
- TestUnary<T>(-42);
-
- TestUnary<T>(127);
- TestUnary<T>(-127);
-
- TestUnary<T>(128);
- TestUnary<T>(-128);
-
- TestUnary<T>(129);
- TestUnary<T>(-129);
-
- TestUnary<T>(200);
- TestUnary<T>(-200);
-
- TestUnary<T>(255);
- TestUnary<T>(-255);
-
- TestUnary<T>(256);
- TestUnary<T>(-256);
-
- TestUnary<T>(257);
- TestUnary<T>(-257);
-
- TestUnary<T>(258);
- TestUnary<T>(-258);
-
- TestUnary<T>(std::numeric_limits<T>::min());
- TestUnary<T>(std::numeric_limits<T>::max());
-
- TestUnary<T>(std::numeric_limits<T>::min() + 1);
- TestUnary<T>(std::numeric_limits<T>::max() - 1);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 2);
- TestUnary<T>(std::numeric_limits<T>::max() - 2);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 3);
- TestUnary<T>(std::numeric_limits<T>::max() - 3);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 7);
- TestUnary<T>(std::numeric_limits<T>::max() - 7);
-
- TestUnary<T>(std::numeric_limits<T>::min() >> 1);
- TestUnary<T>(std::numeric_limits<T>::max() >> 1);
-
- TestUnary<T>(std::numeric_limits<T>::min() >> 3);
- TestUnary<T>(std::numeric_limits<T>::max() >> 3);
-
- TestUnary<T>(std::numeric_limits<T>::min() >> 7);
- TestUnary<T>(std::numeric_limits<T>::max() >> 7);
-
-
- TestUnary<T>(std::numeric_limits<T>::min() + 1);
- TestUnary<T>(std::numeric_limits<T>::max() - 1);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 3);
- TestUnary<T>(std::numeric_limits<T>::max() - 3);
-
- TestUnary<T>(std::numeric_limits<T>::min() + 7);
- TestUnary<T>(std::numeric_limits<T>::max() - 7);
-
-
- TestBinary<T>(0, 0);
- TestBinary<T>(1, 0);
- TestBinary<T>(0, -1);
-
- TestBinary<T>(1, 1);
- TestBinary<T>(1, -1);
- TestBinary<T>(-1, 1);
- TestBinary<T>(-1, -1);
-
- TestBinary<T>(7, 42);
- TestBinary<T>(-7, 42);
-
- TestBinary<T>(0, -43);
-
- TestBinary<T>(-30000, 64);
- TestBinary<T>(30000, -64);
- TestBinary<T>(30000, 64);
-
- TestBinary<T>(21, 0);
- TestBinary<T>(13, -127);
- TestBinary<T>(-19, 128);
- TestBinary<T>(-77, -129);
- TestBinary<T>(13, 127);
- TestBinary<T>(19, 128);
- TestBinary<T>(77, 129);
-
- TestBinary<T>(std::numeric_limits<T>::max(), -1);
-
- TestBinary<T>(std::numeric_limits<T>::min(), -7);
- TestBinary<T>(std::numeric_limits<T>::max(), -7);
-
- TestBinary<T>(std::numeric_limits<T>::min(), -8);
- TestBinary<T>(std::numeric_limits<T>::max(), -8);
-
- TestBinary<T>(std::numeric_limits<T>::min(), -9);
- TestBinary<T>(std::numeric_limits<T>::max(), -9);
-
- TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min() >> 5);
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 5);
-
-
- TestBinary<T>(std::numeric_limits<T>::min(), 7);
- TestBinary<T>(std::numeric_limits<T>::max(), 7);
-
- TestBinary<T>(std::numeric_limits<T>::min(), 8);
- TestBinary<T>(std::numeric_limits<T>::max(), 8);
-
- TestBinary<T>(std::numeric_limits<T>::min(), 9);
- TestBinary<T>(std::numeric_limits<T>::max(), 9);
-
- TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() + 1);
-
-
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
-
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() + 1);
- TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() + 1);
-
- TestBinary<T>(std::numeric_limits<T>::max(), 0);
- TestBinary<T>(std::numeric_limits<T>::min(), 0);
- TestBinary<T>(std::numeric_limits<T>::max() - 1, 0);
- TestBinary<T>(std::numeric_limits<T>::min() + 1, 0);
-
- TestBinary<T>(std::numeric_limits<T>::max(), 1);
- TestBinary<T>(std::numeric_limits<T>::min(), 1);
- TestBinary<T>(std::numeric_limits<T>::max() - 1, 1);
- TestBinary<T>(std::numeric_limits<T>::min() + 1, 1);
-
- TestBinary<T>(std::numeric_limits<T>::max(), 7);
- TestBinary<T>(std::numeric_limits<T>::min(), 7);
- TestBinary<T>(std::numeric_limits<T>::max() - 1, 7);
- TestBinary<T>(std::numeric_limits<T>::min() + 1, 7);
-
- TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min() >> 1);
- TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min() + 1);
- TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() >> 1);
- TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 1);
-
- TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min() >> 3);
- TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min() + 3);
- TestBinary<T>(std::numeric_limits<T>::max() - 3, std::numeric_limits<T>::min() >> 3);
- TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min());
- TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 3);
- }
-
- Y_UNIT_TEST(CheckUnsignedByCompilerIntegrals) {
- TestsForUnsignedType<ui32>();
- TestsForUnsignedType<ui64>();
-#ifndef _win_
- TestsForUnsignedType<ui128_t>();
-#endif
- }
-
-#ifndef _ubsan_enabled_
-#ifndef _msan_enabled_
- Y_UNIT_TEST(CheckSignedByCompilerIntegrals) {
- TestsForSignedType<i32>();
- TestsForSignedType<i64>();
-#ifndef _win_
- TestsForSignedType<i128_t>();
-#endif
- }
-#endif
-#endif
-}
-
-}
+
+namespace NYql {
+Y_UNIT_TEST_SUITE(TYqlWideIntTest) {
+ template<typename T>
+ void TestUnary(const T aa) {
+ using Test = TWide<typename THalfOf<T>::Type>;
+ const Test at(aa);
+ static_assert(sizeof(at) == sizeof(aa), "Bad wide int size!");
+
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<i8>(aa), static_cast<i8>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<ui8>(aa), static_cast<ui8>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<i16>(aa), static_cast<i16>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<ui16>(aa), static_cast<ui16>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<i32>(aa), static_cast<i32>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<ui32>(aa), static_cast<ui32>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<i64>(aa), static_cast<i64>(at));
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<ui64>(aa), static_cast<ui64>(at));
+#ifndef _win_
+ UNIT_ASSERT(static_cast<i128_t>(aa) == static_cast<i128_t>(at));
+ UNIT_ASSERT(static_cast<ui128_t>(aa) == static_cast<ui128_t>(at));
+#endif
+
+ {
+ const auto exp = ~aa;
+ const auto tst = ~at;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = +aa;
+ const auto tst = +at;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = -aa;
+ const auto tst = -at;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ auto exp = aa;
+ auto tst = at;
+ ++exp;
+ ++tst;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ auto exp = aa;
+ auto tst = at;
+ --exp;
+ --tst;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ auto exp = aa;
+ auto tst = at;
+ exp++;
+ tst++;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ auto exp = aa;
+ auto tst = at;
+ exp--;
+ tst--;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+ }
+
+ template<typename T>
+ void TestBinary(const T ll, const T rr) {
+ using Test = TWide<typename THalfOf<T>::Type>;
+ const Test lt(ll), rt(rr);
+
+ {
+ const auto exp = ll & rr;
+ const auto tst = lt & rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll | rr;
+ const auto tst = lt | rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll ^ rr;
+ const auto tst = lt ^ rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll + rr;
+ const auto tst = lt + rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll - rr;
+ const auto tst = lt - rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ if (rr > 0 && rr < T(sizeof(T) << 3U))
+ {
+ const auto exp = ll >> rr;
+ const auto tst = lt >> rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ if (rr > 0 && rr < T(sizeof(T) << 3U))
+ {
+ const auto exp = ll << rr;
+ const auto tst = lt << rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll * rr;
+ const auto tst = lt * rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ if (rr)
+ {
+ const auto exp = ll / rr;
+ const auto tst = lt / rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ if (rr)
+ {
+ const auto exp = ll % rr;
+ const auto tst = lt % rt;
+ UNIT_ASSERT(T(tst) == T(exp));
+ }
+
+ {
+ const auto exp = ll == rr;
+ const auto tst = lt == rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+
+ {
+ const auto exp = ll != rr;
+ const auto tst = lt != rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+
+ {
+ const auto exp = ll > rr;
+ const auto tst = lt > rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+
+ {
+ const auto exp = ll < rr;
+ const auto tst = lt < rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+
+ {
+ const auto exp = ll >= rr;
+ const auto tst = lt >= rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+
+ {
+ const auto exp = ll <= rr;
+ const auto tst = lt <= rt;
+ UNIT_ASSERT_VALUES_EQUAL(tst, exp);
+ }
+ }
+
+ template<typename T>
+ void TestsForUnsignedType() {
+ static_assert(std::is_unsigned<T>::value, "Tests for unsigned type.");
+ TestUnary<T>(2U);
+ TestUnary<T>(4U);
+ TestUnary<T>(17U);
+ TestUnary<T>(42U);
+ TestUnary<T>(127U);
+ TestUnary<T>(128U);
+ TestUnary<T>(129U);
+ TestUnary<T>(200U);
+ TestUnary<T>(255U);
+ TestUnary<T>(256U);
+ TestUnary<T>(257U);
+
+ TestUnary<T>(std::numeric_limits<T>::min());
+ TestUnary<T>(std::numeric_limits<T>::max());
+ TestUnary<T>(std::numeric_limits<T>::max() - 1U);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 1U);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 3U);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 7U);
+
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 1U);
+ TestUnary<T>(std::numeric_limits<T>::max() - 1U);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 3U);
+ TestUnary<T>(std::numeric_limits<T>::max() - 3U);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 7U);
+ TestUnary<T>(std::numeric_limits<T>::max() - 7U);
+
+
+ TestBinary<T>(1U, 1U);
+ TestBinary<T>(7U, 31U);
+ TestBinary<T>(30000U, 13U);
+ TestBinary<T>(127U, 13U);
+ TestBinary<T>(128U, 19U);
+ TestBinary<T>(129U, 17U);
+
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 7U);
+ TestBinary<T>(std::numeric_limits<T>::max(), 7U);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 8U);
+ TestBinary<T>(std::numeric_limits<T>::max(), 8U);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 9U);
+ TestBinary<T>(std::numeric_limits<T>::max(), 9U);
+
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() + 1U);
+
+
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() + 1U);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() + 1U);
+
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::min() + 1U, std::numeric_limits<T>::min());
+
+ TestBinary<T>(std::numeric_limits<T>::max(), 1U);
+ TestBinary<T>(std::numeric_limits<T>::min(), 1U);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, 1U);
+ TestBinary<T>(std::numeric_limits<T>::min() + 1U, 1U);
+
+ TestBinary<T>(std::numeric_limits<T>::max(), 7U);
+ TestBinary<T>(std::numeric_limits<T>::min(), 7U);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, 7U);
+ TestBinary<T>(std::numeric_limits<T>::min() + 1U, 7U);
+
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min() >> 1U);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min() + 1U);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1U, std::numeric_limits<T>::min() >> 1U);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1U, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 1U);
+
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min() >> 3U);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min() + 3U);
+ TestBinary<T>(std::numeric_limits<T>::max() - 3U, std::numeric_limits<T>::min() >> 3U);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3U, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 3U);
+ }
+
+ template<typename T>
+ void TestsForSignedType() {
+ static_assert(std::is_signed<T>::value, "Tests for signed type.");
+ TestUnary<T>(0);
+
+ TestUnary<T>(1);
+ TestUnary<T>(-1);
+
+ TestUnary<T>(2);
+ TestUnary<T>(-2);
+
+ TestUnary<T>(3);
+ TestUnary<T>(-3);
+
+ TestUnary<T>(4);
+ TestUnary<T>(-4);
+
+ TestUnary<T>(17);
+ TestUnary<T>(-17);
+
+ TestUnary<T>(42);
+ TestUnary<T>(-42);
+
+ TestUnary<T>(127);
+ TestUnary<T>(-127);
+
+ TestUnary<T>(128);
+ TestUnary<T>(-128);
+
+ TestUnary<T>(129);
+ TestUnary<T>(-129);
+
+ TestUnary<T>(200);
+ TestUnary<T>(-200);
+
+ TestUnary<T>(255);
+ TestUnary<T>(-255);
+
+ TestUnary<T>(256);
+ TestUnary<T>(-256);
+
+ TestUnary<T>(257);
+ TestUnary<T>(-257);
+
+ TestUnary<T>(258);
+ TestUnary<T>(-258);
+
+ TestUnary<T>(std::numeric_limits<T>::min());
+ TestUnary<T>(std::numeric_limits<T>::max());
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 1);
+ TestUnary<T>(std::numeric_limits<T>::max() - 1);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 2);
+ TestUnary<T>(std::numeric_limits<T>::max() - 2);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 3);
+ TestUnary<T>(std::numeric_limits<T>::max() - 3);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 7);
+ TestUnary<T>(std::numeric_limits<T>::max() - 7);
+
+ TestUnary<T>(std::numeric_limits<T>::min() >> 1);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 1);
+
+ TestUnary<T>(std::numeric_limits<T>::min() >> 3);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 3);
+
+ TestUnary<T>(std::numeric_limits<T>::min() >> 7);
+ TestUnary<T>(std::numeric_limits<T>::max() >> 7);
+
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 1);
+ TestUnary<T>(std::numeric_limits<T>::max() - 1);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 3);
+ TestUnary<T>(std::numeric_limits<T>::max() - 3);
+
+ TestUnary<T>(std::numeric_limits<T>::min() + 7);
+ TestUnary<T>(std::numeric_limits<T>::max() - 7);
+
+
+ TestBinary<T>(0, 0);
+ TestBinary<T>(1, 0);
+ TestBinary<T>(0, -1);
+
+ TestBinary<T>(1, 1);
+ TestBinary<T>(1, -1);
+ TestBinary<T>(-1, 1);
+ TestBinary<T>(-1, -1);
+
+ TestBinary<T>(7, 42);
+ TestBinary<T>(-7, 42);
+
+ TestBinary<T>(0, -43);
+
+ TestBinary<T>(-30000, 64);
+ TestBinary<T>(30000, -64);
+ TestBinary<T>(30000, 64);
+
+ TestBinary<T>(21, 0);
+ TestBinary<T>(13, -127);
+ TestBinary<T>(-19, 128);
+ TestBinary<T>(-77, -129);
+ TestBinary<T>(13, 127);
+ TestBinary<T>(19, 128);
+ TestBinary<T>(77, 129);
+
+ TestBinary<T>(std::numeric_limits<T>::max(), -1);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), -7);
+ TestBinary<T>(std::numeric_limits<T>::max(), -7);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), -8);
+ TestBinary<T>(std::numeric_limits<T>::max(), -8);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), -9);
+ TestBinary<T>(std::numeric_limits<T>::max(), -9);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min() >> 5);
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 5);
+
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 7);
+ TestBinary<T>(std::numeric_limits<T>::max(), 7);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 8);
+ TestBinary<T>(std::numeric_limits<T>::max(), 8);
+
+ TestBinary<T>(std::numeric_limits<T>::min(), 9);
+ TestBinary<T>(std::numeric_limits<T>::max(), 9);
+
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() + 1);
+
+
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() + 1);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() + 1);
+
+ TestBinary<T>(std::numeric_limits<T>::max(), 0);
+ TestBinary<T>(std::numeric_limits<T>::min(), 0);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, 0);
+ TestBinary<T>(std::numeric_limits<T>::min() + 1, 0);
+
+ TestBinary<T>(std::numeric_limits<T>::max(), 1);
+ TestBinary<T>(std::numeric_limits<T>::min(), 1);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, 1);
+ TestBinary<T>(std::numeric_limits<T>::min() + 1, 1);
+
+ TestBinary<T>(std::numeric_limits<T>::max(), 7);
+ TestBinary<T>(std::numeric_limits<T>::min(), 7);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, 7);
+ TestBinary<T>(std::numeric_limits<T>::min() + 1, 7);
+
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min() >> 1);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min() + 1);
+ TestBinary<T>(std::numeric_limits<T>::max() - 1, std::numeric_limits<T>::min() >> 1);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 1, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 1);
+
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min() >> 3);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min() + 3);
+ TestBinary<T>(std::numeric_limits<T>::max() - 3, std::numeric_limits<T>::min() >> 3);
+ TestBinary<T>(std::numeric_limits<T>::max() >> 3, std::numeric_limits<T>::min());
+ TestBinary<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::min() >> 3);
+ }
+
+ Y_UNIT_TEST(CheckUnsignedByCompilerIntegrals) {
+ TestsForUnsignedType<ui32>();
+ TestsForUnsignedType<ui64>();
+#ifndef _win_
+ TestsForUnsignedType<ui128_t>();
+#endif
+ }
+
+#ifndef _ubsan_enabled_
+#ifndef _msan_enabled_
+ Y_UNIT_TEST(CheckSignedByCompilerIntegrals) {
+ TestsForSignedType<i32>();
+ TestsForSignedType<i64>();
+#ifndef _win_
+ TestsForSignedType<i128_t>();
+#endif
+ }
+#endif
+#endif
+}
+
+}
diff --git a/ydb/library/yql/public/decimal/yql_decimal.cpp b/ydb/library/yql/public/decimal/yql_decimal.cpp
index 776504f707..89fc92cd49 100644
--- a/ydb/library/yql/public/decimal/yql_decimal.cpp
+++ b/ydb/library/yql/public/decimal/yql_decimal.cpp
@@ -1,98 +1,98 @@
#include "yql_decimal.h"
-
-#include <cstring>
+
+#include <cstring>
#include <ostream>
#include <string>
-namespace NYql {
-namespace NDecimal {
-
-static const TUint128 Ten(10U);
-
-TUint128 GetDivider(ui8 scale) {
- TUint128 d(1U);
- while (scale--)
- d *= Ten;
- return d;
-}
-
+namespace NYql {
+namespace NDecimal {
+
+static const TUint128 Ten(10U);
+
+TUint128 GetDivider(ui8 scale) {
+ TUint128 d(1U);
+ while (scale--)
+ d *= Ten;
+ return d;
+}
+
bool IsError(TInt128 v) {
return v > Nan() || v < -Nan();
-}
-
-bool IsNan(TInt128 v) {
- return v == Nan() || v == -Nan();
-}
-
-bool IsInf(TInt128 v) {
- return v == Inf() || v == -Inf();
-}
-
-bool IsNormal(TInt128 v) {
- return v < Inf() && v > -Inf();
-}
-
-bool IsComparable(TInt128 v) {
- return v <= Inf() && v >= -Inf();
-}
-
-const char* ToString(TInt128 val, ui8 precision, ui8 scale) {
- if (!precision || precision > MaxPrecision || scale > precision) {
+}
+
+bool IsNan(TInt128 v) {
+ return v == Nan() || v == -Nan();
+}
+
+bool IsInf(TInt128 v) {
+ return v == Inf() || v == -Inf();
+}
+
+bool IsNormal(TInt128 v) {
+ return v < Inf() && v > -Inf();
+}
+
+bool IsComparable(TInt128 v) {
+ return v <= Inf() && v >= -Inf();
+}
+
+const char* ToString(TInt128 val, ui8 precision, ui8 scale) {
+ if (!precision || precision > MaxPrecision || scale > precision) {
return nullptr;
}
- if (val == Inf())
- return "inf";
- if (val == -Inf())
- return "-inf";
- if (val == Nan())
- return "nan";
- if (val == -Nan())
- return "-nan";
-
- if (!IsNormal(val)) {
+ if (val == Inf())
+ return "inf";
+ if (val == -Inf())
+ return "-inf";
+ if (val == Nan())
+ return "nan";
+ if (val == -Nan())
+ return "-nan";
+
+ if (!IsNormal(val)) {
return nullptr;
}
- if (!val) {
- return "0";
- }
-
- const bool neg = val < 0;
- TUint128 v = neg ? -val : val;
-
+ if (!val) {
+ return "0";
+ }
+
+ const bool neg = val < 0;
+ TUint128 v = neg ? -val : val;
+
// log_{10}(2^120) ~= 36.12, 37 decimal places
// plus dot, zero before dot, sign and zero byte at the end
- static thread_local char str[40];
- auto end = str + sizeof(str);
- *--end = 0;
-
- auto s = end;
-
- do {
+ static thread_local char str[40];
+ auto end = str + sizeof(str);
+ *--end = 0;
+
+ auto s = end;
+
+ do {
if (!precision--) {
- return nullptr;
+ return nullptr;
}
-
- const auto digit = ui8(v % Ten);
- if (digit || !scale || s != end) {
- *--s = "0123456789"[digit];
+
+ const auto digit = ui8(v % Ten);
+ if (digit || !scale || s != end) {
+ *--s = "0123456789"[digit];
}
- if (scale && !--scale && s != end) {
- *--s = '.';
+ if (scale && !--scale && s != end) {
+ *--s = '.';
}
- } while (v /= Ten);
-
+ } while (v /= Ten);
+
if (scale) {
- do {
+ do {
if (!precision--) {
return nullptr;
}
*--s = '0';
- } while (--scale);
+ } while (--scale);
*--s = '.';
}
@@ -102,340 +102,340 @@ const char* ToString(TInt128 val, ui8 precision, ui8 scale) {
}
if (neg) {
- *--s = '-';
+ *--s = '-';
+ }
+
+ return s;
+}
+
+namespace {
+ bool IsNan(const char* s) {
+ return (s[0] == 'N' || s[0] == 'n') && (s[1] == 'A' || s[1] == 'a') && (s[2] == 'N' || s[2] == 'n');
}
- return s;
-}
-
-namespace {
- bool IsNan(const char* s) {
- return (s[0] == 'N' || s[0] == 'n') && (s[1] == 'A' || s[1] == 'a') && (s[2] == 'N' || s[2] == 'n');
- }
-
- bool IsInf(const char* s) {
- return (s[0] == 'I' || s[0] == 'i') && (s[1] == 'N' || s[1] == 'n') && (s[2] == 'F' || s[2] == 'f');
- }
-}
-
-
+ bool IsInf(const char* s) {
+ return (s[0] == 'I' || s[0] == 'i') && (s[1] == 'N' || s[1] == 'n') && (s[2] == 'F' || s[2] == 'f');
+ }
+}
+
+
TInt128 FromString(const TStringBuf& str, ui8 precision, ui8 scale) {
- if (scale > precision)
+ if (scale > precision)
return Err();
-
+
auto s = str.data();
auto l = str.size();
-
- if (!s || !l)
+
+ if (!s || !l)
return Err();
-
- const bool neg = '-' == *s;
- if (neg || '+' == *s) {
- ++s;
- --l;
- }
-
- if (3U == l) {
- if (IsInf(s))
- return neg ? -Inf() : Inf();
- if (IsNan(s))
- return neg ? -Nan() : Nan();
- }
-
- TUint128 v = 0U;
- auto integral = precision - scale;
-
- for (bool dot = false; l; --l) {
- if (*s == '.') {
- if (dot)
+
+ const bool neg = '-' == *s;
+ if (neg || '+' == *s) {
+ ++s;
+ --l;
+ }
+
+ if (3U == l) {
+ if (IsInf(s))
+ return neg ? -Inf() : Inf();
+ if (IsNan(s))
+ return neg ? -Nan() : Nan();
+ }
+
+ TUint128 v = 0U;
+ auto integral = precision - scale;
+
+ for (bool dot = false; l; --l) {
+ if (*s == '.') {
+ if (dot)
return Err();
-
- ++s;
- dot = true;
- continue;
- }
-
- if (dot) {
- if (scale)
- --scale;
- else
- break;
- }
-
- const char c = *s++;
- if (!std::isdigit(c))
+
+ ++s;
+ dot = true;
+ continue;
+ }
+
+ if (dot) {
+ if (scale)
+ --scale;
+ else
+ break;
+ }
+
+ const char c = *s++;
+ if (!std::isdigit(c))
return Err();
-
- v *= Ten;
- v += c - '0';
-
- if (!dot && v && !integral--) {
- return neg ? -Inf() : Inf();
- }
- }
-
- if (l--) {
- const char c = *s++;
- if (!std::isdigit(c))
+
+ v *= Ten;
+ v += c - '0';
+
+ if (!dot && v && !integral--) {
+ return neg ? -Inf() : Inf();
+ }
+ }
+
+ if (l--) {
+ const char c = *s++;
+ if (!std::isdigit(c))
return Err();
-
- bool plus = c > '5';
- if (!plus && c == '5') {
- for (plus = v & 1; !plus && l; --l) {
- const char c = *s++;
- if (!std::isdigit(c))
+
+ bool plus = c > '5';
+ if (!plus && c == '5') {
+ for (plus = v & 1; !plus && l; --l) {
+ const char c = *s++;
+ if (!std::isdigit(c))
return Err();
- plus = c != '0';
- }
- }
-
- while (l--)
- if (!std::isdigit(*s++))
- return Err();
-
- if (plus)
- if (++v >= GetDivider(precision))
- v = Inf();
- }
-
- while (scale--)
- v *= Ten;
-
- return neg ? -v : v;
-}
-
-TInt128 FromStringEx(const TStringBuf& str, ui8 precision, ui8 scale) {
- if (scale > precision)
- return Err();
-
+ plus = c != '0';
+ }
+ }
+
+ while (l--)
+ if (!std::isdigit(*s++))
+ return Err();
+
+ if (plus)
+ if (++v >= GetDivider(precision))
+ v = Inf();
+ }
+
+ while (scale--)
+ v *= Ten;
+
+ return neg ? -v : v;
+}
+
+TInt128 FromStringEx(const TStringBuf& str, ui8 precision, ui8 scale) {
+ if (scale > precision)
+ return Err();
+
const auto s = str.data();
-
+
for (auto ptr = s + str.size() - 1U; ptr > s; --ptr) {
- if (*ptr == 'E' || *ptr == 'e') {
- const auto len = ptr - s;
- if (!len)
- return Err();
-
- const auto exp = std::atoi(++ptr);
- if (!exp)
- return Err();
-
- const int p = precision, s = int(scale) + exp;
-
- const auto r = exp > 0 ?
- FromString(str.Head(len), precision, std::min(s, p)):
- FromString(str.Head(len), std::min(p - exp, int(MaxPrecision)), std::max(s, 0));
-
- if (IsNan(r)) {
- return Err();
- }
-
- if (const auto e = exp > 0 ? std::max(0, s - p) : std::min(0, s)) {
- if (r && IsNormal(r)) {
- if (exp > 0)
- return Mul(r, GetDivider(+e));
- if (exp < 0)
- return Div(r, GetDivider(-e));
- }
- }
-
- return r;
- }
- }
-
- return FromString(str, precision, scale);
-}
-
-bool IsValid(const TStringBuf& str) {
+ if (*ptr == 'E' || *ptr == 'e') {
+ const auto len = ptr - s;
+ if (!len)
+ return Err();
+
+ const auto exp = std::atoi(++ptr);
+ if (!exp)
+ return Err();
+
+ const int p = precision, s = int(scale) + exp;
+
+ const auto r = exp > 0 ?
+ FromString(str.Head(len), precision, std::min(s, p)):
+ FromString(str.Head(len), std::min(p - exp, int(MaxPrecision)), std::max(s, 0));
+
+ if (IsNan(r)) {
+ return Err();
+ }
+
+ if (const auto e = exp > 0 ? std::max(0, s - p) : std::min(0, s)) {
+ if (r && IsNormal(r)) {
+ if (exp > 0)
+ return Mul(r, GetDivider(+e));
+ if (exp < 0)
+ return Div(r, GetDivider(-e));
+ }
+ }
+
+ return r;
+ }
+ }
+
+ return FromString(str, precision, scale);
+}
+
+bool IsValid(const TStringBuf& str) {
auto s = str.data();
auto l = str.size();
-
- if (!s || !l)
- return false;
-
- if ('-' == *s || '+' == *s) {
- ++s;
- --l;
- }
-
- if (3U == l && (IsInf(s) || IsNan(s))) {
- return true;
- }
-
- for (bool dot = false; l--;) {
- const char c = *s++;
- if (c == '.') {
- if (dot)
- return false;
-
- dot = true;
- continue;
- }
-
- if (!std::isdigit(c))
- return false;
- }
-
- return true;
-}
-
-TInt128 Mod(TInt128 a, TInt128 b) {
- if (!b || !(IsNormal(a) && IsNormal(b)))
- return Nan();
-
- return a % b;
-}
-
-TInt128 Div(TInt128 a, TInt128 b) {
- if (IsNan(a) || IsNan(b))
- return Nan();
-
- if (!b) {
- if (a > 0)
- return Inf();
- else if (a < 0)
- return -Inf();
- else
- return Nan();
- } else if (IsInf(b)) {
- return IsInf(a) ? Nan() : TInt128(0);
- } else if (IsInf(a)) {
- return b > 0 ? a : -a;
- }
-
- if (b & 1)
- a = TUint128(a) << 1U;
- else
- b >>= 1;
-
- auto d = a / b;
-
- if (d & 1) {
- if (const auto m = a % b) {
- if (m > 0) ++d;
- // else --d;
- } else {
- if (d & 2) ++d;
- }
- }
-
- return d >>= 1;
-}
-
-namespace {
-
-using TInt256 = TWide<TInt128, TInt128, TUint128>;
-
-TInt128 Normalize(const TInt256& v) {
- static const TInt256 PInf256(+Inf()), NInf256(-Inf());
-
- if (v > PInf256)
- return +Inf();
- if (v < NInf256)
- return -Inf();
- return *reinterpret_cast<const TInt128*>(&v);
-}
-
-constexpr auto HalfBitSize = sizeof(TUint128) << 2U;
-
-TUint128 GetUpperHalf(const TUint128& v) {
- return v >> HalfBitSize;
-}
-
-TUint128 GetLowerHalf(const TUint128& v) {
- return v & TUint128(0xFFFFFFFFFFFFFFFFULL);
-}
-
-TInt256 WidenMul(const TInt128& lhs, const TInt128& rhs) {
- const bool nl = lhs < 0;
- const bool nr = rhs < 0;
-
- const TUint128 l = nl ? -lhs : +lhs;
- const TUint128 r = nr ? -rhs : +rhs;
-
- const TUint128 lh[] = {GetLowerHalf(l), GetUpperHalf(l)};
- const TUint128 rh[] = {GetLowerHalf(r), GetUpperHalf(r)};
-
- const TUint128 prods[] = {lh[0] * rh[0], lh[0] * rh[1], lh[1] * rh[0], lh[1] * rh[1]};
-
- const TUint128 fourthQ = GetLowerHalf(prods[0]);
- const TUint128 thirdQ = GetUpperHalf(prods[0]) + GetLowerHalf(prods[1]) + GetLowerHalf(prods[2]);
- const TUint128 secondQ = GetUpperHalf(thirdQ) + GetUpperHalf(prods[1]) + GetUpperHalf(prods[2]) + GetLowerHalf(prods[3]);
- const TUint128 firstQ = GetUpperHalf(secondQ) + GetUpperHalf(prods[3]);
-
- const TInt256 combine((firstQ << HalfBitSize) | GetLowerHalf(secondQ), (thirdQ << HalfBitSize) | fourthQ);
- return nl == nr ? +combine : -combine;
-}
-
-template<bool MayOddDivider>
-TInt256 Div(TInt256&& a, TInt256&& b) {
- if (MayOddDivider && b & 1)
- a <<= 1;
- else
- b >>= 1;
-
- auto d = a / b;
-
- if (d & 1) {
- if (const auto m = a % b) {
- if (m > 0) ++d;
- // else --d;
- } else {
- if (d & 2) ++d;
- }
- }
-
- return d >>= 1;
-}
-
-}
-
-TInt128 Mul(TInt128 a, TInt128 b) {
- if (IsNan(a) || IsNan(b))
- return Nan();
-
- if (IsInf(a))
- return !b ? Nan() : (b > 0 ? a : -a);
-
- if (IsInf(b))
- return !a ? Nan() : (a > 0 ? b : -b);
-
- return Normalize(WidenMul(a, b));
-}
-
-TInt128 MulAndDivNormalMultiplier(TInt128 a, TInt128 b, TInt128 c) {
- if (IsNan(a) || IsNan(c))
- return Nan();
-
- if (!c) {
- if (a > 0)
- return Inf();
- else if (a < 0)
- return -Inf();
- else
- return Nan();
- } else if (IsInf(c)) {
- return IsInf(a) ? Nan() : TInt128(0);
- } else if (IsInf(a)) {
- return c > 0 ? a : -a;
- }
-
- return Normalize(Div<true>(WidenMul(a, b), TInt256(c)));
-}
-
-TInt128 MulAndDivNormalDivider(TInt128 a, TInt128 b, TInt128 c) {
- if (IsNan(a) || IsNan(b))
- return Nan();
-
- if (IsInf(a))
- return !b ? Nan() : (b > 0 ? a : -a);
-
- if (IsInf(b))
- return !a ? Nan() : (a > 0 ? b : -b);
-
- return Normalize(Div<false>(WidenMul(a, b), TInt256(c)));
-}
-
-}
-}
+
+ if (!s || !l)
+ return false;
+
+ if ('-' == *s || '+' == *s) {
+ ++s;
+ --l;
+ }
+
+ if (3U == l && (IsInf(s) || IsNan(s))) {
+ return true;
+ }
+
+ for (bool dot = false; l--;) {
+ const char c = *s++;
+ if (c == '.') {
+ if (dot)
+ return false;
+
+ dot = true;
+ continue;
+ }
+
+ if (!std::isdigit(c))
+ return false;
+ }
+
+ return true;
+}
+
+TInt128 Mod(TInt128 a, TInt128 b) {
+ if (!b || !(IsNormal(a) && IsNormal(b)))
+ return Nan();
+
+ return a % b;
+}
+
+TInt128 Div(TInt128 a, TInt128 b) {
+ if (IsNan(a) || IsNan(b))
+ return Nan();
+
+ if (!b) {
+ if (a > 0)
+ return Inf();
+ else if (a < 0)
+ return -Inf();
+ else
+ return Nan();
+ } else if (IsInf(b)) {
+ return IsInf(a) ? Nan() : TInt128(0);
+ } else if (IsInf(a)) {
+ return b > 0 ? a : -a;
+ }
+
+ if (b & 1)
+ a = TUint128(a) << 1U;
+ else
+ b >>= 1;
+
+ auto d = a / b;
+
+ if (d & 1) {
+ if (const auto m = a % b) {
+ if (m > 0) ++d;
+ // else --d;
+ } else {
+ if (d & 2) ++d;
+ }
+ }
+
+ return d >>= 1;
+}
+
+namespace {
+
+using TInt256 = TWide<TInt128, TInt128, TUint128>;
+
+TInt128 Normalize(const TInt256& v) {
+ static const TInt256 PInf256(+Inf()), NInf256(-Inf());
+
+ if (v > PInf256)
+ return +Inf();
+ if (v < NInf256)
+ return -Inf();
+ return *reinterpret_cast<const TInt128*>(&v);
+}
+
+constexpr auto HalfBitSize = sizeof(TUint128) << 2U;
+
+TUint128 GetUpperHalf(const TUint128& v) {
+ return v >> HalfBitSize;
+}
+
+TUint128 GetLowerHalf(const TUint128& v) {
+ return v & TUint128(0xFFFFFFFFFFFFFFFFULL);
+}
+
+TInt256 WidenMul(const TInt128& lhs, const TInt128& rhs) {
+ const bool nl = lhs < 0;
+ const bool nr = rhs < 0;
+
+ const TUint128 l = nl ? -lhs : +lhs;
+ const TUint128 r = nr ? -rhs : +rhs;
+
+ const TUint128 lh[] = {GetLowerHalf(l), GetUpperHalf(l)};
+ const TUint128 rh[] = {GetLowerHalf(r), GetUpperHalf(r)};
+
+ const TUint128 prods[] = {lh[0] * rh[0], lh[0] * rh[1], lh[1] * rh[0], lh[1] * rh[1]};
+
+ const TUint128 fourthQ = GetLowerHalf(prods[0]);
+ const TUint128 thirdQ = GetUpperHalf(prods[0]) + GetLowerHalf(prods[1]) + GetLowerHalf(prods[2]);
+ const TUint128 secondQ = GetUpperHalf(thirdQ) + GetUpperHalf(prods[1]) + GetUpperHalf(prods[2]) + GetLowerHalf(prods[3]);
+ const TUint128 firstQ = GetUpperHalf(secondQ) + GetUpperHalf(prods[3]);
+
+ const TInt256 combine((firstQ << HalfBitSize) | GetLowerHalf(secondQ), (thirdQ << HalfBitSize) | fourthQ);
+ return nl == nr ? +combine : -combine;
+}
+
+template<bool MayOddDivider>
+TInt256 Div(TInt256&& a, TInt256&& b) {
+ if (MayOddDivider && b & 1)
+ a <<= 1;
+ else
+ b >>= 1;
+
+ auto d = a / b;
+
+ if (d & 1) {
+ if (const auto m = a % b) {
+ if (m > 0) ++d;
+ // else --d;
+ } else {
+ if (d & 2) ++d;
+ }
+ }
+
+ return d >>= 1;
+}
+
+}
+
+TInt128 Mul(TInt128 a, TInt128 b) {
+ if (IsNan(a) || IsNan(b))
+ return Nan();
+
+ if (IsInf(a))
+ return !b ? Nan() : (b > 0 ? a : -a);
+
+ if (IsInf(b))
+ return !a ? Nan() : (a > 0 ? b : -b);
+
+ return Normalize(WidenMul(a, b));
+}
+
+TInt128 MulAndDivNormalMultiplier(TInt128 a, TInt128 b, TInt128 c) {
+ if (IsNan(a) || IsNan(c))
+ return Nan();
+
+ if (!c) {
+ if (a > 0)
+ return Inf();
+ else if (a < 0)
+ return -Inf();
+ else
+ return Nan();
+ } else if (IsInf(c)) {
+ return IsInf(a) ? Nan() : TInt128(0);
+ } else if (IsInf(a)) {
+ return c > 0 ? a : -a;
+ }
+
+ return Normalize(Div<true>(WidenMul(a, b), TInt256(c)));
+}
+
+TInt128 MulAndDivNormalDivider(TInt128 a, TInt128 b, TInt128 c) {
+ if (IsNan(a) || IsNan(b))
+ return Nan();
+
+ if (IsInf(a))
+ return !b ? Nan() : (b > 0 ? a : -a);
+
+ if (IsInf(b))
+ return !a ? Nan() : (a > 0 ? b : -b);
+
+ return Normalize(Div<false>(WidenMul(a, b), TInt256(c)));
+}
+
+}
+}
diff --git a/ydb/library/yql/public/decimal/yql_decimal.h b/ydb/library/yql/public/decimal/yql_decimal.h
index 48aec3397d..20695f0d84 100644
--- a/ydb/library/yql/public/decimal/yql_decimal.h
+++ b/ydb/library/yql/public/decimal/yql_decimal.h
@@ -1,91 +1,91 @@
-#pragma once
-
-#include <util/generic/strbuf.h>
-#include "yql_wide_int.h"
-
+#pragma once
+
+#include <util/generic/strbuf.h>
+#include "yql_wide_int.h"
+
#include <type_traits>
#include <limits>
-namespace NYql {
-namespace NDecimal {
-
-#ifdef _win_
-#ifndef DONT_USE_NATIVE_INT128
-#define DONT_USE_NATIVE_INT128
-#endif
-#endif
-
-#ifdef DONT_USE_NATIVE_INT128
-using TInt128 = TWide<i64>;
-using TUint128 = TWide<ui64>;
+namespace NYql {
+namespace NDecimal {
+
+#ifdef _win_
+#ifndef DONT_USE_NATIVE_INT128
+#define DONT_USE_NATIVE_INT128
+#endif
+#endif
+
+#ifdef DONT_USE_NATIVE_INT128
+using TInt128 = TWide<i64>;
+using TUint128 = TWide<ui64>;
#else
-using TInt128 = signed __int128;
-using TUint128 = unsigned __int128;
-#endif
-
-template<ui8 Scale> struct TDivider;
-#if defined(__clang__) && defined(DONT_USE_NATIVE_INT128)
-template<> struct TDivider<0> { static inline constexpr TUint128 Value = 1U; };
-template<ui8 Scale> struct TDivider { static inline constexpr TInt128 Value = TDivider<Scale - 1U>::Value * 10U; };
-#else
-template<> struct TDivider<0> { static constexpr TUint128 Value = 1U; };
-template<ui8 Scale> struct TDivider { static constexpr TUint128 Value = TDivider<Scale - 1U>::Value * 10U; };
+using TInt128 = signed __int128;
+using TUint128 = unsigned __int128;
#endif
-constexpr ui8 MaxPrecision = 35;
-
+template<ui8 Scale> struct TDivider;
+#if defined(__clang__) && defined(DONT_USE_NATIVE_INT128)
+template<> struct TDivider<0> { static inline constexpr TUint128 Value = 1U; };
+template<ui8 Scale> struct TDivider { static inline constexpr TInt128 Value = TDivider<Scale - 1U>::Value * 10U; };
+#else
+template<> struct TDivider<0> { static constexpr TUint128 Value = 1U; };
+template<ui8 Scale> struct TDivider { static constexpr TUint128 Value = TDivider<Scale - 1U>::Value * 10U; };
+#endif
+
+constexpr ui8 MaxPrecision = 35;
+
static_assert(sizeof(TInt128) == 16, "Wrong size of TInt128, expected 16");
-inline constexpr TInt128 Inf() {
- return TInt128(100000000000000000ULL) * TInt128(1000000000000000000ULL);
+inline constexpr TInt128 Inf() {
+ return TInt128(100000000000000000ULL) * TInt128(1000000000000000000ULL);
}
-
-inline constexpr TInt128 Nan() {
- return Inf() + TInt128(1);
+
+inline constexpr TInt128 Nan() {
+ return Inf() + TInt128(1);
}
-
+
inline constexpr TInt128 Err() {
return Nan() + TInt128(1);
}
-TUint128 GetDivider(ui8 scale);
-
-template<ui8 Precision>
-inline constexpr TUint128 GetDivider() {
- return TDivider<Precision>::Value;
-}
-
-template<ui8 Precision, bool IncLow = false, bool DecHigh = false>
-inline constexpr std::pair<TInt128, TInt128> GetBounds() {
- return std::make_pair(-GetDivider<Precision>() + (IncLow ? 1 : 0), +GetDivider<Precision>() - (DecHigh ? 1 : 0));
-}
-
-bool IsError(TInt128 v);
-bool IsNan(TInt128 v);
-bool IsInf(TInt128 v);
-
-bool IsNormal(TInt128 v);
-bool IsComparable(TInt128 v);
-
-template<ui8 Precision>
-inline bool IsNormal(TInt128 v) {
- const auto& b = GetBounds<Precision>();
- return v > b.first && v < b.second;
-}
-
+TUint128 GetDivider(ui8 scale);
+
+template<ui8 Precision>
+inline constexpr TUint128 GetDivider() {
+ return TDivider<Precision>::Value;
+}
+
+template<ui8 Precision, bool IncLow = false, bool DecHigh = false>
+inline constexpr std::pair<TInt128, TInt128> GetBounds() {
+ return std::make_pair(-GetDivider<Precision>() + (IncLow ? 1 : 0), +GetDivider<Precision>() - (DecHigh ? 1 : 0));
+}
+
+bool IsError(TInt128 v);
+bool IsNan(TInt128 v);
+bool IsInf(TInt128 v);
+
+bool IsNormal(TInt128 v);
+bool IsComparable(TInt128 v);
+
+template<ui8 Precision>
+inline bool IsNormal(TInt128 v) {
+ const auto& b = GetBounds<Precision>();
+ return v > b.first && v < b.second;
+}
+
const char* ToString(TInt128 v, ui8 precision, ui8 scale = 0);
TInt128 FromString(const TStringBuf& str, ui8 precision, ui8 scale = 0);
-// Accept string representation with exponent.
-TInt128 FromStringEx(const TStringBuf& str, ui8 precision, ui8 scale);
-
+// Accept string representation with exponent.
+TInt128 FromStringEx(const TStringBuf& str, ui8 precision, ui8 scale);
+
template<typename TMkqlProto>
inline TInt128 FromProto(const TMkqlProto& val) {
ui64 half[2] = {val.GetLow128(), val.GetHi128()};
TInt128 val128;
std::memcpy(&val128, half, sizeof(val128));
return val128;
-}
+}
template<typename TValue>
inline constexpr TValue YtDecimalNan() {
@@ -136,24 +136,24 @@ inline TInt128 FromHalfs(ui64 lo, i64 hi) {
return val128;
}
-inline std::pair<ui64, ui64> MakePair(const TInt128 v) {
- std::pair<ui64, ui64> r;
- std::memcpy(&r, &v, sizeof(v));
- return r;
- static_assert(sizeof(r) == sizeof(v), "Bad pair size.");
-}
-
-bool IsValid(const TStringBuf& str);
-
-// Round to nearest, ties to even.
-TInt128 Div(TInt128 a, TInt128 b); // a/b
-TInt128 Mul(TInt128 a, TInt128 b); // a*b
-TInt128 Mod(TInt128 a, TInt128 b); // a%b
-
-// a*b/c Only for non zero even normal positive divider.
-TInt128 MulAndDivNormalDivider(TInt128 a, TInt128 b, TInt128 c);
-// a*b/c Only for non zero normal positive multiplier.
-TInt128 MulAndDivNormalMultiplier(TInt128 a, TInt128 b, TInt128 c);
-
-}
-}
+inline std::pair<ui64, ui64> MakePair(const TInt128 v) {
+ std::pair<ui64, ui64> r;
+ std::memcpy(&r, &v, sizeof(v));
+ return r;
+ static_assert(sizeof(r) == sizeof(v), "Bad pair size.");
+}
+
+bool IsValid(const TStringBuf& str);
+
+// Round to nearest, ties to even.
+TInt128 Div(TInt128 a, TInt128 b); // a/b
+TInt128 Mul(TInt128 a, TInt128 b); // a*b
+TInt128 Mod(TInt128 a, TInt128 b); // a%b
+
+// a*b/c Only for non zero even normal positive divider.
+TInt128 MulAndDivNormalDivider(TInt128 a, TInt128 b, TInt128 c);
+// a*b/c Only for non zero normal positive multiplier.
+TInt128 MulAndDivNormalMultiplier(TInt128 a, TInt128 b, TInt128 c);
+
+}
+}
diff --git a/ydb/library/yql/public/decimal/yql_wide_int.h b/ydb/library/yql/public/decimal/yql_wide_int.h
index cea04b273e..0f650213b9 100644
--- a/ydb/library/yql/public/decimal/yql_wide_int.h
+++ b/ydb/library/yql/public/decimal/yql_wide_int.h
@@ -1,344 +1,344 @@
-#pragma once
-
-#include <util/system/types.h>
-
-#include <type_traits>
-#include <tuple>
-#include <cmath>
-
-namespace NYql {
-
-#ifndef _win_
-typedef __int128 i128_t;
-typedef unsigned __int128 ui128_t;
-#endif
-
-template<typename TOneHalf, typename TSignedPart = std::make_signed_t<TOneHalf>, typename TUnsignedPart = std::make_unsigned_t<TOneHalf>>
-class TWide {
-private:
- using THalf = TOneHalf;
- using TPart = TUnsignedPart;
-
- using TIsSigned = std::is_same<THalf, TSignedPart>;
- using TIsUnsigned = std::is_same<THalf, TUnsignedPart>;
-
- static_assert(TIsSigned::value || TIsUnsigned::value, "Invalid using of TWide.");
- static_assert(sizeof(TSignedPart) == sizeof(TUnsignedPart), "Different sizes of TWide parts.");
-
- TPart Lo;
- THalf Hi;
-
- static constexpr auto FullBitSize = sizeof(TPart) << 4U;
- static constexpr auto PartBitSize = sizeof(TPart) << 3U;
- static constexpr auto QuarterBitSize = sizeof(TPart) << 2U;
-
- static constexpr TPart GetUpperQuarter(TPart h) {
- return h >> QuarterBitSize;
- }
-
- static constexpr TPart GetLowerQuarter(TPart h) {
- const auto mask = TPart(~TPart(0U)) >> QuarterBitSize;
- return h & mask;
- }
-
- template<typename T>
- constexpr std::enable_if_t<sizeof(T) <= sizeof(THalf), T> CastImpl() const {
- return static_cast<T>(Lo);
- }
-
- template<typename T>
- constexpr std::enable_if_t<sizeof(T) == sizeof(THalf) << 1U, T> CastImpl() const {
- return *reinterpret_cast<const T*>(this);
- }
-
- template<typename T>
- constexpr std::enable_if_t<sizeof(THalf) << 1U < sizeof(T), T> CastImpl() const {
- return (T(std::make_unsigned_t<T>(Hi) << PartBitSize)) | Lo;
- }
-
- constexpr size_t GetBits() const {
- size_t out = Hi ? PartBitSize : 0U;
- for (auto up = TPart(out ? Hi : Lo); up; up >>= 1U) {
- ++out;
- }
- return out;
- }
-
- using TUnsigned = TWide<TUnsignedPart, TSignedPart, TUnsignedPart>;
-
- using TSibling = std::conditional_t<std::is_same<THalf, TPart>::value,
- TWide<TSignedPart, TSignedPart, TUnsignedPart>, TWide<TUnsignedPart, TSignedPart, TUnsignedPart>>;
- friend TSibling;
-public:
- constexpr TWide() = default;
- constexpr TWide(const TWide& rhs) = default;
- constexpr TWide(TWide&& rhs) = default;
-
- constexpr TWide& operator=(const TWide& rhs) = default;
- constexpr TWide& operator=(TWide&& rhs) = default;
-
- constexpr TWide(const TSibling& rhs)
- : Lo(rhs.Lo), Hi(rhs.Hi)
- {}
-
- template<typename U, typename L>
- constexpr TWide(const U upper_rhs, const L lower_rhs)
- : Lo(lower_rhs), Hi(upper_rhs)
- {}
-
- template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(THalf) < sizeof(T), size_t> Shift = PartBitSize>
- constexpr TWide(const T rhs)
- : Lo(rhs), Hi(rhs >> Shift)
- {}
-
- template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= sizeof(THalf), bool> Signed = std::is_signed<T>::value>
- constexpr TWide(const T rhs)
- : Lo(rhs), Hi(Signed && rhs < 0 ? ~0 : 0)
- {}
-
- template <typename T, typename TArg = std::enable_if_t<std::is_class<T>::value && std::is_same<T, THalf>::value, THalf>>
- constexpr explicit TWide(const T& rhs)
- : Lo(rhs), Hi(TIsSigned::value && rhs < 0 ? ~0 : 0)
- {}
-
- template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(THalf) < sizeof(T), size_t> Shift = PartBitSize>
- constexpr TWide& operator=(const T rhs) {
- Hi = rhs >> Shift;
- Lo = rhs;
- return *this;
- }
-
- template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= sizeof(THalf), bool> Signed = std::is_signed<T>::value>
- constexpr TWide& operator=(const T rhs) {
- Hi = Signed && rhs < 0 ? ~0 : 0;
- Lo = rhs;
- return *this;
- }
-
- constexpr explicit operator bool() const { return bool(Hi) || bool(Lo); }
-
- constexpr explicit operator i8() const { return CastImpl<i8>(); }
- constexpr explicit operator ui8() const { return CastImpl<ui8>(); }
- constexpr explicit operator i16() const { return CastImpl<i16>(); }
- constexpr explicit operator ui16() const { return CastImpl<ui16>(); }
- constexpr explicit operator i32() const { return CastImpl<i32>(); }
- constexpr explicit operator ui32() const { return CastImpl<ui32>(); }
- constexpr explicit operator i64() const { return CastImpl<i64>(); }
- constexpr explicit operator ui64() const { return CastImpl<ui64>(); }
-#ifndef _win_
- constexpr explicit operator i128_t() const { return CastImpl<i128_t>(); }
- constexpr explicit operator ui128_t() const { return CastImpl<ui128_t>(); }
-#endif
- constexpr explicit operator float() const {
- return TIsSigned::value && Hi < 0 ? -float(-*this) : std::fma(float(Hi), std::exp2(float(PartBitSize)), float(Lo));
- }
-
- constexpr explicit operator double() const {
- return TIsSigned::value && Hi < 0 ? -double(-*this) : std::fma(double(Hi), std::exp2(double(PartBitSize)), double(Lo));
- }
-
- constexpr TWide operator~() const {
- return TWide(~Hi, ~Lo);
- }
-
- constexpr TWide operator+() const {
- return TWide(Hi, Lo);
- }
-
- constexpr TWide operator-() const {
- const auto sign = THalf(1) << PartBitSize - 1U;
- if (TIsSigned::value && !Lo && Hi == sign)
- return *this;
- return ++~*this;
- }
-
- constexpr TWide& operator++() {
- if (!++Lo) ++Hi;
- return *this;
- }
-
- constexpr TWide& operator--() {
- if (!Lo--) --Hi;
- return *this;
- }
-
- constexpr TWide operator++(int) {
- const TWide r(*this);
- ++*this;
- return r;
- }
-
- constexpr TWide operator--(int) {
- const TWide r(*this);
- --*this;
- return r;
- }
-
- constexpr TWide& operator&=(const TWide& rhs) {
- Hi &= rhs.Hi;
- Lo &= rhs.Lo;
- return *this;
- }
-
- constexpr TWide& operator|=(const TWide& rhs) {
- Hi |= rhs.Hi;
- Lo |= rhs.Lo;
- return *this;
- }
-
- constexpr TWide& operator^=(const TWide& rhs) {
- Hi ^= rhs.Hi;
- Lo ^= rhs.Lo;
- return *this;
- }
-
- constexpr TWide& operator+=(const TWide& rhs) {
- const auto l = Lo;
- Lo += rhs.Lo;
- Hi += rhs.Hi;
- if (l > Lo) ++Hi;
- return *this;
- }
-
- constexpr TWide& operator-=(const TWide& rhs) {
- const auto l = Lo;
- Lo -= rhs.Lo;
- Hi -= rhs.Hi;
- if (l < Lo) --Hi;
- return *this;
- }
-
- constexpr TWide& operator<<=(const TWide& rhs) {
- if (const auto shift = size_t(rhs.Lo) % FullBitSize) {
- if (shift < PartBitSize) {
- Hi = TPart(Hi) << shift;
+#pragma once
+
+#include <util/system/types.h>
+
+#include <type_traits>
+#include <tuple>
+#include <cmath>
+
+namespace NYql {
+
+#ifndef _win_
+typedef __int128 i128_t;
+typedef unsigned __int128 ui128_t;
+#endif
+
+template<typename TOneHalf, typename TSignedPart = std::make_signed_t<TOneHalf>, typename TUnsignedPart = std::make_unsigned_t<TOneHalf>>
+class TWide {
+private:
+ using THalf = TOneHalf;
+ using TPart = TUnsignedPart;
+
+ using TIsSigned = std::is_same<THalf, TSignedPart>;
+ using TIsUnsigned = std::is_same<THalf, TUnsignedPart>;
+
+ static_assert(TIsSigned::value || TIsUnsigned::value, "Invalid using of TWide.");
+ static_assert(sizeof(TSignedPart) == sizeof(TUnsignedPart), "Different sizes of TWide parts.");
+
+ TPart Lo;
+ THalf Hi;
+
+ static constexpr auto FullBitSize = sizeof(TPart) << 4U;
+ static constexpr auto PartBitSize = sizeof(TPart) << 3U;
+ static constexpr auto QuarterBitSize = sizeof(TPart) << 2U;
+
+ static constexpr TPart GetUpperQuarter(TPart h) {
+ return h >> QuarterBitSize;
+ }
+
+ static constexpr TPart GetLowerQuarter(TPart h) {
+ const auto mask = TPart(~TPart(0U)) >> QuarterBitSize;
+ return h & mask;
+ }
+
+ template<typename T>
+ constexpr std::enable_if_t<sizeof(T) <= sizeof(THalf), T> CastImpl() const {
+ return static_cast<T>(Lo);
+ }
+
+ template<typename T>
+ constexpr std::enable_if_t<sizeof(T) == sizeof(THalf) << 1U, T> CastImpl() const {
+ return *reinterpret_cast<const T*>(this);
+ }
+
+ template<typename T>
+ constexpr std::enable_if_t<sizeof(THalf) << 1U < sizeof(T), T> CastImpl() const {
+ return (T(std::make_unsigned_t<T>(Hi) << PartBitSize)) | Lo;
+ }
+
+ constexpr size_t GetBits() const {
+ size_t out = Hi ? PartBitSize : 0U;
+ for (auto up = TPart(out ? Hi : Lo); up; up >>= 1U) {
+ ++out;
+ }
+ return out;
+ }
+
+ using TUnsigned = TWide<TUnsignedPart, TSignedPart, TUnsignedPart>;
+
+ using TSibling = std::conditional_t<std::is_same<THalf, TPart>::value,
+ TWide<TSignedPart, TSignedPart, TUnsignedPart>, TWide<TUnsignedPart, TSignedPart, TUnsignedPart>>;
+ friend TSibling;
+public:
+ constexpr TWide() = default;
+ constexpr TWide(const TWide& rhs) = default;
+ constexpr TWide(TWide&& rhs) = default;
+
+ constexpr TWide& operator=(const TWide& rhs) = default;
+ constexpr TWide& operator=(TWide&& rhs) = default;
+
+ constexpr TWide(const TSibling& rhs)
+ : Lo(rhs.Lo), Hi(rhs.Hi)
+ {}
+
+ template<typename U, typename L>
+ constexpr TWide(const U upper_rhs, const L lower_rhs)
+ : Lo(lower_rhs), Hi(upper_rhs)
+ {}
+
+ template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(THalf) < sizeof(T), size_t> Shift = PartBitSize>
+ constexpr TWide(const T rhs)
+ : Lo(rhs), Hi(rhs >> Shift)
+ {}
+
+ template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= sizeof(THalf), bool> Signed = std::is_signed<T>::value>
+ constexpr TWide(const T rhs)
+ : Lo(rhs), Hi(Signed && rhs < 0 ? ~0 : 0)
+ {}
+
+ template <typename T, typename TArg = std::enable_if_t<std::is_class<T>::value && std::is_same<T, THalf>::value, THalf>>
+ constexpr explicit TWide(const T& rhs)
+ : Lo(rhs), Hi(TIsSigned::value && rhs < 0 ? ~0 : 0)
+ {}
+
+ template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(THalf) < sizeof(T), size_t> Shift = PartBitSize>
+ constexpr TWide& operator=(const T rhs) {
+ Hi = rhs >> Shift;
+ Lo = rhs;
+ return *this;
+ }
+
+ template <typename T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= sizeof(THalf), bool> Signed = std::is_signed<T>::value>
+ constexpr TWide& operator=(const T rhs) {
+ Hi = Signed && rhs < 0 ? ~0 : 0;
+ Lo = rhs;
+ return *this;
+ }
+
+ constexpr explicit operator bool() const { return bool(Hi) || bool(Lo); }
+
+ constexpr explicit operator i8() const { return CastImpl<i8>(); }
+ constexpr explicit operator ui8() const { return CastImpl<ui8>(); }
+ constexpr explicit operator i16() const { return CastImpl<i16>(); }
+ constexpr explicit operator ui16() const { return CastImpl<ui16>(); }
+ constexpr explicit operator i32() const { return CastImpl<i32>(); }
+ constexpr explicit operator ui32() const { return CastImpl<ui32>(); }
+ constexpr explicit operator i64() const { return CastImpl<i64>(); }
+ constexpr explicit operator ui64() const { return CastImpl<ui64>(); }
+#ifndef _win_
+ constexpr explicit operator i128_t() const { return CastImpl<i128_t>(); }
+ constexpr explicit operator ui128_t() const { return CastImpl<ui128_t>(); }
+#endif
+ constexpr explicit operator float() const {
+ return TIsSigned::value && Hi < 0 ? -float(-*this) : std::fma(float(Hi), std::exp2(float(PartBitSize)), float(Lo));
+ }
+
+ constexpr explicit operator double() const {
+ return TIsSigned::value && Hi < 0 ? -double(-*this) : std::fma(double(Hi), std::exp2(double(PartBitSize)), double(Lo));
+ }
+
+ constexpr TWide operator~() const {
+ return TWide(~Hi, ~Lo);
+ }
+
+ constexpr TWide operator+() const {
+ return TWide(Hi, Lo);
+ }
+
+ constexpr TWide operator-() const {
+ const auto sign = THalf(1) << PartBitSize - 1U;
+ if (TIsSigned::value && !Lo && Hi == sign)
+ return *this;
+ return ++~*this;
+ }
+
+ constexpr TWide& operator++() {
+ if (!++Lo) ++Hi;
+ return *this;
+ }
+
+ constexpr TWide& operator--() {
+ if (!Lo--) --Hi;
+ return *this;
+ }
+
+ constexpr TWide operator++(int) {
+ const TWide r(*this);
+ ++*this;
+ return r;
+ }
+
+ constexpr TWide operator--(int) {
+ const TWide r(*this);
+ --*this;
+ return r;
+ }
+
+ constexpr TWide& operator&=(const TWide& rhs) {
+ Hi &= rhs.Hi;
+ Lo &= rhs.Lo;
+ return *this;
+ }
+
+ constexpr TWide& operator|=(const TWide& rhs) {
+ Hi |= rhs.Hi;
+ Lo |= rhs.Lo;
+ return *this;
+ }
+
+ constexpr TWide& operator^=(const TWide& rhs) {
+ Hi ^= rhs.Hi;
+ Lo ^= rhs.Lo;
+ return *this;
+ }
+
+ constexpr TWide& operator+=(const TWide& rhs) {
+ const auto l = Lo;
+ Lo += rhs.Lo;
+ Hi += rhs.Hi;
+ if (l > Lo) ++Hi;
+ return *this;
+ }
+
+ constexpr TWide& operator-=(const TWide& rhs) {
+ const auto l = Lo;
+ Lo -= rhs.Lo;
+ Hi -= rhs.Hi;
+ if (l < Lo) --Hi;
+ return *this;
+ }
+
+ constexpr TWide& operator<<=(const TWide& rhs) {
+ if (const auto shift = size_t(rhs.Lo) % FullBitSize) {
+ if (shift < PartBitSize) {
+ Hi = TPart(Hi) << shift;
Hi |= Lo >> (PartBitSize - shift);
- Lo <<= shift;
- } else {
+ Lo <<= shift;
+ } else {
Hi = Lo << (shift - PartBitSize);
- Lo = 0;
- }
- }
-
- return *this;
- }
-
- constexpr TWide& operator>>=(const TWide& rhs) {
- if (const auto shift = size_t(rhs.Lo) % FullBitSize) {
- if (shift < PartBitSize) {
- Lo >>= shift;
+ Lo = 0;
+ }
+ }
+
+ return *this;
+ }
+
+ constexpr TWide& operator>>=(const TWide& rhs) {
+ if (const auto shift = size_t(rhs.Lo) % FullBitSize) {
+ if (shift < PartBitSize) {
+ Lo >>= shift;
Lo |= TPart(Hi) << (PartBitSize - shift);
- Hi >>= shift;
- } else {
+ Hi >>= shift;
+ } else {
Lo = Hi >> (shift - PartBitSize);
- Hi = TIsSigned::value && Hi < 0 ? ~0 : 0;
- }
- }
-
- return *this;
- }
-
- constexpr TWide& operator*=(const TWide& rhs) { return *this = Mul(*this, rhs); }
- constexpr TWide& operator/=(const TWide& rhs) { return *this = DivMod(*this, rhs).first; }
- constexpr TWide& operator%=(const TWide& rhs) { return *this = DivMod(*this, rhs).second; }
-
- constexpr TWide operator&(const TWide& rhs) const { return TWide(*this) &= rhs; }
- constexpr TWide operator|(const TWide& rhs) const { return TWide(*this) |= rhs; }
- constexpr TWide operator^(const TWide& rhs) const { return TWide(*this) ^= rhs; }
- constexpr TWide operator+(const TWide& rhs) const { return TWide(*this) += rhs; }
- constexpr TWide operator-(const TWide& rhs) const { return TWide(*this) -= rhs; }
- constexpr TWide operator*(const TWide& rhs) const { return Mul(*this, rhs); }
- constexpr TWide operator/(const TWide& rhs) const { return DivMod(*this, rhs).first; }
- constexpr TWide operator%(const TWide& rhs) const { return DivMod(*this, rhs).second; }
- constexpr TWide operator<<(const TWide& rhs) const { return TWide(*this) <<= rhs; }
- constexpr TWide operator>>(const TWide& rhs) const { return TWide(*this) >>= rhs; }
-
- template <typename T>
- constexpr std::enable_if_t<std::is_integral<T>::value, T> operator&(const T rhs) const { return T(*this) & rhs; }
-
- constexpr bool operator==(const TWide& rhs) const { return std::tie(Hi, Lo) == std::tie(rhs.Hi, rhs.Lo); }
- constexpr bool operator!=(const TWide& rhs) const { return std::tie(Hi, Lo) != std::tie(rhs.Hi, rhs.Lo); }
- constexpr bool operator>=(const TWide& rhs) const { return std::tie(Hi, Lo) >= std::tie(rhs.Hi, rhs.Lo); }
- constexpr bool operator<=(const TWide& rhs) const { return std::tie(Hi, Lo) <= std::tie(rhs.Hi, rhs.Lo); }
- constexpr bool operator>(const TWide& rhs) const { return std::tie(Hi, Lo) > std::tie(rhs.Hi, rhs.Lo); }
- constexpr bool operator<(const TWide& rhs) const { return std::tie(Hi, Lo) < std::tie(rhs.Hi, rhs.Lo); }
-
-private:
- static constexpr TWide Mul(const TWide& lhs, const TWide& rhs) {
- const TPart lq[] = {GetLowerQuarter(lhs.Lo), GetUpperQuarter(lhs.Lo), GetLowerQuarter(lhs.Hi), GetUpperQuarter(lhs.Hi)};
- const TPart rq[] = {GetLowerQuarter(rhs.Lo), GetUpperQuarter(rhs.Lo), GetLowerQuarter(rhs.Hi), GetUpperQuarter(rhs.Hi)};
-
- const TPart prod0[] = {TPart(lq[0] * rq[0])};
- const TPart prod1[] = {TPart(lq[0] * rq[1]), TPart(lq[1] * rq[0])};
- const TPart prod2[] = {TPart(lq[0] * rq[2]), TPart(lq[1] * rq[1]), TPart(lq[2] * rq[0])};
- const TPart prod3[] = {TPart(lq[0] * rq[3]), TPart(lq[1] * rq[2]), TPart(lq[2] * rq[1]), TPart(lq[3] * rq[0])};
-
- const TPart fourthQ = GetLowerQuarter(prod0[0]);
- const TPart thirdQ = GetUpperQuarter(prod0[0])
- + GetLowerQuarter(prod1[0]) + GetLowerQuarter(prod1[1]);
- const TPart secondQ = GetUpperQuarter(thirdQ)
- + GetUpperQuarter(prod1[0]) + GetUpperQuarter(prod1[1])
- + GetLowerQuarter(prod2[0]) + GetLowerQuarter(prod2[1]) + GetLowerQuarter(prod2[2]);
- const TPart firstQ = GetUpperQuarter(secondQ)
- + GetUpperQuarter(prod2[0]) + GetUpperQuarter(prod2[1]) + GetUpperQuarter(prod2[2])
- + GetLowerQuarter(prod3[0]) + GetLowerQuarter(prod3[1]) + GetLowerQuarter(prod3[2]) + GetLowerQuarter(prod3[3]);
-
- return TWide((firstQ << QuarterBitSize) | GetLowerQuarter(secondQ), (thirdQ << QuarterBitSize) | fourthQ);
- }
-
- static constexpr std::pair<TWide, TWide> DivMod(const TWide& lhs, const TWide& rhs) {
- const bool nl = TIsSigned::value && lhs.Hi < 0;
- const bool nr = TIsSigned::value && rhs.Hi < 0;
-
- const TUnsigned l = nl ? -lhs : +lhs, r = nr ? -rhs : +rhs;
-
- TUnsigned div = 0, mod = 0;
-
- for (auto x = l.GetBits(); x;) {
- mod <<= 1;
- div <<= 1;
-
- if (--x < PartBitSize ? l.Lo & (TPart(1U) << x) : l.Hi & (TPart(1U) << x - PartBitSize)) {
- ++mod;
- }
-
- if (mod >= r) {
- mod -= r;
- ++div;
- }
- }
-
- if (nl) mod = -mod;
- if (nr != nl) div = -div;
-
- return {div, mod};
- }
-};
-
-template<typename T> struct THalfOf;
-template<> struct THalfOf<i16> { typedef i8 Type; };
-template<> struct THalfOf<ui16> { typedef ui8 Type; };
-template<> struct THalfOf<i32> { typedef i16 Type; };
-template<> struct THalfOf<ui32> { typedef ui16 Type; };
-template<> struct THalfOf<i64> { typedef i32 Type; };
-template<> struct THalfOf<ui64> { typedef ui32 Type; };
-#ifndef _win_
-template<> struct THalfOf<i128_t> { typedef i64 Type; };
-template<> struct THalfOf<ui128_t> { typedef ui64 Type; };
-#endif
-template<typename T> struct THalfOf {};
-
-template<typename T> struct TPairOf;
-template<> struct TPairOf<i8> { typedef i16 Type; };
-template<> struct TPairOf<ui8> { typedef ui16 Type; };
-template<> struct TPairOf<i16> { typedef i32 Type; };
-template<> struct TPairOf<ui16> { typedef ui32 Type; };
-template<> struct TPairOf<i32> { typedef i64 Type; };
-template<> struct TPairOf<ui32> { typedef ui64 Type; };
-#ifndef _win_
-template<> struct TPairOf<i64> { typedef i128_t Type; };
-template<> struct TPairOf<ui64> { typedef ui128_t Type; };
-#endif
-template<typename T> struct TPairOf {};
-
-}
+ Hi = TIsSigned::value && Hi < 0 ? ~0 : 0;
+ }
+ }
+
+ return *this;
+ }
+
+ constexpr TWide& operator*=(const TWide& rhs) { return *this = Mul(*this, rhs); }
+ constexpr TWide& operator/=(const TWide& rhs) { return *this = DivMod(*this, rhs).first; }
+ constexpr TWide& operator%=(const TWide& rhs) { return *this = DivMod(*this, rhs).second; }
+
+ constexpr TWide operator&(const TWide& rhs) const { return TWide(*this) &= rhs; }
+ constexpr TWide operator|(const TWide& rhs) const { return TWide(*this) |= rhs; }
+ constexpr TWide operator^(const TWide& rhs) const { return TWide(*this) ^= rhs; }
+ constexpr TWide operator+(const TWide& rhs) const { return TWide(*this) += rhs; }
+ constexpr TWide operator-(const TWide& rhs) const { return TWide(*this) -= rhs; }
+ constexpr TWide operator*(const TWide& rhs) const { return Mul(*this, rhs); }
+ constexpr TWide operator/(const TWide& rhs) const { return DivMod(*this, rhs).first; }
+ constexpr TWide operator%(const TWide& rhs) const { return DivMod(*this, rhs).second; }
+ constexpr TWide operator<<(const TWide& rhs) const { return TWide(*this) <<= rhs; }
+ constexpr TWide operator>>(const TWide& rhs) const { return TWide(*this) >>= rhs; }
+
+ template <typename T>
+ constexpr std::enable_if_t<std::is_integral<T>::value, T> operator&(const T rhs) const { return T(*this) & rhs; }
+
+ constexpr bool operator==(const TWide& rhs) const { return std::tie(Hi, Lo) == std::tie(rhs.Hi, rhs.Lo); }
+ constexpr bool operator!=(const TWide& rhs) const { return std::tie(Hi, Lo) != std::tie(rhs.Hi, rhs.Lo); }
+ constexpr bool operator>=(const TWide& rhs) const { return std::tie(Hi, Lo) >= std::tie(rhs.Hi, rhs.Lo); }
+ constexpr bool operator<=(const TWide& rhs) const { return std::tie(Hi, Lo) <= std::tie(rhs.Hi, rhs.Lo); }
+ constexpr bool operator>(const TWide& rhs) const { return std::tie(Hi, Lo) > std::tie(rhs.Hi, rhs.Lo); }
+ constexpr bool operator<(const TWide& rhs) const { return std::tie(Hi, Lo) < std::tie(rhs.Hi, rhs.Lo); }
+
+private:
+ static constexpr TWide Mul(const TWide& lhs, const TWide& rhs) {
+ const TPart lq[] = {GetLowerQuarter(lhs.Lo), GetUpperQuarter(lhs.Lo), GetLowerQuarter(lhs.Hi), GetUpperQuarter(lhs.Hi)};
+ const TPart rq[] = {GetLowerQuarter(rhs.Lo), GetUpperQuarter(rhs.Lo), GetLowerQuarter(rhs.Hi), GetUpperQuarter(rhs.Hi)};
+
+ const TPart prod0[] = {TPart(lq[0] * rq[0])};
+ const TPart prod1[] = {TPart(lq[0] * rq[1]), TPart(lq[1] * rq[0])};
+ const TPart prod2[] = {TPart(lq[0] * rq[2]), TPart(lq[1] * rq[1]), TPart(lq[2] * rq[0])};
+ const TPart prod3[] = {TPart(lq[0] * rq[3]), TPart(lq[1] * rq[2]), TPart(lq[2] * rq[1]), TPart(lq[3] * rq[0])};
+
+ const TPart fourthQ = GetLowerQuarter(prod0[0]);
+ const TPart thirdQ = GetUpperQuarter(prod0[0])
+ + GetLowerQuarter(prod1[0]) + GetLowerQuarter(prod1[1]);
+ const TPart secondQ = GetUpperQuarter(thirdQ)
+ + GetUpperQuarter(prod1[0]) + GetUpperQuarter(prod1[1])
+ + GetLowerQuarter(prod2[0]) + GetLowerQuarter(prod2[1]) + GetLowerQuarter(prod2[2]);
+ const TPart firstQ = GetUpperQuarter(secondQ)
+ + GetUpperQuarter(prod2[0]) + GetUpperQuarter(prod2[1]) + GetUpperQuarter(prod2[2])
+ + GetLowerQuarter(prod3[0]) + GetLowerQuarter(prod3[1]) + GetLowerQuarter(prod3[2]) + GetLowerQuarter(prod3[3]);
+
+ return TWide((firstQ << QuarterBitSize) | GetLowerQuarter(secondQ), (thirdQ << QuarterBitSize) | fourthQ);
+ }
+
+ static constexpr std::pair<TWide, TWide> DivMod(const TWide& lhs, const TWide& rhs) {
+ const bool nl = TIsSigned::value && lhs.Hi < 0;
+ const bool nr = TIsSigned::value && rhs.Hi < 0;
+
+ const TUnsigned l = nl ? -lhs : +lhs, r = nr ? -rhs : +rhs;
+
+ TUnsigned div = 0, mod = 0;
+
+ for (auto x = l.GetBits(); x;) {
+ mod <<= 1;
+ div <<= 1;
+
+ if (--x < PartBitSize ? l.Lo & (TPart(1U) << x) : l.Hi & (TPart(1U) << x - PartBitSize)) {
+ ++mod;
+ }
+
+ if (mod >= r) {
+ mod -= r;
+ ++div;
+ }
+ }
+
+ if (nl) mod = -mod;
+ if (nr != nl) div = -div;
+
+ return {div, mod};
+ }
+};
+
+template<typename T> struct THalfOf;
+template<> struct THalfOf<i16> { typedef i8 Type; };
+template<> struct THalfOf<ui16> { typedef ui8 Type; };
+template<> struct THalfOf<i32> { typedef i16 Type; };
+template<> struct THalfOf<ui32> { typedef ui16 Type; };
+template<> struct THalfOf<i64> { typedef i32 Type; };
+template<> struct THalfOf<ui64> { typedef ui32 Type; };
+#ifndef _win_
+template<> struct THalfOf<i128_t> { typedef i64 Type; };
+template<> struct THalfOf<ui128_t> { typedef ui64 Type; };
+#endif
+template<typename T> struct THalfOf {};
+
+template<typename T> struct TPairOf;
+template<> struct TPairOf<i8> { typedef i16 Type; };
+template<> struct TPairOf<ui8> { typedef ui16 Type; };
+template<> struct TPairOf<i16> { typedef i32 Type; };
+template<> struct TPairOf<ui16> { typedef ui32 Type; };
+template<> struct TPairOf<i32> { typedef i64 Type; };
+template<> struct TPairOf<ui32> { typedef ui64 Type; };
+#ifndef _win_
+template<> struct TPairOf<i64> { typedef i128_t Type; };
+template<> struct TPairOf<ui64> { typedef ui128_t Type; };
+#endif
+template<typename T> struct TPairOf {};
+
+}
diff --git a/ydb/library/yql/public/udf/service/exception_policy/udf_service.cpp b/ydb/library/yql/public/udf/service/exception_policy/udf_service.cpp
index 92411966f3..ff3c42d2ae 100644
--- a/ydb/library/yql/public/udf/service/exception_policy/udf_service.cpp
+++ b/ydb/library/yql/public/udf/service/exception_policy/udf_service.cpp
@@ -1,31 +1,31 @@
#include <ydb/library/yql/public/udf/udf_value.h>
#include <ydb/library/yql/minikql/mkql_alloc.h>
#include <ydb/library/yql/minikql/mkql_terminator.h>
-
-extern "C" void* UdfAllocate(ui64 size) {
+
+extern "C" void* UdfAllocate(ui64 size) {
return ::NKikimr::NMiniKQL::MKQLAllocDeprecated(size);
-}
-
-extern "C" void UdfFree(const void* mem) {
+}
+
+extern "C" void UdfFree(const void* mem) {
return ::NKikimr::NMiniKQL::MKQLFreeDeprecated(mem);
-}
-
+}
+
extern "C" [[noreturn]] void UdfTerminate(const char* message) {
- ::NKikimr::NMiniKQL::MKQLTerminate(message);
-}
-
-extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object) {
- return ::NKikimr::NMiniKQL::MKQLRegisterObject(object);
-}
-
-extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object) {
- return ::NKikimr::NMiniKQL::MKQLUnregisterObject(object);
-}
+ ::NKikimr::NMiniKQL::MKQLTerminate(message);
+}
+
+extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object) {
+ return ::NKikimr::NMiniKQL::MKQLRegisterObject(object);
+}
+
+extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object) {
+ return ::NKikimr::NMiniKQL::MKQLUnregisterObject(object);
+}
extern "C" void* UdfAllocateWithSize(ui64 size) {
return ::NKikimr::NMiniKQL::MKQLAllocWithSize(size);
}
-extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
+extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
return ::NKikimr::NMiniKQL::MKQLFreeWithSize(mem, size);
}
diff --git a/ydb/library/yql/public/udf/service/exception_policy/ya.make b/ydb/library/yql/public/udf/service/exception_policy/ya.make
index 8ff831621c..9d012075f0 100644
--- a/ydb/library/yql/public/udf/service/exception_policy/ya.make
+++ b/ydb/library/yql/public/udf/service/exception_policy/ya.make
@@ -1,17 +1,17 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
a-romanov
g:yql
g:yql_ydb_core
)
-
+
PROVIDES(YqlServicePolicy)
SRCS(
udf_service.cpp
)
-
+
PEERDIR(
ydb/library/yql/minikql
ydb/library/yql/public/udf
@@ -19,4 +19,4 @@ PEERDIR(
YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/library/yql/public/udf/service/stub/udf_service.cpp b/ydb/library/yql/public/udf/service/stub/udf_service.cpp
index 99787c2665..ec840f606c 100644
--- a/ydb/library/yql/public/udf/service/stub/udf_service.cpp
+++ b/ydb/library/yql/public/udf/service/stub/udf_service.cpp
@@ -1,10 +1,10 @@
-#include <util/system/yassert.h>
+#include <util/system/yassert.h>
#include <ydb/library/yql/public/udf/udf_value.h>
-
-extern "C" void* UdfAllocate(ui64) { Y_FAIL("Called UdfAllocate"); }
-extern "C" void UdfFree(const void*) { Y_FAIL("Called UdfFree"); }
-extern "C" void UdfTerminate(const char*) { Y_FAIL("Called UdfTerminate."); }
-extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue*) { Y_FAIL("Called UdfRegisterObject"); }
-extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue*) { Y_FAIL("Called UdfUnregisterObject"); }
+
+extern "C" void* UdfAllocate(ui64) { Y_FAIL("Called UdfAllocate"); }
+extern "C" void UdfFree(const void*) { Y_FAIL("Called UdfFree"); }
+extern "C" void UdfTerminate(const char*) { Y_FAIL("Called UdfTerminate."); }
+extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue*) { Y_FAIL("Called UdfRegisterObject"); }
+extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue*) { Y_FAIL("Called UdfUnregisterObject"); }
extern "C" void* UdfAllocateWithSize(ui64) { Y_FAIL("Called UdfAllocateWithSize"); }
-extern "C" void UdfFreeWithSize(const void*, ui64) { Y_FAIL("Called UdfFreeWithSize"); }
+extern "C" void UdfFreeWithSize(const void*, ui64) { Y_FAIL("Called UdfFreeWithSize"); }
diff --git a/ydb/library/yql/public/udf/service/stub/ya.make b/ydb/library/yql/public/udf/service/stub/ya.make
index 96609af752..02920bf5a1 100644
--- a/ydb/library/yql/public/udf/service/stub/ya.make
+++ b/ydb/library/yql/public/udf/service/stub/ya.make
@@ -1,20 +1,20 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
a-romanov
g:yql
)
-
+
PROVIDES(YqlServicePolicy)
SRCS(
udf_service.cpp
)
-
+
PEERDIR(
ydb/library/yql/public/udf
)
YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/library/yql/public/udf/service/terminate_policy/udf_service.cpp b/ydb/library/yql/public/udf/service/terminate_policy/udf_service.cpp
index c7526c3b6b..a16809b21f 100644
--- a/ydb/library/yql/public/udf/service/terminate_policy/udf_service.cpp
+++ b/ydb/library/yql/public/udf/service/terminate_policy/udf_service.cpp
@@ -1,27 +1,27 @@
#include <ydb/library/yql/public/udf/udf_value.h>
#include <ydb/library/yql/minikql/mkql_alloc.h>
#include <ydb/library/yql/minikql/mkql_terminator.h>
-
-extern "C" void* UdfAllocate(ui64 size) {
+
+extern "C" void* UdfAllocate(ui64 size) {
return ::NKikimr::NMiniKQL::MKQLAllocDeprecated(size);
-}
-
-extern "C" void UdfFree(const void* mem) {
+}
+
+extern "C" void UdfFree(const void* mem) {
return ::NKikimr::NMiniKQL::MKQLFreeDeprecated(mem);
-}
-
+}
+
extern "C" [[noreturn]] void UdfTerminate(const char* message) {
- ::NKikimr::NMiniKQL::MKQLTerminate(message);
-}
-
-extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue*) {}
-
-extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue*) {}
+ ::NKikimr::NMiniKQL::MKQLTerminate(message);
+}
+
+extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue*) {}
+
+extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue*) {}
extern "C" void* UdfAllocateWithSize(ui64 size) {
return ::NKikimr::NMiniKQL::MKQLAllocWithSize(size);
}
-extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
+extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
return ::NKikimr::NMiniKQL::MKQLFreeWithSize(mem, size);
}
diff --git a/ydb/library/yql/public/udf/service/terminate_policy/ya.make b/ydb/library/yql/public/udf/service/terminate_policy/ya.make
index b9fc2959b1..d583ca7195 100644
--- a/ydb/library/yql/public/udf/service/terminate_policy/ya.make
+++ b/ydb/library/yql/public/udf/service/terminate_policy/ya.make
@@ -1,16 +1,16 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
a-romanov
g:yql
)
-
+
PROVIDES(YqlServicePolicy)
SRCS(
udf_service.cpp
)
-
+
PEERDIR(
ydb/library/yql/minikql
ydb/library/yql/public/udf
@@ -18,4 +18,4 @@ PEERDIR(
YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/library/yql/public/udf/support/udf_support.cpp b/ydb/library/yql/public/udf/support/udf_support.cpp
index b32be621ee..d1e7adbc20 100644
--- a/ydb/library/yql/public/udf/support/udf_support.cpp
+++ b/ydb/library/yql/public/udf/support/udf_support.cpp
@@ -1,50 +1,50 @@
#define BUILD_UDF
#include <util/system/backtrace.h>
-#if defined(_win_) || defined(_darwin_)
+#if defined(_win_) || defined(_darwin_)
#include <ydb/library/yql/public/udf/udf_registrator.h>
#include <exception>
-static NYql::NUdf::TStaticSymbols Symbols;
+static NYql::NUdf::TStaticSymbols Symbols;
extern "C" void* UdfAllocate(ui64 size) {
return Symbols.UdfAllocateFunc(size);
}
-extern "C" void UdfFree(const void* mem) {
+extern "C" void UdfFree(const void* mem) {
return Symbols.UdfFreeFunc(mem);
}
extern "C" [[noreturn]] void UdfTerminate(const char* message) {
- Symbols.UdfTerminate(message);
+ Symbols.UdfTerminate(message);
std::terminate();
-}
-
-extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object) {
- return Symbols.UdfRegisterObject(object);
-}
-
-extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object) {
- return Symbols.UdfUnregisterObject(object);
-}
-
+}
+
+extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object) {
+ return Symbols.UdfRegisterObject(object);
+}
+
+extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object) {
+ return Symbols.UdfUnregisterObject(object);
+}
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
extern "C" void* UdfAllocateWithSize(ui64 size) {
return Symbols.UdfAllocateWithSizeFunc(size);
}
-extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
+extern "C" void UdfFreeWithSize(const void* mem, ui64 size) {
return Symbols.UdfFreeWithSizeFunc(mem, size);
}
#endif
-extern "C" void BindSymbols(const NYql::NUdf::TStaticSymbols& symbols) {
+extern "C" void BindSymbols(const NYql::NUdf::TStaticSymbols& symbols) {
Symbols = symbols;
}
#endif
-namespace NYql {
+namespace NYql {
namespace NUdf {
typedef void(*TBackTraceCallback)();
diff --git a/ydb/library/yql/public/udf/tz/gen/ya.make b/ydb/library/yql/public/udf/tz/gen/ya.make
index fcdf519e2d..7dcd21d710 100644
--- a/ydb/library/yql/public/udf/tz/gen/ya.make
+++ b/ydb/library/yql/public/udf/tz/gen/ya.make
@@ -1,5 +1,5 @@
-PY3_PROGRAM(tz_gen)
+PY3_PROGRAM(tz_gen)
OWNER(g:yql)
diff --git a/ydb/library/yql/public/udf/tz/udf_tz.cpp b/ydb/library/yql/public/udf/tz/udf_tz.cpp
index 522becb147..51c106c1ae 100644
--- a/ydb/library/yql/public/udf/tz/udf_tz.cpp
+++ b/ydb/library/yql/public/udf/tz/udf_tz.cpp
@@ -1,20 +1,20 @@
#include "udf_tz.h"
-namespace NYql {
+namespace NYql {
namespace NUdf {
-namespace {
-
-static constexpr std::initializer_list<const std::string_view> TimezonesInit = {
+namespace {
+
+static constexpr std::initializer_list<const std::string_view> TimezonesInit = {
#include "udf_tz.gen"
};
-static constexpr TArrayRef<const std::string_view> Timezones(TimezonesInit);
-
+static constexpr TArrayRef<const std::string_view> Timezones(TimezonesInit);
+
+}
+
+TArrayRef<const std::string_view> GetTimezones() {
+ return Timezones;
}
-
-TArrayRef<const std::string_view> GetTimezones() {
- return Timezones;
}
}
-}
diff --git a/ydb/library/yql/public/udf/tz/udf_tz.gen b/ydb/library/yql/public/udf/tz/udf_tz.gen
index 7271a9cdfe..e45ebf4f33 100644
--- a/ydb/library/yql/public/udf/tz/udf_tz.gen
+++ b/ydb/library/yql/public/udf/tz/udf_tz.gen
@@ -1,597 +1,597 @@
-"GMT",
-"Europe/Moscow",
-"Africa/Abidjan",
-"Africa/Accra",
-"Africa/Addis_Ababa",
-"Africa/Algiers",
-"Africa/Asmara",
-"Africa/Asmera",
-"Africa/Bamako",
-"Africa/Bangui",
-"Africa/Banjul",
-"Africa/Bissau",
-"Africa/Blantyre",
-"Africa/Brazzaville",
-"Africa/Bujumbura",
-"Africa/Cairo",
-"Africa/Casablanca",
-"Africa/Ceuta",
-"Africa/Conakry",
-"Africa/Dakar",
-"Africa/Dar_es_Salaam",
-"Africa/Djibouti",
-"Africa/Douala",
-"Africa/El_Aaiun",
-"Africa/Freetown",
-"Africa/Gaborone",
-"Africa/Harare",
-"Africa/Johannesburg",
-"Africa/Juba",
-"Africa/Kampala",
-"Africa/Khartoum",
-"Africa/Kigali",
-"Africa/Kinshasa",
-"Africa/Lagos",
-"Africa/Libreville",
-"Africa/Lome",
-"Africa/Luanda",
-"Africa/Lubumbashi",
-"Africa/Lusaka",
-"Africa/Malabo",
-"Africa/Maputo",
-"Africa/Maseru",
-"Africa/Mbabane",
-"Africa/Mogadishu",
-"Africa/Monrovia",
-"Africa/Nairobi",
-"Africa/Ndjamena",
-"Africa/Niamey",
-"Africa/Nouakchott",
-"Africa/Ouagadougou",
-"Africa/Porto-Novo",
-"Africa/Sao_Tome",
-"Africa/Timbuktu",
-"Africa/Tripoli",
-"Africa/Tunis",
-"Africa/Windhoek",
-"America/Adak",
-"America/Anchorage",
-"America/Anguilla",
-"America/Antigua",
-"America/Araguaina",
-"America/Argentina/Buenos_Aires",
-"America/Argentina/Catamarca",
-"America/Argentina/ComodRivadavia",
-"America/Argentina/Cordoba",
-"America/Argentina/Jujuy",
-"America/Argentina/La_Rioja",
-"America/Argentina/Mendoza",
-"America/Argentina/Rio_Gallegos",
-"America/Argentina/Salta",
-"America/Argentina/San_Juan",
-"America/Argentina/San_Luis",
-"America/Argentina/Tucuman",
-"America/Argentina/Ushuaia",
-"America/Aruba",
-"America/Asuncion",
-"America/Atikokan",
-"America/Atka",
-"America/Bahia",
-"America/Bahia_Banderas",
-"America/Barbados",
-"America/Belem",
-"America/Belize",
-"America/Blanc-Sablon",
-"America/Boa_Vista",
-"America/Bogota",
-"America/Boise",
-"America/Buenos_Aires",
-"America/Cambridge_Bay",
-"America/Campo_Grande",
-"America/Cancun",
-"America/Caracas",
-"America/Catamarca",
-"America/Cayenne",
-"America/Cayman",
-"America/Chicago",
-"America/Chihuahua",
-"America/Coral_Harbour",
-"America/Cordoba",
-"America/Costa_Rica",
-"America/Creston",
-"America/Cuiaba",
-"America/Curacao",
-"America/Danmarkshavn",
-"America/Dawson",
-"America/Dawson_Creek",
-"America/Denver",
-"America/Detroit",
-"America/Dominica",
-"America/Edmonton",
-"America/Eirunepe",
-"America/El_Salvador",
-"America/Ensenada",
-"America/Fort_Nelson",
-"America/Fort_Wayne",
-"America/Fortaleza",
-"America/Glace_Bay",
-"America/Godthab",
-"America/Goose_Bay",
-"America/Grand_Turk",
-"America/Grenada",
-"America/Guadeloupe",
-"America/Guatemala",
-"America/Guayaquil",
-"America/Guyana",
-"America/Halifax",
-"America/Havana",
-"America/Hermosillo",
-"America/Indiana/Indianapolis",
-"America/Indiana/Knox",
-"America/Indiana/Marengo",
-"America/Indiana/Petersburg",
-"America/Indiana/Tell_City",
-"America/Indiana/Vevay",
-"America/Indiana/Vincennes",
-"America/Indiana/Winamac",
-"America/Indianapolis",
-"America/Inuvik",
-"America/Iqaluit",
-"America/Jamaica",
-"America/Jujuy",
-"America/Juneau",
-"America/Kentucky/Louisville",
-"America/Kentucky/Monticello",
-"America/Knox_IN",
-"America/Kralendijk",
-"America/La_Paz",
-"America/Lima",
-"America/Los_Angeles",
-"America/Louisville",
-"America/Lower_Princes",
-"America/Maceio",
-"America/Managua",
-"America/Manaus",
-"America/Marigot",
-"America/Martinique",
-"America/Matamoros",
-"America/Mazatlan",
-"America/Mendoza",
-"America/Menominee",
-"America/Merida",
-"America/Metlakatla",
-"America/Mexico_City",
-"America/Miquelon",
-"America/Moncton",
-"America/Monterrey",
-"America/Montevideo",
-"America/Montreal",
-"America/Montserrat",
-"America/Nassau",
-"America/New_York",
-"America/Nipigon",
-"America/Nome",
-"America/Noronha",
-"America/North_Dakota/Beulah",
-"America/North_Dakota/Center",
-"America/North_Dakota/New_Salem",
-"America/Ojinaga",
-"America/Panama",
-"America/Pangnirtung",
-"America/Paramaribo",
-"America/Phoenix",
-"America/Port-au-Prince",
-"America/Port_of_Spain",
-"America/Porto_Acre",
-"America/Porto_Velho",
-"America/Puerto_Rico",
-"America/Punta_Arenas",
-"America/Rainy_River",
-"America/Rankin_Inlet",
-"America/Recife",
-"America/Regina",
-"America/Resolute",
-"America/Rio_Branco",
-"America/Rosario",
-"America/Santa_Isabel",
-"America/Santarem",
-"America/Santiago",
-"America/Santo_Domingo",
-"America/Sao_Paulo",
-"America/Scoresbysund",
-"America/Shiprock",
-"America/Sitka",
-"America/St_Barthelemy",
-"America/St_Johns",
-"America/St_Kitts",
-"America/St_Lucia",
-"America/St_Thomas",
-"America/St_Vincent",
-"America/Swift_Current",
-"America/Tegucigalpa",
-"America/Thule",
-"America/Thunder_Bay",
-"America/Tijuana",
-"America/Toronto",
-"America/Tortola",
-"America/Vancouver",
-"America/Virgin",
-"America/Whitehorse",
-"America/Winnipeg",
-"America/Yakutat",
-"America/Yellowknife",
-"Antarctica/Casey",
-"Antarctica/Davis",
-"Antarctica/DumontDUrville",
-"Antarctica/Macquarie",
-"Antarctica/Mawson",
-"Antarctica/McMurdo",
-"Antarctica/Palmer",
-"Antarctica/Rothera",
-"Antarctica/South_Pole",
-"Antarctica/Syowa",
-"Antarctica/Troll",
-"Antarctica/Vostok",
-"Arctic/Longyearbyen",
-"Asia/Aden",
-"Asia/Almaty",
-"Asia/Amman",
-"Asia/Anadyr",
-"Asia/Aqtau",
-"Asia/Aqtobe",
-"Asia/Ashgabat",
-"Asia/Ashkhabad",
-"Asia/Atyrau",
-"Asia/Baghdad",
-"Asia/Bahrain",
-"Asia/Baku",
-"Asia/Bangkok",
-"Asia/Barnaul",
-"Asia/Beirut",
-"Asia/Bishkek",
-"Asia/Brunei",
-"Asia/Calcutta",
-"Asia/Chita",
-"Asia/Choibalsan",
-"Asia/Chongqing",
-"Asia/Chungking",
-"Asia/Colombo",
-"Asia/Dacca",
-"Asia/Damascus",
-"Asia/Dhaka",
-"Asia/Dili",
-"Asia/Dubai",
-"Asia/Dushanbe",
-"Asia/Famagusta",
-"Asia/Gaza",
-"Asia/Harbin",
-"Asia/Hebron",
-"Asia/Ho_Chi_Minh",
-"Asia/Hong_Kong",
-"Asia/Hovd",
-"Asia/Irkutsk",
-"Asia/Istanbul",
-"Asia/Jakarta",
-"Asia/Jayapura",
-"Asia/Jerusalem",
-"Asia/Kabul",
-"Asia/Kamchatka",
-"Asia/Karachi",
-"Asia/Kashgar",
-"Asia/Kathmandu",
-"Asia/Katmandu",
-"Asia/Khandyga",
-"Asia/Kolkata",
-"Asia/Krasnoyarsk",
-"Asia/Kuala_Lumpur",
-"Asia/Kuching",
-"Asia/Kuwait",
-"Asia/Macao",
-"Asia/Macau",
-"Asia/Magadan",
-"Asia/Makassar",
-"Asia/Manila",
-"Asia/Muscat",
-"Asia/Nicosia",
-"Asia/Novokuznetsk",
-"Asia/Novosibirsk",
-"Asia/Omsk",
-"Asia/Oral",
-"Asia/Phnom_Penh",
-"Asia/Pontianak",
-"Asia/Pyongyang",
-"Asia/Qatar",
-"Asia/Qyzylorda",
-"Asia/Rangoon",
-"Asia/Riyadh",
-"Asia/Saigon",
-"Asia/Sakhalin",
-"Asia/Samarkand",
-"Asia/Seoul",
-"Asia/Shanghai",
-"Asia/Singapore",
-"Asia/Srednekolymsk",
-"Asia/Taipei",
-"Asia/Tashkent",
-"Asia/Tbilisi",
-"Asia/Tehran",
-"Asia/Tel_Aviv",
-"Asia/Thimbu",
-"Asia/Thimphu",
-"Asia/Tokyo",
-"Asia/Tomsk",
-"Asia/Ujung_Pandang",
-"Asia/Ulaanbaatar",
-"Asia/Ulan_Bator",
-"Asia/Urumqi",
-"Asia/Ust-Nera",
-"Asia/Vientiane",
-"Asia/Vladivostok",
-"Asia/Yakutsk",
-"Asia/Yangon",
-"Asia/Yekaterinburg",
-"Asia/Yerevan",
-"Atlantic/Azores",
-"Atlantic/Bermuda",
-"Atlantic/Canary",
-"Atlantic/Cape_Verde",
-"Atlantic/Faeroe",
-"Atlantic/Faroe",
-"Atlantic/Jan_Mayen",
-"Atlantic/Madeira",
-"Atlantic/Reykjavik",
-"Atlantic/South_Georgia",
-"Atlantic/St_Helena",
-"Atlantic/Stanley",
-"Australia/ACT",
-"Australia/Adelaide",
-"Australia/Brisbane",
-"Australia/Broken_Hill",
-"Australia/Canberra",
-"Australia/Currie",
-"Australia/Darwin",
-"Australia/Eucla",
-"Australia/Hobart",
-"Australia/LHI",
-"Australia/Lindeman",
-"Australia/Lord_Howe",
-"Australia/Melbourne",
-"Australia/NSW",
-"Australia/North",
-"Australia/Perth",
-"Australia/Queensland",
-"Australia/South",
-"Australia/Sydney",
-"Australia/Tasmania",
-"Australia/Victoria",
-"Australia/West",
-"Australia/Yancowinna",
-"Brazil/Acre",
-"Brazil/DeNoronha",
-"Brazil/East",
-"Brazil/West",
-"CET",
-"CST6CDT",
-"Canada/Atlantic",
-"Canada/Central",
-"Canada/Eastern",
-"Canada/Mountain",
-"Canada/Newfoundland",
-"Canada/Pacific",
-"Canada/Saskatchewan",
-"Canada/Yukon",
-"Chile/Continental",
-"Chile/EasterIsland",
-"Cuba",
-"EET",
-"EST",
-"EST5EDT",
-"Egypt",
-"Eire",
-"Etc/GMT",
-"Etc/GMT+0",
-"Etc/GMT+1",
-"Etc/GMT+10",
-"Etc/GMT+11",
-"Etc/GMT+12",
-"Etc/GMT+2",
-"Etc/GMT+3",
-"Etc/GMT+4",
-"Etc/GMT+5",
-"Etc/GMT+6",
-"Etc/GMT+7",
-"Etc/GMT+8",
-"Etc/GMT+9",
-"Etc/GMT-0",
-"Etc/GMT-1",
-"Etc/GMT-10",
-"Etc/GMT-11",
-"Etc/GMT-12",
-"Etc/GMT-13",
-"Etc/GMT-14",
-"Etc/GMT-2",
-"Etc/GMT-3",
-"Etc/GMT-4",
-"Etc/GMT-5",
-"Etc/GMT-6",
-"Etc/GMT-7",
-"Etc/GMT-8",
-"Etc/GMT-9",
-"Etc/GMT0",
-"Etc/Greenwich",
-"Etc/UCT",
-"Etc/UTC",
-"Etc/Universal",
-"Etc/Zulu",
-"Europe/Amsterdam",
-"Europe/Andorra",
-"Europe/Astrakhan",
-"Europe/Athens",
-"Europe/Belfast",
-"Europe/Belgrade",
-"Europe/Berlin",
-"Europe/Bratislava",
-"Europe/Brussels",
-"Europe/Bucharest",
-"Europe/Budapest",
-"Europe/Busingen",
-"Europe/Chisinau",
-"Europe/Copenhagen",
-"Europe/Dublin",
-"Europe/Gibraltar",
-"Europe/Guernsey",
-"Europe/Helsinki",
-"Europe/Isle_of_Man",
-"Europe/Istanbul",
-"Europe/Jersey",
-"Europe/Kaliningrad",
-"Europe/Kiev",
-"Europe/Kirov",
-"Europe/Lisbon",
-"Europe/Ljubljana",
-"Europe/London",
-"Europe/Luxembourg",
-"Europe/Madrid",
-"Europe/Malta",
-"Europe/Mariehamn",
-"Europe/Minsk",
-"Europe/Monaco",
-"Europe/Nicosia",
-"Europe/Oslo",
-"Europe/Paris",
-"Europe/Podgorica",
-"Europe/Prague",
-"Europe/Riga",
-"Europe/Rome",
-"Europe/Samara",
-"Europe/San_Marino",
-"Europe/Sarajevo",
-"Europe/Saratov",
-"Europe/Simferopol",
-"Europe/Skopje",
-"Europe/Sofia",
-"Europe/Stockholm",
-"Europe/Tallinn",
-"Europe/Tirane",
-"Europe/Tiraspol",
-"Europe/Ulyanovsk",
-"Europe/Uzhgorod",
-"Europe/Vaduz",
-"Europe/Vatican",
-"Europe/Vienna",
-"Europe/Vilnius",
-"Europe/Volgograd",
-"Europe/Warsaw",
-"Europe/Zagreb",
-"Europe/Zaporozhye",
-"Europe/Zurich",
-"Factory",
-"GB",
-"GB-Eire",
-"GMT+0",
-"GMT-0",
-"GMT0",
-"Greenwich",
-"HST",
-"Hongkong",
-"Iceland",
-"Indian/Antananarivo",
-"Indian/Chagos",
-"Indian/Christmas",
-"Indian/Cocos",
-"Indian/Comoro",
-"Indian/Kerguelen",
-"Indian/Mahe",
-"Indian/Maldives",
-"Indian/Mauritius",
-"Indian/Mayotte",
-"Indian/Reunion",
-"Iran",
-"Israel",
-"Jamaica",
-"Japan",
-"Kwajalein",
-"Libya",
-"MET",
-"MST",
-"MST7MDT",
-"Mexico/BajaNorte",
-"Mexico/BajaSur",
-"Mexico/General",
-"NZ",
-"NZ-CHAT",
-"Navajo",
-"PRC",
-"PST8PDT",
-"Pacific/Apia",
-"Pacific/Auckland",
-"Pacific/Bougainville",
-"Pacific/Chatham",
-"Pacific/Chuuk",
-"Pacific/Easter",
-"Pacific/Efate",
-"Pacific/Enderbury",
-"Pacific/Fakaofo",
-"Pacific/Fiji",
-"Pacific/Funafuti",
-"Pacific/Galapagos",
-"Pacific/Gambier",
-"Pacific/Guadalcanal",
-"Pacific/Guam",
-"Pacific/Honolulu",
-"Pacific/Johnston",
-"Pacific/Kiritimati",
-"Pacific/Kosrae",
-"Pacific/Kwajalein",
-"Pacific/Majuro",
-"Pacific/Marquesas",
-"Pacific/Midway",
-"Pacific/Nauru",
-"Pacific/Niue",
-"Pacific/Norfolk",
-"Pacific/Noumea",
-"Pacific/Pago_Pago",
-"Pacific/Palau",
-"Pacific/Pitcairn",
-"Pacific/Pohnpei",
-"Pacific/Ponape",
-"Pacific/Port_Moresby",
-"Pacific/Rarotonga",
-"Pacific/Saipan",
-"Pacific/Samoa",
-"Pacific/Tahiti",
-"Pacific/Tarawa",
-"Pacific/Tongatapu",
-"Pacific/Truk",
-"Pacific/Wake",
-"Pacific/Wallis",
-"Pacific/Yap",
-"Poland",
-"Portugal",
-"ROC",
-"ROK",
-"Singapore",
-"Turkey",
-"UCT",
-"US/Alaska",
-"US/Aleutian",
-"US/Arizona",
-"US/Central",
-"US/East-Indiana",
-"US/Eastern",
-"US/Hawaii",
-"US/Indiana-Starke",
-"US/Michigan",
-"US/Mountain",
-"US/Pacific",
-"",//US/Pacific-New
-"US/Samoa",
-"UTC",
-"Universal",
-"W-SU",
-"WET",
-"Zulu",
-"",//localtime
-"posixrules",
-"Asia/Qostanay",
-"America/Nuuk",
+"GMT",
+"Europe/Moscow",
+"Africa/Abidjan",
+"Africa/Accra",
+"Africa/Addis_Ababa",
+"Africa/Algiers",
+"Africa/Asmara",
+"Africa/Asmera",
+"Africa/Bamako",
+"Africa/Bangui",
+"Africa/Banjul",
+"Africa/Bissau",
+"Africa/Blantyre",
+"Africa/Brazzaville",
+"Africa/Bujumbura",
+"Africa/Cairo",
+"Africa/Casablanca",
+"Africa/Ceuta",
+"Africa/Conakry",
+"Africa/Dakar",
+"Africa/Dar_es_Salaam",
+"Africa/Djibouti",
+"Africa/Douala",
+"Africa/El_Aaiun",
+"Africa/Freetown",
+"Africa/Gaborone",
+"Africa/Harare",
+"Africa/Johannesburg",
+"Africa/Juba",
+"Africa/Kampala",
+"Africa/Khartoum",
+"Africa/Kigali",
+"Africa/Kinshasa",
+"Africa/Lagos",
+"Africa/Libreville",
+"Africa/Lome",
+"Africa/Luanda",
+"Africa/Lubumbashi",
+"Africa/Lusaka",
+"Africa/Malabo",
+"Africa/Maputo",
+"Africa/Maseru",
+"Africa/Mbabane",
+"Africa/Mogadishu",
+"Africa/Monrovia",
+"Africa/Nairobi",
+"Africa/Ndjamena",
+"Africa/Niamey",
+"Africa/Nouakchott",
+"Africa/Ouagadougou",
+"Africa/Porto-Novo",
+"Africa/Sao_Tome",
+"Africa/Timbuktu",
+"Africa/Tripoli",
+"Africa/Tunis",
+"Africa/Windhoek",
+"America/Adak",
+"America/Anchorage",
+"America/Anguilla",
+"America/Antigua",
+"America/Araguaina",
+"America/Argentina/Buenos_Aires",
+"America/Argentina/Catamarca",
+"America/Argentina/ComodRivadavia",
+"America/Argentina/Cordoba",
+"America/Argentina/Jujuy",
+"America/Argentina/La_Rioja",
+"America/Argentina/Mendoza",
+"America/Argentina/Rio_Gallegos",
+"America/Argentina/Salta",
+"America/Argentina/San_Juan",
+"America/Argentina/San_Luis",
+"America/Argentina/Tucuman",
+"America/Argentina/Ushuaia",
+"America/Aruba",
+"America/Asuncion",
+"America/Atikokan",
+"America/Atka",
+"America/Bahia",
+"America/Bahia_Banderas",
+"America/Barbados",
+"America/Belem",
+"America/Belize",
+"America/Blanc-Sablon",
+"America/Boa_Vista",
+"America/Bogota",
+"America/Boise",
+"America/Buenos_Aires",
+"America/Cambridge_Bay",
+"America/Campo_Grande",
+"America/Cancun",
+"America/Caracas",
+"America/Catamarca",
+"America/Cayenne",
+"America/Cayman",
+"America/Chicago",
+"America/Chihuahua",
+"America/Coral_Harbour",
+"America/Cordoba",
+"America/Costa_Rica",
+"America/Creston",
+"America/Cuiaba",
+"America/Curacao",
+"America/Danmarkshavn",
+"America/Dawson",
+"America/Dawson_Creek",
+"America/Denver",
+"America/Detroit",
+"America/Dominica",
+"America/Edmonton",
+"America/Eirunepe",
+"America/El_Salvador",
+"America/Ensenada",
+"America/Fort_Nelson",
+"America/Fort_Wayne",
+"America/Fortaleza",
+"America/Glace_Bay",
+"America/Godthab",
+"America/Goose_Bay",
+"America/Grand_Turk",
+"America/Grenada",
+"America/Guadeloupe",
+"America/Guatemala",
+"America/Guayaquil",
+"America/Guyana",
+"America/Halifax",
+"America/Havana",
+"America/Hermosillo",
+"America/Indiana/Indianapolis",
+"America/Indiana/Knox",
+"America/Indiana/Marengo",
+"America/Indiana/Petersburg",
+"America/Indiana/Tell_City",
+"America/Indiana/Vevay",
+"America/Indiana/Vincennes",
+"America/Indiana/Winamac",
+"America/Indianapolis",
+"America/Inuvik",
+"America/Iqaluit",
+"America/Jamaica",
+"America/Jujuy",
+"America/Juneau",
+"America/Kentucky/Louisville",
+"America/Kentucky/Monticello",
+"America/Knox_IN",
+"America/Kralendijk",
+"America/La_Paz",
+"America/Lima",
+"America/Los_Angeles",
+"America/Louisville",
+"America/Lower_Princes",
+"America/Maceio",
+"America/Managua",
+"America/Manaus",
+"America/Marigot",
+"America/Martinique",
+"America/Matamoros",
+"America/Mazatlan",
+"America/Mendoza",
+"America/Menominee",
+"America/Merida",
+"America/Metlakatla",
+"America/Mexico_City",
+"America/Miquelon",
+"America/Moncton",
+"America/Monterrey",
+"America/Montevideo",
+"America/Montreal",
+"America/Montserrat",
+"America/Nassau",
+"America/New_York",
+"America/Nipigon",
+"America/Nome",
+"America/Noronha",
+"America/North_Dakota/Beulah",
+"America/North_Dakota/Center",
+"America/North_Dakota/New_Salem",
+"America/Ojinaga",
+"America/Panama",
+"America/Pangnirtung",
+"America/Paramaribo",
+"America/Phoenix",
+"America/Port-au-Prince",
+"America/Port_of_Spain",
+"America/Porto_Acre",
+"America/Porto_Velho",
+"America/Puerto_Rico",
+"America/Punta_Arenas",
+"America/Rainy_River",
+"America/Rankin_Inlet",
+"America/Recife",
+"America/Regina",
+"America/Resolute",
+"America/Rio_Branco",
+"America/Rosario",
+"America/Santa_Isabel",
+"America/Santarem",
+"America/Santiago",
+"America/Santo_Domingo",
+"America/Sao_Paulo",
+"America/Scoresbysund",
+"America/Shiprock",
+"America/Sitka",
+"America/St_Barthelemy",
+"America/St_Johns",
+"America/St_Kitts",
+"America/St_Lucia",
+"America/St_Thomas",
+"America/St_Vincent",
+"America/Swift_Current",
+"America/Tegucigalpa",
+"America/Thule",
+"America/Thunder_Bay",
+"America/Tijuana",
+"America/Toronto",
+"America/Tortola",
+"America/Vancouver",
+"America/Virgin",
+"America/Whitehorse",
+"America/Winnipeg",
+"America/Yakutat",
+"America/Yellowknife",
+"Antarctica/Casey",
+"Antarctica/Davis",
+"Antarctica/DumontDUrville",
+"Antarctica/Macquarie",
+"Antarctica/Mawson",
+"Antarctica/McMurdo",
+"Antarctica/Palmer",
+"Antarctica/Rothera",
+"Antarctica/South_Pole",
+"Antarctica/Syowa",
+"Antarctica/Troll",
+"Antarctica/Vostok",
+"Arctic/Longyearbyen",
+"Asia/Aden",
+"Asia/Almaty",
+"Asia/Amman",
+"Asia/Anadyr",
+"Asia/Aqtau",
+"Asia/Aqtobe",
+"Asia/Ashgabat",
+"Asia/Ashkhabad",
+"Asia/Atyrau",
+"Asia/Baghdad",
+"Asia/Bahrain",
+"Asia/Baku",
+"Asia/Bangkok",
+"Asia/Barnaul",
+"Asia/Beirut",
+"Asia/Bishkek",
+"Asia/Brunei",
+"Asia/Calcutta",
+"Asia/Chita",
+"Asia/Choibalsan",
+"Asia/Chongqing",
+"Asia/Chungking",
+"Asia/Colombo",
+"Asia/Dacca",
+"Asia/Damascus",
+"Asia/Dhaka",
+"Asia/Dili",
+"Asia/Dubai",
+"Asia/Dushanbe",
+"Asia/Famagusta",
+"Asia/Gaza",
+"Asia/Harbin",
+"Asia/Hebron",
+"Asia/Ho_Chi_Minh",
+"Asia/Hong_Kong",
+"Asia/Hovd",
+"Asia/Irkutsk",
+"Asia/Istanbul",
+"Asia/Jakarta",
+"Asia/Jayapura",
+"Asia/Jerusalem",
+"Asia/Kabul",
+"Asia/Kamchatka",
+"Asia/Karachi",
+"Asia/Kashgar",
+"Asia/Kathmandu",
+"Asia/Katmandu",
+"Asia/Khandyga",
+"Asia/Kolkata",
+"Asia/Krasnoyarsk",
+"Asia/Kuala_Lumpur",
+"Asia/Kuching",
+"Asia/Kuwait",
+"Asia/Macao",
+"Asia/Macau",
+"Asia/Magadan",
+"Asia/Makassar",
+"Asia/Manila",
+"Asia/Muscat",
+"Asia/Nicosia",
+"Asia/Novokuznetsk",
+"Asia/Novosibirsk",
+"Asia/Omsk",
+"Asia/Oral",
+"Asia/Phnom_Penh",
+"Asia/Pontianak",
+"Asia/Pyongyang",
+"Asia/Qatar",
+"Asia/Qyzylorda",
+"Asia/Rangoon",
+"Asia/Riyadh",
+"Asia/Saigon",
+"Asia/Sakhalin",
+"Asia/Samarkand",
+"Asia/Seoul",
+"Asia/Shanghai",
+"Asia/Singapore",
+"Asia/Srednekolymsk",
+"Asia/Taipei",
+"Asia/Tashkent",
+"Asia/Tbilisi",
+"Asia/Tehran",
+"Asia/Tel_Aviv",
+"Asia/Thimbu",
+"Asia/Thimphu",
+"Asia/Tokyo",
+"Asia/Tomsk",
+"Asia/Ujung_Pandang",
+"Asia/Ulaanbaatar",
+"Asia/Ulan_Bator",
+"Asia/Urumqi",
+"Asia/Ust-Nera",
+"Asia/Vientiane",
+"Asia/Vladivostok",
+"Asia/Yakutsk",
+"Asia/Yangon",
+"Asia/Yekaterinburg",
+"Asia/Yerevan",
+"Atlantic/Azores",
+"Atlantic/Bermuda",
+"Atlantic/Canary",
+"Atlantic/Cape_Verde",
+"Atlantic/Faeroe",
+"Atlantic/Faroe",
+"Atlantic/Jan_Mayen",
+"Atlantic/Madeira",
+"Atlantic/Reykjavik",
+"Atlantic/South_Georgia",
+"Atlantic/St_Helena",
+"Atlantic/Stanley",
+"Australia/ACT",
+"Australia/Adelaide",
+"Australia/Brisbane",
+"Australia/Broken_Hill",
+"Australia/Canberra",
+"Australia/Currie",
+"Australia/Darwin",
+"Australia/Eucla",
+"Australia/Hobart",
+"Australia/LHI",
+"Australia/Lindeman",
+"Australia/Lord_Howe",
+"Australia/Melbourne",
+"Australia/NSW",
+"Australia/North",
+"Australia/Perth",
+"Australia/Queensland",
+"Australia/South",
+"Australia/Sydney",
+"Australia/Tasmania",
+"Australia/Victoria",
+"Australia/West",
+"Australia/Yancowinna",
+"Brazil/Acre",
+"Brazil/DeNoronha",
+"Brazil/East",
+"Brazil/West",
+"CET",
+"CST6CDT",
+"Canada/Atlantic",
+"Canada/Central",
+"Canada/Eastern",
+"Canada/Mountain",
+"Canada/Newfoundland",
+"Canada/Pacific",
+"Canada/Saskatchewan",
+"Canada/Yukon",
+"Chile/Continental",
+"Chile/EasterIsland",
+"Cuba",
+"EET",
+"EST",
+"EST5EDT",
+"Egypt",
+"Eire",
+"Etc/GMT",
+"Etc/GMT+0",
+"Etc/GMT+1",
+"Etc/GMT+10",
+"Etc/GMT+11",
+"Etc/GMT+12",
+"Etc/GMT+2",
+"Etc/GMT+3",
+"Etc/GMT+4",
+"Etc/GMT+5",
+"Etc/GMT+6",
+"Etc/GMT+7",
+"Etc/GMT+8",
+"Etc/GMT+9",
+"Etc/GMT-0",
+"Etc/GMT-1",
+"Etc/GMT-10",
+"Etc/GMT-11",
+"Etc/GMT-12",
+"Etc/GMT-13",
+"Etc/GMT-14",
+"Etc/GMT-2",
+"Etc/GMT-3",
+"Etc/GMT-4",
+"Etc/GMT-5",
+"Etc/GMT-6",
+"Etc/GMT-7",
+"Etc/GMT-8",
+"Etc/GMT-9",
+"Etc/GMT0",
+"Etc/Greenwich",
+"Etc/UCT",
+"Etc/UTC",
+"Etc/Universal",
+"Etc/Zulu",
+"Europe/Amsterdam",
+"Europe/Andorra",
+"Europe/Astrakhan",
+"Europe/Athens",
+"Europe/Belfast",
+"Europe/Belgrade",
+"Europe/Berlin",
+"Europe/Bratislava",
+"Europe/Brussels",
+"Europe/Bucharest",
+"Europe/Budapest",
+"Europe/Busingen",
+"Europe/Chisinau",
+"Europe/Copenhagen",
+"Europe/Dublin",
+"Europe/Gibraltar",
+"Europe/Guernsey",
+"Europe/Helsinki",
+"Europe/Isle_of_Man",
+"Europe/Istanbul",
+"Europe/Jersey",
+"Europe/Kaliningrad",
+"Europe/Kiev",
+"Europe/Kirov",
+"Europe/Lisbon",
+"Europe/Ljubljana",
+"Europe/London",
+"Europe/Luxembourg",
+"Europe/Madrid",
+"Europe/Malta",
+"Europe/Mariehamn",
+"Europe/Minsk",
+"Europe/Monaco",
+"Europe/Nicosia",
+"Europe/Oslo",
+"Europe/Paris",
+"Europe/Podgorica",
+"Europe/Prague",
+"Europe/Riga",
+"Europe/Rome",
+"Europe/Samara",
+"Europe/San_Marino",
+"Europe/Sarajevo",
+"Europe/Saratov",
+"Europe/Simferopol",
+"Europe/Skopje",
+"Europe/Sofia",
+"Europe/Stockholm",
+"Europe/Tallinn",
+"Europe/Tirane",
+"Europe/Tiraspol",
+"Europe/Ulyanovsk",
+"Europe/Uzhgorod",
+"Europe/Vaduz",
+"Europe/Vatican",
+"Europe/Vienna",
+"Europe/Vilnius",
+"Europe/Volgograd",
+"Europe/Warsaw",
+"Europe/Zagreb",
+"Europe/Zaporozhye",
+"Europe/Zurich",
+"Factory",
+"GB",
+"GB-Eire",
+"GMT+0",
+"GMT-0",
+"GMT0",
+"Greenwich",
+"HST",
+"Hongkong",
+"Iceland",
+"Indian/Antananarivo",
+"Indian/Chagos",
+"Indian/Christmas",
+"Indian/Cocos",
+"Indian/Comoro",
+"Indian/Kerguelen",
+"Indian/Mahe",
+"Indian/Maldives",
+"Indian/Mauritius",
+"Indian/Mayotte",
+"Indian/Reunion",
+"Iran",
+"Israel",
+"Jamaica",
+"Japan",
+"Kwajalein",
+"Libya",
+"MET",
+"MST",
+"MST7MDT",
+"Mexico/BajaNorte",
+"Mexico/BajaSur",
+"Mexico/General",
+"NZ",
+"NZ-CHAT",
+"Navajo",
+"PRC",
+"PST8PDT",
+"Pacific/Apia",
+"Pacific/Auckland",
+"Pacific/Bougainville",
+"Pacific/Chatham",
+"Pacific/Chuuk",
+"Pacific/Easter",
+"Pacific/Efate",
+"Pacific/Enderbury",
+"Pacific/Fakaofo",
+"Pacific/Fiji",
+"Pacific/Funafuti",
+"Pacific/Galapagos",
+"Pacific/Gambier",
+"Pacific/Guadalcanal",
+"Pacific/Guam",
+"Pacific/Honolulu",
+"Pacific/Johnston",
+"Pacific/Kiritimati",
+"Pacific/Kosrae",
+"Pacific/Kwajalein",
+"Pacific/Majuro",
+"Pacific/Marquesas",
+"Pacific/Midway",
+"Pacific/Nauru",
+"Pacific/Niue",
+"Pacific/Norfolk",
+"Pacific/Noumea",
+"Pacific/Pago_Pago",
+"Pacific/Palau",
+"Pacific/Pitcairn",
+"Pacific/Pohnpei",
+"Pacific/Ponape",
+"Pacific/Port_Moresby",
+"Pacific/Rarotonga",
+"Pacific/Saipan",
+"Pacific/Samoa",
+"Pacific/Tahiti",
+"Pacific/Tarawa",
+"Pacific/Tongatapu",
+"Pacific/Truk",
+"Pacific/Wake",
+"Pacific/Wallis",
+"Pacific/Yap",
+"Poland",
+"Portugal",
+"ROC",
+"ROK",
+"Singapore",
+"Turkey",
+"UCT",
+"US/Alaska",
+"US/Aleutian",
+"US/Arizona",
+"US/Central",
+"US/East-Indiana",
+"US/Eastern",
+"US/Hawaii",
+"US/Indiana-Starke",
+"US/Michigan",
+"US/Mountain",
+"US/Pacific",
+"",//US/Pacific-New
+"US/Samoa",
+"UTC",
+"Universal",
+"W-SU",
+"WET",
+"Zulu",
+"",//localtime
+"posixrules",
+"Asia/Qostanay",
+"America/Nuuk",
diff --git a/ydb/library/yql/public/udf/tz/udf_tz.h b/ydb/library/yql/public/udf/tz/udf_tz.h
index ad2f7b4994..05d6bc450f 100644
--- a/ydb/library/yql/public/udf/tz/udf_tz.h
+++ b/ydb/library/yql/public/udf/tz/udf_tz.h
@@ -1,11 +1,11 @@
#pragma once
#include <util/generic/array_ref.h>
-#include <string_view>
+#include <string_view>
-namespace NYql {
+namespace NYql {
namespace NUdf {
-TArrayRef<const std::string_view> GetTimezones();
+TArrayRef<const std::string_view> GetTimezones();
}
}
diff --git a/ydb/library/yql/public/udf/tz/udf_tz_ut.cpp b/ydb/library/yql/public/udf/tz/udf_tz_ut.cpp
index 591a4a68f3..5853398c75 100644
--- a/ydb/library/yql/public/udf/tz/udf_tz_ut.cpp
+++ b/ydb/library/yql/public/udf/tz/udf_tz_ut.cpp
@@ -2,7 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
-using namespace NYql::NUdf;
+using namespace NYql::NUdf;
Y_UNIT_TEST_SUITE(TUdfTz) {
Y_UNIT_TEST(Count) {
diff --git a/ydb/library/yql/public/udf/tz/update.py b/ydb/library/yql/public/udf/tz/update.py
index 5ff524cb4c..0d9814841f 100644
--- a/ydb/library/yql/public/udf/tz/update.py
+++ b/ydb/library/yql/public/udf/tz/update.py
@@ -2,14 +2,14 @@ import re
def main():
- REGEXP = "^(\"(.+)\",|\"\",\/\/(.+))$"
+ REGEXP = "^(\"(.+)\",|\"\",\/\/(.+))$"
OUTPUT = "../udf_tz.gen"
INPUT = OUTPUT
CONTRIB_ZONES = "../../../../../../../contrib/libs/cctz/tzdata/ya.make.resources"
RES_PREFIX = "/cctz/tzdata/"
print("process %s into %s" % (INPUT, OUTPUT))
- with open(INPUT, "r") as inp:
+ with open(INPUT, "r") as inp:
lines = inp.readlines()
zones = []
@@ -17,7 +17,7 @@ def main():
m = re.match(REGEXP, line)
if not m:
raise ValueError("invalid line: %s", line)
- zones.append(m.group(2) or m.group(3))
+ zones.append(m.group(2) or m.group(3))
szones = set()
print("loaded %s zones" % len(zones))
@@ -27,7 +27,7 @@ def main():
szones.add(zone)
scontrib = set()
- with open(CONTRIB_ZONES, "r") as contrib:
+ with open(CONTRIB_ZONES, "r") as contrib:
for line in contrib.readlines():
if RES_PREFIX not in line:
continue
@@ -40,14 +40,14 @@ def main():
szones.add(zone)
zones.append(zone)
- lines = []
- for zone in zones:
- if zone in scontrib:
- lines.append('"%s",\n' % zone)
- else:
- lines.append('"",//%s\n' % zone)
-
- with open(OUTPUT, "w") as outp:
+ lines = []
+ for zone in zones:
+ if zone in scontrib:
+ lines.append('"%s",\n' % zone)
+ else:
+ lines.append('"",//%s\n' % zone)
+
+ with open(OUTPUT, "w") as outp:
outp.writelines(lines)
print("saved %s zones" % len(zones))
diff --git a/ydb/library/yql/public/udf/udf_allocator.h b/ydb/library/yql/public/udf/udf_allocator.h
index 64d9085639..48a94ba6a1 100644
--- a/ydb/library/yql/public/udf/udf_allocator.h
+++ b/ydb/library/yql/public/udf/udf_allocator.h
@@ -1,13 +1,13 @@
#pragma once
#include "udf_version.h"
-#include <util/system/types.h>
-#include <new>
+#include <util/system/types.h>
+#include <new>
#include <cstddef>
-#include <limits>
+#include <limits>
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
extern "C" void* UdfAllocateWithSize(ui64 size);
-extern "C" void UdfFreeWithSize(const void* mem, ui64 size);
+extern "C" void UdfFreeWithSize(const void* mem, ui64 size);
#ifdef __clang__
[[deprecated]]
#endif
@@ -20,86 +20,86 @@ extern "C" void UdfFree(const void* mem);
extern "C" void* UdfAllocate(ui64 size);
extern "C" void UdfFree(const void* mem);
#endif
-
-namespace NYql {
+
+namespace NYql {
namespace NUdf {
-template <typename Type>
-struct TStdAllocatorForUdf
-{
- typedef Type value_type;
- typedef Type* pointer;
- typedef const Type* const_pointer;
- typedef Type& reference;
- typedef const Type& const_reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
+template <typename Type>
+struct TStdAllocatorForUdf
+{
+ typedef Type value_type;
+ typedef Type* pointer;
+ typedef const Type* const_pointer;
+ typedef Type& reference;
+ typedef const Type& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ TStdAllocatorForUdf() noexcept = default;
+ ~TStdAllocatorForUdf() noexcept = default;
+
+ template<typename U> TStdAllocatorForUdf(const TStdAllocatorForUdf<U>&) noexcept {};
+ template<typename U> struct rebind { typedef TStdAllocatorForUdf<U> other; };
+ template<typename U> bool operator==(const TStdAllocatorForUdf<U>&) const { return true; };
+ template<typename U> bool operator!=(const TStdAllocatorForUdf<U>&) const { return false; }
- TStdAllocatorForUdf() noexcept = default;
- ~TStdAllocatorForUdf() noexcept = default;
-
- template<typename U> TStdAllocatorForUdf(const TStdAllocatorForUdf<U>&) noexcept {};
- template<typename U> struct rebind { typedef TStdAllocatorForUdf<U> other; };
- template<typename U> bool operator==(const TStdAllocatorForUdf<U>&) const { return true; };
- template<typename U> bool operator!=(const TStdAllocatorForUdf<U>&) const { return false; }
-
- static pointer allocate(size_type n, const void* = nullptr)
- {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
- return static_cast<pointer>(UdfAllocateWithSize(n * sizeof(value_type)));
-#else
- return static_cast<pointer>(UdfAllocate(n * sizeof(value_type)));
-#endif
+ static pointer allocate(size_type n, const void* = nullptr)
+ {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
+ return static_cast<pointer>(UdfAllocateWithSize(n * sizeof(value_type)));
+#else
+ return static_cast<pointer>(UdfAllocate(n * sizeof(value_type)));
+#endif
}
- static void deallocate(const_pointer p, size_type n) noexcept
- {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
- (void)(n);
- return UdfFreeWithSize(static_cast<const void*>(p), n * sizeof(value_type));
-#else
- (void)(n);
- return UdfFree(static_cast<const void*>(p));
-#endif
+ static void deallocate(const_pointer p, size_type n) noexcept
+ {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
+ (void)(n);
+ return UdfFreeWithSize(static_cast<const void*>(p), n * sizeof(value_type));
+#else
+ (void)(n);
+ return UdfFree(static_cast<const void*>(p));
+#endif
}
};
-struct TWithUdfAllocator {
- void* operator new(size_t sz) {
+struct TWithUdfAllocator {
+ void* operator new(size_t sz) {
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
return UdfAllocateWithSize(sz);
#else
- return UdfAllocate(sz);
+ return UdfAllocate(sz);
#endif
- }
-
- void* operator new[](size_t sz) {
+ }
+
+ void* operator new[](size_t sz) {
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
return UdfAllocateWithSize(sz);
#else
- return UdfAllocate(sz);
+ return UdfAllocate(sz);
#endif
- }
-
+ }
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
void operator delete(void *mem, std::size_t sz) noexcept {
return UdfFreeWithSize(mem, sz);
- }
-
+ }
+
void operator delete[](void *mem, std::size_t sz) noexcept {
return UdfFreeWithSize(mem, sz);
- }
+ }
#else
void operator delete(void *mem) noexcept {
- return UdfFree(mem);
- }
-
+ return UdfFree(mem);
+ }
+
void operator delete[](void *mem) noexcept {
- return UdfFree(mem);
- }
+ return UdfFree(mem);
+ }
#endif
-};
+};
} // namespace NUdf
-} // namespace NYql
-
+} // namespace NYql
+
diff --git a/ydb/library/yql/public/udf/udf_counter.cpp b/ydb/library/yql/public/udf/udf_counter.cpp
index 2a2d8ff4dc..93ec968390 100644
--- a/ydb/library/yql/public/udf/udf_counter.cpp
+++ b/ydb/library/yql/public/udf/udf_counter.cpp
@@ -1,9 +1,9 @@
#include "udf_counter.h"
-namespace NYql {
+namespace NYql {
namespace NUdf {
TScopedProbe::TNullHost TScopedProbe::NullHost_;
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
diff --git a/ydb/library/yql/public/udf/udf_counter.h b/ydb/library/yql/public/udf/udf_counter.h
index ef058d126c..d3f1c8c732 100644
--- a/ydb/library/yql/public/udf/udf_counter.h
+++ b/ydb/library/yql/public/udf/udf_counter.h
@@ -2,7 +2,7 @@
#include "udf_types.h"
#include <util/system/atomic.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
class TCounter {
@@ -109,4 +109,4 @@ public:
UDF_ASSERT_TYPE_SIZE(ICountersProvider, 8);
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_counter_ut.cpp b/ydb/library/yql/public/udf/udf_counter_ut.cpp
index 110815e122..22fd91d5f5 100644
--- a/ydb/library/yql/public/udf/udf_counter_ut.cpp
+++ b/ydb/library/yql/public/udf/udf_counter_ut.cpp
@@ -2,7 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
-using namespace NYql::NUdf;
+using namespace NYql::NUdf;
Y_UNIT_TEST_SUITE(TUdfCounter) {
Y_UNIT_TEST(NullCounter) {
diff --git a/ydb/library/yql/public/udf/udf_data_type.h b/ydb/library/yql/public/udf/udf_data_type.h
index 12a2294985..29558c1879 100644
--- a/ydb/library/yql/public/udf/udf_data_type.h
+++ b/ydb/library/yql/public/udf/udf_data_type.h
@@ -175,7 +175,7 @@ constexpr ui32 MAX_YEAR = 2106u;
XX(TzTimestamp, NYql::NProto::TzTimestamp, TTzTimestamp, CommonType | TzDateType, ui64, 0) \
XX(Decimal, NYql::NProto::Decimal, TDecimal, CommonType | DecimalType, TDecimal, 2) \
XX(DyNumber, NYql::NProto::DyNumber, TDyNumber, CommonType, TDyNumber, 0) \
- XX(JsonDocument, NYql::NProto::JsonDocument, TJsonDocument, PayloadType, TJsonDocument, 0) \
+ XX(JsonDocument, NYql::NProto::JsonDocument, TJsonDocument, PayloadType, TJsonDocument, 0) \
#define UDF_TYPE_ID(xName, xTypeId, xType, xFeatures, xLayoutType, xParamsCount) \
template <> \
diff --git a/ydb/library/yql/public/udf/udf_helpers.cpp b/ydb/library/yql/public/udf/udf_helpers.cpp
index 1fd8421c1b..260ff3e544 100644
--- a/ydb/library/yql/public/udf/udf_helpers.cpp
+++ b/ydb/library/yql/public/udf/udf_helpers.cpp
@@ -5,7 +5,7 @@
#include <util/generic/hash.h>
#include <util/generic/singleton.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
struct TLoadedResources {
diff --git a/ydb/library/yql/public/udf/udf_helpers.h b/ydb/library/yql/public/udf/udf_helpers.h
index cfb039ed87..2be9443559 100644
--- a/ydb/library/yql/public/udf/udf_helpers.h
+++ b/ydb/library/yql/public/udf/udf_helpers.h
@@ -2,8 +2,8 @@
#include "udf_value.h"
#include "udf_registrator.h"
-#include "udf_value_builder.h"
-#include "udf_terminator.h"
+#include "udf_value_builder.h"
+#include "udf_terminator.h"
#include "udf_type_builder.h"
#include "udf_type_inspection.h"
#include "udf_version.h"
@@ -14,7 +14,7 @@
#include <util/string/builder.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
inline TSourcePosition GetSourcePosition(IFunctionTypeInfoBuilder& builder) {
@@ -43,23 +43,23 @@ namespace NUdf {
}
#define UDF_IMPL_EX(udfName, typeBody, members, init, irResourceId, irFunctionName, create_impl) \
- class udfName: public ::NYql::NUdf::TBoxedValue { \
+ class udfName: public ::NYql::NUdf::TBoxedValue { \
public: \
- explicit udfName(::NYql::NUdf::IFunctionTypeInfoBuilder& builder) \
+ explicit udfName(::NYql::NUdf::IFunctionTypeInfoBuilder& builder) \
: Pos_(GetSourcePosition(builder)) \
{ \
init \
} \
- static const ::NYql::NUdf::TStringRef& Name() { \
- static auto name = ::NYql::NUdf::TStringRef::Of(#udfName).Substring(1, 256); \
+ static const ::NYql::NUdf::TStringRef& Name() { \
+ static auto name = ::NYql::NUdf::TStringRef::Of(#udfName).Substring(1, 256); \
return name; \
} \
- inline ::NYql::NUdf::TUnboxedValue RunImpl( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const; \
- ::NYql::NUdf::TUnboxedValue Run( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
+ inline ::NYql::NUdf::TUnboxedValue RunImpl( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const; \
+ ::NYql::NUdf::TUnboxedValue Run( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
try { \
return RunImpl(valueBuilder, args); \
} catch (const std::exception&) { \
@@ -71,9 +71,9 @@ namespace NUdf {
} \
} \
static bool DeclareSignature( \
- const ::NYql::NUdf::TStringRef& name, \
- ::NYql::NUdf::TType* userType, \
- ::NYql::NUdf::IFunctionTypeInfoBuilder& builder, \
+ const ::NYql::NUdf::TStringRef& name, \
+ ::NYql::NUdf::TType* userType, \
+ ::NYql::NUdf::IFunctionTypeInfoBuilder& builder, \
bool typesOnly) { \
Y_UNUSED(userType); \
if (Name() == name) { \
@@ -87,13 +87,13 @@ namespace NUdf {
} \
} \
private: \
- ::NYql::NUdf::TSourcePosition Pos_; \
+ ::NYql::NUdf::TSourcePosition Pos_; \
members \
}; \
- ::NYql::NUdf::TUnboxedValue udfName::RunImpl( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const
-
+ ::NYql::NUdf::TUnboxedValue udfName::RunImpl( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const
+
#define UDF_IMPL(udfName, typeBody, members, init, irResourceId, irFunctionName) \
UDF_IMPL_EX(udfName, typeBody, members, init, irResourceId, irFunctionName, builder.Implementation(new udfName(builder));)
@@ -104,32 +104,32 @@ namespace NUdf {
members \
}; \
\
- class udfName: public ::NYql::NUdf::TBoxedValue, public udfName##Members { \
+ class udfName: public ::NYql::NUdf::TBoxedValue, public udfName##Members { \
public: \
- explicit udfName(::NYql::NUdf::IFunctionTypeInfoBuilder& builder) \
+ explicit udfName(::NYql::NUdf::IFunctionTypeInfoBuilder& builder) \
: Pos_(GetSourcePosition(builder)) \
{ \
init \
} \
- static const ::NYql::NUdf::TStringRef& Name() { \
- static auto name = ::NYql::NUdf::TStringRef::Of(#udfName).Substring(1, 256); \
+ static const ::NYql::NUdf::TStringRef& Name() { \
+ static auto name = ::NYql::NUdf::TStringRef::Of(#udfName).Substring(1, 256); \
return name; \
} \
class TImpl: public TBoxedValue, public udfName##Members { \
public: \
TImpl(const udfName##Members& parent, \
- const ::NYql::NUdf::TUnboxedValuePod& runConfig, \
- ::NYql::NUdf::TSourcePosition pos) \
+ const ::NYql::NUdf::TUnboxedValuePod& runConfig, \
+ ::NYql::NUdf::TSourcePosition pos) \
: udfName##Members(parent) \
- , RunConfig(::NYql::NUdf::TUnboxedValuePod(runConfig)) \
+ , RunConfig(::NYql::NUdf::TUnboxedValuePod(runConfig)) \
, Pos_(pos) \
{} \
- inline ::NYql::NUdf::TUnboxedValue RunImpl( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const; \
- ::NYql::NUdf::TUnboxedValue Run( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
+ inline ::NYql::NUdf::TUnboxedValue RunImpl( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const; \
+ ::NYql::NUdf::TUnboxedValue Run( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
try { \
return RunImpl(valueBuilder, args); \
} catch (const std::exception&) { \
@@ -142,19 +142,19 @@ namespace NUdf {
} \
\
private: \
- ::NYql::NUdf::TUnboxedValue RunConfig; \
- ::NYql::NUdf::TSourcePosition Pos_; \
+ ::NYql::NUdf::TUnboxedValue RunConfig; \
+ ::NYql::NUdf::TSourcePosition Pos_; \
}; \
- ::NYql::NUdf::TUnboxedValue Run( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
+ ::NYql::NUdf::TUnboxedValue Run( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const override { \
Y_UNUSED(valueBuilder); \
- return ::NYql::NUdf::TUnboxedValuePod(new TImpl(*this, args[0], Pos_)); \
+ return ::NYql::NUdf::TUnboxedValuePod(new TImpl(*this, args[0], Pos_)); \
} \
static bool DeclareSignature( \
- const ::NYql::NUdf::TStringRef& name, \
- ::NYql::NUdf::TType* userType, \
- ::NYql::NUdf::IFunctionTypeInfoBuilder& builder, \
+ const ::NYql::NUdf::TStringRef& name, \
+ ::NYql::NUdf::TType* userType, \
+ ::NYql::NUdf::IFunctionTypeInfoBuilder& builder, \
bool typesOnly) { \
Y_UNUSED(userType); \
if (Name() == name) { \
@@ -168,17 +168,17 @@ namespace NUdf {
} \
} \
private: \
- ::NYql::NUdf::TSourcePosition Pos_; \
+ ::NYql::NUdf::TSourcePosition Pos_; \
}; \
- ::NYql::NUdf::TUnboxedValue udfName::TImpl::RunImpl( \
- const ::NYql::NUdf::IValueBuilder* valueBuilder, \
- const ::NYql::NUdf::TUnboxedValuePod* args) const
-
+ ::NYql::NUdf::TUnboxedValue udfName::TImpl::RunImpl( \
+ const ::NYql::NUdf::IValueBuilder* valueBuilder, \
+ const ::NYql::NUdf::TUnboxedValuePod* args) const
+
#define UDF_RUN(udfName, typeBody) UDF_RUN_IMPL(udfName, typeBody, ;, ;, "", "")
#define SIMPLE_UDF(udfName, signature) \
UDF(udfName, builder.SimpleSignature<signature>();)
-
+
#define SIMPLE_UDF_WITH_IR(udfName, signature, irResourceId, irFunctionName) \
UDF_IMPL(udfName, builder.SimpleSignature<signature>();, ;, ;, irResourceId, irFunctionName)
@@ -187,46 +187,46 @@ namespace NUdf {
#define SIMPLE_UDF_OPTIONS(udfName, signature, options) \
UDF(udfName, builder.SimpleSignature<signature>(); options;)
-
+
#define SIMPLE_UDF_RUN_OPTIONS(udfName, signature, options) \
UDF_RUN(udfName, builder.SimpleSignature<signature>(); options;)
-
+
#define SIMPLE_UDF_RUN(udfName, signature, runConfigSignature) \
SIMPLE_UDF_RUN_OPTIONS(udfName, signature, builder.RunConfig<runConfigSignature>())
-
+
#define SIMPLE_MODULE(moduleName, ...) \
- class moduleName: public ::NYql::NUdf::TSimpleUdfModuleHelper<__VA_ARGS__> { \
+ class moduleName: public ::NYql::NUdf::TSimpleUdfModuleHelper<__VA_ARGS__> { \
public: \
- ::NYql::NUdf::TStringRef Name() const { \
- auto name = ::NYql::NUdf::TStringRef::Of(#moduleName); \
+ ::NYql::NUdf::TStringRef Name() const { \
+ auto name = ::NYql::NUdf::TStringRef::Of(#moduleName); \
return name.Substring(1, name.Size() - 7); \
} \
};
-
-#define EMPTY_RESULT_ON_EMPTY_ARG(n) \
- if (!args[n]) { \
- return ::NYql::NUdf::TUnboxedValue(); \
+
+#define EMPTY_RESULT_ON_EMPTY_ARG(n) \
+ if (!args[n]) { \
+ return ::NYql::NUdf::TUnboxedValue(); \
}
-namespace NYql {
+namespace NYql {
namespace NUdf {
template<bool CheckOptional, const char* TFuncName, template<class> class TFunc, typename... TUserTypes>
-class TUserDataTypeFuncFactory : public ::NYql::NUdf::TBoxedValue {
+class TUserDataTypeFuncFactory : public ::NYql::NUdf::TBoxedValue {
public:
typedef bool TTypeAwareMarker;
public:
- static const ::NYql::NUdf::TStringRef& Name() {
- static auto name = ::NYql::NUdf::TStringRef(TFuncName, std::strlen(TFuncName));
+ static const ::NYql::NUdf::TStringRef& Name() {
+ static auto name = ::NYql::NUdf::TStringRef(TFuncName, std::strlen(TFuncName));
return name;
}
template<typename TUserType>
static bool DeclareSignatureImpl(
TDataTypeId typeId,
- ::NYql::NUdf::TType* userType,
- ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
+ ::NYql::NUdf::TType* userType,
+ ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
bool typesOnly)
{
if (TDataType<TUserType>::Id != typeId) {
@@ -239,8 +239,8 @@ public:
template<typename TUserType, typename THead, typename... TTail>
static bool DeclareSignatureImpl(
TDataTypeId typeId,
- ::NYql::NUdf::TType* userType,
- ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
+ ::NYql::NUdf::TType* userType,
+ ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
bool typesOnly)
{
if (DeclareSignatureImpl<TUserType>(typeId, userType, builder, typesOnly)) {
@@ -250,9 +250,9 @@ public:
}
static bool DeclareSignature(
- const ::NYql::NUdf::TStringRef& name,
- ::NYql::NUdf::TType* userType,
- ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
+ const ::NYql::NUdf::TStringRef& name,
+ ::NYql::NUdf::TType* userType,
+ ::NYql::NUdf::IFunctionTypeInfoBuilder& builder,
bool typesOnly)
{
if (Name() != name) {
@@ -297,7 +297,7 @@ public:
auto typeId = dataTypeInspector.GetTypeId();
if (!DeclareSignatureImpl<TUserTypes...>(typeId, userType, builder, typesOnly)) {
TStringBuilder sb;
- sb << "User type " << NYql::NUdf::GetDataTypeInfo(NYql::NUdf::GetDataSlot(typeId)).Name << " is not supported";
+ sb << "User type " << NYql::NUdf::GetDataTypeInfo(NYql::NUdf::GetDataSlot(typeId)).Name << " is not supported";
builder.SetError(sb);
}
@@ -315,7 +315,7 @@ public:
}
template<typename TUdfType>
- void GetAllFunctionsImpl(IFunctionNamesSink& names) const {
+ void GetAllFunctionsImpl(IFunctionNamesSink& names) const {
auto r = names.Add(TUdfType::Name());
if (THasTTypeAwareMarker<TUdfType>::value) {
r->SetTypeAwareness();
@@ -323,9 +323,9 @@ public:
}
template<typename THead1, typename THead2, typename... TTail>
- void GetAllFunctionsImpl(IFunctionNamesSink& names) const {
- GetAllFunctionsImpl<THead1>(names);
- GetAllFunctionsImpl<THead2, TTail...>(names);
+ void GetAllFunctionsImpl(IFunctionNamesSink& names) const {
+ GetAllFunctionsImpl<THead1>(names);
+ GetAllFunctionsImpl<THead2, TTail...>(names);
}
template<typename TUdfType>
@@ -356,8 +356,8 @@ public:
return found;
}
- void GetAllFunctions(IFunctionsSink& sink) const final {
- GetAllFunctionsImpl<TUdfs...>(sink);
+ void GetAllFunctions(IFunctionsSink& sink) const final {
+ GetAllFunctionsImpl<TUdfs...>(sink);
}
void BuildFunctionTypeInfo(
@@ -382,4 +382,4 @@ public:
};
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_ptr.h b/ydb/library/yql/public/udf/udf_ptr.h
index e5dd9a204a..44debb7856 100644
--- a/ydb/library/yql/public/udf/udf_ptr.h
+++ b/ydb/library/yql/public/udf/udf_ptr.h
@@ -3,7 +3,7 @@
#include <util/system/yassert.h> // Y_ASSERT
-namespace NYql {
+namespace NYql {
namespace NUdf {
namespace NDetails {
@@ -216,4 +216,4 @@ private:
};
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_registrator.h b/ydb/library/yql/public/udf/udf_registrator.h
index 8560d85974..4d195d7eda 100644
--- a/ydb/library/yql/public/udf/udf_registrator.h
+++ b/ydb/library/yql/public/udf/udf_registrator.h
@@ -4,7 +4,7 @@
#include "udf_types.h"
#include "udf_ptr.h"
#include "udf_string.h"
-#include "udf_value.h"
+#include "udf_value.h"
#include <functional>
@@ -23,81 +23,81 @@
#ifdef BUILD_UDF
#define REGISTER_MODULES(...) \
extern "C" UDF_API void Register( \
- ::NYql::NUdf::IRegistrator& registrator, ui32 flags) { \
+ ::NYql::NUdf::IRegistrator& registrator, ui32 flags) { \
Y_UNUSED(flags); \
- ::NYql::NUdf::RegisterHelper<__VA_ARGS__>(registrator); \
+ ::NYql::NUdf::RegisterHelper<__VA_ARGS__>(registrator); \
} \
extern "C" UDF_API ui32 AbiVersion() { \
- return ::NYql::NUdf::CurrentAbiVersion(); \
+ return ::NYql::NUdf::CurrentAbiVersion(); \
}\
- extern "C" UDF_API void SetBackTraceCallback(::NYql::NUdf::TBackTraceCallback callback) { \
- ::NYql::NUdf::SetBackTraceCallbackImpl(callback); \
+ extern "C" UDF_API void SetBackTraceCallback(::NYql::NUdf::TBackTraceCallback callback) { \
+ ::NYql::NUdf::SetBackTraceCallbackImpl(callback); \
}
#else
#define REGISTER_MODULES(...) \
namespace { \
struct TYqlStaticUdfRegistrator { \
inline TYqlStaticUdfRegistrator() { \
- ::NYql::NUdf::AddToStaticUdfRegistry<__VA_ARGS__>(); \
+ ::NYql::NUdf::AddToStaticUdfRegistry<__VA_ARGS__>(); \
} \
} YQL_REGISTRATOR; \
}
#endif
-namespace NYql {
+namespace NYql {
namespace NUdf {
class IFunctionTypeInfoBuilder;
struct TStaticSymbols {
void* (*UdfAllocateFunc)(ui64 size);
- void (*UdfFreeFunc)(const void* mem);
- void (*UdfTerminate)(const char* message);
- void (*UdfRegisterObject)(TBoxedValue* object);
- void (*UdfUnregisterObject)(TBoxedValue* object);
+ void (*UdfFreeFunc)(const void* mem);
+ void (*UdfTerminate)(const char* message);
+ void (*UdfRegisterObject)(TBoxedValue* object);
+ void (*UdfUnregisterObject)(TBoxedValue* object);
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
void* (*UdfAllocateWithSizeFunc)(ui64 size);
- void (*UdfFreeWithSizeFunc)(const void* mem, ui64 size);
+ void (*UdfFreeWithSizeFunc)(const void* mem, ui64 size);
#endif
};
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
UDF_ASSERT_TYPE_SIZE(TStaticSymbols, 56);
#else
-UDF_ASSERT_TYPE_SIZE(TStaticSymbols, 40);
+UDF_ASSERT_TYPE_SIZE(TStaticSymbols, 40);
#endif
-
+
inline TStaticSymbols GetStaticSymbols();
-
+
+//////////////////////////////////////////////////////////////////////////////
+// IFunctionNamesSink
+//////////////////////////////////////////////////////////////////////////////
+class IFunctionDescriptor
+{
+public:
+ typedef TUniquePtr<IFunctionDescriptor> TPtr;
+
+ virtual ~IFunctionDescriptor() = default;
+
+ virtual void SetTypeAwareness() = 0;
+};
+
+UDF_ASSERT_TYPE_SIZE(IFunctionDescriptor, 8);
+
//////////////////////////////////////////////////////////////////////////////
// IFunctionNamesSink
//////////////////////////////////////////////////////////////////////////////
-class IFunctionDescriptor
-{
-public:
- typedef TUniquePtr<IFunctionDescriptor> TPtr;
-
- virtual ~IFunctionDescriptor() = default;
-
- virtual void SetTypeAwareness() = 0;
-};
-
-UDF_ASSERT_TYPE_SIZE(IFunctionDescriptor, 8);
-
-//////////////////////////////////////////////////////////////////////////////
-// IFunctionNamesSink
-//////////////////////////////////////////////////////////////////////////////
-class IFunctionsSink
-{
-public:
- virtual ~IFunctionsSink() = default;
-
- virtual IFunctionDescriptor::TPtr Add(const TStringRef& name) = 0;
-};
-
-UDF_ASSERT_TYPE_SIZE(IFunctionsSink, 8);
-
-typedef IFunctionsSink IFunctionNamesSink;
+class IFunctionsSink
+{
+public:
+ virtual ~IFunctionsSink() = default;
+
+ virtual IFunctionDescriptor::TPtr Add(const TStringRef& name) = 0;
+};
+
+UDF_ASSERT_TYPE_SIZE(IFunctionsSink, 8);
+
+typedef IFunctionsSink IFunctionNamesSink;
//////////////////////////////////////////////////////////////////////////////
// IUdfModule
@@ -114,7 +114,7 @@ public:
public:
virtual ~IUdfModule() = default;
- virtual void GetAllFunctions(IFunctionsSink& sink) const = 0;
+ virtual void GetAllFunctions(IFunctionsSink& sink) const = 0;
virtual void BuildFunctionTypeInfo(
const TStringRef& name,
@@ -194,16 +194,16 @@ static inline void AddToStaticUdfRegistry() {
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
-extern "C" UDF_API void Register(NYql::NUdf::IRegistrator& registrator, ui32 flags);
+extern "C" UDF_API void Register(NYql::NUdf::IRegistrator& registrator, ui32 flags);
extern "C" UDF_API ui32 AbiVersion();
#if defined(_win_) || defined(_darwin_)
-extern "C" UDF_API void BindSymbols(const NYql::NUdf::TStaticSymbols& symbols);
+extern "C" UDF_API void BindSymbols(const NYql::NUdf::TStaticSymbols& symbols);
#endif
-extern "C" UDF_API void SetBackTraceCallback(NYql::NUdf::TBackTraceCallback callback);
+extern "C" UDF_API void SetBackTraceCallback(NYql::NUdf::TBackTraceCallback callback);
-namespace NYql {
+namespace NYql {
namespace NUdf {
#ifndef BUILD_UDF
diff --git a/ydb/library/yql/public/udf/udf_static_registry.cpp b/ydb/library/yql/public/udf/udf_static_registry.cpp
index ce41c95bd4..b6efa4872c 100644
--- a/ydb/library/yql/public/udf/udf_static_registry.cpp
+++ b/ydb/library/yql/public/udf/udf_static_registry.cpp
@@ -3,7 +3,7 @@
#include <util/generic/singleton.h>
#include <util/generic/vector.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
TUdfModuleWrapperList* StaticUdfModuleWrapperList() {
diff --git a/ydb/library/yql/public/udf/udf_static_registry.h b/ydb/library/yql/public/udf/udf_static_registry.h
index 0ecd104ebe..e50b05ffac 100644
--- a/ydb/library/yql/public/udf/udf_static_registry.h
+++ b/ydb/library/yql/public/udf/udf_static_registry.h
@@ -4,7 +4,7 @@
#include <util/generic/vector.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
using TUdfModuleWrapperList = TVector<TUdfModuleWrapper>;
diff --git a/ydb/library/yql/public/udf/udf_string.h b/ydb/library/yql/public/udf/udf_string.h
index 63de6eddbd..7c687ffbf4 100644
--- a/ydb/library/yql/public/udf/udf_string.h
+++ b/ydb/library/yql/public/udf/udf_string.h
@@ -1,15 +1,15 @@
#pragma once
#include "udf_types.h"
-#include "udf_allocator.h"
-#include "udf_string_ref.h"
+#include "udf_allocator.h"
+#include "udf_string_ref.h"
#include <util/generic/strbuf.h>
#include <util/system/align.h>
#include <new>
-namespace NYql {
+namespace NYql {
namespace NUdf {
//////////////////////////////////////////////////////////////////////////////
@@ -18,68 +18,68 @@ namespace NUdf {
class TStringValue
{
friend class TUnboxedValue;
- friend class TUnboxedValuePod;
+ friend class TUnboxedValuePod;
class TData {
friend class TStringValue;
public:
- inline TData(ui32 size, ui32 cap)
+ inline TData(ui32 size, ui32 cap)
: Size_(size)
- , Refs_(1)
- , Capacity_(cap)
+ , Refs_(1)
+ , Capacity_(cap)
, Reserved_(0)
- {
- Y_UNUSED(Reserved_);
- }
-
- inline i32 RefCount() const { return Refs_; }
- inline void Ref() {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- Refs_++;
- }
- inline void UnRef() {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- Y_VERIFY_DEBUG(Refs_ > 0);
- if (!--Refs_) {
+ {
+ Y_UNUSED(Reserved_);
+ }
+
+ inline i32 RefCount() const { return Refs_; }
+ inline void Ref() {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
+ Refs_++;
+ }
+ inline void UnRef() {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
+ Y_VERIFY_DEBUG(Refs_ > 0);
+ if (!--Refs_) {
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
UdfFreeWithSize(this, sizeof(*this) + Capacity_);
#else
- UdfFree(this);
+ UdfFree(this);
+#endif
+ }
+ }
+ inline void ReleaseRef() {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
+ Y_VERIFY_DEBUG(Refs_ > 0);
+ --Refs_;
+ }
+ inline void DeleteUnreferenced() {
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
#endif
- }
- }
- inline void ReleaseRef() {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- Y_VERIFY_DEBUG(Refs_ > 0);
- --Refs_;
- }
- inline void DeleteUnreferenced() {
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- if (!Refs_) {
+ if (!Refs_) {
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 8)
UdfFreeWithSize(this, sizeof(*this) + Capacity_);
#else
- UdfFree(this);
+ UdfFree(this);
#endif
- }
- }
-
- inline char* Data() const { return (char*)(this+1); }
- inline ui32 Size() const { return Size_; }
- inline bool Empty() const { return Size_ == 0; }
- inline ui32 Capacity() const { return Capacity_; }
+ }
+ }
+
+ inline char* Data() const { return (char*)(this+1); }
+ inline ui32 Size() const { return Size_; }
+ inline bool Empty() const { return Size_ == 0; }
+ inline ui32 Capacity() const { return Capacity_; }
inline i32 LockRef() noexcept {
Y_VERIFY_DEBUG(Refs_ != -1);
@@ -94,84 +94,84 @@ class TStringValue
Refs_ = prev;
}
- private:
- ui32 Size_;
- i32 Refs_;
- ui32 Capacity_;
- ui32 Reserved_;
- };
-
- UDF_ASSERT_TYPE_SIZE(TData, 16);
-
-public:
+ private:
+ ui32 Size_;
+ i32 Refs_;
+ ui32 Capacity_;
+ ui32 Reserved_;
+ };
+
+ UDF_ASSERT_TYPE_SIZE(TData, 16);
+
+public:
inline explicit TStringValue(ui32 size): Data_(AllocateData(size, size)) {}
- inline explicit TStringValue(TData* data): Data_(data) { Ref(); }
-
- inline TStringValue(const TStringValue& rhs): Data_(rhs.Data_) { Ref(); }
- inline TStringValue(TStringValue&& rhs): Data_(rhs.Data_) { rhs.Data_ = nullptr; }
-
- inline ~TStringValue() { UnRef(); }
-
- inline TStringValue& operator=(const TStringValue& rhs) {
- if (this != &rhs) {
- UnRef();
- Data_ = rhs.Data_;
- Ref();
- }
-
- return *this;
- }
-
- TStringValue& operator=(TStringValue&& rhs) {
- if (this != &rhs) {
- UnRef();
- Data_ = rhs.Data_;
- rhs.Data_ = nullptr;
- }
-
- return *this;
- }
-
- inline ui32 Capacity() const { return Data_->Capacity(); }
- inline ui32 Size() const { return Data_->Size(); }
- inline char* Data() const { return Data_->Data(); }
-
- inline void Ref() {
- if (Data_ != nullptr) {
- Data_->Ref();
- }
- }
-
- inline void UnRef() {
- if (Data_ != nullptr) {
- Data_->UnRef();
- Data_ = nullptr;
- }
- }
-
- inline void ReleaseRef() {
- if (Data_ != nullptr) {
- Data_->ReleaseRef();
- Data_ = nullptr;
- }
- }
-
+ inline explicit TStringValue(TData* data): Data_(data) { Ref(); }
+
+ inline TStringValue(const TStringValue& rhs): Data_(rhs.Data_) { Ref(); }
+ inline TStringValue(TStringValue&& rhs): Data_(rhs.Data_) { rhs.Data_ = nullptr; }
+
+ inline ~TStringValue() { UnRef(); }
+
+ inline TStringValue& operator=(const TStringValue& rhs) {
+ if (this != &rhs) {
+ UnRef();
+ Data_ = rhs.Data_;
+ Ref();
+ }
+
+ return *this;
+ }
+
+ TStringValue& operator=(TStringValue&& rhs) {
+ if (this != &rhs) {
+ UnRef();
+ Data_ = rhs.Data_;
+ rhs.Data_ = nullptr;
+ }
+
+ return *this;
+ }
+
+ inline ui32 Capacity() const { return Data_->Capacity(); }
+ inline ui32 Size() const { return Data_->Size(); }
+ inline char* Data() const { return Data_->Data(); }
+
+ inline void Ref() {
+ if (Data_ != nullptr) {
+ Data_->Ref();
+ }
+ }
+
+ inline void UnRef() {
+ if (Data_ != nullptr) {
+ Data_->UnRef();
+ Data_ = nullptr;
+ }
+ }
+
+ inline void ReleaseRef() {
+ if (Data_ != nullptr) {
+ Data_->ReleaseRef();
+ Data_ = nullptr;
+ }
+ }
+
inline i32 RefCount() const {
- return Data_->RefCount();
- }
-
- bool TryExpandOn(ui32 len) {
+ return Data_->RefCount();
+ }
+
+ bool TryExpandOn(ui32 len) {
if (RefCount() < 0)
return false;
- const auto size = Data_->Size_ + len;
- if (Data_->Capacity_ < size)
- return false;
-
- Data_->Size_ = size;
- return true;
- }
-
+ const auto size = Data_->Size_ + len;
+ if (Data_->Capacity_ < size)
+ return false;
+
+ Data_->Size_ = size;
+ return true;
+ }
+
inline i32 LockRef() noexcept {
return Data_->LockRef();
}
@@ -180,20 +180,20 @@ public:
Data_->UnlockRef(prev);
}
-private:
- inline TData* GetBuf() const {
- return Data_;
- }
-
- inline TData* ReleaseBuf() {
- if (const auto data = Data_) {
- Data_ = nullptr;
- data->ReleaseRef();
- return data;
- }
- return nullptr;
- }
-
+private:
+ inline TData* GetBuf() const {
+ return Data_;
+ }
+
+ inline TData* ReleaseBuf() {
+ if (const auto data = Data_) {
+ Data_ = nullptr;
+ data->ReleaseRef();
+ return data;
+ }
+ return nullptr;
+ }
+
public:
static TData* AllocateData(ui32 len, ui32 cap) {
cap = AlignUp(cap, ui32(16));
@@ -204,11 +204,11 @@ public:
return ::new(UdfAllocate(dataSize)) TData(len, cap);
#endif
}
-
- TData* Data_;
-};
-
+
+ TData* Data_;
+};
+
UDF_ASSERT_TYPE_SIZE(TStringValue, 8);
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_string_ref.h b/ydb/library/yql/public/udf/udf_string_ref.h
index cab3383f9f..75a82b81e6 100644
--- a/ydb/library/yql/public/udf/udf_string_ref.h
+++ b/ydb/library/yql/public/udf/udf_string_ref.h
@@ -4,134 +4,134 @@
#include <util/generic/strbuf.h>
-#include <algorithm>
+#include <algorithm>
#include <string_view>
-#include <type_traits>
-
-namespace NYql {
+#include <type_traits>
+
+namespace NYql {
namespace NUdf {
//////////////////////////////////////////////////////////////////////////////
-// TStringRefBase
+// TStringRefBase
//////////////////////////////////////////////////////////////////////////////
-template<bool Const>
-class TStringRefBase
+template<bool Const>
+class TStringRefBase
{
public:
typedef std::conditional_t<Const, const char*, char*> TDataType;
-protected:
- inline constexpr TStringRefBase() noexcept = default;
+protected:
+ inline constexpr TStringRefBase() noexcept = default;
- inline constexpr TStringRefBase(TDataType data, ui32 size) noexcept
+ inline constexpr TStringRefBase(TDataType data, ui32 size) noexcept
: Data_(data)
, Size_(size)
- {}
-
-public:
- inline constexpr operator std::string_view() const noexcept { return { Data_, Size_ }; }
- inline constexpr operator TStringBuf() const noexcept { return { Data_, Size_ }; }
- inline constexpr TDataType Data() const noexcept { return Data_; }
- inline constexpr ui32 Size() const noexcept { return Size_; }
- inline constexpr bool Empty() const noexcept { return Size_ == 0; }
-
-protected:
- TDataType Data_ = nullptr;
- ui32 Size_ = 0U;
+ {}
+
+public:
+ inline constexpr operator std::string_view() const noexcept { return { Data_, Size_ }; }
+ inline constexpr operator TStringBuf() const noexcept { return { Data_, Size_ }; }
+ inline constexpr TDataType Data() const noexcept { return Data_; }
+ inline constexpr ui32 Size() const noexcept { return Size_; }
+ inline constexpr bool Empty() const noexcept { return Size_ == 0; }
+
+protected:
+ TDataType Data_ = nullptr;
+ ui32 Size_ = 0U;
ui8 Reserved_[4] = {};
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// TMutableStringRef
-//////////////////////////////////////////////////////////////////////////////
-class TMutableStringRef : public TStringRefBase<false>
-{
-public:
- typedef TStringRefBase<false> TBase;
-
- inline constexpr TMutableStringRef(TDataType data, ui32 size) noexcept
- : TBase(data, size)
- {}
-};
-
-UDF_ASSERT_TYPE_SIZE(TMutableStringRef, 16);
-
-//////////////////////////////////////////////////////////////////////////////
-// TStringRef
-//////////////////////////////////////////////////////////////////////////////
-class TStringRef : public TStringRefBase<true>
-{
-public:
- typedef TStringRefBase<true> TBase;
-
- inline constexpr TStringRef() noexcept = default;
-
- inline constexpr TStringRef(TDataType data, ui32 size) noexcept
- : TBase(data, size)
- {}
-
- template<size_t Size>
- inline constexpr TStringRef(const char (&data)[Size]) noexcept
- : TBase(data, Size - 1)
- {}
-
- inline constexpr TStringRef(const TMutableStringRef& buf) noexcept
- : TBase(buf.Data(), buf.Size())
- {}
-
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// TMutableStringRef
+//////////////////////////////////////////////////////////////////////////////
+class TMutableStringRef : public TStringRefBase<false>
+{
+public:
+ typedef TStringRefBase<false> TBase;
+
+ inline constexpr TMutableStringRef(TDataType data, ui32 size) noexcept
+ : TBase(data, size)
+ {}
+};
+
+UDF_ASSERT_TYPE_SIZE(TMutableStringRef, 16);
+
+//////////////////////////////////////////////////////////////////////////////
+// TStringRef
+//////////////////////////////////////////////////////////////////////////////
+class TStringRef : public TStringRefBase<true>
+{
+public:
+ typedef TStringRefBase<true> TBase;
+
+ inline constexpr TStringRef() noexcept = default;
+
+ inline constexpr TStringRef(TDataType data, ui32 size) noexcept
+ : TBase(data, size)
+ {}
+
+ template<size_t Size>
+ inline constexpr TStringRef(const char (&data)[Size]) noexcept
+ : TBase(data, Size - 1)
+ {}
+
+ inline constexpr TStringRef(const TMutableStringRef& buf) noexcept
+ : TBase(buf.Data(), buf.Size())
+ {}
+
template <typename TStringType>
- inline constexpr TStringRef(const TStringType& buf) noexcept
+ inline constexpr TStringRef(const TStringType& buf) noexcept
: TBase(TGetData<TStringType>::Get(buf), TGetSize<TStringType>::Get(buf))
- {}
+ {}
template <size_t size>
- inline static constexpr TStringRef Of(const char(&str)[size]) noexcept {
- return TStringRef(str);
+ inline static constexpr TStringRef Of(const char(&str)[size]) noexcept {
+ return TStringRef(str);
}
- inline constexpr TStringRef& Trunc(ui32 len) noexcept {
+ inline constexpr TStringRef& Trunc(ui32 len) noexcept {
if (Size_ > len) {
Size_ = len;
}
return *this;
}
- inline constexpr TStringRef Substring(ui32 start, ui32 count) const noexcept {
- start = std::min(start, Size_);
- count = std::min(count, Size_ - start);
+ inline constexpr TStringRef Substring(ui32 start, ui32 count) const noexcept {
+ start = std::min(start, Size_);
+ count = std::min(count, Size_ - start);
return TStringRef(Data_ + start, count);
}
- inline constexpr bool operator==(const TStringRef& rhs) const noexcept {
+ inline constexpr bool operator==(const TStringRef& rhs) const noexcept {
return Compare(*this, rhs) == 0;
}
- inline constexpr bool operator!=(const TStringRef& rhs) const noexcept {
- return Compare(*this, rhs) != 0;
+ inline constexpr bool operator!=(const TStringRef& rhs) const noexcept {
+ return Compare(*this, rhs) != 0;
}
- inline constexpr bool operator<(const TStringRef& rhs) const noexcept {
+ inline constexpr bool operator<(const TStringRef& rhs) const noexcept {
return Compare(*this, rhs) < 0;
}
- inline constexpr bool operator<=(const TStringRef& rhs) const noexcept {
+ inline constexpr bool operator<=(const TStringRef& rhs) const noexcept {
return Compare(*this, rhs) <= 0;
}
- inline constexpr bool operator>(const TStringRef& rhs) const noexcept {
+ inline constexpr bool operator>(const TStringRef& rhs) const noexcept {
return Compare(*this, rhs) > 0;
}
- inline constexpr bool operator>=(const TStringRef& rhs) const noexcept {
+ inline constexpr bool operator>=(const TStringRef& rhs) const noexcept {
return Compare(*this, rhs) >= 0;
}
private:
- inline static constexpr int Compare(const TStringRef& s1, const TStringRef& s2) noexcept {
+ inline static constexpr int Compare(const TStringRef& s1, const TStringRef& s2) noexcept {
auto minSize = std::min(s1.Size(), s2.Size());
if (const auto result = minSize > 0 ? std::memcmp(s1.Data(), s2.Data(), minSize) : 0)
- return result;
- return int(s1.Size()) - int(s2.Size());
+ return result;
+ return int(s1.Size()) - int(s2.Size());
}
Y_HAS_MEMBER(Data);
@@ -139,28 +139,28 @@ private:
template<typename TStringType>
struct TByData {
- static constexpr auto Get(const TStringType& buf) noexcept {
+ static constexpr auto Get(const TStringType& buf) noexcept {
return buf.Data();
}
};
template<typename TStringType>
struct TBySize {
- static constexpr auto Get(const TStringType& buf) noexcept {
+ static constexpr auto Get(const TStringType& buf) noexcept {
return buf.Size();
}
};
template<typename TStringType>
struct TBydata {
- static constexpr auto Get(const TStringType& buf) noexcept {
+ static constexpr auto Get(const TStringType& buf) noexcept {
return buf.data();
}
};
template<typename TStringType>
struct TBysize {
- static constexpr auto Get(const TStringType& buf) noexcept {
+ static constexpr auto Get(const TStringType& buf) noexcept {
return buf.size();
}
};
@@ -175,4 +175,4 @@ private:
UDF_ASSERT_TYPE_SIZE(TStringRef, 16);
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_terminator.h b/ydb/library/yql/public/udf/udf_terminator.h
index 2d64e0b3c7..b94c7975d3 100644
--- a/ydb/library/yql/public/udf/udf_terminator.h
+++ b/ydb/library/yql/public/udf/udf_terminator.h
@@ -1,12 +1,12 @@
-#pragma once
+#pragma once
#include <util/system/compiler.h>
-
-namespace NYql {
+
+namespace NYql {
namespace NUdf {
class TBoxedValue;
}
}
extern "C" [[noreturn]] void UdfTerminate(const char* message);
-extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object);
-extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object);
+extern "C" void UdfRegisterObject(::NYql::NUdf::TBoxedValue* object);
+extern "C" void UdfUnregisterObject(::NYql::NUdf::TBoxedValue* object);
diff --git a/ydb/library/yql/public/udf/udf_type_builder.h b/ydb/library/yql/public/udf/udf_type_builder.h
index 21ef1e317e..8bfc73a449 100644
--- a/ydb/library/yql/public/udf/udf_type_builder.h
+++ b/ydb/library/yql/public/udf/udf_type_builder.h
@@ -3,12 +3,12 @@
#include "udf_counter.h"
#include "udf_types.h"
#include "udf_ptr.h"
-#include "udf_string_ref.h"
+#include "udf_string_ref.h"
#include "udf_value.h"
-#include <type_traits>
+#include <type_traits>
-namespace NYql {
+namespace NYql {
namespace NUdf {
class TStringRef;
@@ -48,11 +48,11 @@ struct TTuple;
template <const char* Tag>
struct TResource {};
-template <typename... TArgs>
-struct TVariant;
+template <typename... TArgs>
+struct TVariant;
-template <typename T>
-struct TStream { using ItemType = T; };
+template <typename T>
+struct TStream { using ItemType = T; };
template <typename T, const char* Tag>
struct TTagged { using BaseType = T; };
@@ -525,13 +525,13 @@ public:
virtual ICompare::TPtr MakeCompare(const TType* type) = 0;
};
#endif
-
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
class IFunctionTypeInfoBuilder6: public IFunctionTypeInfoBuilder5 {
public:
- virtual TType* Decimal(ui8 precision, ui8 scale) const = 0;
+ virtual TType* Decimal(ui8 precision, ui8 scale) const = 0;
};
-#endif
+#endif
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 16)
class IFunctionTypeInfoBuilder7: public IFunctionTypeInfoBuilder6 {
@@ -746,19 +746,19 @@ struct TTypeBuilderHelper<void> {
}
};
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
-template <ui8 Precision, ui8 Scale>
-struct TTypeBuilderHelper<TDecimalDataType<Precision, Scale>> {
- static TType* Build(const IFunctionTypeInfoBuilder& builder) {
- return builder.Decimal(Precision, Scale);
- }
-};
-#endif
-
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+template <ui8 Precision, ui8 Scale>
+struct TTypeBuilderHelper<TDecimalDataType<Precision, Scale>> {
+ static TType* Build(const IFunctionTypeInfoBuilder& builder) {
+ return builder.Decimal(Precision, Scale);
+ }
+};
+#endif
+
template <const char* Tag>
struct TTypeBuilderHelper<TResource<Tag>> {
static TType* Build(const IFunctionTypeInfoBuilder& builder) {
- return builder.Resource(TStringRef(Tag, std::strlen(Tag)));
+ return builder.Resource(TStringRef(Tag, std::strlen(Tag)));
}
};
@@ -790,14 +790,14 @@ struct TTypeBuilderHelper<TDict<TKey, TValue>> {
}
};
-template <typename T>
-struct TTypeBuilderHelper<TStream<T>> {
- static TType* Build(const IFunctionTypeInfoBuilder& builder) {
- return builder.Stream()->
- Item(TTypeBuilderHelper<T>::Build(builder))
- .Build();
- }
-};
+template <typename T>
+struct TTypeBuilderHelper<TStream<T>> {
+ static TType* Build(const IFunctionTypeInfoBuilder& builder) {
+ return builder.Stream()->
+ Item(TTypeBuilderHelper<T>::Build(builder))
+ .Build();
+ }
+};
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 21)
template <typename T, const char* Tag>
@@ -870,14 +870,14 @@ struct TTypeBuilderHelper<TTuple<TArgs...>> {
}
};
-template <typename... TArgs>
+template <typename... TArgs>
struct TTypeBuilderHelper<NUdf::TVariant<TArgs...>> {
- static TType* Build(const IFunctionTypeInfoBuilder& builder) {
- auto tupleBuilder = builder.Tuple(sizeof...(TArgs));
- TTupleHelper<TArgs...>::Add(*tupleBuilder, builder);
- return builder.Variant()->Over(*tupleBuilder).Build();
- }
-};
+ static TType* Build(const IFunctionTypeInfoBuilder& builder) {
+ auto tupleBuilder = builder.Tuple(sizeof...(TArgs));
+ TTupleHelper<TArgs...>::Add(*tupleBuilder, builder);
+ return builder.Variant()->Over(*tupleBuilder).Build();
+ }
+};
template <>
struct TArgsHelper<> {
@@ -910,7 +910,7 @@ struct TArgsHelper<TArg, TArgs...> {
static void Add(IFunctionArgTypesBuilder& builder, const char* name = nullptr, ui64 flags = 0) {
builder.Add(TTypeBuilderHelper<TArg>::Build(builder.Parent())).Flags(flags);
if (name) {
- builder.Name(TStringRef(name, std::strlen(name)));
+ builder.Name(TStringRef(name, std::strlen(name)));
}
TArgsHelper<TArgs...>::Add(builder);
}
@@ -934,4 +934,4 @@ inline IFunctionArgTypesBuilder& IFunctionArgTypesBuilder::Add()
}
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
diff --git a/ydb/library/yql/public/udf/udf_type_inspection.h b/ydb/library/yql/public/udf/udf_type_inspection.h
index f1fc5320e2..f11ea0ff07 100644
--- a/ydb/library/yql/public/udf/udf_type_inspection.h
+++ b/ydb/library/yql/public/udf/udf_type_inspection.h
@@ -10,7 +10,7 @@
#include <util/generic/ylimits.h> // Max
-namespace NYql {
+namespace NYql {
namespace NUdf {
//////////////////////////////////////////////////////////////////////////////
@@ -37,13 +37,13 @@ private:
void OnStream(const TType* itemType) override;
};
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
class TStubTypeVisitor2: public TStubTypeVisitor1
{
public:
- void OnDecimal(ui8 precision, ui8 scale) override;
+ void OnDecimal(ui8 precision, ui8 scale) override;
};
-#endif
+#endif
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15)
class TStubTypeVisitor3: public TStubTypeVisitor2
{
@@ -87,48 +87,48 @@ private:
void OnDataType(TDataTypeId typeId) override {
TypeId_ = typeId;
}
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
- void OnDecimal(ui8, ui8) override {}
-#endif
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+ void OnDecimal(ui8, ui8) override {}
+#endif
TDataTypeId TypeId_ = 0;
};
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
-//////////////////////////////////////////////////////////////////////////////
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+//////////////////////////////////////////////////////////////////////////////
// TDataAndDecimalTypeInspector
-//////////////////////////////////////////////////////////////////////////////
-class TDataAndDecimalTypeInspector: public TStubTypeVisitor
-{
-public:
- TDataAndDecimalTypeInspector(const ITypeInfoHelper& typeHelper, const TType* type) {
- if (typeHelper.GetTypeKind(type) == ETypeKind::Data) {
- typeHelper.VisitType(type, this);
- }
- }
-
- explicit operator bool() const { return TypeId_ != 0; }
- TDataTypeId GetTypeId() const { return TypeId_; }
+//////////////////////////////////////////////////////////////////////////////
+class TDataAndDecimalTypeInspector: public TStubTypeVisitor
+{
+public:
+ TDataAndDecimalTypeInspector(const ITypeInfoHelper& typeHelper, const TType* type) {
+ if (typeHelper.GetTypeKind(type) == ETypeKind::Data) {
+ typeHelper.VisitType(type, this);
+ }
+ }
+
+ explicit operator bool() const { return TypeId_ != 0; }
+ TDataTypeId GetTypeId() const { return TypeId_; }
ui8 GetPrecision() const {
return Precision_;
}
-
+
ui8 GetScale() const {
return Scale_;
}
-private:
- void OnDataType(TDataTypeId typeId) override {
- TypeId_ = typeId;
- }
-
- void OnDecimal(ui8 precision, ui8 scale) override {
+private:
+ void OnDataType(TDataTypeId typeId) override {
+ TypeId_ = typeId;
+ }
+
+ void OnDecimal(ui8 precision, ui8 scale) override {
Precision_ = precision;
Scale_ = scale;
- }
-
- TDataTypeId TypeId_ = 0;
+ }
+
+ TDataTypeId TypeId_ = 0;
ui8 Precision_ = 0, Scale_ = 0;
-};
-#endif
+};
+#endif
//////////////////////////////////////////////////////////////////////////////
// TStructTypeInspector
//////////////////////////////////////////////////////////////////////////////
@@ -522,4 +522,4 @@ inline void TStubTypeVisitor4::OnTagged(const TType*, TStringRef) {
#endif
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_type_ops.h b/ydb/library/yql/public/udf/udf_type_ops.h
index f88b146db2..4b2446c8fd 100644
--- a/ydb/library/yql/public/udf/udf_type_ops.h
+++ b/ydb/library/yql/public/udf/udf_type_ops.h
@@ -6,14 +6,14 @@
#include <util/generic/hash.h>
#include <util/digest/numeric.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
-using THashType = ui64;
-
+using THashType = ui64;
+
template <EDataSlot Type>
-inline THashType GetValueHash(const TUnboxedValuePod& value);
-inline THashType GetValueHash(EDataSlot type, const TUnboxedValuePod& value);
+inline THashType GetValueHash(const TUnboxedValuePod& value);
+inline THashType GetValueHash(EDataSlot type, const TUnboxedValuePod& value);
template <EDataSlot Type>
inline int CompareValues(const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs);
@@ -40,102 +40,102 @@ struct TUnboxedValueEquals {
// hash
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
-inline THashType GetIntegerHash(const TUnboxedValuePod& value) {
+inline THashType GetIntegerHash(const TUnboxedValuePod& value) {
return std::hash<T>()(value.Get<T>());
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
-inline THashType GetFloatHash(const TUnboxedValuePod& value) {
+inline THashType GetFloatHash(const TUnboxedValuePod& value) {
const auto x = value.Get<T>();
- return std::isunordered(x, x) ? ~0ULL : std::hash<T>()(x);
+ return std::isunordered(x, x) ? ~0ULL : std::hash<T>()(x);
}
-inline THashType GetStringHash(const TUnboxedValuePod& value) {
+inline THashType GetStringHash(const TUnboxedValuePod& value) {
return THash<TStringBuf>{}(value.AsStringRef());
}
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
-inline THashType GetTzIntegerHash(const TUnboxedValuePod& value) {
- return CombineHashes(std::hash<T>()(value.Get<T>()), std::hash<ui16>()(value.GetTimezoneId()));
+inline THashType GetTzIntegerHash(const TUnboxedValuePod& value) {
+ return CombineHashes(std::hash<T>()(value.Get<T>()), std::hash<ui16>()(value.GetTimezoneId()));
}
template <>
-inline THashType GetValueHash<EDataSlot::Bool>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Bool>(const TUnboxedValuePod& value) {
return std::hash<bool>()(value.Get<bool>());
}
template <>
-inline THashType GetValueHash<EDataSlot::Int8>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Int8>(const TUnboxedValuePod& value) {
return GetIntegerHash<i8>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Uint8>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Uint8>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui8>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Int16>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Int16>(const TUnboxedValuePod& value) {
return GetIntegerHash<i16>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Uint16>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Uint16>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui16>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Int32>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Int32>(const TUnboxedValuePod& value) {
return GetIntegerHash<i32>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Uint32>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Uint32>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui32>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Int64>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Int64>(const TUnboxedValuePod& value) {
return GetIntegerHash<i64>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Uint64>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Uint64>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui64>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Float>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Float>(const TUnboxedValuePod& value) {
return GetFloatHash<float>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Double>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Double>(const TUnboxedValuePod& value) {
return GetFloatHash<double>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::String>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::String>(const TUnboxedValuePod& value) {
return GetStringHash(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Utf8>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Utf8>(const TUnboxedValuePod& value) {
return GetStringHash(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Uuid>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Uuid>(const TUnboxedValuePod& value) {
return GetStringHash(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Yson>(const TUnboxedValuePod&) {
+inline THashType GetValueHash<EDataSlot::Yson>(const TUnboxedValuePod&) {
Y_FAIL("Yson isn't hashable.");
}
template <>
-inline THashType GetValueHash<EDataSlot::Json>(const TUnboxedValuePod&) {
+inline THashType GetValueHash<EDataSlot::Json>(const TUnboxedValuePod&) {
Y_FAIL("Json isn't hashable.");
}
@@ -145,52 +145,52 @@ inline THashType GetValueHash<EDataSlot::JsonDocument>(const TUnboxedValuePod&)
}
template <>
-inline THashType GetValueHash<EDataSlot::Date>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Date>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui16>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Datetime>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Datetime>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui32>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Timestamp>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Timestamp>(const TUnboxedValuePod& value) {
return GetIntegerHash<ui64>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Interval>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::Interval>(const TUnboxedValuePod& value) {
return GetIntegerHash<i64>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::TzDate>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::TzDate>(const TUnboxedValuePod& value) {
return GetTzIntegerHash<ui16>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::TzDatetime>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::TzDatetime>(const TUnboxedValuePod& value) {
return GetTzIntegerHash<ui32>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::TzTimestamp>(const TUnboxedValuePod& value) {
+inline THashType GetValueHash<EDataSlot::TzTimestamp>(const TUnboxedValuePod& value) {
return GetTzIntegerHash<ui64>(value);
}
template <>
-inline THashType GetValueHash<EDataSlot::Decimal>(const TUnboxedValuePod& value) {
- const auto pair = NYql::NDecimal::MakePair(value.GetInt128());
- return CombineHashes(pair.first, pair.second);
+inline THashType GetValueHash<EDataSlot::Decimal>(const TUnboxedValuePod& value) {
+ const auto pair = NYql::NDecimal::MakePair(value.GetInt128());
+ return CombineHashes(pair.first, pair.second);
}
-template <>
-inline THashType GetValueHash<EDataSlot::DyNumber>(const TUnboxedValuePod& value) {
- return GetStringHash(value);
-}
-
-inline THashType GetValueHash(EDataSlot type, const TUnboxedValuePod& value) {
+template <>
+inline THashType GetValueHash<EDataSlot::DyNumber>(const TUnboxedValuePod& value) {
+ return GetStringHash(value);
+}
+
+inline THashType GetValueHash(EDataSlot type, const TUnboxedValuePod& value) {
#define HASH_TYPE(slot, ...) \
case EDataSlot::slot: \
return GetValueHash<EDataSlot::slot>(value);
@@ -377,11 +377,11 @@ inline int CompareValues<EDataSlot::Decimal>(const TUnboxedValuePod& lhs, const
return x == y ? 0 : (x < y ? -1 : 1);
}
-template <>
-inline int CompareValues<EDataSlot::DyNumber>(const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
- return CompareStrings(lhs, rhs);
-}
-
+template <>
+inline int CompareValues<EDataSlot::DyNumber>(const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
+ return CompareStrings(lhs, rhs);
+}
+
inline int CompareValues(EDataSlot type, const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
#define COMPARE_TYPE(slot, ...) \
case EDataSlot::slot: \
@@ -545,11 +545,11 @@ inline bool EquateValues<EDataSlot::Decimal>(const TUnboxedValuePod& lhs, const
return lhs.GetInt128() == rhs.GetInt128();
}
-template <>
-inline bool EquateValues<EDataSlot::DyNumber>(const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
- return EquateStrings(lhs, rhs);
-}
-
+template <>
+inline bool EquateValues<EDataSlot::DyNumber>(const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
+ return EquateStrings(lhs, rhs);
+}
+
inline bool EquateValues(EDataSlot type, const TUnboxedValuePod& lhs, const TUnboxedValuePod& rhs) {
#define EQUATE_TYPE(slot, ...) \
case EDataSlot::slot: \
@@ -564,4 +564,4 @@ inline bool EquateValues(EDataSlot type, const TUnboxedValuePod& lhs, const TUnb
}
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
diff --git a/ydb/library/yql/public/udf/udf_type_printer.cpp b/ydb/library/yql/public/udf/udf_type_printer.cpp
index fc49366848..ceb13b783c 100644
--- a/ydb/library/yql/public/udf/udf_type_printer.cpp
+++ b/ydb/library/yql/public/udf/udf_type_printer.cpp
@@ -1,121 +1,121 @@
-#include "udf_type_printer.h"
-
-namespace NYql {
-namespace NUdf {
-
-namespace {
-static thread_local IOutputStream * Output_ = nullptr;
-}
-
+#include "udf_type_printer.h"
+
+namespace NYql {
+namespace NUdf {
+
+namespace {
+static thread_local IOutputStream * Output_ = nullptr;
+}
+
TTypePrinter1::TTypePrinter1(const ITypeInfoHelper& typeHelper, const TType* type)
- : TypeHelper_(typeHelper), Type_(type)
-{}
-
+ : TypeHelper_(typeHelper), Type_(type)
+{}
+
void TTypePrinter1::Out(IOutputStream &o) const {
- Output_ = &o;
- OutImpl(Type_);
- Output_ = nullptr;
-}
-
+ Output_ = &o;
+ OutImpl(Type_);
+ Output_ = nullptr;
+}
+
void TTypePrinter1::OutImpl(const TType* type) const {
- switch (TypeHelper_.GetTypeKind(type)) {
- case ETypeKind::Null: *Output_ << "Null"; break;
- case ETypeKind::Void: *Output_ << "Void"; break;
- case ETypeKind::EmptyList: *Output_ << "EmptyList"; break;
- case ETypeKind::EmptyDict: *Output_ << "EmptyDict"; break;
- case ETypeKind::Unknown: *Output_ << "Unknown"; break;
+ switch (TypeHelper_.GetTypeKind(type)) {
+ case ETypeKind::Null: *Output_ << "Null"; break;
+ case ETypeKind::Void: *Output_ << "Void"; break;
+ case ETypeKind::EmptyList: *Output_ << "EmptyList"; break;
+ case ETypeKind::EmptyDict: *Output_ << "EmptyDict"; break;
+ case ETypeKind::Unknown: *Output_ << "Unknown"; break;
default: TypeHelper_.VisitType(type, const_cast<TTypePrinter1*>(this));
- }
-}
-
+ }
+}
+
void TTypePrinter1::OnDataType(TDataTypeId typeId) {
- *Output_ << GetDataTypeInfo(GetDataSlot(typeId)).Name;
-}
-
+ *Output_ << GetDataTypeInfo(GetDataSlot(typeId)).Name;
+}
+
void TTypePrinter1::OnStruct(ui32 membersCount, TStringRef* membersNames, const TType** membersTypes) {
- *Output_ << "Struct<";
- for (ui32 i = 0U; i < membersCount; ++i) {
- *Output_ << "'" << std::string_view(membersNames[i]) << "':";
- OutImpl(membersTypes[i]);
- if (i < membersCount - 1U)
- *Output_ << ',';
-
- }
- *Output_ << '>';
-}
-
+ *Output_ << "Struct<";
+ for (ui32 i = 0U; i < membersCount; ++i) {
+ *Output_ << "'" << std::string_view(membersNames[i]) << "':";
+ OutImpl(membersTypes[i]);
+ if (i < membersCount - 1U)
+ *Output_ << ',';
+
+ }
+ *Output_ << '>';
+}
+
void TTypePrinter1::OnList(const TType* itemType) {
- *Output_ << "List<";
- OutImpl(itemType);
- *Output_ << '>';
-}
-
+ *Output_ << "List<";
+ OutImpl(itemType);
+ *Output_ << '>';
+}
+
void TTypePrinter1::OnOptional(const TType* itemType) {
- OutImpl(itemType);
- *Output_ << '?';
-}
-
+ OutImpl(itemType);
+ *Output_ << '?';
+}
+
void TTypePrinter1::OnTuple(ui32 elementsCount, const TType** elementsTypes) {
- *Output_ << "Tuple<";
- for (ui32 i = 0U; i < elementsCount; ++i) {
- OutImpl(elementsTypes[i]);
- if (i < elementsCount - 1U)
- *Output_ << ',';
-
- }
- *Output_ << '>';
-}
-
+ *Output_ << "Tuple<";
+ for (ui32 i = 0U; i < elementsCount; ++i) {
+ OutImpl(elementsTypes[i]);
+ if (i < elementsCount - 1U)
+ *Output_ << ',';
+
+ }
+ *Output_ << '>';
+}
+
void TTypePrinter1::OnDict(const TType* keyType, const TType* valueType) {
- *Output_ << "Dict<";
- OutImpl(keyType);
- *Output_ << ',';
- OutImpl(valueType);
- *Output_ << '>';
-}
-
+ *Output_ << "Dict<";
+ OutImpl(keyType);
+ *Output_ << ',';
+ OutImpl(valueType);
+ *Output_ << '>';
+}
+
void TTypePrinter1::OnCallable(const TType* returnType, ui32 argsCount, const TType** argsTypes, ui32 optionalArgsCount, const ICallablePayload* payload) {
- *Output_ << "Callable<(";
- for (ui32 i = 0U; i < argsCount; ++i) {
- if (optionalArgsCount && i == argsCount - optionalArgsCount)
- *Output_ << '[';
- if (const std::string_view name = payload->GetArgumentName(i); !name.empty())
- *Output_ << "'" << name << "':";
- OutImpl(argsTypes[i]);
- if (ICallablePayload::TArgumentFlags::AutoMap == payload->GetArgumentFlags(i))
- *Output_ << "{Flags:AutoMap}";
- if (i < argsCount - 1U)
- *Output_ << ',';
- }
- *Output_ << (optionalArgsCount ? "])->" : ")->");
- OutImpl(returnType);
-}
-
+ *Output_ << "Callable<(";
+ for (ui32 i = 0U; i < argsCount; ++i) {
+ if (optionalArgsCount && i == argsCount - optionalArgsCount)
+ *Output_ << '[';
+ if (const std::string_view name = payload->GetArgumentName(i); !name.empty())
+ *Output_ << "'" << name << "':";
+ OutImpl(argsTypes[i]);
+ if (ICallablePayload::TArgumentFlags::AutoMap == payload->GetArgumentFlags(i))
+ *Output_ << "{Flags:AutoMap}";
+ if (i < argsCount - 1U)
+ *Output_ << ',';
+ }
+ *Output_ << (optionalArgsCount ? "])->" : ")->");
+ OutImpl(returnType);
+}
+
void TTypePrinter1::OnVariant(const TType* underlyingType) {
- *Output_ << "Variant<";
- OutImpl(underlyingType);
- *Output_ << '>';
-}
-
+ *Output_ << "Variant<";
+ OutImpl(underlyingType);
+ *Output_ << '>';
+}
+
void TTypePrinter1::OnStream(const TType* itemType) {
- *Output_ << "Stream<";
- OutImpl(itemType);
- *Output_ << '>';
-}
+ *Output_ << "Stream<";
+ OutImpl(itemType);
+ *Output_ << '>';
+}
void TTypePrinter1::OnDecimalImpl(ui8 precision, ui8 scale) {
- *Output_ << '(' << unsigned(precision) << ',' << unsigned(scale) << ')';
-}
+ *Output_ << '(' << unsigned(precision) << ',' << unsigned(scale) << ')';
+}
void TTypePrinter1::OnResourceImpl(TStringRef tag) {
- *Output_ << "Resource<'" << std::string_view(tag) << "'>";
-}
+ *Output_ << "Resource<'" << std::string_view(tag) << "'>";
+}
void TTypePrinter1::OnTaggedImpl(const TType* baseType, TStringRef tag) {
- *Output_ << "Tagged<";
- OutImpl(baseType);
- *Output_ << ",'" << std::string_view(tag) << "'>";
-}
+ *Output_ << "Tagged<";
+ OutImpl(baseType);
+ *Output_ << ",'" << std::string_view(tag) << "'>";
+}
-}
-}
+}
+}
diff --git a/ydb/library/yql/public/udf/udf_type_printer.h b/ydb/library/yql/public/udf/udf_type_printer.h
index 7720b52840..749118c9bc 100644
--- a/ydb/library/yql/public/udf/udf_type_printer.h
+++ b/ydb/library/yql/public/udf/udf_type_printer.h
@@ -1,28 +1,28 @@
-#pragma once
-
-#include "udf_string_ref.h"
-#include "udf_types.h"
-
-namespace NYql {
-namespace NUdf {
-
+#pragma once
+
+#include "udf_string_ref.h"
+#include "udf_types.h"
+
+namespace NYql {
+namespace NUdf {
+
class TTypePrinter1 : private ITypeVisitor
-{
-public:
+{
+public:
TTypePrinter1(const ITypeInfoHelper& typeHelper, const TType* type);
-
- void Out(IOutputStream &o) const;
-
+
+ void Out(IOutputStream &o) const;
+
protected:
- void OnDataType(TDataTypeId typeId) final;
- void OnStruct(ui32 membersCount, TStringRef* membersNames, const TType** membersTypes) final;
- void OnList(const TType* itemType) final;
- void OnOptional(const TType* itemType) final;
- void OnTuple(ui32 elementsCount, const TType** elementsTypes) final;
- void OnDict(const TType* keyType, const TType* valueType) final;
- void OnCallable(const TType* returnType, ui32 argsCount, const TType** argsTypes, ui32 optionalArgsCount, const ICallablePayload* payload) final;
- void OnVariant(const TType* underlyingType) final;
- void OnStream(const TType* itemType) final;
+ void OnDataType(TDataTypeId typeId) final;
+ void OnStruct(ui32 membersCount, TStringRef* membersNames, const TType** membersTypes) final;
+ void OnList(const TType* itemType) final;
+ void OnOptional(const TType* itemType) final;
+ void OnTuple(ui32 elementsCount, const TType** elementsTypes) final;
+ void OnDict(const TType* keyType, const TType* valueType) final;
+ void OnCallable(const TType* returnType, ui32 argsCount, const TType** argsTypes, ui32 optionalArgsCount, const ICallablePayload* payload) final;
+ void OnVariant(const TType* underlyingType) final;
+ void OnStream(const TType* itemType) final;
void OutImpl(const TType* type) const;
void OnDecimalImpl(ui8 precision, ui8 scale);
void OnResourceImpl(TStringRef tag);
@@ -32,7 +32,7 @@ protected:
const TType* Type_;
};
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 13)
class TTypePrinter2 : public TTypePrinter1 {
public:
using TTypePrinter1::TTypePrinter1;
@@ -42,9 +42,9 @@ protected:
OnDecimalImpl(precision, scale);
}
};
-#endif
+#endif
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15)
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15)
class TTypePrinter3 : public TTypePrinter2 {
public:
using TTypePrinter2::TTypePrinter2;
@@ -54,20 +54,20 @@ protected:
OnResourceImpl(tag);
}
};
-#endif
+#endif
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 21)
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 21)
class TTypePrinter4 : public TTypePrinter3 {
public:
using TTypePrinter3::TTypePrinter3;
-
+
protected:
void OnTagged(const TType* baseType, TStringRef tag) final {
OnTaggedImpl(baseType, tag);
}
-};
+};
#endif
-
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 21)
using TTypePrinter = TTypePrinter4;
#elif UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15)
@@ -79,5 +79,5 @@ using TTypePrinter = TTypePrinter1;
#endif
-}
-}
+}
+}
diff --git a/ydb/library/yql/public/udf/udf_types.h b/ydb/library/yql/public/udf/udf_types.h
index 29f884556a..c2b67c7cbb 100644
--- a/ydb/library/yql/public/udf/udf_types.h
+++ b/ydb/library/yql/public/udf/udf_types.h
@@ -4,7 +4,7 @@
#include "udf_data_type.h"
#include "udf_version.h"
-namespace NYql {
+namespace NYql {
namespace NUdf {
class TStringRef;
@@ -216,4 +216,4 @@ UDF_ASSERT_TYPE_SIZE(ITypeInfoHelper, 16);
UDF_ASSERT_TYPE_SIZE(ITypeInfoHelper::TPtr, 8);
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_ut_helpers.h b/ydb/library/yql/public/udf/udf_ut_helpers.h
index b876c98756..e748ebf898 100644
--- a/ydb/library/yql/public/udf/udf_ut_helpers.h
+++ b/ydb/library/yql/public/udf/udf_ut_helpers.h
@@ -2,32 +2,32 @@
#include "udf_value.h"
#include <util/generic/ymath.h>
-#include <util/system/platform.h>
-#include <util/generic/yexception.h>
-#include <util/system/yassert.h>
+#include <util/system/platform.h>
+#include <util/generic/yexception.h>
+#include <util/system/yassert.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
inline size_t GetMethodPtrIndex(uintptr_t ptr)
-{
-#ifdef _win_
+{
+#ifdef _win_
Y_ENSURE(memcmp((void*)ptr, "\x48\x8B\x01\xFF", 4) == 0);
- size_t offset;
+ size_t offset;
if (*(ui8*)(ptr + 4) == 0x60) {
offset = *(ui8*)(ptr + 5);
} else if (*(ui8*)(ptr + 4) == 0xa0) {
offset = *(ui32*)(ptr + 5);
- } else {
- ythrow yexception() << "Unsupported code";
- }
-
- return offset / 8 + 1;
-#else
+ } else {
+ ythrow yexception() << "Unsupported code";
+ }
+
+ return offset / 8 + 1;
+#else
return ptr >> 3;
-#endif
-}
-
+#endif
+}
+
template<typename Method>
size_t GetMethodIndex(Method method) {
uintptr_t ptr;
@@ -35,45 +35,45 @@ size_t GetMethodIndex(Method method) {
return GetMethodPtrIndex(ptr);
}
-template<bool HasLength = true>
+template<bool HasLength = true>
class TLazyList: public NUdf::TBoxedValue {
- struct TIterator: public NUdf::TBoxedValue {
- TIterator(i32 from, i32 to)
- : From(from), To(to), Curr(Max<i32>())
- {
- if (To >= From) {
- To--; // exclude last
- } else {
- From--; // exclude first
- }
- }
- private:
- bool Skip() override {
- if (Curr == Max<i32>()) {
- Curr = From;
- return true;
- }
- if (To >= From) {
- if (Curr < To) {
- ++Curr;
- return true;
- }
- } else {
- if (Curr > To) {
- --Curr;
- return true;
- }
- }
- return false;
- }
-
- bool Next(NUdf::TUnboxedValue& value) override {
- if (!Skip())
- return false;
- value = NUdf::TUnboxedValuePod(Curr);
- return true;
- }
- i32 From, To, Curr;
+ struct TIterator: public NUdf::TBoxedValue {
+ TIterator(i32 from, i32 to)
+ : From(from), To(to), Curr(Max<i32>())
+ {
+ if (To >= From) {
+ To--; // exclude last
+ } else {
+ From--; // exclude first
+ }
+ }
+ private:
+ bool Skip() override {
+ if (Curr == Max<i32>()) {
+ Curr = From;
+ return true;
+ }
+ if (To >= From) {
+ if (Curr < To) {
+ ++Curr;
+ return true;
+ }
+ } else {
+ if (Curr > To) {
+ --Curr;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool Next(NUdf::TUnboxedValue& value) override {
+ if (!Skip())
+ return false;
+ value = NUdf::TUnboxedValuePod(Curr);
+ return true;
+ }
+ i32 From, To, Curr;
};
public:
TLazyList(i32 from, i32 to)
@@ -83,23 +83,23 @@ public:
private:
bool HasFastListLength() const override {
- return HasLength;
+ return HasLength;
}
ui64 GetListLength() const override {
- if (HasLength)
- return Abs(To_ - From_);
-
- Y_FAIL("No length!");
+ if (HasLength)
+ return Abs(To_ - From_);
+
+ Y_FAIL("No length!");
}
bool HasListItems() const override {
return To_ != From_;
}
- NUdf::TUnboxedValue GetListIterator() const override {
- return NUdf::TUnboxedValuePod(new TIterator(From_, To_));
- }
+ NUdf::TUnboxedValue GetListIterator() const override {
+ return NUdf::TUnboxedValuePod(new TIterator(From_, To_));
+ }
NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
Y_UNUSED(builder);
@@ -108,7 +108,7 @@ private:
NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
Y_UNUSED(builder);
- count = std::min<ui64>(count, Abs(To_ - From_));
+ count = std::min<ui64>(count, Abs(To_ - From_));
if (To_ >= From_) {
return new TLazyList(From_ + count, To_);
}
@@ -117,7 +117,7 @@ private:
NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
Y_UNUSED(builder);
- count = std::min<ui64>(count, Abs(To_ - From_));
+ count = std::min<ui64>(count, Abs(To_ - From_));
if (To_ >= From_) {
return new TLazyList(From_, From_ + count);
}
diff --git a/ydb/library/yql/public/udf/udf_validate.cpp b/ydb/library/yql/public/udf/udf_validate.cpp
index e07c157bbb..be61b79cf2 100644
--- a/ydb/library/yql/public/udf/udf_validate.cpp
+++ b/ydb/library/yql/public/udf/udf_validate.cpp
@@ -2,7 +2,7 @@
#include <util/string/join.h>
#include <util/generic/yexception.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
#define SWITCH_ENUM_TYPE_TO_STR(name, val) \
@@ -53,4 +53,4 @@ EValidatePolicy ValidatePolicyByStr(const TString& validatePolicyStr) {
}
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_validate.h b/ydb/library/yql/public/udf/udf_validate.h
index 896cd37774..6e9957ec25 100644
--- a/ydb/library/yql/public/udf/udf_validate.h
+++ b/ydb/library/yql/public/udf/udf_validate.h
@@ -3,7 +3,7 @@
#include <util/generic/strbuf.h>
#include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
#define UDF_VALIDATE_MODE(XX) \
@@ -32,4 +32,4 @@ TStringBuf ValidatePolicyAsStr(EValidatePolicy verifyPolicy);
EValidatePolicy ValidatePolicyByStr(const TString& verifyPolicy);
} // namspace NUdf
-} // namspace NYql
+} // namspace NYql
diff --git a/ydb/library/yql/public/udf/udf_value.h b/ydb/library/yql/public/udf/udf_value.h
index d9371025c2..705ac41133 100644
--- a/ydb/library/yql/public/udf/udf_value.h
+++ b/ydb/library/yql/public/udf/udf_value.h
@@ -11,17 +11,17 @@
#include <util/generic/utility.h> // Min, Max
#include <util/generic/yexception.h> // Y_ENSURE
#include <util/system/compiler.h> // Y_FORCE_INLINE
-
-#include <algorithm>
-#include <type_traits>
+
+#include <algorithm>
+#include <type_traits>
class IOutputStream;
-namespace NYql {
+namespace NYql {
namespace NUdf {
class TUnboxedValue;
-class TUnboxedValuePod;
+class TUnboxedValuePod;
class TOpaqueListRepresentation;
class IValueBuilder;
@@ -42,15 +42,15 @@ constexpr ui32 PreferredBlockBytes = 1000000;
#endif
///////////////////////////////////////////////////////////////////////////////
-// IApplyContext
-///////////////////////////////////////////////////////////////////////////////
-class IApplyContext {
-public:
- virtual ~IApplyContext() = default;
-};
-
-UDF_ASSERT_TYPE_SIZE(IApplyContext, 8);
-
+// IApplyContext
+///////////////////////////////////////////////////////////////////////////////
+class IApplyContext {
+public:
+ virtual ~IApplyContext() = default;
+};
+
+UDF_ASSERT_TYPE_SIZE(IApplyContext, 8);
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
class TBlock;
class TFlatDataBlock;
@@ -60,7 +60,7 @@ class TSingleBlock;
typedef bool(*TBlockCallback)(TBlock& block, void* context);
#endif
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
// IBoxedValue
///////////////////////////////////////////////////////////////////////////////
class IBoxedValue;
@@ -77,56 +77,56 @@ public:
virtual ~IBoxedValue1() = default;
-private:
- // List accessors
- virtual bool HasFastListLength() const = 0;
- virtual ui64 GetListLength() const = 0;
- virtual ui64 GetEstimatedListLength() const = 0;
- virtual TUnboxedValue GetListIterator() const = 0;
- // customization of list operations, may return null @{
- virtual const TOpaqueListRepresentation* GetListRepresentation() const = 0;
+private:
+ // List accessors
+ virtual bool HasFastListLength() const = 0;
+ virtual ui64 GetListLength() const = 0;
+ virtual ui64 GetEstimatedListLength() const = 0;
+ virtual TUnboxedValue GetListIterator() const = 0;
+ // customization of list operations, may return null @{
+ virtual const TOpaqueListRepresentation* GetListRepresentation() const = 0;
virtual IBoxedValuePtr ReverseListImpl(const IValueBuilder& builder) const = 0;
virtual IBoxedValuePtr SkipListImpl(const IValueBuilder& builder, ui64 count) const = 0;
virtual IBoxedValuePtr TakeListImpl(const IValueBuilder& builder, ui64 count) const = 0;
virtual IBoxedValuePtr ToIndexDictImpl(const IValueBuilder& builder) const = 0;
- // @}
-
- // Dict accessors
- virtual ui64 GetDictLength() const = 0;
- virtual TUnboxedValue GetDictIterator() const = 0;
- virtual TUnboxedValue GetKeysIterator() const = 0; // May return empty.
- virtual TUnboxedValue GetPayloadsIterator() const = 0; // May return empty.
- virtual bool Contains(const TUnboxedValuePod& key) const = 0;
- virtual TUnboxedValue Lookup(const TUnboxedValuePod& key) const = 0;
-
- // Tuple or Struct accessors
- virtual TUnboxedValue GetElement(ui32 index) const = 0;
- virtual const TUnboxedValue* GetElements() const = 0; // May return nullptr.
-
- // Callable accessors
- virtual TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const = 0;
-
- // Resource accessor
- virtual TStringRef GetResourceTag() const = 0;
- virtual void* GetResource() = 0;
-
- virtual bool HasListItems() const = 0;
- virtual bool HasDictItems() const = 0;
-
- virtual ui32 GetVariantIndex() const = 0;
- virtual TUnboxedValue GetVariantItem() const = 0;
-
- // Either Done/Yield with empty result or Ready with non-empty result should be returned
- virtual EFetchStatus Fetch(TUnboxedValue& result) = 0;
-
- // Any iterator.
- virtual bool Skip() = 0;
- // List iterator.
- virtual bool Next(TUnboxedValue& value) = 0;
- // Dict iterator.
- virtual bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) = 0;
-
- virtual void Apply(IApplyContext& context) const = 0;
+ // @}
+
+ // Dict accessors
+ virtual ui64 GetDictLength() const = 0;
+ virtual TUnboxedValue GetDictIterator() const = 0;
+ virtual TUnboxedValue GetKeysIterator() const = 0; // May return empty.
+ virtual TUnboxedValue GetPayloadsIterator() const = 0; // May return empty.
+ virtual bool Contains(const TUnboxedValuePod& key) const = 0;
+ virtual TUnboxedValue Lookup(const TUnboxedValuePod& key) const = 0;
+
+ // Tuple or Struct accessors
+ virtual TUnboxedValue GetElement(ui32 index) const = 0;
+ virtual const TUnboxedValue* GetElements() const = 0; // May return nullptr.
+
+ // Callable accessors
+ virtual TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const = 0;
+
+ // Resource accessor
+ virtual TStringRef GetResourceTag() const = 0;
+ virtual void* GetResource() = 0;
+
+ virtual bool HasListItems() const = 0;
+ virtual bool HasDictItems() const = 0;
+
+ virtual ui32 GetVariantIndex() const = 0;
+ virtual TUnboxedValue GetVariantItem() const = 0;
+
+ // Either Done/Yield with empty result or Ready with non-empty result should be returned
+ virtual EFetchStatus Fetch(TUnboxedValue& result) = 0;
+
+ // Any iterator.
+ virtual bool Skip() = 0;
+ // List iterator.
+ virtual bool Next(TUnboxedValue& value) = 0;
+ // Dict iterator.
+ virtual bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) = 0;
+
+ virtual void Apply(IApplyContext& context) const = 0;
public:
// reference counting
@@ -203,13 +203,13 @@ class IBoxedValue : public IBoxedValue2 {};
#else
class IBoxedValue : public IBoxedValue1 {};
#endif
-
-UDF_ASSERT_TYPE_SIZE(IBoxedValue, 16);
-
+
+UDF_ASSERT_TYPE_SIZE(IBoxedValue, 16);
+
UDF_ASSERT_TYPE_SIZE(IBoxedValuePtr, 8);
-
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
// TBlock
///////////////////////////////////////////////////////////////////////////////
@@ -386,10 +386,10 @@ UDF_ASSERT_TYPE_SIZE(TFlatDataBlockPtr, 8);
#endif
///////////////////////////////////////////////////////////////////////////////
-// TBoxedValueAccessor
-///////////////////////////////////////////////////////////////////////////////
-struct TBoxedValueAccessor
-{
+// TBoxedValueAccessor
+///////////////////////////////////////////////////////////////////////////////
+struct TBoxedValueAccessor
+{
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
#define METHOD_MAP(xx) \
@@ -607,56 +607,56 @@ struct TBoxedValueAccessor
Y_FAIL("unknown method");
}
- template<EMethod Method> static uintptr_t GetMethodPtr();
-
- // List accessors
- static inline bool HasFastListLength(const IBoxedValue& value);
- static inline ui64 GetListLength(const IBoxedValue& value);
- static inline ui64 GetEstimatedListLength(const IBoxedValue& value);
- static inline TUnboxedValue GetListIterator(const IBoxedValue& value);
- // customization of list operations, may return null @{
- static inline const TOpaqueListRepresentation* GetListRepresentation(const IBoxedValue& value);
+ template<EMethod Method> static uintptr_t GetMethodPtr();
+
+ // List accessors
+ static inline bool HasFastListLength(const IBoxedValue& value);
+ static inline ui64 GetListLength(const IBoxedValue& value);
+ static inline ui64 GetEstimatedListLength(const IBoxedValue& value);
+ static inline TUnboxedValue GetListIterator(const IBoxedValue& value);
+ // customization of list operations, may return null @{
+ static inline const TOpaqueListRepresentation* GetListRepresentation(const IBoxedValue& value);
static inline IBoxedValuePtr ReverseListImpl(const IBoxedValue& value, const IValueBuilder& builder);
static inline IBoxedValuePtr SkipListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count);
static inline IBoxedValuePtr TakeListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count);
static inline IBoxedValuePtr ToIndexDictImpl(const IBoxedValue& value, const IValueBuilder& builder);
- // @}
-
- // Dict accessors
- static inline ui64 GetDictLength(const IBoxedValue& value);
- static inline TUnboxedValue GetDictIterator(const IBoxedValue& value);
- static inline TUnboxedValue GetKeysIterator(const IBoxedValue& value);
- static inline TUnboxedValue GetPayloadsIterator(const IBoxedValue& value);
- static inline bool Contains(const IBoxedValue& value, const TUnboxedValuePod& key);
- static inline TUnboxedValue Lookup(const IBoxedValue& value, const TUnboxedValuePod& key);
-
- // Tuple or Struct accessors
- static inline TUnboxedValue GetElement(const IBoxedValue& value, ui32 index);
- static inline const TUnboxedValue* GetElements(const IBoxedValue& value);
-
- // Callable accessors
- static inline TUnboxedValue Run(const IBoxedValue& value, const IValueBuilder* valueBuilder, const TUnboxedValuePod* args);
-
- // Resource accessor
- static inline TStringRef GetResourceTag(const IBoxedValue& value);
- static inline void* GetResource(IBoxedValue& value);
-
- static inline bool HasListItems(const IBoxedValue& value);
- static inline bool HasDictItems(const IBoxedValue& value);
-
- static inline ui32 GetVariantIndex(const IBoxedValue& value);
- static inline TUnboxedValue GetVariantItem(const IBoxedValue& value);
-
- static inline EFetchStatus Fetch(IBoxedValue& value, TUnboxedValue& result);
-
- // Any iterator.
- static inline bool Skip(IBoxedValue& value);
- // List iterator.
- static inline bool Next(IBoxedValue& value, TUnboxedValue& result);
- // Dict iterator.
- static inline bool NextPair(IBoxedValue& value, TUnboxedValue& key, TUnboxedValue& payload);
-
- static inline void Apply(IBoxedValue& value, IApplyContext& context);
+ // @}
+
+ // Dict accessors
+ static inline ui64 GetDictLength(const IBoxedValue& value);
+ static inline TUnboxedValue GetDictIterator(const IBoxedValue& value);
+ static inline TUnboxedValue GetKeysIterator(const IBoxedValue& value);
+ static inline TUnboxedValue GetPayloadsIterator(const IBoxedValue& value);
+ static inline bool Contains(const IBoxedValue& value, const TUnboxedValuePod& key);
+ static inline TUnboxedValue Lookup(const IBoxedValue& value, const TUnboxedValuePod& key);
+
+ // Tuple or Struct accessors
+ static inline TUnboxedValue GetElement(const IBoxedValue& value, ui32 index);
+ static inline const TUnboxedValue* GetElements(const IBoxedValue& value);
+
+ // Callable accessors
+ static inline TUnboxedValue Run(const IBoxedValue& value, const IValueBuilder* valueBuilder, const TUnboxedValuePod* args);
+
+ // Resource accessor
+ static inline TStringRef GetResourceTag(const IBoxedValue& value);
+ static inline void* GetResource(IBoxedValue& value);
+
+ static inline bool HasListItems(const IBoxedValue& value);
+ static inline bool HasDictItems(const IBoxedValue& value);
+
+ static inline ui32 GetVariantIndex(const IBoxedValue& value);
+ static inline TUnboxedValue GetVariantItem(const IBoxedValue& value);
+
+ static inline EFetchStatus Fetch(IBoxedValue& value, TUnboxedValue& result);
+
+ // Any iterator.
+ static inline bool Skip(IBoxedValue& value);
+ // List iterator.
+ static inline bool Next(IBoxedValue& value, TUnboxedValue& result);
+ // Dict iterator.
+ static inline bool NextPair(IBoxedValue& value, TUnboxedValue& key, TUnboxedValue& payload);
+
+ static inline void Apply(IBoxedValue& value, IApplyContext& context);
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
// Save/Load state
@@ -682,65 +682,65 @@ struct TBoxedValueAccessor
static inline EFetchStatus FetchBlock(IBoxedValue& value, TUnboxedValue& result, ui32 rowsLimitHint);
static inline bool VisitBlocks(IBoxedValue& value, TBlockCallback callback, void* context);
#endif
-};
-
-#define MAP_HANDLER(xx) template<> inline uintptr_t TBoxedValueAccessor::GetMethodPtr<TBoxedValueAccessor::EMethod::xx>() { return GetMethodPtr(&IBoxedValue::xx); }
-METHOD_MAP(MAP_HANDLER)
-#undef MAP_HANDLER
-
-#undef METHOD_MAP
-
-///////////////////////////////////////////////////////////////////////////////
-// TBoxedValue
-///////////////////////////////////////////////////////////////////////////////
+};
+
+#define MAP_HANDLER(xx) template<> inline uintptr_t TBoxedValueAccessor::GetMethodPtr<TBoxedValueAccessor::EMethod::xx>() { return GetMethodPtr(&IBoxedValue::xx); }
+METHOD_MAP(MAP_HANDLER)
+#undef MAP_HANDLER
+
+#undef METHOD_MAP
+
+///////////////////////////////////////////////////////////////////////////////
+// TBoxedValue
+///////////////////////////////////////////////////////////////////////////////
class TBoxedValueBase: public IBoxedValue {
-private:
- // List accessors
- bool HasFastListLength() const override;
- ui64 GetListLength() const override;
- ui64 GetEstimatedListLength() const override;
- TUnboxedValue GetListIterator() const override;
- const TOpaqueListRepresentation* GetListRepresentation() const override;
+private:
+ // List accessors
+ bool HasFastListLength() const override;
+ ui64 GetListLength() const override;
+ ui64 GetEstimatedListLength() const override;
+ TUnboxedValue GetListIterator() const override;
+ const TOpaqueListRepresentation* GetListRepresentation() const override;
IBoxedValuePtr ReverseListImpl(const IValueBuilder& builder) const override;
IBoxedValuePtr SkipListImpl(const IValueBuilder& builder, ui64 count) const override;
IBoxedValuePtr TakeListImpl(const IValueBuilder& builder, ui64 count) const override;
IBoxedValuePtr ToIndexDictImpl(const IValueBuilder& builder) const override;
-
- // Dict accessors
- ui64 GetDictLength() const override;
- TUnboxedValue GetDictIterator() const override;
- TUnboxedValue GetKeysIterator() const override;
- TUnboxedValue GetPayloadsIterator() const override;
- bool Contains(const TUnboxedValuePod& key) const override;
- TUnboxedValue Lookup(const TUnboxedValuePod& key) const override;
-
- // Tuple or Struct accessors
- TUnboxedValue GetElement(ui32 index) const override;
- const TUnboxedValue* GetElements() const override;
-
- // Callable accessors
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const override;
-
- // Resource accessors
- TStringRef GetResourceTag() const override;
- void* GetResource() override;
-
- bool HasListItems() const override;
- bool HasDictItems() const override;
-
- ui32 GetVariantIndex() const override;
- TUnboxedValue GetVariantItem() const override;
-
- EFetchStatus Fetch(TUnboxedValue& result) override;
-
- // Any iterator.
- bool Skip() override;
- // List iterator.
- bool Next(TUnboxedValue& value) override;
- // Dict iterator.
- bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) override;
-
- void Apply(IApplyContext& context) const override;
+
+ // Dict accessors
+ ui64 GetDictLength() const override;
+ TUnboxedValue GetDictIterator() const override;
+ TUnboxedValue GetKeysIterator() const override;
+ TUnboxedValue GetPayloadsIterator() const override;
+ bool Contains(const TUnboxedValuePod& key) const override;
+ TUnboxedValue Lookup(const TUnboxedValuePod& key) const override;
+
+ // Tuple or Struct accessors
+ TUnboxedValue GetElement(ui32 index) const override;
+ const TUnboxedValue* GetElements() const override;
+
+ // Callable accessors
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const override;
+
+ // Resource accessors
+ TStringRef GetResourceTag() const override;
+ void* GetResource() override;
+
+ bool HasListItems() const override;
+ bool HasDictItems() const override;
+
+ ui32 GetVariantIndex() const override;
+ TUnboxedValue GetVariantItem() const override;
+
+ EFetchStatus Fetch(TUnboxedValue& result) override;
+
+ // Any iterator.
+ bool Skip() override;
+ // List iterator.
+ bool Next(TUnboxedValue& value) override;
+ // Dict iterator.
+ bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) override;
+
+ void Apply(IApplyContext& context) const override;
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
// Save/Load state
@@ -770,17 +770,17 @@ private:
class TBoxedValueLink: public TBoxedValueBase
{
-public:
+public:
void Link(TBoxedValueLink* root);
- void Unlink();
- void InitLinks() { Left = Right = this; }
+ void Unlink();
+ void InitLinks() { Left = Right = this; }
TBoxedValueLink* GetLeft() const { return Left; }
TBoxedValueLink* GetRight() const { return Right; }
-private:
+private:
TBoxedValueLink *Left = nullptr;
TBoxedValueLink *Right = nullptr;
-};
-
+};
+
class TBoxedValue: public TBoxedValueLink, public TWithUdfAllocator
{
public:
@@ -792,133 +792,133 @@ class TManagedBoxedValue: public TBoxedValueBase, public TWithUdfAllocator
{
};
-UDF_ASSERT_TYPE_SIZE(TBoxedValue, 32);
-
-///////////////////////////////////////////////////////////////////////////////
-// TUnboxedValuePod
-///////////////////////////////////////////////////////////////////////////////
-class TUnboxedValuePod
-{
-friend class TUnboxedValue;
-protected:
- enum class EMarkers : ui8 {
- Empty = 0,
- Embedded,
- String,
- Boxed,
- };
-
-public:
- inline TUnboxedValuePod() noexcept = default;
- inline ~TUnboxedValuePod() noexcept = default;
-
- inline TUnboxedValuePod(const TUnboxedValuePod& value) noexcept = default;
+UDF_ASSERT_TYPE_SIZE(TBoxedValue, 32);
+
+///////////////////////////////////////////////////////////////////////////////
+// TUnboxedValuePod
+///////////////////////////////////////////////////////////////////////////////
+class TUnboxedValuePod
+{
+friend class TUnboxedValue;
+protected:
+ enum class EMarkers : ui8 {
+ Empty = 0,
+ Embedded,
+ String,
+ Boxed,
+ };
+
+public:
+ inline TUnboxedValuePod() noexcept = default;
+ inline ~TUnboxedValuePod() noexcept = default;
+
+ inline TUnboxedValuePod(const TUnboxedValuePod& value) noexcept = default;
inline TUnboxedValuePod(TUnboxedValuePod&& value) noexcept = default;
-
- inline TUnboxedValuePod& operator=(const TUnboxedValuePod& value) noexcept = default;
- inline TUnboxedValuePod& operator=(TUnboxedValuePod&& value) noexcept = default;
-
- inline TUnboxedValuePod(TUnboxedValue&&) = delete;
- inline TUnboxedValuePod& operator=(TUnboxedValue&&) = delete;
-
+
+ inline TUnboxedValuePod& operator=(const TUnboxedValuePod& value) noexcept = default;
+ inline TUnboxedValuePod& operator=(TUnboxedValuePod&& value) noexcept = default;
+
+ inline TUnboxedValuePod(TUnboxedValue&&) = delete;
+ inline TUnboxedValuePod& operator=(TUnboxedValue&&) = delete;
+
template <typename T, typename = std::enable_if_t<TPrimitiveDataType<T>::Result>>
- inline explicit TUnboxedValuePod(T value);
+ inline explicit TUnboxedValuePod(T value);
inline explicit TUnboxedValuePod(IBoxedValuePtr&& value);
- inline explicit TUnboxedValuePod(TStringValue&& value, ui32 size = Max<ui32>(), ui32 offset = 0U);
-
+ inline explicit TUnboxedValuePod(TStringValue&& value, ui32 size = Max<ui32>(), ui32 offset = 0U);
+
void Dump(IOutputStream& out) const;
- // meta information
- inline explicit operator bool() const { return bool(Raw); }
-
- inline bool HasValue() const { return EMarkers::Empty != Raw.GetMarkers(); }
-
- inline bool IsString() const { return EMarkers::String == Raw.GetMarkers(); }
- inline bool IsBoxed() const { return EMarkers::Boxed == Raw.GetMarkers(); }
+ // meta information
+ inline explicit operator bool() const { return bool(Raw); }
+
+ inline bool HasValue() const { return EMarkers::Empty != Raw.GetMarkers(); }
+
+ inline bool IsString() const { return EMarkers::String == Raw.GetMarkers(); }
+ inline bool IsBoxed() const { return EMarkers::Boxed == Raw.GetMarkers(); }
inline bool IsEmbedded() const { return EMarkers::Embedded == Raw.GetMarkers(); }
-
- // Data accessors
+
+ // Data accessors
template <typename T, typename = std::enable_if_t<TPrimitiveDataType<T>::Result>>
- inline T Get() const;
+ inline T Get() const;
template <typename T, typename = std::enable_if_t<TPrimitiveDataType<T>::Result>>
- inline T GetOrDefault(T ifEmpty) const;
-
- inline explicit TUnboxedValuePod(NYql::NDecimal::TInt128 value);
- inline explicit TUnboxedValuePod(NYql::NDecimal::TUint128 value);
- inline NYql::NDecimal::TInt128 GetInt128() const;
- inline NYql::NDecimal::TUint128 GetUint128() const;
-
- inline const void* GetRawPtr() const;
- inline void* GetRawPtr();
-
- inline TStringRef AsStringRef() const&;
- inline TMutableStringRef AsStringRef() &;
- void AsStringRef() && = delete;
-
- inline TStringValue AsStringValue() const;
+ inline T GetOrDefault(T ifEmpty) const;
+
+ inline explicit TUnboxedValuePod(NYql::NDecimal::TInt128 value);
+ inline explicit TUnboxedValuePod(NYql::NDecimal::TUint128 value);
+ inline NYql::NDecimal::TInt128 GetInt128() const;
+ inline NYql::NDecimal::TUint128 GetUint128() const;
+
+ inline const void* GetRawPtr() const;
+ inline void* GetRawPtr();
+
+ inline TStringRef AsStringRef() const&;
+ inline TMutableStringRef AsStringRef() &;
+ void AsStringRef() && = delete;
+
+ inline TStringValue AsStringValue() const;
inline IBoxedValuePtr AsBoxed() const;
- inline bool UniqueBoxed() const;
-
- // special values
- inline static TUnboxedValuePod Void();
- inline static TUnboxedValuePod Zero();
- inline static TUnboxedValuePod Embedded(ui8 size);
- inline static TUnboxedValuePod Embedded(const TStringRef& value);
+ inline bool UniqueBoxed() const;
+
+ // special values
+ inline static TUnboxedValuePod Void();
+ inline static TUnboxedValuePod Zero();
+ inline static TUnboxedValuePod Embedded(ui8 size);
+ inline static TUnboxedValuePod Embedded(const TStringRef& value);
inline static TUnboxedValuePod Invalid();
- inline static TUnboxedValuePod MakeFinish();
- inline static TUnboxedValuePod MakeYield();
+ inline static TUnboxedValuePod MakeFinish();
+ inline static TUnboxedValuePod MakeYield();
inline bool IsInvalid() const;
- inline bool IsFinish() const;
- inline bool IsYield() const;
- inline bool IsSpecial() const;
-
- inline TUnboxedValuePod MakeOptional() const;
- inline TUnboxedValuePod GetOptionalValue() const;
-
- template<bool IsOptional> inline TUnboxedValuePod GetOptionalValueIf() const;
- template<bool IsOptional> inline TUnboxedValuePod MakeOptionalIf() const;
-
- // List accessors
- inline bool HasFastListLength() const;
- inline ui64 GetListLength() const;
- inline ui64 GetEstimatedListLength() const;
- inline TUnboxedValue GetListIterator() const;
- inline bool HasListItems() const;
-
- // Dict accessors
- inline ui64 GetDictLength() const;
- inline TUnboxedValue GetDictIterator() const;
- inline TUnboxedValue GetKeysIterator() const;
- inline TUnboxedValue GetPayloadsIterator() const;
-
- inline bool Contains(const TUnboxedValuePod& key) const;
- inline TUnboxedValue Lookup(const TUnboxedValuePod& key) const;
- inline bool HasDictItems() const;
-
- // Tuple or Struct accessors
- inline TUnboxedValue GetElement(ui32 index) const;
- inline const TUnboxedValue* GetElements() const;
-
- // Callable accessors
+ inline bool IsFinish() const;
+ inline bool IsYield() const;
+ inline bool IsSpecial() const;
+
+ inline TUnboxedValuePod MakeOptional() const;
+ inline TUnboxedValuePod GetOptionalValue() const;
+
+ template<bool IsOptional> inline TUnboxedValuePod GetOptionalValueIf() const;
+ template<bool IsOptional> inline TUnboxedValuePod MakeOptionalIf() const;
+
+ // List accessors
+ inline bool HasFastListLength() const;
+ inline ui64 GetListLength() const;
+ inline ui64 GetEstimatedListLength() const;
+ inline TUnboxedValue GetListIterator() const;
+ inline bool HasListItems() const;
+
+ // Dict accessors
+ inline ui64 GetDictLength() const;
+ inline TUnboxedValue GetDictIterator() const;
+ inline TUnboxedValue GetKeysIterator() const;
+ inline TUnboxedValue GetPayloadsIterator() const;
+
+ inline bool Contains(const TUnboxedValuePod& key) const;
+ inline TUnboxedValue Lookup(const TUnboxedValuePod& key) const;
+ inline bool HasDictItems() const;
+
+ // Tuple or Struct accessors
+ inline TUnboxedValue GetElement(ui32 index) const;
+ inline const TUnboxedValue* GetElements() const;
+
+ // Callable accessors
inline TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const;
-
- // Resource accessors
- inline TStringRef GetResourceTag() const;
- inline void* GetResource() const;
-
- inline ui32 GetVariantIndex() const;
- inline TUnboxedValue GetVariantItem() const;
-
- inline EFetchStatus Fetch(TUnboxedValue& result) const;
-
- // Any iterator.
- inline bool Skip() const;
- // List iterator.
- inline bool Next(TUnboxedValue& value) const;
- // Dict iterator.
- inline bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) const;
-
- inline void Apply(IApplyContext& context) const;
-
+
+ // Resource accessors
+ inline TStringRef GetResourceTag() const;
+ inline void* GetResource() const;
+
+ inline ui32 GetVariantIndex() const;
+ inline TUnboxedValue GetVariantItem() const;
+
+ inline EFetchStatus Fetch(TUnboxedValue& result) const;
+
+ // Any iterator.
+ inline bool Skip() const;
+ // List iterator.
+ inline bool Next(TUnboxedValue& value) const;
+ // Dict iterator.
+ inline bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) const;
+
+ inline void Apply(IApplyContext& context) const;
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
// Save/Load state
inline ui32 GetTraverseCount() const;
@@ -940,118 +940,118 @@ public:
inline bool VisitBlocks(TBlockCallback callback, void* context);
#endif
- inline bool TryMakeVariant(ui32 index);
-
+ inline bool TryMakeVariant(ui32 index);
+
inline void SetTimezoneId(ui16 id);
inline ui16 GetTimezoneId() const;
-protected:
- union TRaw {
- ui64 Halfs[2] = {0, 0};
-
- struct {
- char Buffer[0xE];
- ui8 Size;
- ui8 Meta;
- } Embedded;
-
- struct {
- IBoxedValue* Value;
- ui8 Reserved[7];
- ui8 Meta;
- } Boxed;
-
- struct {
- TStringValue::TData* Value;
- ui32 Size;
- union {
- ui32 Offset;
- struct {
- ui8 Skip[3];
- ui8 Meta;
- };
- };
- } String;
-
- struct {
- union {
- #define FIELD(type) type type##_;
- PRIMITIVE_VALUE_TYPES(FIELD);
- #undef FIELD
- const void* Void;
- ui64 Count;
- };
- union {
- ui64 FullMeta;
- struct {
+protected:
+ union TRaw {
+ ui64 Halfs[2] = {0, 0};
+
+ struct {
+ char Buffer[0xE];
+ ui8 Size;
+ ui8 Meta;
+ } Embedded;
+
+ struct {
+ IBoxedValue* Value;
+ ui8 Reserved[7];
+ ui8 Meta;
+ } Boxed;
+
+ struct {
+ TStringValue::TData* Value;
+ ui32 Size;
+ union {
+ ui32 Offset;
+ struct {
+ ui8 Skip[3];
+ ui8 Meta;
+ };
+ };
+ } String;
+
+ struct {
+ union {
+ #define FIELD(type) type type##_;
+ PRIMITIVE_VALUE_TYPES(FIELD);
+ #undef FIELD
+ const void* Void;
+ ui64 Count;
+ };
+ union {
+ ui64 FullMeta;
+ struct {
ui16 TimezoneId;
ui8 Reserved[4];
- ui8 Size;
- ui8 Meta;
- };
- };
- } Simple;
-
- EMarkers GetMarkers() const {
- return static_cast<EMarkers>(0x3 & Simple.Meta);
- }
-
- ui8 GetIndex() const {
- return Simple.Meta >> 2;
- }
-
- explicit operator bool() const { return Simple.FullMeta | Simple.Count; }
- } Raw;
-
-public:
- inline void Ref() const noexcept;
- inline void UnRef() const noexcept;
- inline void ReleaseRef() const noexcept;
- inline void DeleteUnreferenced() const noexcept;
+ ui8 Size;
+ ui8 Meta;
+ };
+ };
+ } Simple;
+
+ EMarkers GetMarkers() const {
+ return static_cast<EMarkers>(0x3 & Simple.Meta);
+ }
+
+ ui8 GetIndex() const {
+ return Simple.Meta >> 2;
+ }
+
+ explicit operator bool() const { return Simple.FullMeta | Simple.Count; }
+ } Raw;
+
+public:
+ inline void Ref() const noexcept;
+ inline void UnRef() const noexcept;
+ inline void ReleaseRef() const noexcept;
+ inline void DeleteUnreferenced() const noexcept;
inline i32 LockRef() const noexcept;
inline void UnlockRef(i32 prev) const noexcept;
-
- static constexpr ui32 InternalBufferSize = sizeof(TRaw::Embedded.Buffer);
- static constexpr ui32 OffsetLimit = 1U << 24U;
-};
-
-UDF_ASSERT_TYPE_SIZE(TUnboxedValuePod, 16);
-
-static_assert(std::is_trivially_destructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
-static_assert(std::is_trivially_copy_assignable<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
-static_assert(std::is_trivially_move_assignable<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
-static_assert(std::is_trivially_copy_constructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
-static_assert(std::is_trivially_move_constructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
-
-//////////////////////////////////////////////////////////////////////////////
-// TUnboxedValue
-///////////////////////////////////////////////////////////////////////////////
-class TUnboxedValue : public TUnboxedValuePod
-{
-public:
- inline TUnboxedValue() noexcept = default;
- inline ~TUnboxedValue() noexcept;
-
- inline TUnboxedValue(const TUnboxedValuePod& value) noexcept;
- inline TUnboxedValue(TUnboxedValuePod&& value) noexcept;
-
- inline TUnboxedValue(const TUnboxedValue& value) noexcept;
+
+ static constexpr ui32 InternalBufferSize = sizeof(TRaw::Embedded.Buffer);
+ static constexpr ui32 OffsetLimit = 1U << 24U;
+};
+
+UDF_ASSERT_TYPE_SIZE(TUnboxedValuePod, 16);
+
+static_assert(std::is_trivially_destructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
+static_assert(std::is_trivially_copy_assignable<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
+static_assert(std::is_trivially_move_assignable<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
+static_assert(std::is_trivially_copy_constructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
+static_assert(std::is_trivially_move_constructible<TUnboxedValuePod>::value, "Incompatible with LLVM codegeneration!");
+
+//////////////////////////////////////////////////////////////////////////////
+// TUnboxedValue
+///////////////////////////////////////////////////////////////////////////////
+class TUnboxedValue : public TUnboxedValuePod
+{
+public:
+ inline TUnboxedValue() noexcept = default;
+ inline ~TUnboxedValue() noexcept;
+
+ inline TUnboxedValue(const TUnboxedValuePod& value) noexcept;
+ inline TUnboxedValue(TUnboxedValuePod&& value) noexcept;
+
+ inline TUnboxedValue(const TUnboxedValue& value) noexcept;
inline TUnboxedValue(TUnboxedValue&& value) noexcept;
-
- inline TUnboxedValue& operator=(const TUnboxedValue& value) noexcept;
+
+ inline TUnboxedValue& operator=(const TUnboxedValue& value) noexcept;
inline TUnboxedValue& operator=(TUnboxedValue&& value) noexcept;
-
- inline TUnboxedValuePod Release() noexcept;
-
- inline void Clear() noexcept;
-
- using TAllocator = TStdAllocatorForUdf<TUnboxedValue>;
-};
-
-UDF_ASSERT_TYPE_SIZE(TUnboxedValue, 16);
-
+
+ inline TUnboxedValuePod Release() noexcept;
+
+ inline void Clear() noexcept;
+
+ using TAllocator = TStdAllocatorForUdf<TUnboxedValue>;
+};
+
+UDF_ASSERT_TYPE_SIZE(TUnboxedValue, 16);
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
// TSingleBlock
///////////////////////////////////////////////////////////////////////////////
class TSingleBlock: public TBlock {
@@ -1079,62 +1079,62 @@ UDF_ASSERT_TYPE_SIZE(TSingleBlockPtr, 8);
#endif
///////////////////////////////////////////////////////////////////////////////
-// TBoxedResource
-///////////////////////////////////////////////////////////////////////////////
-template <typename TResourceData, const char* ResourceTag>
-class TBoxedResource: public TBoxedValue
-{
-public:
- template <typename... Args>
- inline TBoxedResource(Args&&... args)
- : ResourceData_(std::forward<Args>(args)...)
- {
- }
-
- inline TStringRef GetResourceTag() const override {
- return TStringRef(ResourceTag, std::strlen(ResourceTag));
- }
-
- inline void* GetResource() override {
- return Get();
- }
-
- inline TResourceData* Get() {
- return &ResourceData_;
- }
-
- inline static void Validate(const TUnboxedValuePod& value) {
- Y_VERIFY_DEBUG(value.GetResourceTag() == TStringRef(ResourceTag, std::strlen(ResourceTag)));
- }
-
-private:
- TResourceData ResourceData_;
-};
-
+// TBoxedResource
+///////////////////////////////////////////////////////////////////////////////
+template <typename TResourceData, const char* ResourceTag>
+class TBoxedResource: public TBoxedValue
+{
+public:
+ template <typename... Args>
+ inline TBoxedResource(Args&&... args)
+ : ResourceData_(std::forward<Args>(args)...)
+ {
+ }
+
+ inline TStringRef GetResourceTag() const override {
+ return TStringRef(ResourceTag, std::strlen(ResourceTag));
+ }
+
+ inline void* GetResource() override {
+ return Get();
+ }
+
+ inline TResourceData* Get() {
+ return &ResourceData_;
+ }
+
+ inline static void Validate(const TUnboxedValuePod& value) {
+ Y_VERIFY_DEBUG(value.GetResourceTag() == TStringRef(ResourceTag, std::strlen(ResourceTag)));
+ }
+
+private:
+ TResourceData ResourceData_;
+};
+
#define INCLUDE_UDF_VALUE_INL_H
#include "udf_value_inl.h"
#undef INCLUDE_UDF_VALUE_INL_H
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
template<>
-inline void Out<NYql::NUdf::TUnboxedValuePod>(class IOutputStream &o, const NYql::NUdf::TUnboxedValuePod& value);
+inline void Out<NYql::NUdf::TUnboxedValuePod>(class IOutputStream &o, const NYql::NUdf::TUnboxedValuePod& value);
template<>
-inline void Out<NYql::NUdf::TUnboxedValue>(class IOutputStream &o, const NYql::NUdf::TUnboxedValue& value);
+inline void Out<NYql::NUdf::TUnboxedValue>(class IOutputStream &o, const NYql::NUdf::TUnboxedValue& value);
template<>
-inline void Out<NYql::NUdf::EFetchStatus>(class IOutputStream &o, NYql::NUdf::EFetchStatus value);
+inline void Out<NYql::NUdf::EFetchStatus>(class IOutputStream &o, NYql::NUdf::EFetchStatus value);
template<>
-inline void Out<NYql::NUdf::TStringRef>(class IOutputStream &o, const NYql::NUdf::TStringRef& value);
+inline void Out<NYql::NUdf::TStringRef>(class IOutputStream &o, const NYql::NUdf::TStringRef& value);
#include "udf_terminator.h"
#include <util/stream/output.h>
#include <tuple>
-namespace NYql {
+namespace NYql {
namespace NUdf {
//////////////////////////////////////////////////////////////////////////////
@@ -1224,7 +1224,7 @@ inline TUnboxedValue TBoxedValueBase::GetKeysIterator() const
inline TUnboxedValue TBoxedValueBase::GetPayloadsIterator() const
{
- Y_FAIL("Not implemented");
+ Y_FAIL("Not implemented");
}
inline bool TBoxedValueBase::Skip()
@@ -1394,34 +1394,34 @@ inline void TUnboxedValuePod::Dump(IOutputStream& out) const {
}
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
template<>
-inline void Out<NYql::NUdf::TUnboxedValuePod>(class IOutputStream &o, const NYql::NUdf::TUnboxedValuePod& value) {
+inline void Out<NYql::NUdf::TUnboxedValuePod>(class IOutputStream &o, const NYql::NUdf::TUnboxedValuePod& value) {
value.Dump(o);
}
template<>
-inline void Out<NYql::NUdf::TUnboxedValue>(class IOutputStream &o, const NYql::NUdf::TUnboxedValue& value) {
+inline void Out<NYql::NUdf::TUnboxedValue>(class IOutputStream &o, const NYql::NUdf::TUnboxedValue& value) {
value.Dump(o);
}
template<>
-inline void Out<NYql::NUdf::EFetchStatus>(class IOutputStream &o, NYql::NUdf::EFetchStatus value) {
+inline void Out<NYql::NUdf::EFetchStatus>(class IOutputStream &o, NYql::NUdf::EFetchStatus value) {
switch (value) {
- case NYql::NUdf::EFetchStatus::Ok:
+ case NYql::NUdf::EFetchStatus::Ok:
o << "Ok";
break;
- case NYql::NUdf::EFetchStatus::Yield:
+ case NYql::NUdf::EFetchStatus::Yield:
o << "Yield";
break;
- case NYql::NUdf::EFetchStatus::Finish:
+ case NYql::NUdf::EFetchStatus::Finish:
o << "Finish";
break;
}
}
template<>
-inline void Out<NYql::NUdf::TStringRef>(class IOutputStream &o, const NYql::NUdf::TStringRef& value) {
+inline void Out<NYql::NUdf::TStringRef>(class IOutputStream &o, const NYql::NUdf::TStringRef& value) {
o << TStringBuf(value.Data(), value.Size());
}
diff --git a/ydb/library/yql/public/udf/udf_value_builder.h b/ydb/library/yql/public/udf/udf_value_builder.h
index 20cf4e3315..096f735a2b 100644
--- a/ydb/library/yql/public/udf/udf_value_builder.h
+++ b/ydb/library/yql/public/udf/udf_value_builder.h
@@ -3,12 +3,12 @@
#include "udf_ptr.h"
#include "udf_types.h"
#include "udf_type_builder.h"
-#include "udf_string.h"
-#include "udf_value.h"
+#include "udf_string.h"
+#include "udf_value.h"
#include <array>
-namespace NYql {
+namespace NYql {
namespace NUdf {
///////////////////////////////////////////////////////////////////////////////
@@ -30,13 +30,13 @@ public:
public:
virtual ~IDictValueBuilder() = default;
- virtual IDictValueBuilder& Add(TUnboxedValue&& key, TUnboxedValue&& value) = 0;
-
- virtual TUnboxedValue Build() = 0;
-};
-
-UDF_ASSERT_TYPE_SIZE(IDictValueBuilder, 8);
-
+ virtual IDictValueBuilder& Add(TUnboxedValue&& key, TUnboxedValue&& value) = 0;
+
+ virtual TUnboxedValue Build() = 0;
+};
+
+UDF_ASSERT_TYPE_SIZE(IDictValueBuilder, 8);
+
///////////////////////////////////////////////////////////////////////////////
// IDateBuilder
///////////////////////////////////////////////////////////////////////////////
@@ -53,22 +53,22 @@ public:
virtual bool SplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
ui16 timezoneId = 0) const = 0;
- // deprecated
+ // deprecated
virtual bool EnrichDate(ui16 date, ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek) const = 0;
// in minutes
virtual bool GetTimezoneShift(ui32 year, ui32 month, ui32 day, ui32 hour, ui32 minute, ui32 second,
ui16 timezoneId, i32& value) const = 0;
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT < UDF_ABI_COMPATIBILITY_VERSION(2, 23)
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT < UDF_ABI_COMPATIBILITY_VERSION(2, 23)
virtual void Unused7() const = 0;
virtual void Unused8() const = 0;
-#else
- virtual bool FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const = 0;
- virtual bool FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
- ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const = 0;
-#endif
+#else
+ virtual bool FullSplitDate(ui16 value, ui32& year, ui32& month, ui32& day,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const = 0;
+ virtual bool FullSplitDatetime(ui32 value, ui32& year, ui32& month, ui32& day, ui32& hour, ui32& minute, ui32& second,
+ ui32& dayOfYear, ui32& weekOfYear, ui32& dayOfWeek, ui16 timezoneId = 0) const = 0;
+#endif
};
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 7)
@@ -106,34 +106,34 @@ UDF_ASSERT_TYPE_SIZE(IDateBuilder, 8);
// IValueBuilder
///////////////////////////////////////////////////////////////////////////////
class IValueBuilder1
-{
-public:
+{
+public:
virtual ~IValueBuilder1() = default;
-
- virtual TUnboxedValue NewStringNotFilled(ui32 size) const = 0;
- virtual TUnboxedValue NewString(const TStringRef& ref) const = 0;
-
- virtual TUnboxedValue ConcatStrings(TUnboxedValuePod first, TUnboxedValuePod second) const = 0;
-
- virtual TUnboxedValue AppendString(TUnboxedValuePod value, const TStringRef& ref) const = 0;
- virtual TUnboxedValue PrependString(const TStringRef& ref, TUnboxedValuePod value) const = 0;
-
- virtual TUnboxedValue SubString(TUnboxedValuePod value, ui32 offset, ui32 size) const = 0;
-
- virtual IDictValueBuilder::TPtr NewDict(const TType* dictType, ui32 flags) const = 0;
-
- virtual TUnboxedValue NewList(TUnboxedValue* items, ui64 count) const = 0;
-
- virtual TUnboxedValue ReverseList(const TUnboxedValuePod& list) const = 0;
- virtual TUnboxedValue SkipList(const TUnboxedValuePod& list, ui64 count) const = 0;
- virtual TUnboxedValue TakeList(const TUnboxedValuePod& list, ui64 count) const = 0;
- virtual TUnboxedValue ToIndexDict(const TUnboxedValuePod& list) const = 0;
-
- /// Default representation for Tuple, Struct or List with a known size.
- virtual TUnboxedValue NewArray(ui32 count, TUnboxedValue*& itemsPtr) const = 0;
-
- virtual TUnboxedValue NewVariant(ui32 index, TUnboxedValue&& value) const = 0;
-
+
+ virtual TUnboxedValue NewStringNotFilled(ui32 size) const = 0;
+ virtual TUnboxedValue NewString(const TStringRef& ref) const = 0;
+
+ virtual TUnboxedValue ConcatStrings(TUnboxedValuePod first, TUnboxedValuePod second) const = 0;
+
+ virtual TUnboxedValue AppendString(TUnboxedValuePod value, const TStringRef& ref) const = 0;
+ virtual TUnboxedValue PrependString(const TStringRef& ref, TUnboxedValuePod value) const = 0;
+
+ virtual TUnboxedValue SubString(TUnboxedValuePod value, ui32 offset, ui32 size) const = 0;
+
+ virtual IDictValueBuilder::TPtr NewDict(const TType* dictType, ui32 flags) const = 0;
+
+ virtual TUnboxedValue NewList(TUnboxedValue* items, ui64 count) const = 0;
+
+ virtual TUnboxedValue ReverseList(const TUnboxedValuePod& list) const = 0;
+ virtual TUnboxedValue SkipList(const TUnboxedValuePod& list, ui64 count) const = 0;
+ virtual TUnboxedValue TakeList(const TUnboxedValuePod& list, ui64 count) const = 0;
+ virtual TUnboxedValue ToIndexDict(const TUnboxedValuePod& list) const = 0;
+
+ /// Default representation for Tuple, Struct or List with a known size.
+ virtual TUnboxedValue NewArray(ui32 count, TUnboxedValue*& itemsPtr) const = 0;
+
+ virtual TUnboxedValue NewVariant(ui32 index, TUnboxedValue&& value) const = 0;
+
inline TUnboxedValue NewEmptyList() const { return NewList(nullptr, 0); }
};
@@ -177,7 +177,7 @@ public:
virtual TSingleBlockPtr NewSingleBlock(const TUnboxedValue& value) const = 0;
};
#endif
-
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
class IValueBuilder: public IValueBuilder5 {};
#elif UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 17)
@@ -192,40 +192,40 @@ class IValueBuilder: public IValueBuilder1 {};
UDF_ASSERT_TYPE_SIZE(IValueBuilder, 8);
-class TPlainArrayCache {
-private:
- const ui32 Size;
- std::array<TUnboxedValue, 2U> Cached;
- std::array<TUnboxedValue*, 2U> CachedItems;
- ui8 CacheIndex = 0U;
-public:
- TPlainArrayCache(ui32 size): Size(size) { Clear(); }
-
- TPlainArrayCache(TPlainArrayCache&&) = delete;
- TPlainArrayCache(const TPlainArrayCache&) = delete;
- TPlainArrayCache& operator=(TPlainArrayCache&&) = delete;
- TPlainArrayCache& operator=(const TPlainArrayCache&) = delete;
-
- void Clear() {
- Cached.fill(TUnboxedValue());
- CachedItems.fill(nullptr);
- }
-
- TUnboxedValue NewArray(const IValueBuilder& builder, TUnboxedValue*& items) {
- if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
- CacheIndex ^= 1U;
- if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
- Cached[CacheIndex] = builder.NewArray(Size, CachedItems[CacheIndex]);
- items = CachedItems[CacheIndex];
- return Cached[CacheIndex];
- }
- }
-
- items = CachedItems[CacheIndex];
- std::fill_n(items, Size, TUnboxedValue());
- return Cached[CacheIndex];
- }
-};
-
+class TPlainArrayCache {
+private:
+ const ui32 Size;
+ std::array<TUnboxedValue, 2U> Cached;
+ std::array<TUnboxedValue*, 2U> CachedItems;
+ ui8 CacheIndex = 0U;
+public:
+ TPlainArrayCache(ui32 size): Size(size) { Clear(); }
+
+ TPlainArrayCache(TPlainArrayCache&&) = delete;
+ TPlainArrayCache(const TPlainArrayCache&) = delete;
+ TPlainArrayCache& operator=(TPlainArrayCache&&) = delete;
+ TPlainArrayCache& operator=(const TPlainArrayCache&) = delete;
+
+ void Clear() {
+ Cached.fill(TUnboxedValue());
+ CachedItems.fill(nullptr);
+ }
+
+ TUnboxedValue NewArray(const IValueBuilder& builder, TUnboxedValue*& items) {
+ if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
+ CacheIndex ^= 1U;
+ if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
+ Cached[CacheIndex] = builder.NewArray(Size, CachedItems[CacheIndex]);
+ items = CachedItems[CacheIndex];
+ return Cached[CacheIndex];
+ }
+ }
+
+ items = CachedItems[CacheIndex];
+ std::fill_n(items, Size, TUnboxedValue());
+ return Cached[CacheIndex];
+ }
+};
+
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
diff --git a/ydb/library/yql/public/udf/udf_value_builder_ut.cpp b/ydb/library/yql/public/udf/udf_value_builder_ut.cpp
index 129dfd379f..1b55e94822 100644
--- a/ydb/library/yql/public/udf/udf_value_builder_ut.cpp
+++ b/ydb/library/yql/public/udf/udf_value_builder_ut.cpp
@@ -1,26 +1,26 @@
-#include "udf_value_builder.h"
-#include "udf_ut_helpers.h"
-
+#include "udf_value_builder.h"
+#include "udf_ut_helpers.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NYql::NUdf;
-
+
+using namespace NYql::NUdf;
+
Y_UNIT_TEST_SUITE(TUdfValueBuilder) {
Y_UNIT_TEST(LockMethodsTable) {
- UNIT_ASSERT_VALUES_EQUAL(2, GetMethodIndex(&IValueBuilder::NewStringNotFilled));
- UNIT_ASSERT_VALUES_EQUAL(3, GetMethodIndex(&IValueBuilder::NewString));
- UNIT_ASSERT_VALUES_EQUAL(4, GetMethodIndex(&IValueBuilder::ConcatStrings));
- UNIT_ASSERT_VALUES_EQUAL(5, GetMethodIndex(&IValueBuilder::AppendString));
- UNIT_ASSERT_VALUES_EQUAL(6, GetMethodIndex(&IValueBuilder::PrependString));
- UNIT_ASSERT_VALUES_EQUAL(7, GetMethodIndex(&IValueBuilder::SubString));
- UNIT_ASSERT_VALUES_EQUAL(8, GetMethodIndex(&IValueBuilder::NewDict));
- UNIT_ASSERT_VALUES_EQUAL(9, GetMethodIndex(&IValueBuilder::NewList));
- UNIT_ASSERT_VALUES_EQUAL(10, GetMethodIndex(&IValueBuilder::ReverseList));
- UNIT_ASSERT_VALUES_EQUAL(11, GetMethodIndex(&IValueBuilder::SkipList));
- UNIT_ASSERT_VALUES_EQUAL(12, GetMethodIndex(&IValueBuilder::TakeList));
- UNIT_ASSERT_VALUES_EQUAL(13, GetMethodIndex(&IValueBuilder::ToIndexDict));
- UNIT_ASSERT_VALUES_EQUAL(14, GetMethodIndex(&IValueBuilder::NewArray));
- UNIT_ASSERT_VALUES_EQUAL(15, GetMethodIndex(&IValueBuilder::NewVariant));
+ UNIT_ASSERT_VALUES_EQUAL(2, GetMethodIndex(&IValueBuilder::NewStringNotFilled));
+ UNIT_ASSERT_VALUES_EQUAL(3, GetMethodIndex(&IValueBuilder::NewString));
+ UNIT_ASSERT_VALUES_EQUAL(4, GetMethodIndex(&IValueBuilder::ConcatStrings));
+ UNIT_ASSERT_VALUES_EQUAL(5, GetMethodIndex(&IValueBuilder::AppendString));
+ UNIT_ASSERT_VALUES_EQUAL(6, GetMethodIndex(&IValueBuilder::PrependString));
+ UNIT_ASSERT_VALUES_EQUAL(7, GetMethodIndex(&IValueBuilder::SubString));
+ UNIT_ASSERT_VALUES_EQUAL(8, GetMethodIndex(&IValueBuilder::NewDict));
+ UNIT_ASSERT_VALUES_EQUAL(9, GetMethodIndex(&IValueBuilder::NewList));
+ UNIT_ASSERT_VALUES_EQUAL(10, GetMethodIndex(&IValueBuilder::ReverseList));
+ UNIT_ASSERT_VALUES_EQUAL(11, GetMethodIndex(&IValueBuilder::SkipList));
+ UNIT_ASSERT_VALUES_EQUAL(12, GetMethodIndex(&IValueBuilder::TakeList));
+ UNIT_ASSERT_VALUES_EQUAL(13, GetMethodIndex(&IValueBuilder::ToIndexDict));
+ UNIT_ASSERT_VALUES_EQUAL(14, GetMethodIndex(&IValueBuilder::NewArray));
+ UNIT_ASSERT_VALUES_EQUAL(15, GetMethodIndex(&IValueBuilder::NewVariant));
UNIT_ASSERT_VALUES_EQUAL(16, GetMethodIndex(&IValueBuilder::GetDateBuilder));
UNIT_ASSERT_VALUES_EQUAL(17, GetMethodIndex(&IValueBuilder::GetSecureParam));
UNIT_ASSERT_VALUES_EQUAL(18, GetMethodIndex(&IValueBuilder::CalleePosition));
@@ -28,5 +28,5 @@ Y_UNIT_TEST_SUITE(TUdfValueBuilder) {
UNIT_ASSERT_VALUES_EQUAL(20, GetMethodIndex(&IValueBuilder::NewFlatDataBlock));
UNIT_ASSERT_VALUES_EQUAL(21, GetMethodIndex(&IValueBuilder::NewFlatArrayBlock));
UNIT_ASSERT_VALUES_EQUAL(22, GetMethodIndex(&IValueBuilder::NewSingleBlock));
- }
-}
+ }
+}
diff --git a/ydb/library/yql/public/udf/udf_value_inl.h b/ydb/library/yql/public/udf/udf_value_inl.h
index 759af438f5..eb2db28e18 100644
--- a/ydb/library/yql/public/udf/udf_value_inl.h
+++ b/ydb/library/yql/public/udf/udf_value_inl.h
@@ -28,45 +28,45 @@
//////////////////////////////////////////////////////////////////////////////
inline void IBoxedValue1::Ref() noexcept
{
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- ++Refs_;
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
+ ++Refs_;
}
inline void IBoxedValue1::UnRef() noexcept
{
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
Y_VERIFY_DEBUG(Refs_ > 0);
- if (!--Refs_)
- delete this;
-}
-
+ if (!--Refs_)
+ delete this;
+}
+
inline void IBoxedValue1::ReleaseRef() noexcept
-{
-#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
- if (Refs_ < 0)
- return;
-#endif
- Y_VERIFY_DEBUG(Refs_ > 0);
- --Refs_;
-}
-
+{
+#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 4)
+ if (Refs_ < 0)
+ return;
+#endif
+ Y_VERIFY_DEBUG(Refs_ > 0);
+ --Refs_;
+}
+
inline void IBoxedValue1::DeleteUnreferenced() noexcept
-{
- if (!Refs_)
- delete this;
-}
-
+{
+ if (!Refs_)
+ delete this;
+}
+
inline i32 IBoxedValue1::RefCount() const noexcept
-{
- return Refs_;
-}
-
+{
+ return Refs_;
+}
+
inline void IBoxedValue1::SetUserMark(ui8 mark) noexcept {
UserMark_ = mark;
}
@@ -89,7 +89,7 @@ inline void IBoxedValue1::UnlockRef(i32 prev) noexcept {
}
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 19)
-//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
// TFlatArrayBlock
//////////////////////////////////////////////////////////////////////////////
@@ -115,154 +115,154 @@ inline TFlatArrayBlock::~TFlatArrayBlock() {
#endif
//////////////////////////////////////////////////////////////////////////////
-// TBoxedValueAccessor
-//////////////////////////////////////////////////////////////////////////////
-
-inline bool TBoxedValueAccessor::HasFastListLength(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.HasFastListLength();
-}
-
-inline ui64 TBoxedValueAccessor::GetListLength(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetListLength();
-}
-
-inline ui64 TBoxedValueAccessor::GetEstimatedListLength(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetEstimatedListLength();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetListIterator(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetListIterator();
-}
-
-inline const TOpaqueListRepresentation* TBoxedValueAccessor::GetListRepresentation(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetListRepresentation();
-}
-
+// TBoxedValueAccessor
+//////////////////////////////////////////////////////////////////////////////
+
+inline bool TBoxedValueAccessor::HasFastListLength(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.HasFastListLength();
+}
+
+inline ui64 TBoxedValueAccessor::GetListLength(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetListLength();
+}
+
+inline ui64 TBoxedValueAccessor::GetEstimatedListLength(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetEstimatedListLength();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetListIterator(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetListIterator();
+}
+
+inline const TOpaqueListRepresentation* TBoxedValueAccessor::GetListRepresentation(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetListRepresentation();
+}
+
inline IBoxedValuePtr TBoxedValueAccessor::ReverseListImpl(const IBoxedValue& value, const IValueBuilder& builder) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.ReverseListImpl(builder);
-}
-
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.ReverseListImpl(builder);
+}
+
inline IBoxedValuePtr TBoxedValueAccessor::SkipListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.SkipListImpl(builder, count);
-}
-
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.SkipListImpl(builder, count);
+}
+
inline IBoxedValuePtr TBoxedValueAccessor::TakeListImpl(const IBoxedValue& value, const IValueBuilder& builder, ui64 count) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.TakeListImpl(builder, count);
-}
-
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.TakeListImpl(builder, count);
+}
+
inline IBoxedValuePtr TBoxedValueAccessor::ToIndexDictImpl(const IBoxedValue& value, const IValueBuilder& builder) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.ToIndexDictImpl(builder);
-}
-
-inline ui64 TBoxedValueAccessor::GetDictLength(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetDictLength();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetDictIterator(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetDictIterator();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetKeysIterator(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetKeysIterator();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetPayloadsIterator(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetPayloadsIterator();
-}
-
-inline bool TBoxedValueAccessor::Contains(const IBoxedValue& value, const TUnboxedValuePod& key) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Contains(key);
-}
-
-inline TUnboxedValue TBoxedValueAccessor::Lookup(const IBoxedValue& value, const TUnboxedValuePod& key) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Lookup(key);
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetElement(const IBoxedValue& value, ui32 index) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetElement(index);
-}
-
-inline const TUnboxedValue* TBoxedValueAccessor::GetElements(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetElements();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::Run(const IBoxedValue& value, const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Run(valueBuilder, args);
-}
-
-inline TStringRef TBoxedValueAccessor::GetResourceTag(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetResourceTag();
-}
-
-inline void* TBoxedValueAccessor::GetResource(IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetResource();
-}
-
-inline bool TBoxedValueAccessor::HasListItems(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.HasListItems();
-}
-
-inline bool TBoxedValueAccessor::HasDictItems(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.HasDictItems();
-}
-
-inline ui32 TBoxedValueAccessor::GetVariantIndex(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetVariantIndex();
-}
-
-inline TUnboxedValue TBoxedValueAccessor::GetVariantItem(const IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.GetVariantItem();
-}
-
-inline EFetchStatus TBoxedValueAccessor::Fetch(IBoxedValue& value, TUnboxedValue& result) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Fetch(result);
-}
-
-inline bool TBoxedValueAccessor::Skip(IBoxedValue& value) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Skip();
-}
-
-inline bool TBoxedValueAccessor::Next(IBoxedValue& value, TUnboxedValue& result) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Next(result);
-}
-
-inline bool TBoxedValueAccessor::NextPair(IBoxedValue& value, TUnboxedValue& key, TUnboxedValue& payload) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.NextPair(key, payload);
-}
-
-inline void TBoxedValueAccessor::Apply(IBoxedValue& value, IApplyContext& context) {
- Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
- return value.Apply(context);
-}
-
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.ToIndexDictImpl(builder);
+}
+
+inline ui64 TBoxedValueAccessor::GetDictLength(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetDictLength();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetDictIterator(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetDictIterator();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetKeysIterator(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetKeysIterator();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetPayloadsIterator(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetPayloadsIterator();
+}
+
+inline bool TBoxedValueAccessor::Contains(const IBoxedValue& value, const TUnboxedValuePod& key) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Contains(key);
+}
+
+inline TUnboxedValue TBoxedValueAccessor::Lookup(const IBoxedValue& value, const TUnboxedValuePod& key) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Lookup(key);
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetElement(const IBoxedValue& value, ui32 index) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetElement(index);
+}
+
+inline const TUnboxedValue* TBoxedValueAccessor::GetElements(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetElements();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::Run(const IBoxedValue& value, const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Run(valueBuilder, args);
+}
+
+inline TStringRef TBoxedValueAccessor::GetResourceTag(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetResourceTag();
+}
+
+inline void* TBoxedValueAccessor::GetResource(IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetResource();
+}
+
+inline bool TBoxedValueAccessor::HasListItems(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.HasListItems();
+}
+
+inline bool TBoxedValueAccessor::HasDictItems(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.HasDictItems();
+}
+
+inline ui32 TBoxedValueAccessor::GetVariantIndex(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetVariantIndex();
+}
+
+inline TUnboxedValue TBoxedValueAccessor::GetVariantItem(const IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.GetVariantItem();
+}
+
+inline EFetchStatus TBoxedValueAccessor::Fetch(IBoxedValue& value, TUnboxedValue& result) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Fetch(result);
+}
+
+inline bool TBoxedValueAccessor::Skip(IBoxedValue& value) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Skip();
+}
+
+inline bool TBoxedValueAccessor::Next(IBoxedValue& value, TUnboxedValue& result) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Next(result);
+}
+
+inline bool TBoxedValueAccessor::NextPair(IBoxedValue& value, TUnboxedValue& key, TUnboxedValue& payload) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.NextPair(key, payload);
+}
+
+inline void TBoxedValueAccessor::Apply(IBoxedValue& value, IApplyContext& context) {
+ Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 0)));
+ return value.Apply(context);
+}
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
inline ui32 TBoxedValueAccessor::GetTraverseCount(const IBoxedValue& value) {
Y_VERIFY_DEBUG(value.IsCompatibleTo(MakeAbiCompatibilityVersion(2, 3)));
@@ -335,260 +335,260 @@ inline bool TBoxedValueAccessor::VisitBlocks(IBoxedValue& value, TBlockCallback
#endif
-//////////////////////////////////////////////////////////////////////////////
-// TUnboxedValue
-//////////////////////////////////////////////////////////////////////////////
-Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValuePod& value) noexcept
- : TUnboxedValuePod(value)
-{
- Ref();
-}
-
-Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValuePod&& value) noexcept
- : TUnboxedValuePod(std::move(value))
-{
- value.Raw = TRaw();
- Ref();
-}
-
-Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValue& value) noexcept
- : TUnboxedValuePod(static_cast<const TUnboxedValuePod&>(value))
-{
- Ref();
-}
-
-Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValue&& value) noexcept
- : TUnboxedValuePod(static_cast<TUnboxedValuePod&&>(value))
-{
- value.Raw = TRaw();
-}
-
-Y_FORCE_INLINE TUnboxedValue& TUnboxedValue::operator=(const TUnboxedValue& value) noexcept
-{
- if (this != &value) {
- value.Ref();
- UnRef();
- Raw = value.Raw;
- }
- return *this;
-}
-
+//////////////////////////////////////////////////////////////////////////////
+// TUnboxedValue
+//////////////////////////////////////////////////////////////////////////////
+Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValuePod& value) noexcept
+ : TUnboxedValuePod(value)
+{
+ Ref();
+}
+
+Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValuePod&& value) noexcept
+ : TUnboxedValuePod(std::move(value))
+{
+ value.Raw = TRaw();
+ Ref();
+}
+
+Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(const TUnboxedValue& value) noexcept
+ : TUnboxedValuePod(static_cast<const TUnboxedValuePod&>(value))
+{
+ Ref();
+}
+
+Y_FORCE_INLINE TUnboxedValue::TUnboxedValue(TUnboxedValue&& value) noexcept
+ : TUnboxedValuePod(static_cast<TUnboxedValuePod&&>(value))
+{
+ value.Raw = TRaw();
+}
+
+Y_FORCE_INLINE TUnboxedValue& TUnboxedValue::operator=(const TUnboxedValue& value) noexcept
+{
+ if (this != &value) {
+ value.Ref();
+ UnRef();
+ Raw = value.Raw;
+ }
+ return *this;
+}
+
Y_FORCE_INLINE TUnboxedValue& TUnboxedValue::operator=(TUnboxedValue&& value) noexcept
-{
- if (this != &value) {
- UnRef();
- Raw = value.Raw;
- value.Raw = TRaw();
- }
- return *this;
-}
-
-Y_FORCE_INLINE TUnboxedValuePod TUnboxedValue::Release() noexcept {
- const TUnboxedValuePod value(std::move(*static_cast<TUnboxedValuePod*>(this)));
- Raw = TRaw();
- value.ReleaseRef();
- return value;
-}
-
-Y_FORCE_INLINE void TUnboxedValue::Clear() noexcept
-{
- UnRef();
- Raw = TRaw();
-}
-
-Y_FORCE_INLINE TUnboxedValue::~TUnboxedValue() noexcept
-{
- UnRef();
-}
-//////////////////////////////////////////////////////////////////////////////
-// TUnboxedValuePod
-//////////////////////////////////////////////////////////////////////////////
+{
+ if (this != &value) {
+ UnRef();
+ Raw = value.Raw;
+ value.Raw = TRaw();
+ }
+ return *this;
+}
+
+Y_FORCE_INLINE TUnboxedValuePod TUnboxedValue::Release() noexcept {
+ const TUnboxedValuePod value(std::move(*static_cast<TUnboxedValuePod*>(this)));
+ Raw = TRaw();
+ value.ReleaseRef();
+ return value;
+}
+
+Y_FORCE_INLINE void TUnboxedValue::Clear() noexcept
+{
+ UnRef();
+ Raw = TRaw();
+}
+
+Y_FORCE_INLINE TUnboxedValue::~TUnboxedValue() noexcept
+{
+ UnRef();
+}
+//////////////////////////////////////////////////////////////////////////////
+// TUnboxedValuePod
+//////////////////////////////////////////////////////////////////////////////
Y_FORCE_INLINE TUnboxedValuePod::TUnboxedValuePod(IBoxedValuePtr&& value)
-{
- Raw.Boxed.Meta = static_cast<ui8>(EMarkers::Boxed);
- Raw.Boxed.Value = value.Release();
- Raw.Boxed.Value->ReleaseRef();
-}
-
-Y_FORCE_INLINE TUnboxedValuePod::TUnboxedValuePod(TStringValue&& value, ui32 size, ui32 offset)
-{
- Y_VERIFY_DEBUG(size);
- Y_VERIFY_DEBUG(offset < std::min(OffsetLimit, value.Size()));
- Raw.String.Size = std::min(value.Size() - offset, size);
- Raw.String.Offset = offset;
- Raw.String.Value = value.ReleaseBuf();
- Raw.String.Meta = static_cast<ui8>(EMarkers::String);
-}
-
-inline TStringValue TUnboxedValuePod::AsStringValue() const
-{
- UDF_VERIFY(IsString(), "Value is not a string");
- return TStringValue(Raw.String.Value);
-}
-
+{
+ Raw.Boxed.Meta = static_cast<ui8>(EMarkers::Boxed);
+ Raw.Boxed.Value = value.Release();
+ Raw.Boxed.Value->ReleaseRef();
+}
+
+Y_FORCE_INLINE TUnboxedValuePod::TUnboxedValuePod(TStringValue&& value, ui32 size, ui32 offset)
+{
+ Y_VERIFY_DEBUG(size);
+ Y_VERIFY_DEBUG(offset < std::min(OffsetLimit, value.Size()));
+ Raw.String.Size = std::min(value.Size() - offset, size);
+ Raw.String.Offset = offset;
+ Raw.String.Value = value.ReleaseBuf();
+ Raw.String.Meta = static_cast<ui8>(EMarkers::String);
+}
+
+inline TStringValue TUnboxedValuePod::AsStringValue() const
+{
+ UDF_VERIFY(IsString(), "Value is not a string");
+ return TStringValue(Raw.String.Value);
+}
+
inline IBoxedValuePtr TUnboxedValuePod::AsBoxed() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not boxed");
+{
+ UDF_VERIFY(IsBoxed(), "Value is not boxed");
return IBoxedValuePtr(Raw.Boxed.Value);
-}
-
-inline bool TUnboxedValuePod::UniqueBoxed() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not boxed");
- return Raw.Boxed.Value->RefCount() <= 1;
-}
-
-inline bool TUnboxedValuePod::HasFastListLength() const {
- UDF_VERIFY(IsBoxed(), "Value is not a list");
- return TBoxedValueAccessor::HasFastListLength(*Raw.Boxed.Value);
-}
-
-inline ui64 TUnboxedValuePod::GetListLength() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a list");
- return TBoxedValueAccessor::GetListLength(*Raw.Boxed.Value);
-}
-
-inline ui64 TUnboxedValuePod::GetEstimatedListLength() const {
- UDF_VERIFY(IsBoxed(), "Value is not a list");
- return TBoxedValueAccessor::GetEstimatedListLength(*Raw.Boxed.Value);
-}
-
-inline bool TUnboxedValuePod::HasListItems() const {
- UDF_VERIFY(IsBoxed(), "Value is not a list");
- return TBoxedValueAccessor::HasListItems(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetListIterator() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a list");
- return TBoxedValueAccessor::GetListIterator(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::MakeOptional() const
-{
- if (Raw.Simple.Meta)
- return *this;
-
- TUnboxedValuePod result(*this);
- ++result.Raw.Simple.Count;
- return result;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValue() const
-{
- if (Raw.Simple.Meta)
- return *this;
-
- UDF_VERIFY(Raw.Simple.Count > 0U, "Can't get value from empty.");
-
- TUnboxedValuePod result(*this);
- --result.Raw.Simple.Count;
- return result;
-}
-
-template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<false>() const { return *this; }
-template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<true>() const { return GetOptionalValue(); }
-
-template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<false>() const { return *this; }
-template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<true>() const { return MakeOptional(); }
-
-inline ui64 TUnboxedValuePod::GetDictLength() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::GetDictLength(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetDictIterator() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::GetDictIterator(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetKeysIterator() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::GetKeysIterator(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetPayloadsIterator() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::GetPayloadsIterator(*Raw.Boxed.Value);
-}
-
-inline bool TUnboxedValuePod::Contains(const TUnboxedValuePod& key) const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::Contains(*Raw.Boxed.Value, key);
-}
-
-inline TUnboxedValue TUnboxedValuePod::Lookup(const TUnboxedValuePod& key) const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::Lookup(*Raw.Boxed.Value, key);
-}
-
-inline bool TUnboxedValuePod::HasDictItems() const {
- UDF_VERIFY(IsBoxed(), "Value is not a dict");
- return TBoxedValueAccessor::HasDictItems(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetElement(ui32 index) const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a tuple");
- return TBoxedValueAccessor::GetElement(*Raw.Boxed.Value, index);
-}
-
-inline const TUnboxedValue* TUnboxedValuePod::GetElements() const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a tuple");
- return TBoxedValueAccessor::GetElements(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::Run(
- const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const
-{
- UDF_VERIFY(IsBoxed(), "Value is not a callable");
- return TBoxedValueAccessor::Run(*Raw.Boxed.Value, valueBuilder, args);
-}
-
-inline TStringRef TUnboxedValuePod::GetResourceTag() const {
- UDF_VERIFY(IsBoxed(), "Value is not a resource");
- return TBoxedValueAccessor::GetResourceTag(*Raw.Boxed.Value);
-}
-
-inline void* TUnboxedValuePod::GetResource() const {
- UDF_VERIFY(IsBoxed(), "Value is not a resource");
- return TBoxedValueAccessor::GetResource(*Raw.Boxed.Value);
-}
-
-inline ui32 TUnboxedValuePod::GetVariantIndex() const {
- if (auto index = Raw.GetIndex())
- return --index;
- UDF_VERIFY(IsBoxed(), "Value is not a variant");
- return TBoxedValueAccessor::GetVariantIndex(*Raw.Boxed.Value);
-}
-
-inline TUnboxedValue TUnboxedValuePod::GetVariantItem() const {
- if (Raw.GetIndex()) {
- TUnboxedValuePod item(*this);
- item.Raw.Simple.Meta &= 0x3;
- return std::move(item);
- }
- UDF_VERIFY(IsBoxed(), "Value is not a variant");
- return TBoxedValueAccessor::GetVariantItem(*Raw.Boxed.Value);
-}
-
-inline bool TUnboxedValuePod::TryMakeVariant(ui32 index) {
- static const ui32 limit = (1U << 6U) - 1U;
- if (index >= limit || Raw.GetIndex())
- return false;
-
- Raw.Simple.Meta |= ui8(++index << 2);
- return true;
-}
-
+}
+
+inline bool TUnboxedValuePod::UniqueBoxed() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not boxed");
+ return Raw.Boxed.Value->RefCount() <= 1;
+}
+
+inline bool TUnboxedValuePod::HasFastListLength() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a list");
+ return TBoxedValueAccessor::HasFastListLength(*Raw.Boxed.Value);
+}
+
+inline ui64 TUnboxedValuePod::GetListLength() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a list");
+ return TBoxedValueAccessor::GetListLength(*Raw.Boxed.Value);
+}
+
+inline ui64 TUnboxedValuePod::GetEstimatedListLength() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a list");
+ return TBoxedValueAccessor::GetEstimatedListLength(*Raw.Boxed.Value);
+}
+
+inline bool TUnboxedValuePod::HasListItems() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a list");
+ return TBoxedValueAccessor::HasListItems(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetListIterator() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a list");
+ return TBoxedValueAccessor::GetListIterator(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::MakeOptional() const
+{
+ if (Raw.Simple.Meta)
+ return *this;
+
+ TUnboxedValuePod result(*this);
+ ++result.Raw.Simple.Count;
+ return result;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValue() const
+{
+ if (Raw.Simple.Meta)
+ return *this;
+
+ UDF_VERIFY(Raw.Simple.Count > 0U, "Can't get value from empty.");
+
+ TUnboxedValuePod result(*this);
+ --result.Raw.Simple.Count;
+ return result;
+}
+
+template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<false>() const { return *this; }
+template<> inline TUnboxedValuePod TUnboxedValuePod::GetOptionalValueIf<true>() const { return GetOptionalValue(); }
+
+template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<false>() const { return *this; }
+template<> inline TUnboxedValuePod TUnboxedValuePod::MakeOptionalIf<true>() const { return MakeOptional(); }
+
+inline ui64 TUnboxedValuePod::GetDictLength() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::GetDictLength(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetDictIterator() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::GetDictIterator(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetKeysIterator() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::GetKeysIterator(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetPayloadsIterator() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::GetPayloadsIterator(*Raw.Boxed.Value);
+}
+
+inline bool TUnboxedValuePod::Contains(const TUnboxedValuePod& key) const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::Contains(*Raw.Boxed.Value, key);
+}
+
+inline TUnboxedValue TUnboxedValuePod::Lookup(const TUnboxedValuePod& key) const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::Lookup(*Raw.Boxed.Value, key);
+}
+
+inline bool TUnboxedValuePod::HasDictItems() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a dict");
+ return TBoxedValueAccessor::HasDictItems(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetElement(ui32 index) const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a tuple");
+ return TBoxedValueAccessor::GetElement(*Raw.Boxed.Value, index);
+}
+
+inline const TUnboxedValue* TUnboxedValuePod::GetElements() const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a tuple");
+ return TBoxedValueAccessor::GetElements(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::Run(
+ const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const
+{
+ UDF_VERIFY(IsBoxed(), "Value is not a callable");
+ return TBoxedValueAccessor::Run(*Raw.Boxed.Value, valueBuilder, args);
+}
+
+inline TStringRef TUnboxedValuePod::GetResourceTag() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a resource");
+ return TBoxedValueAccessor::GetResourceTag(*Raw.Boxed.Value);
+}
+
+inline void* TUnboxedValuePod::GetResource() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a resource");
+ return TBoxedValueAccessor::GetResource(*Raw.Boxed.Value);
+}
+
+inline ui32 TUnboxedValuePod::GetVariantIndex() const {
+ if (auto index = Raw.GetIndex())
+ return --index;
+ UDF_VERIFY(IsBoxed(), "Value is not a variant");
+ return TBoxedValueAccessor::GetVariantIndex(*Raw.Boxed.Value);
+}
+
+inline TUnboxedValue TUnboxedValuePod::GetVariantItem() const {
+ if (Raw.GetIndex()) {
+ TUnboxedValuePod item(*this);
+ item.Raw.Simple.Meta &= 0x3;
+ return std::move(item);
+ }
+ UDF_VERIFY(IsBoxed(), "Value is not a variant");
+ return TBoxedValueAccessor::GetVariantItem(*Raw.Boxed.Value);
+}
+
+inline bool TUnboxedValuePod::TryMakeVariant(ui32 index) {
+ static const ui32 limit = (1U << 6U) - 1U;
+ if (index >= limit || Raw.GetIndex())
+ return false;
+
+ Raw.Simple.Meta |= ui8(++index << 2);
+ return true;
+}
+
inline void TUnboxedValuePod::SetTimezoneId(ui16 id) {
UDF_VERIFY(IsEmbedded(), "Value is not a datetime");
Raw.Simple.TimezoneId = id;
@@ -599,31 +599,31 @@ inline ui16 TUnboxedValuePod::GetTimezoneId() const {
return Raw.Simple.TimezoneId;
}
-inline EFetchStatus TUnboxedValuePod::Fetch(TUnboxedValue& result) const {
- UDF_VERIFY(IsBoxed(), "Value is not a stream");
- return TBoxedValueAccessor::Fetch(*Raw.Boxed.Value, result);
-}
-
-inline bool TUnboxedValuePod::Skip() const {
- UDF_VERIFY(IsBoxed(), "Value is not a iterator");
- return TBoxedValueAccessor::Skip(*Raw.Boxed.Value);
-}
-
-inline bool TUnboxedValuePod::Next(TUnboxedValue& value) const {
- UDF_VERIFY(IsBoxed(), "Value is not a iterator");
- return TBoxedValueAccessor::Next(*Raw.Boxed.Value, value);
-}
-
-inline bool TUnboxedValuePod::NextPair(TUnboxedValue& key, TUnboxedValue& payload) const {
- UDF_VERIFY(IsBoxed(), "Value is not a iterator");
- return TBoxedValueAccessor::NextPair(*Raw.Boxed.Value, key, payload);
-}
-
-inline void TUnboxedValuePod::Apply(IApplyContext& context) const {
- UDF_VERIFY(IsBoxed(), "Value is not boxed");
- return TBoxedValueAccessor::Apply(*Raw.Boxed.Value, context);
-}
-
+inline EFetchStatus TUnboxedValuePod::Fetch(TUnboxedValue& result) const {
+ UDF_VERIFY(IsBoxed(), "Value is not a stream");
+ return TBoxedValueAccessor::Fetch(*Raw.Boxed.Value, result);
+}
+
+inline bool TUnboxedValuePod::Skip() const {
+ UDF_VERIFY(IsBoxed(), "Value is not a iterator");
+ return TBoxedValueAccessor::Skip(*Raw.Boxed.Value);
+}
+
+inline bool TUnboxedValuePod::Next(TUnboxedValue& value) const {
+ UDF_VERIFY(IsBoxed(), "Value is not a iterator");
+ return TBoxedValueAccessor::Next(*Raw.Boxed.Value, value);
+}
+
+inline bool TUnboxedValuePod::NextPair(TUnboxedValue& key, TUnboxedValue& payload) const {
+ UDF_VERIFY(IsBoxed(), "Value is not a iterator");
+ return TBoxedValueAccessor::NextPair(*Raw.Boxed.Value, key, payload);
+}
+
+inline void TUnboxedValuePod::Apply(IApplyContext& context) const {
+ UDF_VERIFY(IsBoxed(), "Value is not boxed");
+ return TBoxedValueAccessor::Apply(*Raw.Boxed.Value, context);
+}
+
#if UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 3)
inline ui32 TUnboxedValuePod::GetTraverseCount() const {
UDF_VERIFY(IsBoxed(), "Value is not boxed");
@@ -685,42 +685,42 @@ inline bool TUnboxedValuePod::VisitBlocks(TBlockCallback callback, void* context
}
#endif
-Y_FORCE_INLINE void TUnboxedValuePod::Ref() const noexcept
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::String: return Raw.String.Value->Ref();
- case EMarkers::Boxed: return Raw.Boxed.Value->Ref();
- default: return;
- }
-}
-
-Y_FORCE_INLINE void TUnboxedValuePod::UnRef() const noexcept
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::String: return Raw.String.Value->UnRef();
- case EMarkers::Boxed: return Raw.Boxed.Value->UnRef();
- default: return;
- }
-}
-
-Y_FORCE_INLINE void TUnboxedValuePod::ReleaseRef() const noexcept
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::String: return Raw.String.Value->ReleaseRef();
- case EMarkers::Boxed: return Raw.Boxed.Value->ReleaseRef();
- default: return;
- }
-}
-
-Y_FORCE_INLINE void TUnboxedValuePod::DeleteUnreferenced() const noexcept
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::String: return Raw.String.Value->DeleteUnreferenced();
- case EMarkers::Boxed: return Raw.Boxed.Value->DeleteUnreferenced();
- default: return;
- }
-}
-
+Y_FORCE_INLINE void TUnboxedValuePod::Ref() const noexcept
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::String: return Raw.String.Value->Ref();
+ case EMarkers::Boxed: return Raw.Boxed.Value->Ref();
+ default: return;
+ }
+}
+
+Y_FORCE_INLINE void TUnboxedValuePod::UnRef() const noexcept
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::String: return Raw.String.Value->UnRef();
+ case EMarkers::Boxed: return Raw.Boxed.Value->UnRef();
+ default: return;
+ }
+}
+
+Y_FORCE_INLINE void TUnboxedValuePod::ReleaseRef() const noexcept
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::String: return Raw.String.Value->ReleaseRef();
+ case EMarkers::Boxed: return Raw.Boxed.Value->ReleaseRef();
+ default: return;
+ }
+}
+
+Y_FORCE_INLINE void TUnboxedValuePod::DeleteUnreferenced() const noexcept
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::String: return Raw.String.Value->DeleteUnreferenced();
+ case EMarkers::Boxed: return Raw.Boxed.Value->DeleteUnreferenced();
+ default: return;
+ }
+}
+
Y_FORCE_INLINE i32 TUnboxedValuePod::LockRef() const noexcept
{
switch (Raw.GetMarkers()) {
@@ -739,182 +739,182 @@ Y_FORCE_INLINE void TUnboxedValuePod::UnlockRef(i32 prev) const noexcept
}
}
-#define VALUE_GET(xType) \
- template <> \
- inline xType TUnboxedValuePod::Get<xType>() const \
- { \
- UDF_VERIFY(EMarkers::Embedded == Raw.GetMarkers(), "Value is empty."); \
- return Raw.Simple.xType##_; \
- }
-
-#define VALUE_GET_DEF(xType) \
- template <> \
- inline xType TUnboxedValuePod::GetOrDefault<xType>(xType def) const \
- { \
- return EMarkers::Empty == Raw.GetMarkers() ? def : Raw.Simple.xType##_; \
- }
-
-#define VALUE_CONSTR(xType) \
- template <> \
- inline TUnboxedValuePod::TUnboxedValuePod(xType value) \
- { \
- Raw.Simple.xType##_ = value; \
- Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded); \
- }
-
-PRIMITIVE_VALUE_TYPES(VALUE_GET)
-PRIMITIVE_VALUE_TYPES(VALUE_GET_DEF)
-PRIMITIVE_VALUE_TYPES(VALUE_CONSTR)
-
-template <>
-inline bool TUnboxedValuePod::Get<bool>() const
-{
- UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
- return bool(Raw.Simple.ui8_);
-}
-
-template <>
-inline bool TUnboxedValuePod::GetOrDefault<bool>(bool def) const
-{
- return EMarkers::Empty == Raw.GetMarkers() ? def : bool(Raw.Simple.ui8_);
-}
-
-template <>
-inline TUnboxedValuePod::TUnboxedValuePod(bool value)
-{
- Raw.Simple.ui8_ = value ? 1 : 0;
- Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
-}
-
-inline NYql::NDecimal::TInt128 TUnboxedValuePod::GetInt128() const
-{
- UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
- auto v = *reinterpret_cast<const NYql::NDecimal::TInt128*>(&Raw);
- const auto p = reinterpret_cast<ui8*>(&v);
- p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
- return v;
-}
-
-inline NYql::NDecimal::TUint128 TUnboxedValuePod::GetUint128() const
-{
- UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
- auto v = *reinterpret_cast<const NYql::NDecimal::TUint128*>(&Raw);
- const auto p = reinterpret_cast<ui8*>(&v);
- p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
- return v;
-}
-
-inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TInt128 value)
-{
- *reinterpret_cast<NYql::NDecimal::TInt128*>(&Raw) = value;
- Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
-}
-
-inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TUint128 value)
-{
- *reinterpret_cast<NYql::NDecimal::TUint128*>(&Raw) = value;
- Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
-}
-
-inline const void* TUnboxedValuePod::GetRawPtr() const
-{
- return &Raw;
-}
-
-inline void* TUnboxedValuePod::GetRawPtr()
-{
- return &Raw;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::Void()
-{
- TUnboxedValuePod v;
- v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
- return v;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::Zero()
-{
- TUnboxedValuePod v;
- v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
- return v;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::Embedded(ui8 size) {
- UDF_VERIFY(size <= InternalBufferSize);
-
- TUnboxedValuePod v;
- v.Raw.Embedded.Size = size;
- v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
- return v;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::Embedded(const TStringRef& value) {
- UDF_VERIFY(value.Size() <= InternalBufferSize);
-
- TUnboxedValuePod v;
- v.Raw.Embedded.Size = value.Size();
- v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
+#define VALUE_GET(xType) \
+ template <> \
+ inline xType TUnboxedValuePod::Get<xType>() const \
+ { \
+ UDF_VERIFY(EMarkers::Embedded == Raw.GetMarkers(), "Value is empty."); \
+ return Raw.Simple.xType##_; \
+ }
+
+#define VALUE_GET_DEF(xType) \
+ template <> \
+ inline xType TUnboxedValuePod::GetOrDefault<xType>(xType def) const \
+ { \
+ return EMarkers::Empty == Raw.GetMarkers() ? def : Raw.Simple.xType##_; \
+ }
+
+#define VALUE_CONSTR(xType) \
+ template <> \
+ inline TUnboxedValuePod::TUnboxedValuePod(xType value) \
+ { \
+ Raw.Simple.xType##_ = value; \
+ Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded); \
+ }
+
+PRIMITIVE_VALUE_TYPES(VALUE_GET)
+PRIMITIVE_VALUE_TYPES(VALUE_GET_DEF)
+PRIMITIVE_VALUE_TYPES(VALUE_CONSTR)
+
+template <>
+inline bool TUnboxedValuePod::Get<bool>() const
+{
+ UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
+ return bool(Raw.Simple.ui8_);
+}
+
+template <>
+inline bool TUnboxedValuePod::GetOrDefault<bool>(bool def) const
+{
+ return EMarkers::Empty == Raw.GetMarkers() ? def : bool(Raw.Simple.ui8_);
+}
+
+template <>
+inline TUnboxedValuePod::TUnboxedValuePod(bool value)
+{
+ Raw.Simple.ui8_ = value ? 1 : 0;
+ Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+}
+
+inline NYql::NDecimal::TInt128 TUnboxedValuePod::GetInt128() const
+{
+ UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
+ auto v = *reinterpret_cast<const NYql::NDecimal::TInt128*>(&Raw);
+ const auto p = reinterpret_cast<ui8*>(&v);
+ p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
+ return v;
+}
+
+inline NYql::NDecimal::TUint128 TUnboxedValuePod::GetUint128() const
+{
+ UDF_VERIFY(EMarkers::Empty != Raw.GetMarkers(), "Value is empty.");
+ auto v = *reinterpret_cast<const NYql::NDecimal::TUint128*>(&Raw);
+ const auto p = reinterpret_cast<ui8*>(&v);
+ p[0xF] = (p[0xE] & 0x80) ? 0xFF : 0x00;
+ return v;
+}
+
+inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TInt128 value)
+{
+ *reinterpret_cast<NYql::NDecimal::TInt128*>(&Raw) = value;
+ Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+}
+
+inline TUnboxedValuePod::TUnboxedValuePod(NYql::NDecimal::TUint128 value)
+{
+ *reinterpret_cast<NYql::NDecimal::TUint128*>(&Raw) = value;
+ Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+}
+
+inline const void* TUnboxedValuePod::GetRawPtr() const
+{
+ return &Raw;
+}
+
+inline void* TUnboxedValuePod::GetRawPtr()
+{
+ return &Raw;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::Void()
+{
+ TUnboxedValuePod v;
+ v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+ return v;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::Zero()
+{
+ TUnboxedValuePod v;
+ v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+ return v;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::Embedded(ui8 size) {
+ UDF_VERIFY(size <= InternalBufferSize);
+
+ TUnboxedValuePod v;
+ v.Raw.Embedded.Size = size;
+ v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
+ return v;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::Embedded(const TStringRef& value) {
+ UDF_VERIFY(value.Size() <= InternalBufferSize);
+
+ TUnboxedValuePod v;
+ v.Raw.Embedded.Size = value.Size();
+ v.Raw.Embedded.Meta = static_cast<ui8>(EMarkers::Embedded);
if (v.Raw.Embedded.Size) {
std::memcpy(v.Raw.Embedded.Buffer, value.Data(), v.Raw.Embedded.Size);
}
- return v;
-}
-
+ return v;
+}
+
inline TUnboxedValuePod TUnboxedValuePod::Invalid()
{
TUnboxedValuePod v;
- v.Raw.Simple.Count = std::numeric_limits<ui64>::max();
+ v.Raw.Simple.Count = std::numeric_limits<ui64>::max();
return v;
}
-inline TUnboxedValuePod TUnboxedValuePod::MakeFinish()
-{
- TUnboxedValuePod v;
- v.Raw.Simple.Count = std::numeric_limits<ui64>::max() - 1U;
- return v;
-}
-
-inline TUnboxedValuePod TUnboxedValuePod::MakeYield()
-{
- return Invalid();
-}
-
+inline TUnboxedValuePod TUnboxedValuePod::MakeFinish()
+{
+ TUnboxedValuePod v;
+ v.Raw.Simple.Count = std::numeric_limits<ui64>::max() - 1U;
+ return v;
+}
+
+inline TUnboxedValuePod TUnboxedValuePod::MakeYield()
+{
+ return Invalid();
+}
+
inline bool TUnboxedValuePod::IsInvalid() const
{
- return Raw.Simple.Count == std::numeric_limits<ui64>::max() && Raw.Simple.FullMeta == 0;
-}
-
-inline bool TUnboxedValuePod::IsFinish() const
-{
- return Raw.Simple.Count == std::numeric_limits<ui64>::max() - 1U && Raw.Simple.FullMeta == 0;
-}
-
-inline bool TUnboxedValuePod::IsYield() const
-{
- return IsInvalid();
-}
-
-inline bool TUnboxedValuePod::IsSpecial() const
-{
- return Raw.Simple.FullMeta == 0 && Raw.Simple.Count >= std::numeric_limits<ui64>::max() - 1U;
-}
-
-inline TStringRef TUnboxedValuePod::AsStringRef() const&
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
- case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
+ return Raw.Simple.Count == std::numeric_limits<ui64>::max() && Raw.Simple.FullMeta == 0;
+}
+
+inline bool TUnboxedValuePod::IsFinish() const
+{
+ return Raw.Simple.Count == std::numeric_limits<ui64>::max() - 1U && Raw.Simple.FullMeta == 0;
+}
+
+inline bool TUnboxedValuePod::IsYield() const
+{
+ return IsInvalid();
+}
+
+inline bool TUnboxedValuePod::IsSpecial() const
+{
+ return Raw.Simple.FullMeta == 0 && Raw.Simple.Count >= std::numeric_limits<ui64>::max() - 1U;
+}
+
+inline TStringRef TUnboxedValuePod::AsStringRef() const&
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
+ case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
default: Y_FAIL("Value is not a string.");
- }
-}
-
-inline TMutableStringRef TUnboxedValuePod::AsStringRef() &
-{
- switch (Raw.GetMarkers()) {
- case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
- case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
+ }
+}
+
+inline TMutableStringRef TUnboxedValuePod::AsStringRef() &
+{
+ switch (Raw.GetMarkers()) {
+ case EMarkers::Embedded: return { Raw.Embedded.Buffer, Raw.Embedded.Size };
+ case EMarkers::String: return { Raw.String.Value->Data() + (Raw.String.Offset & 0xFFFFFF), Raw.String.Size };
default: Y_FAIL("Value is not a string.");
- }
-}
+ }
+}
diff --git a/ydb/library/yql/public/udf/udf_value_ut.cpp b/ydb/library/yql/public/udf/udf_value_ut.cpp
index 783d966b10..8d9708c7b1 100644
--- a/ydb/library/yql/public/udf/udf_value_ut.cpp
+++ b/ydb/library/yql/public/udf/udf_value_ut.cpp
@@ -4,81 +4,81 @@
#include <ydb/library/yql/minikql/mkql_alloc.h>
#include <library/cpp/testing/unittest/registar.h>
-using namespace NYql::NUdf;
+using namespace NYql::NUdf;
Y_UNIT_TEST_SUITE(TUdfValue) {
Y_UNIT_TEST(TestOptional) {
- TUnboxedValuePod foo((ui32) 42);
- UNIT_ASSERT(foo);
+ TUnboxedValuePod foo((ui32) 42);
+ UNIT_ASSERT(foo);
UNIT_ASSERT(42 == foo.Get<ui32>());
- auto optFoo = foo.MakeOptional();
- UNIT_ASSERT(optFoo);
- UNIT_ASSERT(optFoo.HasValue());
+ auto optFoo = foo.MakeOptional();
+ UNIT_ASSERT(optFoo);
+ UNIT_ASSERT(optFoo.HasValue());
- auto bar = optFoo.GetOptionalValue();
+ auto bar = optFoo.GetOptionalValue();
UNIT_ASSERT(42 == bar.Get<ui32>());
}
Y_UNIT_TEST(TestOptional2) {
- auto valueOpt = TUnboxedValuePod((ui32) 42);
- UNIT_ASSERT(valueOpt);
- UNIT_ASSERT(valueOpt.HasValue());
+ auto valueOpt = TUnboxedValuePod((ui32) 42);
+ UNIT_ASSERT(valueOpt);
+ UNIT_ASSERT(valueOpt.HasValue());
- auto value = valueOpt.GetOptionalValue();
+ auto value = valueOpt.GetOptionalValue();
UNIT_ASSERT(42 == value.Get<ui32>());
}
Y_UNIT_TEST(TestEmptyOptional) {
- auto optEmpty = TUnboxedValuePod();
- UNIT_ASSERT(!optEmpty);
- UNIT_ASSERT(!optEmpty.HasValue());
-
- auto optOptEmpty = optEmpty.MakeOptional();
- UNIT_ASSERT(optOptEmpty);
- UNIT_ASSERT(!optOptEmpty.HasValue());
-
- auto optOptOptEmpty = optOptEmpty.MakeOptional();
- UNIT_ASSERT(optOptOptEmpty);
- UNIT_ASSERT(!optOptOptEmpty.HasValue());
-
- auto v = optOptEmpty.GetOptionalValue();
- UNIT_ASSERT(!v);
+ auto optEmpty = TUnboxedValuePod();
+ UNIT_ASSERT(!optEmpty);
+ UNIT_ASSERT(!optEmpty.HasValue());
+
+ auto optOptEmpty = optEmpty.MakeOptional();
+ UNIT_ASSERT(optOptEmpty);
+ UNIT_ASSERT(!optOptEmpty.HasValue());
+
+ auto optOptOptEmpty = optOptEmpty.MakeOptional();
+ UNIT_ASSERT(optOptOptEmpty);
+ UNIT_ASSERT(!optOptOptEmpty.HasValue());
+
+ auto v = optOptEmpty.GetOptionalValue();
+ UNIT_ASSERT(!v);
}
Y_UNIT_TEST(TestVariant) {
- TUnboxedValuePod foo((ui64) 42);
- UNIT_ASSERT(foo);
-
- UNIT_ASSERT(!foo.TryMakeVariant(63));
-
- UNIT_ASSERT(foo.TryMakeVariant(62));
-
- UNIT_ASSERT(!foo.TryMakeVariant(0));
-
- UNIT_ASSERT(62 == foo.GetVariantIndex());
- UNIT_ASSERT(42 == foo.Get<ui64>());
- }
-
+ TUnboxedValuePod foo((ui64) 42);
+ UNIT_ASSERT(foo);
+
+ UNIT_ASSERT(!foo.TryMakeVariant(63));
+
+ UNIT_ASSERT(foo.TryMakeVariant(62));
+
+ UNIT_ASSERT(!foo.TryMakeVariant(0));
+
+ UNIT_ASSERT(62 == foo.GetVariantIndex());
+ UNIT_ASSERT(42 == foo.Get<ui64>());
+ }
+
Y_UNIT_TEST(TestEmptyInVariant) {
- TUnboxedValuePod foo;
- UNIT_ASSERT(!foo);
- UNIT_ASSERT(!foo.HasValue());
-
- UNIT_ASSERT(foo.TryMakeVariant(0));
- UNIT_ASSERT(foo);
- UNIT_ASSERT(!foo.HasValue());
-
- UNIT_ASSERT(0 == foo.GetVariantIndex());
-
- const auto opt = foo.MakeOptional();
- UNIT_ASSERT(!std::memcmp(&opt, &foo, sizeof(opt)));
-
- const auto bar = opt.GetOptionalValue();
- UNIT_ASSERT(!std::memcmp(&opt, &bar, sizeof(bar)));
- }
-
+ TUnboxedValuePod foo;
+ UNIT_ASSERT(!foo);
+ UNIT_ASSERT(!foo.HasValue());
+
+ UNIT_ASSERT(foo.TryMakeVariant(0));
+ UNIT_ASSERT(foo);
+ UNIT_ASSERT(!foo.HasValue());
+
+ UNIT_ASSERT(0 == foo.GetVariantIndex());
+
+ const auto opt = foo.MakeOptional();
+ UNIT_ASSERT(!std::memcmp(&opt, &foo, sizeof(opt)));
+
+ const auto bar = opt.GetOptionalValue();
+ UNIT_ASSERT(!std::memcmp(&opt, &bar, sizeof(bar)));
+ }
+
Y_UNIT_TEST(TestInvalid) {
TUnboxedValuePod foo;
UNIT_ASSERT(!foo.IsInvalid());
diff --git a/ydb/library/yql/public/udf/udf_version.cpp b/ydb/library/yql/public/udf/udf_version.cpp
index da97abc129..f900f99b4b 100644
--- a/ydb/library/yql/public/udf/udf_version.cpp
+++ b/ydb/library/yql/public/udf/udf_version.cpp
@@ -3,7 +3,7 @@
#include <util/string/builder.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
TString AbiVersionToStr(ui32 version)
@@ -17,4 +17,4 @@ TString AbiVersionToStr(ui32 version)
}
} // namespace NUdf
-} // namespace NYql
+} // namespace NYql
diff --git a/ydb/library/yql/public/udf/udf_version.h b/ydb/library/yql/public/udf/udf_version.h
index a48e7fa56e..e31e518d44 100644
--- a/ydb/library/yql/public/udf/udf_version.h
+++ b/ydb/library/yql/public/udf/udf_version.h
@@ -3,7 +3,7 @@
#include <util/generic/fwd.h>
#include <util/system/types.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
#define CURRENT_UDF_ABI_VERSION_MAJOR 2
@@ -71,6 +71,6 @@ constexpr bool IsAbiCompatible(ui32 version)
TString AbiVersionToStr(ui32 version);
} // namspace NUdf
-} // namspace NYql
-
-namespace NKikimr { namespace NUdf = ::NYql::NUdf; }
+} // namspace NYql
+
+namespace NKikimr { namespace NUdf = ::NYql::NUdf; }
diff --git a/ydb/library/yql/public/udf/ut/ya.make b/ydb/library/yql/public/udf/ut/ya.make
index 5c90b538ec..e51fd16480 100644
--- a/ydb/library/yql/public/udf/ut/ya.make
+++ b/ydb/library/yql/public/udf/ut/ya.make
@@ -5,7 +5,7 @@ OWNER(g:yql)
SRCS(
udf_counter_ut.cpp
udf_value_ut.cpp
- udf_value_builder_ut.cpp
+ udf_value_builder_ut.cpp
)
YQL_LAST_ABI_VERSION()
diff --git a/ydb/library/yql/public/udf/ya.make b/ydb/library/yql/public/udf/ya.make
index 7810d00074..57a34d00b4 100644
--- a/ydb/library/yql/public/udf/ya.make
+++ b/ydb/library/yql/public/udf/ya.make
@@ -7,7 +7,7 @@ OWNER(
SRCS(
udf_allocator.cpp
- udf_allocator.h
+ udf_allocator.h
udf_counter.cpp
udf_counter.h
udf_data_type.cpp
@@ -25,8 +25,8 @@ SRCS(
udf_type_inspection.cpp
udf_type_inspection.h
udf_type_ops.h
- udf_type_printer.cpp
- udf_type_printer.h
+ udf_type_printer.cpp
+ udf_type_printer.h
udf_types.cpp
udf_types.h
udf_ut_helpers.h
diff --git a/ydb/library/yql/sql/settings/translation_settings.cpp b/ydb/library/yql/sql/settings/translation_settings.cpp
index 26dc193552..e09fd43aaa 100644
--- a/ydb/library/yql/sql/settings/translation_settings.cpp
+++ b/ydb/library/yql/sql/settings/translation_settings.cpp
@@ -38,7 +38,7 @@ namespace NSQLTranslation {
, AnsiLexer(false)
, PgParser(false)
, InferSyntaxVersion(false)
- , V0Behavior(EV0Behavior::Silent)
+ , V0Behavior(EV0Behavior::Silent)
, V0ForceDisable(InTestEnvironment())
, WarnOnV0(true)
, V0WarnAsError(ISqlFeaturePolicy::MakeAlwaysDisallow())
diff --git a/ydb/library/yql/sql/settings/translation_settings.h b/ydb/library/yql/sql/settings/translation_settings.h
index 533de65782..0b9194a249 100644
--- a/ydb/library/yql/sql/settings/translation_settings.h
+++ b/ydb/library/yql/sql/settings/translation_settings.h
@@ -28,12 +28,12 @@ namespace NSQLTranslation {
using TIncrementMonCounterFunction = std::function<void(const TString&, const TString&)>;
- enum class EV0Behavior {
- Silent = 0,
- Report,
- Disable
- };
-
+ enum class EV0Behavior {
+ Silent = 0,
+ Report,
+ Disable
+ };
+
class ISqlFeaturePolicy : public TThrRefBase {
public:
virtual ~ISqlFeaturePolicy() = default;
@@ -76,7 +76,7 @@ namespace NSQLTranslation {
bool AnsiLexer;
bool PgParser;
bool InferSyntaxVersion;
- EV0Behavior V0Behavior;
+ EV0Behavior V0Behavior;
bool V0ForceDisable;
bool WarnOnV0;
ISqlFeaturePolicy::TPtr V0WarnAsError;
diff --git a/ydb/library/yql/sql/v0/SQL.g b/ydb/library/yql/sql/v0/SQL.g
index decbbee03b..3b616b9c9f 100644
--- a/ydb/library/yql/sql/v0/SQL.g
+++ b/ydb/library/yql/sql/v0/SQL.g
@@ -84,7 +84,7 @@ atom_expr:
| exists_expr
| case_expr
| id_or_string NAMESPACE id_or_string
- | bitcast_expr
+ | bitcast_expr
;
in_atom_expr:
@@ -95,13 +95,13 @@ in_atom_expr:
| cast_expr
| case_expr
| LPAREN select_stmt RPAREN
- | bitcast_expr
+ | bitcast_expr
;
cast_expr: CAST LPAREN expr AS type_name RPAREN;
-bitcast_expr: BITCAST LPAREN expr AS type_name RPAREN;
-
+bitcast_expr: BITCAST LPAREN expr AS type_name RPAREN;
+
exists_expr: EXISTS LPAREN select_stmt RPAREN;
case_expr: CASE expr? when_expr+ (ELSE expr)? END;
@@ -161,9 +161,9 @@ named_bind_parameter_list: named_bind_parameter (COMMA named_bind_parameter)*;
unsigned_number: integer | real;
signed_number: (PLUS | MINUS)? (integer | real);
-type_name: id (LPAREN integer (COMMA integer)? RPAREN)?;
+type_name: id (LPAREN integer (COMMA integer)? RPAREN)?;
-flex_type: STRING | type_name;
+flex_type: STRING | type_name;
declare_stmt: DECLARE bind_parameter AS flex_type (EQUALS literal_value)?;
@@ -305,7 +305,7 @@ alter_table_action: alter_table_add_column | alter_table_drop_column;
alter_table_add_column: ADD COLUMN? column_schema (COMMA ADD COLUMN? column_schema)*;
alter_table_drop_column: DROP COLUMN? id;
-column_schema: id_schema flex_type (NOT? NULL)?;
+column_schema: id_schema flex_type (NOT? NULL)?;
column_order_by_specification: id (ASC | DESC)?;
table_constraint:
@@ -424,8 +424,8 @@ keyword: keyword_restricted | keyword_alter_uncompat | keyword_table_uncompat;
keyword_restricted: keyword_compat | keyword_expr_uncompat | keyword_select_uncompat | keyword_in_uncompat;
keyword_expr_uncompat:
- BITCAST
- | CASE
+ BITCAST
+ | CASE
| CAST
| CUBE
| CURRENT_TIME
@@ -713,7 +713,7 @@ BEFORE: B E F O R E;
BEGIN: B E G I N;
BERNOULLI: B E R N O U L L I;
BETWEEN: B E T W E E N;
-BITCAST: B I T C A S T;
+BITCAST: B I T C A S T;
BY: B Y;
CASCADE: C A S C A D E;
CASE: C A S E;
diff --git a/ydb/library/yql/sql/v0/aggregation.cpp b/ydb/library/yql/sql/v0/aggregation.cpp
index bb5351a92c..6440604881 100644
--- a/ydb/library/yql/sql/v0/aggregation.cpp
+++ b/ydb/library/yql/sql/v0/aggregation.cpp
@@ -7,8 +7,8 @@
#include <util/string/builder.h>
#include <util/string/cast.h>
-#include <array>
-
+#include <array>
+
using namespace NYql;
namespace NSQLTranslationV0 {
@@ -49,7 +49,7 @@ protected:
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -57,7 +57,7 @@ protected:
return true;
}
-
+
TNodePtr AggregationTraitsFactory() const override {
return Factory;
}
@@ -82,7 +82,7 @@ protected:
ctx.PushBlockShortcuts();
if (!Expr->Init(ctx, src)) {
return false;
- }
+ }
if (Expr->IsAggregated() && !Expr->IsAggregationKey() && !IsOverWindow()) {
ctx.Error(Pos) << "Aggregation of aggregated values is forbidden for no window functions";
return false;
@@ -91,8 +91,8 @@ protected:
const auto column = Expr->GetColumnName();
if (!column) {
ctx.Error(Expr->GetPos()) << "DISTINCT qualifier may only be used with column references";
- return false;
- }
+ return false;
+ }
DistinctKey = *column;
YQL_ENSURE(src);
if (src->GetJoin()) {
@@ -114,7 +114,7 @@ protected:
ctx.PopBlockShortcuts();
} else {
Expr = ctx.GroundBlockShortcutsForExpr(Expr);
- }
+ }
if (FakeSource) {
ctx.PushBlockShortcuts();
@@ -140,14 +140,14 @@ protected:
return true;
}
-
+
TNodePtr Factory;
TSourcePtr FakeSource;
TNodePtr Expr;
bool DynamicFactory;
bool Multi;
};
-
+
class TAggregationFactoryImpl final : public TAggregationFactory {
public:
TAggregationFactoryImpl(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode, bool multi)
@@ -205,7 +205,7 @@ private:
TAggregationPtr BuildFactoryAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode, bool multi) {
return new TAggregationFactoryImpl(pos, name, func, aggMode, multi);
}
-
+
TAggregationPtr BuildFactoryAggregationWinAutoarg(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode) {
return new TAggregationFactoryWinAutoargImpl(pos, name, func, aggMode);
}
@@ -215,7 +215,7 @@ public:
TKeyPayloadAggregationFactory(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode)
: TAggregationFactory(pos, name, factory, aggMode)
{}
-
+
private:
bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) final {
ui32 adjustArgsCount = isFactory ? 0 : 2;
@@ -223,13 +223,13 @@ private:
ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name << " requires "
<< adjustArgsCount << " or " << (1 + adjustArgsCount) << " arguments, given: " << exprs.size();
return false;
- }
-
+ }
+
if (!isFactory) {
Payload = exprs.front();
Key = exprs[1];
}
-
+
Limit = (1 + adjustArgsCount == exprs.size() ? exprs.back() : Y("Void"));
if (!isFactory) {
Name = src->MakeLocalName(Name);
@@ -237,7 +237,7 @@ private:
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -245,11 +245,11 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TKeyPayloadAggregationFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Key), BuildLambda(Pos, Y("row"), Payload));
AddFactoryArguments(apply);
@@ -288,8 +288,8 @@ private:
return false;
}
return true;
- }
-
+ }
+
TNodePtr Key, Payload, Limit;
};
@@ -310,18 +310,18 @@ private:
ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name << " requires " <<
adjustArgsCount << "arguments, given: " << exprs.size();
return false;
- }
+ }
if (!isFactory) {
Payload = exprs.front();
Predicate = exprs.back();
-
+
Name = src->MakeLocalName(Name);
}
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -329,15 +329,15 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TPayloadPredicateAggregationFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
return Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Payload), BuildLambda(Pos, Y("row"), Predicate));
}
-
+
std::vector<ui32> GetFactoryColumnIndices() const final {
return {0u, 1u};
}
@@ -437,7 +437,7 @@ private:
}
return true;
}
-
+
TNodePtr One, Two;
};
@@ -466,7 +466,7 @@ private:
ctx.Error(Pos) << "Aggregation function " << Name << " requires one, two or three arguments, given: " << exprs.size();
return false;
}
- }
+ }
if (!isFactory) {
/// \todo: solve it with named arguments
@@ -498,21 +498,21 @@ private:
Intervals = Y("Cast", exprs.back(), Q("Uint32"));
}
- }
-
+ }
+
return TAggregationFactory::InitAggr(ctx, isFactory, src, node, isFactory ? TVector<TNodePtr>() : TVector<TNodePtr>(1, exprs.front()));
}
TNodePtr DoClone() const final {
return new THistogramAggregationFactory(Pos, Name, Func, AggMode);
- }
-
+ }
+
TNodePtr GetApply(const TNodePtr& type) const final {
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), BuildLambda(Pos, Y("row"), Weight));
AddFactoryArguments(apply);
return apply;
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, Intervals);
}
@@ -532,7 +532,7 @@ private:
return false;
}
Intervals = ctx.GroundBlockShortcutsForExpr(Intervals);
-
+
return TAggregationFactory::DoInit(ctx, src);
}
@@ -621,7 +621,7 @@ public:
: TAggregationFactory(pos, name, factory, aggMode)
, FakeSource(BuildFakeSource(pos))
{}
-
+
private:
const TString* GetGenericKey() const final {
return Column;
@@ -666,7 +666,7 @@ private:
} else {
x = Y("Double", Q("0.5"));
}
-
+
if (isFactory) {
FactoryPercentile = x;
} else {
@@ -675,7 +675,7 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TPercentileFactory(Pos, Name, Func, AggMode);
}
@@ -689,11 +689,11 @@ private:
percentiles = L(percentiles, percentile.second);
}
percentiles = Q(percentiles);
- }
-
+ }
+
return Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), percentiles);
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, FactoryPercentile);
}
@@ -701,7 +701,7 @@ private:
TNodePtr AggregationTraits(const TNodePtr& type) const final {
if (Percentiles.empty())
return TNodePtr();
-
+
TNodePtr names(Q(Percentiles.cbegin()->first));
if (Percentiles.size() > 1U) {
@@ -720,18 +720,18 @@ private:
for (const auto& p : Percentiles) {
if (!p.second->Init(ctx, src)) {
return false;
- }
- }
-
+ }
+ }
+
return TAggregationFactory::DoInit(ctx, src);
- }
-
+ }
+
TSourcePtr FakeSource;
std::multimap<TString, TNodePtr> Percentiles;
TNodePtr FactoryPercentile;
const TString* Column = nullptr;
};
-
+
TAggregationPtr BuildPercentileFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TPercentileFactory(pos, name, factory, aggMode);
}
@@ -751,7 +751,7 @@ private:
ui32 adjustArgsCount = isFactory ? 0 : 1;
const double DefaultBufferC = 1.5;
const ui32 MinBuffer = 100;
-
+
if (exprs.size() < adjustArgsCount || exprs.size() > 2 + adjustArgsCount) {
ctx.Error(Pos) << "Aggregation function " << (isFactory? "factory " : "") << Name <<
" requires " << adjustArgsCount << " to " << (2 + adjustArgsCount) << " arguments, given: " << exprs.size();
@@ -798,11 +798,11 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TTopFreqFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
TPair topFreqs(TopFreqs.cbegin()->second);
@@ -810,14 +810,14 @@ private:
topFreqs = { Y(), Y() };
for (const auto& topFreq : TopFreqs) {
topFreqs = { L(topFreqs.first, topFreq.second.first), L(topFreqs.second, topFreq.second.second) };
- }
+ }
topFreqs = { Q(topFreqs.first), Q(topFreqs.second) };
- }
-
+ }
+
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), topFreqs.first, topFreqs.second);
return apply;
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, TopFreqFactoryParams.first, TopFreqFactoryParams.second);
}
@@ -825,21 +825,21 @@ private:
TNodePtr AggregationTraits(const TNodePtr& type) const final {
if (TopFreqs.empty())
return TNodePtr();
-
+
TNodePtr names(Q(TopFreqs.cbegin()->first));
-
+
if (TopFreqs.size() > 1U) {
names = Y();
for (const auto& topFreq : TopFreqs)
names = L(names, Q(topFreq.first));
names = Q(names);
- }
-
+ }
+
const bool distinct = AggMode == EAggregateMode::Distinct;
const auto listType = distinct ? Y("ListType", Y("StructMemberType", Y("ListItemType", type), BuildQuotedAtom(Pos, DistinctKey))) : type;
return distinct ? Q(Y(names, GetApply(listType), BuildQuotedAtom(Pos, DistinctKey))) : Q(Y(names, GetApply(listType)));
}
-
+
bool DoInit(TContext& ctx, ISource* src) final {
for (const auto& topFreq : TopFreqs) {
if (!topFreq.second.first->Init(ctx, src)) {
@@ -849,11 +849,11 @@ private:
if (!topFreq.second.second->Init(ctx, src)) {
return false;
}
- }
-
+ }
+
return TAggregationFactory::DoInit(ctx, src);
- }
-
+ }
+
std::multimap<TString, TPair> TopFreqs;
TPair TopFreqFactoryParams;
};
@@ -861,7 +861,7 @@ private:
TAggregationPtr BuildTopFreqFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TTopFreqFactory(pos, name, factory, aggMode);
}
-
+
template <bool HasKey>
class TTopAggregationFactory final : public TAggregationFactory {
public:
@@ -1109,7 +1109,7 @@ public:
TUserDefinedAggregationFactory(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode)
: TAggregationFactory(pos, name, factory, aggMode)
{}
-
+
private:
bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) final {
ui32 adjustArgsCount = isFactory ? 0 : 1;
@@ -1118,7 +1118,7 @@ private:
(3 + adjustArgsCount) << " to " << (7 + adjustArgsCount) << " arguments, given: " << exprs.size();
return false;
}
-
+
Lambdas[0] = BuildLambda(Pos, Y("value", "parent"), Y("NamedApply", exprs[adjustArgsCount], Q(Y("value")), Y("AsStruct"), Y("DependsOn", "parent")));
Lambdas[1] = BuildLambda(Pos, Y("value", "state", "parent"), Y("NamedApply", exprs[adjustArgsCount + 1], Q(Y("state", "value")), Y("AsStruct"), Y("DependsOn", "parent")));
Lambdas[2] = BuildLambda(Pos, Y("one", "two"), Y("Apply", exprs[adjustArgsCount + 2], "one", "two"));
@@ -1167,18 +1167,18 @@ private:
TAggregationPtr BuildUserDefinedFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TUserDefinedAggregationFactory(pos, name, factory, aggMode);
}
-
+
class TCountAggregation final : public TAggregationFactory {
public:
TCountAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode)
: TAggregationFactory(pos, name, func, aggMode)
{}
-
+
private:
TNodePtr DoClone() const final {
return new TCountAggregation(Pos, Name, Func, AggMode);
}
-
+
bool DoInit(TContext& ctx, ISource* src) final {
if (!Expr) {
return true;
diff --git a/ydb/library/yql/sql/v0/builtin.cpp b/ydb/library/yql/sql/v0/builtin.cpp
index 38f157647e..a0945f9d05 100644
--- a/ydb/library/yql/sql/v0/builtin.cpp
+++ b/ydb/library/yql/sql/v0/builtin.cpp
@@ -29,7 +29,7 @@ public:
, Args(args)
{}
- bool DoInit(TContext& ctx, ISource* src) final {
+ bool DoInit(TContext& ctx, ISource* src) final {
if (!src) {
ctx.Error(Pos) << "Grouping function should have source";
return false;
@@ -59,7 +59,7 @@ public:
return TAstListNode::DoInit(ctx, src);
}
- TNodePtr DoClone() const final {
+ TNodePtr DoClone() const final {
return new TGroupingNode(Pos, Args);
}
@@ -67,7 +67,7 @@ private:
const TVector<TNodePtr> Args;
};
-class TBasicAggrFunc final: public TAstListNode {
+class TBasicAggrFunc final: public TAstListNode {
public:
TBasicAggrFunc(TPosition pos, const TString& name, TAggregationPtr aggr, const TVector<TNodePtr>& args)
: TAstListNode(pos)
@@ -80,7 +80,7 @@ public:
return Name;
}
- bool DoInit(TContext& ctx, ISource* src) final {
+ bool DoInit(TContext& ctx, ISource* src) final {
if (!src) {
ctx.Error(Pos) << "Unable to use aggregation function '" << Name << "' without data source";
return false;
@@ -92,7 +92,7 @@ public:
return TAstListNode::DoInit(ctx, src);
}
- TNodePtr DoClone() const final {
+ TNodePtr DoClone() const final {
TAggregationPtr aggrClone = static_cast<IAggregation*>(Aggr->Clone().Release());
return new TBasicAggrFunc(Pos, Name, aggrClone, CloneContainer(Args));
}
@@ -102,15 +102,15 @@ public:
}
private:
- bool DoInitAggregation(TContext& ctx, ISource* src) {
+ bool DoInitAggregation(TContext& ctx, ISource* src) {
if (!Aggr->InitAggr(ctx, false, src, *this, Args)) {
return false;
}
return src->AddAggregation(ctx, Aggr);
}
- void DoUpdateState() const final {
- State.Set(ENodeState::Const, Args.front()->IsConstant());
+ void DoUpdateState() const final {
+ State.Set(ENodeState::Const, Args.front()->IsConstant());
State.Set(ENodeState::Aggregated);
}
@@ -239,15 +239,15 @@ public:
bool DoInit(TContext& ctx, ISource* src) override {
auto slot = NUdf::FindDataSlot(GetOpName());
- if (!slot) {
- ctx.Error(Pos) << "Unexpected type " << GetOpName();
- return false;
- }
-
+ if (!slot) {
+ ctx.Error(Pos) << "Unexpected type " << GetOpName();
+ return false;
+ }
+
if (*slot == NUdf::EDataSlot::Decimal) {
- MinArgs = MaxArgs = 3;
- }
-
+ MinArgs = MaxArgs = 3;
+ }
+
if (!ValidateArguments(ctx)) {
return false;
}
@@ -261,32 +261,32 @@ public:
TString value;
if (*slot == NUdf::EDataSlot::Decimal) {
- const auto precision = Args[1]->GetLiteral("Int32");
- const auto scale = Args[2]->GetLiteral("Int32");
-
- if (!NKikimr::NMiniKQL::IsValidDecimal(*atom)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
-
- ui8 stub;
- if (!(precision && TryFromString<ui8>(*precision, stub))) {
- ctx.Error(Pos) << "Invalid precision " << (precision ? precision->Quote() : "") << " for type " << GetOpName();
- return false;
- }
-
- if (!(scale && TryFromString<ui8>(*scale, stub))) {
- ctx.Error(Pos) << "Invalid scale " << (scale ? scale->Quote() : "") << " for type " << GetOpName();
- return false;
- }
-
- Args[0] = BuildQuotedAtom(GetPos(), *atom);
- Args[1] = BuildQuotedAtom(GetPos(), *precision);
- Args[2] = BuildQuotedAtom(GetPos(), *scale);
- return TCallNode::DoInit(ctx, src);
+ const auto precision = Args[1]->GetLiteral("Int32");
+ const auto scale = Args[2]->GetLiteral("Int32");
+
+ if (!NKikimr::NMiniKQL::IsValidDecimal(*atom)) {
+ ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
+ return false;
+ }
+
+ ui8 stub;
+ if (!(precision && TryFromString<ui8>(*precision, stub))) {
+ ctx.Error(Pos) << "Invalid precision " << (precision ? precision->Quote() : "") << " for type " << GetOpName();
+ return false;
+ }
+
+ if (!(scale && TryFromString<ui8>(*scale, stub))) {
+ ctx.Error(Pos) << "Invalid scale " << (scale ? scale->Quote() : "") << " for type " << GetOpName();
+ return false;
+ }
+
+ Args[0] = BuildQuotedAtom(GetPos(), *atom);
+ Args[1] = BuildQuotedAtom(GetPos(), *precision);
+ Args[2] = BuildQuotedAtom(GetPos(), *scale);
+ return TCallNode::DoInit(ctx, src);
} else if (NUdf::GetDataTypeInfo(*slot).Features & (NUdf::DateType | NUdf::TzDateType | NUdf::TimeIntervalType)) {
- const auto out = NKikimr::NMiniKQL::ValueFromString(*slot, *atom);
- if (!out) {
+ const auto out = NKikimr::NMiniKQL::ValueFromString(*slot, *atom);
+ if (!out) {
ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
return false;
}
@@ -294,45 +294,45 @@ public:
switch (*slot) {
case NUdf::EDataSlot::Date:
case NUdf::EDataSlot::TzDate:
- value = ToString(out.Get<ui16>());
+ value = ToString(out.Get<ui16>());
break;
case NUdf::EDataSlot::Datetime:
case NUdf::EDataSlot::TzDatetime:
- value = ToString(out.Get<ui32>());
+ value = ToString(out.Get<ui32>());
break;
case NUdf::EDataSlot::Timestamp:
case NUdf::EDataSlot::TzTimestamp:
- value = ToString(out.Get<ui64>());
+ value = ToString(out.Get<ui64>());
break;
case NUdf::EDataSlot::Interval:
- value = ToString(out.Get<i64>());
- if ('T' == atom->back()) {
- ctx.Warning(Pos, TIssuesIds::YQL_DEPRECATED_INTERVAL_CONSTANT) << "Time prefix 'T' at end of interval constant";
- }
- break;
+ value = ToString(out.Get<i64>());
+ if ('T' == atom->back()) {
+ ctx.Warning(Pos, TIssuesIds::YQL_DEPRECATED_INTERVAL_CONSTANT) << "Time prefix 'T' at end of interval constant";
+ }
+ break;
default:
Y_FAIL("Unexpected data slot");
}
if (NUdf::GetDataTypeInfo(*slot).Features & NUdf::TzDateType) {
- value += ",";
- value += NKikimr::NMiniKQL::GetTimezoneIANAName(out.GetTimezoneId());
- }
+ value += ",";
+ value += NKikimr::NMiniKQL::GetTimezoneIANAName(out.GetTimezoneId());
+ }
} else if (NUdf::EDataSlot::Uuid == *slot) {
- char out[0x10];
- if (!NKikimr::NMiniKQL::ParseUuid(*atom, out)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
-
- value.assign(out, sizeof(out));
+ char out[0x10];
+ if (!NKikimr::NMiniKQL::ParseUuid(*atom, out)) {
+ ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
+ return false;
+ }
+
+ value.assign(out, sizeof(out));
} else {
- if (!NKikimr::NMiniKQL::IsValidStringValue(*slot, *atom)) {
+ if (!NKikimr::NMiniKQL::IsValidStringValue(*slot, *atom)) {
ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
return false;
}
- value = *atom;
+ value = *atom;
}
Args[0] = BuildQuotedAtom(GetPos(), value);
@@ -732,7 +732,7 @@ TString NormalizeTypeString(const TString& str) {
}
static const TSet<TString> AvailableDataTypes = {"Bool", "String", "Uint32", "Uint64", "Int32", "Int64", "Float", "Double", "Utf8", "Yson", "Json",
- "Date", "Datetime", "Timestamp", "Interval", "Uint8", "Int8", "Uint16", "Int16", "TzDate", "TzDatetime", "TzTimestamp", "Uuid", "Decimal"};
+ "Date", "Datetime", "Timestamp", "Interval", "Uint8", "Int8", "Uint16", "Int16", "TzDate", "TzDatetime", "TzTimestamp", "Uuid", "Decimal"};
TNodePtr GetDataTypeStringNode(TContext& ctx, TCallNode& node, unsigned argNum, TString* outTypeStrPtr = nullptr) {
auto errMsgFunc = [&node, argNum]() {
static std::array<TString, 2> numToName = {{"first", "second"}};
@@ -1397,7 +1397,7 @@ public:
}
const TString yql("(" + parsedName + ")");
- TAstParseResult ast = ParseAst(yql, ctx.Pool.get());
+ TAstParseResult ast = ParseAst(yql, ctx.Pool.get());
/// TODO: do not drop warnings
if (ast.IsOk()) {
Node = AstNode(ast.Root->GetChild(0));
@@ -1770,14 +1770,14 @@ TBuiltinFactoryCallback BuildNamedBuiltinFactoryCallback(const TString& name) {
return new TType(pos, name, args);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildArgcBuiltinFactoryCallback(i32 minArgs, i32 maxArgs) {
return [minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
return new TType(pos, minArgs, maxArgs, args);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildNamedArgcBuiltinFactoryCallback(const TString& name, i32 minArgs, i32 maxArgs) {
return [name, minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
@@ -1798,14 +1798,14 @@ TBuiltinFactoryCallback BuildBoolBuiltinFactoryCallback(bool arg) {
return new TType(pos, args, arg);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildFoldBuiltinFactoryCallback(const TString& name, const TString& defaultValue) {
return [name, defaultValue] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
return new TType(pos, name, "Bool", defaultValue, 1, args);
};
}
-
+
TNodePtr MakePair(TPosition pos, const TVector<TNodePtr>& args) {
TNodePtr list = new TAstListNodeImpl(pos, {
args[0],
@@ -1843,7 +1843,7 @@ struct TBuiltinFuncData {
{"characterlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
{"substring", BuildSimpleBuiltinFactoryCallback<TYqlSubstring>()},
{"byteat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ByteAt", 2, 2) },
-
+
// Numeric builtins
{"abs", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Abs", 1, 1) },
{"tobytes", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ToBytes", 1, 1) },
@@ -1879,9 +1879,9 @@ struct TBuiltinFuncData {
{"listany", BuildFoldBuiltinFactoryCallback<TListFoldBuiltinImpl>("Or", "false")},
{"listall", BuildFoldBuiltinFactoryCallback<TListFoldBuiltinImpl>("And", "true")},
{"listhas", BuildSimpleBuiltinFactoryCallback<TListHasBuiltin>()},
- {"listmax", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrMax")},
- {"listmin", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrMin")},
- {"listsum", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrAdd")},
+ {"listmax", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrMax")},
+ {"listmin", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrMin")},
+ {"listsum", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("AggrAdd")},
{"listavg", BuildSimpleBuiltinFactoryCallback<TListAvgBuiltin>()},
{"listconcat", BuildNamedBuiltinFactoryCallback<TListFold1Builtin>("Concat")},
{"listextract", BuildSimpleBuiltinFactoryCallback<TListExtractBuiltin>()},
@@ -2082,8 +2082,8 @@ struct TBuiltinFuncData {
{"aggrlistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
{"aggregatelistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
- {"median", BuildAggrFuncFactoryCallback("Median", "percentile_traits_factory", PERCENTILE)},
- {"percentile", BuildAggrFuncFactoryCallback("Percentile", "percentile_traits_factory", PERCENTILE)},
+ {"median", BuildAggrFuncFactoryCallback("Median", "percentile_traits_factory", PERCENTILE)},
+ {"percentile", BuildAggrFuncFactoryCallback("Percentile", "percentile_traits_factory", PERCENTILE)},
{"mode", BuildAggrFuncFactoryCallback("Mode", "topfreq_traits_factory", TOPFREQ) },
{"topfreq", BuildAggrFuncFactoryCallback("TopFreq", "topfreq_traits_factory", TOPFREQ) },
diff --git a/ydb/library/yql/sql/v0/context.h b/ydb/library/yql/sql/v0/context.h
index 6ad75220fb..45f40fae61 100644
--- a/ydb/library/yql/sql/v0/context.h
+++ b/ydb/library/yql/sql/v0/context.h
@@ -127,7 +127,7 @@ namespace NSQLTranslationV0 {
public:
THashMap<TString, TNodePtr> Variables;
NSQLTranslation::TTranslationSettings Settings;
- std::unique_ptr<TMemoryPool> Pool;
+ std::unique_ptr<TMemoryPool> Pool;
NYql::TIssues& Issues;
TMap<TString, TStack<TNodePtr>> NamedNodes;
TMap<TString, TNodePtr> UniversalAliases;
diff --git a/ydb/library/yql/sql/v0/node.cpp b/ydb/library/yql/sql/v0/node.cpp
index 8a22bb988d..57f0c6a561 100644
--- a/ydb/library/yql/sql/v0/node.cpp
+++ b/ydb/library/yql/sql/v0/node.cpp
@@ -211,11 +211,11 @@ bool INode::DoInit(TContext& ctx, ISource* src) {
return true;
}
-TNodePtr INode::AstNode() const {
+TNodePtr INode::AstNode() const {
return new TAstListNodeImpl(Pos);
}
-TNodePtr INode::AstNode(TNodePtr node) const {
+TNodePtr INode::AstNode(TNodePtr node) const {
return node;
}
@@ -223,7 +223,7 @@ TNodePtr INode::AstNode(const TString& str) const {
return new TAstAtomNodeImpl(Pos, str, TNodeFlags::Default);
}
-TNodePtr INode::AstNode(TAstNode* node) const {
+TNodePtr INode::AstNode(TAstNode* node) const {
return new TAstDirectNode(node);
}
@@ -977,8 +977,8 @@ TAstNode* ITableKeys::Translate(TContext& ctx) const {
return nullptr;
}
-bool IAggregation::IsDistinct() const {
- return !DistinctKey.empty();
+bool IAggregation::IsDistinct() const {
+ return !DistinctKey.empty();
}
void IAggregation::DoUpdateState() const {
@@ -990,17 +990,17 @@ const TString* IAggregation::GetGenericKey() const {
return nullptr;
}
-void IAggregation::Join(IAggregation*) {
- Y_VERIFY(false);
-}
-
+void IAggregation::Join(IAggregation*) {
+ Y_VERIFY(false);
+}
+
const TString& IAggregation::GetName() const {
return Name;
}
IAggregation::IAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode)
: INode(pos), Name(name), Func(func), AggMode(aggMode)
-{}
+{}
TAstNode* IAggregation::Translate(TContext& ctx) const {
Y_VERIFY_DEBUG(false);
@@ -1012,8 +1012,8 @@ TNodePtr IAggregation::AggregationTraits(const TNodePtr& type) const {
const bool distinct = AggMode == EAggregateMode::Distinct;
const auto listType = distinct ? Y("ListType", Y("StructMemberType", Y("ListItemType", type), BuildQuotedAtom(Pos, DistinctKey))) : type;
return distinct ? Q(Y(Q(Name), GetApply(listType), BuildQuotedAtom(Pos, DistinctKey))): Q(Y(Q(Name), GetApply(listType)));
-}
-
+}
+
void IAggregation::AddFactoryArguments(TNodePtr& apply) const {
Y_UNUSED(apply);
}
@@ -1433,23 +1433,23 @@ TNodePtr ISource::BuildAggregation(const TString& label) {
}
std::map<std::pair<bool, TString>, std::vector<IAggregation*>> genericAggrs;
- for (const auto& aggr: Aggregations) {
- if (const auto key = aggr->GetGenericKey()) {
- genericAggrs[{aggr->IsDistinct(), *key}].emplace_back(aggr.Get());
+ for (const auto& aggr: Aggregations) {
+ if (const auto key = aggr->GetGenericKey()) {
+ genericAggrs[{aggr->IsDistinct(), *key}].emplace_back(aggr.Get());
}
}
- for (const auto& aggr : genericAggrs) {
- for (size_t i = 1U; i < aggr.second.size(); ++i) {
- aggr.second.front()->Join(aggr.second[i]);
+ for (const auto& aggr : genericAggrs) {
+ for (size_t i = 1U; i < aggr.second.size(); ++i) {
+ aggr.second.front()->Join(aggr.second[i]);
}
- }
+ }
- const auto listType = Y("TypeOf", label);
- auto aggrArgs = Y();
- for (const auto& aggr: Aggregations) {
+ const auto listType = Y("TypeOf", label);
+ auto aggrArgs = Y();
+ for (const auto& aggr: Aggregations) {
if (const auto traits = aggr->AggregationTraits(listType))
- aggrArgs = L(aggrArgs, traits);
+ aggrArgs = L(aggrArgs, traits);
}
if (HoppingWindowSpec) {
@@ -1466,7 +1466,7 @@ TNodePtr ISource::BuildAggregation(const TString& label) {
Q(Y(Q(Y(BuildQuotedAtom(Pos, "hopping"), hoppingTraits)))));
}
- return Y("Aggregate", label, Q(keysTuple), Q(aggrArgs));
+ return Y("Aggregate", label, Q(keysTuple), Q(aggrArgs));
}
TMaybe<TString> ISource::FindColumnMistype(const TString& name) const {
@@ -2379,23 +2379,23 @@ TNodePtr BuildAccess(TPosition pos, const TVector<INode::TIdPart>& ids, bool isL
return new TAccessNode(pos, ids, isLookup);
}
-class TBindNode: public TAstListNode {
-public:
+class TBindNode: public TAstListNode {
+public:
TBindNode(TPosition pos, const TString& module, const TString& alias)
- : TAstListNode(pos)
- {
- Add("bind", AstNode(module), BuildQuotedAtom(pos, alias));
- }
+ : TAstListNode(pos)
+ {
+ Add("bind", AstNode(module), BuildQuotedAtom(pos, alias));
+ }
TPtr DoClone() const final {
return {};
}
-};
-
+};
+
TNodePtr BuildBind(TPosition pos, const TString& module, const TString& alias) {
- return new TBindNode(pos, module, alias);
-}
-
+ return new TBindNode(pos, module, alias);
+}
+
class TLambdaNode: public TAstListNode {
public:
TLambdaNode(TPosition pos, TNodePtr params, TNodePtr body, const TString& resName)
@@ -2416,23 +2416,23 @@ TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TStrin
return new TLambdaNode(pos, params, body, resName);
}
-template <bool Bit>
+template <bool Bit>
class TCastNode: public TAstListNode {
public:
- TCastNode(TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo)
- : TAstListNode(pos)
- , Expr(expr)
- , NormalizedTypeName(TypeByAlias(typeName))
- , ParamOne(paramOne)
- , ParamTwo(paramTwo)
- {}
+ TCastNode(TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo)
+ : TAstListNode(pos)
+ , Expr(expr)
+ , NormalizedTypeName(TypeByAlias(typeName))
+ , ParamOne(paramOne)
+ , ParamTwo(paramTwo)
+ {}
const TString* GetSourceName() const override {
return Expr->GetSourceName();
}
TString GetOpName() const override {
- return Bit ? "BitCast" : "Cast";
+ return Bit ? "BitCast" : "Cast";
}
void DoUpdateState() const override {
@@ -2442,76 +2442,76 @@ public:
}
TPtr DoClone() const final {
- return new TCastNode(Pos, Expr->Clone(), NormalizedTypeName, ParamOne, ParamTwo);
+ return new TCastNode(Pos, Expr->Clone(), NormalizedTypeName, ParamOne, ParamTwo);
}
bool DoInit(TContext& ctx, ISource* src) override;
private:
TNodePtr Expr;
const TString NormalizedTypeName;
- const TString ParamOne, ParamTwo;
+ const TString ParamOne, ParamTwo;
};
-template <>
-bool TCastNode<false>::DoInit(TContext& ctx, ISource* src) {
+template <>
+bool TCastNode<false>::DoInit(TContext& ctx, ISource* src) {
if (Expr->IsNull()) {
- if (ParamOne.empty() && ParamTwo.empty()) {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName))));
- } else if (ParamTwo.empty()) {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne))));
- } else {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo))));
- }
+ if (ParamOne.empty() && ParamTwo.empty()) {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName))));
+ } else if (ParamTwo.empty()) {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne))));
+ } else {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo))));
+ }
} else {
- if (ParamOne.empty() && ParamTwo.empty()) {
- Add("Cast", Expr, Q(NormalizedTypeName));
- } else if (ParamTwo.empty()) {
- Add("Cast", Expr, Q(NormalizedTypeName), Q(ParamOne));
- } else {
- Add("Cast", Expr, Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo));
- }
+ if (ParamOne.empty() && ParamTwo.empty()) {
+ Add("Cast", Expr, Q(NormalizedTypeName));
+ } else if (ParamTwo.empty()) {
+ Add("Cast", Expr, Q(NormalizedTypeName), Q(ParamOne));
+ } else {
+ Add("Cast", Expr, Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo));
+ }
}
return TAstListNode::DoInit(ctx, src);
}
-template <>
-bool TCastNode<true>::DoInit(TContext& ctx, ISource* src) {
- if (Expr->IsNull()) {
- if (ParamOne.empty() && ParamTwo.empty()) {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName))));
- } else if (ParamTwo.empty()) {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne))));
- } else {
- Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo))));
- }
- } else {
- if (ParamOne.empty() && ParamTwo.empty()) {
- Add("BitCast", Expr, Q(NormalizedTypeName));
- } else if (ParamTwo.empty()) {
- Add("BitCast", Expr, Q(NormalizedTypeName), Q(ParamOne));
- } else {
- Add("BitCast", Expr, Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo));
- }
- }
- return TAstListNode::DoInit(ctx, src);
-}
-
-TNodePtr BuildCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo) {
+template <>
+bool TCastNode<true>::DoInit(TContext& ctx, ISource* src) {
+ if (Expr->IsNull()) {
+ if (ParamOne.empty() && ParamTwo.empty()) {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName))));
+ } else if (ParamTwo.empty()) {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne))));
+ } else {
+ Add("Nothing", Y("OptionalType", Y("DataType", Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo))));
+ }
+ } else {
+ if (ParamOne.empty() && ParamTwo.empty()) {
+ Add("BitCast", Expr, Q(NormalizedTypeName));
+ } else if (ParamTwo.empty()) {
+ Add("BitCast", Expr, Q(NormalizedTypeName), Q(ParamOne));
+ } else {
+ Add("BitCast", Expr, Q(NormalizedTypeName), Q(ParamOne), Q(ParamTwo));
+ }
+ }
+ return TAstListNode::DoInit(ctx, src);
+}
+
+TNodePtr BuildCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo) {
Y_UNUSED(ctx);
if (!expr) {
return nullptr;
}
- return new TCastNode<false>(pos, expr, typeName, paramOne, paramTwo);
+ return new TCastNode<false>(pos, expr, typeName, paramOne, paramTwo);
}
-TNodePtr BuildBitCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo) {
+TNodePtr BuildBitCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne, const TString& paramTwo) {
Y_UNUSED(ctx);
- if (!expr) {
- return nullptr;
- }
- return new TCastNode<true>(pos, expr, typeName, paramOne, paramTwo);
-}
-
+ if (!expr) {
+ return nullptr;
+ }
+ return new TCastNode<true>(pos, expr, typeName, paramOne, paramTwo);
+}
+
TString TypeByAlias(const TString& alias, bool normalize) {
TString type(alias);
TCiString typeAlias(alias);
diff --git a/ydb/library/yql/sql/v0/node.h b/ydb/library/yql/sql/v0/node.h
index 22cce1e4e9..4c7cfc273b 100644
--- a/ydb/library/yql/sql/v0/node.h
+++ b/ydb/library/yql/sql/v0/node.h
@@ -154,9 +154,9 @@ namespace NSQLTranslationV0 {
virtual bool UsedSubquery() const;
virtual bool IsSelect() const;
- TPtr AstNode() const;
- TPtr AstNode(TAstNode* node) const;
- TPtr AstNode(TPtr node) const;
+ TPtr AstNode() const;
+ TPtr AstNode(TAstNode* node) const;
+ TPtr AstNode(TPtr node) const;
TPtr AstNode(const TString& str) const;
template <typename TVal, typename... TVals>
@@ -165,27 +165,27 @@ namespace NSQLTranslationV0 {
Add(vals...);
}
- void Add() {}
+ void Add() {}
// Y() Q() L()
- TPtr Y() const {
+ TPtr Y() const {
return AstNode();
}
template <typename... TVals>
- TPtr Y(TVals... vals) const {
+ TPtr Y(TVals... vals) const {
TPtr node(AstNode());
node->Add(vals...);
return node;
}
template <typename T>
- TPtr Q(T a) const {
+ TPtr Q(T a) const {
return Y("quote", a);
}
template <typename... TVals>
- TPtr L(TPtr list, TVals... vals) const {
+ TPtr L(TPtr list, TVals... vals) const {
Y_VERIFY_DEBUG(list);
auto copy = list->ShallowCopy();
copy->Add(vals...);
@@ -642,16 +642,16 @@ namespace NSQLTranslationV0 {
class IAggregation: public INode {
public:
- bool IsDistinct() const;
-
+ bool IsDistinct() const;
+
void DoUpdateState() const override;
virtual const TString* GetGenericKey() const;
-
+
virtual bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) = 0;
virtual TNodePtr AggregationTraits(const TNodePtr& type) const;
-
+
virtual TNodePtr AggregationTraitsFactory() const = 0;
virtual std::vector<ui32> GetFactoryColumnIndices() const;
@@ -662,11 +662,11 @@ namespace NSQLTranslationV0 {
const TString& GetName() const;
- virtual void Join(IAggregation* aggr);
-
- private:
- virtual TNodePtr GetApply(const TNodePtr& type) const = 0;
-
+ virtual void Join(IAggregation* aggr);
+
+ private:
+ virtual TNodePtr GetApply(const TNodePtr& type) const = 0;
+
protected:
IAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode mode);
TAstNode* Translate(TContext& ctx) const override;
@@ -891,8 +891,8 @@ namespace NSQLTranslationV0 {
TNodePtr BuildAccess(TPosition pos, const TVector<INode::TIdPart>& ids, bool isLookup);
TNodePtr BuildBind(TPosition pos, const TString& module, const TString& alias);
TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TString& resName = TString());
- TNodePtr BuildCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne = TString(), const TString& paramTwo = TString());
- TNodePtr BuildBitCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne = TString(), const TString& paramTwo = TString());
+ TNodePtr BuildCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne = TString(), const TString& paramTwo = TString());
+ TNodePtr BuildBitCast(TContext& ctx, TPosition pos, TNodePtr expr, const TString& typeName, const TString& paramOne = TString(), const TString& paramTwo = TString());
TNodePtr BuildIsNullOp(TPosition pos, TNodePtr a);
TNodePtr BuildUnaryOp(TPosition pos, const TString& opName, TNodePtr a);
TNodePtr BuildBinaryOp(TPosition pos, const TString& opName, TNodePtr a, TNodePtr b);
diff --git a/ydb/library/yql/sql/v0/query.cpp b/ydb/library/yql/sql/v0/query.cpp
index 7846fbf795..7752b28b01 100644
--- a/ydb/library/yql/sql/v0/query.cpp
+++ b/ydb/library/yql/sql/v0/query.cpp
@@ -877,7 +877,7 @@ public:
TPtr ProduceOperation(TContext& ctx, const TString& sinkName, const TString& service) override {
if (service != KikimrProviderName) {
- ctx.Error(ctx.Pos()) << "ROLLBACK isn't supported for provider: " << TStringBuf(service);
+ ctx.Error(ctx.Pos()) << "ROLLBACK isn't supported for provider: " << TStringBuf(service);
return nullptr;
}
diff --git a/ydb/library/yql/sql/v0/select.cpp b/ydb/library/yql/sql/v0/select.cpp
index bb6f9a660a..ef47023be1 100644
--- a/ydb/library/yql/sql/v0/select.cpp
+++ b/ydb/library/yql/sql/v0/select.cpp
@@ -832,7 +832,7 @@ public:
keysTuple = Q(keysTuple);
}
auto extractKey = Y("SqlExtractKey", "row", BuildLambda(Pos, Y("row"), keysTuple));
- auto extractKeyLambda = BuildLambda(Pos, Y("row"), extractKey);
+ auto extractKeyLambda = BuildLambda(Pos, Y("row"), extractKey);
TNodePtr processPartitions;
switch (Mode) {
@@ -849,7 +849,7 @@ public:
break;
}
case ReduceMode::ByPartition: {
- processPartitions = Y("SqlReduce", "partitionStream", extractKeyLambda, Udf,
+ processPartitions = Y("SqlReduce", "partitionStream", extractKeyLambda, Udf,
BuildLambda(Pos, Y("row"), GroundWithExpr(ExprGround, Args[0])));
break;
}
@@ -864,7 +864,7 @@ public:
sortKeySelector = BuildLambda(Pos, Y("row"), Y("SqlExtractKey", "row", sortKeySelector));
}
- auto partitionByKey = Y(Mode == ReduceMode::ByAll ? "PartitionByKey" : "PartitionsByKeys", "core", extractKeyLambda,
+ auto partitionByKey = Y(Mode == ReduceMode::ByAll ? "PartitionByKey" : "PartitionsByKeys", "core", extractKeyLambda,
sortDirection, sortKeySelector, BuildLambda(Pos, Y("partitionStream"), processPartitions));
auto block(Y(Y("let", "core", input)));
diff --git a/ydb/library/yql/sql/v0/sql.cpp b/ydb/library/yql/sql/v0/sql.cpp
index 599936ef81..b028fc0439 100644
--- a/ydb/library/yql/sql/v0/sql.cpp
+++ b/ydb/library/yql/sql/v0/sql.cpp
@@ -262,41 +262,41 @@ static bool PureColumnOrNamedListStr(const TRule_pure_column_or_named_list& node
return true;
}
-namespace {
+namespace {
bool IsDistinctOptSet(const TRule_opt_set_quantifier& node) {
return node.HasBlock1() && node.GetBlock1().GetToken1().GetId() == SQLLexerTokens::TOKEN_DISTINCT;
}
-std::pair<TString, bool> FlexType(const TRule_flex_type& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_flex_type::kAltFlexType1:
- return std::make_pair(StringContent(ctx.Context(), ctx.Token(node.GetAlt_flex_type1().GetToken1())), true);
- case TRule_flex_type::kAltFlexType2: {
- const auto& typeName = node.GetAlt_flex_type2().GetRule_type_name1();
- const TString& paramOne = typeName.HasBlock2() ? typeName.GetBlock2().GetRule_integer2().GetToken1().GetValue() : TString();
- const TString& paramTwo = !paramOne.empty() && typeName.GetBlock2().HasBlock3() ? typeName.GetBlock2().GetBlock3().GetRule_integer2().GetToken1().GetValue() : TString();
- TString stringType = Id(typeName.GetRule_id1(), ctx);
- if (!paramOne.empty() && !paramTwo.empty()) {
- TStringStream strm;
- strm << '(' << paramOne << ',' << paramTwo << ')';
- stringType += strm.Str();
- }
- return std::make_pair(stringType, false);
- }
- default:
- Y_FAIL("You should change implementation according to grammar changes");
- }
-}
-
-}
-
+std::pair<TString, bool> FlexType(const TRule_flex_type& node, TTranslation& ctx) {
+ switch (node.Alt_case()) {
+ case TRule_flex_type::kAltFlexType1:
+ return std::make_pair(StringContent(ctx.Context(), ctx.Token(node.GetAlt_flex_type1().GetToken1())), true);
+ case TRule_flex_type::kAltFlexType2: {
+ const auto& typeName = node.GetAlt_flex_type2().GetRule_type_name1();
+ const TString& paramOne = typeName.HasBlock2() ? typeName.GetBlock2().GetRule_integer2().GetToken1().GetValue() : TString();
+ const TString& paramTwo = !paramOne.empty() && typeName.GetBlock2().HasBlock3() ? typeName.GetBlock2().GetBlock3().GetRule_integer2().GetToken1().GetValue() : TString();
+ TString stringType = Id(typeName.GetRule_id1(), ctx);
+ if (!paramOne.empty() && !paramTwo.empty()) {
+ TStringStream strm;
+ strm << '(' << paramOne << ',' << paramTwo << ')';
+ stringType += strm.Str();
+ }
+ return std::make_pair(stringType, false);
+ }
+ default:
+ Y_FAIL("You should change implementation according to grammar changes");
+ }
+}
+
+}
+
static TColumnSchema ColumnSchemaImpl(const TRule_column_schema& node, TTranslation& ctx) {
const bool nullable = !node.HasBlock3() || !node.GetBlock3().HasBlock1();
const TString name(Id(node.GetRule_id_schema1(), ctx));
const TPosition pos(ctx.Context().Pos());
- const auto& type = FlexType(node.GetRule_flex_type2(), ctx);
- return TColumnSchema(pos, name, type.first, nullable, type.second);
+ const auto& type = FlexType(node.GetRule_flex_type2(), ctx);
+ return TColumnSchema(pos, name, type.first, nullable, type.second);
}
static bool CreateTableEntry(const TRule_create_table_entry& node, TTranslation& ctx,
@@ -624,7 +624,7 @@ private:
TNodePtr BindParameterRule(const TRule_bind_parameter& rule);
TNodePtr LambdaRule(const TRule_lambda& rule);
TNodePtr CastRule(const TRule_cast_expr& rule);
- TNodePtr BitCastRule(const TRule_bitcast_expr& rule);
+ TNodePtr BitCastRule(const TRule_bitcast_expr& rule);
TNodePtr ExistsRule(const TRule_exists_expr& rule);
TNodePtr CaseRule(const TRule_case_expr& rule);
@@ -1500,17 +1500,17 @@ TNodePtr TSqlExpression::CastRule(const TRule_cast_expr& rule) {
return BuildCast(Ctx, pos, expr.Build(alt.GetRule_expr3()), Id(alt.GetRule_type_name5().GetRule_id1(), *this), paramOne, paramTwo);
}
-TNodePtr TSqlExpression::BitCastRule(const TRule_bitcast_expr& rule) {
- Ctx.IncrementMonCounter("sql_features", "BitCast");
- const auto& alt = rule;
- Token(alt.GetToken1());
- TPosition pos(Ctx.Pos());
- TSqlExpression expr(Ctx, Mode);
- const auto& paramOne = alt.GetRule_type_name5().HasBlock2() ? alt.GetRule_type_name5().GetBlock2().GetRule_integer2().GetToken1().GetValue() : TString();
- const auto& paramTwo = !paramOne.empty() && alt.GetRule_type_name5().GetBlock2().HasBlock3() ? alt.GetRule_type_name5().GetBlock2().GetBlock3().GetRule_integer2().GetToken1().GetValue() : TString();
- return BuildBitCast(Ctx, pos, expr.Build(alt.GetRule_expr3()), Id(alt.GetRule_type_name5().GetRule_id1(), *this), paramOne, paramTwo);
-}
-
+TNodePtr TSqlExpression::BitCastRule(const TRule_bitcast_expr& rule) {
+ Ctx.IncrementMonCounter("sql_features", "BitCast");
+ const auto& alt = rule;
+ Token(alt.GetToken1());
+ TPosition pos(Ctx.Pos());
+ TSqlExpression expr(Ctx, Mode);
+ const auto& paramOne = alt.GetRule_type_name5().HasBlock2() ? alt.GetRule_type_name5().GetBlock2().GetRule_integer2().GetToken1().GetValue() : TString();
+ const auto& paramTwo = !paramOne.empty() && alt.GetRule_type_name5().GetBlock2().HasBlock3() ? alt.GetRule_type_name5().GetBlock2().GetBlock3().GetRule_integer2().GetToken1().GetValue() : TString();
+ return BuildBitCast(Ctx, pos, expr.Build(alt.GetRule_expr3()), Id(alt.GetRule_type_name5().GetRule_id1(), *this), paramOne, paramTwo);
+}
+
TNodePtr TSqlExpression::ExistsRule(const TRule_exists_expr& rule) {
Ctx.IncrementMonCounter("sql_features", "Exists");
const auto& alt = rule;
@@ -1636,8 +1636,8 @@ TNodePtr TSqlExpression::AtomExpr(const TRule_atom_expr& node) {
const TString name(IdOrString(alt.GetRule_id_or_string3(), *this, rawString));
return BuildCallable(pos, module, name, {});
}
- case TRule_atom_expr::kAltAtomExpr9:
- return BitCastRule(node.GetAlt_atom_expr9().GetRule_bitcast_expr1());
+ case TRule_atom_expr::kAltAtomExpr9:
+ return BitCastRule(node.GetAlt_atom_expr9().GetRule_bitcast_expr1());
default:
AltNotImplemented("atom_expr", node);
}
@@ -1681,8 +1681,8 @@ TNodePtr TSqlExpression::InAtomExpr(const TRule_in_atom_expr& node) {
Ctx.IncrementMonCounter("sql_features", "InSubquery");
return BuildSelectResult(pos, std::move(source), false, Mode == NSQLTranslation::ESqlMode::SUBQUERY);
}
- case TRule_in_atom_expr::kAltInAtomExpr8:
- return BitCastRule(node.GetAlt_in_atom_expr8().GetRule_bitcast_expr1());
+ case TRule_in_atom_expr::kAltInAtomExpr8:
+ return BitCastRule(node.GetAlt_in_atom_expr8().GetRule_bitcast_expr1());
default:
AltNotImplemented("in_atom_expr", node);
}
@@ -3669,21 +3669,21 @@ bool TGroupByClause::HoppingWindow(const TRule_hopping_window_specification& nod
});
}
- const auto out = NKikimr::NMiniKQL::ValueFromString(NKikimr::NUdf::EDataSlot::Interval, *literal);
- if (!out) {
+ const auto out = NKikimr::NMiniKQL::ValueFromString(NKikimr::NUdf::EDataSlot::Interval, *literal);
+ if (!out) {
Ctx.Error(node->GetPos()) << "Expected interval in ISO 8601 format";
return nullptr;
}
- if ('T' == literal->back()) {
- Ctx.Warning(node->GetPos(), TIssuesIds::YQL_DEPRECATED_INTERVAL_CONSTANT) << "Time prefix 'T' at end of interval contant";
- }
-
+ if ('T' == literal->back()) {
+ Ctx.Warning(node->GetPos(), TIssuesIds::YQL_DEPRECATED_INTERVAL_CONSTANT) << "Time prefix 'T' at end of interval contant";
+ }
+
return new TAstListNodeImpl(Ctx.Pos(), {
new TAstAtomNodeImpl(Ctx.Pos(), "Interval", TNodeFlags::Default),
new TAstListNodeImpl(Ctx.Pos(), {
new TAstAtomNodeImpl(Ctx.Pos(), "quote", TNodeFlags::Default),
- new TAstAtomNodeImpl(Ctx.Pos(), ToString(out.Get<i64>()), TNodeFlags::Default)
+ new TAstAtomNodeImpl(Ctx.Pos(), ToString(out.Get<i64>()), TNodeFlags::Default)
})
});
};
@@ -4650,11 +4650,11 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
} else if (normalizedPragma == "file") {
if (values.size() != 2U || pragmaValueDefault) {
Error() << "Expected file alias and url as pragma values";
- Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
+ Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
return {};
- }
-
- Ctx.IncrementMonCounter("sql_pragma", "file");
+ }
+
+ Ctx.IncrementMonCounter("sql_pragma", "file");
success = true;
return BuildPragma(Ctx.Pos(), TString(ConfigProviderName), "AddFileByUrl", values, false);
} else if (normalizedPragma == "folder") {
@@ -5061,12 +5061,12 @@ TNodePtr TSqlQuery::Build(const TSQLParserAST& ast) {
"SQL v0 syntax is deprecated and will stop working soon. Consider switching to v1: https://clubs.at.yandex-team.ru/yql/2910";
}
- if (Ctx.Settings.V0Behavior == NSQLTranslation::EV0Behavior::Report) {
- AddStatementToBlocks(blocks, BuildPragma(TPosition(), "config", "flags", {
- TDeferredAtom(TPosition(), "SQL"),
- TDeferredAtom(TPosition(), "0")
- }, false));
- }
+ if (Ctx.Settings.V0Behavior == NSQLTranslation::EV0Behavior::Report) {
+ AddStatementToBlocks(blocks, BuildPragma(TPosition(), "config", "flags", {
+ TDeferredAtom(TPosition(), "SQL"),
+ TDeferredAtom(TPosition(), "0")
+ }, false));
+ }
if (!Statement(blocks, statements.GetRule_sql_stmt1().GetRule_sql_stmt_core2())) {
return nullptr;
}
@@ -5097,9 +5097,9 @@ TNodePtr TSqlQuery::Build(const TSQLParserAST& ast) {
TNodePtr TSqlQuery::FlexType(TTranslation& ctx, const TRule_flex_type& node) {
const auto& stringType = NSQLTranslationV0::FlexType(node, ctx);
- auto res = TryBuildDataType(Ctx.Pos(), TypeByAlias(stringType.first, !stringType.second));
+ auto res = TryBuildDataType(Ctx.Pos(), TypeByAlias(stringType.first, !stringType.second));
if (!res) {
- res = BuildBuiltinFunc(Ctx, Ctx.Pos(), "ParseType", {BuildLiteralRawString(Ctx.Pos(), stringType.first)});
+ res = BuildBuiltinFunc(Ctx, Ctx.Pos(), "ParseType", {BuildLiteralRawString(Ctx.Pos(), stringType.first)});
}
return res;
}
@@ -5271,7 +5271,7 @@ void SqlASTToYqlImpl(NYql::TAstParseResult& res, const google::protobuf::Message
TContext& ctx) {
YQL_ENSURE(!ctx.Issues.Size());
res.Root = SqlASTToYql(protoAst, ctx);
- res.Pool = std::move(ctx.Pool);
+ res.Pool = std::move(ctx.Pool);
if (!res.Root) {
if (ctx.Issues.Size()) {
ctx.IncrementMonCounter("sql_errors", "AstToYqlError");
diff --git a/ydb/library/yql/sql/v0/sql_ut.cpp b/ydb/library/yql/sql/v0/sql_ut.cpp
index e208d5235f..3a70aef93c 100644
--- a/ydb/library/yql/sql/v0/sql_ut.cpp
+++ b/ydb/library/yql/sql/v0/sql_ut.cpp
@@ -33,7 +33,7 @@ NYql::TAstParseResult SqlToYqlWithMode(const TString& query, NSQLTranslation::ES
settings.MaxErrors = maxErrors;
settings.Mode = mode;
settings.Arena = &arena;
- settings.V0Behavior = NSQLTranslation::EV0Behavior::Report;
+ settings.V0Behavior = NSQLTranslation::EV0Behavior::Report;
settings.WarnOnV0 = false;
auto res = SqlToYql(query, settings);
if (debug == EDebugOutput::ToCerr) {
@@ -91,13 +91,13 @@ TString VerifyProgram(const NYql::TAstParseResult& res, TWordCountHive& wordCoun
}
Y_UNIT_TEST_SUITE(SqlParsingOnly) {
- Y_UNIT_TEST(V0) {
- NYql::TAstParseResult res = SqlToYql("select null;");
- UNIT_ASSERT(res.Root);
- const auto programm = GetPrettyPrint(res);
- UNIT_ASSERT(TString::npos != programm.find("(Configure! world (DataSource '\"config\") '\"SQL\" '\"0\"))"));
- }
-
+ Y_UNIT_TEST(V0) {
+ NYql::TAstParseResult res = SqlToYql("select null;");
+ UNIT_ASSERT(res.Root);
+ const auto programm = GetPrettyPrint(res);
+ UNIT_ASSERT(TString::npos != programm.find("(Configure! world (DataSource '\"config\") '\"SQL\" '\"0\"))"));
+ }
+
Y_UNIT_TEST(TableHints) {
UNIT_ASSERT(SqlToYql("SELECT * FROM plato.Input WITH INFER_SCHEME").IsOk());
UNIT_ASSERT(SqlToYql("SELECT * FROM plato.Input WITH (INFER_SCHEME)").IsOk());
@@ -374,7 +374,7 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
NYql::TAstParseResult res = SqlToYql("select key as goal from plato.Input order by goal");
UNIT_ASSERT(res.Root);
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
- if (word == "DataSource" && TString::npos == line.find("SQL")) {
+ if (word == "DataSource" && TString::npos == line.find("SQL")) {
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("plato"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Input"));
@@ -387,7 +387,7 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
};
TWordCountHive elementStat = {{TString("DataSource"), 0}, {TString("Sort"), 0}};
VerifyProgram(res, elementStat, verifyLine);
- UNIT_ASSERT_VALUES_EQUAL(2, elementStat["DataSource"]);
+ UNIT_ASSERT_VALUES_EQUAL(2, elementStat["DataSource"]);
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Sort"]);
}
@@ -719,11 +719,11 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["UnionAll"]);
}
- Y_UNIT_TEST(DeclareDecimalParameter) {
- NYql::TAstParseResult res = SqlToYql("declare $value as Decimal(22,9); select $value as cnt;");
- UNIT_ASSERT(res.Root);
- }
-
+ Y_UNIT_TEST(DeclareDecimalParameter) {
+ NYql::TAstParseResult res = SqlToYql("declare $value as Decimal(22,9); select $value as cnt;");
+ UNIT_ASSERT(res.Root);
+ }
+
Y_UNIT_TEST(SimpleGroupBy) {
NYql::TAstParseResult res = SqlToYql("select count(1),z from plato.Input group by key as z order by z;");
UNIT_ASSERT(res.Root);
@@ -744,33 +744,33 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
VerifyProgram(res, elementStat);
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["rollback"]);
}
-
+
Y_UNIT_TEST(PragmaFile) {
- NYql::TAstParseResult res = SqlToYql(R"(pragma file("HW", "sbr:181041334");)");
- UNIT_ASSERT(res.Root);
-
+ NYql::TAstParseResult res = SqlToYql(R"(pragma file("HW", "sbr:181041334");)");
+ UNIT_ASSERT(res.Root);
+
TWordCountHive elementStat = {{TString(R"((let world (Configure! world (DataSource '"config") '"AddFileByUrl" '"HW" '"sbr:181041334")))"), 0}};
- VerifyProgram(res, elementStat);
- UNIT_ASSERT_VALUES_EQUAL(1, elementStat.cbegin()->second);
- }
+ VerifyProgram(res, elementStat);
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat.cbegin()->second);
+ }
Y_UNIT_TEST(DoNotCrashOnNamedInFilter) {
NYql::TAstParseResult res = SqlToYql("USE plato; $all = YQL::@@(lambda '(table_name) (Bool 'true))@@; SELECT * FROM FILTER(Input, $all)");
UNIT_ASSERT(res.Root);
}
-
+
Y_UNIT_TEST(PragmasFileAndUdfOrder) {
- NYql::TAstParseResult res = SqlToYql(R"(
+ NYql::TAstParseResult res = SqlToYql(R"(
PRAGMA file("libvideoplayers_udf.so", "https://proxy.sandbox.yandex-team.ru/235185290");
- PRAGMA udf("libvideoplayers_udf.so");
- )");
- UNIT_ASSERT(res.Root);
-
- const auto programm = GetPrettyPrint(res);
- const auto file = programm.find("AddFileByUrl");
- const auto udfs = programm.find("ImportUdfs");
- UNIT_ASSERT(file < udfs);
- }
+ PRAGMA udf("libvideoplayers_udf.so");
+ )");
+ UNIT_ASSERT(res.Root);
+
+ const auto programm = GetPrettyPrint(res);
+ const auto file = programm.find("AddFileByUrl");
+ const auto udfs = programm.find("ImportUdfs");
+ UNIT_ASSERT(file < udfs);
+ }
Y_UNIT_TEST(ProcessUserType) {
NYql::TAstParseResult res = SqlToYql("process plato.Input using Kikimr::PushData($ROWS);", 1, TString(NYql::KikimrProviderName));
diff --git a/ydb/library/yql/sql/v1/SQLv1.g.in b/ydb/library/yql/sql/v1/SQLv1.g.in
index d2108c7ce2..ef394c7a00 100644
--- a/ydb/library/yql/sql/v1/SQLv1.g.in
+++ b/ydb/library/yql/sql/v1/SQLv1.g.in
@@ -118,7 +118,7 @@ atom_expr:
| case_expr
| an_id_or_type NAMESPACE (id_or_type | STRING_VALUE)
| value_constructor
- | bitcast_expr
+ | bitcast_expr
| list_literal
| dict_literal
| struct_literal
@@ -135,7 +135,7 @@ in_atom_expr:
// TODO: resolve ANTLR error: rule in_atom_expr has non-LL(*) decision due to recursive rule invocations reachable from alts 3,8
// | LPAREN values_stmt RPAREN
| value_constructor
- | bitcast_expr
+ | bitcast_expr
| list_literal
| dict_literal
| struct_literal
@@ -143,8 +143,8 @@ in_atom_expr:
cast_expr: CAST LPAREN expr AS type_name_or_bind RPAREN;
-bitcast_expr: BITCAST LPAREN expr AS type_name_simple RPAREN;
-
+bitcast_expr: BITCAST LPAREN expr AS type_name_simple RPAREN;
+
exists_expr: EXISTS LPAREN (select_stmt | values_stmt) RPAREN;
case_expr: CASE expr? when_expr+ (ELSE expr)? END;
@@ -784,7 +784,7 @@ keyword:
keyword_expr_uncompat:
BETWEEN
| BITCAST
- | CASE
+ | CASE
| CAST
| CUBE
| CURRENT_DATE
@@ -1133,7 +1133,7 @@ BEFORE: B E F O R E;
BEGIN: B E G I N;
BERNOULLI: B E R N O U L L I;
BETWEEN: B E T W E E N;
-BITCAST: B I T C A S T;
+BITCAST: B I T C A S T;
BY: B Y;
CALLABLE: C A L L A B L E;
CASCADE: C A S C A D E;
diff --git a/ydb/library/yql/sql/v1/aggregation.cpp b/ydb/library/yql/sql/v1/aggregation.cpp
index a92fdcd9ca..850e0e5056 100644
--- a/ydb/library/yql/sql/v1/aggregation.cpp
+++ b/ydb/library/yql/sql/v1/aggregation.cpp
@@ -7,8 +7,8 @@
#include <util/string/builder.h>
#include <util/string/cast.h>
-#include <array>
-
+#include <array>
+
using namespace NYql;
namespace NSQLTranslationV1 {
@@ -69,7 +69,7 @@ protected:
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -80,7 +80,7 @@ protected:
return true;
}
-
+
TNodePtr AggregationTraitsFactory() const override {
return Factory;
}
@@ -104,7 +104,7 @@ protected:
if (!Expr->Init(ctx, src)) {
return false;
- }
+ }
if (Expr->IsAggregated() && !Expr->IsAggregationKey() && !IsOverWindow()) {
ctx.Error(Pos) << "Aggregation of aggregated values is forbidden for no window functions";
return false;
@@ -130,7 +130,7 @@ protected:
return false;
}
Expr = AstNode("row");
- }
+ }
if (FakeSource) {
if (!Factory->Init(ctx, FakeSource.Get())) {
@@ -154,7 +154,7 @@ protected:
return true;
}
-
+
TNodePtr Factory;
TNodePtr Expr;
bool Multi;
@@ -163,7 +163,7 @@ private:
TSourcePtr FakeSource;
bool DynamicFactory;
};
-
+
class TAggregationFactoryImpl final : public TAggregationFactory {
public:
TAggregationFactoryImpl(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode, bool multi)
@@ -179,13 +179,13 @@ private:
TAggregationPtr BuildFactoryAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode, bool multi) {
return new TAggregationFactoryImpl(pos, name, func, aggMode, multi);
}
-
+
class TKeyPayloadAggregationFactory final : public TAggregationFactory {
public:
TKeyPayloadAggregationFactory(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode)
: TAggregationFactory(pos, name, factory, aggMode)
{}
-
+
private:
bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) final {
ui32 adjustArgsCount = isFactory ? 0 : 2;
@@ -193,16 +193,16 @@ private:
ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name << " requires "
<< adjustArgsCount << " or " << (1 + adjustArgsCount) << " arguments, given: " << exprs.size();
return false;
- }
+ }
if (BlockWindowAggregationWithoutFrameSpec(Pos, GetName(), src, ctx)) {
return false;
}
-
+
if (!isFactory) {
Payload = exprs.front();
Key = exprs[1];
}
-
+
if (1 + adjustArgsCount == exprs.size()) {
Limit = exprs.back();
Func += "2";
@@ -220,7 +220,7 @@ private:
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -231,11 +231,11 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TKeyPayloadAggregationFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Key), BuildLambda(Pos, Y("row"), Payload));
AddFactoryArguments(apply);
@@ -274,8 +274,8 @@ private:
return false;
}
return true;
- }
-
+ }
+
TNodePtr Key, Payload, Limit;
};
@@ -296,7 +296,7 @@ private:
ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name << " requires " <<
adjustArgsCount << "arguments, given: " << exprs.size();
return false;
- }
+ }
if (BlockWindowAggregationWithoutFrameSpec(Pos, GetName(), src, ctx)) {
return false;
@@ -310,7 +310,7 @@ private:
if (!Init(ctx, src)) {
return false;
- }
+ }
if (!isFactory) {
node.Add("Member", "row", Q(Name));
@@ -321,15 +321,15 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TPayloadPredicateAggregationFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
return Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Payload), BuildLambda(Pos, Y("row"), Predicate));
}
-
+
std::vector<ui32> GetFactoryColumnIndices() const final {
return {0u, 1u};
}
@@ -427,7 +427,7 @@ private:
}
return true;
}
-
+
TNodePtr One, Two;
};
@@ -456,7 +456,7 @@ private:
ctx.Error(Pos) << "Aggregation function " << Name << " requires one, two or three arguments, given: " << exprs.size();
return false;
}
- }
+ }
if (!isFactory) {
/// \todo: solve it with named arguments
@@ -488,21 +488,21 @@ private:
Intervals = Y("Cast", exprs.back(), Q("Uint32"));
}
- }
-
+ }
+
return TAggregationFactory::InitAggr(ctx, isFactory, src, node, isFactory ? TVector<TNodePtr>() : TVector<TNodePtr>(1, exprs.front()));
}
TNodePtr DoClone() const final {
return new THistogramAggregationFactory(Pos, Name, Func, AggMode);
- }
-
+ }
+
TNodePtr GetApply(const TNodePtr& type) const final {
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), BuildLambda(Pos, Y("row"), Weight));
AddFactoryArguments(apply);
return apply;
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, Intervals);
}
@@ -518,7 +518,7 @@ private:
if (!Intervals->Init(ctx, FakeSource.Get())) {
return false;
}
-
+
return TAggregationFactory::DoInit(ctx, src);
}
@@ -611,7 +611,7 @@ public:
: TAggregationFactory(pos, name, factory, aggMode)
, FakeSource(BuildFakeSource(pos))
{}
-
+
private:
const TString* GetGenericKey() const final {
return Column;
@@ -654,7 +654,7 @@ private:
} else {
x = Y("Double", Q("0.5"));
}
-
+
if (isFactory) {
FactoryPercentile = x;
} else {
@@ -663,7 +663,7 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TPercentileFactory(Pos, Name, Func, AggMode);
}
@@ -677,11 +677,11 @@ private:
percentiles = L(percentiles, percentile.second);
}
percentiles = Q(percentiles);
- }
-
+ }
+
return Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), percentiles);
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, FactoryPercentile);
}
@@ -689,7 +689,7 @@ private:
TNodePtr AggregationTraits(const TNodePtr& type) const final {
if (Percentiles.empty())
return TNodePtr();
-
+
TNodePtr names(Q(Percentiles.cbegin()->first));
if (Percentiles.size() > 1U) {
@@ -708,18 +708,18 @@ private:
for (const auto& p : Percentiles) {
if (!p.second->Init(ctx, src)) {
return false;
- }
- }
-
+ }
+ }
+
return TAggregationFactory::DoInit(ctx, src);
- }
-
+ }
+
TSourcePtr FakeSource;
std::multimap<TString, TNodePtr> Percentiles;
TNodePtr FactoryPercentile;
const TString* Column = nullptr;
};
-
+
TAggregationPtr BuildPercentileFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TPercentileFactory(pos, name, factory, aggMode);
}
@@ -740,7 +740,7 @@ private:
ui32 adjustArgsCount = isFactory ? 0 : 1;
const double DefaultBufferC = 1.5;
const ui32 MinBuffer = 100;
-
+
if (exprs.size() < adjustArgsCount || exprs.size() > 2 + adjustArgsCount) {
ctx.Error(Pos) << "Aggregation function " << (isFactory? "factory " : "") << Name <<
" requires " << adjustArgsCount << " to " << (2 + adjustArgsCount) << " arguments, given: " << exprs.size();
@@ -784,11 +784,11 @@ private:
return true;
}
-
+
TNodePtr DoClone() const final {
return new TTopFreqFactory(Pos, Name, Func, AggMode);
}
-
+
TNodePtr GetApply(const TNodePtr& type) const final {
TPair topFreqs(TopFreqs.cbegin()->second);
@@ -796,14 +796,14 @@ private:
topFreqs = { Y(), Y() };
for (const auto& topFreq : TopFreqs) {
topFreqs = { L(topFreqs.first, topFreq.second.first), L(topFreqs.second, topFreq.second.second) };
- }
+ }
topFreqs = { Q(topFreqs.first), Q(topFreqs.second) };
- }
-
+ }
+
auto apply = Y("Apply", Factory, type, BuildLambda(Pos, Y("row"), Expr), topFreqs.first, topFreqs.second);
return apply;
}
-
+
void AddFactoryArguments(TNodePtr& apply) const final {
apply = L(apply, TopFreqFactoryParams.first, TopFreqFactoryParams.second);
}
@@ -811,21 +811,21 @@ private:
TNodePtr AggregationTraits(const TNodePtr& type) const final {
if (TopFreqs.empty())
return TNodePtr();
-
+
TNodePtr names(Q(TopFreqs.cbegin()->first));
-
+
if (TopFreqs.size() > 1U) {
names = Y();
for (const auto& topFreq : TopFreqs)
names = L(names, Q(topFreq.first));
names = Q(names);
- }
-
+ }
+
const bool distinct = AggMode == EAggregateMode::Distinct;
const auto listType = distinct ? Y("ListType", Y("StructMemberType", Y("ListItemType", type), BuildQuotedAtom(Pos, DistinctKey))) : type;
return distinct ? Q(Y(names, GetApply(listType), BuildQuotedAtom(Pos, DistinctKey))) : Q(Y(names, GetApply(listType)));
}
-
+
bool DoInit(TContext& ctx, ISource* src) final {
for (const auto& topFreq : TopFreqs) {
if (!topFreq.second.first->Init(ctx, src)) {
@@ -835,11 +835,11 @@ private:
if (!topFreq.second.second->Init(ctx, src)) {
return false;
}
- }
-
+ }
+
return TAggregationFactory::DoInit(ctx, src);
- }
-
+ }
+
std::multimap<TString, TPair> TopFreqs;
TPair TopFreqFactoryParams;
TSourcePtr FakeSource;
@@ -848,7 +848,7 @@ private:
TAggregationPtr BuildTopFreqFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TTopFreqFactory(pos, name, factory, aggMode);
}
-
+
template <bool HasKey>
class TTopAggregationFactory final : public TAggregationFactory {
public:
@@ -1114,7 +1114,7 @@ public:
TUserDefinedAggregationFactory(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode)
: TAggregationFactory(pos, name, factory, aggMode)
{}
-
+
private:
bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) final {
ui32 adjustArgsCount = isFactory ? 0 : 1;
@@ -1123,7 +1123,7 @@ private:
(3 + adjustArgsCount) << " to " << (7 + adjustArgsCount) << " arguments, given: " << exprs.size();
return false;
}
-
+
Lambdas[0] = BuildLambda(Pos, Y("value", "parent"), Y("NamedApply", exprs[adjustArgsCount], Q(Y("value")), Y("AsStruct"), Y("DependsOn", "parent")));
Lambdas[1] = BuildLambda(Pos, Y("value", "state", "parent"), Y("NamedApply", exprs[adjustArgsCount + 1], Q(Y("state", "value")), Y("AsStruct"), Y("DependsOn", "parent")));
Lambdas[2] = BuildLambda(Pos, Y("one", "two"), Y("Apply", exprs[adjustArgsCount + 2], "one", "two"));
@@ -1172,18 +1172,18 @@ private:
TAggregationPtr BuildUserDefinedFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode) {
return new TUserDefinedAggregationFactory(pos, name, factory, aggMode);
}
-
+
class TCountAggregation final : public TAggregationFactory {
public:
TCountAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode)
: TAggregationFactory(pos, name, func, aggMode)
{}
-
+
private:
TNodePtr DoClone() const final {
return new TCountAggregation(Pos, Name, Func, AggMode);
}
-
+
bool DoInit(TContext& ctx, ISource* src) final {
if (!Expr) {
return true;
diff --git a/ydb/library/yql/sql/v1/builtin.cpp b/ydb/library/yql/sql/v1/builtin.cpp
index 24db25a8ba..43ef1243f1 100644
--- a/ydb/library/yql/sql/v1/builtin.cpp
+++ b/ydb/library/yql/sql/v1/builtin.cpp
@@ -58,7 +58,7 @@ public:
, Args(args)
{}
- bool DoInit(TContext& ctx, ISource* src) final {
+ bool DoInit(TContext& ctx, ISource* src) final {
if (!src) {
ctx.Error(Pos) << "Grouping function should have source";
return false;
@@ -96,7 +96,7 @@ public:
return TAstListNode::DoInit(ctx, src);
}
- TNodePtr DoClone() const final {
+ TNodePtr DoClone() const final {
return new TGroupingNode(Pos, Args);
}
@@ -104,7 +104,7 @@ private:
const TVector<TNodePtr> Args;
};
-class TBasicAggrFunc final: public TAstListNode {
+class TBasicAggrFunc final: public TAstListNode {
public:
TBasicAggrFunc(TPosition pos, const TString& name, TAggregationPtr aggr, const TVector<TNodePtr>& args)
: TAstListNode(pos)
@@ -117,7 +117,7 @@ public:
return Name;
}
- bool DoInit(TContext& ctx, ISource* src) final {
+ bool DoInit(TContext& ctx, ISource* src) final {
if (!src) {
ctx.Error(Pos) << "Unable to use aggregation function '" << Name << "' without data source";
return false;
@@ -158,7 +158,7 @@ public:
Aggr->MarkKeyColumnAsGenerated();
}
- TNodePtr DoClone() const final {
+ TNodePtr DoClone() const final {
TAggregationPtr aggrClone = static_cast<IAggregation*>(Aggr->Clone().Release());
return new TBasicAggrFunc(Pos, Name, aggrClone, CloneContainer(Args));
}
@@ -168,7 +168,7 @@ public:
}
private:
- bool DoInitAggregation(TContext& ctx, ISource* src) {
+ bool DoInitAggregation(TContext& ctx, ISource* src) {
if (PreaggregateExpr) {
YQL_ENSURE(PreaggregateExpr->HasState(ENodeState::Initialized));
if (PreaggregateExpr->IsAggregated() && !PreaggregateExpr->IsAggregationKey() && !Aggr->IsOverWindow()) {
@@ -183,7 +183,7 @@ private:
return src->AddAggregation(ctx, Aggr);
}
- void DoUpdateState() const final {
+ void DoUpdateState() const final {
State.Set(ENodeState::Const, !Args.empty() && AllOf(Args, [](const auto& arg){ return arg->IsConstant(); }));
State.Set(ENodeState::Aggregated);
}
@@ -332,15 +332,15 @@ public:
bool DoInit(TContext& ctx, ISource* src) override {
auto slot = NUdf::FindDataSlot(GetOpName());
- if (!slot) {
- ctx.Error(Pos) << "Unexpected type " << GetOpName();
- return false;
- }
-
+ if (!slot) {
+ ctx.Error(Pos) << "Unexpected type " << GetOpName();
+ return false;
+ }
+
if (*slot == NUdf::EDataSlot::Decimal) {
- MinArgs = MaxArgs = 3;
- }
-
+ MinArgs = MaxArgs = 3;
+ }
+
if (!ValidateArguments(ctx)) {
return false;
}
@@ -354,32 +354,32 @@ public:
TString value;
if (*slot == NUdf::EDataSlot::Decimal) {
- const auto precision = Args[1]->GetLiteral("Int32");
- const auto scale = Args[2]->GetLiteral("Int32");
-
- if (!NKikimr::NMiniKQL::IsValidDecimal(*atom)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
-
- ui8 stub;
- if (!(precision && TryFromString<ui8>(*precision, stub))) {
- ctx.Error(Pos) << "Invalid precision " << (precision ? precision->Quote() : "") << " for type " << GetOpName();
- return false;
- }
-
- if (!(scale && TryFromString<ui8>(*scale, stub))) {
- ctx.Error(Pos) << "Invalid scale " << (scale ? scale->Quote() : "") << " for type " << GetOpName();
- return false;
- }
-
- Args[0] = BuildQuotedAtom(GetPos(), *atom);
- Args[1] = BuildQuotedAtom(GetPos(), *precision);
- Args[2] = BuildQuotedAtom(GetPos(), *scale);
- return TCallNode::DoInit(ctx, src);
+ const auto precision = Args[1]->GetLiteral("Int32");
+ const auto scale = Args[2]->GetLiteral("Int32");
+
+ if (!NKikimr::NMiniKQL::IsValidDecimal(*atom)) {
+ ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
+ return false;
+ }
+
+ ui8 stub;
+ if (!(precision && TryFromString<ui8>(*precision, stub))) {
+ ctx.Error(Pos) << "Invalid precision " << (precision ? precision->Quote() : "") << " for type " << GetOpName();
+ return false;
+ }
+
+ if (!(scale && TryFromString<ui8>(*scale, stub))) {
+ ctx.Error(Pos) << "Invalid scale " << (scale ? scale->Quote() : "") << " for type " << GetOpName();
+ return false;
+ }
+
+ Args[0] = BuildQuotedAtom(GetPos(), *atom);
+ Args[1] = BuildQuotedAtom(GetPos(), *precision);
+ Args[2] = BuildQuotedAtom(GetPos(), *scale);
+ return TCallNode::DoInit(ctx, src);
} else if (NUdf::GetDataTypeInfo(*slot).Features & (NUdf::DateType | NUdf::TzDateType | NUdf::TimeIntervalType)) {
- const auto out = NKikimr::NMiniKQL::ValueFromString(*slot, *atom);
- if (!out) {
+ const auto out = NKikimr::NMiniKQL::ValueFromString(*slot, *atom);
+ if (!out) {
ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
return false;
}
@@ -387,46 +387,46 @@ public:
switch (*slot) {
case NUdf::EDataSlot::Date:
case NUdf::EDataSlot::TzDate:
- value = ToString(out.Get<ui16>());
+ value = ToString(out.Get<ui16>());
break;
case NUdf::EDataSlot::Datetime:
case NUdf::EDataSlot::TzDatetime:
- value = ToString(out.Get<ui32>());
+ value = ToString(out.Get<ui32>());
break;
case NUdf::EDataSlot::Timestamp:
case NUdf::EDataSlot::TzTimestamp:
- value = ToString(out.Get<ui64>());
+ value = ToString(out.Get<ui64>());
break;
case NUdf::EDataSlot::Interval:
- value = ToString(out.Get<i64>());
- if ('T' == atom->back()) {
- ctx.Error(Pos) << "Time prefix 'T' at end of interval constant. The designator 'T' shall be absent if all of the time components are absent.";
- return false;
- }
- break;
+ value = ToString(out.Get<i64>());
+ if ('T' == atom->back()) {
+ ctx.Error(Pos) << "Time prefix 'T' at end of interval constant. The designator 'T' shall be absent if all of the time components are absent.";
+ return false;
+ }
+ break;
default:
Y_FAIL("Unexpected data slot");
}
if (NUdf::GetDataTypeInfo(*slot).Features & NUdf::TzDateType) {
- value += ",";
- value += NKikimr::NMiniKQL::GetTimezoneIANAName(out.GetTimezoneId());
- }
+ value += ",";
+ value += NKikimr::NMiniKQL::GetTimezoneIANAName(out.GetTimezoneId());
+ }
} else if (NUdf::EDataSlot::Uuid == *slot) {
- char out[0x10];
- if (!NKikimr::NMiniKQL::ParseUuid(*atom, out)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
-
- value.assign(out, sizeof(out));
+ char out[0x10];
+ if (!NKikimr::NMiniKQL::ParseUuid(*atom, out)) {
+ ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
+ return false;
+ }
+
+ value.assign(out, sizeof(out));
} else {
- if (!NKikimr::NMiniKQL::IsValidStringValue(*slot, *atom)) {
+ if (!NKikimr::NMiniKQL::IsValidStringValue(*slot, *atom)) {
ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
return false;
}
- value = *atom;
+ value = *atom;
}
Args[0] = BuildQuotedAtom(GetPos(), value);
@@ -983,15 +983,15 @@ TString NormalizeTypeString(const TString& str) {
if (ret.StartsWith("Json")) {
ret = "Json" + to_title(ret.substr(4));
}
- if (ret.StartsWith("Dy")) {
- ret = "Dy" + to_title(ret.substr(2));
- }
+ if (ret.StartsWith("Dy")) {
+ ret = "Dy" + to_title(ret.substr(2));
+ }
return ret;
}
static const TSet<TString> AvailableDataTypes = {"Bool", "String", "Uint32", "Uint64", "Int32", "Int64", "Float", "Double", "Utf8", "Yson", "Json", "JsonDocument",
- "Date", "Datetime", "Timestamp", "Interval", "Uint8", "Int8", "Uint16", "Int16", "TzDate", "TzDatetime", "TzTimestamp", "Uuid", "Decimal", "DyNumber"};
+ "Date", "Datetime", "Timestamp", "Interval", "Uint8", "Int8", "Uint16", "Int16", "TzDate", "TzDatetime", "TzTimestamp", "Uuid", "Decimal", "DyNumber"};
TNodePtr GetDataTypeStringNode(TContext& ctx, TCallNode& node, unsigned argNum, TString* outTypeStrPtr = nullptr) {
auto errMsgFunc = [&node, argNum]() {
static std::array<TString, 2> numToName = {{"first", "second"}};
@@ -1304,18 +1304,18 @@ private:
class TYqlSubstring final: public TCallNode {
public:
- TYqlSubstring(TPosition pos, const TString& name, const TVector<TNodePtr>& args)
- : TCallNode(pos, name, 2, 3, args)
+ TYqlSubstring(TPosition pos, const TString& name, const TVector<TNodePtr>& args)
+ : TCallNode(pos, name, 2, 3, args)
{}
private:
TCallNode::TPtr DoClone() const override {
- return new TYqlSubstring(GetPos(), OpName, CloneContainer(Args));
+ return new TYqlSubstring(GetPos(), OpName, CloneContainer(Args));
}
bool DoInit(TContext& ctx, ISource* src) override {
if (Args.size() == 2) {
- Args.push_back(Y("Null"));
+ Args.push_back(Y("Null"));
}
return TCallNode::DoInit(ctx, src);
}
@@ -2006,7 +2006,7 @@ public:
}
const TString yql("(" + parsedName->Content + ")");
- TAstParseResult ast = ParseAst(yql, ctx.Pool.get());
+ TAstParseResult ast = ParseAst(yql, ctx.Pool.get());
/// TODO: do not drop warnings
if (ast.IsOk()) {
const auto rootCount = ast.Root->GetChildrenCount();
@@ -2039,9 +2039,9 @@ public:
}
}
- if ("Datetime" == Module || ("Yson" == Module && ctx.PragmaYsonFast))
- Module.append('2');
-
+ if ("Datetime" == Module || ("Yson" == Module && ctx.PragmaYsonFast))
+ Module.append('2');
+
TMaybe<TString> typeConfig = MakeTypeConfig(to_lower(Module), Args);
if (ForReduce) {
TVector<TNodePtr> udfArgs;
@@ -2411,14 +2411,14 @@ TBuiltinFactoryCallback BuildNamedBuiltinFactoryCallback(const TString& name) {
return new TType(pos, name, args);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildArgcBuiltinFactoryCallback(i32 minArgs, i32 maxArgs) {
return [minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
return new TType(pos, minArgs, maxArgs, args);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildNamedArgcBuiltinFactoryCallback(const TString& name, i32 minArgs, i32 maxArgs) {
return [name, minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
@@ -2439,14 +2439,14 @@ TBuiltinFactoryCallback BuildBoolBuiltinFactoryCallback(bool arg) {
return new TType(pos, args, arg);
};
}
-
+
template<typename TType>
TBuiltinFactoryCallback BuildFoldBuiltinFactoryCallback(const TString& name, const TString& defaultValue) {
return [name, defaultValue] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
return new TType(pos, name, "Bool", defaultValue, 1, args);
};
}
-
+
TNodePtr MakePair(TPosition pos, const TVector<TNodePtr>& args) {
TNodePtr list = new TAstListNodeImpl(pos, {
args[0],
@@ -2482,13 +2482,13 @@ struct TBuiltinFuncData {
{"length", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
{"charlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
{"characterlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
- {"substring", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Substring")},
- {"find", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Find")},
- {"rfind", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("RFind")},
+ {"substring", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Substring")},
+ {"find", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Find")},
+ {"rfind", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("RFind")},
{"byteat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ByteAt", 2, 2) },
- {"startswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StartsWith", 2, 2)},
- {"endswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EndsWith", 2, 2)},
-
+ {"startswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StartsWith", 2, 2)},
+ {"endswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EndsWith", 2, 2)},
+
// Numeric builtins
{"abs", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Abs", 1, 1) },
{"tobytes", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ToBytes", 1, 1) },
@@ -2509,38 +2509,38 @@ struct TBuiltinFuncData {
{"listextend", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListExtend", 0, -1)},
{"listextendstrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListExtendStrict", 0, -1)},
{"listunionall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListUnionAll", 0, -1) },
- {"listzip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZip", -1, -1)},
- {"listzipall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZipAll", -1, -1)},
- {"listenumerate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListEnumerate", 1, 3)},
- {"listreverse", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListReverse", 1, 1)},
- {"listskip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSkip", 2, 2)},
- {"listtake", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTake", 2, 2)},
- {"listhead", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHead", 1, 1)},
- {"listlast", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListLast", 1, 1)},
+ {"listzip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZip", -1, -1)},
+ {"listzipall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZipAll", -1, -1)},
+ {"listenumerate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListEnumerate", 1, 3)},
+ {"listreverse", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListReverse", 1, 1)},
+ {"listskip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSkip", 2, 2)},
+ {"listtake", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTake", 2, 2)},
+ {"listhead", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHead", 1, 1)},
+ {"listlast", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListLast", 1, 1)},
{"listsort", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(true)},
{"listsortasc", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(true)},
{"listsortdesc", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(false)},
{"listmap", BuildBoolBuiltinFactoryCallback<TListMapBuiltin>(false)},
{"listflatmap", BuildBoolBuiltinFactoryCallback<TListMapBuiltin>(true)},
- {"listfilter", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListFilter")},
- {"listany", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAny", 1, 1)},
- {"listall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAll", 1, 1)},
- {"listhas", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHas", 2, 2)},
- {"listmax", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMax", 1, 1)},
- {"listmin", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMin", 1, 1)},
- {"listsum", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSum", 1, 1)},
- {"listavg", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAvg", 1, 1)},
- {"listconcat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListConcat", 1, 2)},
+ {"listfilter", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListFilter")},
+ {"listany", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAny", 1, 1)},
+ {"listall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAll", 1, 1)},
+ {"listhas", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHas", 2, 2)},
+ {"listmax", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMax", 1, 1)},
+ {"listmin", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMin", 1, 1)},
+ {"listsum", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSum", 1, 1)},
+ {"listavg", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAvg", 1, 1)},
+ {"listconcat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListConcat", 1, 2)},
{"listextract", BuildSimpleBuiltinFactoryCallback<TListExtractBuiltin>()},
{"listuniq", BuildSimpleBuiltinFactoryCallback<TListUniqBuiltin>()},
{"listcreate", BuildSimpleBuiltinFactoryCallback<TListCreateBuiltin>()},
{"listfromrange", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFromRange", 2, 3) },
- {"listreplicate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Replicate", 2, 2) },
- {"listtakewhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhile") },
- {"listskipwhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhile") },
- {"listtakewhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhileInclusive") },
- {"listskipwhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhileInclusive") },
- {"listcollect", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListCollect", 1, 1) },
+ {"listreplicate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Replicate", 2, 2) },
+ {"listtakewhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhile") },
+ {"listskipwhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhile") },
+ {"listtakewhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhileInclusive") },
+ {"listskipwhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhileInclusive") },
+ {"listcollect", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListCollect", 1, 1) },
{"listnotnull", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListNotNull", 1, 1)},
{"listflatten", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFlatten", 1, 1)},
@@ -2773,8 +2773,8 @@ struct TBuiltinFuncData {
{"aggrlistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
{"aggregatelistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
- {"median", BuildAggrFuncFactoryCallback("Median", "percentile_traits_factory", PERCENTILE)},
- {"percentile", BuildAggrFuncFactoryCallback("Percentile", "percentile_traits_factory", PERCENTILE)},
+ {"median", BuildAggrFuncFactoryCallback("Median", "percentile_traits_factory", PERCENTILE)},
+ {"percentile", BuildAggrFuncFactoryCallback("Percentile", "percentile_traits_factory", PERCENTILE)},
{"mode", BuildAggrFuncFactoryCallback("Mode", "topfreq_traits_factory", TOPFREQ) },
{"topfreq", BuildAggrFuncFactoryCallback("TopFreq", "topfreq_traits_factory", TOPFREQ) },
@@ -3234,45 +3234,45 @@ TNodePtr BuildBuiltinFunc(TContext& ctx, TPosition pos, TString name, const TVec
name = "ParseJson";
}
}
-
- if (ctx.PragmaYsonFast && ns == "yson") {
- ns.append('2');
- nameSpace.append('2');
- }
-
- if (ns.StartsWith("yson")) {
+
+ if (ctx.PragmaYsonFast && ns == "yson") {
+ ns.append('2');
+ nameSpace.append('2');
+ }
+
+ if (ns.StartsWith("yson")) {
if (name == "ConvertTo" && usedArgs.size() > 1) {
customUserType = usedArgs[1];
usedArgs.erase(usedArgs.begin() + 1);
}
-
- if (name == "Serialize") {
- if (usedArgs) {
- usedArgs.resize(1U);
- }
- } else if (ctx.PragmaYsonFast && name == "SerializeJsonEncodeUtf8") {
- name = "SerializeJson";
- if (usedArgs.size() < 2U) {
- usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
- positionalArgs = BuildTuple(pos, usedArgs);
+
+ if (name == "Serialize") {
+ if (usedArgs) {
+ usedArgs.resize(1U);
+ }
+ } else if (ctx.PragmaYsonFast && name == "SerializeJsonEncodeUtf8") {
+ name = "SerializeJson";
+ if (usedArgs.size() < 2U) {
+ usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
+ }
+ positionalArgs = BuildTuple(pos, usedArgs);
auto encodeUtf8 = BuildLiteralBool(pos, true);
- encodeUtf8->SetLabel("EncodeUtf8");
- namedArgs = BuildStructure(pos, {encodeUtf8});
- usedArgs = {positionalArgs, namedArgs};
- } else if (name.StartsWith("From")) {
+ encodeUtf8->SetLabel("EncodeUtf8");
+ namedArgs = BuildStructure(pos, {encodeUtf8});
+ usedArgs = {positionalArgs, namedArgs};
+ } else if (name.StartsWith("From")) {
if (usedArgs) {
usedArgs.resize(1U);
}
- name = "From";
- } else if (name == "GetLength" || name.StartsWith("ConvertTo") || name.StartsWith("Parse") || name.StartsWith("SerializeJson")) {
- if (usedArgs.size() < 2U) {
- usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
- } else if (name == "Contains" || name.StartsWith("Lookup") || name.StartsWith("YPath")) {
- if (usedArgs.size() < 3U) {
- usedArgs.push_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
+ name = "From";
+ } else if (name == "GetLength" || name.StartsWith("ConvertTo") || name.StartsWith("Parse") || name.StartsWith("SerializeJson")) {
+ if (usedArgs.size() < 2U) {
+ usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
+ }
+ } else if (name == "Contains" || name.StartsWith("Lookup") || name.StartsWith("YPath")) {
+ if (usedArgs.size() < 3U) {
+ usedArgs.push_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
+ }
}
}
diff --git a/ydb/library/yql/sql/v1/context.cpp b/ydb/library/yql/sql/v1/context.cpp
index dfec03740a..c08fe96cae 100644
--- a/ydb/library/yql/sql/v1/context.cpp
+++ b/ydb/library/yql/sql/v1/context.cpp
@@ -46,7 +46,7 @@ THashMap<TStringBuf, TPragmaField> CTX_PRAGMA_FIELDS = {
{"WarnOnAnsiAliasShadowing", &TContext::WarnOnAnsiAliasShadowing},
{"PullUpFlatMapOverJoin", &TContext::PragmaPullUpFlatMapOverJoin},
{"DqEngineEnable", &TContext::DqEngineEnable},
- {"DqEngineForce", &TContext::DqEngineForce},
+ {"DqEngineForce", &TContext::DqEngineForce},
{"RegexUseRe2", &TContext::PragmaRegexUseRe2},
{"OrderedColumns", &TContext::OrderedColumns},
{"BogousStarInGroupByOverJoin", &TContext::BogousStarInGroupByOverJoin},
diff --git a/ydb/library/yql/sql/v1/context.h b/ydb/library/yql/sql/v1/context.h
index 70dc79e755..8951757486 100644
--- a/ydb/library/yql/sql/v1/context.h
+++ b/ydb/library/yql/sql/v1/context.h
@@ -203,7 +203,7 @@ namespace NSQLTranslationV1 {
public:
THashMap<TString, TNodePtr> Variables;
NSQLTranslation::TTranslationSettings Settings;
- std::unique_ptr<TMemoryPool> Pool;
+ std::unique_ptr<TMemoryPool> Pool;
NYql::TIssues& Issues;
TMap<TString, TNodePtr> UniversalAliases;
THashSet<TString> Exports;
@@ -226,10 +226,10 @@ namespace NSQLTranslationV1 {
bool SimpleColumns = true;
bool CoalesceJoinKeysOnQualifiedAll = false;
bool PragmaDirectRead = false;
- bool PragmaYsonFast = true;
+ bool PragmaYsonFast = true;
bool PragmaYsonAutoConvert = false;
bool PragmaYsonStrict = true;
- bool PragmaRegexUseRe2 = true;
+ bool PragmaRegexUseRe2 = true;
bool PragmaPullUpFlatMapOverJoin = true;
bool WarnUnnamedColumns = false;
bool DiscoveryMode = false;
diff --git a/ydb/library/yql/sql/v1/list_builtin.cpp b/ydb/library/yql/sql/v1/list_builtin.cpp
index 001eb36757..bc4edc2e4c 100644
--- a/ydb/library/yql/sql/v1/list_builtin.cpp
+++ b/ydb/library/yql/sql/v1/list_builtin.cpp
@@ -15,7 +15,7 @@ TNodePtr TListBuiltin::GetIdentityLambda() {
bool TListSortBuiltin::DoInit(TContext& ctx, ISource* src) {
if (Args.size() < 1 || Args.size() > 2) {
- ctx.Error(Pos) << OpName << " requires one or two parameters.";
+ ctx.Error(Pos) << OpName << " requires one or two parameters.";
return false;
}
if (!Args[0]->Init(ctx, src)) {
@@ -34,7 +34,7 @@ bool TListSortBuiltin::DoInit(TContext& ctx, ISource* src) {
bool TListExtractBuiltin::DoInit(TContext& ctx, ISource* src) {
if (Args.size() != 2) {
- ctx.Error(Pos) << OpName << " requires exactly two parameters.";
+ ctx.Error(Pos) << OpName << " requires exactly two parameters.";
return false;
}
@@ -77,7 +77,7 @@ bool TListFilterBuiltin::DoInit(TContext& ctx, ISource* src) {
if (!CheckArgs(ctx, src)) {
return false;
};
- Node = Y(OpName, Args[0], GetFilterLambda());
+ Node = Y(OpName, Args[0], GetFilterLambda());
return true;
}
@@ -93,7 +93,7 @@ bool TListUniqBuiltin::DoInit(TContext& ctx, ISource* src) {
if (!Args[0]->Init(ctx, src)) {
return false;
}
- Node = Y("DictKeys", Y("ToDict", Args[0], GetIdentityLambda(), BuildLambda(Pos, Y("item"), Y("Void")), Q(Y(Q("Hashed"), Q("One")))));
+ Node = Y("DictKeys", Y("ToDict", Args[0], GetIdentityLambda(), BuildLambda(Pos, Y("item"), Y("Void")), Q(Y(Q("Hashed"), Q("One")))));
return true;
}
diff --git a/ydb/library/yql/sql/v1/list_builtin.h b/ydb/library/yql/sql/v1/list_builtin.h
index c540264c34..a8077b464a 100644
--- a/ydb/library/yql/sql/v1/list_builtin.h
+++ b/ydb/library/yql/sql/v1/list_builtin.h
@@ -39,7 +39,7 @@ protected:
class TListSortBuiltin final: public TListBuiltin {
public:
TListSortBuiltin(TPosition pos, const TVector<TNodePtr>& args, bool asc)
- : TListBuiltin(pos, "ListSort", args)
+ : TListBuiltin(pos, "ListSort", args)
, Asc(asc)
{}
@@ -50,13 +50,13 @@ public:
}
private:
- const bool Asc;
+ const bool Asc;
};
class TListExtractBuiltin final: public TListBuiltin {
public:
TListExtractBuiltin(TPosition pos, const TVector<TNodePtr>& args)
- : TListBuiltin(pos, "ListExtract", args)
+ : TListBuiltin(pos, "ListExtract", args)
{}
bool DoInit(TContext& ctx, ISource* src) override;
@@ -97,16 +97,16 @@ private:
class TListFilterBuiltin final: public TListProcessBuiltin {
public:
- TListFilterBuiltin(TPosition pos, const TString& opName,
+ TListFilterBuiltin(TPosition pos, const TString& opName,
const TVector<TNodePtr>& args)
- : TListProcessBuiltin(pos, opName, args)
+ : TListProcessBuiltin(pos, opName, args)
{}
bool DoInit(TContext& ctx, ISource* src) override;
TNodePtr DoClone() const final {
- return new TListFilterBuiltin(Pos, OpName, CloneContainer(Args));
+ return new TListFilterBuiltin(Pos, OpName, CloneContainer(Args));
}
protected:
virtual TNodePtr GetFilterLambda();
diff --git a/ydb/library/yql/sql/v1/node.cpp b/ydb/library/yql/sql/v1/node.cpp
index 711177dca6..870bbd9cc7 100644
--- a/ydb/library/yql/sql/v1/node.cpp
+++ b/ydb/library/yql/sql/v1/node.cpp
@@ -222,11 +222,11 @@ bool INode::DoInit(TContext& ctx, ISource* src) {
return true;
}
-TNodePtr INode::AstNode() const {
+TNodePtr INode::AstNode() const {
return new TAstListNodeImpl(Pos);
}
-TNodePtr INode::AstNode(TNodePtr node) const {
+TNodePtr INode::AstNode(TNodePtr node) const {
return node;
}
@@ -234,7 +234,7 @@ TNodePtr INode::AstNode(const TString& str) const {
return new TAstAtomNodeImpl(Pos, str, TNodeFlags::Default);
}
-TNodePtr INode::AstNode(TAstNode* node) const {
+TNodePtr INode::AstNode(TAstNode* node) const {
return new TAstDirectNode(node);
}
@@ -612,8 +612,8 @@ bool TCallNode::DoInit(TContext& ctx, ISource* src) {
return false;
}
- Nodes.push_back(BuildAtom(Pos, OpName,
- OpName.cend() == std::find_if_not(OpName.cbegin(), OpName.cend(), [](char c) { return bool(std::isalnum(c)); }) ? TNodeFlags::Default : TNodeFlags::ArbitraryContent));
+ Nodes.push_back(BuildAtom(Pos, OpName,
+ OpName.cend() == std::find_if_not(OpName.cbegin(), OpName.cend(), [](char c) { return bool(std::isalnum(c)); }) ? TNodeFlags::Default : TNodeFlags::ArbitraryContent));
Nodes.insert(Nodes.end(), Args.begin(), Args.end());
return true;
}
@@ -1198,8 +1198,8 @@ TAstNode* ITableKeys::Translate(TContext& ctx) const {
return nullptr;
}
-bool IAggregation::IsDistinct() const {
- return !DistinctKey.empty();
+bool IAggregation::IsDistinct() const {
+ return !DistinctKey.empty();
}
void IAggregation::DoUpdateState() const {
@@ -1211,10 +1211,10 @@ const TString* IAggregation::GetGenericKey() const {
return nullptr;
}
-void IAggregation::Join(IAggregation*) {
- Y_VERIFY(false);
-}
-
+void IAggregation::Join(IAggregation*) {
+ Y_VERIFY(false);
+}
+
const TString& IAggregation::GetName() const {
return Name;
}
@@ -1229,7 +1229,7 @@ void IAggregation::MarkKeyColumnAsGenerated() {
IAggregation::IAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode)
: INode(pos), Name(name), Func(func), AggMode(aggMode)
-{}
+{}
TAstNode* IAggregation::Translate(TContext& ctx) const {
Y_VERIFY_DEBUG(false);
@@ -1241,8 +1241,8 @@ TNodePtr IAggregation::AggregationTraits(const TNodePtr& type) const {
const bool distinct = AggMode == EAggregateMode::Distinct;
const auto listType = distinct ? Y("ListType", Y("StructMemberType", Y("ListItemType", type), BuildQuotedAtom(Pos, DistinctKey))) : type;
return distinct ? Q(Y(Q(Name), GetApply(listType), BuildQuotedAtom(Pos, DistinctKey))): Q(Y(Q(Name), GetApply(listType)));
-}
-
+}
+
void IAggregation::AddFactoryArguments(TNodePtr& apply) const {
Y_UNUSED(apply);
}
@@ -1749,23 +1749,23 @@ TNodePtr ISource::BuildAggregation(const TString& label) {
}
std::map<std::pair<bool, TString>, std::vector<IAggregation*>> genericAggrs;
- for (const auto& aggr: Aggregations) {
- if (const auto key = aggr->GetGenericKey()) {
- genericAggrs[{aggr->IsDistinct(), *key}].emplace_back(aggr.Get());
+ for (const auto& aggr: Aggregations) {
+ if (const auto key = aggr->GetGenericKey()) {
+ genericAggrs[{aggr->IsDistinct(), *key}].emplace_back(aggr.Get());
}
}
- for (const auto& aggr : genericAggrs) {
- for (size_t i = 1U; i < aggr.second.size(); ++i) {
- aggr.second.front()->Join(aggr.second[i]);
+ for (const auto& aggr : genericAggrs) {
+ for (size_t i = 1U; i < aggr.second.size(); ++i) {
+ aggr.second.front()->Join(aggr.second[i]);
}
- }
+ }
- const auto listType = Y("TypeOf", label);
- auto aggrArgs = Y();
- for (const auto& aggr: Aggregations) {
+ const auto listType = Y("TypeOf", label);
+ auto aggrArgs = Y();
+ for (const auto& aggr: Aggregations) {
if (const auto traits = aggr->AggregationTraits(listType))
- aggrArgs = L(aggrArgs, traits);
+ aggrArgs = L(aggrArgs, traits);
}
auto options = Y();
@@ -2828,7 +2828,7 @@ public:
continue;
}
- if (ctx.PragmaYsonAutoConvert || ctx.PragmaYsonStrict || ctx.PragmaYsonFast) {
+ if (ctx.PragmaYsonAutoConvert || ctx.PragmaYsonStrict || ctx.PragmaYsonFast) {
auto ysonOptions = Y();
if (ctx.PragmaYsonAutoConvert) {
ysonOptions->Add(BuildQuotedAtom(Pos, "yson_auto_convert"));
@@ -2836,9 +2836,9 @@ public:
if (ctx.PragmaYsonStrict) {
ysonOptions->Add(BuildQuotedAtom(Pos, "yson_strict"));
}
- if (ctx.PragmaYsonFast) {
- ysonOptions->Add(BuildQuotedAtom(Pos, "yson_fast"));
- }
+ if (ctx.PragmaYsonFast) {
+ ysonOptions->Add(BuildQuotedAtom(Pos, "yson_fast"));
+ }
expr->Add(Q(ysonOptions));
}
}
@@ -3047,23 +3047,23 @@ bool ValidateAllNodesForAggregation(TContext& ctx, const TVector<TNodePtr>& node
return true;
}
-class TBindNode: public TAstListNode {
-public:
+class TBindNode: public TAstListNode {
+public:
TBindNode(TPosition pos, const TString& module, const TString& alias)
- : TAstListNode(pos)
- {
- Add("bind", AstNode(module), BuildQuotedAtom(pos, alias));
- }
+ : TAstListNode(pos)
+ {
+ Add("bind", AstNode(module), BuildQuotedAtom(pos, alias));
+ }
TPtr DoClone() const final {
return {};
}
-};
-
+};
+
TNodePtr BuildBind(TPosition pos, const TString& module, const TString& alias) {
- return new TBindNode(pos, module, alias);
-}
-
+ return new TBindNode(pos, module, alias);
+}
+
class TLambdaNode: public TAstListNode {
public:
TLambdaNode(TPosition pos, TNodePtr params, TNodePtr body, const TString& resName)
@@ -3089,8 +3089,8 @@ TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TStrin
return new TLambdaNode(pos, params, body, resName);
}
-TNodePtr BuildDataType(TPosition pos, const TString& typeName) {
- return new TCallNodeImpl(pos, "DataType", {BuildQuotedAtom(pos, typeName, TNodeFlags::Default)});
+TNodePtr BuildDataType(TPosition pos, const TString& typeName) {
+ return new TCallNodeImpl(pos, "DataType", {BuildQuotedAtom(pos, typeName, TNodeFlags::Default)});
}
TNodePtr BuildSimpleType(TContext& ctx, TPosition pos, const TString& typeName, bool dataOnly) {
@@ -3220,7 +3220,7 @@ TNodePtr BuildCalcOverWindow(TPosition pos, const TString& windowName, TNodePtr
return new TCalcOverWindow(pos, windowName, call);
}
-template<bool Fast>
+template<bool Fast>
class TYsonOptionsNode final: public INode {
public:
TYsonOptionsNode(TPosition pos, bool autoConvert, bool strict)
@@ -3228,7 +3228,7 @@ public:
, AutoConvert(autoConvert)
, Strict(strict)
{
- auto udf = Y("Udf", Q(Fast ? "Yson2.Options" : "Yson.Options"));
+ auto udf = Y("Udf", Q(Fast ? "Yson2.Options" : "Yson.Options"));
auto autoConvertNode = BuildLiteralBool(pos, autoConvert);
autoConvertNode->SetLabel("AutoConvert");
auto strictNode = BuildLiteralBool(pos, strict);
@@ -3261,11 +3261,11 @@ protected:
const bool Strict;
};
-TNodePtr BuildYsonOptionsNode(TPosition pos, bool autoConvert, bool strict, bool fastYson) {
- if (fastYson)
- return new TYsonOptionsNode<true>(pos, autoConvert, strict);
- else
- return new TYsonOptionsNode<false>(pos, autoConvert, strict);
+TNodePtr BuildYsonOptionsNode(TPosition pos, bool autoConvert, bool strict, bool fastYson) {
+ if (fastYson)
+ return new TYsonOptionsNode<true>(pos, autoConvert, strict);
+ else
+ return new TYsonOptionsNode<false>(pos, autoConvert, strict);
}
class TDoCall final : public INode {
diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h
index 588f79e248..de82b45a23 100644
--- a/ydb/library/yql/sql/v1/node.h
+++ b/ydb/library/yql/sql/v1/node.h
@@ -176,9 +176,9 @@ namespace NSQLTranslationV1 {
void VisitTree(const TVisitFunc& func) const;
void VisitTree(const TVisitFunc& func, TVisitNodeSet& visited) const;
- TPtr AstNode() const;
- TPtr AstNode(TAstNode* node) const;
- TPtr AstNode(TPtr node) const;
+ TPtr AstNode() const;
+ TPtr AstNode(TAstNode* node) const;
+ TPtr AstNode(TPtr node) const;
TPtr AstNode(const TString& str) const;
template <typename TVal, typename... TVals>
@@ -187,27 +187,27 @@ namespace NSQLTranslationV1 {
Add(vals...);
}
- void Add() {}
+ void Add() {}
// Y() Q() L()
- TPtr Y() const {
+ TPtr Y() const {
return AstNode();
}
template <typename... TVals>
- TPtr Y(TVals... vals) const {
+ TPtr Y(TVals... vals) const {
TPtr node(AstNode());
node->Add(vals...);
return node;
}
template <typename T>
- TPtr Q(T a) const {
+ TPtr Q(T a) const {
return Y("quote", a);
}
template <typename... TVals>
- TPtr L(TPtr list, TVals... vals) const {
+ TPtr L(TPtr list, TVals... vals) const {
Y_VERIFY_DEBUG(list);
auto copy = list->ShallowCopy();
copy->Add(vals...);
@@ -744,16 +744,16 @@ namespace NSQLTranslationV1 {
class IAggregation: public INode {
public:
- bool IsDistinct() const;
-
+ bool IsDistinct() const;
+
void DoUpdateState() const override;
virtual const TString* GetGenericKey() const;
-
+
virtual bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) = 0;
virtual TNodePtr AggregationTraits(const TNodePtr& type) const;
-
+
virtual TNodePtr AggregationTraitsFactory() const = 0;
virtual std::vector<ui32> GetFactoryColumnIndices() const;
@@ -767,11 +767,11 @@ namespace NSQLTranslationV1 {
EAggregateMode GetAggregationMode() const;
void MarkKeyColumnAsGenerated();
- virtual void Join(IAggregation* aggr);
-
- private:
- virtual TNodePtr GetApply(const TNodePtr& type) const = 0;
-
+ virtual void Join(IAggregation* aggr);
+
+ private:
+ virtual TNodePtr GetApply(const TNodePtr& type) const = 0;
+
protected:
IAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode mode);
TAstNode* Translate(TContext& ctx) const override;
@@ -1209,13 +1209,13 @@ namespace NSQLTranslationV1 {
TNodePtr BuildAccess(TPosition pos, const TVector<INode::TIdPart>& ids, bool isLookup);
TNodePtr BuildBind(TPosition pos, const TString& module, const TString& alias);
TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TString& resName = TString());
- TNodePtr BuildDataType(TPosition pos, const TString& typeName);
+ TNodePtr BuildDataType(TPosition pos, const TString& typeName);
TNodePtr BuildSimpleType(TContext& ctx, TPosition pos, const TString& typeName, bool dataOnly);
TNodePtr BuildIsNullOp(TPosition pos, TNodePtr a);
TNodePtr BuildBinaryOp(TContext& ctx, TPosition pos, const TString& opName, TNodePtr a, TNodePtr b);
TNodePtr BuildCalcOverWindow(TPosition pos, const TString& windowName, TNodePtr call);
- TNodePtr BuildYsonOptionsNode(TPosition pos, bool autoConvert, bool strict, bool fastYson);
+ TNodePtr BuildYsonOptionsNode(TPosition pos, bool autoConvert, bool strict, bool fastYson);
TNodePtr BuildDoCall(TPosition pos, const TNodePtr& node);
TNodePtr BuildTupleResult(TNodePtr tuple, int ensureTupleSize);
diff --git a/ydb/library/yql/sql/v1/query.cpp b/ydb/library/yql/sql/v1/query.cpp
index 7b6fa6dc85..725356b9f5 100644
--- a/ydb/library/yql/sql/v1/query.cpp
+++ b/ydb/library/yql/sql/v1/query.cpp
@@ -68,8 +68,8 @@ public:
if (mode == ITableKeys::EBuildKeysMode::INPUT &&
IsQueryMode(ctx.Settings.Mode) &&
Service != KikimrProviderName &&
- Service != RtmrProviderName &&
- Service != YdbProviderName) {
+ Service != RtmrProviderName &&
+ Service != YdbProviderName) {
key = Y("MrTableConcat", key);
}
@@ -310,14 +310,14 @@ public:
}
if (func.StartsWith("regexp")) {
- if (!ctx.PragmaRegexUseRe2) {
- ctx.Warning(Pos, TIssuesIds::CORE_LEGACY_REGEX_ENGINE) << "Legacy regex engine works incorrectly with unicode. Use PRAGMA RegexUseRe2='true';";
- }
-
+ if (!ctx.PragmaRegexUseRe2) {
+ ctx.Warning(Pos, TIssuesIds::CORE_LEGACY_REGEX_ENGINE) << "Legacy regex engine works incorrectly with unicode. Use PRAGMA RegexUseRe2='true';";
+ }
+
auto pattern = Args[1].Id;
- auto udf = ctx.PragmaRegexUseRe2 ?
- Y("Udf", Q("Re2.Grep"), Q(Y(Y("String", pattern.Build()), Y("Null")))):
- Y("Udf", Q("Pcre.BacktrackingGrep"), Y("String", pattern.Build()));
+ auto udf = ctx.PragmaRegexUseRe2 ?
+ Y("Udf", Q("Re2.Grep"), Q(Y(Y("String", pattern.Build()), Y("Null")))):
+ Y("Udf", Q("Pcre.BacktrackingGrep"), Y("String", pattern.Build()));
predicate = BuildLambda(Pos, Y("item"), Y("Apply", udf, "item"));
} else if (func.StartsWith("like")) {
auto pattern = Args[1].Id;
@@ -1427,7 +1427,7 @@ public:
}
auto getModesMap = [] (const TString& serviceName) -> const TMap<EWriteColumnMode, TString>& {
- if (serviceName == KikimrProviderName || serviceName == YdbProviderName) {
+ if (serviceName == KikimrProviderName || serviceName == YdbProviderName) {
return columnModeToStrMapKikimr;
} else if (serviceName == StatProviderName) {
return columnModeToStrMapStat;
diff --git a/ydb/library/yql/sql/v1/select.cpp b/ydb/library/yql/sql/v1/select.cpp
index 1509d1f626..2841f05a5b 100644
--- a/ydb/library/yql/sql/v1/select.cpp
+++ b/ydb/library/yql/sql/v1/select.cpp
@@ -1042,7 +1042,7 @@ public:
keysTuple = Q(keysTuple);
}
auto extractKey = Y("SqlExtractKey", "row", BuildLambda(Pos, Y("row"), keysTuple));
- auto extractKeyLambda = BuildLambda(Pos, Y("row"), extractKey);
+ auto extractKeyLambda = BuildLambda(Pos, Y("row"), extractKey);
TNodePtr processPartitions;
if (ListCall) {
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index 76bf7f948d..ab5a864788 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -939,7 +939,7 @@ private:
TNodePtr BindParameterRule(const TRule_bind_parameter& rule, const TTrailingQuestions& tail);
TNodePtr LambdaRule(const TRule_lambda& rule);
TNodePtr CastRule(const TRule_cast_expr& rule);
- TNodePtr BitCastRule(const TRule_bitcast_expr& rule);
+ TNodePtr BitCastRule(const TRule_bitcast_expr& rule);
TNodePtr ExistsRule(const TRule_exists_expr& rule);
TNodePtr CaseRule(const TRule_case_expr& rule);
@@ -1396,7 +1396,7 @@ bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWild
if (node.HasBlock1()) {
service = to_lower(Id(node.GetBlock1().GetRule_an_id1(), *this));
allowBinding = false;
- if (service != YtProviderName &&
+ if (service != YtProviderName &&
service != KikimrProviderName &&
service != RtmrProviderName && service != StatProviderName) {
Ctx.Error() << "Unknown service: " << service;
@@ -2122,10 +2122,10 @@ namespace {
}
return true;
}
-
- bool WithoutAlpha(const std::string_view& literal) {
- return literal.cend() == std::find_if(literal.cbegin(), literal.cend(), [](char c) { return std::isalpha(c) || (c & '\x80'); });
- }
+
+ bool WithoutAlpha(const std::string_view& literal) {
+ return literal.cend() == std::find_if(literal.cbegin(), literal.cend(), [](char c) { return std::isalpha(c) || (c & '\x80'); });
+ }
template<typename TChar>
struct TSplitResult {
@@ -4482,12 +4482,12 @@ TNodePtr TSqlExpression::CastRule(const TRule_cast_expr& rule) {
return new TCallNodeImpl(pos, "SafeCast", {exprNode, type});
}
-TNodePtr TSqlExpression::BitCastRule(const TRule_bitcast_expr& rule) {
- Ctx.IncrementMonCounter("sql_features", "BitCast");
- const auto& alt = rule;
- Token(alt.GetToken1());
- TPosition pos(Ctx.Pos());
- TSqlExpression expr(Ctx, Mode);
+TNodePtr TSqlExpression::BitCastRule(const TRule_bitcast_expr& rule) {
+ Ctx.IncrementMonCounter("sql_features", "BitCast");
+ const auto& alt = rule;
+ Token(alt.GetToken1());
+ TPosition pos(Ctx.Pos());
+ TSqlExpression expr(Ctx, Mode);
auto exprNode = expr.Build(rule.GetRule_expr3());
if (!exprNode) {
return {};
@@ -4497,8 +4497,8 @@ TNodePtr TSqlExpression::BitCastRule(const TRule_bitcast_expr& rule) {
return {};
}
return new TCallNodeImpl(pos, "BitCast", {exprNode, type});
-}
-
+}
+
TNodePtr TSqlExpression::ExistsRule(const TRule_exists_expr& rule) {
Ctx.IncrementMonCounter("sql_features", "Exists");
@@ -4749,7 +4749,7 @@ TMaybe<TExprOrIdent> TSqlExpression::InAtomExpr(const TRule_in_atom_expr& node,
result.Expr = ValueConstructor(node.GetAlt_in_atom_expr8().GetRule_value_constructor1());
break;
}
- case TRule_in_atom_expr::kAltInAtomExpr9:
+ case TRule_in_atom_expr::kAltInAtomExpr9:
result.Expr = BitCastRule(node.GetAlt_in_atom_expr9().GetRule_bitcast_expr1());
break;
case TRule_in_atom_expr::kAltInAtomExpr10:
@@ -4995,13 +4995,13 @@ TNodePtr TSqlExpression::SubExpr(const TRule_xor_subexpr& node, const TTrailingQ
TString prefix, suffix;
bool inEscape = false;
bool hasPattern = false;
- bool isSimple = true;
+ bool isSimple = true;
TMaybe<char> escape;
if (escapeLiteral) {
escape = escapeLiteral->front();
}
-
+
bool mayIgnoreCase;
if (isUtf8) {
auto splitResult = SplitPattern(UTF8ToUTF32<false>(*literalPattern), escape, inEscape, hasPattern, isSimple);
@@ -5014,21 +5014,21 @@ TNodePtr TSqlExpression::SubExpr(const TRule_xor_subexpr& node, const TTrailingQ
suffix = splitResult.Suffix;
mayIgnoreCase = WithoutAlpha(*literalPattern);
}
-
+
if (inEscape) {
Ctx.IncrementMonCounter("sql_errors", "LikeEscapeSymbolEnd");
Error() << "LIKE pattern should not end with escape symbol";
return nullptr;
}
-
+
if (opName == "like" || mayIgnoreCase) {
-//TODO: Drop regex if (isSimple) {}
-
- if (!(hasPattern || suffix.empty())) {
+//TODO: Drop regex if (isSimple) {}
+
+ if (!(hasPattern || suffix.empty())) {
isMatch = BuildBinaryOp(Ctx, pos, "==", res, BuildLiteralRawString(pos, suffix, isUtf8));
- } else if (!prefix.empty()) {
+ } else if (!prefix.empty()) {
const auto& lowerBoundOp = BuildBinaryOp(Ctx, pos, "StartsWith", res, BuildLiteralRawString(pos, prefix, isUtf8));
- isMatch = BuildBinaryOp(Ctx, pos, "And", lowerBoundOp, isMatch);
+ isMatch = BuildBinaryOp(Ctx, pos, "And", lowerBoundOp, isMatch);
}
}
}
@@ -5044,13 +5044,13 @@ TNodePtr TSqlExpression::SubExpr(const TRule_xor_subexpr& node, const TTrailingQ
return nullptr;
}
- if (!Ctx.PragmaRegexUseRe2) {
- Ctx.Warning(pos, TIssuesIds::CORE_LEGACY_REGEX_ENGINE) << "Legacy regex engine works incorrectly with unicode. Use PRAGMA RegexUseRe2='true';";
- }
-
- const auto& matcher = Ctx.PragmaRegexUseRe2 ?
- BuildUdf(Ctx, pos, "Re2", opName == "match" ? "Match" : "Grep", {BuildTuple(pos, {pattern, BuildLiteralNull(pos)})}):
- BuildUdf(Ctx, pos, "Pcre", opName == "match" ? "BacktrackingMatch" : "BacktrackingGrep", { pattern });
+ if (!Ctx.PragmaRegexUseRe2) {
+ Ctx.Warning(pos, TIssuesIds::CORE_LEGACY_REGEX_ENGINE) << "Legacy regex engine works incorrectly with unicode. Use PRAGMA RegexUseRe2='true';";
+ }
+
+ const auto& matcher = Ctx.PragmaRegexUseRe2 ?
+ BuildUdf(Ctx, pos, "Re2", opName == "match" ? "Match" : "Grep", {BuildTuple(pos, {pattern, BuildLiteralNull(pos)})}):
+ BuildUdf(Ctx, pos, "Pcre", opName == "match" ? "BacktrackingMatch" : "BacktrackingGrep", { pattern });
isMatch = new TCallNodeImpl(pos, "Apply", { matcher, res });
if (opName != "match") {
Ctx.IncrementMonCounter("sql_features", notMatch ? "NotRegexp" : "Regexp");
@@ -5231,7 +5231,7 @@ TNodePtr TSqlExpression::BinOpList(const TNode& node, TGetNode getNode, TIter be
opName = "/";
Ctx.IncrementMonCounter("sql_binary_operations", "Divide");
if (!Ctx.Scoped->PragmaClassicDivision && partialResult) {
- partialResult = new TCallNodeImpl(pos, "SafeCast", {std::move(partialResult), BuildDataType(pos, "Double")});
+ partialResult = new TCallNodeImpl(pos, "SafeCast", {std::move(partialResult), BuildDataType(pos, "Double")});
}
break;
case SQLv1LexerTokens::TOKEN_PERCENT:
@@ -7375,22 +7375,22 @@ bool TGroupByClause::HoppingWindow(const TRule_hopping_window_specification& nod
});
}
- const auto out = NKikimr::NMiniKQL::ValueFromString(NKikimr::NUdf::EDataSlot::Interval, *literal);
- if (!out) {
+ const auto out = NKikimr::NMiniKQL::ValueFromString(NKikimr::NUdf::EDataSlot::Interval, *literal);
+ if (!out) {
Ctx.Error(node->GetPos()) << "Expected interval in ISO 8601 format";
return nullptr;
}
- if ('T' == literal->back()) {
- Ctx.Error(node->GetPos()) << "Time prefix 'T' at end of interval constant. The designator 'T' shall be absent if all of the time components are absent.";
- return nullptr;
- }
-
+ if ('T' == literal->back()) {
+ Ctx.Error(node->GetPos()) << "Time prefix 'T' at end of interval constant. The designator 'T' shall be absent if all of the time components are absent.";
+ return nullptr;
+ }
+
return new TAstListNodeImpl(Ctx.Pos(), {
new TAstAtomNodeImpl(Ctx.Pos(), "Interval", TNodeFlags::Default),
new TAstListNodeImpl(Ctx.Pos(), {
new TAstAtomNodeImpl(Ctx.Pos(), "quote", TNodeFlags::Default),
- new TAstAtomNodeImpl(Ctx.Pos(), ToString(out.Get<i64>()), TNodeFlags::Default)
+ new TAstAtomNodeImpl(Ctx.Pos(), ToString(out.Get<i64>()), TNodeFlags::Default)
})
});
};
@@ -8089,7 +8089,7 @@ bool TSqlIntoTable::ValidateServiceName(const TRule_into_table_stmt& node, const
Y_UNUSED(node);
auto serviceName = table.Service;
const bool isMapReduce = serviceName == YtProviderName;
- const bool isKikimr = serviceName == KikimrProviderName || serviceName == YdbProviderName;
+ const bool isKikimr = serviceName == KikimrProviderName || serviceName == YdbProviderName;
const bool isRtmr = serviceName == RtmrProviderName;
const bool isStat = serviceName == StatProviderName;
@@ -9250,11 +9250,11 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
} else if (normalizedPragma == "file") {
if (values.size() != 2U || pragmaValueDefault) {
Error() << "Expected file alias and url as pragma values";
- Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
+ Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
return {};
- }
-
- Ctx.IncrementMonCounter("sql_pragma", "file");
+ }
+
+ Ctx.IncrementMonCounter("sql_pragma", "file");
success = true;
return BuildPragma(Ctx.Pos(), TString(ConfigProviderName), "AddFileByUrl", values, false);
} else if (normalizedPragma == "folder") {
@@ -9516,12 +9516,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
} else if (normalizedPragma == "disablewarnonansialiasshadowing") {
Ctx.WarnOnAnsiAliasShadowing = false;
Ctx.IncrementMonCounter("sql_pragma", "DisableWarnOnAnsiAliasShadowing");
- } else if (normalizedPragma == "regexusere2") {
+ } else if (normalizedPragma == "regexusere2") {
if (values.size() != 1U || !values.front().GetLiteral() || !TryFromString(*values.front().GetLiteral(), Ctx.PragmaRegexUseRe2)) {
- Error() << "Expected 'true' or 'false' for: " << pragma;
- Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
- return {};
- }
+ Error() << "Expected 'true' or 'false' for: " << pragma;
+ Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
+ return {};
+ }
Ctx.IncrementMonCounter("sql_pragma", "RegexUseRe2");
} else if (normalizedPragma == "jsonqueryreturnsjsondocument") {
Ctx.JsonQueryReturnsJsonDocument = true;
@@ -9608,12 +9608,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
return {};
}
- if (normalizedPragma == "fast") {
+ if (normalizedPragma == "fast") {
Ctx.Warning(Ctx.Pos(), TIssuesIds::YQL_DEPRECATED_PRAGMA)
<< "Use of deprecated yson.Fast pragma. It will be dropped soon";
- success = true;
- return {};
- } else if (normalizedPragma == "autoconvert") {
+ success = true;
+ return {};
+ } else if (normalizedPragma == "autoconvert") {
Ctx.PragmaYsonAutoConvert = true;
success = true;
return {};
@@ -10094,7 +10094,7 @@ void SqlASTToYqlImpl(NYql::TAstParseResult& res, const google::protobuf::Message
TContext& ctx) {
YQL_ENSURE(!ctx.Issues.Size());
res.Root = SqlASTToYql(protoAst, ctx);
- res.Pool = std::move(ctx.Pool);
+ res.Pool = std::move(ctx.Pool);
if (!res.Root) {
if (ctx.Issues.Size()) {
ctx.IncrementMonCounter("sql_errors", "AstToYqlError");
diff --git a/ydb/library/yql/sql/v1/sql_ut.cpp b/ydb/library/yql/sql/v1/sql_ut.cpp
index d77be33ced..85b6e0dfcd 100644
--- a/ydb/library/yql/sql/v1/sql_ut.cpp
+++ b/ydb/library/yql/sql/v1/sql_ut.cpp
@@ -792,11 +792,11 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["UnionAll"]);
}
- Y_UNIT_TEST(DeclareDecimalParameter) {
- NYql::TAstParseResult res = SqlToYql("declare $value as Decimal(22,9); select $value as cnt;");
- UNIT_ASSERT(res.Root);
- }
-
+ Y_UNIT_TEST(DeclareDecimalParameter) {
+ NYql::TAstParseResult res = SqlToYql("declare $value as Decimal(22,9); select $value as cnt;");
+ UNIT_ASSERT(res.Root);
+ }
+
Y_UNIT_TEST(SimpleGroupBy) {
NYql::TAstParseResult res = SqlToYql("select count(1),z from plato.Input group by key as z order by z;");
UNIT_ASSERT(res.Root);
@@ -817,33 +817,33 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
VerifyProgram(res, elementStat);
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["rollback"]);
}
-
+
Y_UNIT_TEST(PragmaFile) {
- NYql::TAstParseResult res = SqlToYql(R"(pragma file("HW", "sbr:181041334");)");
- UNIT_ASSERT(res.Root);
-
+ NYql::TAstParseResult res = SqlToYql(R"(pragma file("HW", "sbr:181041334");)");
+ UNIT_ASSERT(res.Root);
+
TWordCountHive elementStat = {{TString(R"((let world (Configure! world (DataSource '"config") '"AddFileByUrl" '"HW" '"sbr:181041334")))"), 0}};
- VerifyProgram(res, elementStat);
- UNIT_ASSERT_VALUES_EQUAL(1, elementStat.cbegin()->second);
- }
+ VerifyProgram(res, elementStat);
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat.cbegin()->second);
+ }
Y_UNIT_TEST(DoNotCrashOnNamedInFilter) {
NYql::TAstParseResult res = SqlToYql("USE plato; $all = ($table_name) -> { return true; }; SELECT * FROM FILTER(Input, $all)");
UNIT_ASSERT(res.Root);
}
-
+
Y_UNIT_TEST(PragmasFileAndUdfOrder) {
- NYql::TAstParseResult res = SqlToYql(R"(
+ NYql::TAstParseResult res = SqlToYql(R"(
PRAGMA file("libvideoplayers_udf.so", "https://proxy.sandbox.yandex-team.ru/235185290");
- PRAGMA udf("libvideoplayers_udf.so");
- )");
- UNIT_ASSERT(res.Root);
-
- const auto programm = GetPrettyPrint(res);
- const auto file = programm.find("AddFileByUrl");
- const auto udfs = programm.find("ImportUdfs");
- UNIT_ASSERT(file < udfs);
- }
+ PRAGMA udf("libvideoplayers_udf.so");
+ )");
+ UNIT_ASSERT(res.Root);
+
+ const auto programm = GetPrettyPrint(res);
+ const auto file = programm.find("AddFileByUrl");
+ const auto udfs = programm.find("ImportUdfs");
+ UNIT_ASSERT(file < udfs);
+ }
Y_UNIT_TEST(ProcessUserType) {
NYql::TAstParseResult res = SqlToYql("process plato.Input using Kikimr::PushData(TableRows());", 1, TString(NYql::KikimrProviderName));
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/base/common/map.h b/ydb/library/yql/udfs/common/clickhouse/client/base/common/map.h
index 558d1d3f92..d9dba562d0 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/base/common/map.h
+++ b/ydb/library/yql/udfs/common/clickhouse/client/base/common/map.h
@@ -14,13 +14,13 @@ using unqualified_t = std::remove_cv_t<std::remove_reference_t<T>>;
* with each element transformed by the application of `mapper`.
*/
template <template <typename...> class Collection, typename... Params, typename Mapper>
-auto map(const Collection<Params...> & collection, const Mapper & mapper)
+auto map(const Collection<Params...> & collection, const Mapper & mapper)
{
using value_type = unqualified_t<decltype(mapper(*std::begin(collection)))>;
return Collection<value_type>(
- boost::make_transform_iterator(std::begin(collection), mapper),
- boost::make_transform_iterator(std::end(collection), mapper));
+ boost::make_transform_iterator(std::begin(collection), mapper),
+ boost::make_transform_iterator(std::end(collection), mapper));
}
/** \brief Returns collection of specified container-type,
@@ -28,13 +28,13 @@ auto map(const Collection<Params...> & collection, const Mapper & mapper)
* Allows conversion between different container-types, e.g. std::vector to std::list
*/
template <template <typename...> class ResultCollection, typename Collection, typename Mapper>
-auto map(const Collection & collection, const Mapper & mapper)
+auto map(const Collection & collection, const Mapper & mapper)
{
using value_type = unqualified_t<decltype(mapper(*std::begin(collection)))>;
return ResultCollection<value_type>(
- boost::make_transform_iterator(std::begin(collection), mapper),
- boost::make_transform_iterator(std::end(collection), mapper));
+ boost::make_transform_iterator(std::begin(collection), mapper),
+ boost::make_transform_iterator(std::end(collection), mapper));
}
/** \brief Returns collection of specified type,
@@ -42,11 +42,11 @@ auto map(const Collection & collection, const Mapper & mapper)
* Allows leveraging implicit conversion between the result of applying `mapper` and R::value_type.
*/
template <typename ResultCollection, typename Collection, typename Mapper>
-auto map(const Collection & collection, const Mapper & mapper)
+auto map(const Collection & collection, const Mapper & mapper)
{
return ResultCollection(
- boost::make_transform_iterator(std::begin(collection), mapper),
- boost::make_transform_iterator(std::end(collection), mapper));
+ boost::make_transform_iterator(std::begin(collection), mapper),
+ boost::make_transform_iterator(std::end(collection), mapper));
}
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/clickhouse_client_udf.cpp b/ydb/library/yql/udfs/common/clickhouse/client/clickhouse_client_udf.cpp
index f8c24aef8b..c28539ebe9 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/clickhouse_client_udf.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/clickhouse_client_udf.cpp
@@ -14,8 +14,8 @@
#include "src/Columns/ColumnsNumber.h"
#include "src/Columns/ColumnString.h"
-#include "src/DataStreams/NativeBlockInputStream.h"
-
+#include "src/DataStreams/NativeBlockInputStream.h"
+
#include "src/DataTypes/DataTypeEnum.h"
#include "src/DataTypes/DataTypesNumber.h"
#include "src/DataTypes/DataTypeDate.h"
@@ -34,12 +34,12 @@
#include "src/Formats/InputStreamFromInputFormat.h"
#include "src/Formats/registerFormats.h"
-#include <util/string/split.h>
-
+#include <util/string/split.h>
+
using namespace NYql;
using namespace NUdf;
-namespace {
+namespace {
struct TColumnMeta {
std::optional<TString> Aggregation;
@@ -160,7 +160,7 @@ DB::DataTypePtr MetaToClickHouse(const TColumnMeta& meta) {
case EDataSlot::Int8:
ret = std::make_shared<DB::DataTypeInt8>();
break;
- case EDataSlot::Bool:
+ case EDataSlot::Bool:
case EDataSlot::Uint8:
ret = std::make_shared<DB::DataTypeUInt8>();
break;
@@ -192,11 +192,11 @@ DB::DataTypePtr MetaToClickHouse(const TColumnMeta& meta) {
ret = std::make_shared<DB::DataTypeString>();
break;
case EDataSlot::Date:
- case EDataSlot::TzDate:
+ case EDataSlot::TzDate:
ret = std::make_shared<DB::DataTypeDate>();
break;
case EDataSlot::Datetime:
- case EDataSlot::TzDatetime:
+ case EDataSlot::TzDatetime:
ret = std::make_shared<DB::DataTypeDateTime>();
break;
case EDataSlot::Uuid:
@@ -350,104 +350,104 @@ TUnboxedValuePod ConvertOutputValue(const DB::IColumn* col, const TColumnMeta& m
}
}
-class TParseFromYdb : public TBoxedValue {
-public:
- class TStreamValue : public TBoxedValue {
- public:
- TStreamValue(const IValueBuilder* valueBuilder, const TUnboxedValue& stream,
- const std::vector<TColumnMeta>& outMeta,
- const TSourcePosition& pos,
- ui32 tzId)
- : ValueBuilder(valueBuilder)
- , Stream(stream)
- , OutMeta(outMeta)
- , Pos(pos)
- , TzId(tzId)
- , Cache(OutMeta.size())
- {}
-
- EFetchStatus Fetch(TUnboxedValue& result) final try {
- for (;;) {
- if (!BlockStream) {
- if (const auto status = Stream.Fetch(Input); EFetchStatus::Ok != status)
- return status;
-
- const std::string_view buffer = Input.AsStringRef();
- Buffer = std::make_unique<DB::ReadBufferFromMemory>(buffer.data(), buffer.size());
- BlockStream = std::make_unique<DB::NativeBlockInputStream>(*Buffer, DBMS_MIN_REVISION_WITH_CURRENT_AGGREGATION_VARIANT_SELECTION_METHOD);
- }
-
- if (CurrentRow >= CurrentBlock.rows()) {
- CurrentRow = 0;
- if (CurrentBlock = BlockStream->read(); !CurrentBlock) {
- BlockStream.reset();
- Buffer.reset();
- continue;
- }
- }
-
- TUnboxedValue* items = nullptr;
- result = Cache.NewArray(*ValueBuilder, items);
- for (ui32 i = 0; i < OutMeta.size(); ++i) {
- *items++ = ConvertOutputValue(CurrentBlock.getByPosition(i).column.get(), OutMeta[i], TzId, ValueBuilder, CurrentRow);
- }
-
- ++CurrentRow;
- return EFetchStatus::Ok;
- }
- }
- catch (const Poco::Exception& e) {
- UdfTerminate((TStringBuilder() << ValueBuilder->WithCalleePosition(Pos) << " " << e.displayText()).data());
- }
- catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << ValueBuilder->WithCalleePosition(Pos) << " " << e.what()).data());
- }
- private:
- const IValueBuilder* ValueBuilder;
- const TUnboxedValue Stream;
- const std::vector<TColumnMeta> OutMeta; // in struct order
- const TSourcePosition Pos;
- const ui32 TzId;
-
- TPlainArrayCache Cache;
-
- TUnboxedValue Input;
- std::unique_ptr<DB::ReadBuffer> Buffer;
- std::unique_ptr<DB::IBlockInputStream> BlockStream;
- DB::Block CurrentBlock;
- size_t CurrentRow = 0;
- };
-
- TParseFromYdb(const TSourcePosition& pos, std::vector<TColumnMeta>&& metaForColumns)
- : Pos(pos), OutMeta(std::move(metaForColumns))
- {}
-
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final try {
- ui32 tzId = 0U;
- if (const auto& tz = args[1U]) {
- if (!valueBuilder->GetDateBuilder().FindTimezoneId(tz.AsStringRef(), tzId)) {
- tzId = 0U;
- }
- }
-
- return TUnboxedValuePod(new TStreamValue(valueBuilder, *args, OutMeta, Pos, tzId));
- }
- catch (const Poco::Exception& e) {
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.displayText()).data());
- }
- catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.what()).data());
- }
-private:
- const TSourcePosition Pos;
- const std::vector<TColumnMeta> OutMeta; // in struct order
-};
-
+class TParseFromYdb : public TBoxedValue {
+public:
+ class TStreamValue : public TBoxedValue {
+ public:
+ TStreamValue(const IValueBuilder* valueBuilder, const TUnboxedValue& stream,
+ const std::vector<TColumnMeta>& outMeta,
+ const TSourcePosition& pos,
+ ui32 tzId)
+ : ValueBuilder(valueBuilder)
+ , Stream(stream)
+ , OutMeta(outMeta)
+ , Pos(pos)
+ , TzId(tzId)
+ , Cache(OutMeta.size())
+ {}
+
+ EFetchStatus Fetch(TUnboxedValue& result) final try {
+ for (;;) {
+ if (!BlockStream) {
+ if (const auto status = Stream.Fetch(Input); EFetchStatus::Ok != status)
+ return status;
+
+ const std::string_view buffer = Input.AsStringRef();
+ Buffer = std::make_unique<DB::ReadBufferFromMemory>(buffer.data(), buffer.size());
+ BlockStream = std::make_unique<DB::NativeBlockInputStream>(*Buffer, DBMS_MIN_REVISION_WITH_CURRENT_AGGREGATION_VARIANT_SELECTION_METHOD);
+ }
+
+ if (CurrentRow >= CurrentBlock.rows()) {
+ CurrentRow = 0;
+ if (CurrentBlock = BlockStream->read(); !CurrentBlock) {
+ BlockStream.reset();
+ Buffer.reset();
+ continue;
+ }
+ }
+
+ TUnboxedValue* items = nullptr;
+ result = Cache.NewArray(*ValueBuilder, items);
+ for (ui32 i = 0; i < OutMeta.size(); ++i) {
+ *items++ = ConvertOutputValue(CurrentBlock.getByPosition(i).column.get(), OutMeta[i], TzId, ValueBuilder, CurrentRow);
+ }
+
+ ++CurrentRow;
+ return EFetchStatus::Ok;
+ }
+ }
+ catch (const Poco::Exception& e) {
+ UdfTerminate((TStringBuilder() << ValueBuilder->WithCalleePosition(Pos) << " " << e.displayText()).data());
+ }
+ catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << ValueBuilder->WithCalleePosition(Pos) << " " << e.what()).data());
+ }
+ private:
+ const IValueBuilder* ValueBuilder;
+ const TUnboxedValue Stream;
+ const std::vector<TColumnMeta> OutMeta; // in struct order
+ const TSourcePosition Pos;
+ const ui32 TzId;
+
+ TPlainArrayCache Cache;
+
+ TUnboxedValue Input;
+ std::unique_ptr<DB::ReadBuffer> Buffer;
+ std::unique_ptr<DB::IBlockInputStream> BlockStream;
+ DB::Block CurrentBlock;
+ size_t CurrentRow = 0;
+ };
+
+ TParseFromYdb(const TSourcePosition& pos, std::vector<TColumnMeta>&& metaForColumns)
+ : Pos(pos), OutMeta(std::move(metaForColumns))
+ {}
+
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final try {
+ ui32 tzId = 0U;
+ if (const auto& tz = args[1U]) {
+ if (!valueBuilder->GetDateBuilder().FindTimezoneId(tz.AsStringRef(), tzId)) {
+ tzId = 0U;
+ }
+ }
+
+ return TUnboxedValuePod(new TStreamValue(valueBuilder, *args, OutMeta, Pos, tzId));
+ }
+ catch (const Poco::Exception& e) {
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.displayText()).data());
+ }
+ catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.what()).data());
+ }
+private:
+ const TSourcePosition Pos;
+ const std::vector<TColumnMeta> OutMeta; // in struct order
+};
+
class TParseFormat : public TBoxedValue {
public:
class TStreamValue : public TBoxedValue {
public:
- TStreamValue(const std::string& type, const DB::FormatSettings& settings, const IValueBuilder* valueBuilder, const TUnboxedValue& stream,
+ TStreamValue(const std::string& type, const DB::FormatSettings& settings, const IValueBuilder* valueBuilder, const TUnboxedValue& stream,
const std::vector<TColumnMeta> outMeta, const DB::ColumnsWithTypeAndName& columns, const TSourcePosition& pos, ui32 tzId)
: ValueBuilder(valueBuilder)
, Stream(stream)
@@ -455,7 +455,7 @@ public:
, Columns(columns)
, Pos(pos)
, TzId(tzId)
- , Cache(OutMeta.size())
+ , Cache(OutMeta.size())
, Type(type)
, Settings(settings)
{}
@@ -467,8 +467,8 @@ public:
return status;
const std::string_view buffer = Input.AsStringRef();
- Buffer = std::make_unique<DB::ReadBufferFromMemory>(buffer.data(), buffer.size());
- BlockStream = std::make_unique<DB::InputStreamFromInputFormat>(DB::FormatFactory::instance().getInputFormat(Type, *Buffer, DB::Block(Columns), nullptr, buffer.size(), Settings));
+ Buffer = std::make_unique<DB::ReadBufferFromMemory>(buffer.data(), buffer.size());
+ BlockStream = std::make_unique<DB::InputStreamFromInputFormat>(DB::FormatFactory::instance().getInputFormat(Type, *Buffer, DB::Block(Columns), nullptr, buffer.size(), Settings));
}
if (CurrentRow >= CurrentBlock.rows()) {
@@ -481,7 +481,7 @@ public:
}
TUnboxedValue* items = nullptr;
- result = Cache.NewArray(*ValueBuilder, items);
+ result = Cache.NewArray(*ValueBuilder, items);
for (ui32 i = 0; i < OutMeta.size(); ++i) {
*items++ = ConvertOutputValue(CurrentBlock.getByPosition(i).column.get(), OutMeta[i], TzId, ValueBuilder, CurrentRow);
}
@@ -504,11 +504,11 @@ public:
const TSourcePosition Pos;
const ui32 TzId;
- TPlainArrayCache Cache;
-
+ TPlainArrayCache Cache;
+
TUnboxedValue Input;
const TString Type;
- const DB::FormatSettings Settings;
+ const DB::FormatSettings Settings;
std::unique_ptr<DB::ReadBuffer> Buffer;
std::unique_ptr<DB::IBlockInputStream> BlockStream;
@@ -516,19 +516,19 @@ public:
size_t CurrentRow = 0;
};
- TParseFormat(const std::string_view& type, const std::string_view& settings, const TSourcePosition& pos, std::vector<TColumnMeta>&& outMeta, DB::ColumnsWithTypeAndName&& columns)
- : Type(type), Settings(GetFormatSettings(settings)), Pos(pos), OutMeta(std::move(outMeta)), Columns(std::move(columns))
+ TParseFormat(const std::string_view& type, const std::string_view& settings, const TSourcePosition& pos, std::vector<TColumnMeta>&& outMeta, DB::ColumnsWithTypeAndName&& columns)
+ : Type(type), Settings(GetFormatSettings(settings)), Pos(pos), OutMeta(std::move(outMeta)), Columns(std::move(columns))
{}
TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final try {
- ui32 tzId = 0U;
+ ui32 tzId = 0U;
if (const auto& tz = args[1U]) {
- if (!valueBuilder->GetDateBuilder().FindTimezoneId(tz.AsStringRef(), tzId)) {
- tzId = 0U;
+ if (!valueBuilder->GetDateBuilder().FindTimezoneId(tz.AsStringRef(), tzId)) {
+ tzId = 0U;
}
}
- return TUnboxedValuePod(new TStreamValue(Type, Settings, valueBuilder, *args, OutMeta, Columns, Pos, tzId));
+ return TUnboxedValuePod(new TStreamValue(Type, Settings, valueBuilder, *args, OutMeta, Columns, Pos, tzId));
}
catch (const Poco::Exception& e) {
UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.displayText()).data());
@@ -537,10 +537,10 @@ public:
UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(Pos) << " " << e.what()).data());
}
private:
- static DB::FormatSettings GetFormatSettings(const std::string_view& view) {
- DB::FormatSettings settings;
- settings.skip_unknown_fields = true;
- settings.with_names_use_header = true;
+ static DB::FormatSettings GetFormatSettings(const std::string_view& view) {
+ DB::FormatSettings settings;
+ settings.skip_unknown_fields = true;
+ settings.with_names_use_header = true;
if (!view.empty()) {
const std::string str(view);
const JSON json(str);
@@ -552,155 +552,155 @@ private:
#define SET_FLAG(flag) \
if (json.has(#flag)) \
- settings.flag = json[#flag].get<bool>();
+ settings.flag = json[#flag].get<bool>();
SUPPORTED_FLAGS(SET_FLAG)
#undef SET_FLAG
#undef SUPPORTED_FLAGS
}
- return settings;
+ return settings;
}
const std::string Type;
- const DB::FormatSettings Settings;
+ const DB::FormatSettings Settings;
const TSourcePosition Pos;
const std::vector<TColumnMeta> OutMeta;
const DB::ColumnsWithTypeAndName Columns;
};
-struct TCHInitializer {
- using TWeakPtr = std::weak_ptr<TCHInitializer>;
- using TPtr = std::shared_ptr<TCHInitializer>;
+struct TCHInitializer {
+ using TWeakPtr = std::weak_ptr<TCHInitializer>;
+ using TPtr = std::shared_ptr<TCHInitializer>;
- TCHInitializer()
+ TCHInitializer()
{
DB::registerFormats();
}
};
-template <typename T>
-TString MakeEnumImpl(const T& values) {
- TStringBuilder str;
- str << "Enum<";
- bool first = true;
- for (const auto& value : values) {
- if (!first) {
- str << ',';
- }
- else {
- first = false;
- }
-
- str << "'" << value.first << "'";
- }
-
- str << '>';
- return str;
-}
-
-std::optional<TString> MakeYqlType(DB::DataTypePtr type, bool validTz) {
- if (type->getTypeId() == DB::TypeIndex::Enum8) {
- const DB::DataTypeEnum8* enum8 = DB::checkAndGetDataType<DB::DataTypeEnum8>(type.get());
- return MakeEnumImpl(enum8->getValues());
- }
-
- if (type->getTypeId() == DB::TypeIndex::Enum16) {
- const DB::DataTypeEnum16* enum16 = DB::checkAndGetDataType<DB::DataTypeEnum16>(type.get());
- return MakeEnumImpl(enum16->getValues());
- }
-
- if (type->getTypeId() == DB::TypeIndex::AggregateFunction) {
- return "Tagged<String,'" + TString(type->getName()) + "'>";
- }
-
- if (type->getTypeId() == DB::TypeIndex::Array) {
- const DB::DataTypeArray* array = DB::checkAndGetDataType<DB::DataTypeArray>(type.get());
- type = array->getNestedType();
- if (type->getTypeId() == DB::TypeIndex::Nothing) {
- return "EmptyList";
- }
-
- auto inner = MakeYqlType(type, validTz);
- if (!inner) {
- return std::nullopt;
- }
-
- return "List<" + *inner + '>';
- }
-
- if (type->getTypeId() == DB::TypeIndex::Tuple) {
- const DB::DataTypeTuple* tuple = DB::checkAndGetDataType<DB::DataTypeTuple>(type.get());
- const auto& elems = tuple->getElements();
- TStringBuilder str;
- str << "Tuple<";
- bool first = true;
- for (const auto& e : elems) {
- auto inner = MakeYqlType(e, validTz);
- if (!inner) {
- return std::nullopt;
- }
-
- if (!first) {
- str << ',';
- } else {
- first = false;
- }
-
- str << *inner;
- }
-
- str << '>';
- return str;
- }
-
- if (type->isNullable()) {
- type = removeNullable(type);
- if (type->getTypeId() == DB::TypeIndex::Nothing) {
- return "Null";
- }
-
- auto inner = MakeYqlType(type, validTz);
- if (!inner) {
- return std::nullopt;
- }
-
- return "Optional<" + *inner + '>';
- }
-
- if (type->getTypeId() == DB::TypeIndex::UInt8) return "Uint8";
- else if (type->getTypeId() == DB::TypeIndex::Int8) return "Int8";
- else if (type->getTypeId() == DB::TypeIndex::UInt16) return "Uint16";
- else if (type->getTypeId() == DB::TypeIndex::Int16) return "Int16";
- else if (type->getTypeId() == DB::TypeIndex::UInt32) return "Uint32";
- else if (type->getTypeId() == DB::TypeIndex::Int32) return "Int32";
- else if (type->getTypeId() == DB::TypeIndex::UInt64) return "Uint64";
- else if (type->getTypeId() == DB::TypeIndex::Int64) return "Int64";
- else if (type->getTypeId() == DB::TypeIndex::Float32) return "Float";
- else if (type->getTypeId() == DB::TypeIndex::Float64) return "Double";
- else if (type->getTypeId() == DB::TypeIndex::String) return "String";
- else if (type->getTypeId() == DB::TypeIndex::FixedString) return "String";
- else if (validTz && type->getTypeId() == DB::TypeIndex::Date) return "TzDate";
- else if (validTz && type->getTypeId() == DB::TypeIndex::DateTime) return "TzDatetime";
- else if (type->getTypeId() == DB::TypeIndex::UUID) return "Uuid";
- else return std::nullopt;
-}
-
-SIMPLE_UDF(TToYqlType, TOptional<TUtf8>(TUtf8, TUtf8)) {
- const auto ref = args[0].AsStringRef();
- const auto tzRef = args[1].AsStringRef();
- ui32 tzId;
- const bool validTz = valueBuilder->GetDateBuilder().FindTimezoneId(tzRef, tzId);
- const DB::String typeStr(ref.Data(), ref.Data() + ref.Size());
- const auto type = DB::DataTypeFactory::instance().get(typeStr);
- if (const auto ret = MakeYqlType(type, validTz)) {
- return valueBuilder->NewString(*ret);
- }
- return TUnboxedValue();
-}
-
-}
-
+template <typename T>
+TString MakeEnumImpl(const T& values) {
+ TStringBuilder str;
+ str << "Enum<";
+ bool first = true;
+ for (const auto& value : values) {
+ if (!first) {
+ str << ',';
+ }
+ else {
+ first = false;
+ }
+
+ str << "'" << value.first << "'";
+ }
+
+ str << '>';
+ return str;
+}
+
+std::optional<TString> MakeYqlType(DB::DataTypePtr type, bool validTz) {
+ if (type->getTypeId() == DB::TypeIndex::Enum8) {
+ const DB::DataTypeEnum8* enum8 = DB::checkAndGetDataType<DB::DataTypeEnum8>(type.get());
+ return MakeEnumImpl(enum8->getValues());
+ }
+
+ if (type->getTypeId() == DB::TypeIndex::Enum16) {
+ const DB::DataTypeEnum16* enum16 = DB::checkAndGetDataType<DB::DataTypeEnum16>(type.get());
+ return MakeEnumImpl(enum16->getValues());
+ }
+
+ if (type->getTypeId() == DB::TypeIndex::AggregateFunction) {
+ return "Tagged<String,'" + TString(type->getName()) + "'>";
+ }
+
+ if (type->getTypeId() == DB::TypeIndex::Array) {
+ const DB::DataTypeArray* array = DB::checkAndGetDataType<DB::DataTypeArray>(type.get());
+ type = array->getNestedType();
+ if (type->getTypeId() == DB::TypeIndex::Nothing) {
+ return "EmptyList";
+ }
+
+ auto inner = MakeYqlType(type, validTz);
+ if (!inner) {
+ return std::nullopt;
+ }
+
+ return "List<" + *inner + '>';
+ }
+
+ if (type->getTypeId() == DB::TypeIndex::Tuple) {
+ const DB::DataTypeTuple* tuple = DB::checkAndGetDataType<DB::DataTypeTuple>(type.get());
+ const auto& elems = tuple->getElements();
+ TStringBuilder str;
+ str << "Tuple<";
+ bool first = true;
+ for (const auto& e : elems) {
+ auto inner = MakeYqlType(e, validTz);
+ if (!inner) {
+ return std::nullopt;
+ }
+
+ if (!first) {
+ str << ',';
+ } else {
+ first = false;
+ }
+
+ str << *inner;
+ }
+
+ str << '>';
+ return str;
+ }
+
+ if (type->isNullable()) {
+ type = removeNullable(type);
+ if (type->getTypeId() == DB::TypeIndex::Nothing) {
+ return "Null";
+ }
+
+ auto inner = MakeYqlType(type, validTz);
+ if (!inner) {
+ return std::nullopt;
+ }
+
+ return "Optional<" + *inner + '>';
+ }
+
+ if (type->getTypeId() == DB::TypeIndex::UInt8) return "Uint8";
+ else if (type->getTypeId() == DB::TypeIndex::Int8) return "Int8";
+ else if (type->getTypeId() == DB::TypeIndex::UInt16) return "Uint16";
+ else if (type->getTypeId() == DB::TypeIndex::Int16) return "Int16";
+ else if (type->getTypeId() == DB::TypeIndex::UInt32) return "Uint32";
+ else if (type->getTypeId() == DB::TypeIndex::Int32) return "Int32";
+ else if (type->getTypeId() == DB::TypeIndex::UInt64) return "Uint64";
+ else if (type->getTypeId() == DB::TypeIndex::Int64) return "Int64";
+ else if (type->getTypeId() == DB::TypeIndex::Float32) return "Float";
+ else if (type->getTypeId() == DB::TypeIndex::Float64) return "Double";
+ else if (type->getTypeId() == DB::TypeIndex::String) return "String";
+ else if (type->getTypeId() == DB::TypeIndex::FixedString) return "String";
+ else if (validTz && type->getTypeId() == DB::TypeIndex::Date) return "TzDate";
+ else if (validTz && type->getTypeId() == DB::TypeIndex::DateTime) return "TzDatetime";
+ else if (type->getTypeId() == DB::TypeIndex::UUID) return "Uuid";
+ else return std::nullopt;
+}
+
+SIMPLE_UDF(TToYqlType, TOptional<TUtf8>(TUtf8, TUtf8)) {
+ const auto ref = args[0].AsStringRef();
+ const auto tzRef = args[1].AsStringRef();
+ ui32 tzId;
+ const bool validTz = valueBuilder->GetDateBuilder().FindTimezoneId(tzRef, tzId);
+ const DB::String typeStr(ref.Data(), ref.Data() + ref.Size());
+ const auto type = DB::DataTypeFactory::instance().get(typeStr);
+ if (const auto ret = MakeYqlType(type, validTz)) {
+ return valueBuilder->NewString(*ret);
+ }
+ return TUnboxedValue();
+}
+
+}
+
class TClickHouseClientModule : public IUdfModule
{
public:
@@ -714,9 +714,9 @@ public:
void CleanupOnTerminate() const final {}
void GetAllFunctions(IFunctionsSink& sink) const final {
- sink.Add(TStringRef::Of("ToYqlType"));
+ sink.Add(TStringRef::Of("ToYqlType"));
sink.Add(TStringRef::Of("ParseFormat"))->SetTypeAwareness();
- sink.Add(TStringRef::Of("ParseFromYdb"))->SetTypeAwareness();
+ sink.Add(TStringRef::Of("ParseFromYdb"))->SetTypeAwareness();
}
void BuildFunctionTypeInfo(
@@ -724,117 +724,117 @@ public:
TType* userType,
const TStringRef& typeConfig,
ui32 flags,
- IFunctionTypeInfoBuilder& builder) const final try {
- LazyInitContext();
- auto argBuilder = builder.Args();
-
- if (name == "ToYqlType") {
- argBuilder->Add<TUtf8>();
- argBuilder->Add<TUtf8>();
- argBuilder->Done();
- builder.Returns<TOptional<TUtf8>>();
- if (!(flags & TFlags::TypesOnly)) {
- builder.Implementation(new TToYqlType(builder));
- }
-
- return;
- }
-
- const auto typeHelper = builder.TypeInfoHelper();
- if (name == "ParseFormat") {
- const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
- if (!userTypeInspector || userTypeInspector.GetElementsCount() < 3) {
- return builder.SetError("Invalid user type.");
- }
-
- const auto argsTypeTuple = userTypeInspector.GetElementType(0);
- const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
- if (!argsTypeInspector) {
- return builder.SetError("Invalid user type - expected tuple.");
- }
-
- if (const auto argsCount = argsTypeInspector.GetElementsCount(); argsCount < 1 || argsCount > 2) {
- ::TStringBuilder sb;
- sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
- return builder.SetError(sb);
- }
-
- const auto resultType = userTypeInspector.GetElementType(2);
-
- builder.UserType(userType);
- builder.Args()->Add(builder.Stream()->Item<char*>()).Add<TOptional<TUtf8>>().Done();
- builder.OptionalArgs(1U);
- builder.Returns(builder.Stream()->Item(resultType));
-
- if (const auto structType = TStructTypeInspector(*typeHelper, resultType)) {
- std::vector<TColumnMeta> outMeta(structType.GetMembersCount());
- DB::ColumnsWithTypeAndName columns(structType.GetMembersCount());
- for (ui32 i = 0U; i < structType.GetMembersCount(); ++i) {
- if (auto& meta = outMeta[i]; GetDataType(*typeHelper, structType.GetMemberType(i), meta)) {
- auto& colsumn = columns[i];
- colsumn.type = MetaToClickHouse(meta);
- colsumn.name = structType.GetMemberName(i);
- } else {
- ::TStringBuilder sb;
- sb << "Incompatible column '" << structType.GetMemberName(i) << "' type: ";
- TTypePrinter(*typeHelper, structType.GetMemberType(i)).Out(sb.Out);
- return builder.SetError(sb);
+ IFunctionTypeInfoBuilder& builder) const final try {
+ LazyInitContext();
+ auto argBuilder = builder.Args();
+
+ if (name == "ToYqlType") {
+ argBuilder->Add<TUtf8>();
+ argBuilder->Add<TUtf8>();
+ argBuilder->Done();
+ builder.Returns<TOptional<TUtf8>>();
+ if (!(flags & TFlags::TypesOnly)) {
+ builder.Implementation(new TToYqlType(builder));
+ }
+
+ return;
+ }
+
+ const auto typeHelper = builder.TypeInfoHelper();
+ if (name == "ParseFormat") {
+ const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 3) {
+ return builder.SetError("Invalid user type.");
+ }
+
+ const auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!argsTypeInspector) {
+ return builder.SetError("Invalid user type - expected tuple.");
+ }
+
+ if (const auto argsCount = argsTypeInspector.GetElementsCount(); argsCount < 1 || argsCount > 2) {
+ ::TStringBuilder sb;
+ sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
+ return builder.SetError(sb);
+ }
+
+ const auto resultType = userTypeInspector.GetElementType(2);
+
+ builder.UserType(userType);
+ builder.Args()->Add(builder.Stream()->Item<char*>()).Add<TOptional<TUtf8>>().Done();
+ builder.OptionalArgs(1U);
+ builder.Returns(builder.Stream()->Item(resultType));
+
+ if (const auto structType = TStructTypeInspector(*typeHelper, resultType)) {
+ std::vector<TColumnMeta> outMeta(structType.GetMembersCount());
+ DB::ColumnsWithTypeAndName columns(structType.GetMembersCount());
+ for (ui32 i = 0U; i < structType.GetMembersCount(); ++i) {
+ if (auto& meta = outMeta[i]; GetDataType(*typeHelper, structType.GetMemberType(i), meta)) {
+ auto& colsumn = columns[i];
+ colsumn.type = MetaToClickHouse(meta);
+ colsumn.name = structType.GetMemberName(i);
+ } else {
+ ::TStringBuilder sb;
+ sb << "Incompatible column '" << structType.GetMemberName(i) << "' type: ";
+ TTypePrinter(*typeHelper, structType.GetMemberType(i)).Out(sb.Out);
+ return builder.SetError(sb);
}
- }
-
- if (!(flags & TFlags::TypesOnly)) {
- const std::string_view& typeCfg = typeConfig;
- const auto jsonFrom = typeCfg.find('{');
- builder.Implementation(new TParseFormat(typeCfg.substr(0U, jsonFrom), std::string_view::npos == jsonFrom ? "" : typeCfg.substr(jsonFrom), builder.GetSourcePosition(), std::move(outMeta), std::move(columns)));
- }
- return;
- } else {
- ::TStringBuilder sb;
- sb << "Incompatible row type: ";
- TTypePrinter(*typeHelper, resultType).Out(sb.Out);
- return builder.SetError(sb);
- }
- } else if (name == "ParseFromYdb") {
- builder.UserType(userType);
- builder.Args()->Add(builder.Stream()->Item<char*>()).Add<TOptional<TUtf8>>().Done();
- builder.OptionalArgs(1U);
- builder.Returns(builder.Stream()->Item(userType));
-
- if (const auto structType = TStructTypeInspector(*typeHelper, userType)) {
- std::vector<TColumnMeta> columns(structType.GetMembersCount());
- for (ui32 i = 0U; i < structType.GetMembersCount(); ++i) {
- if (const auto dataType = TDataAndDecimalTypeInspector(*typeHelper, TOptionalTypeInspector(*typeHelper, structType.GetMemberType(i)).GetItemType())) {
- auto& meta = columns[i];
- meta.Slot = GetDataSlot(dataType.GetTypeId());
- meta.IsOptional = true;
- meta.Precision = dataType.GetPrecision();
- meta.Scale = dataType.GetScale();
- } else {
- ::TStringBuilder sb;
- sb << "Incompatible column '" << structType.GetMemberName(i) << "' type: ";
- TTypePrinter(*typeHelper, structType.GetMemberType(i)).Out(sb.Out);
- return builder.SetError(sb);
- }
- }
-
- if (!(flags & TFlags::TypesOnly)) {
- builder.Implementation(new TParseFromYdb(builder.GetSourcePosition(), std::move(columns)));
- }
- return;
- } else {
- ::TStringBuilder sb;
- sb << "Incompatible row type: ";
- TTypePrinter(*typeHelper, userType).Out(sb.Out);
- return builder.SetError(sb);
- }
- }
- }
- catch (const Poco::Exception& e) {
- builder.SetError(e.displayText());
- }
- catch (const std::exception& e) {
- builder.SetError(TStringBuf(e.what()));
- }
+ }
+
+ if (!(flags & TFlags::TypesOnly)) {
+ const std::string_view& typeCfg = typeConfig;
+ const auto jsonFrom = typeCfg.find('{');
+ builder.Implementation(new TParseFormat(typeCfg.substr(0U, jsonFrom), std::string_view::npos == jsonFrom ? "" : typeCfg.substr(jsonFrom), builder.GetSourcePosition(), std::move(outMeta), std::move(columns)));
+ }
+ return;
+ } else {
+ ::TStringBuilder sb;
+ sb << "Incompatible row type: ";
+ TTypePrinter(*typeHelper, resultType).Out(sb.Out);
+ return builder.SetError(sb);
+ }
+ } else if (name == "ParseFromYdb") {
+ builder.UserType(userType);
+ builder.Args()->Add(builder.Stream()->Item<char*>()).Add<TOptional<TUtf8>>().Done();
+ builder.OptionalArgs(1U);
+ builder.Returns(builder.Stream()->Item(userType));
+
+ if (const auto structType = TStructTypeInspector(*typeHelper, userType)) {
+ std::vector<TColumnMeta> columns(structType.GetMembersCount());
+ for (ui32 i = 0U; i < structType.GetMembersCount(); ++i) {
+ if (const auto dataType = TDataAndDecimalTypeInspector(*typeHelper, TOptionalTypeInspector(*typeHelper, structType.GetMemberType(i)).GetItemType())) {
+ auto& meta = columns[i];
+ meta.Slot = GetDataSlot(dataType.GetTypeId());
+ meta.IsOptional = true;
+ meta.Precision = dataType.GetPrecision();
+ meta.Scale = dataType.GetScale();
+ } else {
+ ::TStringBuilder sb;
+ sb << "Incompatible column '" << structType.GetMemberName(i) << "' type: ";
+ TTypePrinter(*typeHelper, structType.GetMemberType(i)).Out(sb.Out);
+ return builder.SetError(sb);
+ }
+ }
+
+ if (!(flags & TFlags::TypesOnly)) {
+ builder.Implementation(new TParseFromYdb(builder.GetSourcePosition(), std::move(columns)));
+ }
+ return;
+ } else {
+ ::TStringBuilder sb;
+ sb << "Incompatible row type: ";
+ TTypePrinter(*typeHelper, userType).Out(sb.Out);
+ return builder.SetError(sb);
+ }
+ }
+ }
+ catch (const Poco::Exception& e) {
+ builder.SetError(e.displayText());
+ }
+ catch (const std::exception& e) {
+ builder.SetError(TStringBuf(e.what()));
+ }
private:
void LazyInitContext() const {
const std::unique_lock lock(CtxMutex);
@@ -842,17 +842,17 @@ private:
if (auto ctx = StaticCtx.lock()) {
Ctx = std::move(ctx);
} else {
- StaticCtx = Ctx = std::make_shared<TCHInitializer>();
+ StaticCtx = Ctx = std::make_shared<TCHInitializer>();
}
}
}
static std::mutex CtxMutex;
- static TCHInitializer::TWeakPtr StaticCtx;
- mutable TCHInitializer::TPtr Ctx;
+ static TCHInitializer::TWeakPtr StaticCtx;
+ mutable TCHInitializer::TPtr Ctx;
};
std::mutex TClickHouseClientModule::CtxMutex;
-TCHInitializer::TWeakPtr TClickHouseClientModule::StaticCtx;
+TCHInitializer::TWeakPtr TClickHouseClientModule::StaticCtx;
REGISTER_MODULES(TClickHouseClientModule);
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp
index 90f7d02eab..6411745d3b 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp
@@ -28,7 +28,7 @@ AggregateFunctionCombinatorPtr AggregateFunctionCombinatorFactory::tryFindSuffix
{
/// O(N) is ok for just a few combinators.
for (const auto & suffix_value : dict)
- if (name.ends_with(suffix_value.name))
+ if (name.ends_with(suffix_value.name))
return suffix_value.combinator_ptr;
return {};
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionFactory.cpp
index d202799253..816620aaa2 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/AggregateFunctions/AggregateFunctionFactory.cpp
@@ -132,25 +132,25 @@ AggregateFunctionPtr AggregateFunctionFactory::getImpl(
found = jt->second;
is_case_insensitive = true;
}
-/*
+/*
ContextPtr query_context;
if (CurrentThread::isInitialized())
query_context = CurrentThread::get().getQueryContext();
-*/
+*/
if (found.creator)
{
out_properties = found.properties;
-/*
+/*
if (query_context && query_context->getSettingsRef().log_queries)
query_context->addQueryFactoriesInfo(
Context::QueryLogFactories::AggregateFunction, is_case_insensitive ? Poco::toLower(name) : name);
-*/
+*/
/// The case when aggregate function should return NULL on NULL arguments. This case is handled in "get" method.
if (!out_properties.returns_default_when_only_null && has_null_arguments)
return nullptr;
-// const Settings * settings = query_context ? &query_context->getSettingsRef() : nullptr;
- return found.creator(name, argument_types, parameters, nullptr);
+// const Settings * settings = query_context ? &query_context->getSettingsRef() : nullptr;
+ return found.creator(name, argument_types, parameters, nullptr);
}
/// Combinators of aggregate functions.
@@ -161,10 +161,10 @@ AggregateFunctionPtr AggregateFunctionFactory::getImpl(
{
if (combinator->isForInternalUsageOnly())
throw Exception("Aggregate function combinator '" + combinator->getName() + "' is only for internal usage", ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION);
-/*
+/*
if (query_context && query_context->getSettingsRef().log_queries)
query_context->addQueryFactoriesInfo(Context::QueryLogFactories::AggregateFunctionCombinator, combinator->getName());
-*/
+*/
String nested_name = name.substr(0, name.size() - combinator->getName().size());
DataTypes nested_types = combinator->transformArguments(argument_types);
Array nested_parameters = combinator->transformParameters(parameters);
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Columns/ColumnArray.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Columns/ColumnArray.cpp
index 48460beee1..d57a259c09 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Columns/ColumnArray.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Columns/ColumnArray.cpp
@@ -54,7 +54,7 @@ ColumnArray::ColumnArray(MutableColumnPtr && nested_column, MutableColumnPtr &&
if (!offsets_concrete)
throw Exception("offsets_column must be a ColumnUInt64", ErrorCodes::LOGICAL_ERROR);
- if (!offsets_concrete->empty() && data)
+ if (!offsets_concrete->empty() && data)
{
Offset last_offset = offsets_concrete->getData().back();
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/ClickHouseRevision.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/ClickHouseRevision.cpp
index bc1b6f8fca..e38856a75e 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/ClickHouseRevision.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/ClickHouseRevision.cpp
@@ -2,6 +2,6 @@
namespace ClickHouseRevision
{
- unsigned getVersionRevision() { return 0; }
- unsigned getVersionInteger() { return 0; }
+ unsigned getVersionRevision() { return 0; }
+ unsigned getVersionInteger() { return 0; }
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.cpp
index 0f2c3e5d16..7a48c5eacc 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.cpp
@@ -115,7 +115,7 @@ std::string getExceptionStackTraceString(std::exception_ptr e)
std::string Exception::getStackTraceString() const
{
- return "";
+ return "";
}
Exception::FramePointers Exception::getStackFramePointers() const
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.h b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.h
index 9d3598a46a..a680e8f709 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.h
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/Exception.h
@@ -3,7 +3,7 @@
#include <cerrno>
#include <vector>
#include <memory>
-#include <optional>
+#include <optional>
#include <Poco/Version.h>
#include <Poco/Exception.h>
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/RemoteHostFilter.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/RemoteHostFilter.cpp
index df167b106a..4cd8b30313 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/RemoteHostFilter.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/RemoteHostFilter.cpp
@@ -37,9 +37,9 @@ void RemoteHostFilter::setValuesFromConfig(const Poco::Util::AbstractConfigurati
config.keys("remote_url_allow_hosts", keys);
for (const auto & key : keys)
{
- if (key.starts_with("host_regexp"))
+ if (key.starts_with("host_regexp"))
regexp_hosts.push_back(config.getString("remote_url_allow_hosts." + key));
- else if (key.starts_with("host"))
+ else if (key.starts_with("host"))
primary_hosts.insert(config.getString("remote_url_allow_hosts." + key));
}
is_allow_by_default = false;
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/escapeForFileName.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/escapeForFileName.cpp
index 9020822d09..86ae632ea4 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/escapeForFileName.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/escapeForFileName.cpp
@@ -1,6 +1,6 @@
#include <Common/hex.h>
#include <Common/escapeForFileName.h>
-#include <Common/StringUtils/StringUtils.h>
+#include <Common/StringUtils/StringUtils.h>
namespace DB
{
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/getMultipleKeysFromConfig.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/getMultipleKeysFromConfig.cpp
index 7362a37584..39798c4882 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Common/getMultipleKeysFromConfig.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Common/getMultipleKeysFromConfig.cpp
@@ -11,7 +11,7 @@ std::vector<std::string> getMultipleKeysFromConfig(const Poco::Util::AbstractCon
config.keys(root, config_keys);
for (const auto & key : config_keys)
{
- if (key != name && !(key.starts_with(name + "[") && key.ends_with("]")))
+ if (key != name && !(key.starts_with(name + "[") && key.ends_with("]")))
continue;
values.emplace_back(key);
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Compression/CompressionFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Compression/CompressionFactory.cpp
index d8b0e504d5..1796303988 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Compression/CompressionFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Compression/CompressionFactory.cpp
@@ -162,7 +162,7 @@ void CompressionCodecFactory::registerSimpleCompressionCodec(
void registerCodecNone(CompressionCodecFactory & factory);
void registerCodecLZ4(CompressionCodecFactory & factory);
-/*
+/*
void registerCodecLZ4HC(CompressionCodecFactory & factory);
void registerCodecZSTD(CompressionCodecFactory & factory);
void registerCodecDelta(CompressionCodecFactory & factory);
@@ -171,13 +171,13 @@ void registerCodecDoubleDelta(CompressionCodecFactory & factory);
void registerCodecGorilla(CompressionCodecFactory & factory);
void registerCodecEncrypted(CompressionCodecFactory & factory);
void registerCodecMultiple(CompressionCodecFactory & factory);
-*/
+*/
CompressionCodecFactory::CompressionCodecFactory()
{
registerCodecLZ4(*this);
registerCodecNone(*this);
-/*
+/*
registerCodecZSTD(*this);
registerCodecLZ4HC(*this);
registerCodecDelta(*this);
@@ -186,7 +186,7 @@ CompressionCodecFactory::CompressionCodecFactory()
registerCodecGorilla(*this);
registerCodecEncrypted(*this);
registerCodecMultiple(*this);
-*/
+*/
default_codec = get("LZ4", {});
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Core/SettingsFields.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Core/SettingsFields.cpp
index 79d49b0fb2..095dda56da 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Core/SettingsFields.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Core/SettingsFields.cpp
@@ -122,7 +122,7 @@ namespace
{
UInt64 stringToMaxThreads(const String & str)
{
- if (str.starts_with("auto"))
+ if (str.starts_with("auto"))
return 0;
return parseFromString<UInt64>(str);
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/DataStreams/NativeBlockOutputStream.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/DataStreams/NativeBlockOutputStream.cpp
index 380454927e..71457bb91d 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/DataStreams/NativeBlockOutputStream.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/DataStreams/NativeBlockOutputStream.cpp
@@ -116,7 +116,7 @@ void NativeBlockOutputStream::write(const Block & block)
/// For compatibility, we will not send explicit timezone parameter in DateTime data type
/// to older clients, that cannot understand it.
if (client_revision < DBMS_MIN_REVISION_WITH_TIME_ZONE_PARAMETER_IN_DATETIME_DATA_TYPE
- && type_name.starts_with("DateTime("))
+ && type_name.starts_with("DateTime("))
type_name = "DateTime";
writeStringBinary(type_name, ostr);
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeFactory.cpp
index 7592bc3338..a6f1f5e54f 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeFactory.cpp
@@ -66,7 +66,7 @@ DataTypePtr DataTypeFactory::get(const String & family_name_param, const ASTPtr
{
String family_name = getAliasToOrName(family_name_param);
- if (family_name.ends_with("WithDictionary"))
+ if (family_name.ends_with("WithDictionary"))
{
ASTPtr low_cardinality_params = std::make_shared<ASTExpressionList>();
String param_name = family_name.substr(0, family_name.size() - strlen("WithDictionary"));
@@ -155,17 +155,17 @@ void DataTypeFactory::registerSimpleDataTypeCustom(const String &name, SimpleCre
const DataTypeFactory::Value & DataTypeFactory::findCreatorByName(const String & family_name) const
{
-/*
+/*
ContextPtr query_context;
if (CurrentThread::isInitialized())
query_context = CurrentThread::get().getQueryContext();
-*/
+*/
{
DataTypesDictionary::const_iterator it = data_types.find(family_name);
if (data_types.end() != it)
{
-// if (query_context && query_context->getSettingsRef().log_queries)
-// query_context->addQueryFactoriesInfo(Context::QueryLogFactories::DataType, family_name);
+// if (query_context && query_context->getSettingsRef().log_queries)
+// query_context->addQueryFactoriesInfo(Context::QueryLogFactories::DataType, family_name);
return it->second;
}
}
@@ -176,8 +176,8 @@ const DataTypeFactory::Value & DataTypeFactory::findCreatorByName(const String &
DataTypesDictionary::const_iterator it = case_insensitive_data_types.find(family_name_lowercase);
if (case_insensitive_data_types.end() != it)
{
-// if (query_context && query_context->getSettingsRef().log_queries)
-// query_context->addQueryFactoriesInfo(Context::QueryLogFactories::DataType, family_name_lowercase);
+// if (query_context && query_context->getSettingsRef().log_queries)
+// query_context->addQueryFactoriesInfo(Context::QueryLogFactories::DataType, family_name_lowercase);
return it->second;
}
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeTuple.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeTuple.cpp
index aaf3303ccb..a919ca84fb 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeTuple.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/DataTypes/DataTypeTuple.cpp
@@ -240,7 +240,7 @@ auto DataTypeTuple::getSubcolumnEntity(const String & subcolumn_name,
using ReturnType = decltype(on_success(0));
for (size_t i = 0; i < names.size(); ++i)
{
- if (subcolumn_name.starts_with(names[i]))
+ if (subcolumn_name.starts_with(names[i]))
{
size_t name_length = names[i].size();
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/DiskSelector.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/DiskSelector.cpp
index b4c6ba924a..9407c582c2 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/DiskSelector.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/DiskSelector.cpp
@@ -4,7 +4,7 @@
#include <IO/WriteHelpers.h>
#include <Common/escapeForFileName.h>
#include <Common/quoteString.h>
-#include <Common/StringUtils/StringUtils.h>
+#include <Common/StringUtils/StringUtils.h>
#include <common/logger_useful.h>
#include <Interpreters/Context.h>
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/IVolume.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/IVolume.cpp
index d992a7b619..586ba81b12 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/IVolume.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Disks/IVolume.cpp
@@ -42,7 +42,7 @@ IVolume::IVolume(
for (const auto & disk : keys)
{
- if (disk.starts_with("disk"))
+ if (disk.starts_with("disk"))
{
auto disk_name = config.getString(config_prefix + "." + disk);
disks.push_back(disk_selector->get(disk_name));
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/FormatFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/FormatFactory.cpp
index a27ef9478d..b8b320d57b 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/FormatFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/FormatFactory.cpp
@@ -46,7 +46,7 @@ template <typename Settings>
FormatSettings getFormatSettings(ContextPtr context, const Settings & settings)
{
FormatSettings format_settings;
-/*
+/*
format_settings.avro.allow_missing_fields = settings.input_format_avro_allow_missing_fields;
format_settings.avro.output_codec = settings.output_format_avro_codec;
format_settings.avro.output_sync_interval = settings.output_format_avro_sync_interval;
@@ -118,7 +118,7 @@ FormatSettings getFormatSettings(ContextPtr context, const Settings & settings)
if (!avro_schema_registry_url.empty())
context->getRemoteHostFilter().checkURL(avro_schema_registry_url);
}
-*/
+*/
return format_settings;
}
@@ -145,7 +145,7 @@ InputFormatPtr FormatFactory::getInput(
{
throw Exception("Format " + name + " is not suitable for input (with processors)", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_INPUT);
}
-/*
+/*
const Settings & settings = context->getSettingsRef();
const auto & file_segmentation_engine = getCreators(name).file_segmentation_engine;
@@ -188,7 +188,7 @@ InputFormatPtr FormatFactory::getInput(
buf, sample, parser_creator, file_segmentation_engine, name, settings.max_threads, settings.min_chunk_bytes_for_parallel_parsing};
return std::make_shared<ParallelParsingInputFormat>(params);
}
-*/
+*/
auto format = getInputFormat(name, buf, sample, context, max_block_size, format_settings);
return format;
}
@@ -201,7 +201,7 @@ BlockOutputStreamPtr FormatFactory::getOutputStreamParallelIfPossible(
WriteCallback callback,
const std::optional<FormatSettings> & _format_settings) const
{
-/*
+/*
const auto & output_getter = getCreators(name).output_processor_creator;
const Settings & settings = context->getSettingsRef();
@@ -224,7 +224,7 @@ BlockOutputStreamPtr FormatFactory::getOutputStreamParallelIfPossible(
return std::make_shared<MaterializingBlockOutputStream>(std::make_shared<OutputStreamToOutputFormat>(format), sample);
}
-*/
+*/
return getOutputStream(name, buf, sample, context, callback, _format_settings);
}
@@ -269,20 +269,20 @@ InputFormatPtr FormatFactory::getInputFormat(
const auto & input_getter = getCreators(name).input_processor_creator;
if (!input_getter)
throw Exception("Format " + name + " is not suitable for input", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_INPUT);
-/*
+/*
const Settings & settings = context->getSettingsRef();
if (context->hasQueryContext() && settings.log_queries)
context->getQueryContext()->addQueryFactoriesInfo(Context::QueryLogFactories::Format, name);
-*/
- auto format_settings = *_format_settings;
+*/
+ auto format_settings = *_format_settings;
RowInputFormatParams params;
params.max_block_size = max_block_size;
params.allow_errors_num = format_settings.input_allow_errors_num;
params.allow_errors_ratio = format_settings.input_allow_errors_ratio;
-// params.max_execution_time = settings.max_execution_time;
-// params.timeout_overflow_mode = settings.timeout_overflow_mode;
+// params.max_execution_time = settings.max_execution_time;
+// params.timeout_overflow_mode = settings.timeout_overflow_mode;
auto format = input_getter(buf, sample, params, format_settings);
/// It's a kludge. Because I cannot remove context from values format.
@@ -303,7 +303,7 @@ OutputFormatPtr FormatFactory::getOutputFormatParallelIfPossible(
const auto & output_getter = getCreators(name).output_processor_creator;
if (!output_getter)
throw Exception(ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT, "Format {} is not suitable for output (with processors)", name);
-/*
+/*
auto format_settings = _format_settings ? *_format_settings : getFormatSettings(context);
const Settings & settings = context->getSettingsRef();
@@ -322,7 +322,7 @@ OutputFormatPtr FormatFactory::getOutputFormatParallelIfPossible(
return std::make_shared<ParallelFormattingOutputFormat>(builder);
}
-*/
+*/
return getOutputFormat(name, buf, sample, context, callback, _format_settings);
}
@@ -338,10 +338,10 @@ OutputFormatPtr FormatFactory::getOutputFormat(
const auto & output_getter = getCreators(name).output_processor_creator;
if (!output_getter)
throw Exception(ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT, "Format {} is not suitable for output (with processors)", name);
-/*
+/*
if (context->hasQueryContext() && context->getSettingsRef().log_queries)
context->getQueryContext()->addQueryFactoriesInfo(Context::QueryLogFactories::Format, name);
-*/
+*/
RowOutputFormatParams params;
params.callback = std::move(callback);
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/registerFormats.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/registerFormats.cpp
index 3022554079..a4c48ed1e3 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/registerFormats.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Formats/registerFormats.cpp
@@ -8,31 +8,31 @@
namespace DB
{
-void registerInputFormatProcessorNative(FormatFactory & factory);
+void registerInputFormatProcessorNative(FormatFactory & factory);
void registerInputFormatProcessorJSONEachRow(FormatFactory & factory);
void registerInputFormatProcessorRawBLOB(FormatFactory & factory);
void registerInputFormatProcessorORC(FormatFactory & factory);
void registerInputFormatProcessorArrow(FormatFactory & factory);
void registerInputFormatProcessorParquet(FormatFactory & factory);
void registerInputFormatProcessorAvro(FormatFactory & factory);
-void registerInputFormatProcessorCSV(FormatFactory & factory);
-void registerInputFormatProcessorTSKV(FormatFactory & factory);
-void registerInputFormatProcessorTabSeparated(FormatFactory & factory);
+void registerInputFormatProcessorCSV(FormatFactory & factory);
+void registerInputFormatProcessorTSKV(FormatFactory & factory);
+void registerInputFormatProcessorTabSeparated(FormatFactory & factory);
void registerFormats()
{
auto & factory = FormatFactory::instance();
- registerInputFormatProcessorNative(factory);
+ registerInputFormatProcessorNative(factory);
registerInputFormatProcessorJSONEachRow(factory);
registerInputFormatProcessorRawBLOB(factory);
registerInputFormatProcessorORC(factory);
registerInputFormatProcessorArrow(factory);
registerInputFormatProcessorParquet(factory);
registerInputFormatProcessorAvro(factory);
- registerInputFormatProcessorCSV(factory);
- registerInputFormatProcessorTSKV(factory);
- registerInputFormatProcessorTabSeparated(factory);
+ registerInputFormatProcessorCSV(factory);
+ registerInputFormatProcessorTSKV(factory);
+ registerInputFormatProcessorTabSeparated(factory);
}
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Functions/FunctionFactory.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Functions/FunctionFactory.cpp
index 9c0ac86050..a4521480eb 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Functions/FunctionFactory.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Functions/FunctionFactory.cpp
@@ -107,14 +107,14 @@ FunctionOverloadResolverPtr FunctionFactory::tryGetImpl(
if (!res)
return nullptr;
-/*
+/*
if (CurrentThread::isInitialized())
{
auto query_context = CurrentThread::get().getQueryContext();
if (query_context && query_context->getSettingsRef().log_queries)
query_context->addQueryFactoriesInfo(Context::QueryLogFactories::Function, name);
}
-*/
+*/
return res;
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.cpp
index 12106bacc9..4e62d8be70 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.cpp
@@ -1,7 +1,7 @@
#include <IO/WriteHelpers.h>
#include <inttypes.h>
#include <Common/hex.h>
-#include <Common/StringUtils/StringUtils.h>
+#include <Common/StringUtils/StringUtils.h>
namespace DB
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.h b/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.h
index affea45824..28ff17a5e2 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.h
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/IO/WriteHelpers.h
@@ -940,8 +940,8 @@ void writeDecimalFractional(const T & x, UInt32 scale, WriteBuffer & ostr, bool
constexpr size_t max_digits = std::numeric_limits<UInt256>::digits10;
assert(scale <= max_digits);
char buf[max_digits];
- const char zero = '0';
- std::memset(buf, zero, scale);
+ const char zero = '0';
+ std::memset(buf, zero, scale);
T value = x;
Int32 last_nonzero_pos = 0;
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Aggregator.h b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Aggregator.h
index ecb364b943..d7b8ebca83 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Aggregator.h
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Aggregator.h
@@ -26,7 +26,7 @@
#include <Interpreters/AggregateDescription.h>
#include <Interpreters/AggregationCommon.h>
-//#include <Interpreters/JIT/compileFunction.h>
+//#include <Interpreters/JIT/compileFunction.h>
#include <Columns/ColumnString.h>
#include <Columns/ColumnFixedString.h>
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/ClientInfo.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/ClientInfo.cpp
index e6960072b9..3591303893 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/ClientInfo.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/ClientInfo.cpp
@@ -174,7 +174,7 @@ void ClientInfo::setInitialQuery()
{
query_kind = QueryKind::INITIAL_QUERY;
fillOSUserHostNameAndVersionInfo();
- client_name = "ClickHouse " + client_name;
+ client_name = "ClickHouse " + client_name;
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Cluster.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Cluster.cpp
index e60c0ad7ba..e5959273f0 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Cluster.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Cluster.cpp
@@ -220,7 +220,7 @@ Cluster::Address Cluster::Address::fromFullString(const String & full_string)
const char * user_pw_end = strchr(full_string.data(), '@');
/// parsing with the new shard{shard_index}[_replica{replica_index}] format
- if (!user_pw_end && full_string.starts_with("shard"))
+ if (!user_pw_end && full_string.starts_with("shard"))
{
const char * underscore = strchr(full_string.data(), '_');
@@ -239,7 +239,7 @@ Cluster::Address Cluster::Address::fromFullString(const String & full_string)
Protocol::Secure secure = Protocol::Secure::Disable;
const char * secure_tag = "+secure";
- if (full_string.ends_with(secure_tag))
+ if (full_string.ends_with(secure_tag))
{
address_end -= strlen(secure_tag);
secure = Protocol::Secure::Enable;
@@ -367,7 +367,7 @@ Cluster::Cluster(const Poco::Util::AbstractConfiguration & config,
UInt32 current_shard_num = 1;
for (const auto & key : config_keys)
{
- if (key.starts_with("node"))
+ if (key.starts_with("node"))
{
/// Shard without replicas.
@@ -404,7 +404,7 @@ Cluster::Cluster(const Poco::Util::AbstractConfiguration & config,
shards_info.emplace_back(std::move(info));
addresses_with_failover.emplace_back(std::move(addresses));
}
- else if (key.starts_with("shard"))
+ else if (key.starts_with("shard"))
{
/// Shard with replicas.
@@ -427,10 +427,10 @@ Cluster::Cluster(const Poco::Util::AbstractConfiguration & config,
for (const auto & replica_key : replica_keys)
{
- if (replica_key.starts_with("weight") ||replica_key.starts_with("internal_replication"))
+ if (replica_key.starts_with("weight") ||replica_key.starts_with("internal_replication"))
continue;
- if (replica_key.starts_with("replica"))
+ if (replica_key.starts_with("replica"))
{
replica_addresses.emplace_back(config,
partial_prefix + replica_key,
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Context_fwd.h b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Context_fwd.h
index 63085433f1..b07679bec6 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Context_fwd.h
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Interpreters/Context_fwd.h
@@ -16,7 +16,7 @@ namespace ErrorCodes
class Block;
/// Scalar results of subqueries
-using Scalars = std::map<std::string, Block>;
+using Scalars = std::map<std::string, Block>;
class Context;
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserExternalDDLQuery.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserExternalDDLQuery.cpp
index 7f15ffce2b..e4da38a9c9 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserExternalDDLQuery.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserExternalDDLQuery.cpp
@@ -6,20 +6,20 @@
#include <Parsers/ParserDropQuery.h>
#include <Parsers/ParserRenameQuery.h>
-// #ifdef USE_MYSQL
-// # include <Parsers/MySQL/ASTAlterQuery.h>
-// # include <Parsers/MySQL/ASTCreateQuery.h>
-// #endif
+// #ifdef USE_MYSQL
+// # include <Parsers/MySQL/ASTAlterQuery.h>
+// # include <Parsers/MySQL/ASTCreateQuery.h>
+// #endif
namespace DB
{
-// #ifdef USE_MYSQL
-// namespace ErrorCodes
-// {
-// extern const int MYSQL_SYNTAX_ERROR;
-// }
-// #endif
+// #ifdef USE_MYSQL
+// namespace ErrorCodes
+// {
+// extern const int MYSQL_SYNTAX_ERROR;
+// }
+// #endif
bool ParserExternalDDLQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
@@ -40,37 +40,37 @@ bool ParserExternalDDLQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expect
bool res = false;
if (external_ddl_query->from->name == "MySQL")
{
-// #ifdef USE_MYSQL
-// ParserDropQuery p_drop_query;
-// ParserRenameQuery p_rename_query;
-// MySQLParser::ParserAlterQuery p_alter_query;
-// MySQLParser::ParserCreateQuery p_create_query;
-//
-// res = p_create_query.parse(pos, external_ddl_query->external_ddl, expected)
-// || p_drop_query.parse(pos, external_ddl_query->external_ddl, expected)
-// || p_alter_query.parse(pos, external_ddl_query->external_ddl, expected)
-// || p_rename_query.parse(pos, external_ddl_query->external_ddl, expected);
-//
-// if (external_ddl_query->external_ddl)
-// external_ddl_query->children.push_back(external_ddl_query->external_ddl);
-//
-// if (!res)
-// {
-// / Syntax error is ignored, so we need to convert the error code for parsing failure
-//
-// if (ParserKeyword("ALTER TABLE").ignore(pos))
-// throw Exception("Cannot parse MySQL alter query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
-//
-// if (ParserKeyword("RENAME TABLE").ignore(pos))
-// throw Exception("Cannot parse MySQL rename query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
-//
-// if (ParserKeyword("DROP TABLE").ignore(pos) || ParserKeyword("TRUNCATE").ignore(pos))
-// throw Exception("Cannot parse MySQL drop query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
-//
-// if (ParserKeyword("CREATE TABLE").ignore(pos) || ParserKeyword("CREATE TEMPORARY TABLE").ignore(pos))
-// throw Exception("Cannot parse MySQL create query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
-// }
-// #endif
+// #ifdef USE_MYSQL
+// ParserDropQuery p_drop_query;
+// ParserRenameQuery p_rename_query;
+// MySQLParser::ParserAlterQuery p_alter_query;
+// MySQLParser::ParserCreateQuery p_create_query;
+//
+// res = p_create_query.parse(pos, external_ddl_query->external_ddl, expected)
+// || p_drop_query.parse(pos, external_ddl_query->external_ddl, expected)
+// || p_alter_query.parse(pos, external_ddl_query->external_ddl, expected)
+// || p_rename_query.parse(pos, external_ddl_query->external_ddl, expected);
+//
+// if (external_ddl_query->external_ddl)
+// external_ddl_query->children.push_back(external_ddl_query->external_ddl);
+//
+// if (!res)
+// {
+// / Syntax error is ignored, so we need to convert the error code for parsing failure
+//
+// if (ParserKeyword("ALTER TABLE").ignore(pos))
+// throw Exception("Cannot parse MySQL alter query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
+//
+// if (ParserKeyword("RENAME TABLE").ignore(pos))
+// throw Exception("Cannot parse MySQL rename query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
+//
+// if (ParserKeyword("DROP TABLE").ignore(pos) || ParserKeyword("TRUNCATE").ignore(pos))
+// throw Exception("Cannot parse MySQL drop query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
+//
+// if (ParserKeyword("CREATE TABLE").ignore(pos) || ParserKeyword("CREATE TEMPORARY TABLE").ignore(pos))
+// throw Exception("Cannot parse MySQL create query.", ErrorCodes::MYSQL_SYNTAX_ERROR);
+// }
+// #endif
}
node = external_ddl_query;
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserQuery.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserQuery.cpp
index 5eb0345220..9233bb6ff5 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserQuery.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Parsers/ParserQuery.cpp
@@ -27,7 +27,7 @@ bool ParserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
ParserExternalDDLQuery external_ddl_p;
ParserBackupQuery backup_p;
- bool res = insert_p.parse(pos, node, expected)
+ bool res = insert_p.parse(pos, node, expected)
|| use_p.parse(pos, node, expected)
|| set_role_p.parse(pos, node, expected)
|| set_p.parse(pos, node, expected)
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/AvroRowInputFormat.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/AvroRowInputFormat.cpp
index 7ec6904a0c..008c3896a4 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/AvroRowInputFormat.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/AvroRowInputFormat.cpp
@@ -614,7 +614,7 @@ bool AvroRowInputFormat::readRow(MutableColumns & columns, RowReadExtension &ext
}
return false;
}
-/*
+/*
class AvroConfluentRowInputFormat::SchemaRegistry
{
public:
@@ -713,7 +713,7 @@ static std::shared_ptr<ConfluentSchemaRegistry> getConfluentSchemaRegistry(const
);
return schema_registry;
}
-*/
+*/
static uint32_t readConfluentSchemaId(ReadBuffer & in)
{
uint8_t magic;
@@ -747,7 +747,7 @@ static uint32_t readConfluentSchemaId(ReadBuffer & in)
AvroConfluentRowInputFormat::AvroConfluentRowInputFormat(
const Block & header_, ReadBuffer & in_, Params params_, const FormatSettings & format_settings_)
: IRowInputFormat(header_, in_, params_)
-// , schema_registry(getConfluentSchemaRegistry(format_settings_))
+// , schema_registry(getConfluentSchemaRegistry(format_settings_))
, input_stream(std::make_unique<InputStreamReadBufferAdapter>(in))
, decoder(avro::binaryDecoder())
, format_settings(format_settings_)
@@ -783,12 +783,12 @@ void AvroConfluentRowInputFormat::syncAfterError()
const AvroDeserializer & AvroConfluentRowInputFormat::getOrCreateDeserializer(SchemaId schema_id)
{
auto it = deserializer_cache.find(schema_id);
- /* if (it == deserializer_cache.end())
+ /* if (it == deserializer_cache.end())
{
auto schema = schema_registry->getSchema(schema_id);
AvroDeserializer deserializer(output.getHeader(), schema, format_settings.avro.allow_missing_fields);
it = deserializer_cache.emplace(schema_id, deserializer).first;
- }*/
+ }*/
return it->second;
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp
index 4c341e9609..85937935f1 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp
@@ -17,7 +17,7 @@ namespace ErrorCodes
TSKVRowInputFormat::TSKVRowInputFormat(ReadBuffer & in_, Block header_, Params params_, const FormatSettings & format_settings_)
- : IRowInputFormat(std::move(header_), in_, std::move(params_)), format_settings(format_settings_)
+ : IRowInputFormat(std::move(header_), in_, std::move(params_)), format_settings(format_settings_)
{
const auto & sample_block = getPort().getHeader();
size_t num_columns = sample_block.columns();
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ColumnsDescription.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ColumnsDescription.cpp
index 75bb67ea8a..acf042364d 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ColumnsDescription.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ColumnsDescription.cpp
@@ -178,7 +178,7 @@ static auto getNameRange(const ColumnsDescription::ColumnsContainer & columns, c
if (begin->name == name_without_dot)
return std::make_pair(begin, std::next(begin));
- if (begin->name.starts_with(name_with_dot))
+ if (begin->name.starts_with(name_with_dot))
break;
}
@@ -188,7 +188,7 @@ static auto getNameRange(const ColumnsDescription::ColumnsContainer & columns, c
auto end = std::next(begin);
for (; end != columns.end(); ++end)
{
- if (!end->name.starts_with(name_with_dot))
+ if (!end->name.starts_with(name_with_dot))
break;
}
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ProjectionsDescription.cpp b/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ProjectionsDescription.cpp
index 74048fbe12..908563c1cf 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ProjectionsDescription.cpp
+++ b/ydb/library/yql/udfs/common/clickhouse/client/src/Storages/ProjectionsDescription.cpp
@@ -104,7 +104,7 @@ ProjectionDescription::getProjectionFromAST(const ASTPtr & definition_ast, const
if (projection_definition->name.empty())
throw Exception("Projection must have name in definition.", ErrorCodes::INCORRECT_QUERY);
- if (projection_definition->name.starts_with("tmp_"))
+ if (projection_definition->name.starts_with("tmp_"))
throw Exception("Projection's name cannot start with 'tmp_'", ErrorCodes::INCORRECT_QUERY);
if (!projection_definition->query)
diff --git a/ydb/library/yql/udfs/common/clickhouse/client/ya.make b/ydb/library/yql/udfs/common/clickhouse/client/ya.make
index 5b69ce7aa6..d9ef0a6645 100644
--- a/ydb/library/yql/udfs/common/clickhouse/client/ya.make
+++ b/ydb/library/yql/udfs/common/clickhouse/client/ya.make
@@ -5,7 +5,7 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
YQL_ABI_VERSION(
2
- 23
+ 23
0
)
@@ -16,88 +16,88 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
base/common/DateLUTImpl.cpp
base/common/demangle.cpp
base/common/errnoToString.cpp
- base/common/getFQDNOrHostName.cpp
+ base/common/getFQDNOrHostName.cpp
base/common/getPageSize.cpp
- base/common/getThreadId.cpp
+ base/common/getThreadId.cpp
base/common/JSON.cpp
base/common/mremap.cpp
base/common/shift10.cpp
base/common/sleep.cpp
base/common/StringRef.cpp
base/common/getResource.cpp
- base/common/phdr_cache.cpp
+ base/common/phdr_cache.cpp
base/common/preciseExp10.cpp
- src/Common/AlignedBuffer.cpp
- src/Common/Allocator.cpp
- src/Common/checkStackSize.cpp
- src/Common/createHardLink.cpp
- src/Common/CurrentMetrics.cpp
- src/Common/Epoll.cpp
- src/Common/escapeForFileName.cpp
- src/Common/filesystemHelpers.cpp
- src/Common/formatIPv6.cpp
- src/Common/formatReadable.cpp
- src/Common/getMultipleKeysFromConfig.cpp
- src/Common/getNumberOfPhysicalCPUCores.cpp
- src/Common/hasLinuxCapability.cpp
- src/Common/hex.cpp
- src/Common/isLocalAddress.cpp
- src/Common/IntervalKind.cpp
- src/Common/parseAddress.cpp
- src/Common/ClickHouseRevision.cpp
- src/Common/CurrentMemoryTracker.cpp
- src/Common/CurrentThread.cpp
- src/Common/DNSResolver.cpp
+ src/Common/AlignedBuffer.cpp
+ src/Common/Allocator.cpp
+ src/Common/checkStackSize.cpp
+ src/Common/createHardLink.cpp
+ src/Common/CurrentMetrics.cpp
+ src/Common/Epoll.cpp
+ src/Common/escapeForFileName.cpp
+ src/Common/filesystemHelpers.cpp
+ src/Common/formatIPv6.cpp
+ src/Common/formatReadable.cpp
+ src/Common/getMultipleKeysFromConfig.cpp
+ src/Common/getNumberOfPhysicalCPUCores.cpp
+ src/Common/hasLinuxCapability.cpp
+ src/Common/hex.cpp
+ src/Common/isLocalAddress.cpp
+ src/Common/IntervalKind.cpp
+ src/Common/parseAddress.cpp
+ src/Common/ClickHouseRevision.cpp
+ src/Common/CurrentMemoryTracker.cpp
+ src/Common/CurrentThread.cpp
+ src/Common/DNSResolver.cpp
src/Common/Exception.cpp
src/Common/ErrorCodes.cpp
- src/Common/FieldVisitorDump.cpp
- src/Common/FieldVisitorToString.cpp
- src/Common/FieldVisitorWriteBinary.cpp
- src/Common/IPv6ToBinary.cpp
- src/Common/MemoryTracker.cpp
- src/Common/OpenSSLHelpers.cpp
- src/Common/PipeFDs.cpp
- src/Common/PODArray.cpp
- src/Common/ProcfsMetricsProvider.cpp
+ src/Common/FieldVisitorDump.cpp
+ src/Common/FieldVisitorToString.cpp
+ src/Common/FieldVisitorWriteBinary.cpp
+ src/Common/IPv6ToBinary.cpp
+ src/Common/MemoryTracker.cpp
+ src/Common/OpenSSLHelpers.cpp
+ src/Common/PipeFDs.cpp
+ src/Common/PODArray.cpp
+ src/Common/ProcfsMetricsProvider.cpp
src/Common/ProfileEvents.cpp
- src/Common/quoteString.cpp
- src/Common/randomSeed.cpp
- src/Common/RemoteHostFilter.cpp
- src/Common/setThreadName.cpp
- src/Common/TaskStatsInfoGetter.cpp
- src/Common/ThreadPool.cpp
- src/Common/ThreadProfileEvents.cpp
- src/Common/ThreadStatus.cpp
- src/Common/Throttler.cpp
- src/Common/TimerDescriptor.cpp
- src/Common/thread_local_rng.cpp
- src/Common/ZooKeeper/IKeeper.cpp
+ src/Common/quoteString.cpp
+ src/Common/randomSeed.cpp
+ src/Common/RemoteHostFilter.cpp
+ src/Common/setThreadName.cpp
+ src/Common/TaskStatsInfoGetter.cpp
+ src/Common/ThreadPool.cpp
+ src/Common/ThreadProfileEvents.cpp
+ src/Common/ThreadStatus.cpp
+ src/Common/Throttler.cpp
+ src/Common/TimerDescriptor.cpp
+ src/Common/thread_local_rng.cpp
+ src/Common/ZooKeeper/IKeeper.cpp
+
+ src/Common/Config/AbstractConfigurationComparison.cpp
+
+ src/Core/BaseSettings.cpp
+ src/Core/Block.cpp
+ src/Core/BlockInfo.cpp
+ src/Core/Field.cpp
+ src/Core/ColumnWithTypeAndName.cpp
+ src/Core/NamesAndTypes.cpp
+ src/Core/Settings.cpp
+ src/Core/SettingsEnums.cpp
+ src/Core/SettingsFields.cpp
- src/Common/Config/AbstractConfigurationComparison.cpp
-
- src/Core/BaseSettings.cpp
- src/Core/Block.cpp
- src/Core/BlockInfo.cpp
- src/Core/Field.cpp
- src/Core/ColumnWithTypeAndName.cpp
- src/Core/NamesAndTypes.cpp
- src/Core/Settings.cpp
- src/Core/SettingsEnums.cpp
- src/Core/SettingsFields.cpp
-
src/Formats/FormatFactory.cpp
src/Formats/JSONEachRowUtils.cpp
- src/Formats/NativeFormat.cpp
+ src/Formats/NativeFormat.cpp
src/Formats/ProtobufReader.cpp
src/Formats/ProtobufWriter.cpp
src/Formats/registerFormats.cpp
src/Formats/verbosePrintString.cpp
- src/AggregateFunctions/AggregateFunctionFactory.cpp
- src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp
+ src/AggregateFunctions/AggregateFunctionFactory.cpp
+ src/AggregateFunctions/AggregateFunctionCombinatorFactory.cpp
src/AggregateFunctions/IAggregateFunction.cpp
-
+
src/Columns/Collator.cpp
src/Columns/ColumnAggregateFunction.cpp
src/Columns/ColumnArray.cpp
@@ -113,9 +113,9 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/Columns/ColumnFixedString.cpp
src/Columns/ColumnLowCardinality.cpp
src/Columns/ColumnMap.cpp
- src/Columns/FilterDescription.cpp
- src/Columns/IColumn.cpp
- src/Columns/MaskOperations.cpp
+ src/Columns/FilterDescription.cpp
+ src/Columns/IColumn.cpp
+ src/Columns/MaskOperations.cpp
src/IO/AsynchronousReadBufferFromFile.cpp
src/IO/AsynchronousReadBufferFromFileDescriptor.cpp
@@ -125,7 +125,7 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/IO/DoubleConverter.cpp
src/IO/MMappedFile.cpp
src/IO/MMappedFileDescriptor.cpp
- src/IO/MMapReadBufferFromFile.cpp
+ src/IO/MMapReadBufferFromFile.cpp
src/IO/MMapReadBufferFromFileDescriptor.cpp
src/IO/MMapReadBufferFromFileWithCache.cpp
src/IO/OpenedFile.cpp
@@ -136,48 +136,48 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/IO/ReadBufferFromFileBase.cpp
src/IO/ReadBufferFromFileDescriptor.cpp
src/IO/ReadBufferFromMemory.cpp
- src/IO/ReadBufferFromPocoSocket.cpp
+ src/IO/ReadBufferFromPocoSocket.cpp
src/IO/readFloatText.cpp
src/IO/ReadHelpers.cpp
src/IO/ReadSettings.cpp
src/IO/SynchronousReader.cpp
- src/IO/TimeoutSetter.cpp
+ src/IO/TimeoutSetter.cpp
src/IO/ThreadPoolReader.cpp
src/IO/UseSSL.cpp
src/IO/WriteHelpers.cpp
- src/IO/WriteBufferFromFile.cpp
- src/IO/WriteBufferFromFileBase.cpp
- src/IO/WriteBufferFromFileDescriptor.cpp
- src/IO/WriteBufferFromFileDescriptorDiscardOnFailure.cpp
- src/IO/WriteBufferFromPocoSocket.cpp
+ src/IO/WriteBufferFromFile.cpp
+ src/IO/WriteBufferFromFileBase.cpp
+ src/IO/WriteBufferFromFileDescriptor.cpp
+ src/IO/WriteBufferFromFileDescriptorDiscardOnFailure.cpp
+ src/IO/WriteBufferFromPocoSocket.cpp
- src/Compression/CompressionCodecLZ4.cpp
- src/Compression/CompressionCodecMultiple.cpp
- src/Compression/CompressionCodecNone.cpp
- src/Compression/CompressionFactory.cpp
- src/Compression/CompressedReadBuffer.cpp
- src/Compression/CompressedReadBufferBase.cpp
+ src/Compression/CompressionCodecLZ4.cpp
+ src/Compression/CompressionCodecMultiple.cpp
+ src/Compression/CompressionCodecNone.cpp
+ src/Compression/CompressionFactory.cpp
+ src/Compression/CompressedReadBuffer.cpp
+ src/Compression/CompressedReadBufferBase.cpp
src/Compression/CompressedReadBufferFromFile.cpp
- src/Compression/CompressedWriteBuffer.cpp
+ src/Compression/CompressedWriteBuffer.cpp
src/Compression/ICompressionCodec.cpp
src/Compression/LZ4_decompress_faster.cpp
- src/DataStreams/BlockStreamProfileInfo.cpp
- src/DataStreams/ColumnGathererStream.cpp
- src/DataStreams/ExecutionSpeedLimits.cpp
+ src/DataStreams/BlockStreamProfileInfo.cpp
+ src/DataStreams/ColumnGathererStream.cpp
+ src/DataStreams/ExecutionSpeedLimits.cpp
src/DataStreams/IBlockInputStream.cpp
- src/DataStreams/materializeBlock.cpp
- src/DataStreams/NativeBlockInputStream.cpp
- src/DataStreams/NativeBlockOutputStream.cpp
- src/DataStreams/SizeLimits.cpp
+ src/DataStreams/materializeBlock.cpp
+ src/DataStreams/NativeBlockInputStream.cpp
+ src/DataStreams/NativeBlockOutputStream.cpp
+ src/DataStreams/SizeLimits.cpp
src/DataTypes/DataTypeArray.cpp
src/DataTypes/DataTypeDate.cpp
src/DataTypes/DataTypeDateTime.cpp
src/DataTypes/DataTypeEnum.cpp
src/DataTypes/DataTypeFactory.cpp
- src/DataTypes/DataTypeFunction.cpp
- src/DataTypes/DataTypeNested.cpp
+ src/DataTypes/DataTypeFunction.cpp
+ src/DataTypes/DataTypeNested.cpp
src/DataTypes/DataTypeNothing.cpp
src/DataTypes/DataTypeNullable.cpp
src/DataTypes/DataTypeNumberBase.cpp
@@ -194,15 +194,15 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/DataTypes/DataTypeFixedString.cpp
src/DataTypes/DataTypeDateTime64.cpp
src/DataTypes/DataTypeAggregateFunction.cpp
- src/DataTypes/DataTypeCustomGeo.cpp
- src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp
- src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp
- src/DataTypes/DataTypeLowCardinalityHelpers.cpp
- src/DataTypes/EnumValues.cpp
- src/DataTypes/IDataType.cpp
+ src/DataTypes/DataTypeCustomGeo.cpp
+ src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp
+ src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp
+ src/DataTypes/DataTypeLowCardinalityHelpers.cpp
+ src/DataTypes/EnumValues.cpp
+ src/DataTypes/IDataType.cpp
src/DataTypes/getLeastSupertype.cpp
- src/DataTypes/NestedUtils.cpp
- src/DataTypes/registerDataTypeDateTime.cpp
+ src/DataTypes/NestedUtils.cpp
+ src/DataTypes/registerDataTypeDateTime.cpp
src/DataTypes/Serializations/ISerialization.cpp
src/DataTypes/Serializations/SerializationArray.cpp
@@ -224,139 +224,139 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/DataTypes/Serializations/SerializationDate32.cpp
src/DataTypes/Serializations/SerializationFixedString.cpp
src/DataTypes/Serializations/SerializationDateTime64.cpp
- src/DataTypes/Serializations/SerializationIP.cpp
+ src/DataTypes/Serializations/SerializationIP.cpp
src/DataTypes/Serializations/SerializationAggregateFunction.cpp
- src/DataTypes/Serializations/SerializationCustomSimpleText.cpp
+ src/DataTypes/Serializations/SerializationCustomSimpleText.cpp
- src/Parsers/ASTAlterQuery.cpp
+ src/Parsers/ASTAlterQuery.cpp
src/Parsers/ASTAsterisk.cpp
- src/Parsers/ASTBackupQuery.cpp
- src/Parsers/ASTColumnDeclaration.cpp
+ src/Parsers/ASTBackupQuery.cpp
+ src/Parsers/ASTColumnDeclaration.cpp
src/Parsers/ASTColumnsMatcher.cpp
src/Parsers/ASTColumnsTransformers.cpp
src/Parsers/ASTConstraintDeclaration.cpp
src/Parsers/ASTCreateQuery.cpp
- src/Parsers/ASTDatabaseOrNone.cpp
+ src/Parsers/ASTDatabaseOrNone.cpp
src/Parsers/ASTDictionary.cpp
src/Parsers/ASTDictionaryAttributeDeclaration.cpp
- src/Parsers/ASTDropQuery.cpp
+ src/Parsers/ASTDropQuery.cpp
src/Parsers/ASTExpressionList.cpp
src/Parsers/ASTFunction.cpp
src/Parsers/ASTFunctionWithKeyValueArguments.cpp
src/Parsers/ASTIdentifier.cpp
src/Parsers/ASTIndexDeclaration.cpp
- src/Parsers/ASTKillQueryQuery.cpp
+ src/Parsers/ASTKillQueryQuery.cpp
src/Parsers/ASTLiteral.cpp
src/Parsers/ASTNameTypePair.cpp
- src/Parsers/ASTOptimizeQuery.cpp
+ src/Parsers/ASTOptimizeQuery.cpp
src/Parsers/ASTOrderByElement.cpp
- src/Parsers/ASTPartition.cpp
+ src/Parsers/ASTPartition.cpp
src/Parsers/ASTProjectionDeclaration.cpp
- src/Parsers/ASTProjectionSelectQuery.cpp
+ src/Parsers/ASTProjectionSelectQuery.cpp
src/Parsers/ASTQualifiedAsterisk.cpp
src/Parsers/ASTQueryWithOnCluster.cpp
src/Parsers/ASTQueryWithOutput.cpp
src/Parsers/ASTQueryWithTableAndOutput.cpp
- src/Parsers/ASTRolesOrUsersSet.cpp
+ src/Parsers/ASTRolesOrUsersSet.cpp
src/Parsers/ASTSelectQuery.cpp
src/Parsers/ASTSelectWithUnionQuery.cpp
src/Parsers/ASTSetQuery.cpp
- src/Parsers/ASTSetRoleQuery.cpp
- src/Parsers/ASTSettingsProfileElement.cpp
- src/Parsers/ASTShowGrantsQuery.cpp
- src/Parsers/ASTShowTablesQuery.cpp
+ src/Parsers/ASTSetRoleQuery.cpp
+ src/Parsers/ASTSettingsProfileElement.cpp
+ src/Parsers/ASTShowGrantsQuery.cpp
+ src/Parsers/ASTShowTablesQuery.cpp
src/Parsers/ASTSubquery.cpp
src/Parsers/ASTTablesInSelectQuery.cpp
src/Parsers/ASTTTLElement.cpp
src/Parsers/ASTWindowDefinition.cpp
src/Parsers/ASTWithAlias.cpp
- src/Parsers/ASTQueryParameter.cpp
- src/Parsers/ASTInsertQuery.cpp
- src/Parsers/ASTWithElement.cpp
- src/Parsers/ASTSampleRatio.cpp
- src/Parsers/ASTSystemQuery.cpp
- src/Parsers/ASTUserNameWithHost.cpp
+ src/Parsers/ASTQueryParameter.cpp
+ src/Parsers/ASTInsertQuery.cpp
+ src/Parsers/ASTWithElement.cpp
+ src/Parsers/ASTSampleRatio.cpp
+ src/Parsers/ASTSystemQuery.cpp
+ src/Parsers/ASTUserNameWithHost.cpp
src/Parsers/CommonParsers.cpp
src/Parsers/ExpressionElementParsers.cpp
src/Parsers/ExpressionListParsers.cpp
- src/Parsers/formatAST.cpp
- src/Parsers/formatSettingName.cpp
+ src/Parsers/formatAST.cpp
+ src/Parsers/formatSettingName.cpp
src/Parsers/IAST.cpp
- src/Parsers/InsertQuerySettingsPushDownVisitor.cpp
+ src/Parsers/InsertQuerySettingsPushDownVisitor.cpp
src/Parsers/IParserBase.cpp
- src/Parsers/Lexer.cpp
- src/Parsers/parseDatabaseAndTableName.cpp
+ src/Parsers/Lexer.cpp
+ src/Parsers/parseDatabaseAndTableName.cpp
src/Parsers/parseIdentifierOrStringLiteral.cpp
src/Parsers/parseIntervalKind.cpp
src/Parsers/parseQuery.cpp
- src/Parsers/parseUserName.cpp
- src/Parsers/ParserAlterQuery.cpp
- src/Parsers/ParserBackupQuery.cpp
+ src/Parsers/parseUserName.cpp
+ src/Parsers/ParserAlterQuery.cpp
+ src/Parsers/ParserBackupQuery.cpp
src/Parsers/ParserCase.cpp
- src/Parsers/ParserCheckQuery.cpp
+ src/Parsers/ParserCheckQuery.cpp
src/Parsers/ParserCreateQuery.cpp
- src/Parsers/ParserDatabaseOrNone.cpp
+ src/Parsers/ParserDatabaseOrNone.cpp
src/Parsers/ParserDataType.cpp
- src/Parsers/ParserDescribeTableQuery.cpp
+ src/Parsers/ParserDescribeTableQuery.cpp
src/Parsers/ParserDictionary.cpp
src/Parsers/ParserDictionaryAttributeDeclaration.cpp
- src/Parsers/ParserDropQuery.cpp
- src/Parsers/ParserExplainQuery.cpp
- src/Parsers/ParserExternalDDLQuery.cpp
- src/Parsers/ParserInsertQuery.cpp
- src/Parsers/ParserKillQueryQuery.cpp
- src/Parsers/ParserOptimizeQuery.cpp
- src/Parsers/ParserPartition.cpp
+ src/Parsers/ParserDropQuery.cpp
+ src/Parsers/ParserExplainQuery.cpp
+ src/Parsers/ParserExternalDDLQuery.cpp
+ src/Parsers/ParserInsertQuery.cpp
+ src/Parsers/ParserKillQueryQuery.cpp
+ src/Parsers/ParserOptimizeQuery.cpp
+ src/Parsers/ParserPartition.cpp
src/Parsers/ParserProjectionSelectQuery.cpp
- src/Parsers/ParserQuery.cpp
- src/Parsers/ParserRenameQuery.cpp
- src/Parsers/ParserRolesOrUsersSet.cpp
+ src/Parsers/ParserQuery.cpp
+ src/Parsers/ParserRenameQuery.cpp
+ src/Parsers/ParserRolesOrUsersSet.cpp
src/Parsers/ParserSelectWithUnionQuery.cpp
src/Parsers/ParserSetQuery.cpp
- src/Parsers/ParserSetRoleQuery.cpp
- src/Parsers/ParserSettingsProfileElement.cpp
+ src/Parsers/ParserSetRoleQuery.cpp
+ src/Parsers/ParserSettingsProfileElement.cpp
src/Parsers/ParserSelectQuery.cpp
- src/Parsers/ParserTablePropertiesQuery.cpp
+ src/Parsers/ParserTablePropertiesQuery.cpp
src/Parsers/ParserTablesInSelectQuery.cpp
src/Parsers/ParserSampleRatio.cpp
- src/Parsers/ParserShowGrantsQuery.cpp
- src/Parsers/ParserShowPrivilegesQuery.cpp
- src/Parsers/ParserShowTablesQuery.cpp
- src/Parsers/ParserSystemQuery.cpp
- src/Parsers/ParserUnionQueryElement.cpp
- src/Parsers/ParserUseQuery.cpp
- src/Parsers/ParserUserNameWithHost.cpp
- src/Parsers/ParserWatchQuery.cpp
- src/Parsers/ParserWithElement.cpp
- src/Parsers/queryToString.cpp
- src/Parsers/QueryWithOutputSettingsPushDownVisitor.cpp
- src/Parsers/TokenIterator.cpp
+ src/Parsers/ParserShowGrantsQuery.cpp
+ src/Parsers/ParserShowPrivilegesQuery.cpp
+ src/Parsers/ParserShowTablesQuery.cpp
+ src/Parsers/ParserSystemQuery.cpp
+ src/Parsers/ParserUnionQueryElement.cpp
+ src/Parsers/ParserUseQuery.cpp
+ src/Parsers/ParserUserNameWithHost.cpp
+ src/Parsers/ParserWatchQuery.cpp
+ src/Parsers/ParserWithElement.cpp
+ src/Parsers/queryToString.cpp
+ src/Parsers/QueryWithOutputSettingsPushDownVisitor.cpp
+ src/Parsers/TokenIterator.cpp
- src/Processors/Chunk.cpp
- src/Processors/ConcatProcessor.cpp
- src/Processors/IAccumulatingTransform.cpp
- src/Processors/IProcessor.cpp
- src/Processors/ISimpleTransform.cpp
- src/Processors/ISink.cpp
- src/Processors/LimitTransform.cpp
+ src/Processors/Chunk.cpp
+ src/Processors/ConcatProcessor.cpp
+ src/Processors/IAccumulatingTransform.cpp
+ src/Processors/IProcessor.cpp
+ src/Processors/ISimpleTransform.cpp
+ src/Processors/ISink.cpp
+ src/Processors/LimitTransform.cpp
src/Processors/ISource.cpp
- src/Processors/Port.cpp
- src/Processors/ResizeProcessor.cpp
+ src/Processors/Port.cpp
+ src/Processors/ResizeProcessor.cpp
src/Processors/Formats/IRowOutputFormat.cpp
src/Processors/Formats/IRowInputFormat.cpp
src/Processors/Formats/IInputFormat.cpp
src/Processors/Formats/IOutputFormat.cpp
src/Processors/Formats/OutputStreamToOutputFormat.cpp
- src/Processors/Formats/RowInputFormatWithDiagnosticInfo.cpp
+ src/Processors/Formats/RowInputFormatWithDiagnosticInfo.cpp
src/Interpreters/castColumn.cpp
- src/Interpreters/ClientInfo.cpp
- src/Interpreters/InternalTextLogsQueue.cpp
- src/Interpreters/QueryLog.cpp
- src/Interpreters/QueryThreadLog.cpp
- src/Interpreters/ProfileEventsExt.cpp
- src/Interpreters/TablesStatus.cpp
+ src/Interpreters/ClientInfo.cpp
+ src/Interpreters/InternalTextLogsQueue.cpp
+ src/Interpreters/QueryLog.cpp
+ src/Interpreters/QueryThreadLog.cpp
+ src/Interpreters/ProfileEventsExt.cpp
+ src/Interpreters/TablesStatus.cpp
src/Functions/CastOverloadResolver.cpp
src/Functions/FunctionHelpers.cpp
@@ -364,28 +364,28 @@ IF (OS_LINUX AND CLANG AND NOT WITH_VALGRIND)
src/Functions/IFunction.cpp
src/Functions/FunctionFactory.cpp
src/Functions/extractTimeZoneFromFunctionArguments.cpp
- src/Functions/toFixedString.cpp
+ src/Functions/toFixedString.cpp
+
+ src/Processors/Executors/PollingQueue.cpp
- src/Processors/Executors/PollingQueue.cpp
-
src/Processors/Formats/Impl/ArrowBlockInputFormat.cpp
src/Processors/Formats/Impl/ArrowBufferedStreams.cpp
src/Processors/Formats/Impl/ArrowColumnToCHColumn.cpp
src/Processors/Formats/Impl/AvroRowInputFormat.cpp
src/Processors/Formats/Impl/CHColumnToArrowColumn.cpp
- src/Processors/Formats/Impl/CSVRowInputFormat.cpp
+ src/Processors/Formats/Impl/CSVRowInputFormat.cpp
src/Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp
- src/Processors/Formats/Impl/ORCBlockInputFormat.cpp
+ src/Processors/Formats/Impl/ORCBlockInputFormat.cpp
src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp
src/Processors/Formats/Impl/RawBLOBRowInputFormat.cpp
- src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp
- src/Processors/Formats/Impl/TSKVRowInputFormat.cpp
+ src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp
+ src/Processors/Formats/Impl/TSKVRowInputFormat.cpp
)
PEERDIR(
contrib/libs/cctz
contrib/restricted/boost
- contrib/restricted/boost/libs
+ contrib/restricted/boost/libs
contrib/restricted/cityhash-1.0.2
contrib/restricted/fast_float
contrib/libs/icu
diff --git a/ydb/library/yql/udfs/common/datetime/datetime_udf.cpp b/ydb/library/yql/udfs/common/datetime/datetime_udf.cpp
index 834bf22951..01567c0b1b 100644
--- a/ydb/library/yql/udfs/common/datetime/datetime_udf.cpp
+++ b/ydb/library/yql/udfs/common/datetime/datetime_udf.cpp
@@ -49,7 +49,7 @@ namespace {
TTimeZone gmt_tz = GetTimeZone("GMT+0");
TSimpleTM ct = ToCivilTime(instant, tz);
ui64 result = ToAbsoluteTime(ct, gmt_tz).MicroSeconds() + instant.MicroSecondsOfSecond();
- return TUnboxedValuePod(result);
+ return TUnboxedValuePod(result);
}
SIMPLE_UDF(TFromTimeZone, ui64(TAutoMap<ui64>, char*)) {
@@ -61,7 +61,7 @@ namespace {
TSimpleTM tm = TSimpleTM::New(static_cast<time_t>(instant.Seconds()));
TInstant at = ToAbsoluteTime(tm, tz);
ui64 result = at.MicroSeconds() + instant.MicroSecondsOfSecond();
- return TUnboxedValuePod(result);
+ return TUnboxedValuePod(result);
}
SIMPLE_UDF(TTimestampFromTimeZone, TTimestamp(TAutoMap<ui64>, char*)) {
@@ -81,7 +81,7 @@ namespace {
const auto input = args[0].Get<ui64>();
TInstant instant = TInstant::MicroSeconds(input);
TSimpleTM tm = TSimpleTM::New(static_cast<time_t>(instant.Seconds()));
- return TUnboxedValuePod(tm.WDay == 0 || tm.WDay == 6);
+ return TUnboxedValuePod(tm.WDay == 0 || tm.WDay == 6);
}
bool TryStrptime(const TString& input, const TString& format, TInstant& result) {
@@ -161,12 +161,12 @@ namespace {
TUnboxedValue FromStringFormatImpl(const TUnboxedValuePod* args) {
EMPTY_RESULT_ON_EMPTY_ARG(0);
- const TString input(args[0].AsStringRef());
+ const TString input(args[0].AsStringRef());
const TString format(args[1].AsStringRef());
TInstant result;
bool success = TryStrptime(input, format, result);
- return success ? TUnboxedValuePod(result.MicroSeconds()) : TUnboxedValuePod();
+ return success ? TUnboxedValuePod(result.MicroSeconds()) : TUnboxedValuePod();
}
SIMPLE_UDF(TFromStringFormat, TOptional<ui64>(TOptional<char*>, char*)) {
diff --git a/ydb/library/yql/udfs/common/datetime2/datetime_udf.cpp b/ydb/library/yql/udfs/common/datetime2/datetime_udf.cpp
index 431d011f4e..763fea8024 100644
--- a/ydb/library/yql/udfs/common/datetime2/datetime_udf.cpp
+++ b/ydb/library/yql/udfs/common/datetime2/datetime_udf.cpp
@@ -51,7 +51,7 @@ namespace {
ui32 year, month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
if (!builder.FullSplitDate2(value, year, month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, timezoneId)) {
- ythrow yexception() << "Error in FullSplitDate";
+ ythrow yexception() << "Error in FullSplitDate";
}
TimezoneId = timezoneId;
@@ -86,7 +86,7 @@ namespace {
ui32 year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
if (!builder.FullSplitDatetime2(value, year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, timezoneId)) {
- ythrow yexception() << "Error in FullSplitDatetime";
+ ythrow yexception() << "Error in FullSplitDatetime";
}
TimezoneId = timezoneId;
@@ -112,7 +112,7 @@ namespace {
}
inline void FromTimestamp(const IDateBuilder& builder, ui64 value, ui16 timezoneId = 0) {
- const ui32 seconds = value / 1000000ull;
+ const ui32 seconds = value / 1000000ull;
FromDatetime(builder, seconds, timezoneId);
Microsecond = value - seconds * 1000000ull;
}
@@ -129,7 +129,7 @@ namespace {
ui32 year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
if (!builder.FullSplitDatetime2(datetime, year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, TimezoneId)) {
- ythrow yexception() << "Error in FullSplitDatetime.";
+ ythrow yexception() << "Error in FullSplitDatetime.";
}
DayOfYear = dayOfYear;
@@ -216,8 +216,8 @@ namespace {
}
inline bool ValidateTimezoneId(ui16 timezoneId) {
- const auto& zones = NUdf::GetTimezones();
- return timezoneId < zones.size() && !zones[timezoneId].empty();
+ const auto& zones = NUdf::GetTimezones();
+ return timezoneId < zones.size() && !zones[timezoneId].empty();
}
inline bool ValidateMonthShortName(const std::string_view& monthName, ui8& month) {
@@ -286,10 +286,10 @@ namespace {
return timestamp < MAX_TIMESTAMP;
}
- inline bool ValidateInterval(i64 interval) {
- return interval > -i64(MAX_TIMESTAMP) && interval < i64(MAX_TIMESTAMP);
- }
-
+ inline bool ValidateInterval(i64 interval) {
+ return interval > -i64(MAX_TIMESTAMP) && interval < i64(MAX_TIMESTAMP);
+ }
+
// Split
template <typename TUserDataType>
@@ -485,22 +485,22 @@ namespace {
GET_METHOD(Month, ui8)
SIMPLE_UDF(TGetMonthName, char*(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- static const std::array<TUnboxedValue, 12U> monthNames = {{
- TUnboxedValuePod::Embedded(TStringRef::Of("January")),
- TUnboxedValuePod::Embedded(TStringRef::Of("February")),
- TUnboxedValuePod::Embedded(TStringRef::Of("March")),
- TUnboxedValuePod::Embedded(TStringRef::Of("April")),
- TUnboxedValuePod::Embedded(TStringRef::Of("May")),
- TUnboxedValuePod::Embedded(TStringRef::Of("June")),
- TUnboxedValuePod::Embedded(TStringRef::Of("July")),
- TUnboxedValuePod::Embedded(TStringRef::Of("August")),
- TUnboxedValuePod::Embedded(TStringRef::Of("September")),
- TUnboxedValuePod::Embedded(TStringRef::Of("October")),
- TUnboxedValuePod::Embedded(TStringRef::Of("November")),
- TUnboxedValuePod::Embedded(TStringRef::Of("December"))
- }};
- return monthNames.at(GetMonth(*args) - 1U);
+ Y_UNUSED(valueBuilder);
+ static const std::array<TUnboxedValue, 12U> monthNames = {{
+ TUnboxedValuePod::Embedded(TStringRef::Of("January")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("February")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("March")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("April")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("May")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("June")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("July")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("August")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("September")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("October")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("November")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("December"))
+ }};
+ return monthNames.at(GetMonth(*args) - 1U);
}
GET_METHOD(WeekOfYear, ui8)
@@ -514,17 +514,17 @@ namespace {
GET_METHOD(DayOfWeek, ui8)
SIMPLE_UDF(TGetDayOfWeekName, char*(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- static const std::array<TUnboxedValue, 7U> dayNames = {{
- TUnboxedValuePod::Embedded(TStringRef::Of("Monday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Tuesday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Wednesday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Thursday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Friday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Saturday")),
- TUnboxedValuePod::Embedded(TStringRef::Of("Sunday"))
- }};
- return dayNames.at(GetDayOfWeek(*args) - 1U);
+ Y_UNUSED(valueBuilder);
+ static const std::array<TUnboxedValue, 7U> dayNames = {{
+ TUnboxedValuePod::Embedded(TStringRef::Of("Monday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Tuesday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Wednesday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Thursday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Friday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Saturday")),
+ TUnboxedValuePod::Embedded(TStringRef::Of("Sunday"))
+ }};
+ return dayNames.at(GetDayOfWeek(*args) - 1U);
}
GET_METHOD(Hour, ui8)
@@ -706,37 +706,37 @@ namespace {
SIMPLE_UDF(TIntervalFromDays, TOptional<TInterval>(TAutoMap<i32>)) {
Y_UNUSED(valueBuilder);
const i64 res = i64(args[0].Get<i32>()) * 86400000000ll;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
- SIMPLE_UDF(TIntervalFromHours, TOptional<TInterval>(TAutoMap<i32>)) {
+ SIMPLE_UDF(TIntervalFromHours, TOptional<TInterval>(TAutoMap<i32>)) {
Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * 3600000000ll;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ const i64 res = i64(args[0].Get<i32>()) * 3600000000ll;
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
- SIMPLE_UDF(TIntervalFromMinutes, TOptional<TInterval>(TAutoMap<i32>)) {
+ SIMPLE_UDF(TIntervalFromMinutes, TOptional<TInterval>(TAutoMap<i32>)) {
Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * 60000000ll;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ const i64 res = i64(args[0].Get<i32>()) * 60000000ll;
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
- SIMPLE_UDF(TIntervalFromSeconds, TOptional<TInterval>(TAutoMap<i32>)) {
+ SIMPLE_UDF(TIntervalFromSeconds, TOptional<TInterval>(TAutoMap<i32>)) {
Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * 1000000ll;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ const i64 res = i64(args[0].Get<i32>()) * 1000000ll;
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
- SIMPLE_UDF(TIntervalFromMilliseconds, TOptional<TInterval>(TAutoMap<i64>)) {
+ SIMPLE_UDF(TIntervalFromMilliseconds, TOptional<TInterval>(TAutoMap<i64>)) {
Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i64>()) * 1000ll;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ const i64 res = i64(args[0].Get<i64>()) * 1000ll;
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
- SIMPLE_UDF(TIntervalFromMicroseconds, TOptional<TInterval>(TAutoMap<i64>)) {
+ SIMPLE_UDF(TIntervalFromMicroseconds, TOptional<TInterval>(TAutoMap<i64>)) {
Y_UNUSED(valueBuilder);
- const i64 res = args[0].Get<i64>();
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
+ const i64 res = args[0].Get<i64>();
+ return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
}
// To*
@@ -748,12 +748,12 @@ namespace {
SIMPLE_UDF(TToHours, i32(TAutoMap<TInterval>)) {
Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(i32(args[0].Get<i64>() / 3600000000ll));
+ return TUnboxedValuePod(i32(args[0].Get<i64>() / 3600000000ll));
}
SIMPLE_UDF(TToMinutes, i32(TAutoMap<TInterval>)) {
Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(i32(args[0].Get<i64>() / 60000000ll));
+ return TUnboxedValuePod(i32(args[0].Get<i64>() / 60000000ll));
}
#define DECLARE_TO_VALUE(units, TSigned, TUnsigned) \
@@ -881,12 +881,12 @@ namespace {
auto& storage = TTMStorage::Reference(result);
auto& builder = valueBuilder->GetDateBuilder();
- const auto date = storage.ToDatetime(builder);
- const ui32 shift = 86400u * (storage.DayOfWeek - 1u);
+ const auto date = storage.ToDatetime(builder);
+ const ui32 shift = 86400u * (storage.DayOfWeek - 1u);
if (shift > date) {
return TUnboxedValuePod();
}
- storage.FromDatetime(builder, date - shift, storage.TimezoneId);
+ storage.FromDatetime(builder, date - shift, storage.TimezoneId);
storage.Hour = 0;
storage.Minute = 0;
@@ -989,33 +989,33 @@ namespace {
return DoAddMonths(args[0], args[1].Get<i32>(), valueBuilder->GetDateBuilder());
}
- template<size_t Digits, bool Exacly = true>
- struct PrintNDigits;
-
- template<bool Exacly>
- struct PrintNDigits<0U, Exacly> {
- static constexpr ui32 Miltiplier = 1U;
-
- template <typename T>
- static constexpr size_t Do(T, char*) { return 0U; }
- };
-
- template<size_t Digits, bool Exacly>
- struct PrintNDigits {
- using TNextPrint = PrintNDigits<Digits - 1U, Exacly>;
- static constexpr ui32 Miltiplier = TNextPrint::Miltiplier * 10U;
-
- template <typename T>
- static constexpr size_t Do(T in, char* out) {
- in %= Miltiplier;
- if (Exacly || in) {
- *out = "0123456789"[in / TNextPrint::Miltiplier];
- return 1U + TNextPrint::Do(in, ++out);
- }
- return 0U;
- }
- };
-
+ template<size_t Digits, bool Exacly = true>
+ struct PrintNDigits;
+
+ template<bool Exacly>
+ struct PrintNDigits<0U, Exacly> {
+ static constexpr ui32 Miltiplier = 1U;
+
+ template <typename T>
+ static constexpr size_t Do(T, char*) { return 0U; }
+ };
+
+ template<size_t Digits, bool Exacly>
+ struct PrintNDigits {
+ using TNextPrint = PrintNDigits<Digits - 1U, Exacly>;
+ static constexpr ui32 Miltiplier = TNextPrint::Miltiplier * 10U;
+
+ template <typename T>
+ static constexpr size_t Do(T in, char* out) {
+ in %= Miltiplier;
+ if (Exacly || in) {
+ *out = "0123456789"[in / TNextPrint::Miltiplier];
+ return 1U + TNextPrint::Do(in, ++out);
+ }
+ return 0U;
+ }
+ };
+
// Format
class TFormat : public TBoxedValue {
@@ -1027,10 +1027,10 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
+ TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
return TUnboxedValuePod(new TFormat(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
const TSourcePosition Pos_;
};
@@ -1064,17 +1064,17 @@ namespace {
private:
const TSourcePosition Pos_;
- const TUnboxedValue Format_;
- std::vector<std::function<size_t(char*, const TUnboxedValuePod&, const IDateBuilder&)>> Printers_;
+ const TUnboxedValue Format_;
+ std::vector<std::function<size_t(char*, const TUnboxedValuePod&, const IDateBuilder&)>> Printers_;
size_t ReservedSize_;
struct TDataPrinter {
- const std::string_view Data;
+ const std::string_view Data;
size_t operator()(char* out, const TUnboxedValuePod&, const IDateBuilder&) const {
- std::memcpy(out, Data.data(), Data.size());
- return Data.size();
+ std::memcpy(out, Data.data(), Data.size());
+ return Data.size();
}
};
@@ -1092,13 +1092,13 @@ namespace {
auto result = valueBuilder->NewStringNotFilled(ReservedSize_);
auto pos = result.AsStringRef().Data();
ui32 size = 0U;
-
+
for (const auto& printer : Printers_) {
if (const auto plus = printer(pos, value, builder)) {
size += plus;
pos += plus;
}
- }
+ }
if (size < ReservedSize_) {
result = valueBuilder->SubString(result.Release(), 0U, size);
@@ -1107,38 +1107,38 @@ namespace {
return result;
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
+ }
}
TFormat(const TUnboxedValuePod& runConfig, TSourcePosition pos)
: Pos_(pos)
, Format_(runConfig)
{
- const std::string_view formatView(Format_.AsStringRef());
- auto dataStart = formatView.begin();
- size_t dataSize = 0U;
- ReservedSize_ = 0U;
+ const std::string_view formatView(Format_.AsStringRef());
+ auto dataStart = formatView.begin();
+ size_t dataSize = 0U;
+ ReservedSize_ = 0U;
- for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) {
+ for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) {
if (*ptr != '%') {
- ++dataSize;
+ ++dataSize;
continue;
}
- if (dataSize) {
- Printers_.emplace_back(TDataPrinter{std::string_view(&*dataStart, dataSize)});
- ReservedSize_ += dataSize;
- dataSize = 0U;
+ if (dataSize) {
+ Printers_.emplace_back(TDataPrinter{std::string_view(&*dataStart, dataSize)});
+ ReservedSize_ += dataSize;
+ dataSize = 0U;
}
- if (formatView.end() == ++ptr) {
- ythrow yexception() << "format string ends with single %%";
+ if (formatView.end() == ++ptr) {
+ ythrow yexception() << "format string ends with single %%";
}
switch (*ptr) {
case '%': {
static constexpr size_t size = 1;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod&, const IDateBuilder&) {
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod&, const IDateBuilder&) {
*out = '%';
return size;
});
@@ -1147,87 +1147,87 @@ namespace {
}
case 'Y': {
static constexpr size_t size = 4;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetYear(value), out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ return PrintNDigits<size>::Do(GetYear(value), out);
});
ReservedSize_ += size;
break;
}
case 'm': {
static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetMonth(value), out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ return PrintNDigits<size>::Do(GetMonth(value), out);
});
ReservedSize_ += size;
break;
}
case 'd': {
static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetDay(value), out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ return PrintNDigits<size>::Do(GetDay(value), out);
});
ReservedSize_ += size;
break;
}
case 'H': {
static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetHour(value), out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ return PrintNDigits<size>::Do(GetHour(value), out);
});
ReservedSize_ += size;
break;
}
case 'M': {
static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetMinute(value), out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ return PrintNDigits<size>::Do(GetMinute(value), out);
});
ReservedSize_ += size;
break;
}
case 'S':
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- constexpr size_t size = 2;
- if (const auto microsecond = GetMicrosecond(value)) {
- out += PrintNDigits<size>::Do(GetSecond(value), out);
- *out++ = '.';
- constexpr size_t msize = 6;
- return size + 1U + PrintNDigits<msize, false>::Do(microsecond, out);
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ constexpr size_t size = 2;
+ if (const auto microsecond = GetMicrosecond(value)) {
+ out += PrintNDigits<size>::Do(GetSecond(value), out);
+ *out++ = '.';
+ constexpr size_t msize = 6;
+ return size + 1U + PrintNDigits<msize, false>::Do(microsecond, out);
}
- return PrintNDigits<size>::Do(GetSecond(value), out);
+ return PrintNDigits<size>::Do(GetSecond(value), out);
});
ReservedSize_ += 9;
break;
case 'z': {
static constexpr size_t size = 5;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder& builder) {
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder& builder) {
auto timezoneId = GetTimezoneId(value);
if (TTMStorage::IsUniversal(timezoneId)) {
- std::memcpy(out, "+0000", size);
+ std::memcpy(out, "+0000", size);
return size;
}
i32 shift;
if (!builder.GetTimezoneShift(GetYear(value), GetMonth(value), GetDay(value),
GetHour(value), GetMinute(value), GetSecond(value), timezoneId, shift))
{
- std::memcpy(out, "+0000", size);
+ std::memcpy(out, "+0000", size);
return size;
}
-
- *out++ = shift > 0 ? '+' : '-';
- shift = std::abs(shift);
- out += PrintNDigits<2U>::Do(shift / 60U, out);
- out += PrintNDigits<2U>::Do(shift % 60U, out);
+
+ *out++ = shift > 0 ? '+' : '-';
+ shift = std::abs(shift);
+ out += PrintNDigits<2U>::Do(shift / 60U, out);
+ out += PrintNDigits<2U>::Do(shift % 60U, out);
return size;
});
ReservedSize_ += size;
break;
}
case 'Z':
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- const auto timezoneId = GetTimezoneId(value);
- const auto tzName = NUdf::GetTimezones()[timezoneId];
+ Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
+ const auto timezoneId = GetTimezoneId(value);
+ const auto tzName = NUdf::GetTimezones()[timezoneId];
std::memcpy(out, tzName.data(), std::min(tzName.size(), MAX_TIMEZONE_NAME_LEN));
return tzName.size();
});
@@ -1287,41 +1287,41 @@ namespace {
ythrow yexception() << "invalid format character: " << *ptr;
}
- dataStart = ptr + 1U;
+ dataStart = ptr + 1U;
+ }
+
+ if (dataSize) {
+ Printers_.emplace_back(TDataPrinter{std::string_view(dataStart, dataSize)});
+ ReservedSize_ += dataSize;
}
+ }
+ };
+
+ template<size_t Digits>
+ struct ParseExaclyNDigits;
+
+ template<>
+ struct ParseExaclyNDigits<0U> {
+ template <typename T>
+ static constexpr bool Do(std::string_view::const_iterator&, T&) {
+ return true;
+ }
+ };
- if (dataSize) {
- Printers_.emplace_back(TDataPrinter{std::string_view(dataStart, dataSize)});
- ReservedSize_ += dataSize;
+ template<size_t Digits>
+ struct ParseExaclyNDigits {
+ template <typename T>
+ static constexpr bool Do(std::string_view::const_iterator& it, T& out) {
+ const auto d = *it;
+ if (!std::isdigit(d)) {
+ return false;
}
+ out *= 10U;
+ out += d - '0';
+ return ParseExaclyNDigits<Digits - 1U>::Do(++it, out);
}
};
- template<size_t Digits>
- struct ParseExaclyNDigits;
-
- template<>
- struct ParseExaclyNDigits<0U> {
- template <typename T>
- static constexpr bool Do(std::string_view::const_iterator&, T&) {
- return true;
- }
- };
-
- template<size_t Digits>
- struct ParseExaclyNDigits {
- template <typename T>
- static constexpr bool Do(std::string_view::const_iterator& it, T& out) {
- const auto d = *it;
- if (!std::isdigit(d)) {
- return false;
- }
- out *= 10U;
- out += d - '0';
- return ParseExaclyNDigits<Digits - 1U>::Do(++it, out);
- }
- };
-
// Parse
class TParse : public TBoxedValue {
@@ -1333,10 +1333,10 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
+ TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
return TUnboxedValuePod(new TParse(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
const TSourcePosition Pos_;
@@ -1375,19 +1375,19 @@ namespace {
private:
const TSourcePosition Pos_;
- const TUnboxedValue Format_;
+ const TUnboxedValue Format_;
- std::vector<std::function<bool(std::string_view::const_iterator& it, size_t, TUnboxedValuePod&, const IDateBuilder&)>> Scanners_;
+ std::vector<std::function<bool(std::string_view::const_iterator& it, size_t, TUnboxedValuePod&, const IDateBuilder&)>> Scanners_;
struct TDataScanner {
- const std::string_view Data_;
+ const std::string_view Data_;
- bool operator()(std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) const {
- if (limit < Data_.size() || !std::equal(Data_.begin(), Data_.end(), it)) {
- return false;
+ bool operator()(std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) const {
+ if (limit < Data_.size() || !std::equal(Data_.begin(), Data_.end(), it)) {
+ return false;
}
- std::advance(it, Data_.size());
- return true;
+ std::advance(it, Data_.size());
+ return true;
}
};
@@ -1426,145 +1426,145 @@ namespace {
: Pos_(pos)
, Format_(runConfig)
{
- const std::string_view formatView(Format_.AsStringRef());
- auto dataStart = formatView.begin();
- size_t dataSize = 0U;
+ const std::string_view formatView(Format_.AsStringRef());
+ auto dataStart = formatView.begin();
+ size_t dataSize = 0U;
- for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) {
+ for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) {
if (*ptr != '%') {
- ++dataSize;
+ ++dataSize;
continue;
}
- if (dataSize) {
- Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)});
- dataSize = 0;
+ if (dataSize) {
+ Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)});
+ dataSize = 0;
}
- if (++ptr == formatView.end()) {
- ythrow yexception() << "format string ends with single %%";
+ if (++ptr == formatView.end()) {
+ ythrow yexception() << "format string ends with single %%";
}
switch (*ptr) {
case '%':
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) {
- return limit > 0U && *it++ == '%';
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) {
+ return limit > 0U && *it++ == '%';
});
break;
case 'Y': {
static constexpr size_t size = 4;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 year = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, year) || !ValidateYear(year)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 year = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, year) || !ValidateYear(year)) {
+ return false;
}
SetYear(result, year);
- return true;
+ return true;
});
break;
}
case 'm': {
static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 month = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, month) || !ValidateMonth(month)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 month = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, month) || !ValidateMonth(month)) {
+ return false;
}
SetMonth(result, month);
- return true;
+ return true;
});
break;
}
case 'd': {
static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 day = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, day) || !ValidateDay(day)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 day = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, day) || !ValidateDay(day)) {
+ return false;
}
SetDay(result, day);
- return true;
+ return true;
});
break;
}
case 'H': {
static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 hour = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, hour) || !ValidateHour(hour)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 hour = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, hour) || !ValidateHour(hour)) {
+ return false;
}
SetHour(result, hour);
- return true;
+ return true;
});
break;
}
case 'M': {
static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 minute = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, minute) || !ValidateMinute(minute)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 minute = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, minute) || !ValidateMinute(minute)) {
+ return false;
}
SetMinute(result, minute);
- return true;
+ return true;
});
break;
}
case 'S': {
static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 second = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, second) || !ValidateSecond(second)) {
- return false;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
+ ui32 second = 0U;
+ if (limit < size || !ParseExaclyNDigits<size>::Do(it, second) || !ValidateSecond(second)) {
+ return false;
}
SetSecond(result, second);
- limit -= size;
-
- if (!limit || *it != '.') {
- return true;
+ limit -= size;
+
+ if (!limit || *it != '.') {
+ return true;
}
- ++it;
- --limit;
- ui32 usec = 0U;
+ ++it;
+ --limit;
+ ui32 usec = 0U;
- size_t digits = 6U;
- for (; limit; --limit) {
- const auto c = *it;
- if (!digits || !std::isdigit(c)) {
+ size_t digits = 6U;
+ for (; limit; --limit) {
+ const auto c = *it;
+ if (!digits || !std::isdigit(c)) {
break;
}
- usec *= 10U;
- usec += c - '0';
- ++it;
- --digits;
+ usec *= 10U;
+ usec += c - '0';
+ ++it;
+ --digits;
}
-
- while (digits--) {
- usec *= 10U;
+
+ while (digits--) {
+ usec *= 10U;
}
SetMicrosecond(result, usec);
- return true;
+ return true;
});
break;
}
case 'Z':
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder& builder) {
- const auto start = it;
- while (limit > 0 && (std::isalnum(*it) || *it == '/' || *it == '_' || *it == '-' || *it == '+')) {
- ++it;
+ Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder& builder) {
+ const auto start = it;
+ while (limit > 0 && (std::isalnum(*it) || *it == '/' || *it == '_' || *it == '-' || *it == '+')) {
+ ++it;
--limit;
}
- const auto size = std::distance(start, it);
+ const auto size = std::distance(start, it);
ui32 timezoneId;
- if (!builder.FindTimezoneId(TStringRef(&*start, size), timezoneId)) {
- return false;
+ if (!builder.FindTimezoneId(TStringRef(&*start, size), timezoneId)) {
+ return false;
}
SetTimezoneId(result, timezoneId);
- return true;
+ return true;
});
break;
case 'b': {
@@ -1611,11 +1611,11 @@ namespace {
ythrow yexception() << "invalid format character: " << *ptr;
}
- dataStart = ptr + 1U;
+ dataStart = ptr + 1U;
}
- if (dataSize) {
- Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)});
+ if (dataSize) {
+ Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)});
}
}
};
diff --git a/ydb/library/yql/udfs/common/digest/digest_udf.cpp b/ydb/library/yql/udfs/common/digest/digest_udf.cpp
index 5057689dd9..7487a078dd 100644
--- a/ydb/library/yql/udfs/common/digest/digest_udf.cpp
+++ b/ydb/library/yql/udfs/common/digest/digest_udf.cpp
@@ -310,46 +310,46 @@ namespace {
return TUnboxedValuePod(x);
}
- SIMPLE_UDF(TXXH3, ui64(TAutoMap<char*>)) {
- Y_UNUSED(valueBuilder);
- const auto& inputRef = args[0].AsStringRef();
- const ui64 hash = XXH3_64bits(inputRef.Data(), inputRef.Size());
- return TUnboxedValuePod(hash);
- }
-
- class TXXH3_128: public TBoxedValue {
- public:
- static TStringRef Name() {
- static auto name = TStringRef::Of("XXH3_128");
- return name;
- }
-
- static bool DeclareSignature(const TStringRef& name, TType*, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
- if (Name() == name) {
- const auto type = builder.Tuple(2)->Add<ui64>().Add<ui64>().Build();
+ SIMPLE_UDF(TXXH3, ui64(TAutoMap<char*>)) {
+ Y_UNUSED(valueBuilder);
+ const auto& inputRef = args[0].AsStringRef();
+ const ui64 hash = XXH3_64bits(inputRef.Data(), inputRef.Size());
+ return TUnboxedValuePod(hash);
+ }
+
+ class TXXH3_128: public TBoxedValue {
+ public:
+ static TStringRef Name() {
+ static auto name = TStringRef::Of("XXH3_128");
+ return name;
+ }
+
+ static bool DeclareSignature(const TStringRef& name, TType*, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
+ if (Name() == name) {
+ const auto type = builder.Tuple(2)->Add<ui64>().Add<ui64>().Build();
builder.Args(1)->Add<TAutoMap<char*>>();
- builder.Returns(type);
- if (!typesOnly) {
- builder.Implementation(new TXXH3_128);
- }
- return true;
- } else {
- return false;
- }
- }
-
- private:
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
- TUnboxedValue* items = nullptr;
- auto val = valueBuilder->NewArray(2U, items);
- const auto& inputRef = args[0].AsStringRef();
- const auto hash = XXH3_128bits(inputRef.Data(), inputRef.Size());
- items[0] = TUnboxedValuePod(ui64(hash.low64));
- items[1] = TUnboxedValuePod(ui64(hash.high64));
- return val;
- }
- };
-
+ builder.Returns(type);
+ if (!typesOnly) {
+ builder.Implementation(new TXXH3_128);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private:
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
+ TUnboxedValue* items = nullptr;
+ auto val = valueBuilder->NewArray(2U, items);
+ const auto& inputRef = args[0].AsStringRef();
+ const auto hash = XXH3_128bits(inputRef.Data(), inputRef.Size());
+ items[0] = TUnboxedValuePod(ui64(hash.low64));
+ items[1] = TUnboxedValuePod(ui64(hash.high64));
+ return val;
+ }
+ };
+
SIMPLE_MODULE(TDigestModule,
TCrc32c,
TCrc64,
@@ -375,9 +375,9 @@ namespace {
TSuperFastHash,
TSha1,
TSha256,
- TIntHash64,
- TXXH3,
- TXXH3_128
+ TIntHash64,
+ TXXH3,
+ TXXH3_128
)
}
diff --git a/ydb/library/yql/udfs/common/digest/ya.make b/ydb/library/yql/udfs/common/digest/ya.make
index 04131a048c..53ee51c8d1 100644
--- a/ydb/library/yql/udfs/common/digest/ya.make
+++ b/ydb/library/yql/udfs/common/digest/ya.make
@@ -16,7 +16,7 @@ PEERDIR(
contrib/libs/farmhash
contrib/libs/highwayhash
contrib/libs/openssl
- contrib/libs/xxhash
+ contrib/libs/xxhash
library/cpp/digest/argonish
library/cpp/digest/crc32c
library/cpp/digest/md5
diff --git a/ydb/library/yql/udfs/common/histogram/histogram_udf.cpp b/ydb/library/yql/udfs/common/histogram/histogram_udf.cpp
index 5fe5b60764..3cbf685cc1 100644
--- a/ydb/library/yql/udfs/common/histogram/histogram_udf.cpp
+++ b/ydb/library/yql/udfs/common/histogram/histogram_udf.cpp
@@ -112,7 +112,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_Create: public TBoxedValue {
+ class THistogram_Create: public TBoxedValue {
public:
THistogram_Create(TSourcePosition pos)
: Pos_(pos)
@@ -126,21 +126,21 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
THolder<THistogramResource> histogram(new THistogramResource(args[2].Get<ui32>()));
histogram->Get()->Add(args[0].Get<double>(), args[1].Get<double>());
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -163,7 +163,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_AddValue: public TBoxedValue {
+ class THistogram_AddValue: public TBoxedValue {
public:
THistogram_AddValue(TSourcePosition pos)
: Pos_(pos)
@@ -177,21 +177,21 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
THistogramResource* resource = static_cast<THistogramResource*>(args[0].AsBoxed().Get());
resource->Get()->Add(args[1].Get<double>(), args[2].Get<double>());
- return TUnboxedValuePod(args[0]);
+ return TUnboxedValuePod(args[0]);
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -214,7 +214,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_Serialize: public TBoxedValue {
+ class THistogram_Serialize: public TBoxedValue {
public:
THistogram_Serialize(TSourcePosition pos)
: Pos_(pos)
@@ -228,10 +228,10 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
THistogram proto;
TString result;
@@ -243,7 +243,7 @@ namespace {
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -266,7 +266,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_Deserialize: public TBoxedValue {
+ class THistogram_Deserialize: public TBoxedValue {
public:
THistogram_Deserialize(TSourcePosition pos)
: Pos_(pos)
@@ -280,23 +280,23 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
THistogram proto;
Y_PROTOBUF_SUPPRESS_NODISCARD proto.ParseFromString(TString(args[0].AsStringRef()));
THolder<THistogramResource> histogram(new THistogramResource(args[1].Get<ui32>()));
histogram->Get()->FromProto(proto);
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -319,7 +319,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_Merge: public TBoxedValue {
+ class THistogram_Merge: public TBoxedValue {
public:
THistogram_Merge(TSourcePosition pos)
: Pos_(pos)
@@ -333,22 +333,22 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
THistogram proto;
static_cast<THistogramResource*>(args[0].AsBoxed().Get())->Get()->ToProto(proto);
static_cast<THistogramResource*>(args[1].AsBoxed().Get())->Get()->Merge(proto, 1.0);
- return TUnboxedValuePod(args[1]);
+ return TUnboxedValuePod(args[1]);
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -371,13 +371,13 @@ namespace {
};
struct THistogramIndexes {
- static constexpr ui32 BinFieldsCount = 2U;
- static constexpr ui32 ResultFieldsCount = 4U;
-
+ static constexpr ui32 BinFieldsCount = 2U;
+ static constexpr ui32 ResultFieldsCount = 4U;
+
THistogramIndexes(IFunctionTypeInfoBuilder& builder) {
- const auto binStructType = builder.Struct(BinFieldsCount)->AddField<double>("Position", &Position).AddField<double>("Frequency", &Frequency).Build();
- const auto binsList = builder.List()->Item(binStructType).Build();
- ResultStructType = builder.Struct(ResultFieldsCount)->AddField<double>("Min", &Min).AddField<double>("Max", &Max).AddField<double>("WeightsSum", &WeightsSum).AddField("Bins", binsList, &Bins).Build();
+ const auto binStructType = builder.Struct(BinFieldsCount)->AddField<double>("Position", &Position).AddField<double>("Frequency", &Frequency).Build();
+ const auto binsList = builder.List()->Item(binStructType).Build();
+ ResultStructType = builder.Struct(ResultFieldsCount)->AddField<double>("Min", &Min).AddField<double>("Max", &Max).AddField<double>("WeightsSum", &WeightsSum).AddField("Bins", binsList, &Bins).Build();
}
ui32 Min;
@@ -392,7 +392,7 @@ namespace {
};
template <typename THistogramType, const char* ResourceName>
- class THistogram_GetResult: public TBoxedValue {
+ class THistogram_GetResult: public TBoxedValue {
public:
typedef TBoxedResource<THistogramType, ResourceName> THistogramResource;
@@ -408,40 +408,40 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
THistogram proto;
auto histogram = static_cast<THistogramResource*>(args[0].AsBoxed().Get())->Get();
histogram->ToProto(proto);
ui32 size = proto.FreqSize();
TUnboxedValue* fields = nullptr;
- auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
+ auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
if (size) {
- TUnboxedValue* items = nullptr;
- fields[HistogramIndexes.Bins] = valueBuilder->NewArray(size, items);
- fields[HistogramIndexes.Min] = TUnboxedValuePod(static_cast<double>(histogram->GetMinValue()));
- fields[HistogramIndexes.Max] = TUnboxedValuePod(static_cast<double>(histogram->GetMaxValue()));
- fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(static_cast<double>(histogram->GetSum()));
+ TUnboxedValue* items = nullptr;
+ fields[HistogramIndexes.Bins] = valueBuilder->NewArray(size, items);
+ fields[HistogramIndexes.Min] = TUnboxedValuePod(static_cast<double>(histogram->GetMinValue()));
+ fields[HistogramIndexes.Max] = TUnboxedValuePod(static_cast<double>(histogram->GetMaxValue()));
+ fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(static_cast<double>(histogram->GetSum()));
for (ui32 i = 0; i < size; ++i) {
TUnboxedValue* binFields = nullptr;
- *items++ = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
- binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(static_cast<double>(proto.GetFreq(i)));
- binFields[HistogramIndexes.Position] = TUnboxedValuePod(static_cast<double>(proto.GetPosition(i)));
+ *items++ = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
+ binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(static_cast<double>(proto.GetFreq(i)));
+ binFields[HistogramIndexes.Position] = TUnboxedValuePod(static_cast<double>(proto.GetPosition(i)));
}
} else {
fields[HistogramIndexes.Bins] = valueBuilder->NewEmptyList();
- fields[HistogramIndexes.Min] = TUnboxedValuePod(0.0);
- fields[HistogramIndexes.Max] = TUnboxedValuePod(0.0);
- fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(0.0);
+ fields[HistogramIndexes.Min] = TUnboxedValuePod(0.0);
+ fields[HistogramIndexes.Max] = TUnboxedValuePod(0.0);
+ fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(0.0);
}
return result;
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -449,7 +449,7 @@ namespace {
bool typesOnly) {
Y_UNUSED(userType);
if (Name() == name) {
- auto resource = builder.Resource(TStringRef(ResourceName, std::strlen(ResourceName)));
+ auto resource = builder.Resource(TStringRef(ResourceName, std::strlen(ResourceName)));
THistogramIndexes histogramIndexes(builder);
@@ -472,14 +472,14 @@ namespace {
template <>
TUnboxedValue THistogram_Create<TLinearHistogram, LinearHistogramResourceName>::Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const {
+ const TUnboxedValuePod* args) const {
using THistogramResource = THistogram_Create<TLinearHistogram, LinearHistogramResourceName>::THistogramResource;
try {
Y_UNUSED(valueBuilder);
THolder<THistogramResource> histogram(new THistogramResource(
args[1].Get<double>(), args[2].Get<double>(), args[3].Get<double>()));
histogram->Get()->Add(args[0].Get<double>(), 1.0);
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
@@ -506,7 +506,7 @@ namespace {
template <>
TUnboxedValue THistogram_Deserialize<TLinearHistogram, LinearHistogramResourceName>::Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const {
+ const TUnboxedValuePod* args) const {
using THistogramResource = THistogram_Deserialize<TLinearHistogram, LinearHistogramResourceName>::THistogramResource;
try {
Y_UNUSED(valueBuilder);
@@ -515,7 +515,7 @@ namespace {
THolder<THistogramResource> histogram(
new THistogramResource(args[1].Get<double>(), args[2].Get<double>(), args[3].Get<double>()));
histogram->Get()->FromProto(proto);
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
@@ -542,14 +542,14 @@ namespace {
template <>
TUnboxedValue THistogram_Create<TLogarithmicHistogram, LogarithmicHistogramResourceName>::Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const {
+ const TUnboxedValuePod* args) const {
using THistogramResource = THistogram_Create<TLogarithmicHistogram, LogarithmicHistogramResourceName>::THistogramResource;
try {
Y_UNUSED(valueBuilder);
THolder<THistogramResource> histogram(new THistogramResource(
args[1].Get<double>(), args[2].Get<double>(), args[3].Get<double>()));
histogram->Get()->Add(args[0].Get<double>(), 1.0);
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
@@ -576,7 +576,7 @@ namespace {
template <>
TUnboxedValue THistogram_Deserialize<TLogarithmicHistogram, LogarithmicHistogramResourceName>::Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const {
+ const TUnboxedValuePod* args) const {
using THistogramResource = THistogram_Deserialize<TLogarithmicHistogram, LogarithmicHistogramResourceName>::THistogramResource;
try {
Y_UNUSED(valueBuilder);
@@ -585,7 +585,7 @@ namespace {
THolder<THistogramResource> histogram(
new THistogramResource(args[1].Get<double>(), args[2].Get<double>(), args[3].Get<double>()));
histogram->Get()->FromProto(proto);
- return TUnboxedValuePod(histogram.Release());
+ return TUnboxedValuePod(histogram.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
@@ -609,7 +609,7 @@ namespace {
}
}
- class THistogramPrint: public TBoxedValue {
+ class THistogramPrint: public TBoxedValue {
public:
THistogramPrint(const THistogramIndexes& histogramIndexes)
: HistogramIndexes(histogramIndexes)
@@ -623,11 +623,11 @@ namespace {
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
- auto bins = args[0].GetElement(HistogramIndexes.Bins);
- double min = args[0].GetElement(HistogramIndexes.Min).Get<double>();
- double max = args[0].GetElement(HistogramIndexes.Max).Get<double>();
- double weightsSum = args[0].GetElement(HistogramIndexes.WeightsSum).Get<double>();
+ const TUnboxedValuePod* args) const override {
+ auto bins = args[0].GetElement(HistogramIndexes.Bins);
+ double min = args[0].GetElement(HistogramIndexes.Min).Get<double>();
+ double max = args[0].GetElement(HistogramIndexes.Max).Get<double>();
+ double weightsSum = args[0].GetElement(HistogramIndexes.WeightsSum).Get<double>();
auto binsIterator = bins.GetListIterator();
TStringBuilder result;
@@ -636,17 +636,17 @@ namespace {
double maxFrequency = 0.0;
size_t maxPositionLength = 0;
size_t maxFrequencyLength = 0;
- const ui8 bars = args[1].GetOrDefault<ui8>(25);
+ const ui8 bars = args[1].GetOrDefault<ui8>(25);
- for (TUnboxedValue current; binsIterator.Next(current);) {
+ for (TUnboxedValue current; binsIterator.Next(current);) {
if (bars) {
- double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
+ double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
if (frequency > maxFrequency) {
maxFrequency = frequency;
}
}
- size_t positionLength = Sprintf("%.3f", current.GetElement(HistogramIndexes.Position).Get<double>()).length();
- size_t frequencyLength = Sprintf("%.3f", current.GetElement(HistogramIndexes.Frequency).Get<double>()).length();
+ size_t positionLength = Sprintf("%.3f", current.GetElement(HistogramIndexes.Position).Get<double>()).length();
+ size_t frequencyLength = Sprintf("%.3f", current.GetElement(HistogramIndexes.Frequency).Get<double>()).length();
if (positionLength > maxPositionLength) {
maxPositionLength = positionLength;
@@ -657,9 +657,9 @@ namespace {
}
binsIterator = bins.GetListIterator();
- for (TUnboxedValue current; binsIterator.Next(current);) {
- double position = current.GetElement(HistogramIndexes.Position).Get<double>();
- double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
+ for (TUnboxedValue current; binsIterator.Next(current);) {
+ double position = current.GetElement(HistogramIndexes.Position).Get<double>();
+ double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
result << "\n";
if (bars && maxFrequency > 0) {
ui8 filledBars = static_cast<ui8>(bars * frequency / maxFrequency);
@@ -703,7 +703,7 @@ namespace {
const THistogramIndexes HistogramIndexes;
};
- class THistogramToCumulativeDistributionFunction: public TBoxedValue {
+ class THistogramToCumulativeDistributionFunction: public TBoxedValue {
public:
THistogramToCumulativeDistributionFunction(const THistogramIndexes& histogramIndexes)
: HistogramIndexes(histogramIndexes)
@@ -717,33 +717,33 @@ namespace {
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
- TUnboxedValue* fields = nullptr;
- auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
- auto bins = args[0].GetElement(HistogramIndexes.Bins);
- double minValue = args[0].GetElement(HistogramIndexes.Min).Get<double>();
- double maxValue = args[0].GetElement(HistogramIndexes.Max).Get<double>();
+ const TUnboxedValuePod* args) const override {
+ TUnboxedValue* fields = nullptr;
+ auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
+ auto bins = args[0].GetElement(HistogramIndexes.Bins);
+ double minValue = args[0].GetElement(HistogramIndexes.Min).Get<double>();
+ double maxValue = args[0].GetElement(HistogramIndexes.Max).Get<double>();
double sum = 0.0;
double weightsSum = 0.0;
- std::vector<TUnboxedValue> resultBins;
- if (bins.HasFastListLength())
- resultBins.reserve(bins.GetListLength());
- const auto binsIterator = bins.GetListIterator();
- for (TUnboxedValue current; binsIterator.Next(current);) {
- TUnboxedValue* binFields = nullptr;
- auto resultCurrent = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
- const auto frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
+ std::vector<TUnboxedValue> resultBins;
+ if (bins.HasFastListLength())
+ resultBins.reserve(bins.GetListLength());
+ const auto binsIterator = bins.GetListIterator();
+ for (TUnboxedValue current; binsIterator.Next(current);) {
+ TUnboxedValue* binFields = nullptr;
+ auto resultCurrent = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
+ const auto frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
sum += frequency;
weightsSum += sum;
- binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(sum);
- binFields[HistogramIndexes.Position] = current.GetElement(HistogramIndexes.Position);
- resultBins.emplace_back(std::move(resultCurrent));
+ binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(sum);
+ binFields[HistogramIndexes.Position] = current.GetElement(HistogramIndexes.Position);
+ resultBins.emplace_back(std::move(resultCurrent));
}
- fields[HistogramIndexes.Bins] = valueBuilder->NewList(resultBins.data(), resultBins.size());
- fields[HistogramIndexes.Max] = TUnboxedValuePod(maxValue);
- fields[HistogramIndexes.Min] = TUnboxedValuePod(minValue);
- fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(weightsSum);
- return result;
+ fields[HistogramIndexes.Bins] = valueBuilder->NewList(resultBins.data(), resultBins.size());
+ fields[HistogramIndexes.Max] = TUnboxedValuePod(maxValue);
+ fields[HistogramIndexes.Min] = TUnboxedValuePod(minValue);
+ fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(weightsSum);
+ return result;
}
static bool DeclareSignature(
@@ -770,7 +770,7 @@ namespace {
const THistogramIndexes HistogramIndexes;
};
- class THistogramNormalize: public TBoxedValue {
+ class THistogramNormalize: public TBoxedValue {
public:
THistogramNormalize(const THistogramIndexes& histogramIndexes)
: HistogramIndexes(histogramIndexes)
@@ -784,46 +784,46 @@ namespace {
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
- TUnboxedValue* fields = nullptr;
- auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
- auto bins = args[0].GetElement(HistogramIndexes.Bins);
- double minValue = args[0].GetElement(HistogramIndexes.Min).Get<double>();
- double maxValue = args[0].GetElement(HistogramIndexes.Max).Get<double>();
- double area = args[1].GetOrDefault<double>(100.0);
+ const TUnboxedValuePod* args) const override {
+ TUnboxedValue* fields = nullptr;
+ auto result = valueBuilder->NewArray(HistogramIndexes.ResultFieldsCount, fields);
+ auto bins = args[0].GetElement(HistogramIndexes.Bins);
+ double minValue = args[0].GetElement(HistogramIndexes.Min).Get<double>();
+ double maxValue = args[0].GetElement(HistogramIndexes.Max).Get<double>();
+ double area = args[1].GetOrDefault<double>(100.0);
bool cdfNormalization = args[2].GetOrDefault<bool>(false);
double sum = 0.0;
double weightsSum = 0.0;
double lastBinFrequency = 0.0;
- std::vector<TUnboxedValue> resultBins;
- if (bins.HasFastListLength())
- resultBins.reserve(bins.GetListLength());
- auto binsIterator = bins.GetListIterator();
- for (TUnboxedValue current; binsIterator.Next(current);) {
- sum += current.GetElement(HistogramIndexes.Frequency).Get<double>();
+ std::vector<TUnboxedValue> resultBins;
+ if (bins.HasFastListLength())
+ resultBins.reserve(bins.GetListLength());
+ auto binsIterator = bins.GetListIterator();
+ for (TUnboxedValue current; binsIterator.Next(current);) {
+ sum += current.GetElement(HistogramIndexes.Frequency).Get<double>();
lastBinFrequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
}
binsIterator = bins.GetListIterator();
- for (TUnboxedValue current; binsIterator.Next(current);) {
- TUnboxedValue* binFields = nullptr;
- auto resultCurrent = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
- double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
+ for (TUnboxedValue current; binsIterator.Next(current);) {
+ TUnboxedValue* binFields = nullptr;
+ auto resultCurrent = valueBuilder->NewArray(HistogramIndexes.BinFieldsCount, binFields);
+ double frequency = current.GetElement(HistogramIndexes.Frequency).Get<double>();
if (cdfNormalization) {
frequency = area * frequency / lastBinFrequency;
} else {
frequency = area * frequency / sum;
}
weightsSum += frequency;
- binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(frequency);
- binFields[HistogramIndexes.Position] = current.GetElement(HistogramIndexes.Position);
- resultBins.emplace_back(std::move(resultCurrent));
+ binFields[HistogramIndexes.Frequency] = TUnboxedValuePod(frequency);
+ binFields[HistogramIndexes.Position] = current.GetElement(HistogramIndexes.Position);
+ resultBins.emplace_back(std::move(resultCurrent));
}
- fields[HistogramIndexes.Bins] = valueBuilder->NewList(resultBins.data(), resultBins.size());
- fields[HistogramIndexes.Max] = TUnboxedValuePod(maxValue);
- fields[HistogramIndexes.Min] = TUnboxedValuePod(minValue);
- fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(weightsSum);
- return result;
+ fields[HistogramIndexes.Bins] = valueBuilder->NewList(resultBins.data(), resultBins.size());
+ fields[HistogramIndexes.Max] = TUnboxedValuePod(maxValue);
+ fields[HistogramIndexes.Min] = TUnboxedValuePod(minValue);
+ fields[HistogramIndexes.WeightsSum] = TUnboxedValuePod(weightsSum);
+ return result;
}
static bool DeclareSignature(
@@ -853,7 +853,7 @@ namespace {
};
template <bool twoArgs>
- class THistogramMethodBase: public TBoxedValue {
+ class THistogramMethodBase: public TBoxedValue {
public:
THistogramMethodBase(const THistogramIndexes& histogramIndexes, TSourcePosition pos)
: HistogramIndexes(histogramIndexes)
@@ -863,24 +863,24 @@ namespace {
virtual TUnboxedValue GetResult(
const THistogram& input,
- const TUnboxedValuePod* args) const = 0;
+ const TUnboxedValuePod* args) const = 0;
TUnboxedValue Run(
- const IValueBuilder*,
- const TUnboxedValuePod* args) const override {
+ const IValueBuilder*,
+ const TUnboxedValuePod* args) const override {
try {
- auto bins = args[0].GetElement(HistogramIndexes.Bins);
- double min = args[0].GetElement(HistogramIndexes.Min).template Get<double>();
- double max = args[0].GetElement(HistogramIndexes.Max).template Get<double>();
+ auto bins = args[0].GetElement(HistogramIndexes.Bins);
+ double min = args[0].GetElement(HistogramIndexes.Min).template Get<double>();
+ double max = args[0].GetElement(HistogramIndexes.Max).template Get<double>();
auto binsIterator = bins.GetListIterator();
THistogram histogram;
histogram.SetType(HT_ADAPTIVE_HISTOGRAM);
histogram.SetMinValue(min);
histogram.SetMaxValue(max);
- for (TUnboxedValue current; binsIterator.Next(current);) {
- double frequency = current.GetElement(HistogramIndexes.Frequency).template Get<double>();
- double position = current.GetElement(HistogramIndexes.Position).template Get<double>();
+ for (TUnboxedValue current; binsIterator.Next(current);) {
+ double frequency = current.GetElement(HistogramIndexes.Frequency).template Get<double>();
+ double position = current.GetElement(HistogramIndexes.Position).template Get<double>();
histogram.AddFreq(frequency);
histogram.AddPosition(position);
}
diff --git a/ydb/library/yql/udfs/common/hyperloglog/hyperloglog_udf.cpp b/ydb/library/yql/udfs/common/hyperloglog/hyperloglog_udf.cpp
index b71069b153..b4b52639dc 100644
--- a/ydb/library/yql/udfs/common/hyperloglog/hyperloglog_udf.cpp
+++ b/ydb/library/yql/udfs/common/hyperloglog/hyperloglog_udf.cpp
@@ -129,7 +129,7 @@ namespace {
using THyperLogLogResource = TBoxedResource<THybridHyperLogLog, HyperLogLogResourceName>;
- class THyperLogLog_Create: public TBoxedValue {
+ class THyperLogLog_Create: public TBoxedValue {
public:
THyperLogLog_Create(TSourcePosition pos)
: Pos_(pos)
@@ -140,20 +140,20 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
- const IValueBuilder*,
- const TUnboxedValuePod* args) const override {
+ const IValueBuilder*,
+ const TUnboxedValuePod* args) const override {
try {
THolder<THyperLogLogResource> hll(new THyperLogLogResource(THybridHyperLogLog::Create(args[1].Get<ui32>())));
hll->Get()->Update(args[0].Get<ui64>());
- return TUnboxedValuePod(hll.Release());
+ return TUnboxedValuePod(hll.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -175,7 +175,7 @@ namespace {
TSourcePosition Pos_;
};
- class THyperLogLog_AddValue: public TBoxedValue {
+ class THyperLogLog_AddValue: public TBoxedValue {
public:
THyperLogLog_AddValue(TSourcePosition pos)
: Pos_(pos)
@@ -186,21 +186,21 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
THyperLogLogResource* resource = static_cast<THyperLogLogResource*>(args[0].AsBoxed().Get());
resource->Get()->Update(args[1].Get<ui64>());
- return TUnboxedValuePod(args[0]);
+ return TUnboxedValuePod(args[0]);
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -222,7 +222,7 @@ namespace {
TSourcePosition Pos_;
};
- class THyperLogLog_Serialize: public TBoxedValue {
+ class THyperLogLog_Serialize: public TBoxedValue {
public:
THyperLogLog_Serialize(TSourcePosition pos)
: Pos_(pos)
@@ -234,10 +234,10 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
TStringStream result;
static_cast<THyperLogLogResource*>(args[0].AsBoxed().Get())->Get()->Save(result);
@@ -247,7 +247,7 @@ namespace {
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -269,7 +269,7 @@ namespace {
TSourcePosition Pos_;
};
- class THyperLogLog_Deserialize: public TBoxedValue {
+ class THyperLogLog_Deserialize: public TBoxedValue {
public:
THyperLogLog_Deserialize(TSourcePosition pos)
: Pos_(pos)
@@ -280,22 +280,22 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
const TString arg(args[0].AsStringRef());
TStringInput input(arg);
THolder<THyperLogLogResource> hll(new THyperLogLogResource(THybridHyperLogLog::Load(input)));
- return TUnboxedValuePod(hll.Release());
+ return TUnboxedValuePod(hll.Release());
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -317,7 +317,7 @@ namespace {
TSourcePosition Pos_;
};
- class THyperLogLog_Merge: public TBoxedValue {
+ class THyperLogLog_Merge: public TBoxedValue {
public:
THyperLogLog_Merge(TSourcePosition pos)
: Pos_(pos)
@@ -328,21 +328,21 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
try {
Y_UNUSED(valueBuilder);
auto left = static_cast<THyperLogLogResource*>(args[0].AsBoxed().Get())->Get();
static_cast<THyperLogLogResource*>(args[1].AsBoxed().Get())->Get()->Merge(*left);
- return TUnboxedValuePod(args[1]);
+ return TUnboxedValuePod(args[1]);
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
@@ -364,7 +364,7 @@ namespace {
TSourcePosition Pos_;
};
- class THyperLogLog_GetResult: public TBoxedValue {
+ class THyperLogLog_GetResult: public TBoxedValue {
public:
THyperLogLog_GetResult(TSourcePosition pos)
: Pos_(pos)
@@ -375,16 +375,16 @@ namespace {
return nameRef;
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
Y_UNUSED(valueBuilder);
auto hll = static_cast<THyperLogLogResource*>(args[0].AsBoxed().Get())->Get();
return TUnboxedValuePod(hll->Estimate());
}
- public:
+ public:
static bool DeclareSignature(
const TStringRef& name,
TType* userType,
diff --git a/ydb/library/yql/udfs/common/hyperscan/hyperscan_udf.cpp b/ydb/library/yql/udfs/common/hyperscan/hyperscan_udf.cpp
index ee435ab90e..bc9251897f 100644
--- a/ydb/library/yql/udfs/common/hyperscan/hyperscan_udf.cpp
+++ b/ydb/library/yql/udfs/common/hyperscan/hyperscan_udf.cpp
@@ -8,8 +8,8 @@
#include <library/cpp/regex/pcre/regexp.h>
#include <util/charset/utf8.h>
-#include <util/string/split.h>
-#include <util/string/builder.h>
+#include <util/string/split.h>
+#include <util/string/builder.h>
#include <util/system/cpu_id.h>
using namespace NHyperscan;
@@ -109,14 +109,14 @@ namespace {
}
THyperscanMatch(
- const IValueBuilder*,
+ const IValueBuilder*,
const TUnboxedValuePod& runConfig,
bool surroundMode,
THyperscanMatch::EMode mode,
TSourcePosition pos,
size_t regexpsCount)
- : Regex_(runConfig.AsStringRef())
- , Mode(mode)
+ : Regex_(runConfig.AsStringRef())
+ , Mode(mode)
, Pos_(pos)
, RegexpsCount(regexpsCount)
{
@@ -126,55 +126,55 @@ namespace {
if (Mode == THyperscanMatch::EMode::BACKTRACKING && Regex_.StartsWith(IGNORE_CASE_PREFIX)) {
pcreOptions |= REG_ICASE;
}
- auto regex = Regex_;
- SetCommonOptions(regex, options);
+ auto regex = Regex_;
+ SetCommonOptions(regex, options);
switch (mode) {
case THyperscanMatch::EMode::NORMAL: {
- if (!surroundMode) {
- regex = TStringBuilder() << '^' << regex << '$';
- }
- Database_ = Compile(regex, options);
+ if (!surroundMode) {
+ regex = TStringBuilder() << '^' << regex << '$';
+ }
+ Database_ = Compile(regex, options);
break;
}
case THyperscanMatch::EMode::BACKTRACKING: {
- if (!surroundMode) {
- regex = TStringBuilder() << '^' << regex << '$';
- }
+ if (!surroundMode) {
+ regex = TStringBuilder() << '^' << regex << '$';
+ }
try {
- Database_ = Compile(regex, options);
+ Database_ = Compile(regex, options);
Mode = THyperscanMatch::EMode::NORMAL;
} catch (const TCompileException&) {
options |= HS_FLAG_PREFILTER;
- Database_ = Compile(regex, options);
- Fallback_ = TRegExMatch(regex, pcreOptions);
+ Database_ = Compile(regex, options);
+ Fallback_ = TRegExMatch(regex, pcreOptions);
}
break;
}
case THyperscanMatch::EMode::MULTI: {
- std::vector<TString> regexes;
+ std::vector<TString> regexes;
TVector<const char*> cregexes;
TVector<TOptions> flags;
TVector<TOptions> ids;
-
- const auto func = [&regexes, &flags, surroundMode](const std::string_view& token) {
- TString regex(token);
-
- TOptions opt = 0;
- SetCommonOptions(regex, opt);
-
- if (!surroundMode) {
- regex = TStringBuilder() << '^' << regex << '$';
- }
-
- regexes.emplace_back(std::move(regex));
- flags.emplace_back(opt);
- };
- StringSplitter(Regex_).Split('\n').Consume(func);
-
- std::transform(regexes.cbegin(), regexes.cend(), std::back_inserter(cregexes), std::bind(&TString::c_str, std::placeholders::_1));
- ids.resize(regexes.size());
- std::iota(ids.begin(), ids.end(), 0);
-
+
+ const auto func = [&regexes, &flags, surroundMode](const std::string_view& token) {
+ TString regex(token);
+
+ TOptions opt = 0;
+ SetCommonOptions(regex, opt);
+
+ if (!surroundMode) {
+ regex = TStringBuilder() << '^' << regex << '$';
+ }
+
+ regexes.emplace_back(std::move(regex));
+ flags.emplace_back(opt);
+ };
+ StringSplitter(Regex_).Split('\n').Consume(func);
+
+ std::transform(regexes.cbegin(), regexes.cend(), std::back_inserter(cregexes), std::bind(&TString::c_str, std::placeholders::_1));
+ ids.resize(regexes.size());
+ std::iota(ids.begin(), ids.end(), 0);
+
Database_ = CompileMulti(cregexes, flags, ids);
break;
}
@@ -188,46 +188,46 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- TUnboxedValue* items = nullptr;
- TUnboxedValue tuple;
- size_t i = 0;
-
- if (Mode == THyperscanMatch::EMode::MULTI) {
- tuple = valueBuilder->NewArray(RegexpsCount, items);
- for (i = 0; i < RegexpsCount; ++i) {
- items[i] = TUnboxedValuePod(false);
+ const TUnboxedValuePod* args) const final try {
+ TUnboxedValue* items = nullptr;
+ TUnboxedValue tuple;
+ size_t i = 0;
+
+ if (Mode == THyperscanMatch::EMode::MULTI) {
+ tuple = valueBuilder->NewArray(RegexpsCount, items);
+ for (i = 0; i < RegexpsCount; ++i) {
+ items[i] = TUnboxedValuePod(false);
}
- }
-
- if (args[0]) {
- const std::string_view input(args[0].AsStringRef());
- if (Y_UNLIKELY(Mode == THyperscanMatch::EMode::MULTI)) {
- auto callback = [items] (TOptions id, ui64 /* from */, ui64 /* to */) {
- items[id] = TUnboxedValuePod(true);
- };
- Scan(Database_, Scratch_, input, callback);
- return tuple;
- } else {
- bool matches = Matches(Database_, Scratch_, input);
- if (matches && Mode == THyperscanMatch::EMode::BACKTRACKING) {
- matches = Fallback_.Match(input.data());
+ }
+
+ if (args[0]) {
+ const std::string_view input(args[0].AsStringRef());
+ if (Y_UNLIKELY(Mode == THyperscanMatch::EMode::MULTI)) {
+ auto callback = [items] (TOptions id, ui64 /* from */, ui64 /* to */) {
+ items[id] = TUnboxedValuePod(true);
+ };
+ Scan(Database_, Scratch_, input, callback);
+ return tuple;
+ } else {
+ bool matches = Matches(Database_, Scratch_, input);
+ if (matches && Mode == THyperscanMatch::EMode::BACKTRACKING) {
+ matches = Fallback_.Match(input.data());
}
- return TUnboxedValuePod(matches);
- }
+ return TUnboxedValuePod(matches);
+ }
- } else {
- return Mode == THyperscanMatch::EMode::MULTI ? tuple : TUnboxedValue(TUnboxedValuePod(false));
+ } else {
+ return Mode == THyperscanMatch::EMode::MULTI ? tuple : TUnboxedValue(TUnboxedValuePod(false));
}
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
private:
- const TString Regex_;
+ const TString Regex_;
THyperscanMatch::EMode Mode;
- const TSourcePosition Pos_;
- const size_t RegexpsCount;
+ const TSourcePosition Pos_;
+ const size_t RegexpsCount;
TDatabase Database_;
TScratch Scratch_;
TRegExMatch Fallback_;
@@ -242,11 +242,11 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*,
- const TUnboxedValuePod* args) const final try {
- return TUnboxedValuePod(new THyperscanCapture(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ TUnboxedValue Run(const IValueBuilder*,
+ const TUnboxedValuePod* args) const final try {
+ return TUnboxedValuePod(new THyperscanCapture(args[0], Pos_));
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
private:
@@ -274,23 +274,23 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- if (const auto arg = args[0]) {
-
- TUnboxedValue result;
- auto callback = [valueBuilder, arg, &result] (TOptions id, ui64 from, ui64 to) {
- Y_UNUSED(id);
- if (!result) {
- result = valueBuilder->SubString(arg, from, to);
- }
- };
- Scan(Database_, Scratch_, arg.AsStringRef(), callback);
- return result;
- }
-
- return TUnboxedValue();
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ const TUnboxedValuePod* args) const final try {
+ if (const auto arg = args[0]) {
+
+ TUnboxedValue result;
+ auto callback = [valueBuilder, arg, &result] (TOptions id, ui64 from, ui64 to) {
+ Y_UNUSED(id);
+ if (!result) {
+ result = valueBuilder->SubString(arg, from, to);
+ }
+ };
+ Scan(Database_, Scratch_, arg.AsStringRef(), callback);
+ return result;
+ }
+
+ return TUnboxedValue();
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
TSourcePosition Pos_;
@@ -308,11 +308,11 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*,
- const TUnboxedValuePod* args) const final try {
- return TUnboxedValuePod(new THyperscanReplace(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ TUnboxedValue Run(const IValueBuilder*,
+ const TUnboxedValuePod* args) const final try {
+ return TUnboxedValuePod(new THyperscanReplace(args[0], Pos_));
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
private:
@@ -340,34 +340,34 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- if (args[0]) {
- const std::string_view input(args[0].AsStringRef());
- const std::string_view replacement(args[1].AsStringRef());
-
- ui64 index = 0;
- TStringBuilder result;
- auto callback = [input, replacement, &index, &result] (TOptions id, ui64 from, ui64 to) {
- Y_UNUSED(id);
- if (index != from) {
- result << input.substr(index, from - index);
- }
- result << replacement;
- index = to;
- };
- Scan(Database_, Scratch_, input, callback);
-
- if (!index) {
- return args[0];
+ const TUnboxedValuePod* args) const final try {
+ if (args[0]) {
+ const std::string_view input(args[0].AsStringRef());
+ const std::string_view replacement(args[1].AsStringRef());
+
+ ui64 index = 0;
+ TStringBuilder result;
+ auto callback = [input, replacement, &index, &result] (TOptions id, ui64 from, ui64 to) {
+ Y_UNUSED(id);
+ if (index != from) {
+ result << input.substr(index, from - index);
+ }
+ result << replacement;
+ index = to;
+ };
+ Scan(Database_, Scratch_, input, callback);
+
+ if (!index) {
+ return args[0];
}
- result << input.substr(index);
- return valueBuilder->NewString(result);
+ result << input.substr(index);
+ return valueBuilder->NewString(result);
}
-
- return TUnboxedValue();
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+
+ return TUnboxedValue();
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
TSourcePosition Pos_;
@@ -430,7 +430,7 @@ namespace {
} else if (isMultiMatch || isMultiGrep) {
auto boolType = builder.SimpleType<bool>();
auto optionalStringType = builder.Optional()->Item<char*>().Build();
- const std::string_view regexp(typeConfig);
+ const std::string_view regexp(typeConfig);
size_t regexpCount = std::count(regexp.begin(), regexp.end(), '\n') + 1;
auto tuple = builder.Tuple();
for (size_t i = 0; i < regexpCount; ++i) {
@@ -440,7 +440,7 @@ namespace {
builder.Args(1)->Add(optionalStringType).Done().Returns(tupleType).RunConfig<char*>();
if (!typesOnly) {
- builder.Implementation(new THyperscanMatch::TFactory(builder.GetSourcePosition(), isMultiGrep, THyperscanMatch::EMode::MULTI, regexpCount));
+ builder.Implementation(new THyperscanMatch::TFactory(builder.GetSourcePosition(), isMultiGrep, THyperscanMatch::EMode::MULTI, regexpCount));
}
} else if (THyperscanCapture::Name() == name) {
builder.SimpleSignature<TOptional<char*>(TOptional<char*>)>()
diff --git a/ydb/library/yql/udfs/common/hyperscan/ya.make b/ydb/library/yql/udfs/common/hyperscan/ya.make
index ef86f22d95..f8bb10662d 100644
--- a/ydb/library/yql/udfs/common/hyperscan/ya.make
+++ b/ydb/library/yql/udfs/common/hyperscan/ya.make
@@ -6,7 +6,7 @@ IF (OS_LINUX AND CLANG)
YQL_ABI_VERSION(
2
- 23
+ 23
0
)
diff --git a/ydb/library/yql/udfs/common/json/json_udf.cpp b/ydb/library/yql/udfs/common/json/json_udf.cpp
index c58fe7f626..e994e589bd 100644
--- a/ydb/library/yql/udfs/common/json/json_udf.cpp
+++ b/ydb/library/yql/udfs/common/json/json_udf.cpp
@@ -21,20 +21,20 @@ namespace {
if (!args[0]) {
return valueBuilder->NewEmptyList();
}
-
+
const TString json(args[0].AsStringRef());
const TString field(args[1].AsStringRef());
-
+
if (field.empty()) {
return valueBuilder->NewEmptyList();
}
NJson::TJsonParser parser;
parser.AddField(field, false);
-
+
TVector<TString> result;
parser.Parse(json, &result);
-
+
TUnboxedValue* items = nullptr;
const auto list = valueBuilder->NewArray(result.size(), items);
for (const TString& item : result) {
diff --git a/ydb/library/yql/udfs/common/json2/sql_value.h b/ydb/library/yql/udfs/common/json2/sql_value.h
index 6b61a581e8..5960c0749e 100644
--- a/ydb/library/yql/udfs/common/json2/sql_value.h
+++ b/ydb/library/yql/udfs/common/json2/sql_value.h
@@ -12,7 +12,7 @@
#include <util/generic/yexception.h>
#include <util/generic/ylimits.h>
-#include <util/string/cast.h>
+#include <util/string/cast.h>
namespace NJson2Udf {
using namespace NKikimr;
@@ -291,4 +291,4 @@ namespace NJson2Udf {
return TStringRef::Of("JsonDocumentSqlValueBool");
}
-}
+}
diff --git a/ydb/library/yql/udfs/common/json2/ya.make b/ydb/library/yql/udfs/common/json2/ya.make
index 80582ab859..617d3c9d00 100644
--- a/ydb/library/yql/udfs/common/json2/ya.make
+++ b/ydb/library/yql/udfs/common/json2/ya.make
@@ -2,7 +2,7 @@ YQL_UDF(json2_udf)
YQL_ABI_VERSION(
2
- 21
+ 21
0
)
diff --git a/ydb/library/yql/udfs/common/math/math_ir.h b/ydb/library/yql/udfs/common/math/math_ir.h
index 20e4f1b81d..2386be96b9 100644
--- a/ydb/library/yql/udfs/common/math/math_ir.h
+++ b/ydb/library/yql/udfs/common/math/math_ir.h
@@ -8,7 +8,7 @@
#include <math.h>
-namespace NYql {
+namespace NYql {
namespace NUdf {
#define CONST_FUNCS(XX) \
@@ -126,4 +126,4 @@ void RemIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueB
}
} // NUdf
-} // NYql
+} // NYql
diff --git a/ydb/library/yql/udfs/common/pire/pire_udf.cpp b/ydb/library/yql/udfs/common/pire/pire_udf.cpp
index d3a2b78585..9592959683 100644
--- a/ydb/library/yql/udfs/common/pire/pire_udf.cpp
+++ b/ydb/library/yql/udfs/common/pire/pire_udf.cpp
@@ -7,7 +7,7 @@
#include <library/cpp/regex/pire/regexp.h>
#include <library/cpp/regex/pire/pcre2pire.h>
-#include <util/string/builder.h>
+#include <util/string/builder.h>
using namespace NRegExp;
using namespace NKikimr;
@@ -20,10 +20,10 @@ namespace {
: Pos_(pos)
{}
- void SetCommonOptions(std::string_view& regex, TFsm::TOptions& options) {
- if (regex.size() >= 4U && regex.substr(0U, 4U) == "(?i)") {
+ void SetCommonOptions(std::string_view& regex, TFsm::TOptions& options) {
+ if (regex.size() >= 4U && regex.substr(0U, 4U) == "(?i)") {
options.SetCaseInsensitive(true);
- regex.remove_prefix(4U);
+ regex.remove_prefix(4U);
}
if (UTF8Detect(regex) == UTF8) {
options.SetCharset(CODES_UTF8);
@@ -52,7 +52,7 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final {
+ const TUnboxedValuePod* args) const final {
return TUnboxedValuePod(
new TPireMatch(
valueBuilder,
@@ -82,11 +82,11 @@ namespace {
TPireMatch(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod& runConfig,
+ const TUnboxedValuePod& runConfig,
bool surroundMode,
bool multiMode,
TSourcePosition pos,
- size_t regexpsCount)
+ size_t regexpsCount)
: TPireUdfBase(pos)
, MultiMode(multiMode)
, RegexpsCount(regexpsCount)
@@ -94,26 +94,26 @@ namespace {
{
Y_UNUSED(valueBuilder);
try {
- std::string_view regex(runConfig.AsStringRef());
+ std::string_view regex(runConfig.AsStringRef());
TFsm::TOptions options;
options.SetSurround(surroundMode);
SetCommonOptions(regex, options);
if (multiMode) {
- std::vector<std::string_view> parts;
- StringSplitter(regex).Split('\n').AddTo(&parts);
- for (const auto& part : parts) {
- if (!part.empty()) {
- if (Fsm_) try {
- *Fsm_ = *Fsm_ | TFsm(TString(part), options);
+ std::vector<std::string_view> parts;
+ StringSplitter(regex).Split('\n').AddTo(&parts);
+ for (const auto& part : parts) {
+ if (!part.empty()) {
+ if (Fsm_) try {
+ *Fsm_ = *Fsm_ | TFsm(TString(part), options);
} catch (const yexception&) {
UdfTerminate((TStringBuilder() << Pos_ << " Failed to glue up regexes, probably the finite state machine appeared to be too large").data());
- } else {
- Fsm_.Reset(new TFsm(TString(part), options));
+ } else {
+ Fsm_.Reset(new TFsm(TString(part), options));
}
}
}
} else {
- Fsm_.Reset(new TFsm(TString(regex), options));
+ Fsm_.Reset(new TFsm(TString(regex), options));
}
} catch (const std::exception& e) {
UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
@@ -123,43 +123,43 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- TUnboxedValue* items = nullptr;
- TUnboxedValue tuple;
- size_t i = 0;
+ const TUnboxedValuePod* args) const final try {
+ TUnboxedValue* items = nullptr;
+ TUnboxedValue tuple;
+ size_t i = 0;
- if (MultiMode) {
- tuple = valueBuilder->NewArray(RegexpsCount, items);
+ if (MultiMode) {
+ tuple = valueBuilder->NewArray(RegexpsCount, items);
- for (i = 0; i < RegexpsCount; ++i) {
- items[i] = TUnboxedValuePod(false);
+ for (i = 0; i < RegexpsCount; ++i) {
+ items[i] = TUnboxedValuePod(false);
}
- }
-
- if (args[0]) {
- const auto input = args[0].AsStringRef();
- TMatcher matcher(*Fsm_);
- const bool isMatch = matcher.Match(input.Data(), input.Size(), SurroundMode, SurroundMode).Final();
- if (MultiMode) {
- if (isMatch) {
- const auto& matchedRegexps = matcher.MatchedRegexps();
- size_t matchesCount = matchedRegexps.second - matchedRegexps.first;
-
- for (i = 0; i < matchesCount; ++i) {
- items[matchedRegexps.first[i]] = TUnboxedValuePod(true);
+ }
+
+ if (args[0]) {
+ const auto input = args[0].AsStringRef();
+ TMatcher matcher(*Fsm_);
+ const bool isMatch = matcher.Match(input.Data(), input.Size(), SurroundMode, SurroundMode).Final();
+ if (MultiMode) {
+ if (isMatch) {
+ const auto& matchedRegexps = matcher.MatchedRegexps();
+ size_t matchesCount = matchedRegexps.second - matchedRegexps.first;
+
+ for (i = 0; i < matchesCount; ++i) {
+ items[matchedRegexps.first[i]] = TUnboxedValuePod(true);
}
}
- return tuple;
+ return tuple;
} else {
- return TUnboxedValuePod(isMatch);
+ return TUnboxedValuePod(isMatch);
}
-
- } else {
- return MultiMode ? tuple : TUnboxedValue(TUnboxedValuePod(false));
+
+ } else {
+ return MultiMode ? tuple : TUnboxedValue(TUnboxedValuePod(false));
}
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
private:
@@ -178,10 +178,10 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
- return TUnboxedValuePod(new TPireCapture(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
+ return TUnboxedValuePod(new TPireCapture(args[0], Pos_));
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
};
@@ -193,7 +193,7 @@ namespace {
TPireCapture(const TUnboxedValuePod& runConfig, TSourcePosition pos)
: TPireUdfBase(pos)
{
- std::string_view regex(runConfig.AsStringRef());
+ std::string_view regex(runConfig.AsStringRef());
TFsm::TOptions options;
SetCommonOptions(regex, options);
Fsm_.Reset(new TSlowCapturingFsm(TString(regex), options));
@@ -202,22 +202,22 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- if (args[0]) {
- const std::string_view input = args[0].AsStringRef();
+ const TUnboxedValuePod* args) const final try {
+ if (args[0]) {
+ const std::string_view input = args[0].AsStringRef();
TSlowSearcher searcher(*Fsm_);
searcher.Search(input.data(), input.size());
- if (searcher.Captured()) {
- const auto& captured = searcher.GetCaptured();
- return valueBuilder->SubString(args[0], std::distance(input.begin(), captured.begin()), captured.length());
+ if (searcher.Captured()) {
+ const auto& captured = searcher.GetCaptured();
+ return valueBuilder->SubString(args[0], std::distance(input.begin(), captured.begin()), captured.length());
}
- }
+ }
- return TUnboxedValue();
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ return TUnboxedValue();
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
TUniquePtr<TSlowCapturingFsm> Fsm_;
@@ -232,10 +232,10 @@ namespace {
{}
private:
- TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
- return TUnboxedValuePod(new TPireReplace(args[0], Pos_));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
+ return TUnboxedValuePod(new TPireReplace(args[0], Pos_));
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
};
@@ -247,7 +247,7 @@ namespace {
TPireReplace(const TUnboxedValuePod& runConfig, TSourcePosition pos)
: TPireUdfBase(pos)
{
- std::string_view regex(runConfig.AsStringRef());
+ std::string_view regex(runConfig.AsStringRef());
TFsm::TOptions options;
SetCommonOptions(regex, options);
Fsm_.Reset(new TSlowCapturingFsm(TString(regex), options));
@@ -256,26 +256,26 @@ namespace {
private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- if (args[0]) {
- const std::string_view input(args[0].AsStringRef());
+ const TUnboxedValuePod* args) const final try {
+ if (args[0]) {
+ const std::string_view input(args[0].AsStringRef());
TSlowSearcher s(*Fsm_);
s.Search(input.data(), input.size());
- if (s.Captured()) {
- const auto& captured = s.GetCaptured();
- const TString replacement(args[1].AsStringRef());
- TString replaced(args[0].AsStringRef());
- replaced.replace(std::distance(input.begin(), captured.begin()), captured.length(), replacement);
- return valueBuilder->NewString(replaced);
+ if (s.Captured()) {
+ const auto& captured = s.GetCaptured();
+ const TString replacement(args[1].AsStringRef());
+ TString replaced(args[0].AsStringRef());
+ replaced.replace(std::distance(input.begin(), captured.begin()), captured.length(), replacement);
+ return valueBuilder->NewString(replaced);
} else {
- return TUnboxedValue(args[0]);
+ return TUnboxedValue(args[0]);
}
- } else {
- return TUnboxedValue();
+ } else {
+ return TUnboxedValue();
}
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
TUniquePtr<TSlowCapturingFsm> Fsm_;
@@ -301,55 +301,55 @@ namespace {
void BuildFunctionTypeInfo(
const TStringRef& name,
- TType*,
+ TType*,
const TStringRef& typeConfig,
ui32 flags,
- IFunctionTypeInfoBuilder& builder) const final try {
- const bool typesOnly = (flags & TFlags::TypesOnly);
- const bool isMatch = (TPireMatch::Name(false, false) == name);
- const bool isGrep = (TPireMatch::Name(true, false) == name);
- const bool isMultiMatch = (TPireMatch::Name(false, true) == name);
- const bool isMultiGrep = (TPireMatch::Name(true, true) == name);
-
- if (isMatch || isGrep) {
- builder.SimpleSignature<bool(TOptional<char*>)>()
- .RunConfig<const char*>();
-
- if (!typesOnly) {
- builder.Implementation(new TPireMatch::TFactory(isGrep, false, builder.GetSourcePosition()));
- }
- } else if (isMultiMatch || isMultiGrep) {
- const auto boolType = builder.SimpleType<bool>();
- const auto optionalStringType = builder.Optional()->Item<char*>().Build();
- const std::string_view regexp(typeConfig);
- const size_t regexpCount = std::count(regexp.begin(), regexp.end(), '\n') + 1;
- const auto tuple = builder.Tuple();
- for (size_t i = 0; i < regexpCount; ++i) {
- tuple->Add(boolType);
- }
- const auto tupleType = tuple->Build();
- builder.Args(1)->Add(optionalStringType).Done().Returns(tupleType).RunConfig<char*>();
-
- if (!typesOnly) {
- builder.Implementation(new TPireMatch::TFactory(isMultiGrep, true, builder.GetSourcePosition(), regexpCount));
- }
- } else if (TPireCapture::Name() == name) {
- builder.SimpleSignature<TOptional<char*>(TOptional<char*>)>()
- .RunConfig<char*>();
-
- if (!typesOnly) {
- builder.Implementation(new TPireCapture::TFactory(builder.GetSourcePosition()));
- }
- } else if (TPireReplace::Name() == name) {
- builder.SimpleSignature<TOptional<char*>(TOptional<char*>, char*)>()
- .RunConfig<char*>();
-
- if (!typesOnly) {
- builder.Implementation(new TPireReplace::TFactory(builder.GetSourcePosition()));
+ IFunctionTypeInfoBuilder& builder) const final try {
+ const bool typesOnly = (flags & TFlags::TypesOnly);
+ const bool isMatch = (TPireMatch::Name(false, false) == name);
+ const bool isGrep = (TPireMatch::Name(true, false) == name);
+ const bool isMultiMatch = (TPireMatch::Name(false, true) == name);
+ const bool isMultiGrep = (TPireMatch::Name(true, true) == name);
+
+ if (isMatch || isGrep) {
+ builder.SimpleSignature<bool(TOptional<char*>)>()
+ .RunConfig<const char*>();
+
+ if (!typesOnly) {
+ builder.Implementation(new TPireMatch::TFactory(isGrep, false, builder.GetSourcePosition()));
+ }
+ } else if (isMultiMatch || isMultiGrep) {
+ const auto boolType = builder.SimpleType<bool>();
+ const auto optionalStringType = builder.Optional()->Item<char*>().Build();
+ const std::string_view regexp(typeConfig);
+ const size_t regexpCount = std::count(regexp.begin(), regexp.end(), '\n') + 1;
+ const auto tuple = builder.Tuple();
+ for (size_t i = 0; i < regexpCount; ++i) {
+ tuple->Add(boolType);
+ }
+ const auto tupleType = tuple->Build();
+ builder.Args(1)->Add(optionalStringType).Done().Returns(tupleType).RunConfig<char*>();
+
+ if (!typesOnly) {
+ builder.Implementation(new TPireMatch::TFactory(isMultiGrep, true, builder.GetSourcePosition(), regexpCount));
+ }
+ } else if (TPireCapture::Name() == name) {
+ builder.SimpleSignature<TOptional<char*>(TOptional<char*>)>()
+ .RunConfig<char*>();
+
+ if (!typesOnly) {
+ builder.Implementation(new TPireCapture::TFactory(builder.GetSourcePosition()));
+ }
+ } else if (TPireReplace::Name() == name) {
+ builder.SimpleSignature<TOptional<char*>(TOptional<char*>, char*)>()
+ .RunConfig<char*>();
+
+ if (!typesOnly) {
+ builder.Implementation(new TPireReplace::TFactory(builder.GetSourcePosition()));
}
}
- } catch (const std::exception& e) {
- builder.SetError(CurrentExceptionMessage());
+ } catch (const std::exception& e) {
+ builder.SetError(CurrentExceptionMessage());
}
};
diff --git a/ydb/library/yql/udfs/common/pire/ya.make b/ydb/library/yql/udfs/common/pire/ya.make
index 398391913c..ba65dd6d10 100644
--- a/ydb/library/yql/udfs/common/pire/ya.make
+++ b/ydb/library/yql/udfs/common/pire/ya.make
@@ -2,7 +2,7 @@ YQL_UDF(pire_udf)
YQL_ABI_VERSION(
2
- 23
+ 23
0
)
diff --git a/ydb/library/yql/udfs/common/re2/re2_udf.cpp b/ydb/library/yql/udfs/common/re2/re2_udf.cpp
index abcce72b34..b478675fb6 100644
--- a/ydb/library/yql/udfs/common/re2/re2_udf.cpp
+++ b/ydb/library/yql/udfs/common/re2/re2_udf.cpp
@@ -77,11 +77,11 @@ namespace {
{
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
- return TUnboxedValuePod(
+ const TUnboxedValuePod* args) const override {
+ return TUnboxedValuePod(
new TRe2Udf(
valueBuilder,
args[0],
@@ -91,7 +91,7 @@ namespace {
OptionsSchema,
Pos_));
}
-
+
EMode Mode;
const TOptionsSchema OptionsSchema;
TSourcePosition Pos_;
@@ -124,8 +124,8 @@ namespace {
}
TRe2Udf(
- const IValueBuilder*,
- const TUnboxedValuePod& runConfig,
+ const IValueBuilder*,
+ const TUnboxedValuePod& runConfig,
const TRegexpGroups regexpGroups,
EMode mode,
bool posix,
@@ -138,9 +138,9 @@ namespace {
, Pos_(pos)
{
try {
- auto patternValue = runConfig.GetElement(0);
- auto optionsValue = runConfig.GetElement(1);
- const std::string_view pattern(patternValue.AsStringRef());
+ auto patternValue = runConfig.GetElement(0);
+ auto optionsValue = runConfig.GetElement(1);
+ const std::string_view pattern(patternValue.AsStringRef());
RE2::Options options;
options.set_posix_syntax(posix);
@@ -150,16 +150,16 @@ namespace {
? RE2::Options::Encoding::EncodingUTF8
: RE2::Options::Encoding::EncodingLatin1
);
- if (optionsValue) {
-#define FIELD_HANDLE(name, index, type, defVal, setter, conv) options.setter(conv(optionsValue.GetElement(OptionsSchema.Indices[index]).Get<type>()));
+ if (optionsValue) {
+#define FIELD_HANDLE(name, index, type, defVal, setter, conv) options.setter(conv(optionsValue.GetElement(OptionsSchema.Indices[index]).Get<type>()));
OPTIONS_MAP(FIELD_HANDLE)
#undef FIELD_HANDLE
}
- Regexp = std::make_unique<RE2>(StringPiece(pattern.data(), pattern.size()), options);
+ Regexp = std::make_unique<RE2>(StringPiece(pattern.data(), pattern.size()), options);
if (mode == EMode::CAPTURE) {
- Captured = std::make_unique<StringPiece[]>(Regexp->NumberOfCapturingGroups() + 1);
+ Captured = std::make_unique<StringPiece[]>(Regexp->NumberOfCapturingGroups() + 1);
}
} catch (const std::exception& e) {
@@ -167,99 +167,99 @@ namespace {
}
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try {
- RE2::Anchor anchor = RE2::UNANCHORED;
- if (args[0]) {
- const std::string_view input(args[0].AsStringRef());
- const StringPiece piece(input.data(), input.size());
-
- switch (Mode) {
- case MATCH:
- anchor = RE2::ANCHOR_BOTH;
+ const TUnboxedValuePod* args) const final try {
+ RE2::Anchor anchor = RE2::UNANCHORED;
+ if (args[0]) {
+ const std::string_view input(args[0].AsStringRef());
+ const StringPiece piece(input.data(), input.size());
+
+ switch (Mode) {
+ case MATCH:
+ anchor = RE2::ANCHOR_BOTH;
[[fallthrough]];
- case GREP:
- return TUnboxedValuePod(Regexp->Match(piece, 0, input.size(), anchor, nullptr, 0));
- case CAPTURE: {
- const int count = Regexp->NumberOfCapturingGroups() + 1;
- TUnboxedValue* items = nullptr;
- const auto result = valueBuilder->NewArray(RegexpGroups.Names.size(), items);
- if (Regexp->Match(piece, 0, input.size(), anchor, Captured.get(), count)) {
- for (int i = 0; i < count; ++i) {
- if (!Captured[i].empty()) {
- items[RegexpGroups.Indexes[i]] = valueBuilder->SubString(args[0], std::distance(piece.begin(), Captured[i].begin()), Captured[i].size());
+ case GREP:
+ return TUnboxedValuePod(Regexp->Match(piece, 0, input.size(), anchor, nullptr, 0));
+ case CAPTURE: {
+ const int count = Regexp->NumberOfCapturingGroups() + 1;
+ TUnboxedValue* items = nullptr;
+ const auto result = valueBuilder->NewArray(RegexpGroups.Names.size(), items);
+ if (Regexp->Match(piece, 0, input.size(), anchor, Captured.get(), count)) {
+ for (int i = 0; i < count; ++i) {
+ if (!Captured[i].empty()) {
+ items[RegexpGroups.Indexes[i]] = valueBuilder->SubString(args[0], std::distance(piece.begin(), Captured[i].begin()), Captured[i].size());
}
}
- } else {
- return BuildEmptyStruct(valueBuilder);
+ } else {
+ return BuildEmptyStruct(valueBuilder);
}
- return result;
- }
- case REPLACE: {
- const std::string_view rewriteRef(args[1].AsStringRef());
- const StringPiece rewrite(rewriteRef.data(), rewriteRef.size());
- TString rewriteError;
- if (!Regexp->CheckRewriteString(rewrite, &rewriteError)) {
- UdfTerminate((TStringBuilder() << Pos_ << " [rewrite error] " << rewriteError).data());
+ return result;
+ }
+ case REPLACE: {
+ const std::string_view rewriteRef(args[1].AsStringRef());
+ const StringPiece rewrite(rewriteRef.data(), rewriteRef.size());
+ TString rewriteError;
+ if (!Regexp->CheckRewriteString(rewrite, &rewriteError)) {
+ UdfTerminate((TStringBuilder() << Pos_ << " [rewrite error] " << rewriteError).data());
}
std::string result(input);
- RE2::GlobalReplace(&result, *Regexp, rewrite);
- return input == result ? TUnboxedValue(args[0]) : valueBuilder->NewString(result);
- }
- case COUNT: {
+ RE2::GlobalReplace(&result, *Regexp, rewrite);
+ return input == result ? TUnboxedValue(args[0]) : valueBuilder->NewString(result);
+ }
+ case COUNT: {
std::string inputHolder(input);
- const ui32 result = RE2::GlobalReplace(&inputHolder, *Regexp, "");
- return TUnboxedValuePod(result);
- }
- case FIND_AND_CONSUME: {
- StringPiece text(piece);
- std::vector<TUnboxedValue> matches;
- for (StringPiece w; RE2::FindAndConsume(&text, *Regexp, &w);) {
- matches.emplace_back(valueBuilder->SubString(args[0], std::distance(piece.begin(), w.begin()), w.size()));
+ const ui32 result = RE2::GlobalReplace(&inputHolder, *Regexp, "");
+ return TUnboxedValuePod(result);
+ }
+ case FIND_AND_CONSUME: {
+ StringPiece text(piece);
+ std::vector<TUnboxedValue> matches;
+ for (StringPiece w; RE2::FindAndConsume(&text, *Regexp, &w);) {
+ matches.emplace_back(valueBuilder->SubString(args[0], std::distance(piece.begin(), w.begin()), w.size()));
}
- return valueBuilder->NewList(matches.data(), matches.size());
+ return valueBuilder->NewList(matches.data(), matches.size());
}
}
- Y_FAIL("Unexpected mode");
- } else {
- switch (Mode) {
- case MATCH:
- case GREP:
- return TUnboxedValuePod(false);
- case CAPTURE:
- return BuildEmptyStruct(valueBuilder);
- case REPLACE:
- return TUnboxedValuePod();
- case COUNT:
- return TUnboxedValuePod::Zero();
- case FIND_AND_CONSUME:
- return valueBuilder->NewEmptyList();
- }
- Y_FAIL("Unexpected mode");
+ Y_FAIL("Unexpected mode");
+ } else {
+ switch (Mode) {
+ case MATCH:
+ case GREP:
+ return TUnboxedValuePod(false);
+ case CAPTURE:
+ return BuildEmptyStruct(valueBuilder);
+ case REPLACE:
+ return TUnboxedValuePod();
+ case COUNT:
+ return TUnboxedValuePod::Zero();
+ case FIND_AND_CONSUME:
+ return valueBuilder->NewEmptyList();
+ }
+ Y_FAIL("Unexpected mode");
}
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
+ } catch (const std::exception& e) {
+ UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
}
-
- std::unique_ptr<RE2> Regexp;
+
+ std::unique_ptr<RE2> Regexp;
const TRegexpGroups RegexpGroups;
EMode Mode;
- std::unique_ptr<StringPiece[]> Captured;
+ std::unique_ptr<StringPiece[]> Captured;
const TOptionsSchema OptionsSchema;
TSourcePosition Pos_;
TUnboxedValue BuildEmptyStruct(const IValueBuilder* valueBuilder) const {
TUnboxedValue* items = nullptr;
- return valueBuilder->NewArray(RegexpGroups.Names.size(), items);
+ return valueBuilder->NewArray(RegexpGroups.Names.size(), items);
}
};
SIMPLE_UDF(TEscape, char*(char*)) {
- const std::string_view input(args[0].AsStringRef());
- const auto& result = RE2::QuoteMeta(StringPiece(input.data(), input.size()));
- return input == result ? TUnboxedValue(args[0]) : valueBuilder->NewString(result);
+ const std::string_view input(args[0].AsStringRef());
+ const auto& result = RE2::QuoteMeta(StringPiece(input.data(), input.size()));
+ return input == result ? TUnboxedValue(args[0]) : valueBuilder->NewString(result);
}
TOptionsSchema MakeOptionsSchema(::NKikimr::NUdf::IFunctionTypeInfoBuilder& builder) {
@@ -285,9 +285,9 @@ namespace {
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override {
+ const TUnboxedValuePod* args) const override {
TUnboxedValue* items = nullptr;
- const auto result = valueBuilder->NewArray(EOptionsField::Count, items);
+ const auto result = valueBuilder->NewArray(EOptionsField::Count, items);
#define FIELD_HANDLE(name, index, type, defVal, ...) \
{ \
auto structIndex = Schema_.Indices[index]; \
@@ -334,17 +334,17 @@ namespace {
};
SIMPLE_UDF_OPTIONS(TPatternFromLike, char*(char*, TOptional<char*>), builder.OptionalArgs(1)) {
- const std::string_view input(args[0].AsStringRef());
- const bool hasEscape = bool(args[1]);
+ const std::string_view input(args[0].AsStringRef());
+ const bool hasEscape = bool(args[1]);
char escape = 0;
if (hasEscape) {
- const std::string_view escapeRef(args[1].AsStringRef());
- if (escapeRef.size() != 1U) {
+ const std::string_view escapeRef(args[1].AsStringRef());
+ if (escapeRef.size() != 1U) {
UdfTerminate((TStringBuilder() << Pos_ << " Escape should be single character").data());
}
- escape = escapeRef.front();
+ escape = escapeRef.front();
}
- const TString escaped(RE2::QuoteMeta(StringPiece(input.data(), input.size())));
+ const TString escaped(RE2::QuoteMeta(StringPiece(input.data(), input.size())));
TStringBuilder result;
result << "(?s)";
@@ -354,10 +354,10 @@ namespace {
for (const char& c : escaped) {
switch (c) {
case '\\':
- if (slash) {
- result << "\\\\";
- }
- slash = !slash;
+ if (slash) {
+ result << "\\\\";
+ }
+ slash = !slash;
break;
case '%':
if (escapeOn) {
@@ -366,33 +366,33 @@ namespace {
} else {
result << ".*";
}
- slash = false;
+ slash = false;
break;
case '_':
if (escapeOn) {
result << "\\_";
escapeOn = false;
} else {
- result << '.';
+ result << '.';
}
- slash = false;
+ slash = false;
break;
default:
if (hasEscape && c == escape) {
if (escapeOn) {
result << c;
}
- escapeOn = !escapeOn;
+ escapeOn = !escapeOn;
} else {
- if (slash)
- result << '\\';
+ if (slash)
+ result << '\\';
result << c;
}
- slash = false;
- break;
+ slash = false;
+ break;
}
}
- return valueBuilder->NewString(result);
+ return valueBuilder->NewString(result);
}
TType* MakeRunConfigType(IFunctionTypeInfoBuilder& builder, TType* optOptionsStructType) {
@@ -409,16 +409,16 @@ namespace {
void CleanupOnTerminate() const final {
}
- void GetAllFunctions(IFunctionsSink& sink) const final {
- sink.Add(TRe2Udf::Name(TRe2Udf::EMode::MATCH));
- sink.Add(TRe2Udf::Name(TRe2Udf::EMode::GREP));
+ void GetAllFunctions(IFunctionsSink& sink) const final {
+ sink.Add(TRe2Udf::Name(TRe2Udf::EMode::MATCH));
+ sink.Add(TRe2Udf::Name(TRe2Udf::EMode::GREP));
sink.Add(TRe2Udf::Name(TRe2Udf::EMode::CAPTURE))->SetTypeAwareness();
- sink.Add(TRe2Udf::Name(TRe2Udf::EMode::REPLACE));
- sink.Add(TRe2Udf::Name(TRe2Udf::EMode::COUNT));
+ sink.Add(TRe2Udf::Name(TRe2Udf::EMode::REPLACE));
+ sink.Add(TRe2Udf::Name(TRe2Udf::EMode::COUNT));
sink.Add(TRe2Udf::Name(TRe2Udf::EMode::FIND_AND_CONSUME));
- sink.Add(TEscape::Name());
- sink.Add(TPatternFromLike::Name());
- sink.Add(TOptions::Name());
+ sink.Add(TEscape::Name());
+ sink.Add(TPatternFromLike::Name());
+ sink.Add(TOptions::Name());
}
void BuildFunctionTypeInfo(
@@ -426,94 +426,94 @@ namespace {
TType* userType,
const TStringRef& typeConfig,
ui32 flags,
- IFunctionTypeInfoBuilder& builder) const final try {
- Y_UNUSED(userType);
- TOptionsSchema optionsSchema = MakeOptionsSchema(builder);
- auto optOptionsStructType = builder.Optional()->Item(optionsSchema.StructType).Build();
-
- bool typesOnly = (flags & TFlags::TypesOnly);
- bool isMatch = (TRe2Udf::Name(TRe2Udf::EMode::MATCH) == name);
- bool isGrep = (TRe2Udf::Name(TRe2Udf::EMode::GREP) == name);
- bool isCapture = (TRe2Udf::Name(TRe2Udf::EMode::CAPTURE) == name);
- bool isReplace = (TRe2Udf::Name(TRe2Udf::EMode::REPLACE) == name);
- bool isCount = (TRe2Udf::Name(TRe2Udf::EMode::COUNT) == name);
- bool isFindAndConsume = (TRe2Udf::Name(TRe2Udf::FIND_AND_CONSUME) == name);
-
- if (isMatch || isGrep) {
- builder.SimpleSignature<bool(TOptional<char*>)>()
- .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
-
- if (!typesOnly) {
- const auto mode = isMatch ? TRe2Udf::EMode::MATCH : TRe2Udf::EMode::GREP;
- builder.Implementation(new TRe2Udf::TFactory<posix>(mode, optionsSchema, builder.GetSourcePosition()));
- }
- } else if (isCapture) {
- TRegexpGroups groups;
- auto optionalStringType = builder.Optional()->Item<char*>().Build();
- auto structBuilder = builder.Struct();
- RE2 regexp(StringPiece(typeConfig.Data(), typeConfig.Size()));
- const auto& groupNames = regexp.CapturingGroupNames();
- int groupCount = regexp.NumberOfCapturingGroups();
- if (groupCount >= 0) {
- int unnamedCount = 0;
- ++groupCount;
- groups.Indexes.resize(groupCount);
- groups.Names.resize(groupCount);
- for (int i = 0; i < groupCount; ++i) {
- TString fieldName;
- auto it = groupNames.find(i);
- if (it != groupNames.end()) {
- fieldName = it->second;
+ IFunctionTypeInfoBuilder& builder) const final try {
+ Y_UNUSED(userType);
+ TOptionsSchema optionsSchema = MakeOptionsSchema(builder);
+ auto optOptionsStructType = builder.Optional()->Item(optionsSchema.StructType).Build();
+
+ bool typesOnly = (flags & TFlags::TypesOnly);
+ bool isMatch = (TRe2Udf::Name(TRe2Udf::EMode::MATCH) == name);
+ bool isGrep = (TRe2Udf::Name(TRe2Udf::EMode::GREP) == name);
+ bool isCapture = (TRe2Udf::Name(TRe2Udf::EMode::CAPTURE) == name);
+ bool isReplace = (TRe2Udf::Name(TRe2Udf::EMode::REPLACE) == name);
+ bool isCount = (TRe2Udf::Name(TRe2Udf::EMode::COUNT) == name);
+ bool isFindAndConsume = (TRe2Udf::Name(TRe2Udf::FIND_AND_CONSUME) == name);
+
+ if (isMatch || isGrep) {
+ builder.SimpleSignature<bool(TOptional<char*>)>()
+ .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
+
+ if (!typesOnly) {
+ const auto mode = isMatch ? TRe2Udf::EMode::MATCH : TRe2Udf::EMode::GREP;
+ builder.Implementation(new TRe2Udf::TFactory<posix>(mode, optionsSchema, builder.GetSourcePosition()));
+ }
+ } else if (isCapture) {
+ TRegexpGroups groups;
+ auto optionalStringType = builder.Optional()->Item<char*>().Build();
+ auto structBuilder = builder.Struct();
+ RE2 regexp(StringPiece(typeConfig.Data(), typeConfig.Size()));
+ const auto& groupNames = regexp.CapturingGroupNames();
+ int groupCount = regexp.NumberOfCapturingGroups();
+ if (groupCount >= 0) {
+ int unnamedCount = 0;
+ ++groupCount;
+ groups.Indexes.resize(groupCount);
+ groups.Names.resize(groupCount);
+ for (int i = 0; i < groupCount; ++i) {
+ TString fieldName;
+ auto it = groupNames.find(i);
+ if (it != groupNames.end()) {
+ fieldName = it->second;
} else {
- fieldName = "_" + ToString(unnamedCount);
- ++unnamedCount;
+ fieldName = "_" + ToString(unnamedCount);
+ ++unnamedCount;
}
- groups.Names[i] = fieldName;
- structBuilder->AddField(fieldName, optionalStringType, &groups.Indexes[i]);
+ groups.Names[i] = fieldName;
+ structBuilder->AddField(fieldName, optionalStringType, &groups.Indexes[i]);
}
- builder.Args(1)->Add(optionalStringType).Done().Returns(structBuilder->Build()).RunConfig(MakeRunConfigType(builder, optOptionsStructType));
+ builder.Args(1)->Add(optionalStringType).Done().Returns(structBuilder->Build()).RunConfig(MakeRunConfigType(builder, optOptionsStructType));
if (!typesOnly) {
- builder.Implementation(
- new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::CAPTURE, optionsSchema, builder.GetSourcePosition(), groups));
+ builder.Implementation(
+ new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::CAPTURE, optionsSchema, builder.GetSourcePosition(), groups));
}
- } else {
- if (regexp.ok()) {
- builder.SetError("Regexp contains no capturing groups");
- } else {
+ } else {
+ if (regexp.ok()) {
+ builder.SetError("Regexp contains no capturing groups");
+ } else {
builder.SetError(regexp.error());
}
}
- } else if (isReplace) {
- builder.SimpleSignature<TOptional<char*>(TOptional<char*>, char*)>()
- .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
-
- if (!typesOnly) {
- builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::REPLACE, optionsSchema, builder.GetSourcePosition()));
- }
- } else if (isCount) {
- builder.SimpleSignature<ui32(TOptional<char*>)>()
- .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
-
- if (!typesOnly) {
- builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::COUNT, optionsSchema, builder.GetSourcePosition()));
- }
- } else if (isFindAndConsume) {
- builder.SimpleSignature<TListType<char*>(TOptional<char*>)>()
- .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
- if (!typesOnly) {
- builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::FIND_AND_CONSUME, optionsSchema, builder.GetSourcePosition()));
- }
- } else if (!(
- TEscape::DeclareSignature(name, userType, builder, typesOnly) ||
- TPatternFromLike::DeclareSignature(name, userType, builder, typesOnly) ||
- TOptions::DeclareSignature(name, userType, builder, typesOnly))) {
- builder.SetError(
- TStringBuilder() << "Unknown function name: " << TString(name));
+ } else if (isReplace) {
+ builder.SimpleSignature<TOptional<char*>(TOptional<char*>, char*)>()
+ .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
+
+ if (!typesOnly) {
+ builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::REPLACE, optionsSchema, builder.GetSourcePosition()));
+ }
+ } else if (isCount) {
+ builder.SimpleSignature<ui32(TOptional<char*>)>()
+ .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
+
+ if (!typesOnly) {
+ builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::COUNT, optionsSchema, builder.GetSourcePosition()));
+ }
+ } else if (isFindAndConsume) {
+ builder.SimpleSignature<TListType<char*>(TOptional<char*>)>()
+ .RunConfig(MakeRunConfigType(builder, optOptionsStructType));
+ if (!typesOnly) {
+ builder.Implementation(new TRe2Udf::TFactory<posix>(TRe2Udf::EMode::FIND_AND_CONSUME, optionsSchema, builder.GetSourcePosition()));
+ }
+ } else if (!(
+ TEscape::DeclareSignature(name, userType, builder, typesOnly) ||
+ TPatternFromLike::DeclareSignature(name, userType, builder, typesOnly) ||
+ TOptions::DeclareSignature(name, userType, builder, typesOnly))) {
+ builder.SetError(
+ TStringBuilder() << "Unknown function name: " << TString(name));
}
- } catch (const std::exception& e) {
- builder.SetError(CurrentExceptionMessage());
+ } catch (const std::exception& e) {
+ builder.SetError(CurrentExceptionMessage());
}
};
diff --git a/ydb/library/yql/udfs/common/set/set_udf.cpp b/ydb/library/yql/udfs/common/set/set_udf.cpp
index 487760fe99..f282c22842 100644
--- a/ydb/library/yql/udfs/common/set/set_udf.cpp
+++ b/ydb/library/yql/udfs/common/set/set_udf.cpp
@@ -12,7 +12,7 @@ namespace {
template <typename THash, typename TEquals>
class TSetBase {
private:
- std::unordered_set<TUnboxedValue, THash, TEquals, TUnboxedValue::TAllocator> Set;
+ std::unordered_set<TUnboxedValue, THash, TEquals, TUnboxedValue::TAllocator> Set;
ui32 MaxSize = 0;
bool WasChanged = false;
diff --git a/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp b/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
index 175208ab84..d6da83539e 100644
--- a/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
+++ b/ydb/library/yql/udfs/common/stat/stat_udf_ut.cpp
@@ -8,187 +8,187 @@
#include <util/system/sanitizers.h>
#include <array>
-namespace NYql {
-using namespace NKikimr::NMiniKQL;
-
+namespace NYql {
+using namespace NKikimr::NMiniKQL;
+
namespace NUdf {
extern NUdf::TUniquePtr<NUdf::IUdfModule> CreateStatModule();
}
- Y_UNIT_TEST_SUITE(TUDFStatTest) {
- Y_UNIT_TEST(SimplePercentile) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
+ Y_UNIT_TEST_SUITE(TUDFStatTest) {
+ Y_UNIT_TEST(SimplePercentile) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
auto timeProvider = CreateDeterministicTimeProvider(10000000);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
-
- TRuntimeNode pgmDigest;
- {
- auto param1 = pgmBuilder.NewDataLiteral<double>(0.0);
- TVector<TRuntimeNode> params = {param1};
- pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
- }
-
- for (int n = 1; n < 10; n += 1) {
- auto param2 = pgmBuilder.NewDataLiteral((double)n);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
- }
-
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.5, 0.001);
- }
-
- Y_UNIT_TEST(SimplePercentileSpecific) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
- auto timeProvider = CreateDeterministicTimeProvider(1);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
-
- TRuntimeNode pgmDigest;
- {
- auto param1 = pgmBuilder.NewDataLiteral<double>(75.0);
- TVector<TRuntimeNode> params = {param1};
- pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+
+ TRuntimeNode pgmDigest;
+ {
+ auto param1 = pgmBuilder.NewDataLiteral<double>(0.0);
+ TVector<TRuntimeNode> params = {param1};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
+ }
+
+ for (int n = 1; n < 10; n += 1) {
+ auto param2 = pgmBuilder.NewDataLiteral((double)n);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
+ }
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.5, 0.001);
+ }
+
+ Y_UNIT_TEST(SimplePercentileSpecific) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
+ auto timeProvider = CreateDeterministicTimeProvider(1);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+
+ TRuntimeNode pgmDigest;
+ {
+ auto param1 = pgmBuilder.NewDataLiteral<double>(75.0);
+ TVector<TRuntimeNode> params = {param1};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
+ }
+
+ TVector<double> vals = {800, 20, 150};
+ for (auto val : vals) {
+ auto param2 = pgmBuilder.NewDataLiteral(val);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param2 = pgmBuilder.NewDataLiteral<double>(0.5);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
+ }
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ Cerr << value.Get<double>() << Endl;
+ //~ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 9.0, 0.001);
+ }
+
+ Y_UNIT_TEST(SerializedPercentile) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
+ auto timeProvider = CreateDeterministicTimeProvider(1);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+ auto udfTDigest_Serialize = pgmBuilder.Udf("Stat.TDigest_Serialize");
+ auto udfTDigest_Deserialize = pgmBuilder.Udf("Stat.TDigest_Deserialize");
+
+ TRuntimeNode pgmDigest;
+ {
+ auto param1 = pgmBuilder.NewDataLiteral<double>(0.0);
+ TVector<TRuntimeNode> params = {param1};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
}
- TVector<double> vals = {800, 20, 150};
- for (auto val : vals) {
- auto param2 = pgmBuilder.NewDataLiteral(val);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param2 = pgmBuilder.NewDataLiteral<double>(0.5);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
- }
-
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- Cerr << value.Get<double>() << Endl;
- //~ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 9.0, 0.001);
- }
-
- Y_UNIT_TEST(SerializedPercentile) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
- auto timeProvider = CreateDeterministicTimeProvider(1);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
- auto udfTDigest_Serialize = pgmBuilder.Udf("Stat.TDigest_Serialize");
- auto udfTDigest_Deserialize = pgmBuilder.Udf("Stat.TDigest_Deserialize");
-
- TRuntimeNode pgmDigest;
- {
- auto param1 = pgmBuilder.NewDataLiteral<double>(0.0);
- TVector<TRuntimeNode> params = {param1};
- pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
+ for (int n = 1; n < 10; n += 1) {
+ auto param2 = pgmBuilder.NewDataLiteral((double)n);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
}
- for (int n = 1; n < 10; n += 1) {
- auto param2 = pgmBuilder.NewDataLiteral((double)n);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
- }
-
- TRuntimeNode pgmSerializedData;
- {
- TVector<TRuntimeNode> params = {pgmDigest};
- pgmSerializedData = pgmBuilder.Apply(udfTDigest_Serialize, params);
- }
-
- TRuntimeNode pgmDigest2;
- {
- TVector<TRuntimeNode> params = {pgmSerializedData};
- pgmDigest2 = pgmBuilder.Apply(udfTDigest_Deserialize, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
- TVector<TRuntimeNode> params = {pgmDigest2, param2};
- pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
- }
-
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.5, 0.001);
- }
-
- Y_UNIT_TEST(SerializedMergedPercentile) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
- auto timeProvider = CreateDeterministicTimeProvider(1);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
- auto udfTDigest_Serialize = pgmBuilder.Udf("Stat.TDigest_Serialize");
- auto udfTDigest_Deserialize = pgmBuilder.Udf("Stat.TDigest_Deserialize");
- auto udfTDigest_Merge = pgmBuilder.Udf("Stat.TDigest_Merge");
-
- TVector<TRuntimeNode> pgmSerializedDataVector;
-
- for (int i = 0; i < 100; i += 10) {
+ TRuntimeNode pgmSerializedData;
+ {
+ TVector<TRuntimeNode> params = {pgmDigest};
+ pgmSerializedData = pgmBuilder.Apply(udfTDigest_Serialize, params);
+ }
+
+ TRuntimeNode pgmDigest2;
+ {
+ TVector<TRuntimeNode> params = {pgmSerializedData};
+ pgmDigest2 = pgmBuilder.Apply(udfTDigest_Deserialize, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
+ TVector<TRuntimeNode> params = {pgmDigest2, param2};
+ pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
+ }
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.5, 0.001);
+ }
+
+ Y_UNIT_TEST(SerializedMergedPercentile) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
+ auto timeProvider = CreateDeterministicTimeProvider(1);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+ auto udfTDigest_Serialize = pgmBuilder.Udf("Stat.TDigest_Serialize");
+ auto udfTDigest_Deserialize = pgmBuilder.Udf("Stat.TDigest_Deserialize");
+ auto udfTDigest_Merge = pgmBuilder.Udf("Stat.TDigest_Merge");
+
+ TVector<TRuntimeNode> pgmSerializedDataVector;
+
+ for (int i = 0; i < 100; i += 10) {
TRuntimeNode pgmDigest;
{
- auto param1 = pgmBuilder.NewDataLiteral(double(i) / 10);
+ auto param1 = pgmBuilder.NewDataLiteral(double(i) / 10);
TVector<TRuntimeNode> params = {param1};
pgmDigest = pgmBuilder.Apply(udfTDigest_Create, params);
}
- for (int n = i + 1; n < i + 10; n += 1) {
- auto param2 = pgmBuilder.NewDataLiteral(double(n) / 10);
+ for (int n = i + 1; n < i + 10; n += 1) {
+ auto param2 = pgmBuilder.NewDataLiteral(double(n) / 10);
TVector<TRuntimeNode> params = {pgmDigest, param2};
pgmDigest = pgmBuilder.Apply(udfTDigest_AddValue, params);
}
@@ -198,166 +198,166 @@ using namespace NKikimr::NMiniKQL;
TVector<TRuntimeNode> params = {pgmDigest};
pgmSerializedData = pgmBuilder.Apply(udfTDigest_Serialize, params);
}
- pgmSerializedDataVector.push_back(pgmSerializedData);
- }
+ pgmSerializedDataVector.push_back(pgmSerializedData);
+ }
- TRuntimeNode pgmDigest;
- for (size_t i = 0; i < pgmSerializedDataVector.size(); ++i) {
+ TRuntimeNode pgmDigest;
+ for (size_t i = 0; i < pgmSerializedDataVector.size(); ++i) {
TRuntimeNode pgmDigest2;
{
- TVector<TRuntimeNode> params = {pgmSerializedDataVector[i]};
+ TVector<TRuntimeNode> params = {pgmSerializedDataVector[i]};
pgmDigest2 = pgmBuilder.Apply(udfTDigest_Deserialize, params);
}
- if (!pgmDigest) {
- pgmDigest = pgmDigest2;
- } else {
- TVector<TRuntimeNode> params = {pgmDigest, pgmDigest2};
- pgmDigest = pgmBuilder.Apply(udfTDigest_Merge, params);
+ if (!pgmDigest) {
+ pgmDigest = pgmDigest2;
+ } else {
+ TVector<TRuntimeNode> params = {pgmDigest, pgmDigest2};
+ pgmDigest = pgmBuilder.Apply(udfTDigest_Merge, params);
}
- }
+ }
- TRuntimeNode pgmReturn;
- {
- auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
- TVector<TRuntimeNode> params = {pgmDigest, param2};
- pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
+ TRuntimeNode pgmReturn;
+ {
+ auto param2 = pgmBuilder.NewDataLiteral<double>(0.9);
+ TVector<TRuntimeNode> params = {pgmDigest, param2};
+ pgmReturn = pgmBuilder.Apply(udfTDigest_GetPercentile, params);
}
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.95, 0.001);
- }
-
- static double GetParetoRandomNumber(double a) {
- return 1 / pow(RandomNumber<double>(), double(1) / a);
- }
-
- Y_UNIT_TEST(BigPercentile) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
- auto timeProvider = CreateDeterministicTimeProvider(1);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
- const size_t NUMBERS = 100000;
- const double PERCENTILE = 0.99;
- const double THRESHOLD = 0.0004; // at q=0.99 threshold is 4*delta*0.0099
- TVector<double> randomNumbers1;
- TVector<TRuntimeNode> randomNumbers2;
- randomNumbers1.reserve(NUMBERS);
- randomNumbers2.reserve(NUMBERS);
- for (size_t n = 0; n < NUMBERS; ++n) {
- double randomNumber = GetParetoRandomNumber(10);
- randomNumbers1.push_back(randomNumber);
- randomNumbers2.push_back(pgmBuilder.NewDataLiteral(randomNumber));
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ UNIT_ASSERT_DOUBLES_EQUAL(value.Get<double>(), 8.95, 0.001);
+ }
+
+ static double GetParetoRandomNumber(double a) {
+ return 1 / pow(RandomNumber<double>(), double(1) / a);
+ }
+
+ Y_UNIT_TEST(BigPercentile) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
+ auto timeProvider = CreateDeterministicTimeProvider(1);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+ const size_t NUMBERS = 100000;
+ const double PERCENTILE = 0.99;
+ const double THRESHOLD = 0.0004; // at q=0.99 threshold is 4*delta*0.0099
+ TVector<double> randomNumbers1;
+ TVector<TRuntimeNode> randomNumbers2;
+ randomNumbers1.reserve(NUMBERS);
+ randomNumbers2.reserve(NUMBERS);
+ for (size_t n = 0; n < NUMBERS; ++n) {
+ double randomNumber = GetParetoRandomNumber(10);
+ randomNumbers1.push_back(randomNumber);
+ randomNumbers2.push_back(pgmBuilder.NewDataLiteral(randomNumber));
}
- TRuntimeNode bigList = pgmBuilder.AsList(randomNumbers2);
- auto pgmDigest =
- pgmBuilder.Fold1(bigList,
- [&](TRuntimeNode item) {
- std::array<TRuntimeNode, 1> args;
- args[0] = item;
- return pgmBuilder.Apply(udfTDigest_Create, args);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- std::array<TRuntimeNode, 2> args;
- args[0] = state;
- args[1] = item;
- return pgmBuilder.Apply(udfTDigest_AddValue, args);
- });
- TRuntimeNode pgmReturn =
- pgmBuilder.Map(pgmDigest, [&](TRuntimeNode item) {
- auto param2 = pgmBuilder.NewDataLiteral(PERCENTILE);
- std::array<TRuntimeNode, 2> args;
- args[0] = item;
- args[1] = param2;
- return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
- });
-
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- UNIT_ASSERT(value);
- double digestValue = value.Get<double>();
- std::sort(randomNumbers1.begin(), randomNumbers1.end());
- // This gives us a 1-based index of the last value <= digestValue
- auto index = std::upper_bound(randomNumbers1.begin(), randomNumbers1.end(), digestValue) - randomNumbers1.begin();
- // See https://en.wikipedia.org/wiki/Percentile#First_Variant.2C
- double p = (index - 0.5) / double(randomNumbers1.size());
- UNIT_ASSERT_DOUBLES_EQUAL(p, PERCENTILE, THRESHOLD);
- }
-
- Y_UNIT_TEST(CentroidPrecision) {
- auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
- auto randomProvider = CreateDeterministicRandomProvider(1);
- auto timeProvider = CreateDeterministicTimeProvider(1);
- NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
- mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
- TScopedAlloc alloc;
- TTypeEnvironment env(alloc);
- TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
- auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
- auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
- auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
- const size_t NUMBERS = 100000;
- const double PERCENTILE = 0.25;
- const double minValue = 1.0;
- const double maxValue = 100.0;
- const double majorityValue = 50.0;
- TVector<TRuntimeNode> numbers;
- numbers.reserve(NUMBERS);
- for (size_t n = 0; n < NUMBERS - 2; ++n) {
- numbers.push_back(pgmBuilder.NewDataLiteral(majorityValue));
+ TRuntimeNode bigList = pgmBuilder.AsList(randomNumbers2);
+ auto pgmDigest =
+ pgmBuilder.Fold1(bigList,
+ [&](TRuntimeNode item) {
+ std::array<TRuntimeNode, 1> args;
+ args[0] = item;
+ return pgmBuilder.Apply(udfTDigest_Create, args);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ std::array<TRuntimeNode, 2> args;
+ args[0] = state;
+ args[1] = item;
+ return pgmBuilder.Apply(udfTDigest_AddValue, args);
+ });
+ TRuntimeNode pgmReturn =
+ pgmBuilder.Map(pgmDigest, [&](TRuntimeNode item) {
+ auto param2 = pgmBuilder.NewDataLiteral(PERCENTILE);
+ std::array<TRuntimeNode, 2> args;
+ args[0] = item;
+ args[1] = param2;
+ return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
+ });
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ UNIT_ASSERT(value);
+ double digestValue = value.Get<double>();
+ std::sort(randomNumbers1.begin(), randomNumbers1.end());
+ // This gives us a 1-based index of the last value <= digestValue
+ auto index = std::upper_bound(randomNumbers1.begin(), randomNumbers1.end(), digestValue) - randomNumbers1.begin();
+ // See https://en.wikipedia.org/wiki/Percentile#First_Variant.2C
+ double p = (index - 0.5) / double(randomNumbers1.size());
+ UNIT_ASSERT_DOUBLES_EQUAL(p, PERCENTILE, THRESHOLD);
+ }
+
+ Y_UNIT_TEST(CentroidPrecision) {
+ auto mutableFunctionRegistry = CreateFunctionRegistry(CreateBuiltinRegistry())->Clone();
+ auto randomProvider = CreateDeterministicRandomProvider(1);
+ auto timeProvider = CreateDeterministicTimeProvider(1);
+ NUdf::TUniquePtr<NUdf::IUdfModule> module = NUdf::CreateStatModule();
+ mutableFunctionRegistry->AddModule("", "Stat", std::move(module));
+ TScopedAlloc alloc;
+ TTypeEnvironment env(alloc);
+ TProgramBuilder pgmBuilder(env, *mutableFunctionRegistry);
+ auto udfTDigest_Create = pgmBuilder.Udf("Stat.TDigest_Create");
+ auto udfTDigest_AddValue = pgmBuilder.Udf("Stat.TDigest_AddValue");
+ auto udfTDigest_GetPercentile = pgmBuilder.Udf("Stat.TDigest_GetPercentile");
+ const size_t NUMBERS = 100000;
+ const double PERCENTILE = 0.25;
+ const double minValue = 1.0;
+ const double maxValue = 100.0;
+ const double majorityValue = 50.0;
+ TVector<TRuntimeNode> numbers;
+ numbers.reserve(NUMBERS);
+ for (size_t n = 0; n < NUMBERS - 2; ++n) {
+ numbers.push_back(pgmBuilder.NewDataLiteral(majorityValue));
}
- numbers.push_back(pgmBuilder.NewDataLiteral(minValue));
- numbers.push_back(pgmBuilder.NewDataLiteral(maxValue));
- TRuntimeNode bigList = pgmBuilder.AsList(numbers);
- auto pgmDigest =
- pgmBuilder.Fold1(bigList,
- [&](TRuntimeNode item) {
- std::array<TRuntimeNode, 1> args;
- args[0] = item;
- return pgmBuilder.Apply(udfTDigest_Create, args);
- },
- [&](TRuntimeNode item, TRuntimeNode state) {
- std::array<TRuntimeNode, 2> args;
- args[0] = state;
- args[1] = item;
- return pgmBuilder.Apply(udfTDigest_AddValue, args);
- });
- TRuntimeNode pgmReturn =
- pgmBuilder.Map(pgmDigest, [&](TRuntimeNode item) {
- auto param2 = pgmBuilder.NewDataLiteral(PERCENTILE);
- std::array<TRuntimeNode, 2> args;
- args[0] = item;
- args[1] = param2;
- return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
- });
-
- TExploringNodeVisitor explorer;
- explorer.Walk(pgmReturn.GetNode(), env);
- TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
- auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
- auto value = graph->GetValue();
- UNIT_ASSERT(value);
- double digestValue = value.Get<double>();
- UNIT_ASSERT_EQUAL(digestValue, majorityValue);
+ numbers.push_back(pgmBuilder.NewDataLiteral(minValue));
+ numbers.push_back(pgmBuilder.NewDataLiteral(maxValue));
+ TRuntimeNode bigList = pgmBuilder.AsList(numbers);
+ auto pgmDigest =
+ pgmBuilder.Fold1(bigList,
+ [&](TRuntimeNode item) {
+ std::array<TRuntimeNode, 1> args;
+ args[0] = item;
+ return pgmBuilder.Apply(udfTDigest_Create, args);
+ },
+ [&](TRuntimeNode item, TRuntimeNode state) {
+ std::array<TRuntimeNode, 2> args;
+ args[0] = state;
+ args[1] = item;
+ return pgmBuilder.Apply(udfTDigest_AddValue, args);
+ });
+ TRuntimeNode pgmReturn =
+ pgmBuilder.Map(pgmDigest, [&](TRuntimeNode item) {
+ auto param2 = pgmBuilder.NewDataLiteral(PERCENTILE);
+ std::array<TRuntimeNode, 2> args;
+ args[0] = item;
+ args[1] = param2;
+ return pgmBuilder.Apply(udfTDigest_GetPercentile, args);
+ });
+
+ TExploringNodeVisitor explorer;
+ explorer.Walk(pgmReturn.GetNode(), env);
+ TComputationPatternOpts opts(alloc.Ref(), env, GetBuiltinFactory(), mutableFunctionRegistry.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ auto pattern = MakeComputationPattern(explorer, pgmReturn, {}, opts);
+ auto graph = pattern->Clone(opts.ToComputationOptions(*randomProvider, *timeProvider));
+ auto value = graph->GetValue();
+ UNIT_ASSERT(value);
+ double digestValue = value.Get<double>();
+ UNIT_ASSERT_EQUAL(digestValue, majorityValue);
}
}
}
diff --git a/ydb/library/yql/udfs/common/stat/static/stat_udf.h b/ydb/library/yql/udfs/common/stat/static/stat_udf.h
index ee8984a81f..6eb6203051 100644
--- a/ydb/library/yql/udfs/common/stat/static/stat_udf.h
+++ b/ydb/library/yql/udfs/common/stat/static/stat_udf.h
@@ -4,7 +4,7 @@
#include <ydb/library/yql/public/udf/udf_value_builder.h>
#include "tdigest.h"
-using namespace NYql;
+using namespace NYql;
using namespace NUdf;
namespace {
diff --git a/ydb/library/yql/udfs/common/stat/static/static_udf.cpp b/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
index 1ee28b0295..3cb1d88a1c 100644
--- a/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
+++ b/ydb/library/yql/udfs/common/stat/static/static_udf.cpp
@@ -1,6 +1,6 @@
#include "stat_udf.h"
-namespace NYql {
+namespace NYql {
namespace NUdf {
NUdf::TUniquePtr<NUdf::IUdfModule> CreateStatModule() {
return new TStatModule();
diff --git a/ydb/library/yql/udfs/common/stat/ut/ya.make b/ydb/library/yql/udfs/common/stat/ut/ya.make
index e505fc9f70..e477adbda6 100644
--- a/ydb/library/yql/udfs/common/stat/ut/ya.make
+++ b/ydb/library/yql/udfs/common/stat/ut/ya.make
@@ -1,5 +1,5 @@
UNITTEST_FOR(ydb/library/yql/udfs/common/stat/static)
-
+
OWNER(xenoxeno)
SRCS(
diff --git a/ydb/library/yql/udfs/common/string/string_udf.cpp b/ydb/library/yql/udfs/common/string/string_udf.cpp
index be28046203..c468215090 100644
--- a/ydb/library/yql/udfs/common/string/string_udf.cpp
+++ b/ydb/library/yql/udfs/common/string/string_udf.cpp
@@ -73,7 +73,7 @@ namespace {
}
#define STROKA_ASCII_CASE_UDF(udfName, function) \
- SIMPLE_UDF(T##udfName, char*(TAutoMap<char*>)) { \
+ SIMPLE_UDF(T##udfName, char*(TAutoMap<char*>)) { \
TString input(args[0].AsStringRef()); \
if (input.function()) { \
return valueBuilder->NewString(input); \
@@ -88,7 +88,7 @@ namespace {
if (args[0]) { \
const TString haystack(args[0].AsStringRef()); \
const TString needle(args[1].AsStringRef()); \
- return TUnboxedValuePod(haystack.function(needle)); \
+ return TUnboxedValuePod(haystack.function(needle)); \
} else { \
return TUnboxedValuePod(false); \
} \
@@ -100,7 +100,7 @@ namespace {
if (args[0]) { \
const TString haystack(args[0].AsStringRef()); \
const TString needle(args[1].AsStringRef()); \
- return TUnboxedValuePod(function(haystack, needle)); \
+ return TUnboxedValuePod(function(haystack, needle)); \
} else { \
return TUnboxedValuePod(false); \
} \
@@ -110,7 +110,7 @@ namespace {
SIMPLE_UDF(T##function, bool(TOptional<char*>)) { \
Y_UNUSED(valueBuilder); \
if (args[0]) { \
- const TStringBuf input(args[0].AsStringRef()); \
+ const TStringBuf input(args[0].AsStringRef()); \
bool result = true; \
for (auto c : input) { \
if (!function(c)) { \
@@ -186,10 +186,10 @@ namespace {
}
SIMPLE_UDF(TReplaceAll, char*(TAutoMap<char*>, char*, char*)) {
- if (TString result(args[0].AsStringRef()); SubstGlobal(result, args[1].AsStringRef(), args[2].AsStringRef()))
- return valueBuilder->NewString(result);
- else
- return args[0];
+ if (TString result(args[0].AsStringRef()); SubstGlobal(result, args[1].AsStringRef(), args[2].AsStringRef()))
+ return valueBuilder->NewString(result);
+ else
+ return args[0];
}
SIMPLE_UDF(TReplaceFirst, char*(TAutoMap<char*>, char*, char*)) {
@@ -202,11 +202,11 @@ namespace {
if (with.size() != 1) {
UdfTerminate("Only one char is supported as third argument");
}
- if (const auto index = result.find(what[0]); index != TStringBuf::npos) {
+ if (const auto index = result.find(what[0]); index != TStringBuf::npos) {
result.replace(index, 1, with.data());
- return valueBuilder->NewString(result);
+ return valueBuilder->NewString(result);
}
- return args[0];
+ return args[0];
}
SIMPLE_UDF(TReplaceLast, char*(TAutoMap<char*>, char*, char*)) {
@@ -219,11 +219,11 @@ namespace {
if (with.size() != 1) {
UdfTerminate("Only one char is supported as third argument");
}
- if (const auto index = result.rfind(what[0]); index != TStringBuf::npos) {
+ if (const auto index = result.rfind(what[0]); index != TStringBuf::npos) {
result.replace(index, 1, with.data());
- return valueBuilder->NewString(result);
+ return valueBuilder->NewString(result);
}
- return args[0];
+ return args[0];
}
SIMPLE_UDF(TRemoveAll, char*(TAutoMap<char*>, char*)) {
@@ -241,11 +241,11 @@ namespace {
if (remove.size() != 1) {
UdfTerminate("Only one char is supported as second argument");
}
- if (const auto index = result.find(remove[0]); index != TStringBuf::npos) {
+ if (const auto index = result.find(remove[0]); index != TStringBuf::npos) {
result.remove(index, 1);
- return valueBuilder->NewString(result);
+ return valueBuilder->NewString(result);
}
- return args[0];
+ return args[0];
}
SIMPLE_UDF(TRemoveLast, char*(TAutoMap<char*>, char*)) {
@@ -254,11 +254,11 @@ namespace {
if (remove.size() != 1) {
UdfTerminate("Only one char is supported as second argument");
}
- if (const auto index = result.rfind(remove[0]); index != TStringBuf::npos) {
+ if (const auto index = result.rfind(remove[0]); index != TStringBuf::npos) {
result.remove(index, 1);
- return valueBuilder->NewString(result);
+ return valueBuilder->NewString(result);
}
- return args[0];
+ return args[0];
}
SIMPLE_UDF_OPTIONS(TFind, i64(TAutoMap<char*>, char*, TOptional<ui64>),
@@ -287,37 +287,37 @@ namespace {
return valueBuilder->NewString(input.substr(from, count));
}
- using TTmpVector = TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator>;
-
+ using TTmpVector = TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator>;
+
template <typename TIt>
static void SplitToListImpl(
const IValueBuilder* valueBuilder,
- const TUnboxedValue& input,
- const std::string_view::const_iterator from,
- const TIt& it,
- TTmpVector& result) {
- for (const auto& elem : it) {
- result.emplace_back(valueBuilder->SubString(input, std::distance(from, elem.TokenStart()), std::distance(elem.TokenStart(), elem.TokenDelim())));
+ const TUnboxedValue& input,
+ const std::string_view::const_iterator from,
+ const TIt& it,
+ TTmpVector& result) {
+ for (const auto& elem : it) {
+ result.emplace_back(valueBuilder->SubString(input, std::distance(from, elem.TokenStart()), std::distance(elem.TokenStart(), elem.TokenDelim())));
}
}
template <typename TIt>
static void SplitToListImpl(
const IValueBuilder* valueBuilder,
- const TUnboxedValue& input,
- const std::string_view::const_iterator from,
+ const TUnboxedValue& input,
+ const std::string_view::const_iterator from,
TIt& it,
bool skipEmpty,
- TTmpVector& result) {
+ TTmpVector& result) {
if (skipEmpty) {
- SplitToListImpl(valueBuilder, input, from, it.SkipEmpty(), result);
+ SplitToListImpl(valueBuilder, input, from, it.SkipEmpty(), result);
} else {
- SplitToListImpl(valueBuilder, input, from, it, result);
+ SplitToListImpl(valueBuilder, input, from, it, result);
}
}
- constexpr char delimeterStringName[] = "DelimeterString";
- constexpr char skipEmptyName[] = "SkipEmpty";
- constexpr char limitName[] = "Limit";
+ constexpr char delimeterStringName[] = "DelimeterString";
+ constexpr char skipEmptyName[] = "SkipEmpty";
+ constexpr char limitName[] = "Limit";
using TDelimeterStringArg = TNamedArg<bool, delimeterStringName>;
using TSkipEmptyArg = TNamedArg<bool, skipEmptyName>;
using TLimitArg = TNamedArg<ui64, limitName>;
@@ -331,28 +331,28 @@ namespace {
TLimitArg
),
builder.OptionalArgs(3)) {
- TTmpVector result;
+ TTmpVector result;
if (args[0]) {
- const std::string_view input(args[0].AsStringRef());
- const std::string_view delimeter(args[1].AsStringRef());
- const bool delimiterString = args[2].GetOrDefault<bool>(true);
- const bool skipEmpty = args[3].GetOrDefault<bool>(false);
- const auto limit = args[4].GetOrDefault<ui64>(0);
+ const std::string_view input(args[0].AsStringRef());
+ const std::string_view delimeter(args[1].AsStringRef());
+ const bool delimiterString = args[2].GetOrDefault<bool>(true);
+ const bool skipEmpty = args[3].GetOrDefault<bool>(false);
+ const auto limit = args[4].GetOrDefault<ui64>(0);
if (delimiterString) {
if (limit) {
auto it = StringSplitter(input).SplitByString(delimeter).Limit(limit + 1);
- SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
+ SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
} else {
auto it = StringSplitter(input).SplitByString(delimeter);
- SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
+ SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
}
} else {
if (limit) {
- auto it = StringSplitter(input).SplitBySet(TString(delimeter).c_str()).Limit(limit + 1);
- SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
+ auto it = StringSplitter(input).SplitBySet(TString(delimeter).c_str()).Limit(limit + 1);
+ SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
} else {
- auto it = StringSplitter(input).SplitBySet(TString(delimeter).c_str());
- SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
+ auto it = StringSplitter(input).SplitBySet(TString(delimeter).c_str());
+ SplitToListImpl(valueBuilder, args[0], input.cbegin(), it, skipEmpty, result);
}
}
}
diff --git a/ydb/library/yql/udfs/common/top/top_udf.cpp b/ydb/library/yql/udfs/common/top/top_udf.cpp
index 02a325a6a4..748ffe489b 100644
--- a/ydb/library/yql/udfs/common/top/top_udf.cpp
+++ b/ydb/library/yql/udfs/common/top/top_udf.cpp
@@ -30,9 +30,9 @@ template <EDataSlot Slot, bool IsTop>
struct TDataPairCompare {
bool operator()(const TUnboxedValuePair& left, const TUnboxedValuePair& right) const {
if (IsTop) {
- return CompareValues<Slot>(left.first, right.first) > 0;
+ return CompareValues<Slot>(left.first, right.first) > 0;
} else {
- return CompareValues<Slot>(left.first, right.first) < 0;
+ return CompareValues<Slot>(left.first, right.first) < 0;
}
}
};
@@ -56,9 +56,9 @@ struct TGenericPairCompare {
bool operator()(const TUnboxedValuePair& left, const TUnboxedValuePair& right) const {
if (IsTop) {
- return Compare->Less(right.first, left.first);
+ return Compare->Less(right.first, left.first);
} else {
- return Compare->Less(left.first, right.first);
+ return Compare->Less(left.first, right.first);
}
}
};
diff --git a/ydb/library/yql/udfs/common/topfreq/static/static_udf.cpp b/ydb/library/yql/udfs/common/topfreq/static/static_udf.cpp
index 1f008e4caa..4075bfa9c2 100644
--- a/ydb/library/yql/udfs/common/topfreq/static/static_udf.cpp
+++ b/ydb/library/yql/udfs/common/topfreq/static/static_udf.cpp
@@ -1,6 +1,6 @@
#include "topfreq_udf.h"
-namespace NYql {
+namespace NYql {
namespace NUdf {
NUdf::TUniquePtr<NUdf::IUdfModule> CreateTopFreqModule() {
return new TTopFreqModule();
diff --git a/ydb/library/yql/udfs/common/topfreq/static/topfreq.cpp b/ydb/library/yql/udfs/common/topfreq/static/topfreq.cpp
index 16e27820cc..31fcd88b54 100644
--- a/ydb/library/yql/udfs/common/topfreq/static/topfreq.cpp
+++ b/ydb/library/yql/udfs/common/topfreq/static/topfreq.cpp
@@ -42,24 +42,24 @@ void TTopFreqBase<THash, TEquals>::Deserialize(const TUnboxedValuePod& serialize
Indices_.reserve(MaxSize_ + 1);
const auto listIter = serialized.GetElement(2).GetListIterator();
- for (TUnboxedValue current; listIter.Next(current);) {
- Update(current.GetElement(1), current.GetElement(0).Get<ui64>());
+ for (TUnboxedValue current; listIter.Next(current);) {
+ Update(current.GetElement(1), current.GetElement(0).Get<ui64>());
}
}
template <typename THash, typename TEquals>
TUnboxedValue TTopFreqBase<THash, TEquals>::Convert(const IValueBuilder* valueBuilder) const {
TUnboxedValue* values = nullptr;
- const auto list = valueBuilder->NewArray(Freqs_.size(), values);
- for (const auto& item : Freqs_) {
- TUnboxedValue* items = nullptr;
- *values++ = valueBuilder->NewArray(2U, items);
- items[0] = TUnboxedValuePod(item.second);
- items[1] = item.first;
- }
- return list;
-}
-
+ const auto list = valueBuilder->NewArray(Freqs_.size(), values);
+ for (const auto& item : Freqs_) {
+ TUnboxedValue* items = nullptr;
+ *values++ = valueBuilder->NewArray(2U, items);
+ items[0] = TUnboxedValuePod(item.second);
+ items[1] = item.first;
+ }
+ return list;
+}
+
template <typename THash, typename TEquals>
void TTopFreqBase<THash, TEquals>::Add(const TTopFreqBase& otherModeCalc) {
for (auto& it : otherModeCalc.Freqs_) {
@@ -73,7 +73,7 @@ template <typename THash, typename TEquals>
TUnboxedValue TTopFreqBase<THash, TEquals>::Get(const IValueBuilder* builder, ui32 resultSize) {
resultSize = std::min(resultSize, ui32(Freqs_.size()));
Compress(resultSize, true);
- return Convert(builder);
+ return Convert(builder);
}
template <typename THash, typename TEquals>
@@ -127,14 +127,14 @@ TUnboxedValue TTopFreqBase<THash, TEquals>::Serialize(const IValueBuilder* build
Compress(MinSize_);
}
- TUnboxedValue* items = nullptr;
- auto tuple = builder->NewArray(3U, items);
- items[0] = TUnboxedValuePod(MinSize_);
- items[1] = TUnboxedValuePod(MaxSize_);
- items[2] = Convert(builder);
- return tuple;
+ TUnboxedValue* items = nullptr;
+ auto tuple = builder->NewArray(3U, items);
+ items[0] = TUnboxedValuePod(MinSize_);
+ items[1] = TUnboxedValuePod(MaxSize_);
+ items[2] = Convert(builder);
+ return tuple;
}
-
+
template <EDataSlot Slot>
TTopFreqData<Slot>::TTopFreqData(const TUnboxedValuePod& value, const ui32 minSize, const ui32 maxSize)
: TBase(TUnboxedValueHash<Slot>(), TUnboxedValueEquals<Slot>())
@@ -173,10 +173,10 @@ void TTopFreqData<Slot>::AddValue(const TUnboxedValuePod& value) {
#define INSTANCE_FOR(slot, ...) \
template class TTopFreqData<EDataSlot::slot>;
-
+
UDF_TYPE_ID_MAP(INSTANCE_FOR)
-#undef INSTANCE_FOR
+#undef INSTANCE_FOR
TTopFreqGeneric::TTopFreqGeneric(const TUnboxedValuePod& value, const ui32 minSize, const ui32 maxSize,
IHash::TPtr hash, IEquate::TPtr equate)
diff --git a/ydb/library/yql/udfs/common/topfreq/static/topfreq.h b/ydb/library/yql/udfs/common/topfreq/static/topfreq.h
index 3c1ac316d1..411190d257 100644
--- a/ydb/library/yql/udfs/common/topfreq/static/topfreq.h
+++ b/ydb/library/yql/udfs/common/topfreq/static/topfreq.h
@@ -3,16 +3,16 @@
#include <ydb/library/yql/public/udf/udf_allocator.h>
#include <ydb/library/yql/public/udf/udf_helpers.h>
#include <ydb/library/yql/public/udf/udf_type_ops.h>
-
+
#include <unordered_map>
template <typename THash, typename TEquals>
class TTopFreqBase {
protected:
- using TUnboxedValuePod = NKikimr::NUdf::TUnboxedValuePod;
+ using TUnboxedValuePod = NKikimr::NUdf::TUnboxedValuePod;
using TUnboxedValue = NKikimr::NUdf::TUnboxedValue;
- using IValueBuilder = NKikimr::NUdf::IValueBuilder;
-
+ using IValueBuilder = NKikimr::NUdf::IValueBuilder;
+
using TVectorElement = std::pair<TUnboxedValue, ui64>;
using TVectorType = std::vector<TVectorElement, NKikimr::NUdf::TStdAllocatorForUdf<TVectorElement>>;
@@ -22,20 +22,20 @@ protected:
ui32 MaxSize_ = 0;
void Add(const TTopFreqBase& otherCalc);
- void Update(const TUnboxedValuePod& key, const ui64 value);
+ void Update(const TUnboxedValuePod& key, const ui64 value);
void TryCompress();
void Compress(ui32 newSize, bool sort = false);
- TUnboxedValue Convert(const IValueBuilder* valueBuilder) const;
+ TUnboxedValue Convert(const IValueBuilder* valueBuilder) const;
protected:
TTopFreqBase(THash hash, TEquals equals);
-
+
void Init(const TUnboxedValuePod& value, const ui32 minSize, const ui32 maxSize);
void Merge(const TTopFreqBase& TopFreq1, const TTopFreqBase& TopFreq2);
void Deserialize(const TUnboxedValuePod& serialized);
- TUnboxedValue Serialize(const IValueBuilder* builder);
- TUnboxedValue Get(const IValueBuilder* builder, ui32 resultSize);
+ TUnboxedValue Serialize(const IValueBuilder* builder);
+ TUnboxedValue Get(const IValueBuilder* builder, ui32 resultSize);
void AddValue(const TUnboxedValuePod& value);
};
diff --git a/ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h b/ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h
index e80cf61db5..5ea0a5f729 100644
--- a/ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h
+++ b/ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h
@@ -11,7 +11,7 @@
#include <algorithm>
#include <array>
-using namespace NYql;
+using namespace NYql;
using namespace NUdf;
namespace {
@@ -51,13 +51,13 @@ namespace {
};
class TTopFreq_Create: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const {
ui32 minSize = args[1].Get<ui32>();
return TUnboxedValuePod(new TTopFreqResource(args[0], minSize, minSize * 2, Hash_, Equate_));
}
- public:
+ public:
TTopFreq_Create(IHash::TPtr hash, IEquate::TPtr equate)
: Hash_(hash)
, Equate_(equate)
@@ -79,11 +79,11 @@ namespace {
};
class TTopFreq_AddValue: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const {
const auto topFreq = GetTopFreqResource(args[0]);
topFreq->Get()->AddValue(args[1]);
- return TUnboxedValuePod(topFreq);
+ return TUnboxedValuePod(topFreq);
}
};
@@ -96,7 +96,7 @@ namespace {
};
class TTopFreq_Serialize: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const {
return GetTopFreqResource(args[0])->Get()->Serialize(valueBuilder);
}
@@ -111,12 +111,12 @@ namespace {
};
class TTopFreq_Deserialize: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const {
return TUnboxedValuePod(new TTopFreqResource(args[0], Hash_, Equate_));
}
- public:
+ public:
TTopFreq_Deserialize(IHash::TPtr hash, IEquate::TPtr equate)
: Hash_(hash)
, Equate_(equate)
@@ -138,14 +138,14 @@ namespace {
};
class TTopFreq_Merge: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const {
const auto topFreq0 = GetTopFreqResource(args[0]);
const auto topFreq1 = GetTopFreqResource(args[1]);
return TUnboxedValuePod(new TTopFreqResource(*topFreq0->Get(), *topFreq1->Get(), Hash_, Equate_));
}
- public:
+ public:
TTopFreq_Merge(IHash::TPtr hash, IEquate::TPtr equate)
: Hash_(hash)
, Equate_(equate)
@@ -158,7 +158,7 @@ namespace {
template <EDataSlot Slot>
class TTopFreq_GetData: public TBoxedValue {
- private:
+ private:
TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const {
return GetTopFreqResourceData<Slot>(args[0])->Get()->Get(valueBuilder, args[1].Get<ui32>());
}
@@ -221,7 +221,7 @@ namespace {
void CleanupOnTerminate() const final {
}
- void GetAllFunctions(IFunctionsSink& sink) const final {
+ void GetAllFunctions(IFunctionsSink& sink) const final {
sink.Add(CreateName)->SetTypeAwareness();
sink.Add(AddValueName)->SetTypeAwareness();
sink.Add(SerializeName)->SetTypeAwareness();
@@ -240,8 +240,8 @@ namespace {
Y_UNUSED(typeConfig);
try {
- const bool typesOnly = (flags & TFlags::TypesOnly);
- builder.UserType(userType);
+ const bool typesOnly = (flags & TFlags::TypesOnly);
+ builder.UserType(userType);
auto typeHelper = builder.TypeInfoHelper();
@@ -301,7 +301,7 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_CREATE)
}
- }
+ }
}
}
@@ -315,13 +315,13 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_ADD_VALUE)
}
- }
+ }
}
}
if (name == MergeName) {
builder.Args()->Add(topFreqType).Add(topFreqType).Done().Returns(topFreqType);
-
+
if (!typesOnly) {
if (isGeneric) {
builder.Implementation(new TTopFreq_Merge(hash, equate));
@@ -329,7 +329,7 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_MERGE)
}
- }
+ }
}
}
@@ -343,7 +343,7 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_SERIALIZE)
}
- }
+ }
}
}
@@ -357,12 +357,12 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_DESERIALIZE)
}
- }
+ }
}
}
if (name == GetName) {
- ui32 indexF, indexV;
+ ui32 indexF, indexV;
auto itemType = builder.Struct()->AddField<ui64>("Frequency", &indexF).AddField("Value", valueType, &indexV).Build();
auto resultType = builder.List()->Item(itemType).Build();
@@ -375,7 +375,7 @@ namespace {
switch (*slot) {
UDF_TYPE_ID_MAP(MAKE_GET)
}
- }
+ }
}
}
diff --git a/ydb/library/yql/udfs/common/topfreq/topfreq_udf_ut.cpp b/ydb/library/yql/udfs/common/topfreq/topfreq_udf_ut.cpp
index 29a3823000..c6f6ecab72 100644
--- a/ydb/library/yql/udfs/common/topfreq/topfreq_udf_ut.cpp
+++ b/ydb/library/yql/udfs/common/topfreq/topfreq_udf_ut.cpp
@@ -9,443 +9,443 @@
#include <array>
#include <ydb/library/yql/udfs/common/topfreq/static/topfreq_udf.h>
-namespace NYql {
- using namespace NKikimr::NMiniKQL;
+namespace NYql {
+ using namespace NKikimr::NMiniKQL;
namespace NUdf {
extern NUdf::TUniquePtr<NUdf::IUdfModule> CreateTopFreqModule();
}
- class TSetup {
- public:
- TSetup()
- : MutableFunctionRegistry_(CreateFunctionRegistry(CreateBuiltinRegistry())->Clone())
- , RandomProvider_(CreateDeterministicRandomProvider(1))
+ class TSetup {
+ public:
+ TSetup()
+ : MutableFunctionRegistry_(CreateFunctionRegistry(CreateBuiltinRegistry())->Clone())
+ , RandomProvider_(CreateDeterministicRandomProvider(1))
, TimeProvider_(CreateDeterministicTimeProvider(10000000))
- , Alloc_()
- , Env_(Alloc_)
- {
- MutableFunctionRegistry_->AddModule("", "TopFreq", NUdf::CreateTopFreqModule());
+ , Alloc_()
+ , Env_(Alloc_)
+ {
+ MutableFunctionRegistry_->AddModule("", "TopFreq", NUdf::CreateTopFreqModule());
PgmBuidler_.Reset(new TProgramBuilder(Env_, *MutableFunctionRegistry_));
- }
-
- TProgramBuilder& GetProgramBuilder() {
- return *PgmBuidler_.Get();
- }
-
- NUdf::TUnboxedValue GetValue(TRuntimeNode& node) {
- Explorer_.Walk(node.GetNode(), Env_);
-
- TComputationPatternOpts opts(Alloc_.Ref(), Env_, GetBuiltinFactory(),
- MutableFunctionRegistry_.Get(),
- NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
- Pattern_ = MakeComputationPattern(Explorer_, node, {}, opts);
- Graph_ = Pattern_->Clone(opts.ToComputationOptions(*RandomProvider_, *TimeProvider_));
-
- return Graph_->GetValue();
- }
-
- private:
- using IMutableFunctionRegistryPtr = TIntrusivePtr<IMutableFunctionRegistry>;
- using IRandomProviderPtr = TIntrusivePtr<IRandomProvider>;
- using ITimeProviderPtr = TIntrusivePtr<ITimeProvider>;
-
- IMutableFunctionRegistryPtr MutableFunctionRegistry_;
- IRandomProviderPtr RandomProvider_;
- ITimeProviderPtr TimeProvider_;
- TScopedAlloc Alloc_;
- TTypeEnvironment Env_;
- THolder<TProgramBuilder> PgmBuidler_;
- IComputationPattern::TPtr Pattern_;
- THolder<IComputationGraph> Graph_;
- TExploringNodeVisitor Explorer_;
- };
-
- Y_UNIT_TEST_SUITE(TUDFTopFreqTest) {
- Y_UNIT_TEST(SimpleTopFreq) {
- TSetup setup;
- TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
-
- const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<i32>::Id);
- const auto emptyStructType = pgmBuilder.NewEmptyStructType();
- const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Int32");
- const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
-
- const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
- const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
- auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
-
- auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
- auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
- auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
-
- auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
- auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
- auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
-
- TRuntimeNode pgmTopFreq;
- {
- auto val = pgmBuilder.NewDataLiteral<i32>(3);
- auto param = pgmBuilder.NewDataLiteral<ui32>(10);
-
- TVector<TRuntimeNode> params = {val, param};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
- }
-
- for (int n = 0; n < 9; n++) {
- auto value = pgmBuilder.NewDataLiteral<i32>(1);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- for (int n = 0; n < 7; n++) {
- auto value = pgmBuilder.NewDataLiteral<i32>(4);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param = pgmBuilder.NewDataLiteral<ui32>(4);
- TVector<TRuntimeNode> params = {pgmTopFreq, param};
- pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
- }
-
- auto value = setup.GetValue(pgmReturn);
-
- auto listIterator = value.GetListIterator();
-
- TUnboxedValue item;
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 1);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 9);
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 4);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 7);
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 3);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 1);
-
- UNIT_ASSERT(!listIterator.Next(item));
- }
-
- Y_UNIT_TEST(MergingTopFreq) {
- TSetup setup;
- TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
-
- const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto emptyStructType = pgmBuilder.NewEmptyStructType();
- const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Uint64");
- const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
-
- const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
- const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
- auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
-
- auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
- auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
- auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
-
- auto mergeArgsType = pgmBuilder.NewTupleType({resourceType, resourceType});
- auto mergeUserType = pgmBuilder.NewTupleType({mergeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Merge = pgmBuilder.Udf("TopFreq.TopFreq_Merge", TRuntimeNode(), mergeUserType);
-
- auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
- auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
- auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
-
- TRuntimeNode pgmTopFreq;
- {
- auto value = pgmBuilder.NewDataLiteral<ui64>(1);
- auto param = pgmBuilder.NewDataLiteral<ui32>(1);
- TVector<TRuntimeNode> params = {value, param};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
- }
-
- for (int n = 0; n < 1; n++) {
- auto value = pgmBuilder.NewDataLiteral<ui64>(1);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- for (int n = 0; n < 4; n++) {
- auto value = pgmBuilder.NewDataLiteral<ui64>(5);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- for (int n = 0; n < 1; n++) {
- auto value = pgmBuilder.NewDataLiteral<ui64>(3);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- TRuntimeNode pgmTopFreq2;
- {
- auto value = pgmBuilder.NewDataLiteral<ui64>(1);
- auto param = pgmBuilder.NewDataLiteral<ui32>(1);
- TVector<TRuntimeNode> params = {value, param};
- pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_Create, params);
- }
-
- for (int n = 0; n < 5; n++) {
- auto value = pgmBuilder.NewDataLiteral<ui64>(1);
- TVector<TRuntimeNode> params = {pgmTopFreq2, value};
- pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- for (int n = 0; n < 5; n++) {
- auto value = pgmBuilder.NewDataLiteral<ui64>(5);
- TVector<TRuntimeNode> params = {pgmTopFreq2, value};
- pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- TRuntimeNode pgmTopFreq3;
- {
- TVector<TRuntimeNode> params = {pgmTopFreq, pgmTopFreq2};
- pgmTopFreq3 = pgmBuilder.Apply(udfTopFreq_Merge, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param = pgmBuilder.NewDataLiteral<ui32>(1);
- TVector<TRuntimeNode> params = {pgmTopFreq3, param};
- pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
- }
-
- auto value = setup.GetValue(pgmReturn);
-
- auto listIterator = value.GetListIterator();
-
- TUnboxedValue item;
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<ui64>(), 5);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 9);
-
- UNIT_ASSERT(!listIterator.Next(item));
- }
-
- Y_UNIT_TEST(SerializedTopFreq) {
- TSetup setup;
- TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
-
- const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<bool>::Id);
- const auto emptyStructType = pgmBuilder.NewEmptyStructType();
- const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Bool");
- const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto ui64Type = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
-
- const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
- const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
- auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
-
- auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
- auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
- auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
-
- auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
- auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
- auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
-
- auto serializeArgsType = pgmBuilder.NewTupleType({resourceType});
- auto serializeUserType = pgmBuilder.NewTupleType({serializeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Serialize = pgmBuilder.Udf("TopFreq.TopFreq_Serialize", TRuntimeNode(), serializeUserType);
-
- auto serializedType = pgmBuilder.NewTupleType({ui32Type, ui32Type,
- pgmBuilder.NewListType(pgmBuilder.NewTupleType({ui64Type, valueType}))});
-
- auto deserializeArgsType = pgmBuilder.NewTupleType({serializedType});
- auto deserializeUserType = pgmBuilder.NewTupleType({deserializeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Deserialize = pgmBuilder.Udf("TopFreq.TopFreq_Deserialize", TRuntimeNode(), deserializeUserType);
-
- TRuntimeNode pgmTopFreq;
- {
- auto value = pgmBuilder.NewDataLiteral<bool>(true);
- auto param = pgmBuilder.NewDataLiteral<ui32>(10);
- TVector<TRuntimeNode> params = {value, param};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
- }
-
- for (int n = 0; n < 7; n++) {
- auto value = pgmBuilder.NewDataLiteral<bool>(true);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- for (int n = 0; n < 10; n++) {
- auto value = pgmBuilder.NewDataLiteral<bool>(false);
- TVector<TRuntimeNode> params = {pgmTopFreq, value};
- pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
- }
-
- TRuntimeNode pgmSerializedTopFreq;
- {
- TVector<TRuntimeNode> params = {pgmTopFreq};
- pgmSerializedTopFreq = pgmBuilder.Apply(udfTopFreq_Serialize, params);
- }
-
- TRuntimeNode pgmDeserializedTopFreq;
- {
- TVector<TRuntimeNode> params = {pgmSerializedTopFreq};
- pgmDeserializedTopFreq = pgmBuilder.Apply(udfTopFreq_Deserialize, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- auto param = pgmBuilder.NewDataLiteral<ui32>(3);
- TVector<TRuntimeNode> params = {pgmDeserializedTopFreq, param};
- pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
- }
-
- auto value = setup.GetValue(pgmReturn);
-
- auto listIterator = value.GetListIterator();
-
- TUnboxedValue item;
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<bool>(), false);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 10);
-
- UNIT_ASSERT(listIterator.Next(item));
- UNIT_ASSERT_EQUAL(item.GetElement(1).Get<bool>(), true);
- UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 8);
-
- UNIT_ASSERT(!listIterator.Next(item));
- }
-
- Y_UNIT_TEST(ApproxTopFreq) {
- TSetup setup;
- TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
-
- const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
- const auto emptyStructType = pgmBuilder.NewEmptyStructType();
- const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Uint64");
- const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
- const auto ui64Type = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
-
- const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
- const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
- auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
-
- auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
- auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
- auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
-
- auto mergeArgsType = pgmBuilder.NewTupleType({resourceType, resourceType});
- auto mergeUserType = pgmBuilder.NewTupleType({mergeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Merge = pgmBuilder.Udf("TopFreq.TopFreq_Merge", TRuntimeNode(), mergeUserType);
-
- auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
- auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
- auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
-
- auto serializeArgsType = pgmBuilder.NewTupleType({resourceType});
- auto serializeUserType = pgmBuilder.NewTupleType({serializeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Serialize = pgmBuilder.Udf("TopFreq.TopFreq_Serialize", TRuntimeNode(), serializeUserType);
-
- auto serializedType = pgmBuilder.NewTupleType({ui32Type, ui32Type,
- pgmBuilder.NewListType(pgmBuilder.NewTupleType({ui64Type, valueType}))});
-
- auto deserializeArgsType = pgmBuilder.NewTupleType({serializedType});
- auto deserializeUserType = pgmBuilder.NewTupleType({deserializeArgsType, emptyStructType, valueType});
- auto udfTopFreq_Deserialize = pgmBuilder.Udf("TopFreq.TopFreq_Deserialize", TRuntimeNode(), deserializeUserType);
-
- static const ui64 BigNum = 20;
- static const ui64 BigEach = 5000;
- static const ui64 SmallNum = 500;
- static const ui64 SmallEach = 20;
- static const ui64 Total = BigNum * BigEach + SmallNum * SmallEach;
- static const i32 AskFor = 25;
- static const ui64 BlockSize = 200;
- static const ui64 BlockCount = 10;
- static const i32 WorksIfAtLeast = 15;
-
- std::array<ui64, Total> values;
- std::array<TRuntimeNode, BlockCount> pgmTopFreqs;
-
- i32 curIndex = 0;
- for (ui64 i = 1; i <= BigNum; i++) {
- for (ui64 j = 0; j < BigEach; j++) {
- values[curIndex++] = i;
+ }
+
+ TProgramBuilder& GetProgramBuilder() {
+ return *PgmBuidler_.Get();
+ }
+
+ NUdf::TUnboxedValue GetValue(TRuntimeNode& node) {
+ Explorer_.Walk(node.GetNode(), Env_);
+
+ TComputationPatternOpts opts(Alloc_.Ref(), Env_, GetBuiltinFactory(),
+ MutableFunctionRegistry_.Get(),
+ NUdf::EValidateMode::None, NUdf::EValidatePolicy::Fail, "", EGraphPerProcess::Multi);
+ Pattern_ = MakeComputationPattern(Explorer_, node, {}, opts);
+ Graph_ = Pattern_->Clone(opts.ToComputationOptions(*RandomProvider_, *TimeProvider_));
+
+ return Graph_->GetValue();
+ }
+
+ private:
+ using IMutableFunctionRegistryPtr = TIntrusivePtr<IMutableFunctionRegistry>;
+ using IRandomProviderPtr = TIntrusivePtr<IRandomProvider>;
+ using ITimeProviderPtr = TIntrusivePtr<ITimeProvider>;
+
+ IMutableFunctionRegistryPtr MutableFunctionRegistry_;
+ IRandomProviderPtr RandomProvider_;
+ ITimeProviderPtr TimeProvider_;
+ TScopedAlloc Alloc_;
+ TTypeEnvironment Env_;
+ THolder<TProgramBuilder> PgmBuidler_;
+ IComputationPattern::TPtr Pattern_;
+ THolder<IComputationGraph> Graph_;
+ TExploringNodeVisitor Explorer_;
+ };
+
+ Y_UNIT_TEST_SUITE(TUDFTopFreqTest) {
+ Y_UNIT_TEST(SimpleTopFreq) {
+ TSetup setup;
+ TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
+
+ const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<i32>::Id);
+ const auto emptyStructType = pgmBuilder.NewEmptyStructType();
+ const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Int32");
+ const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
+
+ const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
+ const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
+
+ auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
+ auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
+ auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
+
+ auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
+ auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
+
+ TRuntimeNode pgmTopFreq;
+ {
+ auto val = pgmBuilder.NewDataLiteral<i32>(3);
+ auto param = pgmBuilder.NewDataLiteral<ui32>(10);
+
+ TVector<TRuntimeNode> params = {val, param};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
+ }
+
+ for (int n = 0; n < 9; n++) {
+ auto value = pgmBuilder.NewDataLiteral<i32>(1);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ for (int n = 0; n < 7; n++) {
+ auto value = pgmBuilder.NewDataLiteral<i32>(4);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param = pgmBuilder.NewDataLiteral<ui32>(4);
+ TVector<TRuntimeNode> params = {pgmTopFreq, param};
+ pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
+ }
+
+ auto value = setup.GetValue(pgmReturn);
+
+ auto listIterator = value.GetListIterator();
+
+ TUnboxedValue item;
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 1);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 9);
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 4);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 7);
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 3);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 1);
+
+ UNIT_ASSERT(!listIterator.Next(item));
+ }
+
+ Y_UNIT_TEST(MergingTopFreq) {
+ TSetup setup;
+ TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
+
+ const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto emptyStructType = pgmBuilder.NewEmptyStructType();
+ const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Uint64");
+ const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
+
+ const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
+ const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
+
+ auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
+ auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
+ auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
+
+ auto mergeArgsType = pgmBuilder.NewTupleType({resourceType, resourceType});
+ auto mergeUserType = pgmBuilder.NewTupleType({mergeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Merge = pgmBuilder.Udf("TopFreq.TopFreq_Merge", TRuntimeNode(), mergeUserType);
+
+ auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
+ auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
+
+ TRuntimeNode pgmTopFreq;
+ {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(1);
+ auto param = pgmBuilder.NewDataLiteral<ui32>(1);
+ TVector<TRuntimeNode> params = {value, param};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
+ }
+
+ for (int n = 0; n < 1; n++) {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(1);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ for (int n = 0; n < 4; n++) {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(5);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ for (int n = 0; n < 1; n++) {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(3);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ TRuntimeNode pgmTopFreq2;
+ {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(1);
+ auto param = pgmBuilder.NewDataLiteral<ui32>(1);
+ TVector<TRuntimeNode> params = {value, param};
+ pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_Create, params);
+ }
+
+ for (int n = 0; n < 5; n++) {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(1);
+ TVector<TRuntimeNode> params = {pgmTopFreq2, value};
+ pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ for (int n = 0; n < 5; n++) {
+ auto value = pgmBuilder.NewDataLiteral<ui64>(5);
+ TVector<TRuntimeNode> params = {pgmTopFreq2, value};
+ pgmTopFreq2 = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ TRuntimeNode pgmTopFreq3;
+ {
+ TVector<TRuntimeNode> params = {pgmTopFreq, pgmTopFreq2};
+ pgmTopFreq3 = pgmBuilder.Apply(udfTopFreq_Merge, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param = pgmBuilder.NewDataLiteral<ui32>(1);
+ TVector<TRuntimeNode> params = {pgmTopFreq3, param};
+ pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
+ }
+
+ auto value = setup.GetValue(pgmReturn);
+
+ auto listIterator = value.GetListIterator();
+
+ TUnboxedValue item;
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<ui64>(), 5);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 9);
+
+ UNIT_ASSERT(!listIterator.Next(item));
+ }
+
+ Y_UNIT_TEST(SerializedTopFreq) {
+ TSetup setup;
+ TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
+
+ const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<bool>::Id);
+ const auto emptyStructType = pgmBuilder.NewEmptyStructType();
+ const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Bool");
+ const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto ui64Type = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
+
+ const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
+ const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
+
+ auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
+ auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
+ auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
+
+ auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
+ auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
+
+ auto serializeArgsType = pgmBuilder.NewTupleType({resourceType});
+ auto serializeUserType = pgmBuilder.NewTupleType({serializeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Serialize = pgmBuilder.Udf("TopFreq.TopFreq_Serialize", TRuntimeNode(), serializeUserType);
+
+ auto serializedType = pgmBuilder.NewTupleType({ui32Type, ui32Type,
+ pgmBuilder.NewListType(pgmBuilder.NewTupleType({ui64Type, valueType}))});
+
+ auto deserializeArgsType = pgmBuilder.NewTupleType({serializedType});
+ auto deserializeUserType = pgmBuilder.NewTupleType({deserializeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Deserialize = pgmBuilder.Udf("TopFreq.TopFreq_Deserialize", TRuntimeNode(), deserializeUserType);
+
+ TRuntimeNode pgmTopFreq;
+ {
+ auto value = pgmBuilder.NewDataLiteral<bool>(true);
+ auto param = pgmBuilder.NewDataLiteral<ui32>(10);
+ TVector<TRuntimeNode> params = {value, param};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
+ }
+
+ for (int n = 0; n < 7; n++) {
+ auto value = pgmBuilder.NewDataLiteral<bool>(true);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ for (int n = 0; n < 10; n++) {
+ auto value = pgmBuilder.NewDataLiteral<bool>(false);
+ TVector<TRuntimeNode> params = {pgmTopFreq, value};
+ pgmTopFreq = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ }
+
+ TRuntimeNode pgmSerializedTopFreq;
+ {
+ TVector<TRuntimeNode> params = {pgmTopFreq};
+ pgmSerializedTopFreq = pgmBuilder.Apply(udfTopFreq_Serialize, params);
+ }
+
+ TRuntimeNode pgmDeserializedTopFreq;
+ {
+ TVector<TRuntimeNode> params = {pgmSerializedTopFreq};
+ pgmDeserializedTopFreq = pgmBuilder.Apply(udfTopFreq_Deserialize, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ auto param = pgmBuilder.NewDataLiteral<ui32>(3);
+ TVector<TRuntimeNode> params = {pgmDeserializedTopFreq, param};
+ pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
+ }
+
+ auto value = setup.GetValue(pgmReturn);
+
+ auto listIterator = value.GetListIterator();
+
+ TUnboxedValue item;
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<bool>(), false);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 10);
+
+ UNIT_ASSERT(listIterator.Next(item));
+ UNIT_ASSERT_EQUAL(item.GetElement(1).Get<bool>(), true);
+ UNIT_ASSERT_EQUAL(item.GetElement(0).Get<ui64>(), 8);
+
+ UNIT_ASSERT(!listIterator.Next(item));
+ }
+
+ Y_UNIT_TEST(ApproxTopFreq) {
+ TSetup setup;
+ TProgramBuilder& pgmBuilder = setup.GetProgramBuilder();
+
+ const auto valueType = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
+ const auto emptyStructType = pgmBuilder.NewEmptyStructType();
+ const auto resourceType = pgmBuilder.NewResourceType("TopFreq.TopFreqResource.Uint64");
+ const auto ui32Type = pgmBuilder.NewDataType(NUdf::TDataType<ui32>::Id);
+ const auto ui64Type = pgmBuilder.NewDataType(NUdf::TDataType<ui64>::Id);
+
+ const auto createArgsType = pgmBuilder.NewTupleType({valueType, ui32Type});
+ const auto createUserType = pgmBuilder.NewTupleType({createArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Create = pgmBuilder.Udf("TopFreq.TopFreq_Create", TRuntimeNode(), createUserType);
+
+ auto addValueArgsType = pgmBuilder.NewTupleType({resourceType, valueType});
+ auto addValueUserType = pgmBuilder.NewTupleType({addValueArgsType, emptyStructType, valueType});
+ auto udfTopFreq_AddValue = pgmBuilder.Udf("TopFreq.TopFreq_AddValue", TRuntimeNode(), addValueUserType);
+
+ auto mergeArgsType = pgmBuilder.NewTupleType({resourceType, resourceType});
+ auto mergeUserType = pgmBuilder.NewTupleType({mergeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Merge = pgmBuilder.Udf("TopFreq.TopFreq_Merge", TRuntimeNode(), mergeUserType);
+
+ auto getArgsType = pgmBuilder.NewTupleType({resourceType, ui32Type});
+ auto getUserType = pgmBuilder.NewTupleType({getArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Get = pgmBuilder.Udf("TopFreq.TopFreq_Get", TRuntimeNode(), getUserType);
+
+ auto serializeArgsType = pgmBuilder.NewTupleType({resourceType});
+ auto serializeUserType = pgmBuilder.NewTupleType({serializeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Serialize = pgmBuilder.Udf("TopFreq.TopFreq_Serialize", TRuntimeNode(), serializeUserType);
+
+ auto serializedType = pgmBuilder.NewTupleType({ui32Type, ui32Type,
+ pgmBuilder.NewListType(pgmBuilder.NewTupleType({ui64Type, valueType}))});
+
+ auto deserializeArgsType = pgmBuilder.NewTupleType({serializedType});
+ auto deserializeUserType = pgmBuilder.NewTupleType({deserializeArgsType, emptyStructType, valueType});
+ auto udfTopFreq_Deserialize = pgmBuilder.Udf("TopFreq.TopFreq_Deserialize", TRuntimeNode(), deserializeUserType);
+
+ static const ui64 BigNum = 20;
+ static const ui64 BigEach = 5000;
+ static const ui64 SmallNum = 500;
+ static const ui64 SmallEach = 20;
+ static const ui64 Total = BigNum * BigEach + SmallNum * SmallEach;
+ static const i32 AskFor = 25;
+ static const ui64 BlockSize = 200;
+ static const ui64 BlockCount = 10;
+ static const i32 WorksIfAtLeast = 15;
+
+ std::array<ui64, Total> values;
+ std::array<TRuntimeNode, BlockCount> pgmTopFreqs;
+
+ i32 curIndex = 0;
+ for (ui64 i = 1; i <= BigNum; i++) {
+ for (ui64 j = 0; j < BigEach; j++) {
+ values[curIndex++] = i;
}
- }
+ }
- for (ui64 i = BigNum + 1; i <= BigNum + SmallNum; i++) {
- for (ui64 j = 0; j < SmallEach; j++) {
- values[curIndex++] = i;
+ for (ui64 i = BigNum + 1; i <= BigNum + SmallNum; i++) {
+ for (ui64 j = 0; j < SmallEach; j++) {
+ values[curIndex++] = i;
}
- }
+ }
- Shuffle(values.begin(), values.end());
+ Shuffle(values.begin(), values.end());
- TVector<TRuntimeNode> params;
- TRuntimeNode param;
- TRuntimeNode pgmvalue;
+ TVector<TRuntimeNode> params;
+ TRuntimeNode param;
+ TRuntimeNode pgmvalue;
- for (ui64 i = 0; i < BlockCount; i++) {
+ for (ui64 i = 0; i < BlockCount; i++) {
{
- pgmvalue = pgmBuilder.NewDataLiteral<ui64>(values[i * BlockSize]);
+ pgmvalue = pgmBuilder.NewDataLiteral<ui64>(values[i * BlockSize]);
param = pgmBuilder.NewDataLiteral<ui32>(AskFor);
params = {pgmvalue, param};
- pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Create, params);
+ pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Create, params);
}
- for (ui64 j = i * BlockSize + 1; j < (i + 1) * BlockSize; j++) {
- pgmvalue = pgmBuilder.NewDataLiteral<ui64>(values[j]);
- params = {pgmTopFreqs[i], pgmvalue};
- pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_AddValue, params);
+ for (ui64 j = i * BlockSize + 1; j < (i + 1) * BlockSize; j++) {
+ pgmvalue = pgmBuilder.NewDataLiteral<ui64>(values[j]);
+ params = {pgmTopFreqs[i], pgmvalue};
+ pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_AddValue, params);
}
{
- params = {pgmTopFreqs[i]};
- pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Serialize, params);
+ params = {pgmTopFreqs[i]};
+ pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Serialize, params);
}
- }
-
- TRuntimeNode pgmMainTopFreq;
- {
- pgmvalue = pgmBuilder.NewDataLiteral<ui64>(Total + 2);
- param = pgmBuilder.NewDataLiteral<ui32>(AskFor);
- params = {pgmvalue, param};
- pgmMainTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
- }
-
- for (ui64 i = 0; i < BlockCount; i++) {
- params = {pgmTopFreqs[i]};
- pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Deserialize, params);
-
- params = {pgmMainTopFreq, pgmTopFreqs[i]};
- pgmMainTopFreq = pgmBuilder.Apply(udfTopFreq_Merge, params);
- }
-
- TRuntimeNode pgmReturn;
- {
- param = pgmBuilder.NewDataLiteral<ui32>(AskFor);
- params = {pgmMainTopFreq, param};
- pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
- }
-
- auto value = setup.GetValue(pgmReturn);
-
- auto listIterator = value.GetListIterator();
-
- ui32 found = 0;
-
- for (ui64 i = 0; i < AskFor; i++) {
- TUnboxedValue item;
-
- UNIT_ASSERT(listIterator.Next(item));
- ui64 current = item.GetElement(1).Get<ui64>();
- if (current <= BigNum)
- found++;
}
-
- UNIT_ASSERT(!listIterator.Skip());
- UNIT_ASSERT(found >= WorksIfAtLeast);
+
+ TRuntimeNode pgmMainTopFreq;
+ {
+ pgmvalue = pgmBuilder.NewDataLiteral<ui64>(Total + 2);
+ param = pgmBuilder.NewDataLiteral<ui32>(AskFor);
+ params = {pgmvalue, param};
+ pgmMainTopFreq = pgmBuilder.Apply(udfTopFreq_Create, params);
+ }
+
+ for (ui64 i = 0; i < BlockCount; i++) {
+ params = {pgmTopFreqs[i]};
+ pgmTopFreqs[i] = pgmBuilder.Apply(udfTopFreq_Deserialize, params);
+
+ params = {pgmMainTopFreq, pgmTopFreqs[i]};
+ pgmMainTopFreq = pgmBuilder.Apply(udfTopFreq_Merge, params);
+ }
+
+ TRuntimeNode pgmReturn;
+ {
+ param = pgmBuilder.NewDataLiteral<ui32>(AskFor);
+ params = {pgmMainTopFreq, param};
+ pgmReturn = pgmBuilder.Apply(udfTopFreq_Get, params);
+ }
+
+ auto value = setup.GetValue(pgmReturn);
+
+ auto listIterator = value.GetListIterator();
+
+ ui32 found = 0;
+
+ for (ui64 i = 0; i < AskFor; i++) {
+ TUnboxedValue item;
+
+ UNIT_ASSERT(listIterator.Next(item));
+ ui64 current = item.GetElement(1).Get<ui64>();
+ if (current <= BigNum)
+ found++;
+ }
+
+ UNIT_ASSERT(!listIterator.Skip());
+ UNIT_ASSERT(found >= WorksIfAtLeast);
}
}
}
diff --git a/ydb/library/yql/udfs/common/url_base/lib/url_parse.cpp b/ydb/library/yql/udfs/common/url_base/lib/url_parse.cpp
index 0cdfbc0d83..63015dadc6 100644
--- a/ydb/library/yql/udfs/common/url_base/lib/url_parse.cpp
+++ b/ydb/library/yql/udfs/common/url_base/lib/url_parse.cpp
@@ -1,11 +1,11 @@
#include "url_parse.h"
-#define FIELD_ADD(name) structBuilder->AddField(#name, optionalStringType, &urlParseIndexes.name);
-#define FIELD_FILL(name) \
- if (value.FldIsSet(TUri::Field##name)) { \
- fields[UrlParseIndexes.name] = valueBuilder->NewString(value.GetField(TUri::Field##name)); \
- }
-
+#define FIELD_ADD(name) structBuilder->AddField(#name, optionalStringType, &urlParseIndexes.name);
+#define FIELD_FILL(name) \
+ if (value.FldIsSet(TUri::Field##name)) { \
+ fields[UrlParseIndexes.name] = valueBuilder->NewString(value.GetField(TUri::Field##name)); \
+ }
+
namespace NUrlUdf {
using namespace NUri;
using namespace NKikimr;
@@ -15,9 +15,9 @@ namespace NUrlUdf {
const IValueBuilder* valueBuilder,
const TUnboxedValuePod* args) const {
TUri value;
- const auto ParseError = value.ParseAbs(args[0].AsStringRef(), ParseFlags);
+ const auto ParseError = value.ParseAbs(args[0].AsStringRef(), ParseFlags);
TUnboxedValue* fields = nullptr;
- const auto result = valueBuilder->NewArray(FieldsCount, fields);
+ const auto result = valueBuilder->NewArray(FieldsCount, fields);
if (ParseError == TUri::ParsedOK) {
FIELD_MAP(FIELD_FILL)
} else {
@@ -36,8 +36,8 @@ namespace NUrlUdf {
TUrlParseIndexes urlParseIndexes;
builder.Args(1)->Add<TAutoMap<char*>>();
- const auto optionalStringType = builder.Optional()->Item<char*>().Build();
- const auto structBuilder = builder.Struct(FieldsCount);
+ const auto optionalStringType = builder.Optional()->Item<char*>().Build();
+ const auto structBuilder = builder.Struct(FieldsCount);
structBuilder->AddField("ParseError", optionalStringType, &urlParseIndexes.ParseError);
FIELD_MAP(FIELD_ADD)
builder.Returns(structBuilder->Build());
diff --git a/ydb/library/yql/udfs/common/yson2/ya.make b/ydb/library/yql/udfs/common/yson2/ya.make
index dfd22274bf..8b293d2fe7 100644
--- a/ydb/library/yql/udfs/common/yson2/ya.make
+++ b/ydb/library/yql/udfs/common/yson2/ya.make
@@ -2,7 +2,7 @@ YQL_UDF(yson2_udf)
YQL_ABI_VERSION(
2
- 21
+ 21
0
)
diff --git a/ydb/library/yql/udfs/common/yson2/yson2_udf.cpp b/ydb/library/yql/udfs/common/yson2/yson2_udf.cpp
index 78f7ed5356..1278ec565c 100644
--- a/ydb/library/yql/udfs/common/yson2/yson2_udf.cpp
+++ b/ydb/library/yql/udfs/common/yson2/yson2_udf.cpp
@@ -10,105 +10,105 @@
#include <library/cpp/yson_pull/exceptions.h>
-#include <util/string/split.h>
-
-using namespace NYql::NUdf;
+#include <util/string/split.h>
+
+using namespace NYql::NUdf;
using namespace NYql::NDom;
using namespace NYsonPull;
-namespace {
-
-constexpr char OptionsResourceName[] = "Yson2.Options";
-
-using TOptionsResource = TResource<OptionsResourceName>;
+namespace {
+
+constexpr char OptionsResourceName[] = "Yson2.Options";
+
+using TOptionsResource = TResource<OptionsResourceName>;
using TNodeResource = TResource<NodeResourceName>;
-
+
using TDictType = TDict<char*, TNodeResource>;
-using TInt64DictType = TDict<char*, i64>;
-using TUint64DictType = TDict<char*, ui64>;
-using TBoolDictType = TDict<char*, bool>;
-using TDoubleDictType = TDict<char*, double>;
-using TStringDictType = TDict<char*, char*>;
-
-enum class EOptions : ui8 {
- Strict = 1,
- AutoConvert = 2
-};
-
-union TOpts {
- ui8 Raw = 0;
- struct {
- bool Strict: 1;
- bool AutoConvert: 1;
- };
-};
-
-static_assert(sizeof(TOpts) == 1U, "Wrong TOpts size.");
-
-TOpts ParseOptions(TUnboxedValuePod x) {
- if (x) {
- return TOpts{x.Get<ui8>()};
- }
- return {};
-}
-
-class TOptions : public TBoxedValue {
+using TInt64DictType = TDict<char*, i64>;
+using TUint64DictType = TDict<char*, ui64>;
+using TBoolDictType = TDict<char*, bool>;
+using TDoubleDictType = TDict<char*, double>;
+using TStringDictType = TDict<char*, char*>;
+
+enum class EOptions : ui8 {
+ Strict = 1,
+ AutoConvert = 2
+};
+
+union TOpts {
+ ui8 Raw = 0;
+ struct {
+ bool Strict: 1;
+ bool AutoConvert: 1;
+ };
+};
+
+static_assert(sizeof(TOpts) == 1U, "Wrong TOpts size.");
+
+TOpts ParseOptions(TUnboxedValuePod x) {
+ if (x) {
+ return TOpts{x.Get<ui8>()};
+ }
+ return {};
+}
+
+class TOptions : public TBoxedValue {
TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const override {
- ui8 options = 0;
-
- if (args[0] && args[0].Get<bool>()) {
- options |= ui8(EOptions::AutoConvert);
- }
-
- if (args[1] && args[1].Get<bool>()) {
- options |= ui8(EOptions::Strict);
- }
-
- return TUnboxedValuePod(options);
- }
-public:
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("Options");
- return name;
- }
-
- static bool DeclareSignature(
- const TStringRef& name,
- TType* userType,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly) {
- Y_UNUSED(userType);
- if (Name() == name) {
- auto argsBuilder = builder.Args(2U);
- argsBuilder->Add<TOptional<bool>>().Name(TStringRef::Of("AutoConvert"));
- argsBuilder->Add<TOptional<bool>>().Name(TStringRef::Of("Strict"));
- builder.Returns(builder.Resource(OptionsResourceName));
- builder.OptionalArgs(2U);
- if (!typesOnly) {
- builder.Implementation(new TOptions);
- }
-
- return true;
- } else {
- return false;
- }
- }
-};
-
-using TConverterPtr = TUnboxedValuePod (*)(TUnboxedValuePod, const IValueBuilder*, const TSourcePosition& pos);
+ ui8 options = 0;
+
+ if (args[0] && args[0].Get<bool>()) {
+ options |= ui8(EOptions::AutoConvert);
+ }
+
+ if (args[1] && args[1].Get<bool>()) {
+ options |= ui8(EOptions::Strict);
+ }
+
+ return TUnboxedValuePod(options);
+ }
+public:
+ static const TStringRef& Name() {
+ static auto name = TStringRef::Of("Options");
+ return name;
+ }
+
+ static bool DeclareSignature(
+ const TStringRef& name,
+ TType* userType,
+ IFunctionTypeInfoBuilder& builder,
+ bool typesOnly) {
+ Y_UNUSED(userType);
+ if (Name() == name) {
+ auto argsBuilder = builder.Args(2U);
+ argsBuilder->Add<TOptional<bool>>().Name(TStringRef::Of("AutoConvert"));
+ argsBuilder->Add<TOptional<bool>>().Name(TStringRef::Of("Strict"));
+ builder.Returns(builder.Resource(OptionsResourceName));
+ builder.OptionalArgs(2U);
+ if (!typesOnly) {
+ builder.Implementation(new TOptions);
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+using TConverterPtr = TUnboxedValuePod (*)(TUnboxedValuePod, const IValueBuilder*, const TSourcePosition& pos);
template <TConverterPtr Converter>
-class TLazyConveterT : public TManagedBoxedValue {
+class TLazyConveterT : public TManagedBoxedValue {
public:
- TLazyConveterT(TUnboxedValue&& original, const IValueBuilder* valueBuilder, const TSourcePosition& pos)
- : Original(std::move(original)), ValueBuilder(valueBuilder), Pos_(pos)
- {}
-private:
+ TLazyConveterT(TUnboxedValue&& original, const IValueBuilder* valueBuilder, const TSourcePosition& pos)
+ : Original(std::move(original)), ValueBuilder(valueBuilder), Pos_(pos)
+ {}
+private:
template <bool NoSwap>
class TIterator: public TManagedBoxedValue {
public:
- TIterator(TUnboxedValue&& original, const IValueBuilder* valueBuilder, const TSourcePosition& pos)
- : Original(std::move(original)), ValueBuilder(valueBuilder), Pos_(pos)
+ TIterator(TUnboxedValue&& original, const IValueBuilder* valueBuilder, const TSourcePosition& pos)
+ : Original(std::move(original)), ValueBuilder(valueBuilder), Pos_(pos)
{}
private:
@@ -119,7 +119,7 @@ private:
bool Next(TUnboxedValue& value) final {
if (Original.Next(value)) {
if constexpr (!NoSwap) {
- value = Converter(value.Release(), ValueBuilder, Pos_);
+ value = Converter(value.Release(), ValueBuilder, Pos_);
}
return true;
}
@@ -129,9 +129,9 @@ private:
bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final {
if (Original.NextPair(key, payload)) {
if constexpr (NoSwap) {
- payload = Converter(payload.Release(), ValueBuilder, Pos_);
+ payload = Converter(payload.Release(), ValueBuilder, Pos_);
} else {
- key = Converter(key.Release(), ValueBuilder, Pos_);
+ key = Converter(key.Release(), ValueBuilder, Pos_);
}
return true;
}
@@ -139,8 +139,8 @@ private:
}
const TUnboxedValue Original;
- const IValueBuilder *const ValueBuilder;
- const TSourcePosition Pos_;
+ const IValueBuilder *const ValueBuilder;
+ const TSourcePosition Pos_;
};
ui64 GetDictLength() const final {
@@ -164,19 +164,19 @@ private:
}
TUnboxedValue GetListIterator() const final {
- return TUnboxedValuePod(new TIterator<false>(Original.GetListIterator(), ValueBuilder, Pos_));
+ return TUnboxedValuePod(new TIterator<false>(Original.GetListIterator(), ValueBuilder, Pos_));
}
TUnboxedValue GetDictIterator() const final {
- return TUnboxedValuePod(new TIterator<true>(Original.GetDictIterator(), ValueBuilder, Pos_));
+ return TUnboxedValuePod(new TIterator<true>(Original.GetDictIterator(), ValueBuilder, Pos_));
}
TUnboxedValue GetKeysIterator() const final {
- return TUnboxedValuePod(new TIterator<true>(Original.GetKeysIterator(), ValueBuilder, Pos_));
+ return TUnboxedValuePod(new TIterator<true>(Original.GetKeysIterator(), ValueBuilder, Pos_));
}
TUnboxedValue GetPayloadsIterator() const override {
- return TUnboxedValuePod(new TIterator<false>(Original.GetPayloadsIterator(), ValueBuilder, Pos_));
+ return TUnboxedValuePod(new TIterator<false>(Original.GetPayloadsIterator(), ValueBuilder, Pos_));
}
bool Contains(const TUnboxedValuePod& key) const final {
@@ -185,7 +185,7 @@ private:
TUnboxedValue Lookup(const TUnboxedValuePod& key) const final {
if (auto lookup = Original.Lookup(key)) {
- return Converter(lookup.Release().GetOptionalValue(), ValueBuilder, Pos_).MakeOptional();
+ return Converter(lookup.Release().GetOptionalValue(), ValueBuilder, Pos_).MakeOptional();
}
return {};
}
@@ -195,499 +195,499 @@ private:
}
const TUnboxedValue Original;
- const IValueBuilder *const ValueBuilder;
- const TSourcePosition Pos_;
+ const IValueBuilder *const ValueBuilder;
+ const TSourcePosition Pos_;
};
-template<bool Strict, bool AutoConvert, TConverterPtr Converter = nullptr>
-TUnboxedValuePod ConvertToListImpl(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+template<bool Strict, bool AutoConvert, TConverterPtr Converter = nullptr>
+TUnboxedValuePod ConvertToListImpl(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
if (!x) {
- return valueBuilder->NewEmptyList().Release();
+ return valueBuilder->NewEmptyList().Release();
}
- switch (GetNodeType(x)) {
- case ENodeType::List:
- if (!x.IsBoxed())
- break;
- if constexpr (Converter != nullptr) {
- if constexpr (Strict || AutoConvert) {
- return TUnboxedValuePod(new TLazyConveterT<Converter>(x, valueBuilder, pos));
- } else {
- TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> values;
- if (const auto elements = x.GetElements()) {
- const auto size = x.GetListLength();
- values.reserve(size);
- for (ui32 i = 0U; i < size; ++i) {
- if (auto converted = Converter(elements[i], valueBuilder, pos)) {
- values.emplace_back(std::move(converted));
- }
- }
- } else {
- const auto it = x.GetListIterator();
- for (TUnboxedValue v; it.Next(v);) {
- if (auto converted = Converter(v.Release(), valueBuilder, pos)) {
- values.emplace_back(std::move(converted));
- }
- }
- }
- if (values.empty()) {
- break;
- }
- return valueBuilder->NewList(values.data(), values.size()).Release();
- }
- }
- return x;
- case ENodeType::Attr:
- return ConvertToListImpl<Strict, AutoConvert, Converter>(x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (Strict) {
- if (!IsNodeType<ENodeType::List>(x)) {
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse list from " << TDebugPrinter(x)).c_str());
- }
- }
+ switch (GetNodeType(x)) {
+ case ENodeType::List:
+ if (!x.IsBoxed())
+ break;
+ if constexpr (Converter != nullptr) {
+ if constexpr (Strict || AutoConvert) {
+ return TUnboxedValuePod(new TLazyConveterT<Converter>(x, valueBuilder, pos));
+ } else {
+ TSmallVec<TUnboxedValue, TUnboxedValue::TAllocator> values;
+ if (const auto elements = x.GetElements()) {
+ const auto size = x.GetListLength();
+ values.reserve(size);
+ for (ui32 i = 0U; i < size; ++i) {
+ if (auto converted = Converter(elements[i], valueBuilder, pos)) {
+ values.emplace_back(std::move(converted));
+ }
+ }
+ } else {
+ const auto it = x.GetListIterator();
+ for (TUnboxedValue v; it.Next(v);) {
+ if (auto converted = Converter(v.Release(), valueBuilder, pos)) {
+ values.emplace_back(std::move(converted));
+ }
+ }
+ }
+ if (values.empty()) {
+ break;
+ }
+ return valueBuilder->NewList(values.data(), values.size()).Release();
+ }
+ }
+ return x;
+ case ENodeType::Attr:
+ return ConvertToListImpl<Strict, AutoConvert, Converter>(x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (Strict) {
+ if (!IsNodeType<ENodeType::List>(x)) {
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse list from " << TDebugPrinter(x)).c_str());
+ }
+ }
}
- return valueBuilder->NewEmptyList().Release();
-}
-
-template<bool Strict, bool AutoConvert, TConverterPtr Converter = nullptr>
-TUnboxedValuePod ConvertToDictImpl(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- if (!x) {
- return valueBuilder->NewEmptyList().Release();
- }
-
- switch (GetNodeType(x)) {
- case ENodeType::Dict:
- if (!x.IsBoxed())
- break;
- if constexpr (Converter != nullptr) {
- if constexpr (Strict || AutoConvert) {
- return TUnboxedValuePod(new TLazyConveterT<Converter>(x, valueBuilder, pos));
- } else if (const auto size = x.GetDictLength()) {
- TSmallVec<TPair, TStdAllocatorForUdf<TPair>> pairs;
- pairs.reserve(size);
- const auto it = x.GetDictIterator();
- for (TUnboxedValue key, payload; it.NextPair(key, payload);) {
- if (auto converted = Converter(payload, valueBuilder, pos)) {
- pairs.emplace_back(std::move(key), std::move(converted));
- }
- }
- if (pairs.empty()) {
- break;
- }
+ return valueBuilder->NewEmptyList().Release();
+}
+
+template<bool Strict, bool AutoConvert, TConverterPtr Converter = nullptr>
+TUnboxedValuePod ConvertToDictImpl(TUnboxedValuePod x, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ if (!x) {
+ return valueBuilder->NewEmptyList().Release();
+ }
+
+ switch (GetNodeType(x)) {
+ case ENodeType::Dict:
+ if (!x.IsBoxed())
+ break;
+ if constexpr (Converter != nullptr) {
+ if constexpr (Strict || AutoConvert) {
+ return TUnboxedValuePod(new TLazyConveterT<Converter>(x, valueBuilder, pos));
+ } else if (const auto size = x.GetDictLength()) {
+ TSmallVec<TPair, TStdAllocatorForUdf<TPair>> pairs;
+ pairs.reserve(size);
+ const auto it = x.GetDictIterator();
+ for (TUnboxedValue key, payload; it.NextPair(key, payload);) {
+ if (auto converted = Converter(payload, valueBuilder, pos)) {
+ pairs.emplace_back(std::move(key), std::move(converted));
+ }
+ }
+ if (pairs.empty()) {
+ break;
+ }
return TUnboxedValuePod(IBoxedValuePtr(new TMapNode(pairs.data(), pairs.size())));
- }
- }
- return x;
- case ENodeType::Attr:
- return ConvertToDictImpl<Strict, AutoConvert, Converter>(x.GetVariantItem().Release(), valueBuilder, pos);
- default:
- if constexpr (Strict) {
- if (!IsNodeType<ENodeType::Dict>(x)) {
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse dict from " << TDebugPrinter(x)).c_str());
- }
- }
- }
-
- return valueBuilder->NewEmptyList().Release();
-}
-
-template <TConverterPtr Converter = nullptr>
-TUnboxedValuePod LookupImpl(TUnboxedValuePod dict, const TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(dict)) {
- case ENodeType::Dict:
- if (dict.IsBoxed()) {
- if (auto payload = dict.Lookup(key)) {
- if constexpr (Converter != nullptr) {
- return Converter(payload.Release().GetOptionalValue(), valueBuilder, pos);
- }
- return payload.Release();
- }
- }
- return {};
- case ENodeType::List:
- if (dict.IsBoxed()) {
- if (const i32 size = dict.GetListLength()) {
- if (i32 index; TryFromString(key.AsStringRef(), index) && index < size && index >= -size) {
- if (index < 0)
- index += size;
- if constexpr (Converter != nullptr) {
- return Converter(dict.GetElement(index).Release(), valueBuilder, pos);
- }
- return dict.GetElement(index).Release();
- }
- }
- }
- return {};
- case ENodeType::Attr:
- return LookupImpl<Converter>(dict.GetVariantItem().Release(), key, valueBuilder, pos);
- default:
- return {};
- }
-}
-
-template <TConverterPtr Converter = nullptr>
-TUnboxedValuePod YPathImpl(TUnboxedValuePod dict, const TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- const std::string_view path = key.AsStringRef();
- if (path.size() < 2U || path.front() != '/' || path.back() == '/') {
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Invalid YPath: '" << path << "'.").data());
- }
-
- for (const auto s : StringSplitter(path.substr(path[1U] == '/' ? 2U : 1U)).Split('/')) {
- const bool attr = IsNodeType<ENodeType::Attr>(dict);
- if (const std::string_view subpath = s.Token(); subpath == "@") {
- if (attr)
- dict = SetNodeType<ENodeType::Dict>(dict);
- else
- return {};
- } else {
- if (attr) {
- dict = dict.GetVariantItem().Release();
- }
-
- const auto subkey = valueBuilder->SubString(key, std::distance(path.begin(), subpath.begin()), subpath.size());
- dict = LookupImpl<nullptr>(dict, subkey, valueBuilder, pos);
- }
-
- if (!dict) {
- return {};
- }
- }
-
- if constexpr (Converter != nullptr) {
- return Converter(dict, valueBuilder, pos);
- }
-
- return dict;
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod ContainsImpl(TUnboxedValuePod dict, TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(dict)) {
- case ENodeType::Attr:
- return ContainsImpl<Strict, AutoConvert>(dict.GetVariantItem().Release(), key, valueBuilder, pos);
- case ENodeType::Dict:
- if (dict.IsBoxed())
- return TUnboxedValuePod(dict.Contains(key));
- else
- return TUnboxedValuePod(false);
- case ENodeType::List:
- if (dict.IsBoxed()) {
- if (const i32 size = dict.GetListLength()) {
- if (i32 index; TryFromString(key.AsStringRef(), index)) {
- return TUnboxedValuePod(index < size && index >= -size);
- }
- }
- }
- return TUnboxedValuePod(false);
- default:
- if constexpr (Strict && !AutoConvert)
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Can't check contains on scalar " << TDebugPrinter(dict)).c_str());
- else
- return {};
- }
-}
-
-template<bool Strict, bool AutoConvert>
-TUnboxedValuePod GetLengthImpl(TUnboxedValuePod dict, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
- switch (GetNodeType(dict)) {
- case ENodeType::Attr:
- return GetLengthImpl<Strict, AutoConvert>(dict.GetVariantItem().Release(), valueBuilder, pos);
- case ENodeType::Dict:
- return TUnboxedValuePod(dict.IsBoxed() ? dict.GetDictLength() : ui64(0));
- case ENodeType::List:
- return TUnboxedValuePod(dict.IsBoxed() ? dict.GetListLength() : ui64(0));
- default:
- if constexpr (Strict && !AutoConvert)
- UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Can't get container length from scalar " << TDebugPrinter(dict)).c_str());
- else
- return {};
- }
-}
-
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToBool, TOptional<bool>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToBool<true, true> : &ConvertToBool<true, false>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToBool<false, true> : &ConvertToBool<false, false>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToInt64, TOptional<i64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToIntegral<true, true, i64> : &ConvertToIntegral<true, false, i64>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToIntegral<false, true, i64> : &ConvertToIntegral<false, false, i64>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToUint64, TOptional<ui64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToIntegral<true, true, ui64> : &ConvertToIntegral<true, false, ui64>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToIntegral<false, true, ui64> : &ConvertToIntegral<false, false, ui64>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToDouble, TOptional<double>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToFloat<true, true, double> : &ConvertToFloat<true, false, double>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToFloat<false, true, double> : &ConvertToFloat<false, false, double>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToString, TOptional<char*>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToString<true, true, false> : &ConvertToString<true, false, false>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToString<false, true, false> : &ConvertToString<false, false, false>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToList, TListType<TNodeResource>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true> : &ConvertToListImpl<true, false>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true> : &ConvertToListImpl<false, false>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToInt64List, TListType<i64>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToIntegral<true, true, i64>> : &ConvertToListImpl<true, false, &ConvertToIntegral<true, false, i64>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToIntegral<false, true, i64>> : &ConvertToListImpl<false, false, &ConvertToIntegral<false, false, i64>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToUint64List, TListType<ui64>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToIntegral<true, true, ui64>> : &ConvertToListImpl<true, false, &ConvertToIntegral<true, false, ui64>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToIntegral<false, true, ui64>> : &ConvertToListImpl<false, false, &ConvertToIntegral<false, false, ui64>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToBoolList, TListType<bool>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToBool<true, true>> : &ConvertToListImpl<true, false, &ConvertToBool<true, false>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToBool<false, true>> : &ConvertToListImpl<false, false, &ConvertToBool<false, false>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToDoubleList, TListType<double>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToFloat<true, true, double>> : &ConvertToListImpl<true, false, &ConvertToFloat<true, false, double>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToFloat<false, true, double>> : &ConvertToListImpl<false, false, &ConvertToFloat<false, false, double>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToStringList, TListType<char*>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToString<true, true, false>> : &ConvertToListImpl<true, false, &ConvertToString<true, false, false>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToString<false, true, false>> : &ConvertToListImpl<false, false, &ConvertToString<false, false, false>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToDict, TDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true> : &ConvertToDictImpl<true, false>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true> : &ConvertToDictImpl<false, false>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToInt64Dict, TInt64DictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToIntegral<true, true, i64>> : &ConvertToDictImpl<true, false, &ConvertToIntegral<true, false, i64>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToIntegral<false, true, i64>> : &ConvertToDictImpl<false, false, &ConvertToIntegral<false, false, i64>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToUint64Dict, TUint64DictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToIntegral<true, true, ui64>> : &ConvertToDictImpl<true, false, &ConvertToIntegral<true, false, ui64>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToIntegral<false, true, ui64>> : &ConvertToDictImpl<false, false, &ConvertToIntegral<false, false, ui64>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToBoolDict, TBoolDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToBool<true, true>> : &ConvertToDictImpl<true, false, &ConvertToBool<true, false>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToBool<false, true>> : &ConvertToDictImpl<false, false, &ConvertToBool<false, false>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToDoubleDict, TDoubleDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToFloat<true, true, double>> : &ConvertToDictImpl<true, false, &ConvertToFloat<true, false, double>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToFloat<false, true, double>> : &ConvertToDictImpl<false, false, &ConvertToFloat<false, false, double>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TConvertToStringDict, TStringDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToString<true, true, false>> : &ConvertToDictImpl<true, false, &ConvertToString<true, false, false>>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToString<false, true, false>> : &ConvertToDictImpl<false, false, &ConvertToString<false, false, false>>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF(TAttributes, TDictType(TAutoMap<TNodeResource>)) {
- const auto x = args[0];
- if (IsNodeType<ENodeType::Attr>(x)) {
+ }
+ }
+ return x;
+ case ENodeType::Attr:
+ return ConvertToDictImpl<Strict, AutoConvert, Converter>(x.GetVariantItem().Release(), valueBuilder, pos);
+ default:
+ if constexpr (Strict) {
+ if (!IsNodeType<ENodeType::Dict>(x)) {
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Cannot parse dict from " << TDebugPrinter(x)).c_str());
+ }
+ }
+ }
+
+ return valueBuilder->NewEmptyList().Release();
+}
+
+template <TConverterPtr Converter = nullptr>
+TUnboxedValuePod LookupImpl(TUnboxedValuePod dict, const TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(dict)) {
+ case ENodeType::Dict:
+ if (dict.IsBoxed()) {
+ if (auto payload = dict.Lookup(key)) {
+ if constexpr (Converter != nullptr) {
+ return Converter(payload.Release().GetOptionalValue(), valueBuilder, pos);
+ }
+ return payload.Release();
+ }
+ }
+ return {};
+ case ENodeType::List:
+ if (dict.IsBoxed()) {
+ if (const i32 size = dict.GetListLength()) {
+ if (i32 index; TryFromString(key.AsStringRef(), index) && index < size && index >= -size) {
+ if (index < 0)
+ index += size;
+ if constexpr (Converter != nullptr) {
+ return Converter(dict.GetElement(index).Release(), valueBuilder, pos);
+ }
+ return dict.GetElement(index).Release();
+ }
+ }
+ }
+ return {};
+ case ENodeType::Attr:
+ return LookupImpl<Converter>(dict.GetVariantItem().Release(), key, valueBuilder, pos);
+ default:
+ return {};
+ }
+}
+
+template <TConverterPtr Converter = nullptr>
+TUnboxedValuePod YPathImpl(TUnboxedValuePod dict, const TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ const std::string_view path = key.AsStringRef();
+ if (path.size() < 2U || path.front() != '/' || path.back() == '/') {
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Invalid YPath: '" << path << "'.").data());
+ }
+
+ for (const auto s : StringSplitter(path.substr(path[1U] == '/' ? 2U : 1U)).Split('/')) {
+ const bool attr = IsNodeType<ENodeType::Attr>(dict);
+ if (const std::string_view subpath = s.Token(); subpath == "@") {
+ if (attr)
+ dict = SetNodeType<ENodeType::Dict>(dict);
+ else
+ return {};
+ } else {
+ if (attr) {
+ dict = dict.GetVariantItem().Release();
+ }
+
+ const auto subkey = valueBuilder->SubString(key, std::distance(path.begin(), subpath.begin()), subpath.size());
+ dict = LookupImpl<nullptr>(dict, subkey, valueBuilder, pos);
+ }
+
+ if (!dict) {
+ return {};
+ }
+ }
+
+ if constexpr (Converter != nullptr) {
+ return Converter(dict, valueBuilder, pos);
+ }
+
+ return dict;
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod ContainsImpl(TUnboxedValuePod dict, TUnboxedValuePod key, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(dict)) {
+ case ENodeType::Attr:
+ return ContainsImpl<Strict, AutoConvert>(dict.GetVariantItem().Release(), key, valueBuilder, pos);
+ case ENodeType::Dict:
+ if (dict.IsBoxed())
+ return TUnboxedValuePod(dict.Contains(key));
+ else
+ return TUnboxedValuePod(false);
+ case ENodeType::List:
+ if (dict.IsBoxed()) {
+ if (const i32 size = dict.GetListLength()) {
+ if (i32 index; TryFromString(key.AsStringRef(), index)) {
+ return TUnboxedValuePod(index < size && index >= -size);
+ }
+ }
+ }
+ return TUnboxedValuePod(false);
+ default:
+ if constexpr (Strict && !AutoConvert)
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Can't check contains on scalar " << TDebugPrinter(dict)).c_str());
+ else
+ return {};
+ }
+}
+
+template<bool Strict, bool AutoConvert>
+TUnboxedValuePod GetLengthImpl(TUnboxedValuePod dict, const IValueBuilder* valueBuilder, const TSourcePosition& pos) {
+ switch (GetNodeType(dict)) {
+ case ENodeType::Attr:
+ return GetLengthImpl<Strict, AutoConvert>(dict.GetVariantItem().Release(), valueBuilder, pos);
+ case ENodeType::Dict:
+ return TUnboxedValuePod(dict.IsBoxed() ? dict.GetDictLength() : ui64(0));
+ case ENodeType::List:
+ return TUnboxedValuePod(dict.IsBoxed() ? dict.GetListLength() : ui64(0));
+ default:
+ if constexpr (Strict && !AutoConvert)
+ UdfTerminate((TStringBuilder() << valueBuilder->WithCalleePosition(pos) << " Can't get container length from scalar " << TDebugPrinter(dict)).c_str());
+ else
+ return {};
+ }
+}
+
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToBool, TOptional<bool>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToBool<true, true> : &ConvertToBool<true, false>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToBool<false, true> : &ConvertToBool<false, false>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToInt64, TOptional<i64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToIntegral<true, true, i64> : &ConvertToIntegral<true, false, i64>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToIntegral<false, true, i64> : &ConvertToIntegral<false, false, i64>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToUint64, TOptional<ui64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToIntegral<true, true, ui64> : &ConvertToIntegral<true, false, ui64>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToIntegral<false, true, ui64> : &ConvertToIntegral<false, false, ui64>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToDouble, TOptional<double>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToFloat<true, true, double> : &ConvertToFloat<true, false, double>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToFloat<false, true, double> : &ConvertToFloat<false, false, double>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToString, TOptional<char*>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToString<true, true, false> : &ConvertToString<true, false, false>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToString<false, true, false> : &ConvertToString<false, false, false>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToList, TListType<TNodeResource>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true> : &ConvertToListImpl<true, false>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true> : &ConvertToListImpl<false, false>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToInt64List, TListType<i64>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToIntegral<true, true, i64>> : &ConvertToListImpl<true, false, &ConvertToIntegral<true, false, i64>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToIntegral<false, true, i64>> : &ConvertToListImpl<false, false, &ConvertToIntegral<false, false, i64>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToUint64List, TListType<ui64>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToIntegral<true, true, ui64>> : &ConvertToListImpl<true, false, &ConvertToIntegral<true, false, ui64>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToIntegral<false, true, ui64>> : &ConvertToListImpl<false, false, &ConvertToIntegral<false, false, ui64>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToBoolList, TListType<bool>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToBool<true, true>> : &ConvertToListImpl<true, false, &ConvertToBool<true, false>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToBool<false, true>> : &ConvertToListImpl<false, false, &ConvertToBool<false, false>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToDoubleList, TListType<double>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToFloat<true, true, double>> : &ConvertToListImpl<true, false, &ConvertToFloat<true, false, double>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToFloat<false, true, double>> : &ConvertToListImpl<false, false, &ConvertToFloat<false, false, double>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToStringList, TListType<char*>(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToListImpl<true, true, &ConvertToString<true, true, false>> : &ConvertToListImpl<true, false, &ConvertToString<true, false, false>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToListImpl<false, true, &ConvertToString<false, true, false>> : &ConvertToListImpl<false, false, &ConvertToString<false, false, false>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToDict, TDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true> : &ConvertToDictImpl<true, false>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true> : &ConvertToDictImpl<false, false>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToInt64Dict, TInt64DictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToIntegral<true, true, i64>> : &ConvertToDictImpl<true, false, &ConvertToIntegral<true, false, i64>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToIntegral<false, true, i64>> : &ConvertToDictImpl<false, false, &ConvertToIntegral<false, false, i64>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToUint64Dict, TUint64DictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToIntegral<true, true, ui64>> : &ConvertToDictImpl<true, false, &ConvertToIntegral<true, false, ui64>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToIntegral<false, true, ui64>> : &ConvertToDictImpl<false, false, &ConvertToIntegral<false, false, ui64>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToBoolDict, TBoolDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToBool<true, true>> : &ConvertToDictImpl<true, false, &ConvertToBool<true, false>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToBool<false, true>> : &ConvertToDictImpl<false, false, &ConvertToBool<false, false>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToDoubleDict, TDoubleDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToFloat<true, true, double>> : &ConvertToDictImpl<true, false, &ConvertToFloat<true, false, double>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToFloat<false, true, double>> : &ConvertToDictImpl<false, false, &ConvertToFloat<false, false, double>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TConvertToStringDict, TStringDictType(TOptional<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &ConvertToDictImpl<true, true, &ConvertToString<true, true, false>> : &ConvertToDictImpl<true, false, &ConvertToString<true, false, false>>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ConvertToDictImpl<false, true, &ConvertToString<false, true, false>> : &ConvertToDictImpl<false, false, &ConvertToString<false, false, false>>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF(TAttributes, TDictType(TAutoMap<TNodeResource>)) {
+ const auto x = args[0];
+ if (IsNodeType<ENodeType::Attr>(x)) {
return x;
}
return valueBuilder->NewEmptyList();
}
-SIMPLE_UDF_OPTIONS(TContains, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &ContainsImpl<true, true> : &ContainsImpl<true, false>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &ContainsImpl<false, true> : &ContainsImpl<false, false>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TGetLength, TOptional<ui64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &GetLengthImpl<true, true> : &GetLengthImpl<true, false>)(args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &GetLengthImpl<false, true> : &GetLengthImpl<false, false>)(args[0], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookup, TOptional<TNodeResource>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- return LookupImpl(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupBool, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToBool<true, true>> : &LookupImpl<&ConvertToBool<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToBool<false, true>> : &LookupImpl<&ConvertToBool<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupInt64, TOptional<i64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<true, true, i64>> : &LookupImpl<&ConvertToIntegral<true, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<false, true, i64>> : &LookupImpl<&ConvertToIntegral<false, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupUint64, TOptional<ui64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<true, true, ui64>> : &LookupImpl<&ConvertToIntegral<true, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<false, true, ui64>> : &LookupImpl<&ConvertToIntegral<false, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupDouble, TOptional<double>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToFloat<true, true, double>> : &LookupImpl<&ConvertToFloat<true, false, double>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToFloat<false, true, double>> : &LookupImpl<&ConvertToFloat<false, false, double>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupString, TOptional<char*>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToString<true, true, false>> : &LookupImpl<&ConvertToString<true, false, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToString<false, true, false>> : &LookupImpl<&ConvertToString<false, false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupList, TOptional<TListType<TNodeResource>>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToListImpl<true, true>> : &LookupImpl<&ConvertToListImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToListImpl<false, true>> : &LookupImpl<&ConvertToListImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TLookupDict, TOptional<TDictType>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &LookupImpl<&ConvertToDictImpl<true, true>> : &LookupImpl<&ConvertToDictImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &LookupImpl<&ConvertToDictImpl<false, true>> : &LookupImpl<&ConvertToDictImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPath, TOptional<TNodeResource>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- return YPathImpl(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathBool, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToBool<true, true>> : &YPathImpl<&ConvertToBool<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToBool<false, true>> : &YPathImpl<&ConvertToBool<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathInt64, TOptional<i64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<true, true, i64>> : &YPathImpl<&ConvertToIntegral<true, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<false, true, i64>> : &YPathImpl<&ConvertToIntegral<false, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathUint64, TOptional<ui64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<true, true, ui64>> : &YPathImpl<&ConvertToIntegral<true, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<false, true, ui64>> : &YPathImpl<&ConvertToIntegral<false, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathDouble, TOptional<double>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToFloat<true, true, double>> : &YPathImpl<&ConvertToFloat<true, false, double>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToFloat<false, true, double>> : &YPathImpl<&ConvertToFloat<false, false, double>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathString, TOptional<char*>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToString<true, true, false>> : &YPathImpl<&ConvertToString<true, false, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToString<false, true, false>> : &YPathImpl<&ConvertToString<false, false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathList, TOptional<TListType<TNodeResource>>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToListImpl<true, true>> : &YPathImpl<&ConvertToListImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToListImpl<false, true>> : &YPathImpl<&ConvertToListImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF_OPTIONS(TYPathDict, TOptional<TDictType>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
- if (const auto options = ParseOptions(args[2]); options.Strict)
- return (options.AutoConvert ? &YPathImpl<&ConvertToDictImpl<true, true>> : &YPathImpl<&ConvertToDictImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &YPathImpl<&ConvertToDictImpl<false, true>> : &YPathImpl<&ConvertToDictImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
-}
-
-SIMPLE_UDF(TSerialize, TYson(TAutoMap<TNodeResource>)) {
- return valueBuilder->NewString(SerializeYsonDomToBinary(args[0]));
-}
-
-SIMPLE_UDF(TSerializeText, TYson(TAutoMap<TNodeResource>)) {
- return valueBuilder->NewString(SerializeYsonDomToText(args[0]));
-}
-
-SIMPLE_UDF(TSerializePretty, TYson(TAutoMap<TNodeResource>)) {
- return valueBuilder->NewString(SerializeYsonDomToPrettyText(args[0]));
-}
-
-constexpr char SkipMapEntity[] = "SkipMapEntity";
-constexpr char EncodeUtf8[] = "EncodeUtf8";
-
-SIMPLE_UDF_OPTIONS(TSerializeJson, TOptional<TJson>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>, TNamedArg<bool, SkipMapEntity>, TNamedArg<bool, EncodeUtf8>), builder.OptionalArgs(3U)) try {
- return valueBuilder->NewString(SerializeJsonDom(args[0], args[2].GetOrDefault(false), args[3].GetOrDefault(false)));
-} catch (const std::exception& e) {
- if (ParseOptions(args[1]).Strict) {
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
- }
- return {};
-}
-
-SIMPLE_UDF(TWithAttributes, TOptional<TNodeResource>(TAutoMap<TNodeResource>, TAutoMap<TNodeResource>)) {
+SIMPLE_UDF_OPTIONS(TContains, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &ContainsImpl<true, true> : &ContainsImpl<true, false>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &ContainsImpl<false, true> : &ContainsImpl<false, false>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TGetLength, TOptional<ui64>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &GetLengthImpl<true, true> : &GetLengthImpl<true, false>)(args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &GetLengthImpl<false, true> : &GetLengthImpl<false, false>)(args[0], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookup, TOptional<TNodeResource>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ return LookupImpl(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupBool, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToBool<true, true>> : &LookupImpl<&ConvertToBool<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToBool<false, true>> : &LookupImpl<&ConvertToBool<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupInt64, TOptional<i64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<true, true, i64>> : &LookupImpl<&ConvertToIntegral<true, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<false, true, i64>> : &LookupImpl<&ConvertToIntegral<false, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupUint64, TOptional<ui64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<true, true, ui64>> : &LookupImpl<&ConvertToIntegral<true, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToIntegral<false, true, ui64>> : &LookupImpl<&ConvertToIntegral<false, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupDouble, TOptional<double>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToFloat<true, true, double>> : &LookupImpl<&ConvertToFloat<true, false, double>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToFloat<false, true, double>> : &LookupImpl<&ConvertToFloat<false, false, double>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupString, TOptional<char*>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToString<true, true, false>> : &LookupImpl<&ConvertToString<true, false, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToString<false, true, false>> : &LookupImpl<&ConvertToString<false, false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupList, TOptional<TListType<TNodeResource>>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToListImpl<true, true>> : &LookupImpl<&ConvertToListImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToListImpl<false, true>> : &LookupImpl<&ConvertToListImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TLookupDict, TOptional<TDictType>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &LookupImpl<&ConvertToDictImpl<true, true>> : &LookupImpl<&ConvertToDictImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &LookupImpl<&ConvertToDictImpl<false, true>> : &LookupImpl<&ConvertToDictImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPath, TOptional<TNodeResource>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ return YPathImpl(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathBool, TOptional<bool>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToBool<true, true>> : &YPathImpl<&ConvertToBool<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToBool<false, true>> : &YPathImpl<&ConvertToBool<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathInt64, TOptional<i64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<true, true, i64>> : &YPathImpl<&ConvertToIntegral<true, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<false, true, i64>> : &YPathImpl<&ConvertToIntegral<false, false, i64>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathUint64, TOptional<ui64>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<true, true, ui64>> : &YPathImpl<&ConvertToIntegral<true, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToIntegral<false, true, ui64>> : &YPathImpl<&ConvertToIntegral<false, false, ui64>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathDouble, TOptional<double>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToFloat<true, true, double>> : &YPathImpl<&ConvertToFloat<true, false, double>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToFloat<false, true, double>> : &YPathImpl<&ConvertToFloat<false, false, double>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathString, TOptional<char*>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToString<true, true, false>> : &YPathImpl<&ConvertToString<true, false, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToString<false, true, false>> : &YPathImpl<&ConvertToString<false, false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathList, TOptional<TListType<TNodeResource>>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToListImpl<true, true>> : &YPathImpl<&ConvertToListImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToListImpl<false, true>> : &YPathImpl<&ConvertToListImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF_OPTIONS(TYPathDict, TOptional<TDictType>(TAutoMap<TNodeResource>, char*, TOptional<TOptionsResource>), builder.OptionalArgs(1)) {
+ if (const auto options = ParseOptions(args[2]); options.Strict)
+ return (options.AutoConvert ? &YPathImpl<&ConvertToDictImpl<true, true>> : &YPathImpl<&ConvertToDictImpl<true, false>>)(args[0], args[1], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &YPathImpl<&ConvertToDictImpl<false, true>> : &YPathImpl<&ConvertToDictImpl<false, false>>)(args[0], args[1], valueBuilder, Pos_);
+}
+
+SIMPLE_UDF(TSerialize, TYson(TAutoMap<TNodeResource>)) {
+ return valueBuilder->NewString(SerializeYsonDomToBinary(args[0]));
+}
+
+SIMPLE_UDF(TSerializeText, TYson(TAutoMap<TNodeResource>)) {
+ return valueBuilder->NewString(SerializeYsonDomToText(args[0]));
+}
+
+SIMPLE_UDF(TSerializePretty, TYson(TAutoMap<TNodeResource>)) {
+ return valueBuilder->NewString(SerializeYsonDomToPrettyText(args[0]));
+}
+
+constexpr char SkipMapEntity[] = "SkipMapEntity";
+constexpr char EncodeUtf8[] = "EncodeUtf8";
+
+SIMPLE_UDF_OPTIONS(TSerializeJson, TOptional<TJson>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>, TNamedArg<bool, SkipMapEntity>, TNamedArg<bool, EncodeUtf8>), builder.OptionalArgs(3U)) try {
+ return valueBuilder->NewString(SerializeJsonDom(args[0], args[2].GetOrDefault(false), args[3].GetOrDefault(false)));
+} catch (const std::exception& e) {
+ if (ParseOptions(args[1]).Strict) {
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
+ }
+ return {};
+}
+
+SIMPLE_UDF(TWithAttributes, TOptional<TNodeResource>(TAutoMap<TNodeResource>, TAutoMap<TNodeResource>)) {
Y_UNUSED(valueBuilder);
auto x = args[0];
auto y = args[1];
- if (!IsNodeType<ENodeType::Dict>(y)) {
- return {};
- }
-
+ if (!IsNodeType<ENodeType::Dict>(y)) {
+ return {};
+ }
+
if (y.IsEmbedded()) {
return x;
}
@@ -696,356 +696,356 @@ SIMPLE_UDF(TWithAttributes, TOptional<TNodeResource>(TAutoMap<TNodeResource>, TA
return {};
}
- // clone dict as attrnode
- if (const auto resource = y.GetResource()) {
- return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(x), static_cast<const TPair*>(resource), y.GetDictLength())));
- } else {
- TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
- items.reserve(y.GetDictLength());
- const auto it = y.GetDictIterator();
- for (TUnboxedValue x, y; it.NextPair(x, y);) {
- items.emplace_back(std::move(x), std::move(y));
- }
-
- if (items.empty()) {
- return x;
- }
-
- return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(x), items.data(), items.size())));
+ // clone dict as attrnode
+ if (const auto resource = y.GetResource()) {
+ return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(x), static_cast<const TPair*>(resource), y.GetDictLength())));
+ } else {
+ TSmallVec<TPair, TStdAllocatorForUdf<TPair>> items;
+ items.reserve(y.GetDictLength());
+ const auto it = y.GetDictIterator();
+ for (TUnboxedValue x, y; it.NextPair(x, y);) {
+ items.emplace_back(std::move(x), std::move(y));
+ }
+
+ if (items.empty()) {
+ return x;
+ }
+
+ return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(x), items.data(), items.size())));
}
}
-template<ENodeType Type>
-TUnboxedValuePod IsTypeImpl(TUnboxedValuePod y) {
- if (IsNodeType<ENodeType::Attr>(y)) {
- y = y.GetVariantItem().Release();
+template<ENodeType Type>
+TUnboxedValuePod IsTypeImpl(TUnboxedValuePod y) {
+ if (IsNodeType<ENodeType::Attr>(y)) {
+ y = y.GetVariantItem().Release();
}
- return TUnboxedValuePod(IsNodeType<Type>(y));
-}
-
-SIMPLE_UDF(TIsString, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::String>(*args);
-}
-
-SIMPLE_UDF(TIsInt64, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Int64>(*args);
-}
-
-SIMPLE_UDF(TIsUint64, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Uint64>(*args);
-}
-
-SIMPLE_UDF(TIsBool, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Bool>(*args);
-}
-
-SIMPLE_UDF(TIsDouble, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Double>(*args);
-}
-
-SIMPLE_UDF(TIsList, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::List>(*args);
-}
-
-SIMPLE_UDF(TIsDict, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Dict>(*args);
-}
-
-SIMPLE_UDF(TIsEntity, bool(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return IsTypeImpl<ENodeType::Entity>(*args);
-}
-
-SIMPLE_UDF(TEquals, bool(TAutoMap<TNodeResource>, TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(EquateDoms(args[0], args[1]));
-}
-
-SIMPLE_UDF(TGetHash, ui64(TAutoMap<TNodeResource>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(HashDom(args[0]));
-}
-
-namespace {
-
-class TBase: public TBoxedValue {
-public:
- typedef bool TTypeAwareMarker;
-
- TBase(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
- : Pos_(pos), TypeHelper_(typeHelper), Shape_(shape)
- {}
-
-protected:
- template<bool MoreTypesAllowed>
- static const TType* CheckType(const ITypeInfoHelper::TPtr typeHelper, const TType* shape) {
- switch (const auto kind = typeHelper->GetTypeKind(shape)) {
- case ETypeKind::Null:
- case ETypeKind::EmptyList:
- case ETypeKind::EmptyDict:
- return MoreTypesAllowed ? nullptr : shape;
- case ETypeKind::Data:
- switch (TDataTypeInspector(*typeHelper, shape).GetTypeId()) {
- case TDataType<char*>::Id:
- case TDataType<TUtf8>::Id:
- case TDataType<bool>::Id:
- case TDataType<i8>::Id:
- case TDataType<i16>::Id:
- case TDataType<i32>::Id:
- case TDataType<i64>::Id:
- case TDataType<ui8>::Id:
- case TDataType<ui16>::Id:
- case TDataType<ui32>::Id:
- case TDataType<ui64>::Id:
- case TDataType<float>::Id:
- case TDataType<double>::Id:
- case TDataType<TYson>::Id:
- case TDataType<TJson>::Id:
- return nullptr;
- default:
- return shape;
- }
- case ETypeKind::Optional:
- return CheckType<MoreTypesAllowed>(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType());
- case ETypeKind::List:
- return CheckType<MoreTypesAllowed>(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType());
- case ETypeKind::Dict: {
- const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
- if (const auto keyType = dictTypeInspector.GetKeyType(); ETypeKind::Data == typeHelper->GetTypeKind(keyType))
- if (const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId(); keyId == TDataType<char*>::Id || keyId == TDataType<TUtf8>::Id)
- return CheckType<MoreTypesAllowed>(typeHelper, dictTypeInspector.GetValueType());
- return shape;
- }
- case ETypeKind::Tuple:
- if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) do
- if (const auto bad = CheckType<MoreTypesAllowed>(typeHelper, tupleTypeInspector.GetElementType(--count)))
- return bad;
- while (count);
- return nullptr;
- case ETypeKind::Struct:
- if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); auto count = structTypeInspector.GetMembersCount()) do
- if (const auto bad = CheckType<MoreTypesAllowed>(typeHelper, structTypeInspector.GetMemberType(--count)))
- return bad;
- while (count);
- return nullptr;
- case ETypeKind::Variant:
- if constexpr (MoreTypesAllowed)
- return CheckType<MoreTypesAllowed>(typeHelper, TVariantTypeInspector(*typeHelper, shape).GetUnderlyingType());
- else
- return shape;
- case ETypeKind::Resource:
- if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
- return nullptr;
+ return TUnboxedValuePod(IsNodeType<Type>(y));
+}
+
+SIMPLE_UDF(TIsString, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::String>(*args);
+}
+
+SIMPLE_UDF(TIsInt64, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Int64>(*args);
+}
+
+SIMPLE_UDF(TIsUint64, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Uint64>(*args);
+}
+
+SIMPLE_UDF(TIsBool, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Bool>(*args);
+}
+
+SIMPLE_UDF(TIsDouble, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Double>(*args);
+}
+
+SIMPLE_UDF(TIsList, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::List>(*args);
+}
+
+SIMPLE_UDF(TIsDict, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Dict>(*args);
+}
+
+SIMPLE_UDF(TIsEntity, bool(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return IsTypeImpl<ENodeType::Entity>(*args);
+}
+
+SIMPLE_UDF(TEquals, bool(TAutoMap<TNodeResource>, TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return TUnboxedValuePod(EquateDoms(args[0], args[1]));
+}
+
+SIMPLE_UDF(TGetHash, ui64(TAutoMap<TNodeResource>)) {
+ Y_UNUSED(valueBuilder);
+ return TUnboxedValuePod(HashDom(args[0]));
+}
+
+namespace {
+
+class TBase: public TBoxedValue {
+public:
+ typedef bool TTypeAwareMarker;
+
+ TBase(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
+ : Pos_(pos), TypeHelper_(typeHelper), Shape_(shape)
+ {}
+
+protected:
+ template<bool MoreTypesAllowed>
+ static const TType* CheckType(const ITypeInfoHelper::TPtr typeHelper, const TType* shape) {
+ switch (const auto kind = typeHelper->GetTypeKind(shape)) {
+ case ETypeKind::Null:
+ case ETypeKind::EmptyList:
+ case ETypeKind::EmptyDict:
+ return MoreTypesAllowed ? nullptr : shape;
+ case ETypeKind::Data:
+ switch (TDataTypeInspector(*typeHelper, shape).GetTypeId()) {
+ case TDataType<char*>::Id:
+ case TDataType<TUtf8>::Id:
+ case TDataType<bool>::Id:
+ case TDataType<i8>::Id:
+ case TDataType<i16>::Id:
+ case TDataType<i32>::Id:
+ case TDataType<i64>::Id:
+ case TDataType<ui8>::Id:
+ case TDataType<ui16>::Id:
+ case TDataType<ui32>::Id:
+ case TDataType<ui64>::Id:
+ case TDataType<float>::Id:
+ case TDataType<double>::Id:
+ case TDataType<TYson>::Id:
+ case TDataType<TJson>::Id:
+ return nullptr;
+ default:
+ return shape;
+ }
+ case ETypeKind::Optional:
+ return CheckType<MoreTypesAllowed>(typeHelper, TOptionalTypeInspector(*typeHelper, shape).GetItemType());
+ case ETypeKind::List:
+ return CheckType<MoreTypesAllowed>(typeHelper, TListTypeInspector(*typeHelper, shape).GetItemType());
+ case ETypeKind::Dict: {
+ const auto dictTypeInspector = TDictTypeInspector(*typeHelper, shape);
+ if (const auto keyType = dictTypeInspector.GetKeyType(); ETypeKind::Data == typeHelper->GetTypeKind(keyType))
+ if (const auto keyId = TDataTypeInspector(*typeHelper, keyType).GetTypeId(); keyId == TDataType<char*>::Id || keyId == TDataType<TUtf8>::Id)
+ return CheckType<MoreTypesAllowed>(typeHelper, dictTypeInspector.GetValueType());
+ return shape;
+ }
+ case ETypeKind::Tuple:
+ if (const auto tupleTypeInspector = TTupleTypeInspector(*typeHelper, shape); auto count = tupleTypeInspector.GetElementsCount()) do
+ if (const auto bad = CheckType<MoreTypesAllowed>(typeHelper, tupleTypeInspector.GetElementType(--count)))
+ return bad;
+ while (count);
+ return nullptr;
+ case ETypeKind::Struct:
+ if (const auto structTypeInspector = TStructTypeInspector(*typeHelper, shape); auto count = structTypeInspector.GetMembersCount()) do
+ if (const auto bad = CheckType<MoreTypesAllowed>(typeHelper, structTypeInspector.GetMemberType(--count)))
+ return bad;
+ while (count);
+ return nullptr;
+ case ETypeKind::Variant:
+ if constexpr (MoreTypesAllowed)
+ return CheckType<MoreTypesAllowed>(typeHelper, TVariantTypeInspector(*typeHelper, shape).GetUnderlyingType());
+ else
+ return shape;
+ case ETypeKind::Resource:
+ if (const auto inspector = TResourceTypeInspector(*typeHelper, shape); TStringBuf(inspector.GetTag()) == NodeResourceName)
+ return nullptr;
[[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- default:
- return shape;
- }
- }
-
- const TSourcePosition Pos_;
- const ITypeInfoHelper::TPtr TypeHelper_;
- const TType *const Shape_;
-};
-
-class TFrom: public TBase {
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
- return MakeDom(TypeHelper_, Shape_, *args, valueBuilder);
- }
-public:
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("From");
- return name;
- }
-
- TFrom(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
- : TBase(pos, typeHelper, shape)
- {}
-
- static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
- if (Name() == name) {
- if (!userType) {
- builder.SetError("Missing user type.");
- return true;
- }
-
- builder.UserType(userType);
- const auto typeHelper = builder.TypeInfoHelper();
- const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
- if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
- builder.SetError("Invalid user type.");
- return true;
- }
-
- const auto argsTypeTuple = userTypeInspector.GetElementType(0);
- const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
- if (!argsTypeInspector) {
- builder.SetError("Invalid user type - expected tuple.");
- return true;
- }
-
- if (argsTypeInspector.GetElementsCount() != 1) {
- builder.SetError("Expected single argument.");
- return true;
- }
-
- const auto inputType = argsTypeInspector.GetElementType(0);
- if (const auto badType = CheckType<true>(typeHelper, inputType)) {
- ::TStringBuilder sb;
- sb << "Impossible to create DOM from incompatible with Yson type: ";
- TTypePrinter(*typeHelper, inputType).Out(sb.Out);
- if (badType != inputType) {
- sb << " Incompatible type: ";
- TTypePrinter(*typeHelper, badType).Out(sb.Out);
- }
- builder.SetError(sb);
- return true;
- }
-
- builder.Args()->Add(inputType).Done().Returns(builder.Resource(NodeResourceName));
-
- if (!typesOnly) {
- builder.Implementation(new TFrom(builder.GetSourcePosition(), typeHelper, inputType));
- }
- return true;
- } else {
- return false;
- }
- }
-};
-
-class TConvert: public TBase {
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
- if (const auto options = ParseOptions(args[1]); options.Strict)
- return (options.AutoConvert ? &PeelDom<true, true> : &PeelDom<true, false>)(TypeHelper_, Shape_, args[0], valueBuilder, Pos_);
- else
- return (options.AutoConvert ? &PeelDom<false, true> : &PeelDom<false, false>)(TypeHelper_, Shape_, args[0], valueBuilder, Pos_);
- }
-
-public:
- TConvert(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
- : TBase(pos, typeHelper, shape)
- {}
-
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("ConvertTo");
- return name;
- }
-
-
- static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
- if (Name() == name) {
- const auto optionsType = builder.Optional()->Item(builder.Resource(OptionsResourceName)).Build();
- builder.OptionalArgs(1);
-
- if (!userType) {
- builder.SetError("Missing user type.");
- return true;
- }
-
- builder.UserType(userType);
- const auto typeHelper = builder.TypeInfoHelper();
- const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
- if (!userTypeInspector || userTypeInspector.GetElementsCount() < 3) {
- builder.SetError("Invalid user type.");
- return true;
- }
-
- const auto argsTypeTuple = userTypeInspector.GetElementType(0);
- const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
- if (!argsTypeInspector) {
- builder.SetError("Invalid user type - expected tuple.");
- return true;
- }
-
- if (const auto argsCount = argsTypeInspector.GetElementsCount(); argsCount < 1 || argsCount > 2) {
- ::TStringBuilder sb;
- sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
- builder.SetError(sb);
- return true;
- }
-
- const auto resultType = userTypeInspector.GetElementType(2);
- if (const auto badType = CheckType<false>(typeHelper, resultType)) {
- ::TStringBuilder sb;
- sb << "Impossible to convert DOM to incompatible with Yson type: ";
- TTypePrinter(*typeHelper, resultType).Out(sb.Out);
- if (badType != resultType) {
- sb << " Incompatible type: ";
- TTypePrinter(*typeHelper, badType).Out(sb.Out);
- }
- builder.SetError(sb);
- return true;
- }
-
+ default:
+ return shape;
+ }
+ }
+
+ const TSourcePosition Pos_;
+ const ITypeInfoHelper::TPtr TypeHelper_;
+ const TType *const Shape_;
+};
+
+class TFrom: public TBase {
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
+ return MakeDom(TypeHelper_, Shape_, *args, valueBuilder);
+ }
+public:
+ static const TStringRef& Name() {
+ static auto name = TStringRef::Of("From");
+ return name;
+ }
+
+ TFrom(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
+ : TBase(pos, typeHelper, shape)
+ {}
+
+ static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
+ if (Name() == name) {
+ if (!userType) {
+ builder.SetError("Missing user type.");
+ return true;
+ }
+
+ builder.UserType(userType);
+ const auto typeHelper = builder.TypeInfoHelper();
+ const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
+ builder.SetError("Invalid user type.");
+ return true;
+ }
+
+ const auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!argsTypeInspector) {
+ builder.SetError("Invalid user type - expected tuple.");
+ return true;
+ }
+
+ if (argsTypeInspector.GetElementsCount() != 1) {
+ builder.SetError("Expected single argument.");
+ return true;
+ }
+
+ const auto inputType = argsTypeInspector.GetElementType(0);
+ if (const auto badType = CheckType<true>(typeHelper, inputType)) {
+ ::TStringBuilder sb;
+ sb << "Impossible to create DOM from incompatible with Yson type: ";
+ TTypePrinter(*typeHelper, inputType).Out(sb.Out);
+ if (badType != inputType) {
+ sb << " Incompatible type: ";
+ TTypePrinter(*typeHelper, badType).Out(sb.Out);
+ }
+ builder.SetError(sb);
+ return true;
+ }
+
+ builder.Args()->Add(inputType).Done().Returns(builder.Resource(NodeResourceName));
+
+ if (!typesOnly) {
+ builder.Implementation(new TFrom(builder.GetSourcePosition(), typeHelper, inputType));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+class TConvert: public TBase {
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
+ if (const auto options = ParseOptions(args[1]); options.Strict)
+ return (options.AutoConvert ? &PeelDom<true, true> : &PeelDom<true, false>)(TypeHelper_, Shape_, args[0], valueBuilder, Pos_);
+ else
+ return (options.AutoConvert ? &PeelDom<false, true> : &PeelDom<false, false>)(TypeHelper_, Shape_, args[0], valueBuilder, Pos_);
+ }
+
+public:
+ TConvert(TSourcePosition pos, const ITypeInfoHelper::TPtr typeHelper, const TType* shape)
+ : TBase(pos, typeHelper, shape)
+ {}
+
+ static const TStringRef& Name() {
+ static auto name = TStringRef::Of("ConvertTo");
+ return name;
+ }
+
+
+ static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
+ if (Name() == name) {
+ const auto optionsType = builder.Optional()->Item(builder.Resource(OptionsResourceName)).Build();
+ builder.OptionalArgs(1);
+
+ if (!userType) {
+ builder.SetError("Missing user type.");
+ return true;
+ }
+
+ builder.UserType(userType);
+ const auto typeHelper = builder.TypeInfoHelper();
+ const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 3) {
+ builder.SetError("Invalid user type.");
+ return true;
+ }
+
+ const auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!argsTypeInspector) {
+ builder.SetError("Invalid user type - expected tuple.");
+ return true;
+ }
+
+ if (const auto argsCount = argsTypeInspector.GetElementsCount(); argsCount < 1 || argsCount > 2) {
+ ::TStringBuilder sb;
+ sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
+ builder.SetError(sb);
+ return true;
+ }
+
+ const auto resultType = userTypeInspector.GetElementType(2);
+ if (const auto badType = CheckType<false>(typeHelper, resultType)) {
+ ::TStringBuilder sb;
+ sb << "Impossible to convert DOM to incompatible with Yson type: ";
+ TTypePrinter(*typeHelper, resultType).Out(sb.Out);
+ if (badType != resultType) {
+ sb << " Incompatible type: ";
+ TTypePrinter(*typeHelper, badType).Out(sb.Out);
+ }
+ builder.SetError(sb);
+ return true;
+ }
+
builder.Args()->Add(builder.Resource(NodeResourceName)).Flags(ICallablePayload::TArgumentFlags::AutoMap).Add(optionsType);
- builder.Returns(resultType);
-
- if (!typesOnly) {
- builder.Implementation(new TConvert(builder.GetSourcePosition(), typeHelper, resultType));
- }
- return true;
- } else {
- return false;
- }
- }
-};
-
-template<typename TYJson, bool DecodeUtf8 = false>
-class TParse: public TBoxedValue {
-public:
- typedef bool TTypeAwareMarker;
-private:
- const TSourcePosition Pos_;
- const bool StrictType_;
-
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final;
-public:
- TParse(TSourcePosition pos, bool strictType)
- : Pos_(pos), StrictType_(strictType)
- {}
-
- static const TStringRef& Name();
-
- static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
- if (Name() == name) {
- auto typeId = TDataType<TYJson>::Id;
- if (userType) {
- const auto typeHelper = builder.TypeInfoHelper();
- const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
- if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
- builder.SetError("Missing or invalid user type.");
- return true;
- }
-
- const auto argsTypeTuple = userTypeInspector.GetElementType(0);
- const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
- if (!argsTypeInspector) {
- builder.SetError("Invalid user type - expected tuple.");
- return true;
- }
-
- const auto argsCount = argsTypeInspector.GetElementsCount();
- if (argsCount < 1 || argsCount > 2) {
- ::TStringBuilder sb;
- sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
- builder.SetError(sb);
- return true;
- }
-
- const auto inputType = argsTypeInspector.GetElementType(0);
- auto dataType = inputType;
- if (const auto optInspector = TOptionalTypeInspector(*typeHelper, inputType)) {
- dataType = optInspector.GetItemType();
- }
-
+ builder.Returns(resultType);
+
+ if (!typesOnly) {
+ builder.Implementation(new TConvert(builder.GetSourcePosition(), typeHelper, resultType));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+template<typename TYJson, bool DecodeUtf8 = false>
+class TParse: public TBoxedValue {
+public:
+ typedef bool TTypeAwareMarker;
+private:
+ const TSourcePosition Pos_;
+ const bool StrictType_;
+
+ TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final;
+public:
+ TParse(TSourcePosition pos, bool strictType)
+ : Pos_(pos), StrictType_(strictType)
+ {}
+
+ static const TStringRef& Name();
+
+ static bool DeclareSignature(const TStringRef& name, TType* userType, IFunctionTypeInfoBuilder& builder, bool typesOnly) {
+ if (Name() == name) {
+ auto typeId = TDataType<TYJson>::Id;
+ if (userType) {
+ const auto typeHelper = builder.TypeInfoHelper();
+ const auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
+ builder.SetError("Missing or invalid user type.");
+ return true;
+ }
+
+ const auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ const auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!argsTypeInspector) {
+ builder.SetError("Invalid user type - expected tuple.");
+ return true;
+ }
+
+ const auto argsCount = argsTypeInspector.GetElementsCount();
+ if (argsCount < 1 || argsCount > 2) {
+ ::TStringBuilder sb;
+ sb << "Invalid user type - expected one or two arguments, got: " << argsCount;
+ builder.SetError(sb);
+ return true;
+ }
+
+ const auto inputType = argsTypeInspector.GetElementType(0);
+ auto dataType = inputType;
+ if (const auto optInspector = TOptionalTypeInspector(*typeHelper, inputType)) {
+ dataType = optInspector.GetItemType();
+ }
+
if (const auto resInspector = TResourceTypeInspector(*typeHelper, dataType)) {
typeId = TDataType<TYJson>::Id;
} else {
@@ -1053,107 +1053,107 @@ public:
typeId = dataInspector.GetTypeId();
}
- builder.UserType(userType);
- }
-
- const auto optionsType = builder.Optional()->Item(builder.Resource(OptionsResourceName)).Build();
- builder.OptionalArgs(1);
-
- switch (typeId) {
- case TDataType<TYJson>::Id:
- builder.Args()->Add<TAutoMap<TYJson>>().Add(optionsType).Done().Returns(builder.Resource(NodeResourceName));
- break;
- case TDataType<TUtf8>::Id:
- builder.Args()->Add<TAutoMap<TUtf8>>().Add(optionsType).Done().Returns(builder.Optional()->Item(builder.Resource(NodeResourceName)).Build());
- break;
- default:
- builder.Args()->Add<TAutoMap<char*>>().Add(optionsType).Done().Returns(builder.Optional()->Item(builder.Resource(NodeResourceName)).Build());
- break;
- }
-
- if (!typesOnly) {
- builder.Implementation(new TParse(builder.GetSourcePosition(), TDataType<TYJson>::Id == typeId));
- }
- return true;
- } else {
- return false;
- }
- }
-};
-
-template<>
-TUnboxedValue TParse<TYson, false>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
- return TryParseYsonDom(args[0].AsStringRef(), valueBuilder);
-} catch (const std::exception& e) {
- if (StrictType_ || ParseOptions(args[1]).Strict) {
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
- }
- return TUnboxedValuePod();
-}
-
-template<>
-TUnboxedValue TParse<TJson, false>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
- return TryParseJsonDom(args[0].AsStringRef(), valueBuilder);
-} catch (const std::exception& e) {
- if (StrictType_ || ParseOptions(args[1]).Strict) {
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
- }
- return TUnboxedValuePod();
-}
-
-template<>
-TUnboxedValue TParse<TJson, true>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
- return TryParseJsonDom(args[0].AsStringRef(), valueBuilder, true);
-} catch (const std::exception& e) {
- if (StrictType_ || ParseOptions(args[1]).Strict) {
- UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
- }
- return TUnboxedValuePod();
-}
-
-template<>
-const TStringRef& TParse<TYson, false>::Name() {
- static auto yson = TStringRef::Of("Parse");
- return yson;
-}
-
-template<>
-const TStringRef& TParse<TJson, false>::Name() {
- static auto yson = TStringRef::Of("ParseJson");
- return yson;
-}
-
-template<>
-const TStringRef& TParse<TJson, true>::Name() {
- static auto yson = TStringRef::Of("ParseJsonDecodeUtf8");
- return yson;
-}
-
-}
-
+ builder.UserType(userType);
+ }
+
+ const auto optionsType = builder.Optional()->Item(builder.Resource(OptionsResourceName)).Build();
+ builder.OptionalArgs(1);
+
+ switch (typeId) {
+ case TDataType<TYJson>::Id:
+ builder.Args()->Add<TAutoMap<TYJson>>().Add(optionsType).Done().Returns(builder.Resource(NodeResourceName));
+ break;
+ case TDataType<TUtf8>::Id:
+ builder.Args()->Add<TAutoMap<TUtf8>>().Add(optionsType).Done().Returns(builder.Optional()->Item(builder.Resource(NodeResourceName)).Build());
+ break;
+ default:
+ builder.Args()->Add<TAutoMap<char*>>().Add(optionsType).Done().Returns(builder.Optional()->Item(builder.Resource(NodeResourceName)).Build());
+ break;
+ }
+
+ if (!typesOnly) {
+ builder.Implementation(new TParse(builder.GetSourcePosition(), TDataType<TYJson>::Id == typeId));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+template<>
+TUnboxedValue TParse<TYson, false>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
+ return TryParseYsonDom(args[0].AsStringRef(), valueBuilder);
+} catch (const std::exception& e) {
+ if (StrictType_ || ParseOptions(args[1]).Strict) {
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
+ }
+ return TUnboxedValuePod();
+}
+
+template<>
+TUnboxedValue TParse<TJson, false>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
+ return TryParseJsonDom(args[0].AsStringRef(), valueBuilder);
+} catch (const std::exception& e) {
+ if (StrictType_ || ParseOptions(args[1]).Strict) {
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
+ }
+ return TUnboxedValuePod();
+}
+
+template<>
+TUnboxedValue TParse<TJson, true>::Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const try {
+ return TryParseJsonDom(args[0].AsStringRef(), valueBuilder, true);
+} catch (const std::exception& e) {
+ if (StrictType_ || ParseOptions(args[1]).Strict) {
+ UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(Pos_) << " " << e.what()).data());
+ }
+ return TUnboxedValuePod();
+}
+
+template<>
+const TStringRef& TParse<TYson, false>::Name() {
+ static auto yson = TStringRef::Of("Parse");
+ return yson;
+}
+
+template<>
+const TStringRef& TParse<TJson, false>::Name() {
+ static auto yson = TStringRef::Of("ParseJson");
+ return yson;
+}
+
+template<>
+const TStringRef& TParse<TJson, true>::Name() {
+ static auto yson = TStringRef::Of("ParseJsonDecodeUtf8");
+ return yson;
+}
+
+}
+
SIMPLE_MODULE(TYson2Module,
- TOptions,
- TParse<TYson>,
- TParse<TJson>,
- TParse<TJson, true>,
- TConvert,
+ TOptions,
+ TParse<TYson>,
+ TParse<TJson>,
+ TParse<TJson, true>,
+ TConvert,
TConvertToBool,
TConvertToInt64,
TConvertToUint64,
TConvertToDouble,
TConvertToString,
TConvertToList,
- TConvertToBoolList,
- TConvertToInt64List,
- TConvertToUint64List,
- TConvertToDoubleList,
- TConvertToStringList,
+ TConvertToBoolList,
+ TConvertToInt64List,
+ TConvertToUint64List,
+ TConvertToDoubleList,
+ TConvertToStringList,
TConvertToDict,
- TConvertToBoolDict,
- TConvertToInt64Dict,
- TConvertToUint64Dict,
- TConvertToDoubleDict,
- TConvertToStringDict,
+ TConvertToBoolDict,
+ TConvertToInt64Dict,
+ TConvertToUint64Dict,
+ TConvertToDoubleDict,
+ TConvertToStringDict,
TAttributes,
TContains,
TLookup,
@@ -1164,31 +1164,31 @@ SIMPLE_MODULE(TYson2Module,
TLookupString,
TLookupList,
TLookupDict,
- TYPath,
- TYPathBool,
- TYPathInt64,
- TYPathUint64,
- TYPathDouble,
- TYPathString,
- TYPathList,
- TYPathDict,
+ TYPath,
+ TYPathBool,
+ TYPathInt64,
+ TYPathUint64,
+ TYPathDouble,
+ TYPathString,
+ TYPathList,
+ TYPathDict,
TSerialize,
TSerializeText,
TSerializePretty,
- TSerializeJson,
+ TSerializeJson,
TWithAttributes,
- TIsString,
- TIsInt64,
- TIsUint64,
- TIsBool,
- TIsDouble,
- TIsList,
- TIsDict,
+ TIsString,
+ TIsInt64,
+ TIsUint64,
+ TIsBool,
+ TIsDouble,
+ TIsList,
+ TIsDict,
TIsEntity,
- TFrom,
- TGetLength,
- TEquals,
- TGetHash
+ TFrom,
+ TGetLength,
+ TEquals,
+ TGetHash
);
REGISTER_MODULES(TYson2Module);
diff --git a/ydb/library/yql/udfs/logs/dsv/dsv_udf.cpp b/ydb/library/yql/udfs/logs/dsv/dsv_udf.cpp
index 4f0a525c6c..b74bf80b18 100644
--- a/ydb/library/yql/udfs/logs/dsv/dsv_udf.cpp
+++ b/ydb/library/yql/udfs/logs/dsv/dsv_udf.cpp
@@ -25,24 +25,24 @@ struct TResultIndexes
ui32 key;
ui32 subkey;
ui32 dict;
- static constexpr ui32 FieldsCount = 3U;
+ static constexpr ui32 FieldsCount = 3U;
};
-void ParseDsv(const TUnboxedValuePod& value,
- const std::string_view& separator,
+void ParseDsv(const TUnboxedValuePod& value,
+ const std::string_view& separator,
const IValueBuilder* valueBuilder,
IDictValueBuilder* builder) {
- const std::string_view input(value.AsStringRef());
- const std::vector<std::string_view> parts = StringSplitter(input).SplitByString(separator);
- for (const auto& part : parts) {
- const auto pos = part.find('=');
- if (std::string_view::npos != pos) {
- const auto from = std::distance(input.begin(), part.begin());
- builder->Add(
- valueBuilder->SubString(value, from, pos),
- valueBuilder->SubString(value, from + pos + 1U, part.length() - pos - 1U)
- );
- }
+ const std::string_view input(value.AsStringRef());
+ const std::vector<std::string_view> parts = StringSplitter(input).SplitByString(separator);
+ for (const auto& part : parts) {
+ const auto pos = part.find('=');
+ if (std::string_view::npos != pos) {
+ const auto from = std::distance(input.begin(), part.begin());
+ builder->Add(
+ valueBuilder->SubString(value, from, pos),
+ valueBuilder->SubString(value, from + pos + 1U, part.length() - pos - 1U)
+ );
+ }
}
}
@@ -57,63 +57,63 @@ public:
, KsvIndexes_(ksvIndexes)
{
}
- private:
+ private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try
+ const TUnboxedValuePod* args) const final try
{
- const auto optRunConfig = args[0];
- TUnboxedValue separator;
- if (optRunConfig && !optRunConfig.AsStringRef().Empty()) {
- separator = optRunConfig;
- } else {
- separator = valueBuilder->NewString("\t");
- }
-
- return TUnboxedValuePod(new TDsvReadRecord(separator, ResultIndexes_, KsvIndexes_));
+ const auto optRunConfig = args[0];
+ TUnboxedValue separator;
+ if (optRunConfig && !optRunConfig.AsStringRef().Empty()) {
+ separator = optRunConfig;
+ } else {
+ separator = valueBuilder->NewString("\t");
+ }
+
+ return TUnboxedValuePod(new TDsvReadRecord(separator, ResultIndexes_, KsvIndexes_));
+ }
+ catch (const std::exception& e) {
+ UdfTerminate(e.what());
}
- catch (const std::exception& e) {
- UdfTerminate(e.what());
- }
const TResultIndexes ResultIndexes_;
const TKsvIndexes KsvIndexes_;
};
- explicit TDsvReadRecord(const TUnboxedValue& separator,
+ explicit TDsvReadRecord(const TUnboxedValue& separator,
const TResultIndexes& fieldIndexes,
const TKsvIndexes& ksvIndexes)
- : Separator_(std::move(separator))
+ : Separator_(std::move(separator))
, ResultIndexes_(fieldIndexes)
, KsvIndexes_(ksvIndexes)
{
}
-private:
+private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try
+ const TUnboxedValuePod* args) const final try
{
- auto keyData = args[0].GetElement(KsvIndexes_.key);
- auto subkeyData = args[0].GetElement(KsvIndexes_.subkey);
- auto valueData = args[0].GetElement(KsvIndexes_.value);
+ auto keyData = args[0].GetElement(KsvIndexes_.key);
+ auto subkeyData = args[0].GetElement(KsvIndexes_.subkey);
+ auto valueData = args[0].GetElement(KsvIndexes_.value);
- auto dict = valueBuilder->NewDict(ResultIndexes_.DictType, 0);
+ auto dict = valueBuilder->NewDict(ResultIndexes_.DictType, 0);
- ParseDsv(valueData, Separator_.AsStringRef(), valueBuilder, dict.Get());
+ ParseDsv(valueData, Separator_.AsStringRef(), valueBuilder, dict.Get());
- TUnboxedValue* items = nullptr;
- const auto result = valueBuilder->NewArray(ResultIndexes_.FieldsCount, items);
- items[ResultIndexes_.key] = keyData;
- items[ResultIndexes_.subkey] = subkeyData;
- items[ResultIndexes_.dict] = dict->Build();
- return result;
+ TUnboxedValue* items = nullptr;
+ const auto result = valueBuilder->NewArray(ResultIndexes_.FieldsCount, items);
+ items[ResultIndexes_.key] = keyData;
+ items[ResultIndexes_.subkey] = subkeyData;
+ items[ResultIndexes_.dict] = dict->Build();
+ return result;
+ }
+ catch (const std::exception& e) {
+ UdfTerminate(e.what());
}
- catch (const std::exception& e) {
- UdfTerminate(e.what());
- }
-
- const TUnboxedValue Separator_;
+
+ const TUnboxedValue Separator_;
const TResultIndexes ResultIndexes_;
const TKsvIndexes KsvIndexes_;
};
@@ -124,23 +124,23 @@ public:
explicit TDsvParse(TType* dictType)
: DictType(dictType)
{}
-private:
+private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try
+ const TUnboxedValuePod* args) const final try
{
- const std::string_view separator = args[1] ?
- std::string_view(args[1].AsStringRef()):
- std::string_view("\t");
+ const std::string_view separator = args[1] ?
+ std::string_view(args[1].AsStringRef()):
+ std::string_view("\t");
- auto dict = valueBuilder->NewDict(DictType, 0);
- ParseDsv(args[0], separator, valueBuilder, dict.Get());
- return dict->Build();
+ auto dict = valueBuilder->NewDict(DictType, 0);
+ ParseDsv(args[0], separator, valueBuilder, dict.Get());
+ return dict->Build();
+ }
+ catch (const std::exception& e) {
+ UdfTerminate(e.what());
}
- catch (const std::exception& e) {
- UdfTerminate(e.what());
- }
-
+
const TType* DictType;
};
@@ -155,41 +155,41 @@ public:
, StructInspector(structInspector)
{}
-private:
+private:
TUnboxedValue Run(
const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const final try
+ const TUnboxedValuePod* args) const final try
{
- TVector<TString> result;
- if (const ui32 structSize = StructInspector->GetMembersCount()) {
- result.reserve(structSize);
- for (ui32 i = 0; i < structSize; ++i) {
- auto part = TString(StructInspector->GetMemberName(i));
- part += '=';
- const TUnboxedValue& member = args[0].GetElement(i);
- switch (TypeIds[i]) {
- TYPE_TO_STRING(i32)
- TYPE_TO_STRING(ui32)
- TYPE_TO_STRING(i64)
- TYPE_TO_STRING(ui64)
- TYPE_TO_STRING(ui8)
- TYPE_TO_STRING(bool)
- TYPE_TO_STRING(double)
- TYPE_TO_STRING(float)
- default:
- part += member.AsStringRef();
- break;
+ TVector<TString> result;
+ if (const ui32 structSize = StructInspector->GetMembersCount()) {
+ result.reserve(structSize);
+ for (ui32 i = 0; i < structSize; ++i) {
+ auto part = TString(StructInspector->GetMemberName(i));
+ part += '=';
+ const TUnboxedValue& member = args[0].GetElement(i);
+ switch (TypeIds[i]) {
+ TYPE_TO_STRING(i32)
+ TYPE_TO_STRING(ui32)
+ TYPE_TO_STRING(i64)
+ TYPE_TO_STRING(ui64)
+ TYPE_TO_STRING(ui8)
+ TYPE_TO_STRING(bool)
+ TYPE_TO_STRING(double)
+ TYPE_TO_STRING(float)
+ default:
+ part += member.AsStringRef();
+ break;
}
- result.emplace_back(std::move(part));
+ result.emplace_back(std::move(part));
}
}
- return valueBuilder->NewString(JoinStrings(result, "\t"));
+ return valueBuilder->NewString(JoinStrings(result, "\t"));
}
- catch (const std::exception& e) {
- UdfTerminate(e.what());
- }
-
+ catch (const std::exception& e) {
+ UdfTerminate(e.what());
+ }
+
const TVector<TDataTypeId> TypeIds;
THolder<TStructTypeInspector> StructInspector;
};
@@ -201,11 +201,11 @@ public:
return TStringRef::Of("Dsv");
}
- void CleanupOnTerminate() const final {}
+ void CleanupOnTerminate() const final {}
- void GetAllFunctions(IFunctionsSink& sink) const final {
- sink.Add(TStringRef::Of("ReadRecord"));
- sink.Add(TStringRef::Of("Parse"));
+ void GetAllFunctions(IFunctionsSink& sink) const final {
+ sink.Add(TStringRef::Of("ReadRecord"));
+ sink.Add(TStringRef::Of("Parse"));
sink.Add(TStringRef::Of("Serialize"))->SetTypeAwareness();
}
@@ -214,97 +214,97 @@ public:
TType* userType,
const TStringRef& typeConfig,
ui32 flags,
- IFunctionTypeInfoBuilder& builder) const final try
+ IFunctionTypeInfoBuilder& builder) const final try
{
- Y_UNUSED(typeConfig);
-
- bool typesOnly = (flags & TFlags::TypesOnly);
-
- if (TStringRef::Of("ReadRecord") == name) {
- TKsvIndexes ksvIndexes;
- auto recordType = builder.Struct(3U)->
- AddField<char*>("key", &ksvIndexes.key)
- .AddField<char*>("subkey", &ksvIndexes.subkey)
- .AddField<char*>("value", &ksvIndexes.value)
- .Build();
-
- TResultIndexes resultIndexes;
- resultIndexes.DictType = builder.Dict()->Key<char*>().Value<char*>().Build();
- const auto structType = builder.Struct(resultIndexes.FieldsCount)
- ->AddField<char*>("key", &resultIndexes.key)
- .AddField<char*>("subkey", &resultIndexes.subkey)
- .AddField("dict", resultIndexes.DictType, &resultIndexes.dict)
- .Build();
-
- builder.Returns(structType)
- .Args()->Add(recordType).Done()
- .RunConfig<TOptional<char*>>();
-
- if (!typesOnly) {
- builder.Implementation(new TDsvReadRecord::TFactory(
- resultIndexes, ksvIndexes));
- }
- } else if (TStringRef::Of("Parse") == name) {
- auto optionalStringType = builder.Optional()->Item<char*>().Build();
- auto dictType = builder.Dict()->Key<char*>().Value<char*>().Build();
-
- builder.Returns(dictType)
- .Args()->Add<char*>().Flags(ICallablePayload::TArgumentFlags::AutoMap).Add(optionalStringType).Done()
- .OptionalArgs(1);
-
- if (!typesOnly) {
- builder.Implementation(new TDsvParse(dictType));
- }
- } else if (TStringRef::Of("Serialize") == name) {
- auto typeHelper = builder.TypeInfoHelper();
- auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
- if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
- builder.SetError("Expected user type");
- return;
- }
- auto argsTypeTuple = userTypeInspector.GetElementType(0);
- auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
- if (!(argsTypeInspector && argsTypeInspector.GetElementsCount() == 1)) {
- builder.SetError("Only one argument is expected " + ToString(argsTypeInspector.GetElementsCount()));
- return;
- }
-
- TVector<TDataTypeId> typeIds;
- const auto structType = argsTypeInspector.GetElementType(0);
- THolder<TStructTypeInspector> structInspector(new TStructTypeInspector(*typeHelper, structType));
- if (structInspector) {
- ui32 memberCount = structInspector->GetMembersCount();
- typeIds.reserve(memberCount);
-
- if (memberCount) {
- for (ui32 i = 0; i < memberCount; ++i) {
- const TString memberName(structInspector->GetMemberName(i));
- const auto memberType = structInspector->GetMemberType(i);
- auto memberInspector = TDataTypeInspector(*typeHelper, memberType);
- if (!memberInspector) {
- builder.SetError("Only DataType members are supported at the moment, failed at " + memberName);
- return;
- }
- typeIds.push_back(memberInspector.GetTypeId());
- }
+ Y_UNUSED(typeConfig);
+
+ bool typesOnly = (flags & TFlags::TypesOnly);
+
+ if (TStringRef::Of("ReadRecord") == name) {
+ TKsvIndexes ksvIndexes;
+ auto recordType = builder.Struct(3U)->
+ AddField<char*>("key", &ksvIndexes.key)
+ .AddField<char*>("subkey", &ksvIndexes.subkey)
+ .AddField<char*>("value", &ksvIndexes.value)
+ .Build();
+
+ TResultIndexes resultIndexes;
+ resultIndexes.DictType = builder.Dict()->Key<char*>().Value<char*>().Build();
+ const auto structType = builder.Struct(resultIndexes.FieldsCount)
+ ->AddField<char*>("key", &resultIndexes.key)
+ .AddField<char*>("subkey", &resultIndexes.subkey)
+ .AddField("dict", resultIndexes.DictType, &resultIndexes.dict)
+ .Build();
+
+ builder.Returns(structType)
+ .Args()->Add(recordType).Done()
+ .RunConfig<TOptional<char*>>();
+
+ if (!typesOnly) {
+ builder.Implementation(new TDsvReadRecord::TFactory(
+ resultIndexes, ksvIndexes));
+ }
+ } else if (TStringRef::Of("Parse") == name) {
+ auto optionalStringType = builder.Optional()->Item<char*>().Build();
+ auto dictType = builder.Dict()->Key<char*>().Value<char*>().Build();
+
+ builder.Returns(dictType)
+ .Args()->Add<char*>().Flags(ICallablePayload::TArgumentFlags::AutoMap).Add(optionalStringType).Done()
+ .OptionalArgs(1);
+
+ if (!typesOnly) {
+ builder.Implementation(new TDsvParse(dictType));
+ }
+ } else if (TStringRef::Of("Serialize") == name) {
+ auto typeHelper = builder.TypeInfoHelper();
+ auto userTypeInspector = TTupleTypeInspector(*typeHelper, userType);
+ if (!userTypeInspector || userTypeInspector.GetElementsCount() < 1) {
+ builder.SetError("Expected user type");
+ return;
+ }
+ auto argsTypeTuple = userTypeInspector.GetElementType(0);
+ auto argsTypeInspector = TTupleTypeInspector(*typeHelper, argsTypeTuple);
+ if (!(argsTypeInspector && argsTypeInspector.GetElementsCount() == 1)) {
+ builder.SetError("Only one argument is expected " + ToString(argsTypeInspector.GetElementsCount()));
+ return;
+ }
+
+ TVector<TDataTypeId> typeIds;
+ const auto structType = argsTypeInspector.GetElementType(0);
+ THolder<TStructTypeInspector> structInspector(new TStructTypeInspector(*typeHelper, structType));
+ if (structInspector) {
+ ui32 memberCount = structInspector->GetMembersCount();
+ typeIds.reserve(memberCount);
+
+ if (memberCount) {
+ for (ui32 i = 0; i < memberCount; ++i) {
+ const TString memberName(structInspector->GetMemberName(i));
+ const auto memberType = structInspector->GetMemberType(i);
+ auto memberInspector = TDataTypeInspector(*typeHelper, memberType);
+ if (!memberInspector) {
+ builder.SetError("Only DataType members are supported at the moment, failed at " + memberName);
+ return;
+ }
+ typeIds.push_back(memberInspector.GetTypeId());
+ }
} else {
- builder.SetError("Zero members in input Struct");
+ builder.SetError("Zero members in input Struct");
return;
}
- } else {
- builder.SetError("Only Structs are supported at the moment");
- return;
- }
+ } else {
+ builder.SetError("Only Structs are supported at the moment");
+ return;
+ }
- builder.UserType(userType).Returns<char*>().Args()->Add(structType).Done();
+ builder.UserType(userType).Returns<char*>().Args()->Add(structType).Done();
- if (!typesOnly) {
- builder.Implementation(new TDsvSerialize(typeIds, structInspector.Release()));
- }
+ if (!typesOnly) {
+ builder.Implementation(new TDsvSerialize(typeIds, structInspector.Release()));
+ }
}
- } catch (const std::exception& e) {
- builder.SetError(CurrentExceptionMessage());
+ } catch (const std::exception& e) {
+ builder.SetError(CurrentExceptionMessage());
}
};
diff --git a/ydb/library/yql/utils/backtrace/backtrace.cpp b/ydb/library/yql/utils/backtrace/backtrace.cpp
index 885bdad974..f9487f6671 100644
--- a/ydb/library/yql/utils/backtrace/backtrace.cpp
+++ b/ydb/library/yql/utils/backtrace/backtrace.cpp
@@ -1,8 +1,8 @@
#include "backtrace.h"
-#include <llvm/DebugInfo/Symbolize/Symbolize.h>
-#include <llvm/DebugInfo/Symbolize/DIPrinter.h>
-#include <llvm/Support/raw_ostream.h>
+#include <llvm/DebugInfo/Symbolize/Symbolize.h>
+#include <llvm/DebugInfo/Symbolize/DIPrinter.h>
+#include <llvm/Support/raw_ostream.h>
#include <library/cpp/malloc/api/malloc.h>
diff --git a/ydb/library/yql/utils/backtrace/ya.make b/ydb/library/yql/utils/backtrace/ya.make
index 64ad895682..990bc74cc5 100644
--- a/ydb/library/yql/utils/backtrace/ya.make
+++ b/ydb/library/yql/utils/backtrace/ya.make
@@ -11,7 +11,7 @@ SRCS(
)
PEERDIR(
- contrib/libs/llvm12/lib/DebugInfo/Symbolize
+ contrib/libs/llvm12/lib/DebugInfo/Symbolize
)
END()
diff --git a/ydb/library/yql/utils/log/log_component.h b/ydb/library/yql/utils/log/log_component.h
index 1b014518c4..d7a1e10ca1 100644
--- a/ydb/library/yql/utils/log/log_component.h
+++ b/ydb/library/yql/utils/log/log_component.h
@@ -28,9 +28,9 @@ enum class EComponent {
CorePeepHole,
ProviderDq,
ProviderClickHouse,
- ProviderYdb,
+ ProviderYdb,
ProviderPq,
- ProviderS3,
+ ProviderS3,
CoreDq,
// <--- put other log components here
MaxValue
@@ -71,7 +71,7 @@ struct EComponentHelpers {
case EComponent::ProviderClickHouse: return TStringBuf("CLICKHOUSE");
case EComponent::ProviderYdb: return TStringBuf("YDB");
case EComponent::ProviderPq: return TStringBuf("PQ");
- case EComponent::ProviderS3: return TStringBuf("S3");
+ case EComponent::ProviderS3: return TStringBuf("S3");
case EComponent::CoreDq: return TStringBuf("core dq");
default:
ythrow yexception() << "invalid log component value: "
@@ -101,7 +101,7 @@ struct EComponentHelpers {
if (str == TStringBuf("CLICKHOUSE")) return EComponent::ProviderClickHouse;
if (str == TStringBuf("YDB")) return EComponent::ProviderYdb;
if (str == TStringBuf("PQ")) return EComponent::ProviderPq;
- if (str == TStringBuf("S3")) return EComponent::ProviderS3;
+ if (str == TStringBuf("S3")) return EComponent::ProviderS3;
if (str == TStringBuf("core dq")) return EComponent::CoreDq;
ythrow yexception() << "unknown log component: '" << str << '\'';
}
diff --git a/ydb/library/yql/utils/ut/ya.make b/ydb/library/yql/utils/ut/ya.make
index 9a1d8876c2..0d26eb2c5f 100644
--- a/ydb/library/yql/utils/ut/ya.make
+++ b/ydb/library/yql/utils/ut/ya.make
@@ -9,7 +9,7 @@ SRCS(
parse_double_ut.cpp
range_walker_ut.cpp
retry_ut.cpp
- utf8_ut.cpp
+ utf8_ut.cpp
)
END()
diff --git a/ydb/library/yql/utils/utf8.cpp b/ydb/library/yql/utils/utf8.cpp
index 38af692b46..af284849a8 100644
--- a/ydb/library/yql/utils/utf8.cpp
+++ b/ydb/library/yql/utils/utf8.cpp
@@ -1,14 +1,14 @@
-#include "utf8.h"
+#include "utf8.h"
#include <util/charset/wide.h>
-#include <ctype.h>
+#include <ctype.h>
#include <vector>
-
-namespace NYql {
-
-namespace {
-
+
+namespace NYql {
+
+namespace {
+
unsigned char GetRange(unsigned char c) {
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
@@ -25,8 +25,8 @@ unsigned char GetRange(unsigned char c) {
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
};
return type[c];
-}
-
+}
+
struct TByteRange {
ui8 First = 0;
ui8 Last = 0;
@@ -126,15 +126,15 @@ std::optional<std::string> RoundBadUtf8(size_t range, std::string_view inputStri
}
-bool IsUtf8(const std::string_view& str) {
- for (auto it = str.cbegin(); str.cend() != it;) {
+bool IsUtf8(const std::string_view& str) {
+ for (auto it = str.cbegin(); str.cend() != it;) {
#define COPY() if (str.cend() != it) { c = *it++; } else { return false; }
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70)
auto c = *it++;
if (!(c & 0x80))
continue;
-
+
bool result = true;
switch (GetRange(static_cast<unsigned char>(c))) {
case 2: TAIL(); break;
@@ -146,29 +146,29 @@ bool IsUtf8(const std::string_view& str) {
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); break;
default: return false;
}
-
+
if (!result) return false;
#undef COPY
#undef TRANS
#undef TAIL
- }
- return true;
-}
-
-unsigned char WideCharSize(char head) {
- switch (GetRange(static_cast<unsigned char>(head))) {
- case 0: return 1;
- case 2: return 2;
- case 3: return 3;
- case 4: return 3;
- case 5: return 4;
- case 6: return 4;
- case 10: return 3;
- case 11: return 4;
- default: return 0;
- }
-}
-
+ }
+ return true;
+}
+
+unsigned char WideCharSize(char head) {
+ switch (GetRange(static_cast<unsigned char>(head))) {
+ case 0: return 1;
+ case 2: return 2;
+ case 3: return 3;
+ case 4: return 3;
+ case 5: return 4;
+ case 6: return 4;
+ case 10: return 3;
+ case 11: return 4;
+ default: return 0;
+ }
+}
+
std::optional<std::string> RoundToNearestValidUtf8(const std::string_view& str, bool roundDown) {
const size_t ss = str.size();
for (size_t pos = 0; pos < ss; ) {
@@ -204,7 +204,7 @@ std::optional<std::string> RoundToNearestValidUtf8(const std::string_view& str,
}
}
return std::string(str);
-}
+}
std::optional<std::string> NextValidUtf8(const std::string_view& str) {
Y_ENSURE(IsUtf8(str));
diff --git a/ydb/library/yql/utils/utf8.h b/ydb/library/yql/utils/utf8.h
index d688c8e3f6..5c28353416 100644
--- a/ydb/library/yql/utils/utf8.h
+++ b/ydb/library/yql/utils/utf8.h
@@ -1,16 +1,16 @@
-#pragma once
-
+#pragma once
+
#include <optional>
-#include <string_view>
-
-namespace NYql {
-
-bool IsUtf8(const std::string_view& str);
-
-unsigned char WideCharSize(char head);
-
+#include <string_view>
+
+namespace NYql {
+
+bool IsUtf8(const std::string_view& str);
+
+unsigned char WideCharSize(char head);
+
std::optional<std::string> RoundToNearestValidUtf8(const std::string_view& str, bool roundDown);
std::optional<std::string> NextValidUtf8(const std::string_view& str);
std::optional<std::string> NextLexicographicString(const std::string_view& str);
-}
+}
diff --git a/ydb/library/yql/utils/utf8_ut.cpp b/ydb/library/yql/utils/utf8_ut.cpp
index 7ac33b8bde..7479acd7a1 100644
--- a/ydb/library/yql/utils/utf8_ut.cpp
+++ b/ydb/library/yql/utils/utf8_ut.cpp
@@ -1,29 +1,29 @@
-#include "utf8.h"
-
+#include "utf8.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-Y_UNIT_TEST_SUITE(TUtf8Tests) {
- Y_UNIT_TEST(Simple) {
- UNIT_ASSERT(NYql::IsUtf8(""));
- UNIT_ASSERT(NYql::IsUtf8("\x01_ASCII_\x7F"));
- UNIT_ASSERT(NYql::IsUtf8("Привет!"));
- UNIT_ASSERT(NYql::IsUtf8("\xF0\x9F\x94\xA2"));
-
- UNIT_ASSERT(!NYql::IsUtf8("\xf5\x80\x80\x80"));
- UNIT_ASSERT(!NYql::IsUtf8("\xed\xa6\x80"));
- UNIT_ASSERT(!NYql::IsUtf8("\xF0\x9F\x94"));
- UNIT_ASSERT(!NYql::IsUtf8("\xE3\x85\xB6\xE7\x9C\xB0\xE3\x9C\xBA\xE2\xAA\x96\xEE\xA2\x8C\xEC\xAF\xB8\xE1\xB2\xBB\xEC\xA3\x9C\xE3\xAB\x8B\xEC\x95\x92\xE1\x8A\xBF\xE2\x8E\x86\xEC\x9B\x8D\xE2\x8E\xAE\xE3\x8A\xA3\xE0\xAC\xBC\xED\xB6\x85"));
- UNIT_ASSERT(!NYql::IsUtf8("\xc0\xbe\xd0\xb1\xd0\xbd\xd0\xbe\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8e"));
- }
-
- Y_UNIT_TEST(CharSize) {
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize(' '), 1);
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x00'), 1);
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x7F'), 1);
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xD1'), 2);
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xF0'), 4);
- UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xFF'), 0);
- }
+
+Y_UNIT_TEST_SUITE(TUtf8Tests) {
+ Y_UNIT_TEST(Simple) {
+ UNIT_ASSERT(NYql::IsUtf8(""));
+ UNIT_ASSERT(NYql::IsUtf8("\x01_ASCII_\x7F"));
+ UNIT_ASSERT(NYql::IsUtf8("Привет!"));
+ UNIT_ASSERT(NYql::IsUtf8("\xF0\x9F\x94\xA2"));
+
+ UNIT_ASSERT(!NYql::IsUtf8("\xf5\x80\x80\x80"));
+ UNIT_ASSERT(!NYql::IsUtf8("\xed\xa6\x80"));
+ UNIT_ASSERT(!NYql::IsUtf8("\xF0\x9F\x94"));
+ UNIT_ASSERT(!NYql::IsUtf8("\xE3\x85\xB6\xE7\x9C\xB0\xE3\x9C\xBA\xE2\xAA\x96\xEE\xA2\x8C\xEC\xAF\xB8\xE1\xB2\xBB\xEC\xA3\x9C\xE3\xAB\x8B\xEC\x95\x92\xE1\x8A\xBF\xE2\x8E\x86\xEC\x9B\x8D\xE2\x8E\xAE\xE3\x8A\xA3\xE0\xAC\xBC\xED\xB6\x85"));
+ UNIT_ASSERT(!NYql::IsUtf8("\xc0\xbe\xd0\xb1\xd0\xbd\xd0\xbe\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8e"));
+ }
+
+ Y_UNIT_TEST(CharSize) {
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize(' '), 1);
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x00'), 1);
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x7F'), 1);
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xD1'), 2);
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xF0'), 4);
+ UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xFF'), 0);
+ }
Y_UNIT_TEST(RoundingDown) {
auto checkDown = [](std::string_view in, std::string_view out) {
@@ -96,4 +96,4 @@ Y_UNIT_TEST_SUITE(TUtf8Tests) {
UNIT_ASSERT(!NYql::NextLexicographicString("\xff\xff"));
checkNext(std::string_view("x\x00\xff\xff", 4), "x\x01");
}
-}
+}
diff --git a/ydb/library/yql/utils/ya.make b/ydb/library/yql/utils/ya.make
index 34f6252114..afba70be53 100644
--- a/ydb/library/yql/utils/ya.make
+++ b/ydb/library/yql/utils/ya.make
@@ -34,7 +34,7 @@ SRCS(
yql_panic.h
yql_paths.cpp
yql_paths.h
- utf8.cpp
+ utf8.cpp
)
PEERDIR(
diff --git a/ydb/public/api/protos/yq.proto b/ydb/public/api/protos/yq.proto
index 88fefb42a3..6aa7169a89 100644
--- a/ydb/public/api/protos/yq.proto
+++ b/ydb/public/api/protos/yq.proto
@@ -393,9 +393,9 @@ message DescribeJobResult {
message CurrentIAMTokenAuth {
}
-message NoneAuth {
-}
-
+message NoneAuth {
+}
+
message ServiceAccountAuth {
string id = 1 [(Ydb.length).le = 1024];
}
@@ -404,7 +404,7 @@ message IamAuth {
oneof identity {
CurrentIAMTokenAuth current_iam = 1;
ServiceAccountAuth service_account = 2;
- NoneAuth none = 3;
+ NoneAuth none = 3;
}
}
@@ -736,4 +736,4 @@ message DeleteBindingResponse {
}
message DeleteBindingResult {
-}
+}
diff --git a/ydb/public/lib/deprecated/client/msgbus_client.h b/ydb/public/lib/deprecated/client/msgbus_client.h
index af25af7905..7d721946d8 100644
--- a/ydb/public/lib/deprecated/client/msgbus_client.h
+++ b/ydb/public/lib/deprecated/client/msgbus_client.h
@@ -5,7 +5,7 @@
#include <ydb/public/lib/base/defs.h>
#include <ydb/public/lib/base/msgbus.h>
-#include <functional>
+#include <functional>
#include <util/system/info.h>
#include <library/cpp/messagebus/ybus.h>
@@ -24,7 +24,7 @@ private:
void OnResult(TAutoPtr<NBus::TBusMessage> pMessage, NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> pReply);
public:
- typedef std::function<void (NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> reply)> TOnCall;
+ typedef std::function<void (NBus::EMessageStatus status, TAutoPtr<NBus::TBusMessage> reply)> TOnCall;
typedef std::function<void (NBus::EMessageStatus status,
TAutoPtr<NBus::TBusMessage> message,
TAutoPtr<NBus::TBusMessage> reply)> TOnCallWithRequest;
diff --git a/ydb/public/lib/deprecated/kicli/result.cpp b/ydb/public/lib/deprecated/kicli/result.cpp
index 6b92aef067..0f86ba4340 100644
--- a/ydb/public/lib/deprecated/kicli/result.cpp
+++ b/ydb/public/lib/deprecated/kicli/result.cpp
@@ -154,7 +154,7 @@ template <> TString TReadTableResult::ValueToString<TFormatCSV>(const YdbOld::Va
}
case NScheme::NTypeIds::Decimal:
{
- NYql::NDecimal::TInt128 val;
+ NYql::NDecimal::TInt128 val;
auto p = reinterpret_cast<char*>(&val);
reinterpret_cast<ui64*>(p)[0] = value.low_128();
reinterpret_cast<ui64*>(p)[1] = value.high_128();
diff --git a/ydb/public/lib/experimental/ydb_clickhouse_internal.cpp b/ydb/public/lib/experimental/ydb_clickhouse_internal.cpp
index 05e5d5a7c3..2984f680b7 100644
--- a/ydb/public/lib/experimental/ydb_clickhouse_internal.cpp
+++ b/ydb/public/lib/experimental/ydb_clickhouse_internal.cpp
@@ -147,28 +147,28 @@ bool RangeFinished(const TString& lastReadKey, const TString& endKey, const TVec
return cmp >= 0;
}
-TScanIterator::TScanIterator(const TDriver& driver, const TString &database, const TString &endpoint, const TString &token, bool ssl, const TString& path,
- const TVector<TString>& columns,
- const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest,
- const TString& keyFrom, const TString& keyTo,
- const TScanSettings& settings)
- : Path(path)
- , Columns(columns)
- , KeyColumnTypes(keyColumnTypes)
- , MaxRows(maxRowsInRequest)
- , MaxBytes(maxBytesInRequest)
- , Settings(settings)
- , Connection(driver, NYdb::TCommonClientSettings().Database(database).AuthToken(token).DiscoveryEndpoint(endpoint).DiscoveryMode(NYdb::EDiscoveryMode::Async).EnableSsl(ssl))
- , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
- , LastReadKeyInclusive(false)
- , EndKey(keyTo)
- , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
- , MaxRetries(20)
- , Retried(0)
-{
- MakeRequest();
-}
+TScanIterator::TScanIterator(const TDriver& driver, const TString &database, const TString &endpoint, const TString &token, bool ssl, const TString& path,
+ const TVector<TString>& columns,
+ const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest,
+ const TString& keyFrom, const TString& keyTo,
+ const TScanSettings& settings)
+ : Path(path)
+ , Columns(columns)
+ , KeyColumnTypes(keyColumnTypes)
+ , MaxRows(maxRowsInRequest)
+ , MaxBytes(maxBytesInRequest)
+ , Settings(settings)
+ , Connection(driver, NYdb::TCommonClientSettings().Database(database).AuthToken(token).DiscoveryEndpoint(endpoint).DiscoveryMode(NYdb::EDiscoveryMode::Async).EnableSsl(ssl))
+ , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
+ , LastReadKeyInclusive(false)
+ , EndKey(keyTo)
+ , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
+ , MaxRetries(20)
+ , Retried(0)
+{
+ MakeRequest();
+}
TScanIterator::TScanIterator(const TDriver& driver, const TString &database, const TString &token, const TString& path,
const TVector<TString>& columns,
@@ -183,10 +183,10 @@ TScanIterator::TScanIterator(const TDriver& driver, const TString &database, con
, MaxBytes(maxBytesInRequest)
, Settings(settings)
, Connection(driver, NYdb::TCommonClientSettings().Database(database).AuthToken(token))
- , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
+ , LastReadKey(keyFrom.empty() ? NKikimr::TSerializedCellVec::Serialize(TVector<NKikimr::TCell>(KeyColumnTypes.size())) : keyFrom)
, LastReadKeyInclusive(false)
, EndKey(keyTo)
- , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
+ , RequestsDone(!EndKey.empty() && RangeFinished(LastReadKey, EndKey, KeyColumnTypes))
, MaxRetries(20)
, Retried(0)
{
diff --git a/ydb/public/lib/experimental/ydb_clickhouse_internal.h b/ydb/public/lib/experimental/ydb_clickhouse_internal.h
index 2ec6795889..d2a846ca8f 100644
--- a/ydb/public/lib/experimental/ydb_clickhouse_internal.h
+++ b/ydb/public/lib/experimental/ydb_clickhouse_internal.h
@@ -60,11 +60,11 @@ private:
// the last returned key
class TScanIterator {
public:
- TScanIterator(const TDriver& driver, const TString &database, const TString &endpoint, const TString& token, bool ssl, const TString& path, const TVector<TString>& columns,
- const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
- ui64 maxRowsInRequest, ui64 maxBytesInRequest,
- const TString& keyFrom = TString(), const TString& keyTo = TString(),
- const TScanSettings& settings = TScanSettings());
+ TScanIterator(const TDriver& driver, const TString &database, const TString &endpoint, const TString& token, bool ssl, const TString& path, const TVector<TString>& columns,
+ const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
+ ui64 maxRowsInRequest, ui64 maxBytesInRequest,
+ const TString& keyFrom = TString(), const TString& keyTo = TString(),
+ const TScanSettings& settings = TScanSettings());
TScanIterator(const TDriver& driver, const TString &database, const TString& token, const TString& path, const TVector<TString>& columns,
const TVector<NKikimr::NScheme::TTypeId>& keyColumnTypes,
ui64 maxRowsInRequest, ui64 maxBytesInRequest,
diff --git a/ydb/public/sdk/cpp/client/ydb_persqueue_core/impl/read_session.h b/ydb/public/sdk/cpp/client/ydb_persqueue_core/impl/read_session.h
index 899ef146b6..b5b874954f 100644
--- a/ydb/public/sdk/cpp/client/ydb_persqueue_core/impl/read_session.h
+++ b/ydb/public/sdk/cpp/client/ydb_persqueue_core/impl/read_session.h
@@ -852,11 +852,11 @@ private:
i64 GetCompressedDataSizeLimit() const {
const double overallLimit = static_cast<double>(Settings.MaxMemoryUsageBytes_);
// CompressedDataSize + CompressedDataSize * AverageCompressionRatio <= Settings.MaxMemoryUsageBytes_
- return Max<i64>(1l, static_cast<i64>(overallLimit / (1.0 + AverageCompressionRatio)));
+ return Max<i64>(1l, static_cast<i64>(overallLimit / (1.0 + AverageCompressionRatio)));
}
i64 GetDecompressedDataSizeLimit() const {
- return Max<i64>(1l, static_cast<i64>(Settings.MaxMemoryUsageBytes_) - GetCompressedDataSizeLimit());
+ return Max<i64>(1l, static_cast<i64>(Settings.MaxMemoryUsageBytes_) - GetCompressedDataSizeLimit());
}
void CallCloseCallbackImpl();
diff --git a/ydb/public/sdk/cpp/client/ydb_value/value.cpp b/ydb/public/sdk/cpp/client/ydb_value/value.cpp
index b63be50daa..8c18d4d50f 100644
--- a/ydb/public/sdk/cpp/client/ydb_value/value.cpp
+++ b/ydb/public/sdk/cpp/client/ydb_value/value.cpp
@@ -872,7 +872,7 @@ TDecimalValue::TDecimalValue(const Ydb::Value& valueProto, const TDecimalType& d
TDecimalValue::TDecimalValue(const TString& decimalString, ui8 precision, ui8 scale)
: DecimalType_(precision, scale)
{
- NYql::NDecimal::TInt128 val = NYql::NDecimal::FromString(decimalString, precision, scale);
+ NYql::NDecimal::TInt128 val = NYql::NDecimal::FromString(decimalString, precision, scale);
static_assert(sizeof(val) == 16, "wrong TInt128 size");
char* buf = reinterpret_cast<char*>(&val);
Low_ = *(ui64*)buf;
@@ -880,8 +880,8 @@ TDecimalValue::TDecimalValue(const TString& decimalString, ui8 precision, ui8 sc
}
TString TDecimalValue::ToString() const {
- NYql::NDecimal::TInt128 val = NYql::NDecimal::FromHalfs(Low_, Hi_);
- return NYql::NDecimal::ToString(val, DecimalType_.Precision, DecimalType_.Scale);
+ NYql::NDecimal::TInt128 val = NYql::NDecimal::FromHalfs(Low_, Hi_);
+ return NYql::NDecimal::ToString(val, DecimalType_.Precision, DecimalType_.Scale);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/services/ydb/ydb_ut.cpp b/ydb/services/ydb/ydb_ut.cpp
index 3447be5e8d..2d37063079 100644
--- a/ydb/services/ydb/ydb_ut.cpp
+++ b/ydb/services/ydb/ydb_ut.cpp
@@ -4781,7 +4781,7 @@ void CheckYqlDecimalValues(std::shared_ptr<grpc::Channel> channel, const TString
TVector<std::pair<ui64, ui64>> halves;
for (auto &pr : vals) {
- NYql::NDecimal::TInt128 val = pr.first;
+ NYql::NDecimal::TInt128 val = pr.first;
val *= Power(10, NScheme::DECIMAL_SCALE);
if (val >= 0)
val += pr.second;